1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileFieldOverView.hxx"
23 #include "MEDFileField.hxx"
24 #include "MEDLoader.hxx"
25 #include "MEDLoaderNS.hxx"
26 #include "MEDFileSafeCaller.txx"
27 #include "MEDLoaderBase.hxx"
29 #include "MEDCouplingUMesh.hxx"
30 #include "MEDCouplingMappedExtrudedMesh.hxx"
32 #include "InterpKernelAutoPtr.hxx"
37 extern med_geometry_type 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 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
86 MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
88 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
91 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
92 throw INTERP_KERNEL::Exception(oss.str().c_str());
94 MEDCoupling::MEDCouplingMeshType meshType;
97 MEDCoupling::MEDCouplingAxisType dummy3;
98 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
99 MCAuto<MEDFileMesh> ret;
104 ret=MEDFileUMesh::New();
109 ret=MEDFileCMesh::New();
114 ret=MEDFileCurveLinearMesh::New();
119 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
120 throw INTERP_KERNEL::Exception(oss.str().c_str());
123 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
128 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
129 * file. The mesh to load is specified by its name and numbers of a time step and an
131 * \param [in] fileName - the name of MED file to read.
132 * \param [in] mName - the name of the mesh to read.
133 * \param [in] dt - the number of a time step.
134 * \param [in] it - the number of an iteration.
135 * \param [in] joints - the sub-domain joints to use instead of those that can be read
136 * from the MED file. Usually this joints are those just read by another iteration
137 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
138 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
139 * mesh using decrRef() as it is no more needed.
140 * \throw If the file is not readable.
141 * \throw If there is no mesh with given attributes in the file.
142 * \throw If the mesh in the file is of a not supported type.
144 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
146 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
147 return New(fid,mName,dt,it,mrs,joints);
150 MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
152 MEDCoupling::MEDCouplingMeshType meshType;
155 MEDCoupling::MEDCouplingAxisType dummy3;
156 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
157 MCAuto<MEDFileMesh> ret;
162 ret=MEDFileUMesh::New();
167 ret=MEDFileCMesh::New();
172 ret=MEDFileCurveLinearMesh::New();
177 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
178 throw INTERP_KERNEL::Exception(oss.str().c_str());
181 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
186 * Writes \a this mesh into an open MED file specified by its descriptor.
187 * \param [in] fid - the MED file descriptor.
188 * \throw If the mesh name is not set.
189 * \throw If the file is open for reading only.
190 * \throw If the writing mode == 1 and the same data is present in an existing file.
192 void MEDFileMesh::writeLL(med_idt fid) const
195 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
197 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
200 const MEDFileEquivalences *eqs(_equiv);
206 * Checks if \a this and another mesh are equal.
207 * \param [in] other - the mesh to compare with.
208 * \param [in] eps - a precision used to compare real values.
209 * \param [in,out] what - the string returning description of unequal data.
210 * \return bool - \c true if the meshes are equal, \c false, else.
212 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
214 if(_order!=other->_order)
216 what="Orders differ !";
219 if(_iteration!=other->_iteration)
221 what="Iterations differ !";
224 if(fabs(_time-other->_time)>eps)
226 what="Time values differ !";
229 if(_dt_unit!=other->_dt_unit)
231 what="Time units differ !";
234 if(_name!=other->_name)
236 what="Names differ !";
239 //univ_name has been ignored -> not a bug because it is a mutable attribute
240 if(_desc_name!=other->_desc_name)
242 what="Description names differ !";
245 if(!areGrpsEqual(other,what))
247 if(!areFamsEqual(other,what))
249 if(!areEquivalencesEqual(other,what))
254 void MEDFileMesh::setName(const std::string& name)
260 * Clears redundant attributes of incorporated data arrays.
262 void MEDFileMesh::clearNonDiscrAttributes() const
267 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
269 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
271 if((*it).first==_name)
281 * Copies data on groups and families from another mesh.
282 * \param [in] other - the mesh to copy the data from.
284 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
286 _groups=other._groups;
287 _families=other._families;
292 * This method clear all the groups in the map.
293 * So this method does not operate at all on arrays.
294 * So this method can lead to orphan families.
296 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
298 void MEDFileMesh::clearGrpMap()
304 * This method clear all the families in the map.
305 * So this method does not operate at all on arrays.
306 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
308 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
310 void MEDFileMesh::clearFamMap()
316 * This method clear all the families and groups in the map.
317 * So this method does not operate at all on arrays.
318 * As all groups and families entry will be removed after
319 * 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.
321 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
323 void MEDFileMesh::clearFamGrpMaps()
330 * Returns names of families constituting a group.
331 * \param [in] name - the name of the group of interest.
332 * \return std::vector<std::string> - a sequence of names of the families.
333 * \throw If the name of a nonexistent group is specified.
335 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
337 std::string oname(name);
338 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
339 if(it==_groups.end())
341 std::vector<std::string> grps=getGroupsNames();
342 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
343 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
344 throw INTERP_KERNEL::Exception(oss.str().c_str());
350 * Returns names of families constituting some groups.
351 * \param [in] grps - a sequence of names of groups of interest.
352 * \return std::vector<std::string> - a sequence of names of the families.
353 * \throw If a name of a nonexistent group is present in \a grps.
355 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
357 std::set<std::string> fams;
358 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
360 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
361 if(it2==_groups.end())
363 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
364 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
365 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
366 throw INTERP_KERNEL::Exception(oss.str().c_str());
368 fams.insert((*it2).second.begin(),(*it2).second.end());
370 std::vector<std::string> fams2(fams.begin(),fams.end());
375 * Returns ids of families constituting a group.
376 * \param [in] name - the name of the group of interest.
377 * \return std::vector<int> - sequence of ids of the families.
378 * \throw If the name of a nonexistent group is specified.
380 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
382 std::string oname(name);
383 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
384 std::vector<std::string> grps=getGroupsNames();
385 if(it==_groups.end())
387 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
388 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
389 throw INTERP_KERNEL::Exception(oss.str().c_str());
391 return getFamiliesIds((*it).second);
395 * Sets names of families constituting a group. If data on families of this group is
396 * already present, it is overwritten. Every family in \a fams is checked, and if a
397 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
398 * \param [in] name - the name of the group of interest.
399 * \param [in] fams - a sequence of names of families constituting the group.
401 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
403 std::string oname(name);
405 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
407 std::map<std::string,int>::iterator it2=_families.find(*it1);
408 if(it2==_families.end())
414 * Sets families constituting a group. The families are specified by their ids.
415 * If a family name is not found by its id, an exception is thrown.
416 * If several families have same id, the first one in lexical order is taken.
417 * \param [in] name - the name of the group of interest.
418 * \param [in] famIds - a sequence of ids of families constituting the group.
419 * \throw If a family name is not found by its id.
421 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
423 std::string oname(name);
424 std::vector<std::string> fams(famIds.size());
426 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
428 std::string name2=getFamilyNameGivenId(*it1);
435 * Returns names of groups including a given family.
436 * \param [in] name - the name of the family of interest.
437 * \return std::vector<std::string> - a sequence of names of groups including the family.
439 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
441 std::vector<std::string> ret;
442 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
444 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
447 ret.push_back((*it1).first);
455 * Adds an existing family to groups.
456 * \param [in] famName - a name of family to add to \a grps.
457 * \param [in] grps - a sequence of group names to add the family in.
458 * \throw If a family named \a famName not yet exists.
460 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
462 std::string fName(famName);
463 const std::map<std::string,int>::const_iterator it=_families.find(fName);
464 if(it==_families.end())
466 std::vector<std::string> fams=getFamiliesNames();
467 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
468 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
469 throw INTERP_KERNEL::Exception(oss.str().c_str());
471 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
473 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
474 if(it2!=_groups.end())
475 (*it2).second.push_back(fName);
478 std::vector<std::string> grps2(1,fName);
485 * Returns names of all groups of \a this mesh.
486 * \return std::vector<std::string> - a sequence of group names.
488 std::vector<std::string> MEDFileMesh::getGroupsNames() const
490 std::vector<std::string> ret(_groups.size());
492 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
498 * Returns names of all families of \a this mesh.
499 * \return std::vector<std::string> - a sequence of family names.
501 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
503 std::vector<std::string> ret(_families.size());
505 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
511 * Returns names of all families of \a this mesh but like they would be in file.
512 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
513 * 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 !
514 * For your information internaly in memory such families are renamed to have a nicer API.
516 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
518 std::vector<std::string> ret(getFamiliesNames());
519 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
524 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
525 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
526 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
529 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
531 std::vector<std::string> ret;
532 std::vector<std::string> allGrps(getGroupsNames());
533 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
535 std::vector<int> levs(getGrpNonEmptyLevelsExt((*it)));
536 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
543 * Returns all relative mesh levels (including nodes) where a given group is defined.
544 * \param [in] grp - the name of the group of interest.
545 * \return std::vector<int> - a sequence of the relative dimensions.
547 std::vector<int> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
549 std::vector<std::string> fams(getFamiliesOnGroup(grp));
550 return getFamsNonEmptyLevelsExt(fams);
554 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
555 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
556 * \param [in] grps - a sequence of names of the groups of interest.
557 * \return std::vector<int> - a sequence of the relative dimensions.
559 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
561 std::vector<std::string> fams(getFamiliesOnGroups(grps));
562 return getFamsNonEmptyLevels(fams);
566 * Returns all relative mesh levels (including nodes) where given groups are defined.
567 * \param [in] grps - a sequence of names of the groups of interest.
568 * \return std::vector<int> - a sequence of the relative dimensions.
570 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
572 std::vector<std::string> fams(getFamiliesOnGroups(grps));
573 return getFamsNonEmptyLevelsExt(fams);
577 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
578 * To include nodes, call getGrpNonEmptyLevelsExt() method.
579 * \param [in] grp - the name of the group of interest.
580 * \return std::vector<int> - a sequence of the relative dimensions.
582 std::vector<int> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
584 std::vector<std::string> fams(getFamiliesOnGroup(grp));
585 return getFamsNonEmptyLevels(fams);
589 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
590 * To include nodes, call getFamNonEmptyLevelsExt() method.
591 * \param [in] fam - the name of the family of interest.
592 * \return std::vector<int> - a sequence of the relative dimensions.
594 std::vector<int> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
596 std::vector<std::string> fams(1,std::string(fam));
597 return getFamsNonEmptyLevels(fams);
601 * Returns all relative mesh levels (including nodes) where a given family is defined.
602 * \param [in] fam - the name of the family of interest.
603 * \return std::vector<int> - a sequence of the relative dimensions.
605 std::vector<int> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
607 std::vector<std::string> fams(1,std::string(fam));
608 return getFamsNonEmptyLevelsExt(fams);
611 std::string MEDFileMesh::GetMagicFamilyStr()
613 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
617 * Changes a name of every family, included in one group only, to be same as the group name.
618 * \throw If there are families with equal names in \a this mesh.
620 void MEDFileMesh::assignFamilyNameWithGroupName()
622 std::map<std::string, std::vector<std::string> > groups(_groups);
623 std::map<std::string,int> newFams;
624 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
626 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
627 if(grps.size()==1 && groups[grps[0]].size()==1)
629 if(newFams.find(grps[0])!=newFams.end())
631 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
632 throw INTERP_KERNEL::Exception(oss.str().c_str());
634 newFams[grps[0]]=(*it).second;
635 std::vector<std::string>& grps2=groups[grps[0]];
636 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
641 if(newFams.find((*it).first)!=newFams.end())
643 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
644 throw INTERP_KERNEL::Exception(oss.str().c_str());
646 newFams[(*it).first]=(*it).second;
654 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
656 * \return the removed groups.
658 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
660 std::vector<std::string> ret;
661 std::map<std::string, std::vector<std::string> > newGrps;
662 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
664 if((*it).second.empty())
665 ret.push_back((*it).first);
667 newGrps[(*it).first]=(*it).second;
675 * Removes a group from \a this mesh.
676 * \param [in] name - the name of the group to remove.
677 * \throw If no group with such a \a name exists.
679 void MEDFileMesh::removeGroup(const std::string& name)
681 std::string oname(name);
682 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
683 std::vector<std::string> grps=getGroupsNames();
684 if(it==_groups.end())
686 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
687 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
688 throw INTERP_KERNEL::Exception(oss.str().c_str());
694 * Removes a family from \a this mesh.
695 * \param [in] name - the name of the family to remove.
696 * \throw If no family with such a \a name exists.
698 void MEDFileMesh::removeFamily(const std::string& name)
700 std::string oname(name);
701 std::map<std::string, int >::iterator it=_families.find(oname);
702 std::vector<std::string> fams=getFamiliesNames();
703 if(it==_families.end())
705 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
706 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
707 throw INTERP_KERNEL::Exception(oss.str().c_str());
710 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
712 std::vector<std::string>& v=(*it3).second;
713 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
720 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
721 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
722 * family field whatever its level. This method also suppresses the orphan families.
724 * \return - The list of removed groups names.
726 * \sa MEDFileMesh::removeOrphanFamilies.
728 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
730 removeOrphanFamilies();
731 return removeEmptyGroups();
735 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
736 * 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.
738 * \return - The list of removed families names.
739 * \sa MEDFileMesh::removeOrphanGroups.
741 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
743 MCAuto<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
744 std::vector<std::string> ret;
745 if(!((DataArrayInt*)allFamIdsInUse))
747 ret=getFamiliesNames();
748 _families.clear(); _groups.clear();
751 std::map<std::string,int> famMap;
752 std::map<std::string, std::vector<std::string> > grps(_groups);
753 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
755 if(allFamIdsInUse->presenceOfValue((*it).second))
756 famMap[(*it).first]=(*it).second;
759 ret.push_back((*it).first);
760 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
761 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
763 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
764 std::vector<std::string>& famv=(*it3).second;
765 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
771 { _families=famMap; _groups=grps; }
776 * 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
777 * this family is orphan or not.
779 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
781 void MEDFileMesh::removeFamiliesReferedByNoGroups()
783 std::map<std::string,int> fams;
784 std::set<std::string> sfams;
785 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
786 sfams.insert((*it).first);
787 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
788 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
790 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
791 if(*it!=DFT_FAM_NAME)
792 _families.erase(*it);
796 * 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
797 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
798 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
800 * \sa MEDFileMesh::removeOrphanFamilies
802 void MEDFileMesh::rearrangeFamilies()
804 checkOrphanFamilyZero();
805 removeFamiliesReferedByNoGroups();
807 std::vector<int> levels(getNonEmptyLevelsExt());
808 std::set<int> idsRefed;
809 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
810 idsRefed.insert((*it).second);
811 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
813 const DataArrayInt *fams(0);
816 fams=getFamilyFieldAtLevel(*it);
818 catch(INTERP_KERNEL::Exception& e) { }
821 std::vector<bool> v(fams->getNumberOfTuples(),false);
822 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
823 fams->switchOnTupleEqualTo(*pt,v);
824 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
825 if(!unfetchedIds->empty())
827 MCAuto<DataArrayInt> newFams(fams->deepCopy());
828 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
829 setFamilyFieldArr(*it,newFams);
832 removeOrphanFamilies();
836 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
838 void MEDFileMesh::checkOrphanFamilyZero() const
840 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
842 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
844 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
845 throw INTERP_KERNEL::Exception(oss.str().c_str());
851 * Renames a group in \a this mesh.
852 * \param [in] oldName - a current name of the group to rename.
853 * \param [in] newName - a new group name.
854 * \throw If no group named \a oldName exists in \a this mesh.
855 * \throw If a group named \a newName already exists.
857 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
859 std::string oname(oldName);
860 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
861 std::vector<std::string> grps=getGroupsNames();
862 if(it==_groups.end())
864 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
865 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
866 throw INTERP_KERNEL::Exception(oss.str().c_str());
868 std::string nname(newName);
869 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
870 if(it2!=_groups.end())
872 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
873 throw INTERP_KERNEL::Exception(oss.str().c_str());
875 std::vector<std::string> cpy=(*it).second;
877 _groups[newName]=cpy;
881 * Changes an id of a family in \a this mesh.
882 * This method calls changeFamilyIdArr().
883 * \param [in] oldId - a current id of the family.
884 * \param [in] newId - a new family id.
886 void MEDFileMesh::changeFamilyId(int oldId, int newId)
888 changeFamilyIdArr(oldId,newId);
889 std::map<std::string,int> fam2;
890 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
892 if((*it).second==oldId)
893 fam2[(*it).first]=newId;
895 fam2[(*it).first]=(*it).second;
901 * Renames a family in \a this mesh.
902 * \param [in] oldName - a current name of the family to rename.
903 * \param [in] newName - a new family name.
904 * \throw If no family named \a oldName exists in \a this mesh.
905 * \throw If a family named \a newName already exists.
907 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
909 std::string oname(oldName);
910 std::map<std::string, int >::iterator it=_families.find(oname);
911 std::vector<std::string> fams=getFamiliesNames();
912 if(it==_families.end())
914 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
915 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
916 throw INTERP_KERNEL::Exception(oss.str().c_str());
918 std::string nname(newName);
919 std::map<std::string, int >::iterator it2=_families.find(nname);
920 if(it2!=_families.end())
922 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
923 throw INTERP_KERNEL::Exception(oss.str().c_str());
925 int cpy=(*it).second;
927 _families[newName]=cpy;
928 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
930 std::vector<std::string>& v=(*it3).second;
931 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
938 * Checks if \a this and another mesh contains the same families.
939 * \param [in] other - the mesh to compare with \a this one.
940 * \param [in,out] what - an unused parameter.
941 * \return bool - \c true if number of families and their ids are the same in the two
942 * meshes. Families with the id == \c 0 are not considered.
944 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
946 if(_families==other->_families)
948 std::map<std::string,int> fam0;
949 std::map<std::string,int> fam1;
950 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
952 fam0[(*it).first]=(*it).second;
953 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
955 fam1[(*it).first]=(*it).second;
960 * Checks if \a this and another mesh contains the same groups.
961 * \param [in] other - the mesh to compare with \a this one.
962 * \param [in,out] what - a string describing a difference of groups of the two meshes
963 * in case if this method returns \c false.
964 * \return bool - \c true if number of groups and families constituting them are the
965 * same in the two meshes.
967 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
969 if(_groups==other->_groups)
972 std::size_t sz=_groups.size();
973 if(sz!=other->_groups.size())
975 what="Groups differ because not same number !\n";
980 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
981 for(std::size_t i=0;i<sz && ret;i++,it1++)
983 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
984 if(it2!=other->_groups.end())
986 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
987 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
993 what="A group in first mesh exists not in other !\n";
999 std::ostringstream oss; oss << "Groups description differs :\n";
1000 oss << "First group description :\n";
1001 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1003 oss << " Group \"" << (*it).first << "\" on following families :\n";
1004 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1005 oss << " \"" << *it2 << "\n";
1007 oss << "Second group description :\n";
1008 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1010 oss << " Group \"" << (*it).first << "\" on following families :\n";
1011 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1012 oss << " \"" << *it2 << "\n";
1020 * Checks if a group with a given name exists in \a this mesh.
1021 * \param [in] groupName - the group name.
1022 * \return bool - \c true the group \a groupName exists in \a this mesh.
1024 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1026 std::string grpName(groupName);
1027 return _groups.find(grpName)!=_groups.end();
1031 * Checks if a family with a given id exists in \a this mesh.
1032 * \param [in] famId - the family id.
1033 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1035 bool MEDFileMesh::existsFamily(int famId) const
1037 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1038 if((*it2).second==famId)
1044 * Checks if a family with a given name exists in \a this mesh.
1045 * \param [in] familyName - the family name.
1046 * \return bool - \c true the family \a familyName exists in \a this mesh.
1048 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1050 std::string fname(familyName);
1051 return _families.find(fname)!=_families.end();
1055 * Sets an id of a family.
1056 * \param [in] familyName - the family name.
1057 * \param [in] id - a new id of the family.
1059 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1061 std::string fname(familyName);
1062 _families[fname]=id;
1065 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1067 std::string fname(familyName);
1068 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1069 if((*it).second==id)
1071 if((*it).first!=familyName)
1073 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1074 throw INTERP_KERNEL::Exception(oss.str().c_str());
1077 _families[fname]=id;
1081 * Adds a family to \a this mesh.
1082 * \param [in] familyName - a name of the family.
1083 * \param [in] famId - an id of the family.
1084 * \throw If a family with the same name or id already exists in \a this mesh.
1086 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1088 std::string fname(familyName);
1089 std::map<std::string,int>::const_iterator it=_families.find(fname);
1090 if(it==_families.end())
1092 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1093 if((*it2).second==famId)
1095 std::ostringstream oss;
1096 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1097 throw INTERP_KERNEL::Exception(oss.str().c_str());
1099 _families[fname]=famId;
1103 if((*it).second!=famId)
1105 std::ostringstream oss;
1106 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1107 throw INTERP_KERNEL::Exception(oss.str().c_str());
1113 * Creates a group including all mesh entities of given dimension.
1114 * \warning This method does \b not guarantee that the created group includes mesh
1115 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1116 * present in family fields of different dimensions. To assure this, call
1117 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1118 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1120 * \param [in] groupName - a name of the new group.
1121 * \throw If a group named \a groupName already exists.
1122 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1123 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1125 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1127 std::string grpName(groupName);
1128 std::vector<int> levs=getNonEmptyLevelsExt();
1129 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1131 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1132 oss << "Available relative ext levels are : ";
1133 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1134 throw INTERP_KERNEL::Exception(oss.str().c_str());
1136 if(existsGroup(groupName))
1138 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1139 oss << "Already existing groups are : ";
1140 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1141 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1142 throw INTERP_KERNEL::Exception(oss.str().c_str());
1144 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1146 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1147 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1148 std::vector<std::string> familiesOnWholeGroup;
1149 for(const int *it=famIds->begin();it!=famIds->end();it++)
1152 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1154 _groups[grpName]=familiesOnWholeGroup;
1158 * Ensures that given family ids do not present in family fields of dimensions different
1159 * than given ones. If a family id is present in the family fields of dimensions different
1160 * than the given ones, a new family is created and the whole data is updated accordingly.
1161 * \param [in] famIds - a sequence of family ids to check.
1162 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1163 * famIds should exclusively belong.
1164 * \return bool - \c true if no modification is done in \a this mesh by this method.
1166 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1168 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1169 std::vector<int> levs=getNonEmptyLevelsExt();
1170 std::set<int> levs2(levs.begin(),levs.end());
1171 std::vector<int> levsToTest;
1172 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1173 std::set<int> famIds2(famIds.begin(),famIds.end());
1176 if(!_families.empty())
1177 maxFamId=getMaxFamilyId()+1;
1178 std::vector<std::string> allFams=getFamiliesNames();
1179 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1181 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1184 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1185 std::vector<int> tmp;
1186 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1187 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1190 std::string famName=getFamilyNameGivenId(*it2);
1191 std::ostringstream oss; oss << "Family_" << maxFamId;
1192 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1193 addFamilyOnAllGroupsHaving(famName,zeName);
1194 _families[zeName]=maxFamId;
1195 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1204 * Adds a family to a given group in \a this mesh. If the group with a given name does
1205 * not exist, it is created.
1206 * \param [in] grpName - the name of the group to add the family in.
1207 * \param [in] famName - the name of the family to add to the group named \a grpName.
1208 * \throw If \a grpName or \a famName is an empty string.
1209 * \throw If no family named \a famName is present in \a this mesh.
1211 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1213 std::string grpn(grpName);
1214 std::string famn(famName);
1215 if(grpn.empty() || famn.empty())
1216 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1217 std::vector<std::string> fams=getFamiliesNames();
1218 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1220 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1221 oss << "Create this family or choose an existing one ! Existing fams are : ";
1222 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1223 throw INTERP_KERNEL::Exception(oss.str().c_str());
1225 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1226 if(it==_groups.end())
1228 _groups[grpn].push_back(famn);
1232 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1233 if(it2==(*it).second.end())
1234 (*it).second.push_back(famn);
1239 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1240 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1241 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1243 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1245 std::string famNameCpp(famName);
1246 std::string otherCpp(otherFamName);
1247 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1249 std::vector<std::string>& v=(*it).second;
1250 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1252 v.push_back(otherCpp);
1258 * \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).
1259 * \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)
1261 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1264 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1265 std::string grpName(ids->getName());
1267 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1268 ids->checkStrictlyMonotonic(true);
1269 famArr->incrRef(); MCAuto<DataArrayInt> famArrTmp(famArr);
1270 std::vector<std::string> grpsNames=getGroupsNames();
1271 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1273 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1274 throw INTERP_KERNEL::Exception(oss.str().c_str());
1276 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1277 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1278 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1279 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1280 std::vector<int> familyIds;
1281 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1282 int maxVal=getTheMaxAbsFamilyId()+1;
1283 std::map<std::string,int> families(_families);
1284 std::map<std::string, std::vector<std::string> > groups(_groups);
1285 std::vector<std::string> fams;
1286 bool created(false);
1287 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1289 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1290 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1291 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1292 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1295 bool isFamPresent=false;
1296 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1297 isFamPresent=(*itl)->presenceOfValue(*famId);
1299 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1302 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1303 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1304 fams.push_back(locFamName);
1305 if(existsFamily(*famId))
1307 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1308 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1311 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1315 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1316 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1317 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1318 if(existsFamily(*famId))
1320 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1321 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1326 for(std::size_t i=0;i<familyIds.size();i++)
1328 DataArrayInt *da=idsPerfamiliyIds[i];
1329 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1333 _groups[grpName]=fams;
1336 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1338 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1341 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1343 std::string fam(familyNameToChange);
1344 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1346 std::vector<std::string>& fams((*it).second);
1347 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1351 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1357 * Returns a name of the family having a given id or, if no such a family exists, creates
1358 * a new uniquely named family and returns its name.
1359 * \param [in] id - the id of the family whose name is required.
1360 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1361 * \return std::string - the name of the existing or the created family.
1362 * \throw If it is not possible to create a unique family name.
1364 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1366 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1370 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1371 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1372 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1373 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1375 * This method will throws an exception if it is not possible to create a unique family name.
1377 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1379 std::vector<std::string> famAlreadyExisting(families.size());
1381 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1383 if((*it).second!=id)
1385 famAlreadyExisting[ii]=(*it).first;
1394 std::ostringstream oss; oss << "Family_" << id;
1395 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1401 * Sets names and ids of all families in \a this mesh.
1402 * \param [in] info - a map of a family name to a family id.
1404 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1410 * Sets names of all groups and families constituting them in \a this mesh.
1411 * \param [in] info - a map of a group name to a vector of names of families
1412 * constituting the group.
1414 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1420 * Returns an id of the family having a given name.
1421 * \param [in] name - the name of the family of interest.
1422 * \return int - the id of the family of interest.
1423 * \throw If no family with such a \a name exists.
1425 int MEDFileMesh::getFamilyId(const std::string& name) const
1427 std::map<std::string, int>::const_iterator it=_families.find(name);
1428 if(it==_families.end())
1430 std::vector<std::string> fams(getFamiliesNames());
1431 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1432 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1433 throw INTERP_KERNEL::Exception(oss.str().c_str());
1435 return (*it).second;
1439 * Returns ids of the families having given names.
1440 * \param [in] fams - a sequence of the names of families of interest.
1441 * \return std::vector<int> - a sequence of the ids of families of interest.
1442 * \throw If \a fams contains a name of an inexistent family.
1444 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1446 std::vector<int> ret(fams.size());
1448 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1450 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1451 if(it2==_families.end())
1453 std::vector<std::string> fams2=getFamiliesNames();
1454 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1455 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1456 throw INTERP_KERNEL::Exception(oss.str().c_str());
1458 ret[i]=(*it2).second;
1464 * Returns a maximal abs(id) of families in \a this mesh.
1465 * \return int - the maximal norm of family id.
1466 * \throw If there are no families in \a this mesh.
1468 int MEDFileMesh::getMaxAbsFamilyId() const
1470 if(_families.empty())
1471 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1472 int ret=-std::numeric_limits<int>::max();
1473 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1475 ret=std::max(std::abs((*it).second),ret);
1481 * Returns a maximal id of families in \a this mesh.
1482 * \return int - the maximal family id.
1483 * \throw If there are no families in \a this mesh.
1485 int MEDFileMesh::getMaxFamilyId() const
1487 if(_families.empty())
1488 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1489 int ret=-std::numeric_limits<int>::max();
1490 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1492 ret=std::max((*it).second,ret);
1498 * Returns a minimal id of families in \a this mesh.
1499 * \return int - the minimal family id.
1500 * \throw If there are no families in \a this mesh.
1502 int MEDFileMesh::getMinFamilyId() const
1504 if(_families.empty())
1505 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1506 int ret=std::numeric_limits<int>::max();
1507 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1509 ret=std::min((*it).second,ret);
1515 * Returns a maximal id of families in \a this mesh. Not only named families are
1516 * considered but all family fields as well.
1517 * \return int - the maximal family id.
1519 int MEDFileMesh::getTheMaxAbsFamilyId() const
1521 int m1=-std::numeric_limits<int>::max();
1522 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1523 m1=std::max(std::abs((*it).second),m1);
1524 int m2=getMaxAbsFamilyIdInArrays();
1525 return std::max(m1,m2);
1529 * Returns a maximal id of families in \a this mesh. Not only named families are
1530 * considered but all family fields as well.
1531 * \return int - the maximal family id.
1533 int MEDFileMesh::getTheMaxFamilyId() const
1535 int m1=-std::numeric_limits<int>::max();
1536 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1537 m1=std::max((*it).second,m1);
1538 int m2=getMaxFamilyIdInArrays();
1539 return std::max(m1,m2);
1543 * Returns a minimal id of families in \a this mesh. Not only named families are
1544 * considered but all family fields as well.
1545 * \return int - the minimal family id.
1547 int MEDFileMesh::getTheMinFamilyId() const
1549 int m1=std::numeric_limits<int>::max();
1550 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1551 m1=std::min((*it).second,m1);
1552 int m2=getMinFamilyIdInArrays();
1553 return std::min(m1,m2);
1557 * This method only considers the maps. The contain of family array is ignored here.
1559 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1561 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1563 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1565 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1566 v.insert((*it).second);
1567 ret->alloc((int)v.size(),1);
1568 std::copy(v.begin(),v.end(),ret->getPointer());
1573 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1575 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1577 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1579 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1580 MCAuto<DataArrayInt> ret;
1581 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1583 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1584 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1585 if((DataArrayInt *) ret)
1586 ret=dv->buildUnion(ret);
1594 * true is returned if no modification has been needed. false if family
1595 * renumbering has been needed.
1597 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1599 std::vector<int> levs=getNonEmptyLevelsExt();
1600 std::set<int> allFamIds;
1601 int maxId=getMaxFamilyId()+1;
1602 std::map<int,std::vector<int> > famIdsToRenum;
1603 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1605 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1608 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1610 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1612 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1614 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1617 if(famIdsToRenum.empty())
1619 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1620 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1622 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1623 int *famIdsToChange=fam->getPointer();
1624 std::map<int,int> ren;
1625 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1627 if(allIds->presenceOfValue(*it3))
1629 std::string famName=getFamilyNameGivenId(*it3);
1630 std::vector<std::string> grps=getGroupsOnFamily(famName);
1633 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1634 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1635 addFamilyOnGrp((*it4),newFam);
1638 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1639 for(const int *id=ids->begin();id!=ids->end();id++)
1640 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1646 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1647 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1648 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1649 * This method will throw an exception if a same family id is detected in different level.
1650 * \warning This policy is the opposite of those in MED file documentation ...
1652 void MEDFileMesh::normalizeFamIdsTrio()
1654 ensureDifferentFamIdsPerLevel();
1655 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1656 std::vector<int> levs=getNonEmptyLevelsExt();
1657 std::set<int> levsS(levs.begin(),levs.end());
1658 std::set<std::string> famsFetched;
1659 std::map<std::string,int> families;
1660 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1663 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1667 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1668 std::map<int,int> ren;
1669 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1671 int nbOfTuples=fam->getNumberOfTuples();
1672 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1673 for(int *w=start;w!=start+nbOfTuples;w++)
1675 for(const int *it=tmp->begin();it!=tmp->end();it++)
1677 if(allIds->presenceOfValue(*it))
1679 std::string famName=getFamilyNameGivenId(*it);
1680 families[famName]=ren[*it];
1681 famsFetched.insert(famName);
1686 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1689 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1693 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1694 std::map<int,int> ren;
1695 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1697 int nbOfTuples=fam->getNumberOfTuples();
1698 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1699 for(int *w=start;w!=start+nbOfTuples;w++)
1701 for(const int *it=tmp->begin();it!=tmp->end();it++)
1703 if(allIds->presenceOfValue(*it))
1705 std::string famName=getFamilyNameGivenId(*it);
1706 families[famName]=ren[*it];
1707 famsFetched.insert(famName);
1712 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1714 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1717 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1718 fam->fillWithZero();
1719 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1720 if(allIds->presenceOfValue(*it3))
1722 std::string famName=getFamilyNameGivenId(*it3);
1723 families[famName]=0;
1724 famsFetched.insert(famName);
1729 std::vector<std::string> allFams=getFamiliesNames();
1730 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1731 std::set<std::string> unFetchedIds;
1732 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1733 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1734 families[*it4]=_families[*it4];
1739 * This method normalizes fam id with the following policy.
1740 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1741 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1742 * This method will throw an exception if a same family id is detected in different level.
1744 void MEDFileMesh::normalizeFamIdsMEDFile()
1746 ensureDifferentFamIdsPerLevel();
1747 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1748 std::vector<int> levs=getNonEmptyLevelsExt();
1749 std::set<int> levsS(levs.begin(),levs.end());
1750 std::set<std::string> famsFetched;
1751 std::map<std::string,int> families;
1753 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1756 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1759 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1760 std::map<int,int> ren;
1761 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1763 int nbOfTuples=fam->getNumberOfTuples();
1764 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1765 for(int *w=start;w!=start+nbOfTuples;w++)
1767 for(const int *it=tmp->begin();it!=tmp->end();it++)
1769 if(allIds->presenceOfValue(*it))
1771 std::string famName=getFamilyNameGivenId(*it);
1772 families[famName]=ren[*it];
1773 famsFetched.insert(famName);
1779 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1781 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1784 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1785 std::map<int,int> ren;
1786 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1788 int nbOfTuples=fam->getNumberOfTuples();
1789 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1790 for(int *w=start;w!=start+nbOfTuples;w++)
1792 for(const int *it=tmp->begin();it!=tmp->end();it++)
1794 if(allIds->presenceOfValue(*it))
1796 std::string famName=getFamilyNameGivenId(*it);
1797 families[famName]=ren[*it];
1798 famsFetched.insert(famName);
1804 std::vector<std::string> allFams=getFamiliesNames();
1805 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1806 std::set<std::string> unFetchedIds;
1807 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1808 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1809 families[*it4]=_families[*it4];
1814 * Returns a name of the family by its id. If there are several families having the given
1815 * id, the name first in lexical order is returned.
1816 * \param [in] id - the id of the family whose name is required.
1817 * \return std::string - the name of the found family.
1818 * \throw If no family with the given \a id exists.
1820 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1822 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1823 if((*it).second==id)
1825 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1826 throw INTERP_KERNEL::Exception(oss.str().c_str());
1830 * Returns a string describing \a this mesh. This description includes the mesh name and
1831 * the mesh description string.
1832 * \return std::string - the mesh information string.
1834 std::string MEDFileMesh::simpleRepr() const
1836 std::ostringstream oss;
1837 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1838 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1839 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1844 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1845 * an empty one is created.
1847 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1849 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1852 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1853 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1854 arr->fillWithZero();
1855 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1856 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1860 * Returns ids of mesh entities contained in a given group of a given dimension.
1861 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1863 * \param [in] grp - the name of the group of interest.
1864 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1865 * returned instead of ids.
1866 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1867 * numbers, if available and required, of mesh entities of the group. The caller
1868 * is to delete this array using decrRef() as it is no more needed.
1869 * \throw If the name of a nonexistent group is specified.
1870 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1872 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1874 std::vector<std::string> tmp(1);
1876 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1882 * Returns ids of mesh entities contained in given groups of a given dimension.
1883 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1885 * \param [in] grps - the names of the groups of interest.
1886 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1887 * returned instead of ids.
1888 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1889 * numbers, if available and required, of mesh entities of the groups. The caller
1890 * is to delete this array using decrRef() as it is no more needed.
1891 * \throw If the name of a nonexistent group is present in \a grps.
1892 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1894 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1896 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1897 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1901 * Returns ids of mesh entities contained in a given family of a given dimension.
1902 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1904 * \param [in] fam - the name of the family of interest.
1905 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1906 * returned instead of ids.
1907 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1908 * numbers, if available and required, of mesh entities of the family. The caller
1909 * is to delete this array using decrRef() as it is no more needed.
1910 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1912 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1914 std::vector<std::string> tmp(1);
1916 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1922 * Returns ids of nodes contained in a given group.
1923 * \param [in] grp - the name of the group of interest.
1924 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1925 * returned instead of ids.
1926 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1927 * numbers, if available and required, of nodes of the group. The caller
1928 * is to delete this array using decrRef() as it is no more needed.
1929 * \throw If the name of a nonexistent group is specified.
1930 * \throw If the family field is missing for nodes.
1932 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1934 std::vector<std::string> tmp(1);
1936 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1942 * Returns ids of nodes contained in given groups.
1943 * \param [in] grps - the names of the groups of interest.
1944 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1945 * returned instead of ids.
1946 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1947 * numbers, if available and required, of nodes of the groups. The caller
1948 * is to delete this array using decrRef() as it is no more needed.
1949 * \throw If the name of a nonexistent group is present in \a grps.
1950 * \throw If the family field is missing for nodes.
1952 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1954 return getGroupsArr(1,grps,renum);
1958 * Returns ids of nodes contained in a given group.
1959 * \param [in] grp - the name of the group of interest.
1960 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1961 * returned instead of ids.
1962 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1963 * numbers, if available and required, of nodes of the group. The caller
1964 * is to delete this array using decrRef() as it is no more needed.
1965 * \throw If the name of a nonexistent group is specified.
1966 * \throw If the family field is missing for nodes.
1968 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1970 std::vector<std::string> tmp(1);
1972 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1978 * Returns ids of nodes contained in given families.
1979 * \param [in] fams - the names of the families of interest.
1980 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1981 * returned instead of ids.
1982 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1983 * numbers, if available and required, of nodes of the families. The caller
1984 * is to delete this array using decrRef() as it is no more needed.
1985 * \throw If the family field is missing for nodes.
1987 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1989 return getFamiliesArr(1,fams,renum);
1993 * Adds groups of given dimension and creates corresponding families and family fields
1994 * given ids of mesh entities of each group.
1995 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1996 * \param [in] grps - a sequence of arrays of ids each describing a group.
1997 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1999 * \throw If names of some groups in \a grps are equal.
2000 * \throw If \a grps includes a group with an empty name.
2001 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2002 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2004 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2008 std::set<std::string> grpsName;
2009 std::vector<std::string> grpsName2(grps.size());
2012 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2014 grpsName.insert((*it)->getName());
2015 grpsName2[i]=(*it)->getName();
2017 if(grpsName.size()!=grps.size())
2018 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2019 if(grpsName.find(std::string(""))!=grpsName.end())
2020 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2021 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2022 MCAuto<DataArrayInt> fam;
2023 std::vector< std::vector<int> > fidsOfGroups;
2026 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2030 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2031 for(unsigned int ii=0;ii<grps.size();ii++)
2033 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2034 grps2[ii]->setName(grps[ii]->getName());
2036 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2037 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2040 if(!_families.empty())
2041 offset=getMaxAbsFamilyId()+1;
2042 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2043 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2044 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2045 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2049 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2050 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2051 * For the moment, the two last input parameters are not taken into account.
2053 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2055 std::map<int,std::string> famInv;
2056 for(const int *it=famIds->begin();it!=famIds->end();it++)
2058 std::ostringstream oss;
2059 oss << "Family_" << (*it);
2060 _families[oss.str()]=(*it);
2061 famInv[*it]=oss.str();
2064 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2066 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2068 _groups[grpNames[i]].push_back(famInv[*it2]);
2073 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2075 std::vector<int> levs(getNonEmptyLevels());
2076 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2077 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2079 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2080 ret.insert(ret.end(),elts.begin(),elts.end());
2086 * \sa getAllDistributionOfTypes
2088 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2090 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2091 return mLev->getDistributionOfTypes();
2094 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2096 loadLL(fid,mName,dt,it,mrs);
2097 loadJointsFromFile(fid);
2098 loadEquivalences(fid);
2101 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2103 famArr->applyLin(offset>0?1:-1,offset,0);
2104 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2107 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2108 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2113 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2114 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2115 * If this method fails to find such a name it will throw an exception.
2117 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2120 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2123 std::size_t len=nameTry.length();
2124 for(std::size_t ii=1;ii<len;ii++)
2126 std::string tmp=nameTry.substr(ii,len-ii);
2127 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2133 for(std::size_t i=1;i<30;i++)
2135 std::string tmp1(nameTry.at(0),i);
2137 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2143 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2145 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2147 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2150 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2152 std::size_t nbOfChunks=code.size()/3;
2153 if(code.size()%3!=0)
2154 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2156 for(std::size_t i=0;i<nbOfChunks;i++)
2165 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2166 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2167 * If _name is not empty and that 'm' has the same name nothing is done.
2168 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2170 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2173 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2178 std::string name(m->getName());
2183 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2184 oss << name << "' ! Names must match !";
2185 throw INTERP_KERNEL::Exception(oss.str().c_str());
2189 if(_desc_name.empty())
2190 _desc_name=m->getDescription();
2193 std::string name(m->getDescription());
2196 if(_desc_name!=name)
2198 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2199 oss << name << "' ! Names must match !";
2200 throw INTERP_KERNEL::Exception(oss.str().c_str());
2206 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2208 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2209 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2211 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2212 oss << " - Groups lying on this family : ";
2213 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2214 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2215 oss << std::endl << std::endl;
2220 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2221 * file. The mesh to load is specified by its name and numbers of a time step and an
2223 * \param [in] fileName - the name of MED file to read.
2224 * \param [in] mName - the name of the mesh to read.
2225 * \param [in] dt - the number of a time step.
2226 * \param [in] it - the number of an iteration.
2227 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2228 * mesh using decrRef() as it is no more needed.
2229 * \throw If the file is not readable.
2230 * \throw If there is no mesh with given attributes in the file.
2231 * \throw If the mesh in the file is not an unstructured one.
2233 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2235 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2236 return New(fid,mName,dt,it,mrs);
2239 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2241 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2245 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2246 * file. The first mesh in the file is loaded.
2247 * \param [in] fileName - the name of MED file to read.
2248 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2249 * mesh using decrRef() as it is no more needed.
2250 * \throw If the file is not readable.
2251 * \throw If there is no meshes in the file.
2252 * \throw If the mesh in the file is not an unstructured one.
2254 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2256 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2257 return New(fid,mrs);
2261 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2263 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2266 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2267 throw INTERP_KERNEL::Exception(oss.str().c_str());
2270 MEDCoupling::MEDCouplingMeshType meshType;
2272 MEDCoupling::MEDCouplingAxisType dummy3;
2273 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2274 return T::New(fid,ms.front(),dt,it,mrs);
2277 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2279 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2283 * \b WARNING this implementation is dependant from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2284 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2286 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2289 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2290 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2291 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2292 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2294 m2D->setCoords(m3D->getCoords());
2295 ret->setMeshAtLevel(0,m3D);
2296 ret->setMeshAtLevel(-1,m2D);
2297 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2302 * Returns an empty instance of MEDFileUMesh.
2303 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2304 * mesh using decrRef() as it is no more needed.
2306 MEDFileUMesh *MEDFileUMesh::New()
2308 return new MEDFileUMesh;
2312 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2313 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2314 * \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.
2315 * 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
2316 * at most the memory consumtion.
2318 * \param [in] fileName - the name of the file.
2319 * \param [in] mName - the name of the mesh to be read.
2320 * \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.
2321 * \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.
2322 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2323 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2324 * \param [in] mrs - the request for what to be loaded.
2325 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2327 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)
2329 MEDFileUtilities::CheckFileForRead(fileName);
2330 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2331 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2335 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2336 * This method is \b NOT wrapped into python.
2338 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)
2340 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2341 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2345 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2347 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2348 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>));
2352 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2354 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2355 ret.push_back((const DataArrayDouble*)_coords);
2356 ret.push_back((const DataArrayInt *)_fam_coords);
2357 ret.push_back((const DataArrayInt *)_num_coords);
2358 ret.push_back((const DataArrayInt *)_rev_num_coords);
2359 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2360 ret.push_back((const PartDefinition *)_part_coords);
2361 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2362 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2366 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2368 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2372 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2374 return new MEDFileUMesh;
2377 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2379 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2380 ret->deepCpyEquivalences(*this);
2381 if((const DataArrayDouble*)_coords)
2382 ret->_coords=_coords->deepCopy();
2383 if((const DataArrayInt*)_fam_coords)
2384 ret->_fam_coords=_fam_coords->deepCopy();
2385 if((const DataArrayInt*)_num_coords)
2386 ret->_num_coords=_num_coords->deepCopy();
2387 if((const DataArrayInt*)_rev_num_coords)
2388 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2389 if((const DataArrayAsciiChar*)_name_coords)
2390 ret->_name_coords=_name_coords->deepCopy();
2392 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2394 if((const MEDFileUMeshSplitL1 *)(*it))
2395 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2397 if((const PartDefinition*)_part_coords)
2398 ret->_part_coords=_part_coords->deepCopy();
2403 * Checks if \a this and another mesh are equal.
2404 * \param [in] other - the mesh to compare with.
2405 * \param [in] eps - a precision used to compare real values.
2406 * \param [in,out] what - the string returning description of unequal data.
2407 * \return bool - \c true if the meshes are equal, \c false, else.
2409 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2411 if(!MEDFileMesh::isEqual(other,eps,what))
2413 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2416 what="Mesh types differ ! This is unstructured and other is NOT !";
2419 clearNonDiscrAttributes();
2420 otherC->clearNonDiscrAttributes();
2421 const DataArrayDouble *coo1=_coords;
2422 const DataArrayDouble *coo2=otherC->_coords;
2423 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2425 what="Mismatch of coordinates ! One is defined and not other !";
2430 bool ret=coo1->isEqual(*coo2,eps);
2433 what="Coords differ !";
2437 const DataArrayInt *famc1=_fam_coords;
2438 const DataArrayInt *famc2=otherC->_fam_coords;
2439 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2441 what="Mismatch of families arr on nodes ! One is defined and not other !";
2446 bool ret=famc1->isEqual(*famc2);
2449 what="Families arr on node differ !";
2453 const DataArrayInt *numc1=_num_coords;
2454 const DataArrayInt *numc2=otherC->_num_coords;
2455 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2457 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2462 bool ret=numc1->isEqual(*numc2);
2465 what="Numbering arr on node differ !";
2469 const DataArrayAsciiChar *namec1=_name_coords;
2470 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2471 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2473 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2478 bool ret=namec1->isEqual(*namec2);
2481 what="Names arr on node differ !";
2485 if(_ms.size()!=otherC->_ms.size())
2487 what="Number of levels differs !";
2490 std::size_t sz=_ms.size();
2491 for(std::size_t i=0;i<sz;i++)
2493 const MEDFileUMeshSplitL1 *s1=_ms[i];
2494 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2495 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2497 what="Mismatch of presence of sub levels !";
2502 bool ret=s1->isEqual(s2,eps,what);
2507 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2510 if((!pd0 && pd1) || (pd0 && !pd1))
2512 what=std::string("node part def is defined only for one among this or other !");
2515 return pd0->isEqual(pd1,what);
2519 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2520 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2521 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2522 * \throw if internal family array is inconsistent
2523 * \sa checkSMESHConsistency()
2525 void MEDFileUMesh::checkConsistency() const
2527 if(!_coords || !_coords->isAllocated())
2530 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2532 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2533 if (!_num_coords || !_rev_num_coords)
2534 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2538 int nbCoo = _coords->getNumberOfTuples();
2540 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2543 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2545 int maxValue=_num_coords->getMaxValue(pos);
2546 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2547 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2549 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2550 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2551 if (_num_coords && !_num_coords->hasUniqueValues())
2552 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2554 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2555 // Now sub part check:
2556 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2557 it != _ms.end(); it++)
2558 (*it)->checkConsistency();
2563 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2564 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2565 * entities as it likes), or non overlapping between all sub-levels.
2566 * \throw if the condition above is not respected
2568 void MEDFileUMesh::checkSMESHConsistency() const
2571 // For all sub-levels, numbering is either always null or with void intersection:
2574 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2575 std::vector< const DataArrayInt * > v;
2576 bool voidOrNot = ((*it)->_num == 0);
2577 for (it++; it != _ms.end(); it++)
2578 if( ((*it)->_num == 0) != voidOrNot )
2579 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2580 else if (!voidOrNot)
2581 v.push_back((*it)->_num);
2584 // don't forget the 1st one:
2585 v.push_back(_ms[0]->_num);
2586 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2587 if (inter->getNumberOfTuples())
2588 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2594 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2595 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2597 void MEDFileUMesh::clearNodeAndCellNumbers()
2600 _rev_num_coords = 0;
2601 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
2602 it != _ms.end(); it++)
2605 (*it)->_rev_num = 0;
2610 * Clears redundant attributes of incorporated data arrays.
2612 void MEDFileUMesh::clearNonDiscrAttributes() const
2614 MEDFileMesh::clearNonDiscrAttributes();
2615 const DataArrayDouble *coo1=_coords;
2617 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2618 const DataArrayInt *famc1=_fam_coords;
2620 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2621 const DataArrayInt *numc1=_num_coords;
2623 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2624 const DataArrayAsciiChar *namc1=_name_coords;
2626 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2627 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2629 const MEDFileUMeshSplitL1 *tmp=(*it);
2631 tmp->clearNonDiscrAttributes();
2635 void MEDFileUMesh::setName(const std::string& name)
2637 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2638 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2639 (*it)->setName(name);
2640 MEDFileMesh::setName(name);
2643 MEDFileUMesh::MEDFileUMesh()
2647 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2650 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2652 catch(INTERP_KERNEL::Exception& e)
2658 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2659 * See MEDFileUMesh::LoadPartOf for detailed description.
2663 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)
2665 MEDFileUMeshL2 loaderl2;
2666 MEDCoupling::MEDCouplingMeshType meshType;
2669 MEDCoupling::MEDCouplingAxisType dummy3;
2670 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2671 if(meshType!=UNSTRUCTURED)
2673 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2674 throw INTERP_KERNEL::Exception(oss.str().c_str());
2676 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2677 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2681 * \brief Write joints in a file
2683 void MEDFileMesh::writeJoints(med_idt fid) const
2685 if ( _joints.isNotNull() )
2686 _joints->writeLL(fid);
2690 * \brief Load joints in a file or use provided ones
2692 //================================================================================
2694 * \brief Load joints in a file or use provided ones
2695 * \param [in] fid - MED file descriptor
2696 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2697 * Usually this joints are those just read by another iteration
2698 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2700 //================================================================================
2702 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2704 if ( toUseInstedOfReading )
2705 setJoints( toUseInstedOfReading );
2707 _joints = MEDFileJoints::New( fid, _name );
2710 void MEDFileMesh::loadEquivalences(med_idt fid)
2712 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2714 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2717 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2719 const MEDFileEquivalences *equiv(other._equiv);
2721 _equiv=equiv->deepCopy(this);
2724 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2726 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2727 if(!thisEq && !otherEq)
2729 if(thisEq && otherEq)
2730 return thisEq->isEqual(otherEq,what);
2733 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2738 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2740 const MEDFileEquivalences *equiv(_equiv);
2743 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2744 _equiv->getRepr(oss);
2747 void MEDFileMesh::checkCartesian() const
2749 if(getAxisType()!=AX_CART)
2751 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()) << ").";
2752 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2753 oss << " - call setAxisType(AX_CART)" << std::endl;
2754 oss << " - call cartesianize()";
2755 throw INTERP_KERNEL::Exception(oss.str().c_str());
2760 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2762 int MEDFileMesh::getNumberOfJoints() const
2764 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2768 * \brief Return joints with all adjacent mesh domains
2770 MEDFileJoints * MEDFileMesh::getJoints() const
2772 return const_cast<MEDFileJoints*>(& (*_joints));
2775 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2777 if ( joints != _joints )
2786 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2788 * \sa loadPartUMeshFromFile
2790 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2792 MEDFileUMeshL2 loaderl2;
2793 MEDCoupling::MEDCouplingMeshType meshType;
2796 MEDCoupling::MEDCouplingAxisType axType;
2797 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2798 setAxisType(axType);
2799 if(meshType!=UNSTRUCTURED)
2801 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2802 throw INTERP_KERNEL::Exception(oss.str().c_str());
2804 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2805 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2808 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2810 int lev=loaderl2.getNumberOfLevels();
2812 for(int i=0;i<lev;i++)
2814 if(!loaderl2.emptyLev(i))
2815 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2819 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2821 setName(loaderl2.getName());
2822 setDescription(loaderl2.getDescription());
2823 setUnivName(loaderl2.getUnivName());
2824 setIteration(loaderl2.getIteration());
2825 setOrder(loaderl2.getOrder());
2826 setTimeValue(loaderl2.getTime());
2827 setTimeUnit(loaderl2.getTimeUnit());
2828 _coords=loaderl2.getCoords();
2829 if(!mrs || mrs->isNodeFamilyFieldReading())
2830 _fam_coords=loaderl2.getCoordsFamily();
2831 if(!mrs || mrs->isNodeNumFieldReading())
2832 _num_coords=loaderl2.getCoordsNum();
2833 if(!mrs || mrs->isNodeNameFieldReading())
2834 _name_coords=loaderl2.getCoordsName();
2835 _part_coords=loaderl2.getPartDefOfCoo();
2839 MEDFileUMesh::~MEDFileUMesh()
2843 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2845 const DataArrayDouble *coo=_coords;
2846 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2847 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2848 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2849 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2850 int spaceDim=coo?coo->getNumberOfComponents():0;
2853 mdim=getMeshDimension();
2854 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2855 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2856 for(int i=0;i<spaceDim;i++)
2858 std::string info=coo->getInfoOnComponent(i);
2860 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2861 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
2862 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
2864 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2866 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2867 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2868 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2869 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2870 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2871 (*it)->write(fid,meshName,mdim);
2872 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2876 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2877 * \return std::vector<int> - a sequence of the relative dimensions.
2879 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2881 std::vector<int> ret;
2883 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2884 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2891 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2892 * \return std::vector<int> - a sequence of the relative dimensions.
2894 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2896 std::vector<int> ret0=getNonEmptyLevels();
2897 if((const DataArrayDouble *) _coords)
2899 std::vector<int> ret(ret0.size()+1);
2901 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2907 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2909 std::vector<int> ret;
2910 const DataArrayInt *famCoo(_fam_coords);
2914 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2916 const MEDFileUMeshSplitL1 *cur(*it);
2918 if(cur->getFamilyField())
2924 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2926 std::vector<int> ret;
2927 const DataArrayInt *numCoo(_num_coords);
2931 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2933 const MEDFileUMeshSplitL1 *cur(*it);
2935 if(cur->getNumberField())
2941 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2943 std::vector<int> ret;
2944 const DataArrayAsciiChar *nameCoo(_name_coords);
2948 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2950 const MEDFileUMeshSplitL1 *cur(*it);
2952 if(cur->getNameField())
2959 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2960 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2961 * \param [in] fams - the name of the family of interest.
2962 * \return std::vector<int> - a sequence of the relative dimensions.
2964 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2966 std::vector<int> ret;
2967 std::vector<int> levs(getNonEmptyLevels());
2968 std::vector<int> famIds(getFamiliesIds(fams));
2969 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2970 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2976 * Returns all relative mesh levels (including nodes) where given families are defined.
2977 * \param [in] fams - the names of the families of interest.
2978 * \return std::vector<int> - a sequence of the relative dimensions.
2980 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2982 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2983 const DataArrayInt *famCoords(_fam_coords);
2986 std::vector<int> famIds(getFamiliesIds(fams));
2987 if(famCoords->presenceOfValue(famIds))
2989 std::vector<int> ret(ret0.size()+1);
2991 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2998 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3000 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3001 if((const DataArrayInt *)_fam_coords)
3003 int val=_fam_coords->getMaxValue(tmp);
3004 ret=std::max(ret,std::abs(val));
3006 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3008 if((const MEDFileUMeshSplitL1 *)(*it))
3010 const DataArrayInt *da=(*it)->getFamilyField();
3013 int val=da->getMaxValue(tmp);
3014 ret=std::max(ret,std::abs(val));
3021 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3023 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3024 if((const DataArrayInt *)_fam_coords)
3026 int val=_fam_coords->getMaxValue(tmp);
3027 ret=std::max(ret,val);
3029 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3031 if((const MEDFileUMeshSplitL1 *)(*it))
3033 const DataArrayInt *da=(*it)->getFamilyField();
3036 int val=da->getMaxValue(tmp);
3037 ret=std::max(ret,val);
3044 int MEDFileUMesh::getMinFamilyIdInArrays() const
3046 int ret=std::numeric_limits<int>::max(),tmp=-1;
3047 if((const DataArrayInt *)_fam_coords)
3049 int val=_fam_coords->getMinValue(tmp);
3050 ret=std::min(ret,val);
3052 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3054 if((const MEDFileUMeshSplitL1 *)(*it))
3056 const DataArrayInt *da=(*it)->getFamilyField();
3059 int val=da->getMinValue(tmp);
3060 ret=std::min(ret,val);
3068 * Returns the dimension on cells in \a this mesh.
3069 * \return int - the mesh dimension.
3070 * \throw If there are no cells in this mesh.
3072 int MEDFileUMesh::getMeshDimension() const
3075 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3076 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3077 return (*it)->getMeshDimension()+lev;
3078 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3082 * Returns the space dimension of \a this mesh that is equal to number of components in
3083 * the node coordinates array.
3084 * \return int - the space dimension of \a this mesh.
3085 * \throw If the node coordinates array is not available.
3087 int MEDFileUMesh::getSpaceDimension() const
3089 const DataArrayDouble *coo=_coords;
3091 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3092 return coo->getNumberOfComponents();
3096 * Returns a string describing \a this mesh.
3097 * \return std::string - the mesh information string.
3099 std::string MEDFileUMesh::simpleRepr() const
3101 std::ostringstream oss;
3102 oss << MEDFileMesh::simpleRepr();
3103 const DataArrayDouble *coo=_coords;
3104 oss << "- The dimension of the space is ";
3105 static const char MSG1[]= "*** NO COORDS SET ***";
3106 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3108 oss << _coords->getNumberOfComponents() << std::endl;
3110 oss << MSG1 << std::endl;
3111 oss << "- Type of the mesh : UNSTRUCTURED\n";
3112 oss << "- Number of nodes : ";
3114 oss << _coords->getNumberOfTuples() << std::endl;
3116 oss << MSG1 << std::endl;
3117 std::size_t nbOfLev=_ms.size();
3118 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3119 for(std::size_t i=0;i<nbOfLev;i++)
3121 const MEDFileUMeshSplitL1 *lev=_ms[i];
3122 oss << " - Level #" << -((int) i) << " has dimension : ";
3125 oss << lev->getMeshDimension() << std::endl;
3126 lev->simpleRepr(oss);
3129 oss << MSG2 << std::endl;
3131 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3134 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3135 oss << "- Names of coordinates :" << std::endl;
3136 std::vector<std::string> vars=coo->getVarsOnComponent();
3137 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3138 oss << std::endl << "- Units of coordinates : " << std::endl;
3139 std::vector<std::string> units=coo->getUnitsOnComponent();
3140 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3142 oss << std::endl << std::endl;
3144 getEquivalencesRepr(oss);
3149 * Returns a full textual description of \a this mesh.
3150 * \return std::string - the string holding the mesh description.
3152 std::string MEDFileUMesh::advancedRepr() const
3154 return simpleRepr();
3158 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3159 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3160 * \return int - the number of entities.
3161 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3163 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3165 if(meshDimRelToMaxExt==1)
3167 if(!((const DataArrayDouble *)_coords))
3168 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3169 return _coords->getNumberOfTuples();
3171 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3175 * Returns the family field for mesh entities of a given dimension.
3176 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3177 * \return const DataArrayInt * - the family field. It is an array of ids of families
3178 * each mesh entity belongs to. It can be \c NULL.
3180 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3182 if(meshDimRelToMaxExt==1)
3184 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3185 return l1->getFamilyField();
3188 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3190 if(meshDimRelToMaxExt==1)
3192 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3193 return l1->getFamilyField();
3197 * Returns the optional numbers of mesh entities of a given dimension.
3198 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3199 * \return const DataArrayInt * - the array of the entity numbers.
3200 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3202 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3204 if(meshDimRelToMaxExt==1)
3206 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3207 return l1->getNumberField();
3210 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3212 if(meshDimRelToMaxExt==1)
3213 return _name_coords;
3214 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3215 return l1->getNameField();
3219 * 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).
3221 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3222 * \param [in] gt - The input geometric type for which the part definition is requested.
3223 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3225 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3227 if(meshDimRelToMaxExt==1)
3228 return _part_coords;
3229 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3230 return l1->getPartDef(gt);
3233 int MEDFileUMesh::getNumberOfNodes() const
3235 const DataArrayDouble *coo(_coords);
3237 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3238 return coo->getNumberOfTuples();
3241 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3243 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3244 return l1->getNumberOfCells();
3247 bool MEDFileUMesh::hasImplicitPart() const
3252 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3254 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3257 void MEDFileUMesh::releaseImplicitPartIfAny() const
3261 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3263 std::size_t sz(st.getNumberOfItems());
3264 for(std::size_t i=0;i<sz;i++)
3266 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3267 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3268 if(st[i].getPflName().empty())
3269 m->computeNodeIdsAlg(nodesFetched);
3272 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3273 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3274 m2->computeNodeIdsAlg(nodesFetched);
3279 MEDFileMesh *MEDFileUMesh::cartesianize() const
3281 if(getAxisType()==AX_CART)
3284 return const_cast<MEDFileUMesh *>(this);
3288 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3289 const DataArrayDouble *coords(_coords);
3291 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3292 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3293 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3294 if((const MEDFileUMeshSplitL1 *)(*it))
3295 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3296 ret->_coords=coordsCart;
3297 ret->setAxisType(AX_CART);
3303 * Returns the optional numbers of mesh entities of a given dimension transformed using
3304 * DataArrayInt::invertArrayN2O2O2N().
3305 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3306 * \return const DataArrayInt * - the array of the entity numbers transformed using
3307 * DataArrayInt::invertArrayN2O2O2N().
3308 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3310 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3312 if(meshDimRelToMaxExt==1)
3314 if(!((const DataArrayInt *)_num_coords))
3315 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3316 return _rev_num_coords;
3318 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3319 return l1->getRevNumberField();
3323 * Returns a pointer to the node coordinates array of \a this mesh \b without
3324 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3326 DataArrayDouble *MEDFileUMesh::getCoords() const
3329 MCAuto<DataArrayDouble> tmp(_coords);
3330 if((DataArrayDouble *)tmp)
3338 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3339 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3341 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3342 * \param [in] grp - the name of the group whose mesh entities are included in the
3344 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3345 * according to the optional numbers of entities, if available.
3346 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3347 * delete this mesh using decrRef() as it is no more needed.
3348 * \throw If the name of a nonexistent group is specified.
3349 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3351 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3354 synchronizeTinyInfoOnLeaves();
3355 std::vector<std::string> tmp(1);
3357 return getGroups(meshDimRelToMaxExt,tmp,renum);
3361 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3362 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3364 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3365 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3367 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3368 * according to the optional numbers of entities, if available.
3369 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3370 * delete this mesh using decrRef() as it is no more needed.
3371 * \throw If a name of a nonexistent group is present in \a grps.
3372 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3374 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3377 synchronizeTinyInfoOnLeaves();
3378 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3379 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3380 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3381 zeRet->setName(grps[0]);
3382 return zeRet.retn();
3386 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3387 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3389 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3390 * \param [in] fam - the name of the family whose mesh entities are included in the
3392 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3393 * according to the optional numbers of entities, if available.
3394 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3395 * delete this mesh using decrRef() as it is no more needed.
3396 * \throw If a name of a nonexistent family is present in \a grps.
3397 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3399 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3402 synchronizeTinyInfoOnLeaves();
3403 std::vector<std::string> tmp(1);
3405 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3409 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3410 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3412 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3413 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3415 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3416 * according to the optional numbers of entities, if available.
3417 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3418 * delete this mesh using decrRef() as it is no more needed.
3419 * \throw If a name of a nonexistent family is present in \a fams.
3420 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3422 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3425 synchronizeTinyInfoOnLeaves();
3426 if(meshDimRelToMaxExt==1)
3428 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3429 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3430 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3434 std::vector<int> famIds=getFamiliesIds(fams);
3435 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3436 MCAuto<MEDCouplingUMesh> zeRet;
3438 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3440 zeRet=l1->getFamilyPart(0,0,renum);
3441 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3442 zeRet->setName(fams[0]);
3443 return zeRet.retn();
3447 * Returns ids of mesh entities contained in given families of a given dimension.
3448 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3450 * \param [in] fams - the names of the families of interest.
3451 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3452 * returned instead of ids.
3453 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3454 * numbers, if available and required, of mesh entities of the families. The caller
3455 * is to delete this array using decrRef() as it is no more needed.
3456 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3458 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3460 std::vector<int> famIds=getFamiliesIds(fams);
3461 if(meshDimRelToMaxExt==1)
3463 if((const DataArrayInt *)_fam_coords)
3465 MCAuto<DataArrayInt> da;
3467 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3469 da=_fam_coords->findIdsEqualList(0,0);
3471 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3476 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3478 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3480 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3482 return l1->getFamilyPartArr(0,0,renum);
3486 * Returns a MEDCouplingUMesh of a given relative dimension.
3487 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3488 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3489 * To build a valid MEDCouplingUMesh from the returned one in this case,
3490 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3491 * \param [in] meshDimRelToMax - the relative dimension of interest.
3492 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3493 * optional numbers of mesh entities.
3494 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3495 * delete using decrRef() as it is no more needed.
3496 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3498 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3501 synchronizeTinyInfoOnLeaves();
3502 if(meshDimRelToMaxExt==1)
3506 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3507 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3508 umesh->setCoords(cc);
3509 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3510 umesh->setName(getName());
3514 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3515 return l1->getWholeMesh(renum);
3518 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3520 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3521 return l1->getDistributionOfTypes();
3525 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3526 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3527 * optional numbers of mesh entities.
3528 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3529 * delete using decrRef() as it is no more needed.
3530 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3532 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3534 return getMeshAtLevel(0,renum);
3538 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3539 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3540 * optional numbers of mesh entities.
3541 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3542 * delete using decrRef() as it is no more needed.
3543 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3545 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3547 return getMeshAtLevel(-1,renum);
3551 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3552 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3553 * optional numbers of mesh entities.
3554 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3555 * delete using decrRef() as it is no more needed.
3556 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3558 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3560 return getMeshAtLevel(-2,renum);
3564 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3565 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3566 * optional numbers of mesh entities.
3567 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3568 * delete using decrRef() as it is no more needed.
3569 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3571 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3573 return getMeshAtLevel(-3,renum);
3577 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3578 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3579 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3580 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3582 void MEDFileUMesh::forceComputationOfParts() const
3584 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3586 const MEDFileUMeshSplitL1 *elt(*it);
3588 elt->forceComputationOfParts();
3593 * This method returns a vector of mesh parts containing each exactly one geometric type.
3594 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3595 * This method is only for memory aware users.
3596 * The returned pointers are **NOT** new object pointer. No need to mange them.
3598 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3601 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3602 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3606 * This method returns the part of \a this having the geometric type \a gt.
3607 * If such part is not existing an exception will be thrown.
3608 * The returned pointer is **NOT** new object pointer. No need to mange it.
3610 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3613 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3614 int lev=(int)cm.getDimension()-getMeshDimension();
3615 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3616 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3620 * This method returns for each geo types in \a this number of cells with this geo type.
3621 * 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.
3622 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3624 * \sa getDistributionOfTypes
3626 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3628 std::vector< std::pair<int,int> > ret;
3629 std::vector<int> nel(getNonEmptyLevels());
3630 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3632 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3633 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3635 int nbCells(getNumberOfCellsWithType(*it1));
3636 ret.push_back(std::pair<int,int>(*it1,nbCells));
3639 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3644 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3645 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3647 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3649 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3650 return sp->getGeoTypes();
3653 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3655 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3656 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3657 return sp->getNumberOfCellsWithType(ct);
3661 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3662 * \param [in] gt - the geometric type for which the family field is asked.
3663 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3664 * delete using decrRef() as it is no more needed.
3665 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3667 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3669 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3670 int lev=(int)cm.getDimension()-getMeshDimension();
3671 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3672 return sp->extractFamilyFieldOnGeoType(gt);
3676 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3677 * \param [in] gt - the geometric type for which the number field is asked.
3678 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3679 * delete using decrRef() as it is no more needed.
3680 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3682 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3684 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3685 int lev=(int)cm.getDimension()-getMeshDimension();
3686 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3687 return sp->extractNumberFieldOnGeoType(gt);
3691 * This method returns for specified geometric type \a gt the relative level to \a this.
3692 * If the relative level is empty an exception will be thrown.
3694 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3696 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3697 int ret((int)cm.getDimension()-getMeshDimension());
3698 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3702 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3704 if(meshDimRelToMaxExt==1)
3705 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3706 if(meshDimRelToMaxExt>1)
3707 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3708 int tracucedRk=-meshDimRelToMaxExt;
3709 if(tracucedRk>=(int)_ms.size())
3710 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3711 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3712 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3713 return _ms[tracucedRk];
3716 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3718 if(meshDimRelToMaxExt==1)
3719 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3720 if(meshDimRelToMaxExt>1)
3721 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3722 int tracucedRk=-meshDimRelToMaxExt;
3723 if(tracucedRk>=(int)_ms.size())
3724 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3725 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3726 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3727 return _ms[tracucedRk];
3730 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3732 if(-meshDimRelToMax>=(int)_ms.size())
3733 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3735 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3737 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3739 int ref=(*it)->getMeshDimension();
3740 if(ref+i!=meshDim-meshDimRelToMax)
3741 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3747 * Sets the node coordinates array of \a this mesh.
3748 * \param [in] coords - the new node coordinates array.
3749 * \throw If \a coords == \c NULL.
3751 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3754 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3755 if(coords==(DataArrayDouble *)_coords)
3757 coords->checkAllocated();
3758 int nbOfTuples(coords->getNumberOfTuples());
3761 _fam_coords=DataArrayInt::New();
3762 _fam_coords->alloc(nbOfTuples,1);
3763 _fam_coords->fillWithZero();
3764 _num_coords=0; _rev_num_coords=0; _name_coords=0;
3765 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3766 if((MEDFileUMeshSplitL1 *)(*it))
3767 (*it)->setCoords(coords);
3771 * Change coords without changing anything concerning families and numbering on nodes.
3773 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3776 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3777 if(coords==(DataArrayDouble *)_coords)
3779 coords->checkAllocated();
3780 int nbOfTuples(coords->getNumberOfTuples());
3781 if(_coords.isNull())
3788 int oldNbTuples(_coords->getNumberOfTuples());
3789 if(oldNbTuples!=nbOfTuples)
3790 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3794 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3795 if((MEDFileUMeshSplitL1 *)(*it))
3796 (*it)->setCoords(coords);
3800 * Removes all groups of a given dimension in \a this mesh.
3801 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3802 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3804 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3806 if(meshDimRelToMaxExt==1)
3808 if((DataArrayInt *)_fam_coords)
3809 _fam_coords->fillWithZero();
3812 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3813 l1->eraseFamilyField();
3818 * Removes all families with ids not present in the family fields of \a this mesh.
3820 void MEDFileUMesh::optimizeFamilies()
3822 std::vector<int> levs=getNonEmptyLevelsExt();
3823 std::set<int> allFamsIds;
3824 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3826 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3827 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3829 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3832 std::set<std::string> famNamesToKill;
3833 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3835 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3836 famNamesToKill.insert((*it).first);
3838 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3839 _families.erase(*it);
3840 std::vector<std::string> grpNamesToKill;
3841 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3843 std::vector<std::string> tmp;
3844 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3846 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3847 tmp.push_back(*it2);
3852 tmp.push_back((*it).first);
3854 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3859 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3860 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3861 * The boundary is built according to the following method:
3862 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3863 * coordinates array is extended).
3864 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3865 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3866 * might not be duplicated at all.
3867 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3868 * other side of the group is no more a neighbor)
3869 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3870 * bordering the newly created boundary use the newly computed nodes.
3871 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3872 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3874 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3875 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3877 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3878 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3879 * \sa clearNodeAndCellNumbers()
3881 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3882 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3884 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3885 typedef MCAuto<DataArrayInt> DAInt;
3887 std::vector<int> levs=getNonEmptyLevels();
3888 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3889 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3890 MUMesh m0=getMeshAtLevel(0);
3891 MUMesh m1=getMeshAtLevel(-1);
3892 int nbNodes=m0->getNumberOfNodes();
3893 MUMesh m11=getGroup(-1,grpNameM1);
3894 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3895 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3896 DAInt nodeIdsToDuplicate(tmp00);
3897 DAInt cellsToModifyConn0(tmp11);
3898 DAInt cellsToModifyConn1(tmp22);
3899 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3900 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3901 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3902 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3903 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3904 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3905 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3906 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3907 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3908 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3909 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3910 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3911 DAInt grpIds=getGroupArr(-1,grpNameM1);
3912 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3913 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3914 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3915 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3916 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3917 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3918 m0->setCoords(tmp0->getCoords());
3919 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3920 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3921 m1->setCoords(m0->getCoords());
3922 _coords=m0->getCoords(); _coords->incrRef();
3923 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3924 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3925 DataArrayInt * duplCells;
3926 m1->areCellsIncludedIn(m11, 0, duplCells);
3927 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3928 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3929 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3930 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3931 DAInt szOfCellGrpOfSameType(tmp00);
3932 DAInt idInMsOfCellGrpOfSameType(tmp11);
3934 newm1->setName(getName());
3935 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3937 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3938 DAInt newFam=DataArrayInt::New();
3939 newFam->alloc(newm1->getNumberOfCells(),1);
3940 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3941 // Positive ID for family of nodes, negative for all the rest.
3943 if (m1->getMeshDimension() == 0)
3944 idd=getMaxFamilyId()+1;
3946 idd=getMinFamilyId()-1;
3947 int globStart=0,start=0,end,globEnd;
3948 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3949 for(int i=0;i<nbOfChunks;i++)
3951 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3952 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3954 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3955 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
3956 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3961 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3965 newm1->setCoords(getCoords());
3966 setMeshAtLevel(-1,newm1);
3967 setFamilyFieldArr(-1,newFam);
3968 std::string grpName2(grpNameM1); grpName2+="_dup";
3969 addFamily(grpName2,idd);
3970 addFamilyOnGrp(grpName2,grpName2);
3975 int newNbOfNodes=getCoords()->getNumberOfTuples();
3976 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3977 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3978 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3983 _rev_num_coords = 0;
3984 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
3985 it != _ms.end(); it++)
3988 (*it)->_rev_num = 0;
3990 nodesDuplicated=nodeIdsToDuplicate.retn();
3991 cellsModified=cellsToModifyConn0.retn();
3992 cellsNotModified=cellsToModifyConn1.retn();
3995 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
3996 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
3999 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4000 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4001 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4003 * \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.
4004 * 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.
4006 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4008 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4009 std::vector<int> levs=getNonEmptyLevels();
4011 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4012 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4015 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4017 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4018 std::vector<int> code1=m->getDistributionOfTypes();
4019 end=PutInThirdComponentOfCodeOffset(code1,start);
4020 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4021 bool hasChanged=m->unPolyze();
4022 DataArrayInt *fake=0;
4023 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4024 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4026 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4029 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4030 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4032 MCAuto<DataArrayInt> famField2,numField2;
4033 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4034 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4035 setMeshAtLevel(*it,m);
4036 std::vector<int> code2=m->getDistributionOfTypes();
4037 end=PutInThirdComponentOfCodeOffset(code2,start);
4038 newCode.insert(newCode.end(),code2.begin(),code2.end());
4040 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4044 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4045 setFamilyFieldArr(*it,newFamField);
4049 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4050 setRenumFieldArr(*it,newNumField);
4055 newCode.insert(newCode.end(),code1.begin(),code1.end());
4061 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4062 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4063 o2nRenumCell=o2nRenumCellRet.retn();
4068 /*! \cond HIDDEN_ITEMS */
4069 struct MEDLoaderAccVisit1
4071 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4072 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4073 int _new_nb_of_nodes;
4078 * 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.
4079 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4080 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4081 * -1 values in returned array means that the corresponding old node is no more used.
4083 * \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
4084 * is modified in \a this.
4085 * \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
4088 DataArrayInt *MEDFileUMesh::zipCoords()
4090 const DataArrayDouble *coo(getCoords());
4092 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4093 int nbOfNodes(coo->getNumberOfTuples());
4094 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4095 std::vector<int> neLevs(getNonEmptyLevels());
4096 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4098 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4099 if(zeLev->isMeshStoredSplitByType())
4101 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4102 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4104 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4108 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4109 mesh->computeNodeIdsAlg(nodeIdsInUse);
4112 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4113 if(nbrOfNodesInUse==nbOfNodes)
4114 return 0;//no need to update _part_coords
4115 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4116 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4117 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4118 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4119 MCAuto<DataArrayInt> newFamCoords;
4120 MCAuto<DataArrayAsciiChar> newNameCoords;
4121 if((const DataArrayInt *)_fam_coords)
4122 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4123 MCAuto<DataArrayInt> newNumCoords;
4124 if((const DataArrayInt *)_num_coords)
4125 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4126 if((const DataArrayAsciiChar *)_name_coords)
4127 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4128 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
4129 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4131 if((MEDFileUMeshSplitL1*)*it)
4133 (*it)->renumberNodesInConn(ret->begin());
4134 (*it)->setCoords(_coords);
4137 // updates _part_coords
4138 const PartDefinition *pc(_part_coords);
4141 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4142 _part_coords=tmpPD->composeWith(pc);
4148 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4149 * The extraction of \a this is specified by the extractDef \a input map.
4150 * This map tells for each level of cells, the cells kept in the extraction.
4152 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4153 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4155 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4157 std::vector<int> levs(getNonEmptyLevels());
4158 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4159 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4162 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4163 if((*it).second.isNull())
4164 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4167 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4169 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4170 throw INTERP_KERNEL::Exception(oss.str());
4172 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4173 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4174 mPart->computeNodeIdsAlg(fetchedNodes);
4176 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4180 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4182 * \return - a new reference of MEDFileUMesh
4183 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4185 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4187 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4188 std::vector<int> levs(getNonEmptyLevels());
4189 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4192 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4193 if((*it).second.isNull())
4194 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4197 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4199 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4200 throw INTERP_KERNEL::Exception(oss.str());
4202 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4203 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4204 ret->setMeshAtLevel((*it).first,mPart);
4205 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4208 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4209 ret->setFamilyFieldArr((*it).first,famPart);
4213 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4214 ret->setFamilyFieldArr((*it).first,numPart);
4217 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4218 if(it2!=extractDef.end())
4220 const DataArrayDouble *coo(ret->getCoords());
4222 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4223 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4224 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4225 ret->setCoords(cooPart);
4226 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4229 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4230 ret->setFamilyFieldArr(1,famPart);
4234 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4235 ret->setFamilyFieldArr(1,numPart);
4237 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4241 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4242 m->renumberNodesInConn(o2nNodes->begin());
4243 ret->setMeshAtLevel((*it3).first,m);
4250 * This method performs an extrusion along a path defined by \a m1D.
4251 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4252 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4253 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4254 * This method scans all levels in \a this
4255 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4257 * \param [in] m1D - the mesh defining the extrusion path.
4258 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4259 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4261 * \sa MEDCouplingUMesh::buildExtrudedMesh
4263 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4266 if(getMeshDimension()!=2)
4267 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4268 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4269 m1D->checkConsistencyLight();
4270 if(m1D->getMeshDimension()!=1)
4271 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4272 int nbRep(m1D->getNumberOfCells());
4273 std::vector<int> levs(getNonEmptyLevels());
4274 std::vector<std::string> grps(getGroupsNames());
4275 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4276 DataArrayDouble *coords(0);
4277 std::size_t nbOfLevsOut(levs.size()+1);
4278 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4279 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4281 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4282 item=item->clone(false);
4283 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4284 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4285 tmp->changeSpaceDimension(3+(*lev),0.);
4286 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4287 zeList.push_back(elt);
4289 coords=elt->getCoords();
4292 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4293 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4295 (*it)->setName(getName());
4296 (*it)->setCoords(coords);
4298 for(std::size_t ii=0;ii!=zeList.size();ii++)
4301 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4304 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4305 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4306 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4307 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4308 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4309 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4310 std::vector<const MEDCouplingUMesh *> elts(3);
4311 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4312 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4313 elt->setName(getName());
4316 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4317 ret->setMeshAtLevel(lev,elt);
4319 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4320 endLev=endLev->clone(false); endLev->setCoords(coords);
4321 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4322 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4323 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4324 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4325 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4326 endLev->setName(getName());
4327 ret->setMeshAtLevel(levs.back()-1,endLev);
4329 for(std::size_t ii=0;ii!=zeList.size();ii++)
4332 std::vector< MCAuto<DataArrayInt> > outGrps;
4333 std::vector< const DataArrayInt * > outGrps2;
4336 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4338 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4339 if(!grpArr->empty())
4341 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4342 int offset0(zeList[ii]->getNumberOfCells());
4343 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4344 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4345 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4346 grpArr2->setName(oss.str());
4347 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4348 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4349 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4350 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4355 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4357 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4358 if(!grpArr->empty())
4360 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4361 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4362 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4363 for(int iii=0;iii<nbRep;iii++)
4365 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4366 grpArrs2[iii]=grpArrs[iii];
4368 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4369 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4370 std::ostringstream grpName; grpName << *grp << "_extruded";
4371 grpArrExt->setName(grpName.str());
4372 outGrps.push_back(grpArrExt);
4373 outGrps2.push_back(grpArrExt);
4376 ret->setGroupsAtLevel(lev,outGrps2);
4378 std::vector< MCAuto<DataArrayInt> > outGrps;
4379 std::vector< const DataArrayInt * > outGrps2;
4380 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4382 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4383 if(grpArr1->empty())
4385 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4386 std::ostringstream grpName; grpName << *grp << "_top";
4387 grpArr2->setName(grpName.str());
4388 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4389 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4390 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4392 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4397 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4398 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4399 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4401 * \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
4402 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4403 * \param [in] eps - detection threshold for coordinates.
4404 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4406 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4408 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4411 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4412 int initialNbNodes(getNumberOfNodes());
4413 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4414 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4416 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4418 DataArrayDouble *zeCoords(m0->getCoords());
4419 ret->setMeshAtLevel(0,m0);
4420 std::vector<int> levs(getNonEmptyLevels());
4421 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4424 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4425 ret->setFamilyFieldArr(0,famFieldCpy);
4427 famField=getFamilyFieldAtLevel(1);
4430 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4431 fam->fillWithZero();
4432 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4433 ret->setFamilyFieldArr(1,fam);
4435 ret->copyFamGrpMapsFrom(*this);
4436 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4437 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4441 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4442 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4443 if(m1->getMeshDimension()!=0)
4446 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4447 }//kill unused notUsed var
4448 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4450 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4451 MCAuto<DataArrayInt> bSafe(b);
4454 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4455 throw INTERP_KERNEL::Exception(oss.str().c_str());
4457 b->applyLin(1,initialNbNodes);
4458 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4459 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4460 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4461 m1->renumberNodesInConn(renum->begin());
4463 m1->setCoords(zeCoords);
4464 ret->setMeshAtLevel(*lev,m1);
4465 famField=getFamilyFieldAtLevel(*lev);
4468 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4469 ret->setFamilyFieldArr(*lev,famFieldCpy);
4476 * This method converts all quadratic cells in \a this into linear cells.
4477 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4478 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4480 * \param [in] eps - detection threshold for coordinates.
4481 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4483 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4485 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4488 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4489 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4490 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4491 m0->convertQuadraticCellsToLinear();
4493 DataArrayDouble *zeCoords(m0->getCoords());
4494 ret->setMeshAtLevel(0,m0);
4495 std::vector<int> levs(getNonEmptyLevels());
4496 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4499 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4500 ret->setFamilyFieldArr(0,famFieldCpy);
4502 famField=getFamilyFieldAtLevel(1);
4505 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4506 ret->setFamilyFieldArr(1,fam);
4508 ret->copyFamGrpMapsFrom(*this);
4509 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4513 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4514 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4515 m1->convertQuadraticCellsToLinear();
4518 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4519 MCAuto<DataArrayInt> bSafe(b);
4522 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4523 throw INTERP_KERNEL::Exception(oss.str().c_str());
4525 m1->renumberNodesInConn(b->begin());
4526 m1->setCoords(zeCoords);
4527 ret->setMeshAtLevel(*lev,m1);
4528 famField=getFamilyFieldAtLevel(*lev);
4531 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4532 ret->setFamilyFieldArr(*lev,famFieldCpy);
4539 * Computes the symmetry of \a this.
4540 * \return a new object.
4542 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4544 MCAuto<MEDFileUMesh> ret(deepCopy());
4545 DataArrayDouble *myCoo(getCoords());
4548 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4549 ret->setCoordsForced(newCoo);
4554 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4557 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4558 std::size_t sz(meshes.size()),i(0);
4559 std::vector<const DataArrayDouble *> coos(sz);
4560 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4561 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4564 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4565 coos[i]=(*it)->getCoords();
4566 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4567 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4569 const MEDFileUMesh *ref(meshes[0]);
4570 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4571 std::vector<int> levs(ref->getNonEmptyLevels());
4572 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4573 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4574 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4575 std::map<std::string,int> map1;
4576 std::map<std::string, std::vector<std::string> > map2;
4577 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4579 if((*it)->getSpaceDimension()!=spaceDim)
4580 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4581 if((*it)->getMeshDimension()!=meshDim)
4582 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4583 if((*it)->getNonEmptyLevels()!=levs)
4584 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4585 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4587 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4588 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4589 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4590 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4592 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4593 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4594 map1[(*it3).first]=(*it3).second;
4595 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4596 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4597 map2[(*it4).first]=(*it4).second;
4599 // Easy part : nodes
4600 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4601 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4602 ret->setCoords(coo);
4603 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4605 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4606 ret->setFamilyFieldArr(1,fam_coo);
4608 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4610 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4611 ret->setRenumFieldArr(1,num_coo);
4614 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4616 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4617 if(it2==m_mesh.end())
4618 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4619 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4620 mesh->setCoords(coo); mesh->setName(ref->getName());
4621 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4622 ret->setMeshAtLevel(*it,mesh);
4623 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4624 if(it3!=m_fam.end())
4626 const std::vector<const DataArrayInt *>& fams((*it3).second);
4627 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4629 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4630 famm->renumberInPlace(renum->begin());
4631 ret->setFamilyFieldArr(*it,famm);
4634 if(it4!=m_renum.end())
4636 const std::vector<const DataArrayInt *>& renums((*it4).second);
4637 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4639 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4640 renumm->renumberInPlace(renum->begin());
4641 ret->setRenumFieldArr(*it,renumm);
4646 ret->setFamilyInfo(map1);
4647 ret->setGroupInfo(map2);
4648 ret->setName(ref->getName());
4652 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4654 if(getMeshDimension()!=3)
4655 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4656 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4657 if(m3D.isNull() || m2D.isNull())
4658 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4659 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4660 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4664 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4666 clearNonDiscrAttributes();
4667 forceComputationOfParts();
4668 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4669 std::vector<int> layer0;
4670 layer0.push_back(getAxisType());//0 i
4671 layer0.push_back(_order); //1 i
4672 layer0.push_back(_iteration);//2 i
4673 layer0.push_back(getSpaceDimension());//3 i
4674 tinyDouble.push_back(_time);//0 d
4675 tinyStr.push_back(_name);//0 s
4676 tinyStr.push_back(_desc_name);//1 s
4677 for(int i=0;i<getSpaceDimension();i++)
4678 tinyStr.push_back(_coords->getInfoOnComponent(i));
4679 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4680 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4682 tinyStr.push_back((*it).first);
4683 layer0.push_back((*it).second);
4685 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4686 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4688 layer0.push_back((int)(*it0).second.size());
4689 tinyStr.push_back((*it0).first);
4690 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4691 tinyStr.push_back(*it1);
4693 // sizeof(layer0)==4+aa+1+bb layer#0
4694 bigArrayD=_coords;// 0 bd
4695 bigArraysI.push_back(_fam_coords);// 0 bi
4696 bigArraysI.push_back(_num_coords);// 1 bi
4697 const PartDefinition *pd(_part_coords);
4699 layer0.push_back(-1);
4702 std::vector<int> tmp0;
4703 pd->serialize(tmp0,bigArraysI);
4704 tinyInt.push_back(tmp0.size());
4705 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4708 std::vector<int> layer1;
4709 std::vector<int> levs(getNonEmptyLevels());
4710 layer1.push_back((int)levs.size());// 0 i <- key
4711 layer1.insert(layer1.end(),levs.begin(),levs.end());
4712 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4714 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4715 lev->serialize(layer1,bigArraysI);
4717 // put layers all together.
4718 tinyInt.push_back(layer0.size());
4719 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4720 tinyInt.push_back(layer1.size());
4721 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4724 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4725 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4727 int sz0(tinyInt[0]);
4728 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4729 int sz1(tinyInt[sz0+1]);
4730 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4732 std::reverse(layer0.begin(),layer0.end());
4733 std::reverse(layer1.begin(),layer1.end());
4734 std::reverse(tinyDouble.begin(),tinyDouble.end());
4735 std::reverse(tinyStr.begin(),tinyStr.end());
4736 std::reverse(bigArraysI.begin(),bigArraysI.end());
4738 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4739 _order=layer0.back(); layer0.pop_back();
4740 _iteration=layer0.back(); layer0.pop_back();
4741 int spaceDim(layer0.back()); layer0.pop_back();
4742 _time=tinyDouble.back(); tinyDouble.pop_back();
4743 _name=tinyStr.back(); tinyStr.pop_back();
4744 _desc_name=tinyStr.back(); tinyStr.pop_back();
4745 _coords=bigArrayD; _coords->rearrange(spaceDim);
4746 for(int i=0;i<spaceDim;i++)
4748 _coords->setInfoOnComponent(i,tinyStr.back());
4751 int nbOfFams(layer0.back()); layer0.pop_back();
4753 for(int i=0;i<nbOfFams;i++)
4755 _families[tinyStr.back()]=layer0.back();
4756 tinyStr.pop_back(); layer0.pop_back();
4758 int nbGroups(layer0.back()); layer0.pop_back();
4760 for(int i=0;i<nbGroups;i++)
4762 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4763 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4764 std::vector<std::string> fams(nbOfFamsOnGrp);
4765 for(int j=0;j<nbOfFamsOnGrp;j++)
4767 fams[j]=tinyStr.back(); tinyStr.pop_back();
4769 _groups[grpName]=fams;
4771 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4772 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4774 int isPd(layer0.back()); layer0.pop_back();
4777 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4778 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4779 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4782 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4784 int nbLevs(layer1.back()); layer1.pop_back();
4785 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4787 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4788 _ms.resize(maxLev+1);
4789 for(int i=0;i<nbLevs;i++)
4793 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4798 * Adds a group of nodes to \a this mesh.
4799 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4800 * The ids should be sorted and different each other (MED file norm).
4802 * \warning this method can alter default "FAMILLE_ZERO" family.
4803 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4805 * \throw If the node coordinates array is not set.
4806 * \throw If \a ids == \c NULL.
4807 * \throw If \a ids->getName() == "".
4808 * \throw If \a ids does not respect the MED file norm.
4809 * \throw If a group with name \a ids->getName() already exists.
4811 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4813 const DataArrayDouble *coords(_coords);
4815 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4816 int nbOfNodes(coords->getNumberOfTuples());
4817 if(!((DataArrayInt *)_fam_coords))
4818 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4820 addGroupUnderground(true,ids,_fam_coords);
4824 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4826 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4827 * The ids should be sorted and different each other (MED file norm).
4829 * \warning this method can alter default "FAMILLE_ZERO" family.
4830 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4832 * \throw If the node coordinates array is not set.
4833 * \throw If \a ids == \c NULL.
4834 * \throw If \a ids->getName() == "".
4835 * \throw If \a ids does not respect the MED file norm.
4836 * \throw If a group with name \a ids->getName() already exists.
4838 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4840 std::vector<int> levs(getNonEmptyLevelsExt());
4841 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4843 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4844 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4846 if(meshDimRelToMaxExt==1)
4847 { addNodeGroup(ids); return ; }
4848 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4849 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4850 addGroupUnderground(false,ids,fam);
4854 * Changes a name of a family specified by its id.
4855 * \param [in] id - the id of the family of interest.
4856 * \param [in] newFamName - the new family name.
4857 * \throw If no family with the given \a id exists.
4859 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4861 std::string oldName=getFamilyNameGivenId(id);
4862 _families.erase(oldName);
4863 _families[newFamName]=id;
4867 * Removes a mesh of a given dimension.
4868 * \param [in] meshDimRelToMax - the relative dimension of interest.
4869 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4871 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4873 std::vector<int> levSet=getNonEmptyLevels();
4874 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4875 if(it==levSet.end())
4876 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4877 int pos=(-meshDimRelToMax);
4882 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4883 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4884 * \param [in] m - the new mesh to set.
4885 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4887 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4888 * another node coordinates array.
4889 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4890 * to the existing meshes of other levels of \a this mesh.
4892 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4894 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4895 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4899 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4900 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4901 * \param [in] m - the new mesh to set.
4902 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4903 * writing \a this mesh in a MED file.
4904 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4906 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4907 * another node coordinates array.
4908 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4909 * to the existing meshes of other levels of \a this mesh.
4911 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4913 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4914 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4917 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4919 dealWithTinyInfo(m);
4920 std::vector<int> levSet=getNonEmptyLevels();
4921 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4923 if((DataArrayDouble *)_coords==0)
4925 DataArrayDouble *c=m->getCoords();
4930 if(m->getCoords()!=_coords)
4931 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4932 int sz=(-meshDimRelToMax)+1;
4933 if(sz>=(int)_ms.size())
4935 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4939 return _ms[-meshDimRelToMax];
4943 * This method allows to set at once the content of different levels in \a this.
4944 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4946 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4947 * \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.
4948 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4950 * \throw If \a there is a null pointer in \a ms.
4951 * \sa MEDFileUMesh::setMeshAtLevel
4953 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4957 const MEDCouplingUMesh *mRef=ms[0];
4959 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4960 std::string name(mRef->getName());
4961 const DataArrayDouble *coo(mRef->getCoords());
4964 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4966 const MEDCouplingUMesh *cur(*it);
4968 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4969 if(coo!=cur->getCoords())
4970 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4971 int mdim=cur->getMeshDimension();
4972 zeDim=std::max(zeDim,mdim);
4973 if(s.find(mdim)!=s.end())
4974 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4976 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4978 int mdim=(*it)->getMeshDimension();
4979 setName((*it)->getName());
4980 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4986 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4987 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4988 * The given meshes must share the same node coordinates array.
4989 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4990 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4991 * create in \a this mesh.
4992 * \throw If \a ms is empty.
4993 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4994 * to the existing meshes of other levels of \a this mesh.
4995 * \throw If the meshes in \a ms do not share the same node coordinates array.
4996 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4997 * of the given meshes.
4998 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
4999 * \throw If names of some meshes in \a ms are equal.
5000 * \throw If \a ms includes a mesh with an empty name.
5002 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5005 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5006 int sz=(-meshDimRelToMax)+1;
5007 if(sz>=(int)_ms.size())
5009 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5010 DataArrayDouble *coo=checkMultiMesh(ms);
5011 if((DataArrayDouble *)_coords==0)
5017 if((DataArrayDouble *)_coords!=coo)
5018 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5019 std::vector<DataArrayInt *> corr;
5020 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5021 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5022 setMeshAtLevel(meshDimRelToMax,m,renum);
5023 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5024 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5028 * Creates groups at a given level in \a this mesh from a sequence of
5029 * meshes each representing a group.
5030 * The given meshes must share the same node coordinates array.
5031 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5032 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5033 * create in \a this mesh.
5034 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5036 * \throw If \a ms is empty.
5037 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5038 * to the existing meshes of other levels of \a this mesh.
5039 * \throw If the meshes in \a ms do not share the same node coordinates array.
5040 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5041 * of the given meshes.
5042 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5043 * \throw If names of some meshes in \a ms are equal.
5044 * \throw If \a ms includes a mesh with an empty name.
5046 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5049 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5050 int sz=(-meshDimRelToMax)+1;
5051 if(sz>=(int)_ms.size())
5053 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5054 DataArrayDouble *coo=checkMultiMesh(ms);
5055 if((DataArrayDouble *)_coords==0)
5061 if((DataArrayDouble *)_coords!=coo)
5062 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5063 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5064 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5066 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5068 DataArrayInt *arr=0;
5069 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5073 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5074 throw INTERP_KERNEL::Exception(oss.str().c_str());
5077 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5078 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5081 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5083 const DataArrayDouble *ret=ms[0]->getCoords();
5084 int mdim=ms[0]->getMeshDimension();
5085 for(unsigned int i=1;i<ms.size();i++)
5087 ms[i]->checkConsistencyLight();
5088 if(ms[i]->getCoords()!=ret)
5089 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5090 if(ms[i]->getMeshDimension()!=mdim)
5091 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5093 return const_cast<DataArrayDouble *>(ret);
5097 * Sets the family field of a given relative dimension.
5098 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5099 * the family field is set.
5100 * \param [in] famArr - the array of the family field.
5101 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5102 * \throw If \a famArr has an invalid size.
5104 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5106 if(meshDimRelToMaxExt==1)
5113 DataArrayDouble *coo(_coords);
5115 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5116 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5121 if(meshDimRelToMaxExt>1)
5122 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5123 int traducedRk=-meshDimRelToMaxExt;
5124 if(traducedRk>=(int)_ms.size())
5125 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5126 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5127 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5128 return _ms[traducedRk]->setFamilyArr(famArr);
5132 * Sets the optional numbers of mesh entities of a given dimension.
5133 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5134 * \param [in] renumArr - the array of the numbers.
5135 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5136 * \throw If \a renumArr has an invalid size.
5138 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5140 if(meshDimRelToMaxExt==1)
5148 DataArrayDouble *coo(_coords);
5150 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5151 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5152 renumArr->incrRef();
5153 _num_coords=renumArr;
5157 if(meshDimRelToMaxExt>1)
5158 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5159 int traducedRk=-meshDimRelToMaxExt;
5160 if(traducedRk>=(int)_ms.size())
5161 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5162 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5163 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5164 return _ms[traducedRk]->setRenumArr(renumArr);
5168 * Sets the optional names of mesh entities of a given dimension.
5169 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5170 * \param [in] nameArr - the array of the names.
5171 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5172 * \throw If \a nameArr has an invalid size.
5174 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5176 if(meshDimRelToMaxExt==1)
5183 DataArrayDouble *coo(_coords);
5185 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5186 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5188 _name_coords=nameArr;
5191 if(meshDimRelToMaxExt>1)
5192 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5193 int traducedRk=-meshDimRelToMaxExt;
5194 if(traducedRk>=(int)_ms.size())
5195 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5196 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5197 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5198 return _ms[traducedRk]->setNameArr(nameArr);
5201 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5203 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5204 if((const MEDFileUMeshSplitL1 *)(*it))
5205 (*it)->synchronizeTinyInfo(*this);
5209 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5211 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5213 DataArrayInt *arr=_fam_coords;
5215 arr->changeValue(oldId,newId);
5216 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5218 MEDFileUMeshSplitL1 *sp=(*it);
5221 sp->changeFamilyIdArr(oldId,newId);
5226 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5228 std::list< MCAuto<DataArrayInt> > ret;
5229 const DataArrayInt *da(_fam_coords);
5231 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5232 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5234 const MEDFileUMeshSplitL1 *elt(*it);
5237 da=elt->getFamilyField();
5239 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5245 void MEDFileUMesh::computeRevNum() const
5247 if((const DataArrayInt *)_num_coords)
5250 int maxValue=_num_coords->getMaxValue(pos);
5251 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5255 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5257 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5260 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5262 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5263 ret.push_back((const DataArrayInt *)_fam_nodes);
5264 ret.push_back((const DataArrayInt *)_num_nodes);
5265 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5266 ret.push_back((const DataArrayInt *)_fam_cells);
5267 ret.push_back((const DataArrayInt *)_num_cells);
5268 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5269 ret.push_back((const DataArrayInt *)_fam_faces);
5270 ret.push_back((const DataArrayInt *)_num_faces);
5271 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5272 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5273 ret.push_back((const DataArrayInt *)_rev_num_cells);
5274 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5278 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5280 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5281 if((const DataArrayInt *)_fam_nodes)
5283 int val=_fam_nodes->getMaxValue(tmp);
5284 ret=std::max(ret,std::abs(val));
5286 if((const DataArrayInt *)_fam_cells)
5288 int val=_fam_cells->getMaxValue(tmp);
5289 ret=std::max(ret,std::abs(val));
5291 if((const DataArrayInt *)_fam_faces)
5293 int val=_fam_faces->getMaxValue(tmp);
5294 ret=std::max(ret,std::abs(val));
5299 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5301 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5302 if((const DataArrayInt *)_fam_nodes)
5304 int val=_fam_nodes->getMaxValue(tmp);
5305 ret=std::max(ret,val);
5307 if((const DataArrayInt *)_fam_cells)
5309 int val=_fam_cells->getMaxValue(tmp);
5310 ret=std::max(ret,val);
5312 if((const DataArrayInt *)_fam_faces)
5314 int val=_fam_faces->getMaxValue(tmp);
5315 ret=std::max(ret,val);
5320 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5322 int ret=std::numeric_limits<int>::max(),tmp=-1;
5323 if((const DataArrayInt *)_fam_nodes)
5325 int val=_fam_nodes->getMinValue(tmp);
5326 ret=std::min(ret,val);
5328 if((const DataArrayInt *)_fam_cells)
5330 int val=_fam_cells->getMinValue(tmp);
5331 ret=std::min(ret,val);
5333 if((const DataArrayInt *)_fam_faces)
5335 int val=_fam_faces->getMinValue(tmp);
5336 ret=std::min(ret,val);
5341 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5343 if(!MEDFileMesh::isEqual(other,eps,what))
5345 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5348 what="Mesh types differ ! This is structured and other is NOT !";
5351 const DataArrayInt *famc1=_fam_nodes;
5352 const DataArrayInt *famc2=otherC->_fam_nodes;
5353 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5355 what="Mismatch of families arr on nodes ! One is defined and not other !";
5360 bool ret=famc1->isEqual(*famc2);
5363 what="Families arr on nodes differ !";
5368 famc2=otherC->_fam_cells;
5369 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5371 what="Mismatch of families arr on cells ! One is defined and not other !";
5376 bool ret=famc1->isEqual(*famc2);
5379 what="Families arr on cells differ !";
5384 famc2=otherC->_fam_faces;
5385 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5387 what="Mismatch of families arr on faces ! One is defined and not other !";
5392 bool ret=famc1->isEqual(*famc2);
5395 what="Families arr on faces differ !";
5400 famc2=otherC->_num_nodes;
5401 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5403 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5408 bool ret=famc1->isEqual(*famc2);
5411 what="Numbering arr on nodes differ !";
5416 famc2=otherC->_num_cells;
5417 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5419 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5424 bool ret=famc1->isEqual(*famc2);
5427 what="Numbering arr on cells differ !";
5432 famc2=otherC->_num_faces;
5433 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5435 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5440 bool ret=famc1->isEqual(*famc2);
5443 what="Numbering arr on faces differ !";
5447 const DataArrayAsciiChar *d1=_names_cells;
5448 const DataArrayAsciiChar *d2=otherC->_names_cells;
5449 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5451 what="Mismatch of naming arr on cells ! One is defined and not other !";
5456 bool ret=d1->isEqual(*d2);
5459 what="Naming arr on cells differ !";
5464 d2=otherC->_names_faces;
5465 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5467 what="Mismatch of naming arr on faces ! One is defined and not other !";
5472 bool ret=d1->isEqual(*d2);
5475 what="Naming arr on faces differ !";
5480 d2=otherC->_names_nodes;
5481 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5483 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5488 bool ret=d1->isEqual(*d2);
5491 what="Naming arr on nodes differ !";
5498 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5500 MEDFileMesh::clearNonDiscrAttributes();
5501 const DataArrayInt *tmp=_fam_nodes;
5503 (const_cast<DataArrayInt *>(tmp))->setName("");
5506 (const_cast<DataArrayInt *>(tmp))->setName("");
5509 (const_cast<DataArrayInt *>(tmp))->setName("");
5512 (const_cast<DataArrayInt *>(tmp))->setName("");
5515 (const_cast<DataArrayInt *>(tmp))->setName("");
5518 (const_cast<DataArrayInt *>(tmp))->setName("");
5522 * Returns ids of mesh entities contained in given families of a given dimension.
5523 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5525 * \param [in] fams - the names of the families of interest.
5526 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5527 * returned instead of ids.
5528 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5529 * numbers, if available and required, of mesh entities of the families. The caller
5530 * is to delete this array using decrRef() as it is no more needed.
5531 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5533 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5535 std::vector<int> famIds(getFamiliesIds(fams));
5536 switch(meshDimRelToMaxExt)
5540 if((const DataArrayInt *)_fam_nodes)
5542 MCAuto<DataArrayInt> da;
5544 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5546 da=_fam_nodes->findIdsEqualList(0,0);
5548 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5553 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5558 if((const DataArrayInt *)_fam_cells)
5560 MCAuto<DataArrayInt> da;
5562 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5564 da=_fam_cells->findIdsEqualList(0,0);
5566 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5571 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5576 if((const DataArrayInt *)_fam_faces)
5578 MCAuto<DataArrayInt> da;
5580 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5582 da=_fam_faces->findIdsEqualList(0,0);
5584 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5589 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5593 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5595 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5599 * Sets the family field of a given relative dimension.
5600 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5601 * the family field is set.
5602 * \param [in] famArr - the array of the family field.
5603 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5604 * \throw If \a famArr has an invalid size.
5605 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5607 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5609 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5611 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5612 switch(meshDimRelToMaxExt)
5616 int nbCells(mesh->getNumberOfCells());
5618 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5624 int nbNodes(mesh->getNumberOfNodes());
5626 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5632 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5634 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5639 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5646 * Sets the optional numbers of mesh entities of a given dimension.
5647 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5648 * \param [in] renumArr - the array of the numbers.
5649 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5650 * \throw If \a renumArr has an invalid size.
5651 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5653 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5655 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5657 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5658 switch(meshDimRelToMaxExt)
5662 int nbCells=mesh->getNumberOfCells();
5663 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5664 _num_cells=renumArr;
5669 int nbNodes=mesh->getNumberOfNodes();
5670 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5671 _num_nodes=renumArr;
5676 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5677 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5678 _num_faces=renumArr;
5682 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5685 renumArr->incrRef();
5689 * Sets the optional names of mesh entities of a given dimension.
5690 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5691 * \param [in] nameArr - the array of the names.
5692 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5693 * \throw If \a nameArr has an invalid size.
5695 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5697 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5699 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5700 switch(meshDimRelToMaxExt)
5704 int nbCells=mesh->getNumberOfCells();
5705 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5706 _names_cells=nameArr;
5711 int nbNodes=mesh->getNumberOfNodes();
5712 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5713 _names_nodes=nameArr;
5718 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5719 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5720 _names_cells=nameArr;
5723 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5730 * Adds a group of nodes to \a this mesh.
5731 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5732 * The ids should be sorted and different each other (MED file norm).
5734 * \warning this method can alter default "FAMILLE_ZERO" family.
5735 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5737 * \throw If the node coordinates array is not set.
5738 * \throw If \a ids == \c NULL.
5739 * \throw If \a ids->getName() == "".
5740 * \throw If \a ids does not respect the MED file norm.
5741 * \throw If a group with name \a ids->getName() already exists.
5743 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5749 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5751 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5752 * The ids should be sorted and different each other (MED file norm).
5754 * \warning this method can alter default "FAMILLE_ZERO" family.
5755 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5757 * \throw If the node coordinates array is not set.
5758 * \throw If \a ids == \c NULL.
5759 * \throw If \a ids->getName() == "".
5760 * \throw If \a ids does not respect the MED file norm.
5761 * \throw If a group with name \a ids->getName() already exists.
5763 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5765 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5766 addGroupUnderground(false,ids,fam);
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 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5779 switch(meshDimRelToMaxExt)
5788 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5793 * Returns the family field for mesh entities of a given dimension.
5794 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5795 * \return const DataArrayInt * - the family field. It is an array of ids of families
5796 * each mesh entity belongs to. It can be \c NULL.
5797 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5799 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5801 switch(meshDimRelToMaxExt)
5810 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5815 * Returns the optional numbers of mesh entities of a given dimension.
5816 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5817 * \return const DataArrayInt * - the array of the entity numbers.
5818 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5819 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5821 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5823 switch(meshDimRelToMaxExt)
5832 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5837 * Returns the optional numbers of mesh entities of a given dimension transformed using
5838 * DataArrayInt::invertArrayN2O2O2N().
5839 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5840 * \return const DataArrayInt * - the array of the entity numbers transformed using
5841 * DataArrayInt::invertArrayN2O2O2N().
5842 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5843 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5845 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5847 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5848 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5849 if(meshDimRelToMaxExt==0)
5851 if((const DataArrayInt *)_num_cells)
5854 int maxValue=_num_cells->getMaxValue(pos);
5855 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5856 return _rev_num_cells;
5859 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5863 if((const DataArrayInt *)_num_nodes)
5866 int maxValue=_num_nodes->getMaxValue(pos);
5867 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5868 return _rev_num_nodes;
5871 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5875 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5877 switch(meshDimRelToMaxExt)
5880 return _names_cells;
5882 return _names_nodes;
5884 return _names_faces;
5886 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5891 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5892 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5894 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5896 std::vector<int> ret(1);
5901 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5902 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5904 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5906 std::vector<int> ret(2);
5912 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5914 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5916 std::vector<int> ret;
5917 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5928 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5930 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5932 std::vector<int> ret;
5933 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5944 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5946 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5948 std::vector<int> ret;
5949 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5960 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5962 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5964 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5968 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5970 DataArrayInt *arr=_fam_nodes;
5972 arr->changeValue(oldId,newId);
5975 arr->changeValue(oldId,newId);
5978 arr->changeValue(oldId,newId);
5981 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5983 std::list< MCAuto<DataArrayInt> > ret;
5984 const DataArrayInt *da(_fam_nodes);
5986 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5989 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5992 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5996 void MEDFileStructuredMesh::deepCpyAttributes()
5998 if((const DataArrayInt*)_fam_nodes)
5999 _fam_nodes=_fam_nodes->deepCopy();
6000 if((const DataArrayInt*)_num_nodes)
6001 _num_nodes=_num_nodes->deepCopy();
6002 if((const DataArrayAsciiChar*)_names_nodes)
6003 _names_nodes=_names_nodes->deepCopy();
6004 if((const DataArrayInt*)_fam_cells)
6005 _fam_cells=_fam_cells->deepCopy();
6006 if((const DataArrayInt*)_num_cells)
6007 _num_cells=_num_cells->deepCopy();
6008 if((const DataArrayAsciiChar*)_names_cells)
6009 _names_cells=_names_cells->deepCopy();
6010 if((const DataArrayInt*)_fam_faces)
6011 _fam_faces=_fam_faces->deepCopy();
6012 if((const DataArrayInt*)_num_faces)
6013 _num_faces=_num_faces->deepCopy();
6014 if((const DataArrayAsciiChar*)_names_faces)
6015 _names_faces=_names_faces->deepCopy();
6016 if((const DataArrayInt*)_rev_num_nodes)
6017 _rev_num_nodes=_rev_num_nodes->deepCopy();
6018 if((const DataArrayInt*)_rev_num_cells)
6019 _rev_num_cells=_rev_num_cells->deepCopy();
6023 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
6025 * \return a pointer to cartesian mesh that need to be managed by the caller.
6026 * \warning the returned pointer has to be managed by the caller.
6030 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6031 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6032 * \param [in] renum - it must be \c false.
6033 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6034 * delete using decrRef() as it is no more needed.
6036 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6040 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6041 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6042 switch(meshDimRelToMax)
6048 return const_cast<MEDCouplingStructuredMesh *>(m);
6053 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6054 buildMinusOneImplicitPartIfNeeded();
6055 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6061 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6065 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6067 std::vector<int> ret;
6068 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6069 if(famCells && famCells->presenceOfValue(ret))
6071 if(famFaces && famFaces->presenceOfValue(ret))
6076 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6078 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6079 const DataArrayInt *famNodes(_fam_nodes);
6080 if(famNodes && famNodes->presenceOfValue(ret))
6086 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6087 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6088 * \return int - the number of entities.
6089 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6091 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6093 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6095 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6096 switch(meshDimRelToMaxExt)
6099 return cmesh->getNumberOfCells();
6101 return cmesh->getNumberOfNodes();
6103 return cmesh->getNumberOfCellsOfSubLevelMesh();
6105 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6109 int MEDFileStructuredMesh::getNumberOfNodes() const
6111 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6113 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6114 return cmesh->getNumberOfNodes();
6117 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6119 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6121 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6122 switch(meshDimRelToMaxExt)
6125 return cmesh->getNumberOfCells();
6127 return cmesh->getNumberOfCellsOfSubLevelMesh();
6129 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6133 bool MEDFileStructuredMesh::hasImplicitPart() const
6139 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6141 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6143 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6144 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6147 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6148 if(cm.getReverseExtrudedType()!=gt)
6149 throw INTERP_KERNEL::Exception(MSG);
6150 buildImplicitPart();
6151 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6155 if(gt!=zeFaceMesh->getCellModelEnum())
6156 throw INTERP_KERNEL::Exception(MSG);
6157 return zeFaceMesh->getNumberOfCells();
6161 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6163 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6165 buildImplicitPart();
6168 void MEDFileStructuredMesh::buildImplicitPart() const
6170 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6172 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6173 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6176 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6178 _faces_if_necessary=0;
6182 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6183 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6185 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6187 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6190 return _faces_if_necessary;
6193 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6195 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6197 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6198 switch(meshDimRelToMax)
6202 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6207 int mdim(cmesh->getMeshDimension());
6209 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6210 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6214 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6218 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6220 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6223 return getNumberOfCellsAtLevel(0);
6226 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6228 if(st.getNumberOfItems()!=1)
6229 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 !");
6230 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6231 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6232 if(getNumberOfNodes()!=(int)nodesFetched.size())
6233 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6234 if(st[0].getPflName().empty())
6236 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6239 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6240 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6241 int sz(nodesFetched.size());
6242 for(const int *work=arr->begin();work!=arr->end();work++)
6244 std::vector<int> conn;
6245 cmesh->getNodeIdsOfCell(*work,conn);
6246 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6247 if(*it>=0 && *it<sz)
6248 nodesFetched[*it]=true;
6250 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6254 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6256 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6260 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6261 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6263 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6264 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6266 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6269 if(!mrs || mrs->isCellFamilyFieldReading())
6271 famCells=DataArrayInt::New();
6272 famCells->alloc(nbOfElt,1);
6273 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6276 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6279 if(!mrs || mrs->isCellNumFieldReading())
6281 numCells=DataArrayInt::New();
6282 numCells->alloc(nbOfElt,1);
6283 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6286 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6289 if(!mrs || mrs->isCellNameFieldReading())
6291 namesCells=DataArrayAsciiChar::New();
6292 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6293 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6294 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6299 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6301 setName(strm->getName());
6302 setDescription(strm->getDescription());
6303 setUnivName(strm->getUnivName());
6304 setIteration(strm->getIteration());
6305 setOrder(strm->getOrder());
6306 setTimeValue(strm->getTime());
6307 setTimeUnit(strm->getTimeUnit());
6308 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6309 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6310 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6313 if(!mrs || mrs->isNodeFamilyFieldReading())
6315 int nbNodes(getNumberOfNodes());
6317 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6318 _fam_nodes=DataArrayInt::New();
6319 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6320 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...
6321 _fam_nodes->fillWithZero();
6322 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6325 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6328 if(!mrs || mrs->isNodeNumFieldReading())
6330 _num_nodes=DataArrayInt::New();
6331 _num_nodes->alloc(nbOfElt,1);
6332 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6335 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6338 if(!mrs || mrs->isNodeNameFieldReading())
6340 _names_nodes=DataArrayAsciiChar::New();
6341 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6342 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6343 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6346 int meshDim(getStructuredMesh()->getMeshDimension());
6347 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6349 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6352 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6354 int meshDim(getStructuredMesh()->getMeshDimension());
6355 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6357 if((const DataArrayInt *)_fam_cells)
6358 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6359 if((const DataArrayInt *)_fam_faces)
6360 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6361 if((const DataArrayInt *)_fam_nodes)
6362 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6363 if((const DataArrayInt *)_num_cells)
6364 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6365 if((const DataArrayInt *)_num_faces)
6366 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6367 if((const DataArrayInt *)_num_nodes)
6368 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6369 if((const DataArrayAsciiChar *)_names_cells)
6371 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6373 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6374 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6375 throw INTERP_KERNEL::Exception(oss.str().c_str());
6377 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6379 if((const DataArrayAsciiChar *)_names_faces)
6381 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6383 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6384 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6385 throw INTERP_KERNEL::Exception(oss.str().c_str());
6387 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6389 if((const DataArrayAsciiChar *)_names_nodes)
6391 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6393 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6394 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6395 throw INTERP_KERNEL::Exception(oss.str().c_str());
6397 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6400 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6404 * Returns an empty instance of MEDFileCMesh.
6405 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6406 * mesh using decrRef() as it is no more needed.
6408 MEDFileCMesh *MEDFileCMesh::New()
6410 return new MEDFileCMesh;
6414 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6415 * file. The first mesh in the file is loaded.
6416 * \param [in] fileName - the name of MED file to read.
6417 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6418 * mesh using decrRef() as it is no more needed.
6419 * \throw If the file is not readable.
6420 * \throw If there is no meshes in the file.
6421 * \throw If the mesh in the file is not a Cartesian one.
6423 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6425 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6426 return New(fid,mrs);
6429 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6431 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6435 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6436 * file. The mesh to load is specified by its name and numbers of a time step and an
6438 * \param [in] fileName - the name of MED file to read.
6439 * \param [in] mName - the name of the mesh to read.
6440 * \param [in] dt - the number of a time step.
6441 * \param [in] it - the number of an iteration.
6442 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6443 * mesh using decrRef() as it is no more needed.
6444 * \throw If the file is not readable.
6445 * \throw If there is no mesh with given attributes in the file.
6446 * \throw If the mesh in the file is not a Cartesian one.
6448 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6450 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6451 return New(fid,mName,dt,it,mrs);
6454 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6456 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6459 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6461 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6464 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6466 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6467 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6472 * Returns the dimension on cells in \a this mesh.
6473 * \return int - the mesh dimension.
6474 * \throw If there are no cells in this mesh.
6476 int MEDFileCMesh::getMeshDimension() const
6478 if(!((const MEDCouplingCMesh*)_cmesh))
6479 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6480 return _cmesh->getMeshDimension();
6484 * Returns the dimension on nodes in \a this mesh.
6485 * \return int - the space dimension.
6486 * \throw If there are no cells in this mesh.
6488 int MEDFileCMesh::getSpaceDimension() const
6490 if(!((const MEDCouplingCMesh*)_cmesh))
6491 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6492 return _cmesh->getSpaceDimension();
6496 * Returns a string describing \a this mesh.
6497 * \return std::string - the mesh information string.
6499 std::string MEDFileCMesh::simpleRepr() const
6501 return MEDFileStructuredMesh::simpleRepr();
6505 * Returns a full textual description of \a this mesh.
6506 * \return std::string - the string holding the mesh description.
6508 std::string MEDFileCMesh::advancedRepr() const
6510 return simpleRepr();
6513 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6515 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6519 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6521 return new MEDFileCMesh;
6524 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6526 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6527 ret->deepCpyEquivalences(*this);
6528 if((const MEDCouplingCMesh*)_cmesh)
6529 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6530 ret->deepCpyAttributes();
6535 * Checks if \a this and another mesh are equal.
6536 * \param [in] other - the mesh to compare with.
6537 * \param [in] eps - a precision used to compare real values.
6538 * \param [in,out] what - the string returning description of unequal data.
6539 * \return bool - \c true if the meshes are equal, \c false, else.
6541 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6543 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6545 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6548 what="Mesh types differ ! This is cartesian and other is NOT !";
6551 clearNonDiscrAttributes();
6552 otherC->clearNonDiscrAttributes();
6553 const MEDCouplingCMesh *coo1=_cmesh;
6554 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6555 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6557 what="Mismatch of cartesian meshes ! One is defined and not other !";
6562 bool ret=coo1->isEqual(coo2,eps);
6565 what="cartesian meshes differ !";
6573 * Clears redundant attributes of incorporated data arrays.
6575 void MEDFileCMesh::clearNonDiscrAttributes() const
6577 MEDFileStructuredMesh::clearNonDiscrAttributes();
6578 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6581 MEDFileCMesh::MEDFileCMesh()
6585 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6588 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6590 catch(INTERP_KERNEL::Exception& e)
6595 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6597 MEDCoupling::MEDCouplingMeshType meshType;
6600 MEDCoupling::MEDCouplingAxisType axType;
6601 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6602 if(meshType!=CARTESIAN)
6604 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6605 throw INTERP_KERNEL::Exception(oss.str().c_str());
6607 MEDFileCMeshL2 loaderl2;
6608 loaderl2.loadAll(fid,mid,mName,dt,it);
6609 setAxisType(axType);
6610 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6613 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6617 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6618 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6620 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6622 synchronizeTinyInfoOnLeaves();
6626 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6628 synchronizeTinyInfoOnLeaves();
6633 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6634 * \param [in] m - the new MEDCouplingCMesh to refer to.
6635 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6638 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6640 dealWithTinyInfo(m);
6646 MEDFileMesh *MEDFileCMesh::cartesianize() const
6648 if(getAxisType()==AX_CART)
6651 return const_cast<MEDFileCMesh *>(this);
6655 const MEDCouplingCMesh *cmesh(getMesh());
6657 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6658 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6659 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6660 clmesh->setCoords(coords);
6661 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6662 ret->MEDFileStructuredMesh::operator=(*this);
6663 ret->setMesh(clmesh);
6664 ret->setAxisType(AX_CART);
6669 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6671 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6672 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6673 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6674 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6675 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6676 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6677 int spaceDim(_cmesh->getSpaceDimension());
6678 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6679 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6680 for(int i=0;i<spaceDim;i++)
6682 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6684 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6685 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
6686 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
6688 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6690 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6691 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6692 for(int i=0;i<spaceDim;i++)
6694 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6695 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6698 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6699 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6702 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6704 const MEDCouplingCMesh *cmesh=_cmesh;
6707 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6708 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6709 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6710 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6713 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6715 return new MEDFileCurveLinearMesh;
6718 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6720 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
6723 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6725 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6726 return New(fid,mrs);
6729 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6731 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6732 return New(fid,mName,dt,it,mrs);
6735 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6737 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6740 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6742 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6745 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6747 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6748 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6752 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6754 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6758 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6760 return new MEDFileCurveLinearMesh;
6763 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6765 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6766 ret->deepCpyEquivalences(*this);
6767 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6768 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6769 ret->deepCpyAttributes();
6773 int MEDFileCurveLinearMesh::getMeshDimension() const
6775 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6776 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6777 return _clmesh->getMeshDimension();
6780 std::string MEDFileCurveLinearMesh::simpleRepr() const
6782 return MEDFileStructuredMesh::simpleRepr();
6785 std::string MEDFileCurveLinearMesh::advancedRepr() const
6787 return simpleRepr();
6790 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6792 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6794 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6797 what="Mesh types differ ! This is curve linear and other is NOT !";
6800 clearNonDiscrAttributes();
6801 otherC->clearNonDiscrAttributes();
6802 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6803 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6804 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6806 what="Mismatch of curve linear meshes ! One is defined and not other !";
6811 bool ret=coo1->isEqual(coo2,eps);
6814 what="curve linear meshes differ !";
6821 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6823 MEDFileStructuredMesh::clearNonDiscrAttributes();
6824 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6827 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6829 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6832 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6833 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6834 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6835 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6838 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6840 synchronizeTinyInfoOnLeaves();
6844 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6846 dealWithTinyInfo(m);
6852 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6854 if(getAxisType()==AX_CART)
6857 return const_cast<MEDFileCurveLinearMesh *>(this);
6861 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6863 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6864 const DataArrayDouble *coords(mesh->getCoords());
6866 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6867 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6868 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6869 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6870 mesh2->setCoords(coordsCart);
6871 ret->setMesh(mesh2);
6872 ret->setAxisType(AX_CART);
6877 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6879 synchronizeTinyInfoOnLeaves();
6883 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6887 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6890 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6892 catch(INTERP_KERNEL::Exception& e)
6897 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
6899 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6900 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6901 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6902 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6903 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6904 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6905 int spaceDim=_clmesh->getSpaceDimension();
6906 int meshDim=_clmesh->getMeshDimension();
6907 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6908 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6909 const DataArrayDouble *coords=_clmesh->getCoords();
6911 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
6912 for(int i=0;i<spaceDim;i++)
6914 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6916 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6917 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
6918 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
6920 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6922 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6923 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6924 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6925 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6927 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6929 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6930 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6933 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6935 MEDCoupling::MEDCouplingMeshType meshType;
6938 MEDCoupling::MEDCouplingAxisType axType;
6939 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6940 setAxisType(axType);
6941 if(meshType!=CURVE_LINEAR)
6943 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6944 throw INTERP_KERNEL::Exception(oss.str().c_str());
6946 MEDFileCLMeshL2 loaderl2;
6947 loaderl2.loadAll(fid,mid,mName,dt,it);
6948 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6951 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6954 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6956 return new MEDFileMeshMultiTS;
6959 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
6961 return new MEDFileMeshMultiTS(fid);
6964 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6966 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6970 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
6972 return new MEDFileMeshMultiTS(fid,mName);
6975 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6977 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6978 return New(fid,mName);
6981 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
6983 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
6984 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6986 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6987 if((const MEDFileMesh *)*it)
6988 meshOneTs[i]=(*it)->deepCopy();
6989 ret->_mesh_one_ts=meshOneTs;
6993 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6995 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
6998 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7000 std::vector<const BigMemoryObject *> ret;
7001 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7002 ret.push_back((const MEDFileMesh *)*it);
7006 std::string MEDFileMeshMultiTS::getName() const
7008 if(_mesh_one_ts.empty())
7009 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7010 return _mesh_one_ts[0]->getName();
7013 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7015 std::string oldName(getName());
7016 std::vector< std::pair<std::string,std::string> > v(1);
7017 v[0].first=oldName; v[0].second=newMeshName;
7021 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7024 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7026 MEDFileMesh *cur(*it);
7028 ret=cur->changeNames(modifTab) || ret;
7033 void MEDFileMeshMultiTS::cartesianizeMe()
7035 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7037 MEDFileMesh *cur(*it);
7040 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7046 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7048 if(_mesh_one_ts.empty())
7049 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7050 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7053 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7056 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7057 _mesh_one_ts.resize(1);
7058 mesh1TimeStep->incrRef();
7059 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7060 _mesh_one_ts[0]=mesh1TimeStep;
7063 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7065 if ( MEDFileMesh* m = getOneTimeStep() )
7066 return m->getJoints();
7071 * \brief Set Joints that are common to all time-stamps
7073 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7075 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7077 (*it)->setJoints( joints );
7081 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7083 MEDFileJoints *joints(getJoints());
7084 bool jointsWritten(false);
7086 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7088 if ( jointsWritten )
7089 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7091 jointsWritten = true;
7093 (*it)->copyOptionsFrom(*this);
7094 (*it)->writeLL(fid);
7097 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7100 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7102 MEDFileJoints *joints(0);
7103 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7105 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7106 joints = getOneTimeStep()->getJoints();
7108 _mesh_one_ts.clear(); //for the moment to be improved
7109 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7112 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7116 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7119 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7122 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7123 throw INTERP_KERNEL::Exception(oss.str().c_str());
7126 MEDCoupling::MEDCouplingMeshType meshType;
7128 MEDCoupling::MEDCouplingAxisType dummy3;
7129 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7130 loadFromFile(fid,ms.front());
7132 catch(INTERP_KERNEL::Exception& e)
7137 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7140 loadFromFile(fid,mName);
7142 catch(INTERP_KERNEL::Exception& e)
7147 MEDFileMeshes *MEDFileMeshes::New()
7149 return new MEDFileMeshes;
7152 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7154 return new MEDFileMeshes(fid);
7157 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7159 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7163 void MEDFileMeshes::writeLL(med_idt fid) const
7165 checkConsistencyLight();
7166 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7168 (*it)->copyOptionsFrom(*this);
7169 (*it)->writeLL(fid);
7173 // MEDFileMeshes::writ checkConsistencyLight();
7175 int MEDFileMeshes::getNumberOfMeshes() const
7177 return _meshes.size();
7180 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7182 return new MEDFileMeshesIterator(this);
7185 /** Return a borrowed reference (caller is not responsible) */
7186 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7188 if(i<0 || i>=(int)_meshes.size())
7190 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7191 throw INTERP_KERNEL::Exception(oss.str().c_str());
7193 return _meshes[i]->getOneTimeStep();
7196 /** Return a borrowed reference (caller is not responsible) */
7197 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7199 std::vector<std::string> ms=getMeshesNames();
7200 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7203 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7204 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7205 throw INTERP_KERNEL::Exception(oss.str().c_str());
7207 return getMeshAtPos((int)std::distance(ms.begin(),it));
7210 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7212 std::vector<std::string> ret(_meshes.size());
7214 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7216 const MEDFileMeshMultiTS *f=(*it);
7219 ret[i]=f->getName();
7223 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7224 throw INTERP_KERNEL::Exception(oss.str().c_str());
7230 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7233 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7235 MEDFileMeshMultiTS *cur(*it);
7237 ret=cur->changeNames(modifTab) || ret;
7242 void MEDFileMeshes::cartesianizeMe()
7244 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7246 MEDFileMeshMultiTS *cur(*it);
7248 cur->cartesianizeMe();
7252 void MEDFileMeshes::resize(int newSize)
7254 _meshes.resize(newSize);
7257 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7260 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7261 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7262 elt->setOneTimeStep(mesh);
7263 _meshes.push_back(elt);
7266 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7269 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7270 if(i>=(int)_meshes.size())
7271 _meshes.resize(i+1);
7272 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7273 elt->setOneTimeStep(mesh);
7277 void MEDFileMeshes::destroyMeshAtPos(int i)
7279 if(i<0 || i>=(int)_meshes.size())
7281 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7282 throw INTERP_KERNEL::Exception(oss.str().c_str());
7284 _meshes.erase(_meshes.begin()+i);
7287 void MEDFileMeshes::loadFromFile(med_idt fid)
7289 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7291 _meshes.resize(ms.size());
7292 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7293 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7296 MEDFileMeshes::MEDFileMeshes()
7300 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7305 catch(INTERP_KERNEL::Exception& /*e*/)
7309 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7311 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7313 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7314 if((const MEDFileMeshMultiTS *)*it)
7315 meshes[i]=(*it)->deepCopy();
7316 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7317 ret->_meshes=meshes;
7321 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7323 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7326 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7328 std::vector<const BigMemoryObject *> ret;
7329 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7330 ret.push_back((const MEDFileMeshMultiTS *)*it);
7334 std::string MEDFileMeshes::simpleRepr() const
7336 std::ostringstream oss;
7337 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7338 simpleReprWithoutHeader(oss);
7342 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7344 int nbOfMeshes=getNumberOfMeshes();
7345 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7346 std::vector<std::string> mns=getMeshesNames();
7347 for(int i=0;i<nbOfMeshes;i++)
7348 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7351 void MEDFileMeshes::checkConsistencyLight() const
7353 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7355 std::set<std::string> s;
7356 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7358 const MEDFileMeshMultiTS *elt=(*it);
7361 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7362 throw INTERP_KERNEL::Exception(oss.str().c_str());
7364 std::size_t sz=s.size();
7365 s.insert(std::string((*it)->getName()));
7368 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7369 throw INTERP_KERNEL::Exception(oss.str().c_str());
7374 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7379 _nb_iter=ms->getNumberOfMeshes();
7383 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7387 MEDFileMesh *MEDFileMeshesIterator::nextt()
7389 if(_iter_id<_nb_iter)
7391 MEDFileMeshes *ms(_ms);
7393 return ms->getMeshAtPos(_iter_id++);