1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileUtilities.hxx"
23 #include "MEDFileFieldOverView.hxx"
24 #include "MEDFileField.hxx"
25 #include "MEDLoader.hxx"
26 #include "MEDFileSafeCaller.txx"
27 #include "MEDLoaderBase.hxx"
29 #include "MEDCouplingUMesh.hxx"
30 #include "MEDCouplingMappedExtrudedMesh.hxx"
32 #include "InterpKernelAutoPtr.hxx"
37 extern med_geometry_type typmai3[34];
39 using namespace MEDCoupling;
41 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
43 const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
45 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
49 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
51 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
52 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
54 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
55 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
56 ret+=(*it2).capacity();
58 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
59 ret+=(*it).first.capacity()+sizeof(int);
63 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
65 std::vector<const BigMemoryObject *> ret(1);
66 ret[0]=(const MEDFileEquivalences *)_equiv;
71 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
72 * file. The first mesh in the file is loaded.
73 * \param [in] fileName - the name of MED file to read.
74 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
75 * mesh using decrRef() as it is no more needed.
76 * \throw If the file is not readable.
77 * \throw If there is no meshes in the file.
78 * \throw If the mesh in the file is of a not supported type.
80 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
82 std::vector<std::string> ms=MEDCoupling::GetMeshNames(fileName);
85 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
86 throw INTERP_KERNEL::Exception(oss.str().c_str());
88 MEDFileUtilities::CheckFileForRead(fileName);
89 MEDCoupling::MEDCouplingMeshType meshType;
90 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
93 MEDCoupling::MEDCouplingAxisType dummy3;
94 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
95 MCAuto<MEDFileMesh> ret;
100 ret=MEDFileUMesh::New();
105 ret=MEDFileCMesh::New();
110 ret=MEDFileCurveLinearMesh::New();
115 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
116 throw INTERP_KERNEL::Exception(oss.str().c_str());
119 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
124 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
125 * file. The mesh to load is specified by its name and numbers of a time step and an
127 * \param [in] fileName - the name of MED file to read.
128 * \param [in] mName - the name of the mesh to read.
129 * \param [in] dt - the number of a time step.
130 * \param [in] it - the number of an iteration.
131 * \param [in] joints - the sub-domain joints to use instead of those that can be read
132 * from the MED file. Usually this joints are those just read by another iteration
133 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
134 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
135 * mesh using decrRef() as it is no more needed.
136 * \throw If the file is not readable.
137 * \throw If there is no mesh with given attributes in the file.
138 * \throw If the mesh in the file is of a not supported type.
140 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
142 MEDFileUtilities::CheckFileForRead(fileName);
143 MEDCoupling::MEDCouplingMeshType meshType;
144 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
147 MEDCoupling::MEDCouplingAxisType dummy3;
148 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
149 MCAuto<MEDFileMesh> ret;
154 ret=MEDFileUMesh::New();
159 ret=MEDFileCMesh::New();
164 ret=MEDFileCurveLinearMesh::New();
169 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
170 throw INTERP_KERNEL::Exception(oss.str().c_str());
173 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
178 * Writes \a this mesh into an open MED file specified by its descriptor.
179 * \param [in] fid - the MED file descriptor.
180 * \throw If the mesh name is not set.
181 * \throw If the file is open for reading only.
182 * \throw If the writing mode == 1 and the same data is present in an existing file.
184 void MEDFileMesh::write(med_idt fid) const
187 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
189 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
192 const MEDFileEquivalences *eqs(_equiv);
198 * Writes \a this mesh into a MED file specified by its name.
199 * \param [in] fileName - the MED file name.
200 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
201 * - 2 - erase; an existing file is removed.
202 * - 1 - append; same data should not be present in an existing file.
203 * - 0 - overwrite; same data present in an existing file is overwritten.
204 * \throw If the mesh name is not set.
205 * \throw If \a mode == 1 and the same data is present in an existing file.
207 void MEDFileMesh::write(const std::string& fileName, int mode) const
209 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
210 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
211 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
212 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
217 * Checks if \a this and another mesh are equal.
218 * \param [in] other - the mesh to compare with.
219 * \param [in] eps - a precision used to compare real values.
220 * \param [in,out] what - the string returning description of unequal data.
221 * \return bool - \c true if the meshes are equal, \c false, else.
223 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
225 if(_order!=other->_order)
227 what="Orders differ !";
230 if(_iteration!=other->_iteration)
232 what="Iterations differ !";
235 if(fabs(_time-other->_time)>eps)
237 what="Time values differ !";
240 if(_dt_unit!=other->_dt_unit)
242 what="Time units differ !";
245 if(_name!=other->_name)
247 what="Names differ !";
250 //univ_name has been ignored -> not a bug because it is a mutable attribute
251 if(_desc_name!=other->_desc_name)
253 what="Description names differ !";
256 if(!areGrpsEqual(other,what))
258 if(!areFamsEqual(other,what))
260 if(!areEquivalencesEqual(other,what))
265 void MEDFileMesh::setName(const std::string& name)
271 * Clears redundant attributes of incorporated data arrays.
273 void MEDFileMesh::clearNonDiscrAttributes() const
278 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
280 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
282 if((*it).first==_name)
292 * Copies data on groups and families from another mesh.
293 * \param [in] other - the mesh to copy the data from.
295 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
297 _groups=other._groups;
298 _families=other._families;
303 * This method clear all the groups in the map.
304 * So this method does not operate at all on arrays.
305 * So this method can lead to orphan families.
307 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
309 void MEDFileMesh::clearGrpMap()
315 * This method clear all the families in the map.
316 * So this method does not operate at all on arrays.
317 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
319 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
321 void MEDFileMesh::clearFamMap()
327 * This method clear all the families and groups in the map.
328 * So this method does not operate at all on arrays.
329 * As all groups and families entry will be removed after
330 * 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.
332 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
334 void MEDFileMesh::clearFamGrpMaps()
341 * Returns names of families constituting a group.
342 * \param [in] name - the name of the group of interest.
343 * \return std::vector<std::string> - a sequence of names of the families.
344 * \throw If the name of a nonexistent group is specified.
346 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
348 std::string oname(name);
349 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
350 if(it==_groups.end())
352 std::vector<std::string> grps=getGroupsNames();
353 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
354 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
355 throw INTERP_KERNEL::Exception(oss.str().c_str());
361 * Returns names of families constituting some groups.
362 * \param [in] grps - a sequence of names of groups of interest.
363 * \return std::vector<std::string> - a sequence of names of the families.
364 * \throw If a name of a nonexistent group is present in \a grps.
366 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
368 std::set<std::string> fams;
369 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
371 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
372 if(it2==_groups.end())
374 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
375 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
376 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
377 throw INTERP_KERNEL::Exception(oss.str().c_str());
379 fams.insert((*it2).second.begin(),(*it2).second.end());
381 std::vector<std::string> fams2(fams.begin(),fams.end());
386 * Returns ids of families constituting a group.
387 * \param [in] name - the name of the group of interest.
388 * \return std::vector<int> - sequence of ids of the families.
389 * \throw If the name of a nonexistent group is specified.
391 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
393 std::string oname(name);
394 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
395 std::vector<std::string> grps=getGroupsNames();
396 if(it==_groups.end())
398 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
399 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
400 throw INTERP_KERNEL::Exception(oss.str().c_str());
402 return getFamiliesIds((*it).second);
406 * Sets names of families constituting a group. If data on families of this group is
407 * already present, it is overwritten. Every family in \a fams is checked, and if a
408 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
409 * \param [in] name - the name of the group of interest.
410 * \param [in] fams - a sequence of names of families constituting the group.
412 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
414 std::string oname(name);
416 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
418 std::map<std::string,int>::iterator it2=_families.find(*it1);
419 if(it2==_families.end())
425 * Sets families constituting a group. The families are specified by their ids.
426 * If a family name is not found by its id, an exception is thrown.
427 * If several families have same id, the first one in lexical order is taken.
428 * \param [in] name - the name of the group of interest.
429 * \param [in] famIds - a sequence of ids of families constituting the group.
430 * \throw If a family name is not found by its id.
432 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
434 std::string oname(name);
435 std::vector<std::string> fams(famIds.size());
437 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
439 std::string name2=getFamilyNameGivenId(*it1);
446 * Returns names of groups including a given family.
447 * \param [in] name - the name of the family of interest.
448 * \return std::vector<std::string> - a sequence of names of groups including the family.
450 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
452 std::vector<std::string> ret;
453 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
455 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
458 ret.push_back((*it1).first);
466 * Adds an existing family to groups.
467 * \param [in] famName - a name of family to add to \a grps.
468 * \param [in] grps - a sequence of group names to add the family in.
469 * \throw If a family named \a famName not yet exists.
471 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
473 std::string fName(famName);
474 const std::map<std::string,int>::const_iterator it=_families.find(fName);
475 if(it==_families.end())
477 std::vector<std::string> fams=getFamiliesNames();
478 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
479 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
480 throw INTERP_KERNEL::Exception(oss.str().c_str());
482 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
484 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
485 if(it2!=_groups.end())
486 (*it2).second.push_back(fName);
489 std::vector<std::string> grps2(1,fName);
496 * Returns names of all groups of \a this mesh.
497 * \return std::vector<std::string> - a sequence of group names.
499 std::vector<std::string> MEDFileMesh::getGroupsNames() const
501 std::vector<std::string> ret(_groups.size());
503 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
509 * Returns names of all families of \a this mesh.
510 * \return std::vector<std::string> - a sequence of family names.
512 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
514 std::vector<std::string> ret(_families.size());
516 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
522 * Returns names of all families of \a this mesh but like they would be in file.
523 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
524 * 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 !
525 * For your information internaly in memory such families are renamed to have a nicer API.
527 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
529 std::vector<std::string> ret(getFamiliesNames());
530 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
535 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
536 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
537 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
540 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
542 std::vector<std::string> ret;
543 std::vector<std::string> allGrps(getGroupsNames());
544 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
546 std::vector<int> levs(getGrpNonEmptyLevelsExt((*it)));
547 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
554 * Returns all relative mesh levels (including nodes) where a given group is defined.
555 * \param [in] grp - the name of the group of interest.
556 * \return std::vector<int> - a sequence of the relative dimensions.
558 std::vector<int> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
560 std::vector<std::string> fams(getFamiliesOnGroup(grp));
561 return getFamsNonEmptyLevelsExt(fams);
565 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
566 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
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::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
572 std::vector<std::string> fams(getFamiliesOnGroups(grps));
573 return getFamsNonEmptyLevels(fams);
577 * Returns all relative mesh levels (including nodes) where given groups are defined.
578 * \param [in] grps - a sequence of names of the groups of interest.
579 * \return std::vector<int> - a sequence of the relative dimensions.
581 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
583 std::vector<std::string> fams(getFamiliesOnGroups(grps));
584 return getFamsNonEmptyLevelsExt(fams);
588 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
589 * To include nodes, call getGrpNonEmptyLevelsExt() method.
590 * \param [in] grp - the name of the group of interest.
591 * \return std::vector<int> - a sequence of the relative dimensions.
593 std::vector<int> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
595 std::vector<std::string> fams(getFamiliesOnGroup(grp));
596 return getFamsNonEmptyLevels(fams);
600 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
601 * To include nodes, call getFamNonEmptyLevelsExt() method.
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::getFamNonEmptyLevels(const std::string& fam) const
607 std::vector<std::string> fams(1,std::string(fam));
608 return getFamsNonEmptyLevels(fams);
612 * Returns all relative mesh levels (including nodes) where a given family is defined.
613 * \param [in] fam - the name of the family of interest.
614 * \return std::vector<int> - a sequence of the relative dimensions.
616 std::vector<int> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
618 std::vector<std::string> fams(1,std::string(fam));
619 return getFamsNonEmptyLevelsExt(fams);
622 std::string MEDFileMesh::GetMagicFamilyStr()
624 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
628 * Changes a name of every family, included in one group only, to be same as the group name.
629 * \throw If there are families with equal names in \a this mesh.
631 void MEDFileMesh::assignFamilyNameWithGroupName()
633 std::map<std::string, std::vector<std::string> > groups(_groups);
634 std::map<std::string,int> newFams;
635 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
637 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
638 if(grps.size()==1 && groups[grps[0]].size()==1)
640 if(newFams.find(grps[0])!=newFams.end())
642 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
643 throw INTERP_KERNEL::Exception(oss.str().c_str());
645 newFams[grps[0]]=(*it).second;
646 std::vector<std::string>& grps2=groups[grps[0]];
647 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
652 if(newFams.find((*it).first)!=newFams.end())
654 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
655 throw INTERP_KERNEL::Exception(oss.str().c_str());
657 newFams[(*it).first]=(*it).second;
665 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
667 * \return the removed groups.
669 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
671 std::vector<std::string> ret;
672 std::map<std::string, std::vector<std::string> > newGrps;
673 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
675 if((*it).second.empty())
676 ret.push_back((*it).first);
678 newGrps[(*it).first]=(*it).second;
686 * Removes a group from \a this mesh.
687 * \param [in] name - the name of the group to remove.
688 * \throw If no group with such a \a name exists.
690 void MEDFileMesh::removeGroup(const std::string& name)
692 std::string oname(name);
693 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
694 std::vector<std::string> grps=getGroupsNames();
695 if(it==_groups.end())
697 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
698 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
699 throw INTERP_KERNEL::Exception(oss.str().c_str());
705 * Removes a family from \a this mesh.
706 * \param [in] name - the name of the family to remove.
707 * \throw If no family with such a \a name exists.
709 void MEDFileMesh::removeFamily(const std::string& name)
711 std::string oname(name);
712 std::map<std::string, int >::iterator it=_families.find(oname);
713 std::vector<std::string> fams=getFamiliesNames();
714 if(it==_families.end())
716 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
717 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
718 throw INTERP_KERNEL::Exception(oss.str().c_str());
721 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
723 std::vector<std::string>& v=(*it3).second;
724 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
731 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
732 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
733 * family field whatever its level. This method also suppresses the orphan families.
735 * \return - The list of removed groups names.
737 * \sa MEDFileMesh::removeOrphanFamilies.
739 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
741 removeOrphanFamilies();
742 return removeEmptyGroups();
746 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
747 * 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.
749 * \return - The list of removed families names.
750 * \sa MEDFileMesh::removeOrphanGroups.
752 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
754 MCAuto<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
755 std::vector<std::string> ret;
756 if(!((DataArrayInt*)allFamIdsInUse))
758 ret=getFamiliesNames();
759 _families.clear(); _groups.clear();
762 std::map<std::string,int> famMap;
763 std::map<std::string, std::vector<std::string> > grps(_groups);
764 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
766 if(allFamIdsInUse->presenceOfValue((*it).second))
767 famMap[(*it).first]=(*it).second;
770 ret.push_back((*it).first);
771 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
772 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
774 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
775 std::vector<std::string>& famv=(*it3).second;
776 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
782 { _families=famMap; _groups=grps; }
787 * 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
788 * this family is orphan or not.
790 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
792 void MEDFileMesh::removeFamiliesReferedByNoGroups()
794 std::map<std::string,int> fams;
795 std::set<std::string> sfams;
796 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
797 sfams.insert((*it).first);
798 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
799 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
801 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
802 if(*it!=DFT_FAM_NAME)
803 _families.erase(*it);
807 * 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
808 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
809 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
811 * \sa MEDFileMesh::removeOrphanFamilies
813 void MEDFileMesh::rearrangeFamilies()
815 checkOrphanFamilyZero();
816 removeFamiliesReferedByNoGroups();
818 std::vector<int> levels(getNonEmptyLevelsExt());
819 std::set<int> idsRefed;
820 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
821 idsRefed.insert((*it).second);
822 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
824 const DataArrayInt *fams(0);
827 fams=getFamilyFieldAtLevel(*it);
829 catch(INTERP_KERNEL::Exception& e) { }
832 std::vector<bool> v(fams->getNumberOfTuples(),false);
833 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
834 fams->switchOnTupleEqualTo(*pt,v);
835 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
836 if(!unfetchedIds->empty())
838 MCAuto<DataArrayInt> newFams(fams->deepCopy());
839 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
840 setFamilyFieldArr(*it,newFams);
843 removeOrphanFamilies();
847 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
849 void MEDFileMesh::checkOrphanFamilyZero() const
851 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
853 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
855 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
856 throw INTERP_KERNEL::Exception(oss.str().c_str());
862 * Renames a group in \a this mesh.
863 * \param [in] oldName - a current name of the group to rename.
864 * \param [in] newName - a new group name.
865 * \throw If no group named \a oldName exists in \a this mesh.
866 * \throw If a group named \a newName already exists.
868 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
870 std::string oname(oldName);
871 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
872 std::vector<std::string> grps=getGroupsNames();
873 if(it==_groups.end())
875 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
876 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
877 throw INTERP_KERNEL::Exception(oss.str().c_str());
879 std::string nname(newName);
880 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
881 if(it2!=_groups.end())
883 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
884 throw INTERP_KERNEL::Exception(oss.str().c_str());
886 std::vector<std::string> cpy=(*it).second;
888 _groups[newName]=cpy;
892 * Changes an id of a family in \a this mesh.
893 * This method calls changeFamilyIdArr().
894 * \param [in] oldId - a current id of the family.
895 * \param [in] newId - a new family id.
897 void MEDFileMesh::changeFamilyId(int oldId, int newId)
899 changeFamilyIdArr(oldId,newId);
900 std::map<std::string,int> fam2;
901 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
903 if((*it).second==oldId)
904 fam2[(*it).first]=newId;
906 fam2[(*it).first]=(*it).second;
912 * Renames a family in \a this mesh.
913 * \param [in] oldName - a current name of the family to rename.
914 * \param [in] newName - a new family name.
915 * \throw If no family named \a oldName exists in \a this mesh.
916 * \throw If a family named \a newName already exists.
918 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
920 std::string oname(oldName);
921 std::map<std::string, int >::iterator it=_families.find(oname);
922 std::vector<std::string> fams=getFamiliesNames();
923 if(it==_families.end())
925 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
926 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
927 throw INTERP_KERNEL::Exception(oss.str().c_str());
929 std::string nname(newName);
930 std::map<std::string, int >::iterator it2=_families.find(nname);
931 if(it2!=_families.end())
933 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
934 throw INTERP_KERNEL::Exception(oss.str().c_str());
936 int cpy=(*it).second;
938 _families[newName]=cpy;
939 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
941 std::vector<std::string>& v=(*it3).second;
942 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
949 * Checks if \a this and another mesh contains the same families.
950 * \param [in] other - the mesh to compare with \a this one.
951 * \param [in,out] what - an unused parameter.
952 * \return bool - \c true if number of families and their ids are the same in the two
953 * meshes. Families with the id == \c 0 are not considered.
955 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
957 if(_families==other->_families)
959 std::map<std::string,int> fam0;
960 std::map<std::string,int> fam1;
961 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
963 fam0[(*it).first]=(*it).second;
964 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
966 fam1[(*it).first]=(*it).second;
971 * Checks if \a this and another mesh contains the same groups.
972 * \param [in] other - the mesh to compare with \a this one.
973 * \param [in,out] what - a string describing a difference of groups of the two meshes
974 * in case if this method returns \c false.
975 * \return bool - \c true if number of groups and families constituting them are the
976 * same in the two meshes.
978 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
980 if(_groups==other->_groups)
983 std::size_t sz=_groups.size();
984 if(sz!=other->_groups.size())
986 what="Groups differ because not same number !\n";
991 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
992 for(std::size_t i=0;i<sz && ret;i++,it1++)
994 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
995 if(it2!=other->_groups.end())
997 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
998 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1004 what="A group in first mesh exists not in other !\n";
1010 std::ostringstream oss; oss << "Groups description differs :\n";
1011 oss << "First group description :\n";
1012 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1014 oss << " Group \"" << (*it).first << "\" on following families :\n";
1015 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1016 oss << " \"" << *it2 << "\n";
1018 oss << "Second group description :\n";
1019 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1021 oss << " Group \"" << (*it).first << "\" on following families :\n";
1022 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1023 oss << " \"" << *it2 << "\n";
1031 * Checks if a group with a given name exists in \a this mesh.
1032 * \param [in] groupName - the group name.
1033 * \return bool - \c true the group \a groupName exists in \a this mesh.
1035 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1037 std::string grpName(groupName);
1038 return _groups.find(grpName)!=_groups.end();
1042 * Checks if a family with a given id exists in \a this mesh.
1043 * \param [in] famId - the family id.
1044 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1046 bool MEDFileMesh::existsFamily(int famId) const
1048 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1049 if((*it2).second==famId)
1055 * Checks if a family with a given name exists in \a this mesh.
1056 * \param [in] familyName - the family name.
1057 * \return bool - \c true the family \a familyName exists in \a this mesh.
1059 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1061 std::string fname(familyName);
1062 return _families.find(fname)!=_families.end();
1066 * Sets an id of a family.
1067 * \param [in] familyName - the family name.
1068 * \param [in] id - a new id of the family.
1070 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1072 std::string fname(familyName);
1073 _families[fname]=id;
1076 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1078 std::string fname(familyName);
1079 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1080 if((*it).second==id)
1082 if((*it).first!=familyName)
1084 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1085 throw INTERP_KERNEL::Exception(oss.str().c_str());
1088 _families[fname]=id;
1092 * Adds a family to \a this mesh.
1093 * \param [in] familyName - a name of the family.
1094 * \param [in] famId - an id of the family.
1095 * \throw If a family with the same name or id already exists in \a this mesh.
1097 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1099 std::string fname(familyName);
1100 std::map<std::string,int>::const_iterator it=_families.find(fname);
1101 if(it==_families.end())
1103 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1104 if((*it2).second==famId)
1106 std::ostringstream oss;
1107 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1108 throw INTERP_KERNEL::Exception(oss.str().c_str());
1110 _families[fname]=famId;
1114 if((*it).second!=famId)
1116 std::ostringstream oss;
1117 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1118 throw INTERP_KERNEL::Exception(oss.str().c_str());
1124 * Creates a group including all mesh entities of given dimension.
1125 * \warning This method does \b not guarantee that the created group includes mesh
1126 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1127 * present in family fields of different dimensions. To assure this, call
1128 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1129 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1131 * \param [in] groupName - a name of the new group.
1132 * \throw If a group named \a groupName already exists.
1133 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1134 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1136 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1138 std::string grpName(groupName);
1139 std::vector<int> levs=getNonEmptyLevelsExt();
1140 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1142 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1143 oss << "Available relative ext levels are : ";
1144 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1145 throw INTERP_KERNEL::Exception(oss.str().c_str());
1147 if(existsGroup(groupName))
1149 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1150 oss << "Already existing groups are : ";
1151 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1152 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1153 throw INTERP_KERNEL::Exception(oss.str().c_str());
1155 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1157 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1158 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1159 std::vector<std::string> familiesOnWholeGroup;
1160 for(const int *it=famIds->begin();it!=famIds->end();it++)
1163 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1165 _groups[grpName]=familiesOnWholeGroup;
1169 * Ensures that given family ids do not present in family fields of dimensions different
1170 * than given ones. If a family id is present in the family fields of dimensions different
1171 * than the given ones, a new family is created and the whole data is updated accordingly.
1172 * \param [in] famIds - a sequence of family ids to check.
1173 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1174 * famIds should exclusively belong.
1175 * \return bool - \c true if no modification is done in \a this mesh by this method.
1177 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1179 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1180 std::vector<int> levs=getNonEmptyLevelsExt();
1181 std::set<int> levs2(levs.begin(),levs.end());
1182 std::vector<int> levsToTest;
1183 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1184 std::set<int> famIds2(famIds.begin(),famIds.end());
1187 if(!_families.empty())
1188 maxFamId=getMaxFamilyId()+1;
1189 std::vector<std::string> allFams=getFamiliesNames();
1190 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1192 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1195 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1196 std::vector<int> tmp;
1197 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1198 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1201 std::string famName=getFamilyNameGivenId(*it2);
1202 std::ostringstream oss; oss << "Family_" << maxFamId;
1203 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1204 addFamilyOnAllGroupsHaving(famName,zeName);
1205 _families[zeName]=maxFamId;
1206 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1215 * Adds a family to a given group in \a this mesh. If the group with a given name does
1216 * not exist, it is created.
1217 * \param [in] grpName - the name of the group to add the family in.
1218 * \param [in] famName - the name of the family to add to the group named \a grpName.
1219 * \throw If \a grpName or \a famName is an empty string.
1220 * \throw If no family named \a famName is present in \a this mesh.
1222 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1224 std::string grpn(grpName);
1225 std::string famn(famName);
1226 if(grpn.empty() || famn.empty())
1227 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1228 std::vector<std::string> fams=getFamiliesNames();
1229 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1231 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1232 oss << "Create this family or choose an existing one ! Existing fams are : ";
1233 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1234 throw INTERP_KERNEL::Exception(oss.str().c_str());
1236 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1237 if(it==_groups.end())
1239 _groups[grpn].push_back(famn);
1243 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1244 if(it2==(*it).second.end())
1245 (*it).second.push_back(famn);
1250 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1251 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1252 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1254 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1256 std::string famNameCpp(famName);
1257 std::string otherCpp(otherFamName);
1258 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1260 std::vector<std::string>& v=(*it).second;
1261 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1263 v.push_back(otherCpp);
1269 * \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).
1270 * \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)
1272 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1275 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1276 std::string grpName(ids->getName());
1278 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1279 ids->checkStrictlyMonotonic(true);
1280 famArr->incrRef(); MCAuto<DataArrayInt> famArrTmp(famArr);
1281 std::vector<std::string> grpsNames=getGroupsNames();
1282 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1284 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1285 throw INTERP_KERNEL::Exception(oss.str().c_str());
1287 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1288 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1289 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1290 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1291 std::vector<int> familyIds;
1292 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1293 int maxVal=getTheMaxAbsFamilyId()+1;
1294 std::map<std::string,int> families(_families);
1295 std::map<std::string, std::vector<std::string> > groups(_groups);
1296 std::vector<std::string> fams;
1297 bool created(false);
1298 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1300 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1301 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1302 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1303 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1306 bool isFamPresent=false;
1307 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1308 isFamPresent=(*itl)->presenceOfValue(*famId);
1310 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1313 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1314 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1315 fams.push_back(locFamName);
1316 if(existsFamily(*famId))
1318 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1319 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1322 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1326 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1327 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1328 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1329 if(existsFamily(*famId))
1331 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1332 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1337 for(std::size_t i=0;i<familyIds.size();i++)
1339 DataArrayInt *da=idsPerfamiliyIds[i];
1340 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1344 _groups[grpName]=fams;
1347 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1349 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1352 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1354 std::string fam(familyNameToChange);
1355 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1357 std::vector<std::string>& fams((*it).second);
1358 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1362 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1368 * Returns a name of the family having a given id or, if no such a family exists, creates
1369 * a new uniquely named family and returns its name.
1370 * \param [in] id - the id of the family whose name is required.
1371 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1372 * \return std::string - the name of the existing or the created family.
1373 * \throw If it is not possible to create a unique family name.
1375 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1377 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1381 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1382 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1383 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1384 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1386 * This method will throws an exception if it is not possible to create a unique family name.
1388 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1390 std::vector<std::string> famAlreadyExisting(families.size());
1392 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1394 if((*it).second!=id)
1396 famAlreadyExisting[ii]=(*it).first;
1405 std::ostringstream oss; oss << "Family_" << id;
1406 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1412 * Sets names and ids of all families in \a this mesh.
1413 * \param [in] info - a map of a family name to a family id.
1415 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1421 * Sets names of all groups and families constituting them in \a this mesh.
1422 * \param [in] info - a map of a group name to a vector of names of families
1423 * constituting the group.
1425 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1431 * Returns an id of the family having a given name.
1432 * \param [in] name - the name of the family of interest.
1433 * \return int - the id of the family of interest.
1434 * \throw If no family with such a \a name exists.
1436 int MEDFileMesh::getFamilyId(const std::string& name) const
1438 std::map<std::string, int>::const_iterator it=_families.find(name);
1439 if(it==_families.end())
1441 std::vector<std::string> fams(getFamiliesNames());
1442 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1443 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1444 throw INTERP_KERNEL::Exception(oss.str().c_str());
1446 return (*it).second;
1450 * Returns ids of the families having given names.
1451 * \param [in] fams - a sequence of the names of families of interest.
1452 * \return std::vector<int> - a sequence of the ids of families of interest.
1453 * \throw If \a fams contains a name of an inexistent family.
1455 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1457 std::vector<int> ret(fams.size());
1459 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1461 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1462 if(it2==_families.end())
1464 std::vector<std::string> fams2=getFamiliesNames();
1465 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1466 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1467 throw INTERP_KERNEL::Exception(oss.str().c_str());
1469 ret[i]=(*it2).second;
1475 * Returns a maximal abs(id) of families in \a this mesh.
1476 * \return int - the maximal norm of family id.
1477 * \throw If there are no families in \a this mesh.
1479 int MEDFileMesh::getMaxAbsFamilyId() const
1481 if(_families.empty())
1482 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1483 int ret=-std::numeric_limits<int>::max();
1484 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1486 ret=std::max(std::abs((*it).second),ret);
1492 * Returns a maximal id of families in \a this mesh.
1493 * \return int - the maximal family id.
1494 * \throw If there are no families in \a this mesh.
1496 int MEDFileMesh::getMaxFamilyId() const
1498 if(_families.empty())
1499 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1500 int ret=-std::numeric_limits<int>::max();
1501 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1503 ret=std::max((*it).second,ret);
1509 * Returns a minimal id of families in \a this mesh.
1510 * \return int - the minimal family id.
1511 * \throw If there are no families in \a this mesh.
1513 int MEDFileMesh::getMinFamilyId() const
1515 if(_families.empty())
1516 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1517 int ret=std::numeric_limits<int>::max();
1518 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1520 ret=std::min((*it).second,ret);
1526 * Returns a maximal id of families in \a this mesh. Not only named families are
1527 * considered but all family fields as well.
1528 * \return int - the maximal family id.
1530 int MEDFileMesh::getTheMaxAbsFamilyId() const
1532 int m1=-std::numeric_limits<int>::max();
1533 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1534 m1=std::max(std::abs((*it).second),m1);
1535 int m2=getMaxAbsFamilyIdInArrays();
1536 return std::max(m1,m2);
1540 * Returns a maximal id of families in \a this mesh. Not only named families are
1541 * considered but all family fields as well.
1542 * \return int - the maximal family id.
1544 int MEDFileMesh::getTheMaxFamilyId() const
1546 int m1=-std::numeric_limits<int>::max();
1547 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1548 m1=std::max((*it).second,m1);
1549 int m2=getMaxFamilyIdInArrays();
1550 return std::max(m1,m2);
1554 * Returns a minimal id of families in \a this mesh. Not only named families are
1555 * considered but all family fields as well.
1556 * \return int - the minimal family id.
1558 int MEDFileMesh::getTheMinFamilyId() const
1560 int m1=std::numeric_limits<int>::max();
1561 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1562 m1=std::min((*it).second,m1);
1563 int m2=getMinFamilyIdInArrays();
1564 return std::min(m1,m2);
1568 * This method only considers the maps. The contain of family array is ignored here.
1570 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1572 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1574 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1576 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1577 v.insert((*it).second);
1578 ret->alloc((int)v.size(),1);
1579 std::copy(v.begin(),v.end(),ret->getPointer());
1584 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1586 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1588 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1590 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1591 MCAuto<DataArrayInt> ret;
1592 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1594 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1595 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1596 if((DataArrayInt *) ret)
1597 ret=dv->buildUnion(ret);
1605 * true is returned if no modification has been needed. false if family
1606 * renumbering has been needed.
1608 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1610 std::vector<int> levs=getNonEmptyLevelsExt();
1611 std::set<int> allFamIds;
1612 int maxId=getMaxFamilyId()+1;
1613 std::map<int,std::vector<int> > famIdsToRenum;
1614 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1616 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1619 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1621 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1623 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1625 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1628 if(famIdsToRenum.empty())
1630 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1631 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1633 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1634 int *famIdsToChange=fam->getPointer();
1635 std::map<int,int> ren;
1636 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1638 if(allIds->presenceOfValue(*it3))
1640 std::string famName=getFamilyNameGivenId(*it3);
1641 std::vector<std::string> grps=getGroupsOnFamily(famName);
1644 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1645 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1646 addFamilyOnGrp((*it4),newFam);
1649 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1650 for(const int *id=ids->begin();id!=ids->end();id++)
1651 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1657 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1658 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1659 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1660 * This method will throw an exception if a same family id is detected in different level.
1661 * \warning This policy is the opposite of those in MED file documentation ...
1663 void MEDFileMesh::normalizeFamIdsTrio()
1665 ensureDifferentFamIdsPerLevel();
1666 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1667 std::vector<int> levs=getNonEmptyLevelsExt();
1668 std::set<int> levsS(levs.begin(),levs.end());
1669 std::set<std::string> famsFetched;
1670 std::map<std::string,int> families;
1671 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1674 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1678 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1679 std::map<int,int> ren;
1680 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1682 int nbOfTuples=fam->getNumberOfTuples();
1683 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1684 for(int *w=start;w!=start+nbOfTuples;w++)
1686 for(const int *it=tmp->begin();it!=tmp->end();it++)
1688 if(allIds->presenceOfValue(*it))
1690 std::string famName=getFamilyNameGivenId(*it);
1691 families[famName]=ren[*it];
1692 famsFetched.insert(famName);
1697 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1700 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1704 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1705 std::map<int,int> ren;
1706 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1708 int nbOfTuples=fam->getNumberOfTuples();
1709 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1710 for(int *w=start;w!=start+nbOfTuples;w++)
1712 for(const int *it=tmp->begin();it!=tmp->end();it++)
1714 if(allIds->presenceOfValue(*it))
1716 std::string famName=getFamilyNameGivenId(*it);
1717 families[famName]=ren[*it];
1718 famsFetched.insert(famName);
1723 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1725 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1728 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1729 fam->fillWithZero();
1730 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1731 if(allIds->presenceOfValue(*it3))
1733 std::string famName=getFamilyNameGivenId(*it3);
1734 families[famName]=0;
1735 famsFetched.insert(famName);
1740 std::vector<std::string> allFams=getFamiliesNames();
1741 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1742 std::set<std::string> unFetchedIds;
1743 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1744 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1745 families[*it4]=_families[*it4];
1750 * This method normalizes fam id with the following policy.
1751 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1752 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1753 * This method will throw an exception if a same family id is detected in different level.
1755 void MEDFileMesh::normalizeFamIdsMEDFile()
1757 ensureDifferentFamIdsPerLevel();
1758 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1759 std::vector<int> levs=getNonEmptyLevelsExt();
1760 std::set<int> levsS(levs.begin(),levs.end());
1761 std::set<std::string> famsFetched;
1762 std::map<std::string,int> families;
1764 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1767 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1770 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1771 std::map<int,int> ren;
1772 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1774 int nbOfTuples=fam->getNumberOfTuples();
1775 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1776 for(int *w=start;w!=start+nbOfTuples;w++)
1778 for(const int *it=tmp->begin();it!=tmp->end();it++)
1780 if(allIds->presenceOfValue(*it))
1782 std::string famName=getFamilyNameGivenId(*it);
1783 families[famName]=ren[*it];
1784 famsFetched.insert(famName);
1790 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1792 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1795 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1796 std::map<int,int> ren;
1797 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1799 int nbOfTuples=fam->getNumberOfTuples();
1800 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1801 for(int *w=start;w!=start+nbOfTuples;w++)
1803 for(const int *it=tmp->begin();it!=tmp->end();it++)
1805 if(allIds->presenceOfValue(*it))
1807 std::string famName=getFamilyNameGivenId(*it);
1808 families[famName]=ren[*it];
1809 famsFetched.insert(famName);
1815 std::vector<std::string> allFams=getFamiliesNames();
1816 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1817 std::set<std::string> unFetchedIds;
1818 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1819 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1820 families[*it4]=_families[*it4];
1825 * Returns a name of the family by its id. If there are several families having the given
1826 * id, the name first in lexical order is returned.
1827 * \param [in] id - the id of the family whose name is required.
1828 * \return std::string - the name of the found family.
1829 * \throw If no family with the given \a id exists.
1831 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1833 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1834 if((*it).second==id)
1836 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1837 throw INTERP_KERNEL::Exception(oss.str().c_str());
1841 * Returns a string describing \a this mesh. This description includes the mesh name and
1842 * the mesh description string.
1843 * \return std::string - the mesh information string.
1845 std::string MEDFileMesh::simpleRepr() const
1847 std::ostringstream oss;
1848 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1849 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1850 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1855 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1856 * an empty one is created.
1858 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1860 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1863 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1864 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1865 arr->fillWithZero();
1866 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1867 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1871 * Returns ids of mesh entities contained in a given group of a given dimension.
1872 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1874 * \param [in] grp - the name of the group of interest.
1875 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1876 * returned instead of ids.
1877 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1878 * numbers, if available and required, of mesh entities of the group. The caller
1879 * is to delete this array using decrRef() as it is no more needed.
1880 * \throw If the name of a nonexistent group is specified.
1881 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1883 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1885 std::vector<std::string> tmp(1);
1887 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1893 * Returns ids of mesh entities contained in given groups of a given dimension.
1894 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1896 * \param [in] grps - the names of the groups of interest.
1897 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1898 * returned instead of ids.
1899 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1900 * numbers, if available and required, of mesh entities of the groups. The caller
1901 * is to delete this array using decrRef() as it is no more needed.
1902 * \throw If the name of a nonexistent group is present in \a grps.
1903 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1905 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1907 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1908 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1912 * Returns ids of mesh entities contained in a given family of a given dimension.
1913 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1915 * \param [in] fam - the name of the family of interest.
1916 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1917 * returned instead of ids.
1918 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1919 * numbers, if available and required, of mesh entities of the family. The caller
1920 * is to delete this array using decrRef() as it is no more needed.
1921 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1923 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1925 std::vector<std::string> tmp(1);
1927 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1933 * Returns ids of nodes contained in a given group.
1934 * \param [in] grp - the name of the group of interest.
1935 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1936 * returned instead of ids.
1937 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1938 * numbers, if available and required, of nodes of the group. The caller
1939 * is to delete this array using decrRef() as it is no more needed.
1940 * \throw If the name of a nonexistent group is specified.
1941 * \throw If the family field is missing for nodes.
1943 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1945 std::vector<std::string> tmp(1);
1947 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1953 * Returns ids of nodes contained in given groups.
1954 * \param [in] grps - the names of the groups of interest.
1955 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1956 * returned instead of ids.
1957 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1958 * numbers, if available and required, of nodes of the groups. The caller
1959 * is to delete this array using decrRef() as it is no more needed.
1960 * \throw If the name of a nonexistent group is present in \a grps.
1961 * \throw If the family field is missing for nodes.
1963 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1965 return getGroupsArr(1,grps,renum);
1969 * Returns ids of nodes contained in a given group.
1970 * \param [in] grp - the name of the group of interest.
1971 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1972 * returned instead of ids.
1973 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1974 * numbers, if available and required, of nodes of the group. The caller
1975 * is to delete this array using decrRef() as it is no more needed.
1976 * \throw If the name of a nonexistent group is specified.
1977 * \throw If the family field is missing for nodes.
1979 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1981 std::vector<std::string> tmp(1);
1983 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1989 * Returns ids of nodes contained in given families.
1990 * \param [in] fams - the names of the families of interest.
1991 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1992 * returned instead of ids.
1993 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1994 * numbers, if available and required, of nodes of the families. The caller
1995 * is to delete this array using decrRef() as it is no more needed.
1996 * \throw If the family field is missing for nodes.
1998 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
2000 return getFamiliesArr(1,fams,renum);
2004 * Adds groups of given dimension and creates corresponding families and family fields
2005 * given ids of mesh entities of each group.
2006 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2007 * \param [in] grps - a sequence of arrays of ids each describing a group.
2008 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2010 * \throw If names of some groups in \a grps are equal.
2011 * \throw If \a grps includes a group with an empty name.
2012 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2013 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2015 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2019 std::set<std::string> grpsName;
2020 std::vector<std::string> grpsName2(grps.size());
2023 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2025 grpsName.insert((*it)->getName());
2026 grpsName2[i]=(*it)->getName();
2028 if(grpsName.size()!=grps.size())
2029 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2030 if(grpsName.find(std::string(""))!=grpsName.end())
2031 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2032 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2033 MCAuto<DataArrayInt> fam;
2034 std::vector< std::vector<int> > fidsOfGroups;
2037 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2041 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2042 for(unsigned int ii=0;ii<grps.size();ii++)
2044 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2045 grps2[ii]->setName(grps[ii]->getName());
2047 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2048 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2051 if(!_families.empty())
2052 offset=getMaxAbsFamilyId()+1;
2053 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2054 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2055 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2056 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2060 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2061 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2062 * For the moment, the two last input parameters are not taken into account.
2064 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2066 std::map<int,std::string> famInv;
2067 for(const int *it=famIds->begin();it!=famIds->end();it++)
2069 std::ostringstream oss;
2070 oss << "Family_" << (*it);
2071 _families[oss.str()]=(*it);
2072 famInv[*it]=oss.str();
2075 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2077 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2079 _groups[grpNames[i]].push_back(famInv[*it2]);
2084 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2086 std::vector<int> levs(getNonEmptyLevels());
2087 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2088 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2090 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2091 ret.insert(ret.end(),elts.begin(),elts.end());
2097 * \sa getAllDistributionOfTypes
2099 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2101 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2102 return mLev->getDistributionOfTypes();
2105 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2107 loadLL(fid,mName,dt,it,mrs);
2108 loadJointsFromFile(fid);
2109 loadEquivalences(fid);
2112 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2114 famArr->applyLin(offset>0?1:-1,offset,0);
2115 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2118 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2119 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2124 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2125 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2126 * If this method fails to find such a name it will throw an exception.
2128 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2131 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2134 std::size_t len=nameTry.length();
2135 for(std::size_t ii=1;ii<len;ii++)
2137 std::string tmp=nameTry.substr(ii,len-ii);
2138 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2144 for(std::size_t i=1;i<30;i++)
2146 std::string tmp1(nameTry.at(0),i);
2148 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2154 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2156 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2158 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2161 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2163 std::size_t nbOfChunks=code.size()/3;
2164 if(code.size()%3!=0)
2165 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2167 for(std::size_t i=0;i<nbOfChunks;i++)
2176 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2177 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2178 * If _name is not empty and that 'm' has the same name nothing is done.
2179 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2181 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2184 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2189 std::string name(m->getName());
2194 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2195 oss << name << "' ! Names must match !";
2196 throw INTERP_KERNEL::Exception(oss.str().c_str());
2200 if(_desc_name.empty())
2201 _desc_name=m->getDescription();
2204 std::string name(m->getDescription());
2207 if(_desc_name!=name)
2209 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2210 oss << name << "' ! Names must match !";
2211 throw INTERP_KERNEL::Exception(oss.str().c_str());
2217 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2219 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2220 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2222 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2223 oss << " - Groups lying on this family : ";
2224 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2225 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2226 oss << std::endl << std::endl;
2231 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2232 * file. The mesh to load is specified by its name and numbers of a time step and an
2234 * \param [in] fileName - the name of MED file to read.
2235 * \param [in] mName - the name of the mesh to read.
2236 * \param [in] dt - the number of a time step.
2237 * \param [in] it - the number of an iteration.
2238 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2239 * mesh using decrRef() as it is no more needed.
2240 * \throw If the file is not readable.
2241 * \throw If there is no mesh with given attributes in the file.
2242 * \throw If the mesh in the file is not an unstructured one.
2244 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2246 MEDFileUtilities::CheckFileForRead(fileName);
2247 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2248 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2252 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2253 * file. The first mesh in the file is loaded.
2254 * \param [in] fileName - the name of MED file to read.
2255 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2256 * mesh using decrRef() as it is no more needed.
2257 * \throw If the file is not readable.
2258 * \throw If there is no meshes in the file.
2259 * \throw If the mesh in the file is not an unstructured one.
2261 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2263 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
2266 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2267 throw INTERP_KERNEL::Exception(oss.str().c_str());
2269 MEDFileUtilities::CheckFileForRead(fileName);
2270 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2272 MEDCoupling::MEDCouplingMeshType meshType;
2274 MEDCoupling::MEDCouplingAxisType dummy3;
2275 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2276 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2280 * \b WARNING this implementation is dependant from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2281 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2283 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2286 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2287 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2288 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2289 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2291 m2D->setCoords(m3D->getCoords());
2292 ret->setMeshAtLevel(0,m3D);
2293 ret->setMeshAtLevel(-1,m2D);
2294 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2299 * Returns an empty instance of MEDFileUMesh.
2300 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2301 * mesh using decrRef() as it is no more needed.
2303 MEDFileUMesh *MEDFileUMesh::New()
2305 return new MEDFileUMesh;
2309 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2310 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2311 * \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.
2312 * 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
2313 * at most the memory consumtion.
2315 * \param [in] fileName - the name of the file.
2316 * \param [in] mName - the name of the mesh to be read.
2317 * \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.
2318 * \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.
2319 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2320 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2321 * \param [in] mrs - the request for what to be loaded.
2322 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2324 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)
2326 MEDFileUtilities::CheckFileForRead(fileName);
2327 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2328 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2332 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2333 * This method is \b NOT wrapped into python.
2335 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)
2337 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2338 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2342 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2344 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2345 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>));
2349 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2351 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2352 ret.push_back((const DataArrayDouble*)_coords);
2353 ret.push_back((const DataArrayInt *)_fam_coords);
2354 ret.push_back((const DataArrayInt *)_num_coords);
2355 ret.push_back((const DataArrayInt *)_rev_num_coords);
2356 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2357 ret.push_back((const PartDefinition *)_part_coords);
2358 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2359 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2363 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2365 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2369 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2371 return new MEDFileUMesh;
2374 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2376 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2377 ret->deepCpyEquivalences(*this);
2378 if((const DataArrayDouble*)_coords)
2379 ret->_coords=_coords->deepCopy();
2380 if((const DataArrayInt*)_fam_coords)
2381 ret->_fam_coords=_fam_coords->deepCopy();
2382 if((const DataArrayInt*)_num_coords)
2383 ret->_num_coords=_num_coords->deepCopy();
2384 if((const DataArrayInt*)_rev_num_coords)
2385 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2386 if((const DataArrayAsciiChar*)_name_coords)
2387 ret->_name_coords=_name_coords->deepCopy();
2389 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2391 if((const MEDFileUMeshSplitL1 *)(*it))
2392 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2394 if((const PartDefinition*)_part_coords)
2395 ret->_part_coords=_part_coords->deepCopy();
2400 * Checks if \a this and another mesh are equal.
2401 * \param [in] other - the mesh to compare with.
2402 * \param [in] eps - a precision used to compare real values.
2403 * \param [in,out] what - the string returning description of unequal data.
2404 * \return bool - \c true if the meshes are equal, \c false, else.
2406 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2408 if(!MEDFileMesh::isEqual(other,eps,what))
2410 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2413 what="Mesh types differ ! This is unstructured and other is NOT !";
2416 clearNonDiscrAttributes();
2417 otherC->clearNonDiscrAttributes();
2418 const DataArrayDouble *coo1=_coords;
2419 const DataArrayDouble *coo2=otherC->_coords;
2420 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2422 what="Mismatch of coordinates ! One is defined and not other !";
2427 bool ret=coo1->isEqual(*coo2,eps);
2430 what="Coords differ !";
2434 const DataArrayInt *famc1=_fam_coords;
2435 const DataArrayInt *famc2=otherC->_fam_coords;
2436 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2438 what="Mismatch of families arr on nodes ! One is defined and not other !";
2443 bool ret=famc1->isEqual(*famc2);
2446 what="Families arr on node differ !";
2450 const DataArrayInt *numc1=_num_coords;
2451 const DataArrayInt *numc2=otherC->_num_coords;
2452 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2454 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2459 bool ret=numc1->isEqual(*numc2);
2462 what="Numbering arr on node differ !";
2466 const DataArrayAsciiChar *namec1=_name_coords;
2467 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2468 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2470 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2475 bool ret=namec1->isEqual(*namec2);
2478 what="Names arr on node differ !";
2482 if(_ms.size()!=otherC->_ms.size())
2484 what="Number of levels differs !";
2487 std::size_t sz=_ms.size();
2488 for(std::size_t i=0;i<sz;i++)
2490 const MEDFileUMeshSplitL1 *s1=_ms[i];
2491 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2492 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2494 what="Mismatch of presence of sub levels !";
2499 bool ret=s1->isEqual(s2,eps,what);
2504 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2507 if((!pd0 && pd1) || (pd0 && !pd1))
2509 what=std::string("node part def is defined only for one among this or other !");
2512 return pd0->isEqual(pd1,what);
2516 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2517 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2518 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2519 * \throw if internal family array is inconsistent
2520 * \sa checkSMESHConsistency()
2522 void MEDFileUMesh::checkConsistency() const
2524 if(!_coords || !_coords->isAllocated())
2527 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2529 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2530 if (!_num_coords || !_rev_num_coords)
2531 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2535 int nbCoo = _coords->getNumberOfTuples();
2537 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2540 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2542 int maxValue=_num_coords->getMaxValue(pos);
2543 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2544 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2546 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2547 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2548 if (_num_coords && !_num_coords->hasUniqueValues())
2549 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2551 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2552 // Now sub part check:
2553 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2554 it != _ms.end(); it++)
2555 (*it)->checkConsistency();
2560 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2561 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2562 * entities as it likes), or non overlapping between all sub-levels.
2563 * \throw if the condition above is not respected
2565 void MEDFileUMesh::checkSMESHConsistency() const
2568 // For all sub-levels, numbering is either always null or with void intersection:
2571 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2572 std::vector< const DataArrayInt * > v;
2573 bool voidOrNot = ((*it)->_num == 0);
2574 for (it++; it != _ms.end(); it++)
2575 if( ((*it)->_num == 0) != voidOrNot )
2576 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2577 else if (!voidOrNot)
2578 v.push_back((*it)->_num);
2581 // don't forget the 1st one:
2582 v.push_back(_ms[0]->_num);
2583 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2584 if (inter->getNumberOfTuples())
2585 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2591 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2592 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2594 void MEDFileUMesh::clearNodeAndCellNumbers()
2597 _rev_num_coords = 0;
2598 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
2599 it != _ms.end(); it++)
2602 (*it)->_rev_num = 0;
2607 * Clears redundant attributes of incorporated data arrays.
2609 void MEDFileUMesh::clearNonDiscrAttributes() const
2611 MEDFileMesh::clearNonDiscrAttributes();
2612 const DataArrayDouble *coo1=_coords;
2614 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2615 const DataArrayInt *famc1=_fam_coords;
2617 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2618 const DataArrayInt *numc1=_num_coords;
2620 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2621 const DataArrayAsciiChar *namc1=_name_coords;
2623 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2624 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2626 const MEDFileUMeshSplitL1 *tmp=(*it);
2628 tmp->clearNonDiscrAttributes();
2632 void MEDFileUMesh::setName(const std::string& name)
2634 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2635 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2636 (*it)->setName(name);
2637 MEDFileMesh::setName(name);
2640 MEDFileUMesh::MEDFileUMesh()
2644 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2647 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2649 catch(INTERP_KERNEL::Exception& e)
2655 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2656 * See MEDFileUMesh::LoadPartOf for detailed description.
2660 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)
2662 MEDFileUMeshL2 loaderl2;
2663 MEDCoupling::MEDCouplingMeshType meshType;
2666 MEDCoupling::MEDCouplingAxisType dummy3;
2667 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2668 if(meshType!=UNSTRUCTURED)
2670 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2671 throw INTERP_KERNEL::Exception(oss.str().c_str());
2673 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2674 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2678 * \brief Write joints in a file
2680 void MEDFileMesh::writeJoints(med_idt fid) const
2682 if ( (const MEDFileJoints*) _joints )
2683 _joints->write(fid);
2687 * \brief Load joints in a file or use provided ones
2689 //================================================================================
2691 * \brief Load joints in a file or use provided ones
2692 * \param [in] fid - MED file descriptor
2693 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2694 * Usually this joints are those just read by another iteration
2695 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2697 //================================================================================
2699 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2701 if ( toUseInstedOfReading )
2702 setJoints( toUseInstedOfReading );
2704 _joints = MEDFileJoints::New( fid, _name );
2707 void MEDFileMesh::loadEquivalences(med_idt fid)
2709 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2711 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2714 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2716 const MEDFileEquivalences *equiv(other._equiv);
2718 _equiv=equiv->deepCopy(this);
2721 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2723 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2724 if(!thisEq && !otherEq)
2726 if(thisEq && otherEq)
2727 return thisEq->isEqual(otherEq,what);
2730 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2735 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2737 const MEDFileEquivalences *equiv(_equiv);
2740 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2741 _equiv->getRepr(oss);
2744 void MEDFileMesh::checkCartesian() const
2746 if(getAxisType()!=AX_CART)
2748 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()) << ").";
2749 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2750 oss << " - call setAxisType(AX_CART)" << std::endl;
2751 oss << " - call cartesianize()";
2752 throw INTERP_KERNEL::Exception(oss.str().c_str());
2757 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2759 int MEDFileMesh::getNumberOfJoints() const
2761 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2765 * \brief Return joints with all adjacent mesh domains
2767 MEDFileJoints * MEDFileMesh::getJoints() const
2769 return const_cast<MEDFileJoints*>(& (*_joints));
2772 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2774 if ( joints != _joints )
2783 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2785 * \sa loadPartUMeshFromFile
2787 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2789 MEDFileUMeshL2 loaderl2;
2790 MEDCoupling::MEDCouplingMeshType meshType;
2793 MEDCoupling::MEDCouplingAxisType axType;
2794 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2795 setAxisType(axType);
2796 if(meshType!=UNSTRUCTURED)
2798 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2799 throw INTERP_KERNEL::Exception(oss.str().c_str());
2801 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2802 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2805 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2807 int lev=loaderl2.getNumberOfLevels();
2809 for(int i=0;i<lev;i++)
2811 if(!loaderl2.emptyLev(i))
2812 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2816 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2818 setName(loaderl2.getName());
2819 setDescription(loaderl2.getDescription());
2820 setUnivName(loaderl2.getUnivName());
2821 setIteration(loaderl2.getIteration());
2822 setOrder(loaderl2.getOrder());
2823 setTimeValue(loaderl2.getTime());
2824 setTimeUnit(loaderl2.getTimeUnit());
2825 _coords=loaderl2.getCoords();
2826 if(!mrs || mrs->isNodeFamilyFieldReading())
2827 _fam_coords=loaderl2.getCoordsFamily();
2828 if(!mrs || mrs->isNodeNumFieldReading())
2829 _num_coords=loaderl2.getCoordsNum();
2830 if(!mrs || mrs->isNodeNameFieldReading())
2831 _name_coords=loaderl2.getCoordsName();
2832 _part_coords=loaderl2.getPartDefOfCoo();
2836 MEDFileUMesh::~MEDFileUMesh()
2840 void MEDFileUMesh::writeLL(med_idt fid) const
2842 const DataArrayDouble *coo=_coords;
2843 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2844 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2845 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2846 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2847 int spaceDim=coo?coo->getNumberOfComponents():0;
2850 mdim=getMeshDimension();
2851 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2852 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2853 for(int i=0;i<spaceDim;i++)
2855 std::string info=coo->getInfoOnComponent(i);
2857 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2858 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
2859 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
2861 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2863 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2864 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2865 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2866 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2867 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2868 (*it)->write(fid,meshName,mdim);
2869 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2873 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2874 * \return std::vector<int> - a sequence of the relative dimensions.
2876 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2878 std::vector<int> ret;
2880 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2881 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2888 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2889 * \return std::vector<int> - a sequence of the relative dimensions.
2891 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2893 std::vector<int> ret0=getNonEmptyLevels();
2894 if((const DataArrayDouble *) _coords)
2896 std::vector<int> ret(ret0.size()+1);
2898 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2904 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2906 std::vector<int> ret;
2907 const DataArrayInt *famCoo(_fam_coords);
2911 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2913 const MEDFileUMeshSplitL1 *cur(*it);
2915 if(cur->getFamilyField())
2921 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2923 std::vector<int> ret;
2924 const DataArrayInt *numCoo(_num_coords);
2928 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2930 const MEDFileUMeshSplitL1 *cur(*it);
2932 if(cur->getNumberField())
2938 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2940 std::vector<int> ret;
2941 const DataArrayAsciiChar *nameCoo(_name_coords);
2945 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2947 const MEDFileUMeshSplitL1 *cur(*it);
2949 if(cur->getNameField())
2956 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2957 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2958 * \param [in] fams - the name of the family of interest.
2959 * \return std::vector<int> - a sequence of the relative dimensions.
2961 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2963 std::vector<int> ret;
2964 std::vector<int> levs(getNonEmptyLevels());
2965 std::vector<int> famIds(getFamiliesIds(fams));
2966 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2967 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2973 * Returns all relative mesh levels (including nodes) where given families are defined.
2974 * \param [in] fams - the names of the families of interest.
2975 * \return std::vector<int> - a sequence of the relative dimensions.
2977 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2979 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2980 const DataArrayInt *famCoords(_fam_coords);
2983 std::vector<int> famIds(getFamiliesIds(fams));
2984 if(famCoords->presenceOfValue(famIds))
2986 std::vector<int> ret(ret0.size()+1);
2988 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2995 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2997 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2998 if((const DataArrayInt *)_fam_coords)
3000 int val=_fam_coords->getMaxValue(tmp);
3001 ret=std::max(ret,std::abs(val));
3003 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3005 if((const MEDFileUMeshSplitL1 *)(*it))
3007 const DataArrayInt *da=(*it)->getFamilyField();
3010 int val=da->getMaxValue(tmp);
3011 ret=std::max(ret,std::abs(val));
3018 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3020 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3021 if((const DataArrayInt *)_fam_coords)
3023 int val=_fam_coords->getMaxValue(tmp);
3024 ret=std::max(ret,val);
3026 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3028 if((const MEDFileUMeshSplitL1 *)(*it))
3030 const DataArrayInt *da=(*it)->getFamilyField();
3033 int val=da->getMaxValue(tmp);
3034 ret=std::max(ret,val);
3041 int MEDFileUMesh::getMinFamilyIdInArrays() const
3043 int ret=std::numeric_limits<int>::max(),tmp=-1;
3044 if((const DataArrayInt *)_fam_coords)
3046 int val=_fam_coords->getMinValue(tmp);
3047 ret=std::min(ret,val);
3049 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3051 if((const MEDFileUMeshSplitL1 *)(*it))
3053 const DataArrayInt *da=(*it)->getFamilyField();
3056 int val=da->getMinValue(tmp);
3057 ret=std::min(ret,val);
3065 * Returns the dimension on cells in \a this mesh.
3066 * \return int - the mesh dimension.
3067 * \throw If there are no cells in this mesh.
3069 int MEDFileUMesh::getMeshDimension() const
3072 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3073 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3074 return (*it)->getMeshDimension()+lev;
3075 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3079 * Returns the space dimension of \a this mesh that is equal to number of components in
3080 * the node coordinates array.
3081 * \return int - the space dimension of \a this mesh.
3082 * \throw If the node coordinates array is not available.
3084 int MEDFileUMesh::getSpaceDimension() const
3086 const DataArrayDouble *coo=_coords;
3088 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3089 return coo->getNumberOfComponents();
3093 * Returns a string describing \a this mesh.
3094 * \return std::string - the mesh information string.
3096 std::string MEDFileUMesh::simpleRepr() const
3098 std::ostringstream oss;
3099 oss << MEDFileMesh::simpleRepr();
3100 const DataArrayDouble *coo=_coords;
3101 oss << "- The dimension of the space is ";
3102 static const char MSG1[]= "*** NO COORDS SET ***";
3103 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3105 oss << _coords->getNumberOfComponents() << std::endl;
3107 oss << MSG1 << std::endl;
3108 oss << "- Type of the mesh : UNSTRUCTURED\n";
3109 oss << "- Number of nodes : ";
3111 oss << _coords->getNumberOfTuples() << std::endl;
3113 oss << MSG1 << std::endl;
3114 std::size_t nbOfLev=_ms.size();
3115 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3116 for(std::size_t i=0;i<nbOfLev;i++)
3118 const MEDFileUMeshSplitL1 *lev=_ms[i];
3119 oss << " - Level #" << -((int) i) << " has dimension : ";
3122 oss << lev->getMeshDimension() << std::endl;
3123 lev->simpleRepr(oss);
3126 oss << MSG2 << std::endl;
3128 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3131 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3132 oss << "- Names of coordinates :" << std::endl;
3133 std::vector<std::string> vars=coo->getVarsOnComponent();
3134 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3135 oss << std::endl << "- Units of coordinates : " << std::endl;
3136 std::vector<std::string> units=coo->getUnitsOnComponent();
3137 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3139 oss << std::endl << std::endl;
3141 getEquivalencesRepr(oss);
3146 * Returns a full textual description of \a this mesh.
3147 * \return std::string - the string holding the mesh description.
3149 std::string MEDFileUMesh::advancedRepr() const
3151 return simpleRepr();
3155 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3156 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3157 * \return int - the number of entities.
3158 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3160 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3162 if(meshDimRelToMaxExt==1)
3164 if(!((const DataArrayDouble *)_coords))
3165 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3166 return _coords->getNumberOfTuples();
3168 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3172 * Returns the family field for mesh entities of a given dimension.
3173 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3174 * \return const DataArrayInt * - the family field. It is an array of ids of families
3175 * each mesh entity belongs to. It can be \c NULL.
3177 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3179 if(meshDimRelToMaxExt==1)
3181 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3182 return l1->getFamilyField();
3185 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3187 if(meshDimRelToMaxExt==1)
3189 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3190 return l1->getFamilyField();
3194 * Returns the optional numbers of mesh entities of a given dimension.
3195 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3196 * \return const DataArrayInt * - the array of the entity numbers.
3197 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3199 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3201 if(meshDimRelToMaxExt==1)
3203 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3204 return l1->getNumberField();
3207 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3209 if(meshDimRelToMaxExt==1)
3210 return _name_coords;
3211 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3212 return l1->getNameField();
3216 * 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).
3218 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3219 * \param [in] gt - The input geometric type for which the part definition is requested.
3220 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3222 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3224 if(meshDimRelToMaxExt==1)
3225 return _part_coords;
3226 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3227 return l1->getPartDef(gt);
3230 int MEDFileUMesh::getNumberOfNodes() const
3232 const DataArrayDouble *coo(_coords);
3234 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3235 return coo->getNumberOfTuples();
3238 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3240 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3241 return l1->getNumberOfCells();
3244 bool MEDFileUMesh::hasImplicitPart() const
3249 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3251 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3254 void MEDFileUMesh::releaseImplicitPartIfAny() const
3258 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3260 std::size_t sz(st.getNumberOfItems());
3261 for(std::size_t i=0;i<sz;i++)
3263 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3264 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3265 if(st[i].getPflName().empty())
3266 m->computeNodeIdsAlg(nodesFetched);
3269 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3270 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3271 m2->computeNodeIdsAlg(nodesFetched);
3276 MEDFileMesh *MEDFileUMesh::cartesianize() const
3278 if(getAxisType()==AX_CART)
3281 return const_cast<MEDFileUMesh *>(this);
3285 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3286 const DataArrayDouble *coords(_coords);
3288 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3289 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3290 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3291 if((const MEDFileUMeshSplitL1 *)(*it))
3292 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3293 ret->_coords=coordsCart;
3294 ret->setAxisType(AX_CART);
3300 * Returns the optional numbers of mesh entities of a given dimension transformed using
3301 * DataArrayInt::invertArrayN2O2O2N().
3302 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3303 * \return const DataArrayInt * - the array of the entity numbers transformed using
3304 * DataArrayInt::invertArrayN2O2O2N().
3305 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3307 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3309 if(meshDimRelToMaxExt==1)
3311 if(!((const DataArrayInt *)_num_coords))
3312 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3313 return _rev_num_coords;
3315 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3316 return l1->getRevNumberField();
3320 * Returns a pointer to the node coordinates array of \a this mesh \b without
3321 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3323 DataArrayDouble *MEDFileUMesh::getCoords() const
3326 MCAuto<DataArrayDouble> tmp(_coords);
3327 if((DataArrayDouble *)tmp)
3335 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3336 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3338 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3339 * \param [in] grp - the name of the group whose mesh entities are included in the
3341 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3342 * according to the optional numbers of entities, if available.
3343 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3344 * delete this mesh using decrRef() as it is no more needed.
3345 * \throw If the name of a nonexistent group is specified.
3346 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3348 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3351 synchronizeTinyInfoOnLeaves();
3352 std::vector<std::string> tmp(1);
3354 return getGroups(meshDimRelToMaxExt,tmp,renum);
3358 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3359 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3361 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3362 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3364 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3365 * according to the optional numbers of entities, if available.
3366 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3367 * delete this mesh using decrRef() as it is no more needed.
3368 * \throw If a name of a nonexistent group is present in \a grps.
3369 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3371 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3374 synchronizeTinyInfoOnLeaves();
3375 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3376 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3377 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3378 zeRet->setName(grps[0]);
3379 return zeRet.retn();
3383 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3384 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3386 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3387 * \param [in] fam - the name of the family whose mesh entities are included in the
3389 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3390 * according to the optional numbers of entities, if available.
3391 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3392 * delete this mesh using decrRef() as it is no more needed.
3393 * \throw If a name of a nonexistent family is present in \a grps.
3394 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3396 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3399 synchronizeTinyInfoOnLeaves();
3400 std::vector<std::string> tmp(1);
3402 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3406 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3407 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3409 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3410 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3412 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3413 * according to the optional numbers of entities, if available.
3414 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3415 * delete this mesh using decrRef() as it is no more needed.
3416 * \throw If a name of a nonexistent family is present in \a fams.
3417 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3419 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3422 synchronizeTinyInfoOnLeaves();
3423 if(meshDimRelToMaxExt==1)
3425 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3426 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3427 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3431 std::vector<int> famIds=getFamiliesIds(fams);
3432 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3433 MCAuto<MEDCouplingUMesh> zeRet;
3435 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3437 zeRet=l1->getFamilyPart(0,0,renum);
3438 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3439 zeRet->setName(fams[0]);
3440 return zeRet.retn();
3444 * Returns ids of mesh entities contained in given families of a given dimension.
3445 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3447 * \param [in] fams - the names of the families of interest.
3448 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3449 * returned instead of ids.
3450 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3451 * numbers, if available and required, of mesh entities of the families. The caller
3452 * is to delete this array using decrRef() as it is no more needed.
3453 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3455 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3457 std::vector<int> famIds=getFamiliesIds(fams);
3458 if(meshDimRelToMaxExt==1)
3460 if((const DataArrayInt *)_fam_coords)
3462 MCAuto<DataArrayInt> da;
3464 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3466 da=_fam_coords->findIdsEqualList(0,0);
3468 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3473 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3475 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3477 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3479 return l1->getFamilyPartArr(0,0,renum);
3483 * Returns a MEDCouplingUMesh of a given relative dimension.
3484 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3485 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3486 * To build a valid MEDCouplingUMesh from the returned one in this case,
3487 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3488 * \param [in] meshDimRelToMax - the relative dimension of interest.
3489 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3490 * optional numbers of mesh entities.
3491 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3492 * delete using decrRef() as it is no more needed.
3493 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3495 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3498 synchronizeTinyInfoOnLeaves();
3499 if(meshDimRelToMaxExt==1)
3503 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3504 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3505 umesh->setCoords(cc);
3506 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3507 umesh->setName(getName());
3511 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3512 return l1->getWholeMesh(renum);
3515 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3517 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3518 return l1->getDistributionOfTypes();
3522 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3523 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3524 * optional numbers of mesh entities.
3525 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3526 * delete using decrRef() as it is no more needed.
3527 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3529 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3531 return getMeshAtLevel(0,renum);
3535 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3536 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3537 * optional numbers of mesh entities.
3538 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3539 * delete using decrRef() as it is no more needed.
3540 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3542 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3544 return getMeshAtLevel(-1,renum);
3548 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3549 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3550 * optional numbers of mesh entities.
3551 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3552 * delete using decrRef() as it is no more needed.
3553 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3555 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3557 return getMeshAtLevel(-2,renum);
3561 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3562 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3563 * optional numbers of mesh entities.
3564 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3565 * delete using decrRef() as it is no more needed.
3566 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3568 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3570 return getMeshAtLevel(-3,renum);
3574 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3575 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3576 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3577 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3579 void MEDFileUMesh::forceComputationOfParts() const
3581 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3583 const MEDFileUMeshSplitL1 *elt(*it);
3585 elt->forceComputationOfParts();
3590 * This method returns a vector of mesh parts containing each exactly one geometric type.
3591 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3592 * This method is only for memory aware users.
3593 * The returned pointers are **NOT** new object pointer. No need to mange them.
3595 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3598 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3599 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3603 * This method returns the part of \a this having the geometric type \a gt.
3604 * If such part is not existing an exception will be thrown.
3605 * The returned pointer is **NOT** new object pointer. No need to mange it.
3607 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3610 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3611 int lev=(int)cm.getDimension()-getMeshDimension();
3612 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3613 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3617 * This method returns for each geo types in \a this number of cells with this geo type.
3618 * 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.
3619 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3621 * \sa getDistributionOfTypes
3623 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3625 std::vector< std::pair<int,int> > ret;
3626 std::vector<int> nel(getNonEmptyLevels());
3627 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3629 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3630 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3632 int nbCells(getNumberOfCellsWithType(*it1));
3633 ret.push_back(std::pair<int,int>(*it1,nbCells));
3636 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3641 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3642 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3644 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3646 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3647 return sp->getGeoTypes();
3650 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3652 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3653 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3654 return sp->getNumberOfCellsWithType(ct);
3658 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3659 * \param [in] gt - the geometric type for which the family field is asked.
3660 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3661 * delete using decrRef() as it is no more needed.
3662 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3664 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3666 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3667 int lev=(int)cm.getDimension()-getMeshDimension();
3668 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3669 return sp->extractFamilyFieldOnGeoType(gt);
3673 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3674 * \param [in] gt - the geometric type for which the number field is asked.
3675 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3676 * delete using decrRef() as it is no more needed.
3677 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3679 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3681 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3682 int lev=(int)cm.getDimension()-getMeshDimension();
3683 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3684 return sp->extractNumberFieldOnGeoType(gt);
3688 * This method returns for specified geometric type \a gt the relative level to \a this.
3689 * If the relative level is empty an exception will be thrown.
3691 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3693 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3694 int ret((int)cm.getDimension()-getMeshDimension());
3695 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3699 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3701 if(meshDimRelToMaxExt==1)
3702 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3703 if(meshDimRelToMaxExt>1)
3704 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3705 int tracucedRk=-meshDimRelToMaxExt;
3706 if(tracucedRk>=(int)_ms.size())
3707 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3708 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3709 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3710 return _ms[tracucedRk];
3713 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3715 if(meshDimRelToMaxExt==1)
3716 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3717 if(meshDimRelToMaxExt>1)
3718 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3719 int tracucedRk=-meshDimRelToMaxExt;
3720 if(tracucedRk>=(int)_ms.size())
3721 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3722 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3723 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3724 return _ms[tracucedRk];
3727 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3729 if(-meshDimRelToMax>=(int)_ms.size())
3730 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3732 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3734 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3736 int ref=(*it)->getMeshDimension();
3737 if(ref+i!=meshDim-meshDimRelToMax)
3738 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3744 * Sets the node coordinates array of \a this mesh.
3745 * \param [in] coords - the new node coordinates array.
3746 * \throw If \a coords == \c NULL.
3748 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3751 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3752 if(coords==(DataArrayDouble *)_coords)
3754 coords->checkAllocated();
3755 int nbOfTuples(coords->getNumberOfTuples());
3758 _fam_coords=DataArrayInt::New();
3759 _fam_coords->alloc(nbOfTuples,1);
3760 _fam_coords->fillWithZero();
3761 _num_coords=0; _rev_num_coords=0; _name_coords=0;
3762 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3763 if((MEDFileUMeshSplitL1 *)(*it))
3764 (*it)->setCoords(coords);
3768 * Change coords without changing anything concerning families and numbering on nodes.
3770 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3773 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3774 if(coords==(DataArrayDouble *)_coords)
3776 coords->checkAllocated();
3777 int nbOfTuples(coords->getNumberOfTuples());
3778 if(_coords.isNull())
3785 int oldNbTuples(_coords->getNumberOfTuples());
3786 if(oldNbTuples!=nbOfTuples)
3787 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3791 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3792 if((MEDFileUMeshSplitL1 *)(*it))
3793 (*it)->setCoords(coords);
3797 * Removes all groups of a given dimension in \a this mesh.
3798 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3799 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3801 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3803 if(meshDimRelToMaxExt==1)
3805 if((DataArrayInt *)_fam_coords)
3806 _fam_coords->fillWithZero();
3809 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3810 l1->eraseFamilyField();
3815 * Removes all families with ids not present in the family fields of \a this mesh.
3817 void MEDFileUMesh::optimizeFamilies()
3819 std::vector<int> levs=getNonEmptyLevelsExt();
3820 std::set<int> allFamsIds;
3821 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3823 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3824 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3826 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3829 std::set<std::string> famNamesToKill;
3830 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3832 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3833 famNamesToKill.insert((*it).first);
3835 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3836 _families.erase(*it);
3837 std::vector<std::string> grpNamesToKill;
3838 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3840 std::vector<std::string> tmp;
3841 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3843 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3844 tmp.push_back(*it2);
3849 tmp.push_back((*it).first);
3851 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3856 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3857 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3858 * The boundary is built according to the following method:
3859 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3860 * coordinates array is extended).
3861 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3862 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3863 * might not be duplicated at all.
3864 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3865 * other side of the group is no more a neighbor)
3866 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3867 * bordering the newly created boundary use the newly computed nodes.
3868 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3869 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3871 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3872 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3874 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3875 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3876 * \sa clearNodeAndCellNumbers()
3878 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3879 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3881 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3882 typedef MCAuto<DataArrayInt> DAInt;
3884 std::vector<int> levs=getNonEmptyLevels();
3885 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3886 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3887 MUMesh m0=getMeshAtLevel(0);
3888 MUMesh m1=getMeshAtLevel(-1);
3889 int nbNodes=m0->getNumberOfNodes();
3890 MUMesh m11=getGroup(-1,grpNameM1);
3891 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3892 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3893 DAInt nodeIdsToDuplicate(tmp00);
3894 DAInt cellsToModifyConn0(tmp11);
3895 DAInt cellsToModifyConn1(tmp22);
3896 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3897 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3898 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3899 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3900 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3901 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3902 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3903 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3904 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3905 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3906 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3907 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3908 DAInt grpIds=getGroupArr(-1,grpNameM1);
3909 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3910 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3911 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3912 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3913 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3914 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3915 m0->setCoords(tmp0->getCoords());
3916 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3917 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3918 m1->setCoords(m0->getCoords());
3919 _coords=m0->getCoords(); _coords->incrRef();
3920 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3921 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3922 DataArrayInt * duplCells;
3923 m1->areCellsIncludedIn(m11, 0, duplCells);
3924 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3925 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3926 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3927 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3928 DAInt szOfCellGrpOfSameType(tmp00);
3929 DAInt idInMsOfCellGrpOfSameType(tmp11);
3931 newm1->setName(getName());
3932 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3934 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3935 DAInt newFam=DataArrayInt::New();
3936 newFam->alloc(newm1->getNumberOfCells(),1);
3937 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3938 // Positive ID for family of nodes, negative for all the rest.
3940 if (m1->getMeshDimension() == 0)
3941 idd=getMaxFamilyId()+1;
3943 idd=getMinFamilyId()-1;
3944 int globStart=0,start=0,end,globEnd;
3945 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3946 for(int i=0;i<nbOfChunks;i++)
3948 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3949 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3951 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3952 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
3953 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3958 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3962 newm1->setCoords(getCoords());
3963 setMeshAtLevel(-1,newm1);
3964 setFamilyFieldArr(-1,newFam);
3965 std::string grpName2(grpNameM1); grpName2+="_dup";
3966 addFamily(grpName2,idd);
3967 addFamilyOnGrp(grpName2,grpName2);
3972 int newNbOfNodes=getCoords()->getNumberOfTuples();
3973 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3974 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3975 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3980 _rev_num_coords = 0;
3981 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
3982 it != _ms.end(); it++)
3985 (*it)->_rev_num = 0;
3987 nodesDuplicated=nodeIdsToDuplicate.retn();
3988 cellsModified=cellsToModifyConn0.retn();
3989 cellsNotModified=cellsToModifyConn1.retn();
3992 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
3993 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
3996 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3997 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3998 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4000 * \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.
4001 * 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.
4003 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4005 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4006 std::vector<int> levs=getNonEmptyLevels();
4008 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4009 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4012 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4014 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4015 std::vector<int> code1=m->getDistributionOfTypes();
4016 end=PutInThirdComponentOfCodeOffset(code1,start);
4017 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4018 bool hasChanged=m->unPolyze();
4019 DataArrayInt *fake=0;
4020 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4021 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4023 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4026 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4027 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4029 MCAuto<DataArrayInt> famField2,numField2;
4030 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4031 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4032 setMeshAtLevel(*it,m);
4033 std::vector<int> code2=m->getDistributionOfTypes();
4034 end=PutInThirdComponentOfCodeOffset(code2,start);
4035 newCode.insert(newCode.end(),code2.begin(),code2.end());
4037 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4041 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4042 setFamilyFieldArr(*it,newFamField);
4046 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4047 setRenumFieldArr(*it,newNumField);
4052 newCode.insert(newCode.end(),code1.begin(),code1.end());
4058 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4059 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4060 o2nRenumCell=o2nRenumCellRet.retn();
4065 /*! \cond HIDDEN_ITEMS */
4066 struct MEDLoaderAccVisit1
4068 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4069 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4070 int _new_nb_of_nodes;
4075 * 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.
4076 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4077 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4078 * -1 values in returned array means that the corresponding old node is no more used.
4080 * \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
4081 * is modified in \a this.
4082 * \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
4085 DataArrayInt *MEDFileUMesh::zipCoords()
4087 const DataArrayDouble *coo(getCoords());
4089 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4090 int nbOfNodes(coo->getNumberOfTuples());
4091 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4092 std::vector<int> neLevs(getNonEmptyLevels());
4093 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4095 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4096 if(zeLev->isMeshStoredSplitByType())
4098 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4099 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4101 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4105 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4106 mesh->computeNodeIdsAlg(nodeIdsInUse);
4109 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4110 if(nbrOfNodesInUse==nbOfNodes)
4111 return 0;//no need to update _part_coords
4112 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4113 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4114 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4115 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4116 MCAuto<DataArrayInt> newFamCoords;
4117 MCAuto<DataArrayAsciiChar> newNameCoords;
4118 if((const DataArrayInt *)_fam_coords)
4119 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4120 MCAuto<DataArrayInt> newNumCoords;
4121 if((const DataArrayInt *)_num_coords)
4122 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4123 if((const DataArrayAsciiChar *)_name_coords)
4124 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4125 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
4126 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4128 if((MEDFileUMeshSplitL1*)*it)
4130 (*it)->renumberNodesInConn(ret->begin());
4131 (*it)->setCoords(_coords);
4134 // updates _part_coords
4135 const PartDefinition *pc(_part_coords);
4138 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4139 _part_coords=tmpPD->composeWith(pc);
4145 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4146 * The extraction of \a this is specified by the extractDef \a input map.
4147 * This map tells for each level of cells, the cells kept in the extraction.
4149 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4150 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4152 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4154 std::vector<int> levs(getNonEmptyLevels());
4155 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4156 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4159 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4160 if((*it).second.isNull())
4161 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4164 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4166 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4167 throw INTERP_KERNEL::Exception(oss.str());
4169 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4170 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4171 mPart->computeNodeIdsAlg(fetchedNodes);
4173 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4177 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4179 * \return - a new reference of MEDFileUMesh
4180 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4182 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4184 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4185 std::vector<int> levs(getNonEmptyLevels());
4186 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4189 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4190 if((*it).second.isNull())
4191 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4194 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4196 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4197 throw INTERP_KERNEL::Exception(oss.str());
4199 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4200 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4201 ret->setMeshAtLevel((*it).first,mPart);
4202 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4205 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4206 ret->setFamilyFieldArr((*it).first,famPart);
4210 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4211 ret->setFamilyFieldArr((*it).first,numPart);
4214 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4215 if(it2!=extractDef.end())
4217 const DataArrayDouble *coo(ret->getCoords());
4219 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4220 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4221 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4222 ret->setCoords(cooPart);
4223 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4226 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4227 ret->setFamilyFieldArr(1,famPart);
4231 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4232 ret->setFamilyFieldArr(1,numPart);
4234 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4238 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4239 m->renumberNodesInConn(o2nNodes->begin());
4240 ret->setMeshAtLevel((*it3).first,m);
4247 * This method performs an extrusion along a path defined by \a m1D.
4248 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4249 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4250 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4251 * This method scans all levels in \a this
4252 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4254 * \param [in] m1D - the mesh defining the extrusion path.
4255 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4256 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4258 * \sa MEDCouplingUMesh::buildExtrudedMesh
4260 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4263 if(getMeshDimension()!=2)
4264 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4265 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4266 m1D->checkConsistencyLight();
4267 if(m1D->getMeshDimension()!=1)
4268 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4269 int nbRep(m1D->getNumberOfCells());
4270 std::vector<int> levs(getNonEmptyLevels());
4271 std::vector<std::string> grps(getGroupsNames());
4272 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4273 DataArrayDouble *coords(0);
4274 std::size_t nbOfLevsOut(levs.size()+1);
4275 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4276 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4278 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4279 item=item->clone(false);
4280 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4281 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4282 tmp->changeSpaceDimension(3+(*lev),0.);
4283 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4284 zeList.push_back(elt);
4286 coords=elt->getCoords();
4289 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4290 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4292 (*it)->setName(getName());
4293 (*it)->setCoords(coords);
4295 for(std::size_t ii=0;ii!=zeList.size();ii++)
4298 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4301 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4302 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4303 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4304 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4305 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4306 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4307 std::vector<const MEDCouplingUMesh *> elts(3);
4308 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4309 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4310 elt->setName(getName());
4313 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4314 ret->setMeshAtLevel(lev,elt);
4316 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4317 endLev=endLev->clone(false); endLev->setCoords(coords);
4318 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4319 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4320 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4321 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4322 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4323 endLev->setName(getName());
4324 ret->setMeshAtLevel(levs.back()-1,endLev);
4326 for(std::size_t ii=0;ii!=zeList.size();ii++)
4329 std::vector< MCAuto<DataArrayInt> > outGrps;
4330 std::vector< const DataArrayInt * > outGrps2;
4333 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4335 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4336 if(!grpArr->empty())
4338 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4339 int offset0(zeList[ii]->getNumberOfCells());
4340 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4341 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4342 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4343 grpArr2->setName(oss.str());
4344 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4345 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4346 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4347 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4352 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4354 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4355 if(!grpArr->empty())
4357 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4358 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4359 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4360 for(int iii=0;iii<nbRep;iii++)
4362 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4363 grpArrs2[iii]=grpArrs[iii];
4365 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4366 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4367 std::ostringstream grpName; grpName << *grp << "_extruded";
4368 grpArrExt->setName(grpName.str());
4369 outGrps.push_back(grpArrExt);
4370 outGrps2.push_back(grpArrExt);
4373 ret->setGroupsAtLevel(lev,outGrps2);
4375 std::vector< MCAuto<DataArrayInt> > outGrps;
4376 std::vector< const DataArrayInt * > outGrps2;
4377 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4379 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4380 if(grpArr1->empty())
4382 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4383 std::ostringstream grpName; grpName << *grp << "_top";
4384 grpArr2->setName(grpName.str());
4385 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4386 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4387 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4389 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4394 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4395 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4396 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4398 * \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
4399 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4400 * \param [in] eps - detection threshold for coordinates.
4401 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4403 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4405 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4408 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4409 int initialNbNodes(getNumberOfNodes());
4410 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4411 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4413 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4415 DataArrayDouble *zeCoords(m0->getCoords());
4416 ret->setMeshAtLevel(0,m0);
4417 std::vector<int> levs(getNonEmptyLevels());
4418 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4421 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4422 ret->setFamilyFieldArr(0,famFieldCpy);
4424 famField=getFamilyFieldAtLevel(1);
4427 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4428 fam->fillWithZero();
4429 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4430 ret->setFamilyFieldArr(1,fam);
4432 ret->copyFamGrpMapsFrom(*this);
4433 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4434 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4438 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4439 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4440 if(m1->getMeshDimension()!=0)
4443 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4444 }//kill unused notUsed var
4445 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4447 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4448 MCAuto<DataArrayInt> bSafe(b);
4451 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4452 throw INTERP_KERNEL::Exception(oss.str().c_str());
4454 b->applyLin(1,initialNbNodes);
4455 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4456 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4457 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4458 m1->renumberNodesInConn(renum->begin());
4460 m1->setCoords(zeCoords);
4461 ret->setMeshAtLevel(*lev,m1);
4462 famField=getFamilyFieldAtLevel(*lev);
4465 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4466 ret->setFamilyFieldArr(*lev,famFieldCpy);
4473 * This method converts all quadratic cells in \a this into linear cells.
4474 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4475 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4477 * \param [in] eps - detection threshold for coordinates.
4478 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4480 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4482 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4485 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4486 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4487 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4488 m0->convertQuadraticCellsToLinear();
4490 DataArrayDouble *zeCoords(m0->getCoords());
4491 ret->setMeshAtLevel(0,m0);
4492 std::vector<int> levs(getNonEmptyLevels());
4493 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4496 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4497 ret->setFamilyFieldArr(0,famFieldCpy);
4499 famField=getFamilyFieldAtLevel(1);
4502 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4503 ret->setFamilyFieldArr(1,fam);
4505 ret->copyFamGrpMapsFrom(*this);
4506 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4510 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4511 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4512 m1->convertQuadraticCellsToLinear();
4515 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4516 MCAuto<DataArrayInt> bSafe(b);
4519 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4520 throw INTERP_KERNEL::Exception(oss.str().c_str());
4522 m1->renumberNodesInConn(b->begin());
4523 m1->setCoords(zeCoords);
4524 ret->setMeshAtLevel(*lev,m1);
4525 famField=getFamilyFieldAtLevel(*lev);
4528 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4529 ret->setFamilyFieldArr(*lev,famFieldCpy);
4536 * Computes the symmetry of \a this.
4537 * \return a new object.
4539 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4541 MCAuto<MEDFileUMesh> ret(deepCopy());
4542 DataArrayDouble *myCoo(getCoords());
4545 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4546 ret->setCoordsForced(newCoo);
4551 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4554 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4555 std::size_t sz(meshes.size()),i(0);
4556 std::vector<const DataArrayDouble *> coos(sz);
4557 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4558 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4561 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4562 coos[i]=(*it)->getCoords();
4563 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4564 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4566 const MEDFileUMesh *ref(meshes[0]);
4567 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4568 std::vector<int> levs(ref->getNonEmptyLevels());
4569 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4570 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4571 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4572 std::map<std::string,int> map1;
4573 std::map<std::string, std::vector<std::string> > map2;
4574 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4576 if((*it)->getSpaceDimension()!=spaceDim)
4577 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4578 if((*it)->getMeshDimension()!=meshDim)
4579 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4580 if((*it)->getNonEmptyLevels()!=levs)
4581 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4582 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4584 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4585 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4586 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4587 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4589 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4590 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4591 map1[(*it3).first]=(*it3).second;
4592 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4593 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4594 map2[(*it4).first]=(*it4).second;
4596 // Easy part : nodes
4597 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4598 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4599 ret->setCoords(coo);
4600 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4602 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4603 ret->setFamilyFieldArr(1,fam_coo);
4605 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4607 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4608 ret->setRenumFieldArr(1,num_coo);
4611 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4613 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4614 if(it2==m_mesh.end())
4615 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4616 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4617 mesh->setCoords(coo); mesh->setName(ref->getName());
4618 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4619 ret->setMeshAtLevel(*it,mesh);
4620 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4621 if(it3!=m_fam.end())
4623 const std::vector<const DataArrayInt *>& fams((*it3).second);
4624 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4626 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4627 famm->renumberInPlace(renum->begin());
4628 ret->setFamilyFieldArr(*it,famm);
4631 if(it4!=m_renum.end())
4633 const std::vector<const DataArrayInt *>& renums((*it4).second);
4634 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4636 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4637 renumm->renumberInPlace(renum->begin());
4638 ret->setRenumFieldArr(*it,renumm);
4643 ret->setFamilyInfo(map1);
4644 ret->setGroupInfo(map2);
4645 ret->setName(ref->getName());
4649 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4651 if(getMeshDimension()!=3)
4652 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4653 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4654 if(m3D.isNull() || m2D.isNull())
4655 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4656 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4657 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4661 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4663 clearNonDiscrAttributes();
4664 forceComputationOfParts();
4665 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4666 std::vector<int> layer0;
4667 layer0.push_back(getAxisType());//0 i
4668 layer0.push_back(_order); //1 i
4669 layer0.push_back(_iteration);//2 i
4670 layer0.push_back(getSpaceDimension());//3 i
4671 tinyDouble.push_back(_time);//0 d
4672 tinyStr.push_back(_name);//0 s
4673 tinyStr.push_back(_desc_name);//1 s
4674 for(int i=0;i<getSpaceDimension();i++)
4675 tinyStr.push_back(_coords->getInfoOnComponent(i));
4676 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4677 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4679 tinyStr.push_back((*it).first);
4680 layer0.push_back((*it).second);
4682 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4683 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4685 layer0.push_back((int)(*it0).second.size());
4686 tinyStr.push_back((*it0).first);
4687 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4688 tinyStr.push_back(*it1);
4690 // sizeof(layer0)==4+aa+1+bb layer#0
4691 bigArrayD=_coords;// 0 bd
4692 bigArraysI.push_back(_fam_coords);// 0 bi
4693 bigArraysI.push_back(_num_coords);// 1 bi
4694 const PartDefinition *pd(_part_coords);
4696 layer0.push_back(-1);
4699 std::vector<int> tmp0;
4700 pd->serialize(tmp0,bigArraysI);
4701 tinyInt.push_back(tmp0.size());
4702 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4705 std::vector<int> layer1;
4706 std::vector<int> levs(getNonEmptyLevels());
4707 layer1.push_back((int)levs.size());// 0 i <- key
4708 layer1.insert(layer1.end(),levs.begin(),levs.end());
4709 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4711 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4712 lev->serialize(layer1,bigArraysI);
4714 // put layers all together.
4715 tinyInt.push_back(layer0.size());
4716 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4717 tinyInt.push_back(layer1.size());
4718 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4721 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4722 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4724 int sz0(tinyInt[0]);
4725 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4726 int sz1(tinyInt[sz0+1]);
4727 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4729 std::reverse(layer0.begin(),layer0.end());
4730 std::reverse(layer1.begin(),layer1.end());
4731 std::reverse(tinyDouble.begin(),tinyDouble.end());
4732 std::reverse(tinyStr.begin(),tinyStr.end());
4733 std::reverse(bigArraysI.begin(),bigArraysI.end());
4735 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4736 _order=layer0.back(); layer0.pop_back();
4737 _iteration=layer0.back(); layer0.pop_back();
4738 int spaceDim(layer0.back()); layer0.pop_back();
4739 _time=tinyDouble.back(); tinyDouble.pop_back();
4740 _name=tinyStr.back(); tinyStr.pop_back();
4741 _desc_name=tinyStr.back(); tinyStr.pop_back();
4742 _coords=bigArrayD; _coords->rearrange(spaceDim);
4743 for(int i=0;i<spaceDim;i++)
4745 _coords->setInfoOnComponent(i,tinyStr.back());
4748 int nbOfFams(layer0.back()); layer0.pop_back();
4750 for(int i=0;i<nbOfFams;i++)
4752 _families[tinyStr.back()]=layer0.back();
4753 tinyStr.pop_back(); layer0.pop_back();
4755 int nbGroups(layer0.back()); layer0.pop_back();
4757 for(int i=0;i<nbGroups;i++)
4759 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4760 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4761 std::vector<std::string> fams(nbOfFamsOnGrp);
4762 for(int j=0;j<nbOfFamsOnGrp;j++)
4764 fams[j]=tinyStr.back(); tinyStr.pop_back();
4766 _groups[grpName]=fams;
4768 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4769 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4771 int isPd(layer0.back()); layer0.pop_back();
4774 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4775 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4776 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4779 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4781 int nbLevs(layer1.back()); layer1.pop_back();
4782 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4784 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4785 _ms.resize(maxLev+1);
4786 for(int i=0;i<nbLevs;i++)
4790 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4795 * Adds a group of nodes to \a this mesh.
4796 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4797 * The ids should be sorted and different each other (MED file norm).
4799 * \warning this method can alter default "FAMILLE_ZERO" family.
4800 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4802 * \throw If the node coordinates array is not set.
4803 * \throw If \a ids == \c NULL.
4804 * \throw If \a ids->getName() == "".
4805 * \throw If \a ids does not respect the MED file norm.
4806 * \throw If a group with name \a ids->getName() already exists.
4808 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4810 const DataArrayDouble *coords(_coords);
4812 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4813 int nbOfNodes(coords->getNumberOfTuples());
4814 if(!((DataArrayInt *)_fam_coords))
4815 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4817 addGroupUnderground(true,ids,_fam_coords);
4821 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4823 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4824 * The ids should be sorted and different each other (MED file norm).
4826 * \warning this method can alter default "FAMILLE_ZERO" family.
4827 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4829 * \throw If the node coordinates array is not set.
4830 * \throw If \a ids == \c NULL.
4831 * \throw If \a ids->getName() == "".
4832 * \throw If \a ids does not respect the MED file norm.
4833 * \throw If a group with name \a ids->getName() already exists.
4835 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4837 std::vector<int> levs(getNonEmptyLevelsExt());
4838 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4840 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4841 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4843 if(meshDimRelToMaxExt==1)
4844 { addNodeGroup(ids); return ; }
4845 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4846 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4847 addGroupUnderground(false,ids,fam);
4851 * Changes a name of a family specified by its id.
4852 * \param [in] id - the id of the family of interest.
4853 * \param [in] newFamName - the new family name.
4854 * \throw If no family with the given \a id exists.
4856 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4858 std::string oldName=getFamilyNameGivenId(id);
4859 _families.erase(oldName);
4860 _families[newFamName]=id;
4864 * Removes a mesh of a given dimension.
4865 * \param [in] meshDimRelToMax - the relative dimension of interest.
4866 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4868 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4870 std::vector<int> levSet=getNonEmptyLevels();
4871 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4872 if(it==levSet.end())
4873 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4874 int pos=(-meshDimRelToMax);
4879 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4880 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4881 * \param [in] m - the new mesh to set.
4882 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4884 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4885 * another node coordinates array.
4886 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4887 * to the existing meshes of other levels of \a this mesh.
4889 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4891 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4892 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4896 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4897 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4898 * \param [in] m - the new mesh to set.
4899 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4900 * writing \a this mesh in a MED file.
4901 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4903 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4904 * another node coordinates array.
4905 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4906 * to the existing meshes of other levels of \a this mesh.
4908 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4910 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4911 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4914 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4916 dealWithTinyInfo(m);
4917 std::vector<int> levSet=getNonEmptyLevels();
4918 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4920 if((DataArrayDouble *)_coords==0)
4922 DataArrayDouble *c=m->getCoords();
4927 if(m->getCoords()!=_coords)
4928 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4929 int sz=(-meshDimRelToMax)+1;
4930 if(sz>=(int)_ms.size())
4932 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4936 return _ms[-meshDimRelToMax];
4940 * This method allows to set at once the content of different levels in \a this.
4941 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4943 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4944 * \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.
4945 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4947 * \throw If \a there is a null pointer in \a ms.
4948 * \sa MEDFileUMesh::setMeshAtLevel
4950 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4954 const MEDCouplingUMesh *mRef=ms[0];
4956 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4957 std::string name(mRef->getName());
4958 const DataArrayDouble *coo(mRef->getCoords());
4961 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4963 const MEDCouplingUMesh *cur(*it);
4965 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4966 if(coo!=cur->getCoords())
4967 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4968 int mdim=cur->getMeshDimension();
4969 zeDim=std::max(zeDim,mdim);
4970 if(s.find(mdim)!=s.end())
4971 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4973 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4975 int mdim=(*it)->getMeshDimension();
4976 setName((*it)->getName());
4977 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4983 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4984 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4985 * The given meshes must share the same node coordinates array.
4986 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4987 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4988 * create in \a this mesh.
4989 * \throw If \a ms is empty.
4990 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4991 * to the existing meshes of other levels of \a this mesh.
4992 * \throw If the meshes in \a ms do not share the same node coordinates array.
4993 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4994 * of the given meshes.
4995 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
4996 * \throw If names of some meshes in \a ms are equal.
4997 * \throw If \a ms includes a mesh with an empty name.
4999 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5002 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5003 int sz=(-meshDimRelToMax)+1;
5004 if(sz>=(int)_ms.size())
5006 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5007 DataArrayDouble *coo=checkMultiMesh(ms);
5008 if((DataArrayDouble *)_coords==0)
5014 if((DataArrayDouble *)_coords!=coo)
5015 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5016 std::vector<DataArrayInt *> corr;
5017 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5018 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5019 setMeshAtLevel(meshDimRelToMax,m,renum);
5020 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5021 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5025 * Creates groups at a given level in \a this mesh from a sequence of
5026 * meshes each representing a group.
5027 * The given meshes must share the same node coordinates array.
5028 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5029 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5030 * create in \a this mesh.
5031 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5033 * \throw If \a ms is empty.
5034 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5035 * to the existing meshes of other levels of \a this mesh.
5036 * \throw If the meshes in \a ms do not share the same node coordinates array.
5037 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5038 * of the given meshes.
5039 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5040 * \throw If names of some meshes in \a ms are equal.
5041 * \throw If \a ms includes a mesh with an empty name.
5043 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5046 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5047 int sz=(-meshDimRelToMax)+1;
5048 if(sz>=(int)_ms.size())
5050 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5051 DataArrayDouble *coo=checkMultiMesh(ms);
5052 if((DataArrayDouble *)_coords==0)
5058 if((DataArrayDouble *)_coords!=coo)
5059 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5060 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5061 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5063 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5065 DataArrayInt *arr=0;
5066 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5070 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5071 throw INTERP_KERNEL::Exception(oss.str().c_str());
5074 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5075 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5078 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5080 const DataArrayDouble *ret=ms[0]->getCoords();
5081 int mdim=ms[0]->getMeshDimension();
5082 for(unsigned int i=1;i<ms.size();i++)
5084 ms[i]->checkConsistencyLight();
5085 if(ms[i]->getCoords()!=ret)
5086 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5087 if(ms[i]->getMeshDimension()!=mdim)
5088 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5090 return const_cast<DataArrayDouble *>(ret);
5094 * Sets the family field of a given relative dimension.
5095 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5096 * the family field is set.
5097 * \param [in] famArr - the array of the family field.
5098 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5099 * \throw If \a famArr has an invalid size.
5101 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5103 if(meshDimRelToMaxExt==1)
5110 DataArrayDouble *coo(_coords);
5112 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5113 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5118 if(meshDimRelToMaxExt>1)
5119 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5120 int traducedRk=-meshDimRelToMaxExt;
5121 if(traducedRk>=(int)_ms.size())
5122 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5123 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5124 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5125 return _ms[traducedRk]->setFamilyArr(famArr);
5129 * Sets the optional numbers of mesh entities of a given dimension.
5130 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5131 * \param [in] renumArr - the array of the numbers.
5132 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5133 * \throw If \a renumArr has an invalid size.
5135 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5137 if(meshDimRelToMaxExt==1)
5145 DataArrayDouble *coo(_coords);
5147 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5148 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5149 renumArr->incrRef();
5150 _num_coords=renumArr;
5154 if(meshDimRelToMaxExt>1)
5155 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5156 int traducedRk=-meshDimRelToMaxExt;
5157 if(traducedRk>=(int)_ms.size())
5158 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5159 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5160 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5161 return _ms[traducedRk]->setRenumArr(renumArr);
5165 * Sets the optional names of mesh entities of a given dimension.
5166 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5167 * \param [in] nameArr - the array of the names.
5168 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5169 * \throw If \a nameArr has an invalid size.
5171 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5173 if(meshDimRelToMaxExt==1)
5180 DataArrayDouble *coo(_coords);
5182 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5183 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5185 _name_coords=nameArr;
5188 if(meshDimRelToMaxExt>1)
5189 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5190 int traducedRk=-meshDimRelToMaxExt;
5191 if(traducedRk>=(int)_ms.size())
5192 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5193 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5194 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5195 return _ms[traducedRk]->setNameArr(nameArr);
5198 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5200 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5201 if((const MEDFileUMeshSplitL1 *)(*it))
5202 (*it)->synchronizeTinyInfo(*this);
5206 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5208 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5210 DataArrayInt *arr=_fam_coords;
5212 arr->changeValue(oldId,newId);
5213 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5215 MEDFileUMeshSplitL1 *sp=(*it);
5218 sp->changeFamilyIdArr(oldId,newId);
5223 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5225 std::list< MCAuto<DataArrayInt> > ret;
5226 const DataArrayInt *da(_fam_coords);
5228 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5229 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5231 const MEDFileUMeshSplitL1 *elt(*it);
5234 da=elt->getFamilyField();
5236 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5242 void MEDFileUMesh::computeRevNum() const
5244 if((const DataArrayInt *)_num_coords)
5247 int maxValue=_num_coords->getMaxValue(pos);
5248 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5252 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5254 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5257 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5259 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5260 ret.push_back((const DataArrayInt *)_fam_nodes);
5261 ret.push_back((const DataArrayInt *)_num_nodes);
5262 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5263 ret.push_back((const DataArrayInt *)_fam_cells);
5264 ret.push_back((const DataArrayInt *)_num_cells);
5265 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5266 ret.push_back((const DataArrayInt *)_fam_faces);
5267 ret.push_back((const DataArrayInt *)_num_faces);
5268 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5269 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5270 ret.push_back((const DataArrayInt *)_rev_num_cells);
5271 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5275 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5277 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5278 if((const DataArrayInt *)_fam_nodes)
5280 int val=_fam_nodes->getMaxValue(tmp);
5281 ret=std::max(ret,std::abs(val));
5283 if((const DataArrayInt *)_fam_cells)
5285 int val=_fam_cells->getMaxValue(tmp);
5286 ret=std::max(ret,std::abs(val));
5288 if((const DataArrayInt *)_fam_faces)
5290 int val=_fam_faces->getMaxValue(tmp);
5291 ret=std::max(ret,std::abs(val));
5296 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5298 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5299 if((const DataArrayInt *)_fam_nodes)
5301 int val=_fam_nodes->getMaxValue(tmp);
5302 ret=std::max(ret,val);
5304 if((const DataArrayInt *)_fam_cells)
5306 int val=_fam_cells->getMaxValue(tmp);
5307 ret=std::max(ret,val);
5309 if((const DataArrayInt *)_fam_faces)
5311 int val=_fam_faces->getMaxValue(tmp);
5312 ret=std::max(ret,val);
5317 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5319 int ret=std::numeric_limits<int>::max(),tmp=-1;
5320 if((const DataArrayInt *)_fam_nodes)
5322 int val=_fam_nodes->getMinValue(tmp);
5323 ret=std::min(ret,val);
5325 if((const DataArrayInt *)_fam_cells)
5327 int val=_fam_cells->getMinValue(tmp);
5328 ret=std::min(ret,val);
5330 if((const DataArrayInt *)_fam_faces)
5332 int val=_fam_faces->getMinValue(tmp);
5333 ret=std::min(ret,val);
5338 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5340 if(!MEDFileMesh::isEqual(other,eps,what))
5342 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5345 what="Mesh types differ ! This is structured and other is NOT !";
5348 const DataArrayInt *famc1=_fam_nodes;
5349 const DataArrayInt *famc2=otherC->_fam_nodes;
5350 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5352 what="Mismatch of families arr on nodes ! One is defined and not other !";
5357 bool ret=famc1->isEqual(*famc2);
5360 what="Families arr on nodes differ !";
5365 famc2=otherC->_fam_cells;
5366 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5368 what="Mismatch of families arr on cells ! One is defined and not other !";
5373 bool ret=famc1->isEqual(*famc2);
5376 what="Families arr on cells differ !";
5381 famc2=otherC->_fam_faces;
5382 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5384 what="Mismatch of families arr on faces ! One is defined and not other !";
5389 bool ret=famc1->isEqual(*famc2);
5392 what="Families arr on faces differ !";
5397 famc2=otherC->_num_nodes;
5398 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5400 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5405 bool ret=famc1->isEqual(*famc2);
5408 what="Numbering arr on nodes differ !";
5413 famc2=otherC->_num_cells;
5414 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5416 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5421 bool ret=famc1->isEqual(*famc2);
5424 what="Numbering arr on cells differ !";
5429 famc2=otherC->_num_faces;
5430 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5432 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5437 bool ret=famc1->isEqual(*famc2);
5440 what="Numbering arr on faces differ !";
5444 const DataArrayAsciiChar *d1=_names_cells;
5445 const DataArrayAsciiChar *d2=otherC->_names_cells;
5446 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5448 what="Mismatch of naming arr on cells ! One is defined and not other !";
5453 bool ret=d1->isEqual(*d2);
5456 what="Naming arr on cells differ !";
5461 d2=otherC->_names_faces;
5462 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5464 what="Mismatch of naming arr on faces ! One is defined and not other !";
5469 bool ret=d1->isEqual(*d2);
5472 what="Naming arr on faces differ !";
5477 d2=otherC->_names_nodes;
5478 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5480 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5485 bool ret=d1->isEqual(*d2);
5488 what="Naming arr on nodes differ !";
5495 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5497 MEDFileMesh::clearNonDiscrAttributes();
5498 const DataArrayInt *tmp=_fam_nodes;
5500 (const_cast<DataArrayInt *>(tmp))->setName("");
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("");
5519 * Returns ids of mesh entities contained in given families of a given dimension.
5520 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5522 * \param [in] fams - the names of the families of interest.
5523 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5524 * returned instead of ids.
5525 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5526 * numbers, if available and required, of mesh entities of the families. The caller
5527 * is to delete this array using decrRef() as it is no more needed.
5528 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5530 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5532 std::vector<int> famIds(getFamiliesIds(fams));
5533 switch(meshDimRelToMaxExt)
5537 if((const DataArrayInt *)_fam_nodes)
5539 MCAuto<DataArrayInt> da;
5541 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5543 da=_fam_nodes->findIdsEqualList(0,0);
5545 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5550 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5555 if((const DataArrayInt *)_fam_cells)
5557 MCAuto<DataArrayInt> da;
5559 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5561 da=_fam_cells->findIdsEqualList(0,0);
5563 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5568 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5573 if((const DataArrayInt *)_fam_faces)
5575 MCAuto<DataArrayInt> da;
5577 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5579 da=_fam_faces->findIdsEqualList(0,0);
5581 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5586 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5590 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5592 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5596 * Sets the family field of a given relative dimension.
5597 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5598 * the family field is set.
5599 * \param [in] famArr - the array of the family field.
5600 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5601 * \throw If \a famArr has an invalid size.
5602 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5604 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5606 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5608 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5609 switch(meshDimRelToMaxExt)
5613 int nbCells(mesh->getNumberOfCells());
5615 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5621 int nbNodes(mesh->getNumberOfNodes());
5623 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5629 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5631 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5636 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5643 * Sets the optional numbers of mesh entities of a given dimension.
5644 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5645 * \param [in] renumArr - the array of the numbers.
5646 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5647 * \throw If \a renumArr has an invalid size.
5648 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5650 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5652 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5654 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5655 switch(meshDimRelToMaxExt)
5659 int nbCells=mesh->getNumberOfCells();
5660 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5661 _num_cells=renumArr;
5666 int nbNodes=mesh->getNumberOfNodes();
5667 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5668 _num_nodes=renumArr;
5673 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5674 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5675 _num_faces=renumArr;
5679 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5682 renumArr->incrRef();
5686 * Sets the optional names of mesh entities of a given dimension.
5687 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5688 * \param [in] nameArr - the array of the names.
5689 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5690 * \throw If \a nameArr has an invalid size.
5692 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5694 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5696 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5697 switch(meshDimRelToMaxExt)
5701 int nbCells=mesh->getNumberOfCells();
5702 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5703 _names_cells=nameArr;
5708 int nbNodes=mesh->getNumberOfNodes();
5709 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5710 _names_nodes=nameArr;
5715 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5716 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5717 _names_cells=nameArr;
5720 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5727 * Adds a group of nodes to \a this mesh.
5728 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5729 * The ids should be sorted and different each other (MED file norm).
5731 * \warning this method can alter default "FAMILLE_ZERO" family.
5732 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5734 * \throw If the node coordinates array is not set.
5735 * \throw If \a ids == \c NULL.
5736 * \throw If \a ids->getName() == "".
5737 * \throw If \a ids does not respect the MED file norm.
5738 * \throw If a group with name \a ids->getName() already exists.
5740 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5746 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5748 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5749 * The ids should be sorted and different each other (MED file norm).
5751 * \warning this method can alter default "FAMILLE_ZERO" family.
5752 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5754 * \throw If the node coordinates array is not set.
5755 * \throw If \a ids == \c NULL.
5756 * \throw If \a ids->getName() == "".
5757 * \throw If \a ids does not respect the MED file norm.
5758 * \throw If a group with name \a ids->getName() already exists.
5760 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5762 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5763 addGroupUnderground(false,ids,fam);
5768 * Returns the family field for mesh entities of a given dimension.
5769 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5770 * \return const DataArrayInt * - the family field. It is an array of ids of families
5771 * each mesh entity belongs to. It can be \c NULL.
5772 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5774 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5776 switch(meshDimRelToMaxExt)
5785 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5790 * Returns the family field for mesh entities of a given dimension.
5791 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5792 * \return const DataArrayInt * - the family field. It is an array of ids of families
5793 * each mesh entity belongs to. It can be \c NULL.
5794 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5796 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5798 switch(meshDimRelToMaxExt)
5807 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5812 * Returns the optional numbers of mesh entities of a given dimension.
5813 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5814 * \return const DataArrayInt * - the array of the entity numbers.
5815 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5816 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5818 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5820 switch(meshDimRelToMaxExt)
5829 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5834 * Returns the optional numbers of mesh entities of a given dimension transformed using
5835 * DataArrayInt::invertArrayN2O2O2N().
5836 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5837 * \return const DataArrayInt * - the array of the entity numbers transformed using
5838 * DataArrayInt::invertArrayN2O2O2N().
5839 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5840 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5842 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5844 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5845 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5846 if(meshDimRelToMaxExt==0)
5848 if((const DataArrayInt *)_num_cells)
5851 int maxValue=_num_cells->getMaxValue(pos);
5852 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5853 return _rev_num_cells;
5856 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5860 if((const DataArrayInt *)_num_nodes)
5863 int maxValue=_num_nodes->getMaxValue(pos);
5864 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5865 return _rev_num_nodes;
5868 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5872 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5874 switch(meshDimRelToMaxExt)
5877 return _names_cells;
5879 return _names_nodes;
5881 return _names_faces;
5883 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5888 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5889 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5891 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5893 std::vector<int> ret(1);
5898 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5899 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5901 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5903 std::vector<int> ret(2);
5909 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5911 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5913 std::vector<int> ret;
5914 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5925 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5927 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5929 std::vector<int> ret;
5930 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5941 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5943 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5945 std::vector<int> ret;
5946 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5957 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5959 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5961 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5965 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5967 DataArrayInt *arr=_fam_nodes;
5969 arr->changeValue(oldId,newId);
5972 arr->changeValue(oldId,newId);
5975 arr->changeValue(oldId,newId);
5978 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5980 std::list< MCAuto<DataArrayInt> > ret;
5981 const DataArrayInt *da(_fam_nodes);
5983 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5986 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5989 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5993 void MEDFileStructuredMesh::deepCpyAttributes()
5995 if((const DataArrayInt*)_fam_nodes)
5996 _fam_nodes=_fam_nodes->deepCopy();
5997 if((const DataArrayInt*)_num_nodes)
5998 _num_nodes=_num_nodes->deepCopy();
5999 if((const DataArrayAsciiChar*)_names_nodes)
6000 _names_nodes=_names_nodes->deepCopy();
6001 if((const DataArrayInt*)_fam_cells)
6002 _fam_cells=_fam_cells->deepCopy();
6003 if((const DataArrayInt*)_num_cells)
6004 _num_cells=_num_cells->deepCopy();
6005 if((const DataArrayAsciiChar*)_names_cells)
6006 _names_cells=_names_cells->deepCopy();
6007 if((const DataArrayInt*)_fam_faces)
6008 _fam_faces=_fam_faces->deepCopy();
6009 if((const DataArrayInt*)_num_faces)
6010 _num_faces=_num_faces->deepCopy();
6011 if((const DataArrayAsciiChar*)_names_faces)
6012 _names_faces=_names_faces->deepCopy();
6013 if((const DataArrayInt*)_rev_num_nodes)
6014 _rev_num_nodes=_rev_num_nodes->deepCopy();
6015 if((const DataArrayInt*)_rev_num_cells)
6016 _rev_num_cells=_rev_num_cells->deepCopy();
6020 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
6022 * \return a pointer to cartesian mesh that need to be managed by the caller.
6023 * \warning the returned pointer has to be managed by the caller.
6027 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6028 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6029 * \param [in] renum - it must be \c false.
6030 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6031 * delete using decrRef() as it is no more needed.
6033 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6037 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6038 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6039 switch(meshDimRelToMax)
6045 return const_cast<MEDCouplingStructuredMesh *>(m);
6050 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6051 buildMinusOneImplicitPartIfNeeded();
6052 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6058 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6062 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6064 std::vector<int> ret;
6065 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6066 if(famCells && famCells->presenceOfValue(ret))
6068 if(famFaces && famFaces->presenceOfValue(ret))
6073 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6075 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6076 const DataArrayInt *famNodes(_fam_nodes);
6077 if(famNodes && famNodes->presenceOfValue(ret))
6083 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6084 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6085 * \return int - the number of entities.
6086 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6088 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6090 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6092 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6093 switch(meshDimRelToMaxExt)
6096 return cmesh->getNumberOfCells();
6098 return cmesh->getNumberOfNodes();
6100 return cmesh->getNumberOfCellsOfSubLevelMesh();
6102 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6106 int MEDFileStructuredMesh::getNumberOfNodes() const
6108 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6110 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6111 return cmesh->getNumberOfNodes();
6114 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6116 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6118 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6119 switch(meshDimRelToMaxExt)
6122 return cmesh->getNumberOfCells();
6124 return cmesh->getNumberOfCellsOfSubLevelMesh();
6126 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6130 bool MEDFileStructuredMesh::hasImplicitPart() const
6136 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6138 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6140 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6141 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6144 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6145 if(cm.getReverseExtrudedType()!=gt)
6146 throw INTERP_KERNEL::Exception(MSG);
6147 buildImplicitPart();
6148 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6152 if(gt!=zeFaceMesh->getCellModelEnum())
6153 throw INTERP_KERNEL::Exception(MSG);
6154 return zeFaceMesh->getNumberOfCells();
6158 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6160 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6162 buildImplicitPart();
6165 void MEDFileStructuredMesh::buildImplicitPart() const
6167 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6169 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6170 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6173 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6175 _faces_if_necessary=0;
6179 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6180 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6182 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6184 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6187 return _faces_if_necessary;
6190 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6192 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6194 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6195 switch(meshDimRelToMax)
6199 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6204 int mdim(cmesh->getMeshDimension());
6206 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6207 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6211 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6215 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6217 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6220 return getNumberOfCellsAtLevel(0);
6223 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6225 if(st.getNumberOfItems()!=1)
6226 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 !");
6227 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6228 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6229 if(getNumberOfNodes()!=(int)nodesFetched.size())
6230 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6231 if(st[0].getPflName().empty())
6233 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6236 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6237 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6238 int sz(nodesFetched.size());
6239 for(const int *work=arr->begin();work!=arr->end();work++)
6241 std::vector<int> conn;
6242 cmesh->getNodeIdsOfCell(*work,conn);
6243 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6244 if(*it>=0 && *it<sz)
6245 nodesFetched[*it]=true;
6247 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6251 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6253 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6257 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6258 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6260 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6261 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6263 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6266 if(!mrs || mrs->isCellFamilyFieldReading())
6268 famCells=DataArrayInt::New();
6269 famCells->alloc(nbOfElt,1);
6270 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6273 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6276 if(!mrs || mrs->isCellNumFieldReading())
6278 numCells=DataArrayInt::New();
6279 numCells->alloc(nbOfElt,1);
6280 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6283 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6286 if(!mrs || mrs->isCellNameFieldReading())
6288 namesCells=DataArrayAsciiChar::New();
6289 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6290 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6291 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6296 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6298 setName(strm->getName());
6299 setDescription(strm->getDescription());
6300 setUnivName(strm->getUnivName());
6301 setIteration(strm->getIteration());
6302 setOrder(strm->getOrder());
6303 setTimeValue(strm->getTime());
6304 setTimeUnit(strm->getTimeUnit());
6305 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6306 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6307 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6310 if(!mrs || mrs->isNodeFamilyFieldReading())
6312 int nbNodes(getNumberOfNodes());
6314 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6315 _fam_nodes=DataArrayInt::New();
6316 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6317 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...
6318 _fam_nodes->fillWithZero();
6319 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6322 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6325 if(!mrs || mrs->isNodeNumFieldReading())
6327 _num_nodes=DataArrayInt::New();
6328 _num_nodes->alloc(nbOfElt,1);
6329 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6332 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6335 if(!mrs || mrs->isNodeNameFieldReading())
6337 _names_nodes=DataArrayAsciiChar::New();
6338 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6339 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6340 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6343 int meshDim(getStructuredMesh()->getMeshDimension());
6344 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6346 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6349 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6351 int meshDim(getStructuredMesh()->getMeshDimension());
6352 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6354 if((const DataArrayInt *)_fam_cells)
6355 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6356 if((const DataArrayInt *)_fam_faces)
6357 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6358 if((const DataArrayInt *)_fam_nodes)
6359 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6360 if((const DataArrayInt *)_num_cells)
6361 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6362 if((const DataArrayInt *)_num_faces)
6363 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6364 if((const DataArrayInt *)_num_nodes)
6365 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6366 if((const DataArrayAsciiChar *)_names_cells)
6368 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6370 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6371 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6372 throw INTERP_KERNEL::Exception(oss.str().c_str());
6374 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6376 if((const DataArrayAsciiChar *)_names_faces)
6378 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6380 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6381 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6382 throw INTERP_KERNEL::Exception(oss.str().c_str());
6384 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6386 if((const DataArrayAsciiChar *)_names_nodes)
6388 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6390 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6391 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6392 throw INTERP_KERNEL::Exception(oss.str().c_str());
6394 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6397 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6401 * Returns an empty instance of MEDFileCMesh.
6402 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6403 * mesh using decrRef() as it is no more needed.
6405 MEDFileCMesh *MEDFileCMesh::New()
6407 return new MEDFileCMesh;
6411 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6412 * file. The first mesh in the file is loaded.
6413 * \param [in] fileName - the name of MED file to read.
6414 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6415 * mesh using decrRef() as it is no more needed.
6416 * \throw If the file is not readable.
6417 * \throw If there is no meshes in the file.
6418 * \throw If the mesh in the file is not a Cartesian one.
6420 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6422 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6425 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6426 throw INTERP_KERNEL::Exception(oss.str().c_str());
6428 MEDFileUtilities::CheckFileForRead(fileName);
6429 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6431 MEDCoupling::MEDCouplingMeshType meshType;
6433 MEDCoupling::MEDCouplingAxisType dummy3;
6434 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6435 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
6439 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6440 * file. The mesh to load is specified by its name and numbers of a time step and an
6442 * \param [in] fileName - the name of MED file to read.
6443 * \param [in] mName - the name of the mesh to read.
6444 * \param [in] dt - the number of a time step.
6445 * \param [in] it - the number of an iteration.
6446 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6447 * mesh using decrRef() as it is no more needed.
6448 * \throw If the file is not readable.
6449 * \throw If there is no mesh with given attributes in the file.
6450 * \throw If the mesh in the file is not a Cartesian one.
6452 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6454 MEDFileUtilities::CheckFileForRead(fileName);
6455 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
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::writeLL(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(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6720 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6723 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6724 throw INTERP_KERNEL::Exception(oss.str().c_str());
6726 MEDFileUtilities::CheckFileForRead(fileName);
6727 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6729 MEDCoupling::MEDCouplingMeshType meshType;
6730 MEDCoupling::MEDCouplingAxisType dummy3;
6732 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6733 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6736 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6738 MEDFileUtilities::CheckFileForRead(fileName);
6739 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6740 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6743 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6745 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6748 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6750 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6751 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6755 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6757 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6761 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6763 return new MEDFileCurveLinearMesh;
6766 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6768 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6769 ret->deepCpyEquivalences(*this);
6770 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6771 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6772 ret->deepCpyAttributes();
6776 int MEDFileCurveLinearMesh::getMeshDimension() const
6778 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6779 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6780 return _clmesh->getMeshDimension();
6783 std::string MEDFileCurveLinearMesh::simpleRepr() const
6785 return MEDFileStructuredMesh::simpleRepr();
6788 std::string MEDFileCurveLinearMesh::advancedRepr() const
6790 return simpleRepr();
6793 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6795 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6797 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6800 what="Mesh types differ ! This is curve linear and other is NOT !";
6803 clearNonDiscrAttributes();
6804 otherC->clearNonDiscrAttributes();
6805 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6806 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6807 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6809 what="Mismatch of curve linear meshes ! One is defined and not other !";
6814 bool ret=coo1->isEqual(coo2,eps);
6817 what="curve linear meshes differ !";
6824 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6826 MEDFileStructuredMesh::clearNonDiscrAttributes();
6827 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6830 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6832 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6835 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6836 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6837 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6838 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6841 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6843 synchronizeTinyInfoOnLeaves();
6847 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6849 dealWithTinyInfo(m);
6855 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6857 if(getAxisType()==AX_CART)
6860 return const_cast<MEDFileCurveLinearMesh *>(this);
6864 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6866 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6867 const DataArrayDouble *coords(mesh->getCoords());
6869 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6870 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6871 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6872 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6873 mesh2->setCoords(coordsCart);
6874 ret->setMesh(mesh2);
6875 ret->setAxisType(AX_CART);
6880 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6882 synchronizeTinyInfoOnLeaves();
6886 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6890 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6893 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6895 catch(INTERP_KERNEL::Exception& e)
6900 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6902 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6903 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6904 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6905 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6906 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6907 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6908 int spaceDim=_clmesh->getSpaceDimension();
6909 int meshDim=_clmesh->getMeshDimension();
6910 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6911 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6912 const DataArrayDouble *coords=_clmesh->getCoords();
6914 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6915 for(int i=0;i<spaceDim;i++)
6917 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6919 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6920 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
6921 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
6923 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6925 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6926 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6927 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6928 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6930 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6932 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6933 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6936 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6938 MEDCoupling::MEDCouplingMeshType meshType;
6941 MEDCoupling::MEDCouplingAxisType axType;
6942 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6943 setAxisType(axType);
6944 if(meshType!=CURVE_LINEAR)
6946 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6947 throw INTERP_KERNEL::Exception(oss.str().c_str());
6949 MEDFileCLMeshL2 loaderl2;
6950 loaderl2.loadAll(fid,mid,mName,dt,it);
6951 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6954 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6957 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6959 return new MEDFileMeshMultiTS;
6962 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6964 return new MEDFileMeshMultiTS(fileName);
6967 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6969 return new MEDFileMeshMultiTS(fileName,mName);
6972 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
6974 MCAuto<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6975 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6977 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6978 if((const MEDFileMesh *)*it)
6979 meshOneTs[i]=(*it)->deepCopy();
6980 ret->_mesh_one_ts=meshOneTs;
6984 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6986 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
6989 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6991 std::vector<const BigMemoryObject *> ret;
6992 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6993 ret.push_back((const MEDFileMesh *)*it);
6997 std::string MEDFileMeshMultiTS::getName() const
6999 if(_mesh_one_ts.empty())
7000 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7001 return _mesh_one_ts[0]->getName();
7004 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7006 std::string oldName(getName());
7007 std::vector< std::pair<std::string,std::string> > v(1);
7008 v[0].first=oldName; v[0].second=newMeshName;
7012 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7015 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7017 MEDFileMesh *cur(*it);
7019 ret=cur->changeNames(modifTab) || ret;
7024 void MEDFileMeshMultiTS::cartesianizeMe()
7026 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7028 MEDFileMesh *cur(*it);
7031 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7037 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7039 if(_mesh_one_ts.empty())
7040 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7041 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7044 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7047 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7048 _mesh_one_ts.resize(1);
7049 mesh1TimeStep->incrRef();
7050 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7051 _mesh_one_ts[0]=mesh1TimeStep;
7054 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7056 if ( MEDFileMesh* m = getOneTimeStep() )
7057 return m->getJoints();
7062 * \brief Set Joints that are common to all time-stamps
7064 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7066 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7068 (*it)->setJoints( joints );
7072 void MEDFileMeshMultiTS::write(med_idt fid) const
7074 MEDFileJoints *joints(getJoints());
7075 bool jointsWritten(false);
7077 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7079 if ( jointsWritten )
7080 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7082 jointsWritten = true;
7084 (*it)->copyOptionsFrom(*this);
7088 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7091 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
7093 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
7094 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
7095 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
7096 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
7100 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, 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();
7109 _mesh_one_ts.clear(); //for the moment to be improved
7110 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
7113 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7117 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
7120 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
7123 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
7124 throw INTERP_KERNEL::Exception(oss.str().c_str());
7126 MEDFileUtilities::CheckFileForRead(fileName);
7127 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
7129 MEDCoupling::MEDCouplingMeshType meshType;
7131 MEDCoupling::MEDCouplingAxisType dummy3;
7132 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7133 loadFromFile(fileName,ms.front());
7135 catch(INTERP_KERNEL::Exception& e)
7140 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
7143 loadFromFile(fileName,mName);
7145 catch(INTERP_KERNEL::Exception& e)
7150 MEDFileMeshes *MEDFileMeshes::New()
7152 return new MEDFileMeshes;
7155 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7157 return new MEDFileMeshes(fileName);
7160 void MEDFileMeshes::write(med_idt fid) const
7162 checkConsistencyLight();
7163 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7165 (*it)->copyOptionsFrom(*this);
7170 void MEDFileMeshes::write(const std::string& fileName, int mode) const
7172 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
7173 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
7174 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
7175 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
7176 checkConsistencyLight();
7180 int MEDFileMeshes::getNumberOfMeshes() const
7182 return _meshes.size();
7185 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7187 return new MEDFileMeshesIterator(this);
7190 /** Return a borrowed reference (caller is not responsible) */
7191 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7193 if(i<0 || i>=(int)_meshes.size())
7195 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7196 throw INTERP_KERNEL::Exception(oss.str().c_str());
7198 return _meshes[i]->getOneTimeStep();
7201 /** Return a borrowed reference (caller is not responsible) */
7202 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7204 std::vector<std::string> ms=getMeshesNames();
7205 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7208 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7209 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7210 throw INTERP_KERNEL::Exception(oss.str().c_str());
7212 return getMeshAtPos((int)std::distance(ms.begin(),it));
7215 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7217 std::vector<std::string> ret(_meshes.size());
7219 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7221 const MEDFileMeshMultiTS *f=(*it);
7224 ret[i]=f->getName();
7228 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7229 throw INTERP_KERNEL::Exception(oss.str().c_str());
7235 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7238 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7240 MEDFileMeshMultiTS *cur(*it);
7242 ret=cur->changeNames(modifTab) || ret;
7247 void MEDFileMeshes::cartesianizeMe()
7249 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7251 MEDFileMeshMultiTS *cur(*it);
7253 cur->cartesianizeMe();
7257 void MEDFileMeshes::resize(int newSize)
7259 _meshes.resize(newSize);
7262 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7265 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7266 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7267 elt->setOneTimeStep(mesh);
7268 _meshes.push_back(elt);
7271 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7274 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7275 if(i>=(int)_meshes.size())
7276 _meshes.resize(i+1);
7277 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7278 elt->setOneTimeStep(mesh);
7282 void MEDFileMeshes::destroyMeshAtPos(int i)
7284 if(i<0 || i>=(int)_meshes.size())
7286 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7287 throw INTERP_KERNEL::Exception(oss.str().c_str());
7289 _meshes.erase(_meshes.begin()+i);
7292 void MEDFileMeshes::loadFromFile(const std::string& fileName)
7294 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
7296 _meshes.resize(ms.size());
7297 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7298 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
7301 MEDFileMeshes::MEDFileMeshes()
7305 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
7308 loadFromFile(fileName);
7310 catch(INTERP_KERNEL::Exception& /*e*/)
7314 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7316 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7318 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7319 if((const MEDFileMeshMultiTS *)*it)
7320 meshes[i]=(*it)->deepCopy();
7321 MCAuto<MEDFileMeshes> ret=MEDFileMeshes::New();
7322 ret->_meshes=meshes;
7326 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7328 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7331 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7333 std::vector<const BigMemoryObject *> ret;
7334 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7335 ret.push_back((const MEDFileMeshMultiTS *)*it);
7339 std::string MEDFileMeshes::simpleRepr() const
7341 std::ostringstream oss;
7342 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7343 simpleReprWithoutHeader(oss);
7347 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7349 int nbOfMeshes=getNumberOfMeshes();
7350 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7351 std::vector<std::string> mns=getMeshesNames();
7352 for(int i=0;i<nbOfMeshes;i++)
7353 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7356 void MEDFileMeshes::checkConsistencyLight() const
7358 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7360 std::set<std::string> s;
7361 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7363 const MEDFileMeshMultiTS *elt=(*it);
7366 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7367 throw INTERP_KERNEL::Exception(oss.str().c_str());
7369 std::size_t sz=s.size();
7370 s.insert(std::string((*it)->getName()));
7373 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7374 throw INTERP_KERNEL::Exception(oss.str().c_str());
7379 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7384 _nb_iter=ms->getNumberOfMeshes();
7388 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7392 MEDFileMesh *MEDFileMeshesIterator::nextt()
7394 if(_iter_id<_nb_iter)
7396 MEDFileMeshes *ms(_ms);
7398 return ms->getMeshAtPos(_iter_id++);