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"
31 #include "InterpKernelAutoPtr.hxx"
36 extern med_geometry_type typmai3[34];
38 using namespace MEDCoupling;
40 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
42 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
46 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
48 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
49 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
51 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
52 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
53 ret+=(*it2).capacity();
55 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
56 ret+=(*it).first.capacity()+sizeof(int);
60 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
62 std::vector<const BigMemoryObject *> ret(1);
63 ret[0]=(const MEDFileEquivalences *)_equiv;
68 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
69 * file. The first mesh in the file is loaded.
70 * \param [in] fileName - the name of MED file to read.
71 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
72 * mesh using decrRef() as it is no more needed.
73 * \throw If the file is not readable.
74 * \throw If there is no meshes in the file.
75 * \throw If the mesh in the file is of a not supported type.
77 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
79 std::vector<std::string> ms=MEDCoupling::GetMeshNames(fileName);
82 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
83 throw INTERP_KERNEL::Exception(oss.str().c_str());
85 MEDFileUtilities::CheckFileForRead(fileName);
86 MEDCoupling::MEDCouplingMeshType meshType;
87 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
90 MEDCoupling::MEDCouplingAxisType dummy3;
91 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
92 MCAuto<MEDFileMesh> ret;
97 ret=MEDFileUMesh::New();
102 ret=MEDFileCMesh::New();
107 ret=MEDFileCurveLinearMesh::New();
112 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
113 throw INTERP_KERNEL::Exception(oss.str().c_str());
116 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
121 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
122 * file. The mesh to load is specified by its name and numbers of a time step and an
124 * \param [in] fileName - the name of MED file to read.
125 * \param [in] mName - the name of the mesh to read.
126 * \param [in] dt - the number of a time step.
127 * \param [in] it - the number of an iteration.
128 * \param [in] joints - the sub-domain joints to use instead of those that can be read
129 * from the MED file. Usually this joints are those just read by another iteration
130 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
131 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
132 * mesh using decrRef() as it is no more needed.
133 * \throw If the file is not readable.
134 * \throw If there is no mesh with given attributes in the file.
135 * \throw If the mesh in the file is of a not supported type.
137 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
139 MEDFileUtilities::CheckFileForRead(fileName);
140 MEDCoupling::MEDCouplingMeshType meshType;
141 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
144 MEDCoupling::MEDCouplingAxisType dummy3;
145 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
146 MCAuto<MEDFileMesh> ret;
151 ret=MEDFileUMesh::New();
156 ret=MEDFileCMesh::New();
161 ret=MEDFileCurveLinearMesh::New();
166 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
167 throw INTERP_KERNEL::Exception(oss.str().c_str());
170 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
175 * Writes \a this mesh into an open MED file specified by its descriptor.
176 * \param [in] fid - the MED file descriptor.
177 * \throw If the mesh name is not set.
178 * \throw If the file is open for reading only.
179 * \throw If the writing mode == 1 and the same data is present in an existing file.
181 void MEDFileMesh::write(med_idt fid) const
184 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
186 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
189 const MEDFileEquivalences *eqs(_equiv);
195 * Writes \a this mesh into a MED file specified by its name.
196 * \param [in] fileName - the MED file name.
197 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
198 * - 2 - erase; an existing file is removed.
199 * - 1 - append; same data should not be present in an existing file.
200 * - 0 - overwrite; same data present in an existing file is overwritten.
201 * \throw If the mesh name is not set.
202 * \throw If \a mode == 1 and the same data is present in an existing file.
204 void MEDFileMesh::write(const std::string& fileName, int mode) const
206 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
207 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
208 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
209 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
214 * Checks if \a this and another mesh are equal.
215 * \param [in] other - the mesh to compare with.
216 * \param [in] eps - a precision used to compare real values.
217 * \param [in,out] what - the string returning description of unequal data.
218 * \return bool - \c true if the meshes are equal, \c false, else.
220 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
222 if(_order!=other->_order)
224 what="Orders differ !";
227 if(_iteration!=other->_iteration)
229 what="Iterations differ !";
232 if(fabs(_time-other->_time)>eps)
234 what="Time values differ !";
237 if(_dt_unit!=other->_dt_unit)
239 what="Time units differ !";
242 if(_name!=other->_name)
244 what="Names differ !";
247 //univ_name has been ignored -> not a bug because it is a mutable attribute
248 if(_desc_name!=other->_desc_name)
250 what="Description names differ !";
253 if(!areGrpsEqual(other,what))
255 if(!areFamsEqual(other,what))
257 if(!areEquivalencesEqual(other,what))
262 void MEDFileMesh::setName(const std::string& name)
268 * Clears redundant attributes of incorporated data arrays.
270 void MEDFileMesh::clearNonDiscrAttributes() const
275 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
277 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
279 if((*it).first==_name)
289 * Copies data on groups and families from another mesh.
290 * \param [in] other - the mesh to copy the data from.
292 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
294 _groups=other._groups;
295 _families=other._families;
300 * This method clear all the groups in the map.
301 * So this method does not operate at all on arrays.
302 * So this method can lead to orphan families.
304 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
306 void MEDFileMesh::clearGrpMap()
312 * This method clear all the families in the map.
313 * So this method does not operate at all on arrays.
314 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
316 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
318 void MEDFileMesh::clearFamMap()
324 * This method clear all the families and groups in the map.
325 * So this method does not operate at all on arrays.
326 * As all groups and families entry will be removed after
327 * 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.
329 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
331 void MEDFileMesh::clearFamGrpMaps()
338 * Returns names of families constituting a group.
339 * \param [in] name - the name of the group of interest.
340 * \return std::vector<std::string> - a sequence of names of the families.
341 * \throw If the name of a nonexistent group is specified.
343 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
345 std::string oname(name);
346 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
347 if(it==_groups.end())
349 std::vector<std::string> grps=getGroupsNames();
350 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
351 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
352 throw INTERP_KERNEL::Exception(oss.str().c_str());
358 * Returns names of families constituting some groups.
359 * \param [in] grps - a sequence of names of groups of interest.
360 * \return std::vector<std::string> - a sequence of names of the families.
361 * \throw If a name of a nonexistent group is present in \a grps.
363 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
365 std::set<std::string> fams;
366 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
368 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
369 if(it2==_groups.end())
371 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
372 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
373 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
374 throw INTERP_KERNEL::Exception(oss.str().c_str());
376 fams.insert((*it2).second.begin(),(*it2).second.end());
378 std::vector<std::string> fams2(fams.begin(),fams.end());
383 * Returns ids of families constituting a group.
384 * \param [in] name - the name of the group of interest.
385 * \return std::vector<int> - sequence of ids of the families.
386 * \throw If the name of a nonexistent group is specified.
388 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
390 std::string oname(name);
391 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
392 std::vector<std::string> grps=getGroupsNames();
393 if(it==_groups.end())
395 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
396 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
397 throw INTERP_KERNEL::Exception(oss.str().c_str());
399 return getFamiliesIds((*it).second);
403 * Sets names of families constituting a group. If data on families of this group is
404 * already present, it is overwritten. Every family in \a fams is checked, and if a
405 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
406 * \param [in] name - the name of the group of interest.
407 * \param [in] fams - a sequence of names of families constituting the group.
409 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
411 std::string oname(name);
413 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
415 std::map<std::string,int>::iterator it2=_families.find(*it1);
416 if(it2==_families.end())
422 * Sets families constituting a group. The families are specified by their ids.
423 * If a family name is not found by its id, an exception is thrown.
424 * If several families have same id, the first one in lexical order is taken.
425 * \param [in] name - the name of the group of interest.
426 * \param [in] famIds - a sequence of ids of families constituting the group.
427 * \throw If a family name is not found by its id.
429 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
431 std::string oname(name);
432 std::vector<std::string> fams(famIds.size());
434 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
436 std::string name2=getFamilyNameGivenId(*it1);
443 * Returns names of groups including a given family.
444 * \param [in] name - the name of the family of interest.
445 * \return std::vector<std::string> - a sequence of names of groups including the family.
447 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
449 std::vector<std::string> ret;
450 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
452 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
455 ret.push_back((*it1).first);
463 * Adds an existing family to groups.
464 * \param [in] famName - a name of family to add to \a grps.
465 * \param [in] grps - a sequence of group names to add the family in.
466 * \throw If a family named \a famName not yet exists.
468 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
470 std::string fName(famName);
471 const std::map<std::string,int>::const_iterator it=_families.find(fName);
472 if(it==_families.end())
474 std::vector<std::string> fams=getFamiliesNames();
475 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
476 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
477 throw INTERP_KERNEL::Exception(oss.str().c_str());
479 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
481 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
482 if(it2!=_groups.end())
483 (*it2).second.push_back(fName);
486 std::vector<std::string> grps2(1,fName);
493 * Returns names of all groups of \a this mesh.
494 * \return std::vector<std::string> - a sequence of group names.
496 std::vector<std::string> MEDFileMesh::getGroupsNames() const
498 std::vector<std::string> ret(_groups.size());
500 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
506 * Returns names of all families of \a this mesh.
507 * \return std::vector<std::string> - a sequence of family names.
509 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
511 std::vector<std::string> ret(_families.size());
513 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
519 * Returns names of all families of \a this mesh but like they would be in file.
520 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
521 * 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 !
522 * For your information internaly in memory such families are renamed to have a nicer API.
524 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
526 std::vector<std::string> ret(getFamiliesNames());
527 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
532 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
533 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
534 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
537 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
539 std::vector<std::string> ret;
540 std::vector<std::string> allGrps(getGroupsNames());
541 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
543 std::vector<int> levs(getGrpNonEmptyLevelsExt((*it)));
544 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
551 * Returns all relative mesh levels (including nodes) where a given group is defined.
552 * \param [in] grp - the name of the group of interest.
553 * \return std::vector<int> - a sequence of the relative dimensions.
555 std::vector<int> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
557 std::vector<std::string> fams(getFamiliesOnGroup(grp));
558 return getFamsNonEmptyLevelsExt(fams);
562 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
563 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
564 * \param [in] grps - a sequence of names of the groups of interest.
565 * \return std::vector<int> - a sequence of the relative dimensions.
567 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
569 std::vector<std::string> fams(getFamiliesOnGroups(grps));
570 return getFamsNonEmptyLevels(fams);
574 * Returns all relative mesh levels (including nodes) where given groups are defined.
575 * \param [in] grps - a sequence of names of the groups of interest.
576 * \return std::vector<int> - a sequence of the relative dimensions.
578 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
580 std::vector<std::string> fams(getFamiliesOnGroups(grps));
581 return getFamsNonEmptyLevelsExt(fams);
585 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
586 * To include nodes, call getGrpNonEmptyLevelsExt() method.
587 * \param [in] grp - the name of the group of interest.
588 * \return std::vector<int> - a sequence of the relative dimensions.
590 std::vector<int> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
592 std::vector<std::string> fams(getFamiliesOnGroup(grp));
593 return getFamsNonEmptyLevels(fams);
597 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
598 * To include nodes, call getFamNonEmptyLevelsExt() method.
599 * \param [in] fam - the name of the family of interest.
600 * \return std::vector<int> - a sequence of the relative dimensions.
602 std::vector<int> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
604 std::vector<std::string> fams(1,std::string(fam));
605 return getFamsNonEmptyLevels(fams);
609 * Returns all relative mesh levels (including nodes) where a given family is defined.
610 * \param [in] fam - the name of the family of interest.
611 * \return std::vector<int> - a sequence of the relative dimensions.
613 std::vector<int> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
615 std::vector<std::string> fams(1,std::string(fam));
616 return getFamsNonEmptyLevelsExt(fams);
619 std::string MEDFileMesh::GetMagicFamilyStr()
621 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
625 * Changes a name of every family, included in one group only, to be same as the group name.
626 * \throw If there are families with equal names in \a this mesh.
628 void MEDFileMesh::assignFamilyNameWithGroupName()
630 std::map<std::string, std::vector<std::string> > groups(_groups);
631 std::map<std::string,int> newFams;
632 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
634 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
635 if(grps.size()==1 && groups[grps[0]].size()==1)
637 if(newFams.find(grps[0])!=newFams.end())
639 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
640 throw INTERP_KERNEL::Exception(oss.str().c_str());
642 newFams[grps[0]]=(*it).second;
643 std::vector<std::string>& grps2=groups[grps[0]];
644 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
649 if(newFams.find((*it).first)!=newFams.end())
651 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
652 throw INTERP_KERNEL::Exception(oss.str().c_str());
654 newFams[(*it).first]=(*it).second;
662 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
664 * \return the removed groups.
666 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
668 std::vector<std::string> ret;
669 std::map<std::string, std::vector<std::string> > newGrps;
670 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
672 if((*it).second.empty())
673 ret.push_back((*it).first);
675 newGrps[(*it).first]=(*it).second;
683 * Removes a group from \a this mesh.
684 * \param [in] name - the name of the group to remove.
685 * \throw If no group with such a \a name exists.
687 void MEDFileMesh::removeGroup(const std::string& name)
689 std::string oname(name);
690 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
691 std::vector<std::string> grps=getGroupsNames();
692 if(it==_groups.end())
694 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
695 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
696 throw INTERP_KERNEL::Exception(oss.str().c_str());
702 * Removes a family from \a this mesh.
703 * \param [in] name - the name of the family to remove.
704 * \throw If no family with such a \a name exists.
706 void MEDFileMesh::removeFamily(const std::string& name)
708 std::string oname(name);
709 std::map<std::string, int >::iterator it=_families.find(oname);
710 std::vector<std::string> fams=getFamiliesNames();
711 if(it==_families.end())
713 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
714 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
715 throw INTERP_KERNEL::Exception(oss.str().c_str());
718 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
720 std::vector<std::string>& v=(*it3).second;
721 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
728 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
729 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
730 * family field whatever its level. This method also suppresses the orphan families.
732 * \return - The list of removed groups names.
734 * \sa MEDFileMesh::removeOrphanFamilies.
736 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
738 removeOrphanFamilies();
739 return removeEmptyGroups();
743 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
744 * 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.
746 * \return - The list of removed families names.
747 * \sa MEDFileMesh::removeOrphanGroups.
749 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
751 MCAuto<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
752 std::vector<std::string> ret;
753 if(!((DataArrayInt*)allFamIdsInUse))
755 ret=getFamiliesNames();
756 _families.clear(); _groups.clear();
759 std::map<std::string,int> famMap;
760 std::map<std::string, std::vector<std::string> > grps(_groups);
761 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
763 if(allFamIdsInUse->presenceOfValue((*it).second))
764 famMap[(*it).first]=(*it).second;
767 ret.push_back((*it).first);
768 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
769 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
771 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
772 std::vector<std::string>& famv=(*it3).second;
773 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
779 { _families=famMap; _groups=grps; }
784 * 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
785 * this family is orphan or not.
787 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
789 void MEDFileMesh::removeFamiliesReferedByNoGroups()
791 std::map<std::string,int> fams;
792 std::set<std::string> sfams;
793 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
794 sfams.insert((*it).first);
795 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
796 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
798 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
799 if(*it!=DFT_FAM_NAME)
800 _families.erase(*it);
804 * 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
805 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
806 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
808 * \sa MEDFileMesh::removeOrphanFamilies
810 void MEDFileMesh::rearrangeFamilies()
812 checkOrphanFamilyZero();
813 removeFamiliesReferedByNoGroups();
815 std::vector<int> levels(getNonEmptyLevelsExt());
816 std::set<int> idsRefed;
817 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
818 idsRefed.insert((*it).second);
819 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
821 const DataArrayInt *fams(0);
824 fams=getFamilyFieldAtLevel(*it);
826 catch(INTERP_KERNEL::Exception& e) { }
829 std::vector<bool> v(fams->getNumberOfTuples(),false);
830 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
831 fams->switchOnTupleEqualTo(*pt,v);
832 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
833 if(!unfetchedIds->empty())
835 MCAuto<DataArrayInt> newFams(fams->deepCopy());
836 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
837 setFamilyFieldArr(*it,newFams);
840 removeOrphanFamilies();
844 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
846 void MEDFileMesh::checkOrphanFamilyZero() const
848 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
850 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
852 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
853 throw INTERP_KERNEL::Exception(oss.str().c_str());
859 * Renames a group in \a this mesh.
860 * \param [in] oldName - a current name of the group to rename.
861 * \param [in] newName - a new group name.
862 * \throw If no group named \a oldName exists in \a this mesh.
863 * \throw If a group named \a newName already exists.
865 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
867 std::string oname(oldName);
868 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
869 std::vector<std::string> grps=getGroupsNames();
870 if(it==_groups.end())
872 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
873 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
874 throw INTERP_KERNEL::Exception(oss.str().c_str());
876 std::string nname(newName);
877 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
878 if(it2!=_groups.end())
880 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
881 throw INTERP_KERNEL::Exception(oss.str().c_str());
883 std::vector<std::string> cpy=(*it).second;
885 _groups[newName]=cpy;
889 * Changes an id of a family in \a this mesh.
890 * This method calls changeFamilyIdArr().
891 * \param [in] oldId - a current id of the family.
892 * \param [in] newId - a new family id.
894 void MEDFileMesh::changeFamilyId(int oldId, int newId)
896 changeFamilyIdArr(oldId,newId);
897 std::map<std::string,int> fam2;
898 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
900 if((*it).second==oldId)
901 fam2[(*it).first]=newId;
903 fam2[(*it).first]=(*it).second;
909 * Renames a family in \a this mesh.
910 * \param [in] oldName - a current name of the family to rename.
911 * \param [in] newName - a new family name.
912 * \throw If no family named \a oldName exists in \a this mesh.
913 * \throw If a family named \a newName already exists.
915 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
917 std::string oname(oldName);
918 std::map<std::string, int >::iterator it=_families.find(oname);
919 std::vector<std::string> fams=getFamiliesNames();
920 if(it==_families.end())
922 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
923 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
924 throw INTERP_KERNEL::Exception(oss.str().c_str());
926 std::string nname(newName);
927 std::map<std::string, int >::iterator it2=_families.find(nname);
928 if(it2!=_families.end())
930 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
931 throw INTERP_KERNEL::Exception(oss.str().c_str());
933 int cpy=(*it).second;
935 _families[newName]=cpy;
936 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
938 std::vector<std::string>& v=(*it3).second;
939 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
946 * Checks if \a this and another mesh contains the same families.
947 * \param [in] other - the mesh to compare with \a this one.
948 * \param [in,out] what - an unused parameter.
949 * \return bool - \c true if number of families and their ids are the same in the two
950 * meshes. Families with the id == \c 0 are not considered.
952 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
954 if(_families==other->_families)
956 std::map<std::string,int> fam0;
957 std::map<std::string,int> fam1;
958 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
960 fam0[(*it).first]=(*it).second;
961 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
963 fam1[(*it).first]=(*it).second;
968 * Checks if \a this and another mesh contains the same groups.
969 * \param [in] other - the mesh to compare with \a this one.
970 * \param [in,out] what - a string describing a difference of groups of the two meshes
971 * in case if this method returns \c false.
972 * \return bool - \c true if number of groups and families constituting them are the
973 * same in the two meshes.
975 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
977 if(_groups==other->_groups)
980 std::size_t sz=_groups.size();
981 if(sz!=other->_groups.size())
983 what="Groups differ because not same number !\n";
988 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
989 for(std::size_t i=0;i<sz && ret;i++,it1++)
991 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
992 if(it2!=other->_groups.end())
994 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
995 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
1001 what="A group in first mesh exists not in other !\n";
1007 std::ostringstream oss; oss << "Groups description differs :\n";
1008 oss << "First group description :\n";
1009 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1011 oss << " Group \"" << (*it).first << "\" on following families :\n";
1012 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1013 oss << " \"" << *it2 << "\n";
1015 oss << "Second group description :\n";
1016 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
1018 oss << " Group \"" << (*it).first << "\" on following families :\n";
1019 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1020 oss << " \"" << *it2 << "\n";
1028 * Checks if a group with a given name exists in \a this mesh.
1029 * \param [in] groupName - the group name.
1030 * \return bool - \c true the group \a groupName exists in \a this mesh.
1032 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1034 std::string grpName(groupName);
1035 return _groups.find(grpName)!=_groups.end();
1039 * Checks if a family with a given id exists in \a this mesh.
1040 * \param [in] famId - the family id.
1041 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1043 bool MEDFileMesh::existsFamily(int famId) const
1045 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1046 if((*it2).second==famId)
1052 * Checks if a family with a given name exists in \a this mesh.
1053 * \param [in] familyName - the family name.
1054 * \return bool - \c true the family \a familyName exists in \a this mesh.
1056 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1058 std::string fname(familyName);
1059 return _families.find(fname)!=_families.end();
1063 * Sets an id of a family.
1064 * \param [in] familyName - the family name.
1065 * \param [in] id - a new id of the family.
1067 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1069 std::string fname(familyName);
1070 _families[fname]=id;
1073 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1075 std::string fname(familyName);
1076 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1077 if((*it).second==id)
1079 if((*it).first!=familyName)
1081 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1082 throw INTERP_KERNEL::Exception(oss.str().c_str());
1085 _families[fname]=id;
1089 * Adds a family to \a this mesh.
1090 * \param [in] familyName - a name of the family.
1091 * \param [in] famId - an id of the family.
1092 * \throw If a family with the same name or id already exists in \a this mesh.
1094 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1096 std::string fname(familyName);
1097 std::map<std::string,int>::const_iterator it=_families.find(fname);
1098 if(it==_families.end())
1100 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1101 if((*it2).second==famId)
1103 std::ostringstream oss;
1104 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1105 throw INTERP_KERNEL::Exception(oss.str().c_str());
1107 _families[fname]=famId;
1111 if((*it).second!=famId)
1113 std::ostringstream oss;
1114 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1115 throw INTERP_KERNEL::Exception(oss.str().c_str());
1121 * Creates a group including all mesh entities of given dimension.
1122 * \warning This method does \b not guarantee that the created group includes mesh
1123 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1124 * present in family fields of different dimensions. To assure this, call
1125 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1126 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1128 * \param [in] groupName - a name of the new group.
1129 * \throw If a group named \a groupName already exists.
1130 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1131 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1133 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1135 std::string grpName(groupName);
1136 std::vector<int> levs=getNonEmptyLevelsExt();
1137 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1139 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1140 oss << "Available relative ext levels are : ";
1141 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1142 throw INTERP_KERNEL::Exception(oss.str().c_str());
1144 if(existsGroup(groupName))
1146 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1147 oss << "Already existing groups are : ";
1148 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1149 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1150 throw INTERP_KERNEL::Exception(oss.str().c_str());
1152 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1154 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1155 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1156 std::vector<std::string> familiesOnWholeGroup;
1157 for(const int *it=famIds->begin();it!=famIds->end();it++)
1160 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1162 _groups[grpName]=familiesOnWholeGroup;
1166 * Ensures that given family ids do not present in family fields of dimensions different
1167 * than given ones. If a family id is present in the family fields of dimensions different
1168 * than the given ones, a new family is created and the whole data is updated accordingly.
1169 * \param [in] famIds - a sequence of family ids to check.
1170 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1171 * famIds should exclusively belong.
1172 * \return bool - \c true if no modification is done in \a this mesh by this method.
1174 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1176 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1177 std::vector<int> levs=getNonEmptyLevelsExt();
1178 std::set<int> levs2(levs.begin(),levs.end());
1179 std::vector<int> levsToTest;
1180 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1181 std::set<int> famIds2(famIds.begin(),famIds.end());
1184 if(!_families.empty())
1185 maxFamId=getMaxFamilyId()+1;
1186 std::vector<std::string> allFams=getFamiliesNames();
1187 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1189 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1192 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1193 std::vector<int> tmp;
1194 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1195 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1198 std::string famName=getFamilyNameGivenId(*it2);
1199 std::ostringstream oss; oss << "Family_" << maxFamId;
1200 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1201 addFamilyOnAllGroupsHaving(famName,zeName);
1202 _families[zeName]=maxFamId;
1203 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1212 * Adds a family to a given group in \a this mesh. If the group with a given name does
1213 * not exist, it is created.
1214 * \param [in] grpName - the name of the group to add the family in.
1215 * \param [in] famName - the name of the family to add to the group named \a grpName.
1216 * \throw If \a grpName or \a famName is an empty string.
1217 * \throw If no family named \a famName is present in \a this mesh.
1219 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1221 std::string grpn(grpName);
1222 std::string famn(famName);
1223 if(grpn.empty() || famn.empty())
1224 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1225 std::vector<std::string> fams=getFamiliesNames();
1226 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1228 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1229 oss << "Create this family or choose an existing one ! Existing fams are : ";
1230 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1231 throw INTERP_KERNEL::Exception(oss.str().c_str());
1233 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1234 if(it==_groups.end())
1236 _groups[grpn].push_back(famn);
1240 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1241 if(it2==(*it).second.end())
1242 (*it).second.push_back(famn);
1247 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1248 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1249 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1251 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1253 std::string famNameCpp(famName);
1254 std::string otherCpp(otherFamName);
1255 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1257 std::vector<std::string>& v=(*it).second;
1258 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1260 v.push_back(otherCpp);
1266 * \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).
1267 * \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)
1269 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1272 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1273 std::string grpName(ids->getName());
1275 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1276 ids->checkStrictlyMonotonic(true);
1277 famArr->incrRef(); MCAuto<DataArrayInt> famArrTmp(famArr);
1278 std::vector<std::string> grpsNames=getGroupsNames();
1279 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1281 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1282 throw INTERP_KERNEL::Exception(oss.str().c_str());
1284 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1285 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1286 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1287 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1288 std::vector<int> familyIds;
1289 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1290 int maxVal=getTheMaxAbsFamilyId()+1;
1291 std::map<std::string,int> families(_families);
1292 std::map<std::string, std::vector<std::string> > groups(_groups);
1293 std::vector<std::string> fams;
1294 bool created(false);
1295 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1297 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1298 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1299 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1300 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1303 bool isFamPresent=false;
1304 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1305 isFamPresent=(*itl)->presenceOfValue(*famId);
1307 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1310 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1311 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1312 fams.push_back(locFamName);
1313 if(existsFamily(*famId))
1315 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1316 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1319 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1323 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1324 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1325 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1326 if(existsFamily(*famId))
1328 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1329 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1334 for(std::size_t i=0;i<familyIds.size();i++)
1336 DataArrayInt *da=idsPerfamiliyIds[i];
1337 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1341 _groups[grpName]=fams;
1344 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1346 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1349 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1351 std::string fam(familyNameToChange);
1352 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1354 std::vector<std::string>& fams((*it).second);
1355 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1359 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1365 * Returns a name of the family having a given id or, if no such a family exists, creates
1366 * a new uniquely named family and returns its name.
1367 * \param [in] id - the id of the family whose name is required.
1368 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1369 * \return std::string - the name of the existing or the created family.
1370 * \throw If it is not possible to create a unique family name.
1372 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1374 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1378 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1379 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1380 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1381 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1383 * This method will throws an exception if it is not possible to create a unique family name.
1385 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1387 std::vector<std::string> famAlreadyExisting(families.size());
1389 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1391 if((*it).second!=id)
1393 famAlreadyExisting[ii]=(*it).first;
1402 std::ostringstream oss; oss << "Family_" << id;
1403 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1409 * Sets names and ids of all families in \a this mesh.
1410 * \param [in] info - a map of a family name to a family id.
1412 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1418 * Sets names of all groups and families constituting them in \a this mesh.
1419 * \param [in] info - a map of a group name to a vector of names of families
1420 * constituting the group.
1422 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1428 * Returns an id of the family having a given name.
1429 * \param [in] name - the name of the family of interest.
1430 * \return int - the id of the family of interest.
1431 * \throw If no family with such a \a name exists.
1433 int MEDFileMesh::getFamilyId(const std::string& name) const
1435 std::map<std::string, int>::const_iterator it=_families.find(name);
1436 if(it==_families.end())
1438 std::vector<std::string> fams(getFamiliesNames());
1439 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1440 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1441 throw INTERP_KERNEL::Exception(oss.str().c_str());
1443 return (*it).second;
1447 * Returns ids of the families having given names.
1448 * \param [in] fams - a sequence of the names of families of interest.
1449 * \return std::vector<int> - a sequence of the ids of families of interest.
1450 * \throw If \a fams contains a name of an inexistent family.
1452 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1454 std::vector<int> ret(fams.size());
1456 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1458 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1459 if(it2==_families.end())
1461 std::vector<std::string> fams2=getFamiliesNames();
1462 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1463 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1464 throw INTERP_KERNEL::Exception(oss.str().c_str());
1466 ret[i]=(*it2).second;
1472 * Returns a maximal abs(id) of families in \a this mesh.
1473 * \return int - the maximal norm of family id.
1474 * \throw If there are no families in \a this mesh.
1476 int MEDFileMesh::getMaxAbsFamilyId() const
1478 if(_families.empty())
1479 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1480 int ret=-std::numeric_limits<int>::max();
1481 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1483 ret=std::max(std::abs((*it).second),ret);
1489 * Returns a maximal id of families in \a this mesh.
1490 * \return int - the maximal family id.
1491 * \throw If there are no families in \a this mesh.
1493 int MEDFileMesh::getMaxFamilyId() const
1495 if(_families.empty())
1496 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1497 int ret=-std::numeric_limits<int>::max();
1498 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1500 ret=std::max((*it).second,ret);
1506 * Returns a minimal id of families in \a this mesh.
1507 * \return int - the minimal family id.
1508 * \throw If there are no families in \a this mesh.
1510 int MEDFileMesh::getMinFamilyId() const
1512 if(_families.empty())
1513 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1514 int ret=std::numeric_limits<int>::max();
1515 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1517 ret=std::min((*it).second,ret);
1523 * Returns a maximal id of families in \a this mesh. Not only named families are
1524 * considered but all family fields as well.
1525 * \return int - the maximal family id.
1527 int MEDFileMesh::getTheMaxAbsFamilyId() const
1529 int m1=-std::numeric_limits<int>::max();
1530 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1531 m1=std::max(std::abs((*it).second),m1);
1532 int m2=getMaxAbsFamilyIdInArrays();
1533 return std::max(m1,m2);
1537 * Returns a maximal id of families in \a this mesh. Not only named families are
1538 * considered but all family fields as well.
1539 * \return int - the maximal family id.
1541 int MEDFileMesh::getTheMaxFamilyId() const
1543 int m1=-std::numeric_limits<int>::max();
1544 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1545 m1=std::max((*it).second,m1);
1546 int m2=getMaxFamilyIdInArrays();
1547 return std::max(m1,m2);
1551 * Returns a minimal id of families in \a this mesh. Not only named families are
1552 * considered but all family fields as well.
1553 * \return int - the minimal family id.
1555 int MEDFileMesh::getTheMinFamilyId() const
1557 int m1=std::numeric_limits<int>::max();
1558 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1559 m1=std::min((*it).second,m1);
1560 int m2=getMinFamilyIdInArrays();
1561 return std::min(m1,m2);
1565 * This method only considers the maps. The contain of family array is ignored here.
1567 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1569 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1571 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1573 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1574 v.insert((*it).second);
1575 ret->alloc((int)v.size(),1);
1576 std::copy(v.begin(),v.end(),ret->getPointer());
1581 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1583 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1585 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1587 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1588 MCAuto<DataArrayInt> ret;
1589 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1591 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1592 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1593 if((DataArrayInt *) ret)
1594 ret=dv->buildUnion(ret);
1602 * true is returned if no modification has been needed. false if family
1603 * renumbering has been needed.
1605 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1607 std::vector<int> levs=getNonEmptyLevelsExt();
1608 std::set<int> allFamIds;
1609 int maxId=getMaxFamilyId()+1;
1610 std::map<int,std::vector<int> > famIdsToRenum;
1611 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1613 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1616 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1618 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1620 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1622 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1625 if(famIdsToRenum.empty())
1627 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1628 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1630 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1631 int *famIdsToChange=fam->getPointer();
1632 std::map<int,int> ren;
1633 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1635 if(allIds->presenceOfValue(*it3))
1637 std::string famName=getFamilyNameGivenId(*it3);
1638 std::vector<std::string> grps=getGroupsOnFamily(famName);
1641 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1642 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1643 addFamilyOnGrp((*it4),newFam);
1646 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1647 for(const int *id=ids->begin();id!=ids->end();id++)
1648 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1654 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1655 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1656 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1657 * This method will throw an exception if a same family id is detected in different level.
1658 * \warning This policy is the opposite of those in MED file documentation ...
1660 void MEDFileMesh::normalizeFamIdsTrio()
1662 ensureDifferentFamIdsPerLevel();
1663 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1664 std::vector<int> levs=getNonEmptyLevelsExt();
1665 std::set<int> levsS(levs.begin(),levs.end());
1666 std::set<std::string> famsFetched;
1667 std::map<std::string,int> families;
1668 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1671 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1675 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1676 std::map<int,int> ren;
1677 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1679 int nbOfTuples=fam->getNumberOfTuples();
1680 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1681 for(int *w=start;w!=start+nbOfTuples;w++)
1683 for(const int *it=tmp->begin();it!=tmp->end();it++)
1685 if(allIds->presenceOfValue(*it))
1687 std::string famName=getFamilyNameGivenId(*it);
1688 families[famName]=ren[*it];
1689 famsFetched.insert(famName);
1694 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1697 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1701 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1702 std::map<int,int> ren;
1703 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1705 int nbOfTuples=fam->getNumberOfTuples();
1706 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1707 for(int *w=start;w!=start+nbOfTuples;w++)
1709 for(const int *it=tmp->begin();it!=tmp->end();it++)
1711 if(allIds->presenceOfValue(*it))
1713 std::string famName=getFamilyNameGivenId(*it);
1714 families[famName]=ren[*it];
1715 famsFetched.insert(famName);
1720 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1722 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1725 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1726 fam->fillWithZero();
1727 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1728 if(allIds->presenceOfValue(*it3))
1730 std::string famName=getFamilyNameGivenId(*it3);
1731 families[famName]=0;
1732 famsFetched.insert(famName);
1737 std::vector<std::string> allFams=getFamiliesNames();
1738 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1739 std::set<std::string> unFetchedIds;
1740 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1741 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1742 families[*it4]=_families[*it4];
1747 * This method normalizes fam id with the following policy.
1748 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1749 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1750 * This method will throw an exception if a same family id is detected in different level.
1752 void MEDFileMesh::normalizeFamIdsMEDFile()
1754 ensureDifferentFamIdsPerLevel();
1755 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1756 std::vector<int> levs=getNonEmptyLevelsExt();
1757 std::set<int> levsS(levs.begin(),levs.end());
1758 std::set<std::string> famsFetched;
1759 std::map<std::string,int> families;
1761 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1764 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1767 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1768 std::map<int,int> ren;
1769 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1771 int nbOfTuples=fam->getNumberOfTuples();
1772 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1773 for(int *w=start;w!=start+nbOfTuples;w++)
1775 for(const int *it=tmp->begin();it!=tmp->end();it++)
1777 if(allIds->presenceOfValue(*it))
1779 std::string famName=getFamilyNameGivenId(*it);
1780 families[famName]=ren[*it];
1781 famsFetched.insert(famName);
1787 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1789 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1792 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1793 std::map<int,int> ren;
1794 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1796 int nbOfTuples=fam->getNumberOfTuples();
1797 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1798 for(int *w=start;w!=start+nbOfTuples;w++)
1800 for(const int *it=tmp->begin();it!=tmp->end();it++)
1802 if(allIds->presenceOfValue(*it))
1804 std::string famName=getFamilyNameGivenId(*it);
1805 families[famName]=ren[*it];
1806 famsFetched.insert(famName);
1812 std::vector<std::string> allFams=getFamiliesNames();
1813 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1814 std::set<std::string> unFetchedIds;
1815 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1816 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1817 families[*it4]=_families[*it4];
1822 * Returns a name of the family by its id. If there are several families having the given
1823 * id, the name first in lexical order is returned.
1824 * \param [in] id - the id of the family whose name is required.
1825 * \return std::string - the name of the found family.
1826 * \throw If no family with the given \a id exists.
1828 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1830 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1831 if((*it).second==id)
1833 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1834 throw INTERP_KERNEL::Exception(oss.str().c_str());
1838 * Returns a string describing \a this mesh. This description includes the mesh name and
1839 * the mesh description string.
1840 * \return std::string - the mesh information string.
1842 std::string MEDFileMesh::simpleRepr() const
1844 std::ostringstream oss;
1845 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1846 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1847 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1852 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1853 * an empty one is created.
1855 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1857 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1860 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1861 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1862 arr->fillWithZero();
1863 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1864 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1868 * Returns ids of mesh entities contained in a given group of a given dimension.
1869 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1871 * \param [in] grp - the name of the group of interest.
1872 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1873 * returned instead of ids.
1874 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1875 * numbers, if available and required, of mesh entities of the group. The caller
1876 * is to delete this array using decrRef() as it is no more needed.
1877 * \throw If the name of a nonexistent group is specified.
1878 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1880 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1882 std::vector<std::string> tmp(1);
1884 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1890 * Returns ids of mesh entities contained in given groups of a given dimension.
1891 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1893 * \param [in] grps - the names of the groups of interest.
1894 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1895 * returned instead of ids.
1896 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1897 * numbers, if available and required, of mesh entities of the groups. The caller
1898 * is to delete this array using decrRef() as it is no more needed.
1899 * \throw If the name of a nonexistent group is present in \a grps.
1900 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1902 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1904 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1905 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1909 * Returns ids of mesh entities contained in a given family of a given dimension.
1910 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1912 * \param [in] fam - the name of the family of interest.
1913 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1914 * returned instead of ids.
1915 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1916 * numbers, if available and required, of mesh entities of the family. The caller
1917 * is to delete this array using decrRef() as it is no more needed.
1918 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1920 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1922 std::vector<std::string> tmp(1);
1924 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1930 * Returns ids of nodes contained in a given group.
1931 * \param [in] grp - the name of the group of interest.
1932 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1933 * returned instead of ids.
1934 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1935 * numbers, if available and required, of nodes of the group. The caller
1936 * is to delete this array using decrRef() as it is no more needed.
1937 * \throw If the name of a nonexistent group is specified.
1938 * \throw If the family field is missing for nodes.
1940 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1942 std::vector<std::string> tmp(1);
1944 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1950 * Returns ids of nodes contained in given groups.
1951 * \param [in] grps - the names of the groups of interest.
1952 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1953 * returned instead of ids.
1954 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1955 * numbers, if available and required, of nodes of the groups. The caller
1956 * is to delete this array using decrRef() as it is no more needed.
1957 * \throw If the name of a nonexistent group is present in \a grps.
1958 * \throw If the family field is missing for nodes.
1960 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1962 return getGroupsArr(1,grps,renum);
1966 * Returns ids of nodes contained in a given group.
1967 * \param [in] grp - the name of the group of interest.
1968 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1969 * returned instead of ids.
1970 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1971 * numbers, if available and required, of nodes of the group. The caller
1972 * is to delete this array using decrRef() as it is no more needed.
1973 * \throw If the name of a nonexistent group is specified.
1974 * \throw If the family field is missing for nodes.
1976 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1978 std::vector<std::string> tmp(1);
1980 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1986 * Returns ids of nodes contained in given families.
1987 * \param [in] fams - the names of the families of interest.
1988 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1989 * returned instead of ids.
1990 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1991 * numbers, if available and required, of nodes of the families. The caller
1992 * is to delete this array using decrRef() as it is no more needed.
1993 * \throw If the family field is missing for nodes.
1995 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1997 return getFamiliesArr(1,fams,renum);
2001 * Adds groups of given dimension and creates corresponding families and family fields
2002 * given ids of mesh entities of each group.
2003 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
2004 * \param [in] grps - a sequence of arrays of ids each describing a group.
2005 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2007 * \throw If names of some groups in \a grps are equal.
2008 * \throw If \a grps includes a group with an empty name.
2009 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2010 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2012 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2016 std::set<std::string> grpsName;
2017 std::vector<std::string> grpsName2(grps.size());
2020 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2022 grpsName.insert((*it)->getName());
2023 grpsName2[i]=(*it)->getName();
2025 if(grpsName.size()!=grps.size())
2026 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2027 if(grpsName.find(std::string(""))!=grpsName.end())
2028 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2029 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2030 MCAuto<DataArrayInt> fam;
2031 std::vector< std::vector<int> > fidsOfGroups;
2034 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2038 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2039 for(unsigned int ii=0;ii<grps.size();ii++)
2041 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2042 grps2[ii]->setName(grps[ii]->getName());
2044 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2045 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2048 if(!_families.empty())
2049 offset=getMaxAbsFamilyId()+1;
2050 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2051 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2052 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2053 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2057 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2058 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2059 * For the moment, the two last input parameters are not taken into account.
2061 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2063 std::map<int,std::string> famInv;
2064 for(const int *it=famIds->begin();it!=famIds->end();it++)
2066 std::ostringstream oss;
2067 oss << "Family_" << (*it);
2068 _families[oss.str()]=(*it);
2069 famInv[*it]=oss.str();
2072 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2074 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2076 _groups[grpNames[i]].push_back(famInv[*it2]);
2081 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2083 std::vector<int> levs(getNonEmptyLevels());
2084 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2085 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2087 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2088 ret.insert(ret.end(),elts.begin(),elts.end());
2094 * \sa getAllDistributionOfTypes
2096 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2098 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2099 return mLev->getDistributionOfTypes();
2102 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2104 loadLL(fid,mName,dt,it,mrs);
2105 loadJointsFromFile(fid);
2106 loadEquivalences(fid);
2109 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2111 famArr->applyLin(offset>0?1:-1,offset,0);
2112 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2115 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2116 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2121 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2122 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2123 * If this method fails to find such a name it will throw an exception.
2125 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2128 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2131 std::size_t len=nameTry.length();
2132 for(std::size_t ii=1;ii<len;ii++)
2134 std::string tmp=nameTry.substr(ii,len-ii);
2135 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2141 for(std::size_t i=1;i<30;i++)
2143 std::string tmp1(nameTry.at(0),i);
2145 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2151 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2153 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2155 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2158 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2160 std::size_t nbOfChunks=code.size()/3;
2161 if(code.size()%3!=0)
2162 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2164 for(std::size_t i=0;i<nbOfChunks;i++)
2173 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2174 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2175 * If _name is not empty and that 'm' has the same name nothing is done.
2176 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2178 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2181 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2186 std::string name(m->getName());
2191 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2192 oss << name << "' ! Names must match !";
2193 throw INTERP_KERNEL::Exception(oss.str().c_str());
2197 if(_desc_name.empty())
2198 _desc_name=m->getDescription();
2201 std::string name(m->getDescription());
2204 if(_desc_name!=name)
2206 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2207 oss << name << "' ! Names must match !";
2208 throw INTERP_KERNEL::Exception(oss.str().c_str());
2214 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2216 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2217 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2219 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2220 oss << " - Groups lying on this family : ";
2221 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2222 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2223 oss << std::endl << std::endl;
2228 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2229 * file. The mesh to load is specified by its name and numbers of a time step and an
2231 * \param [in] fileName - the name of MED file to read.
2232 * \param [in] mName - the name of the mesh to read.
2233 * \param [in] dt - the number of a time step.
2234 * \param [in] it - the number of an iteration.
2235 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2236 * mesh using decrRef() as it is no more needed.
2237 * \throw If the file is not readable.
2238 * \throw If there is no mesh with given attributes in the file.
2239 * \throw If the mesh in the file is not an unstructured one.
2241 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2243 MEDFileUtilities::CheckFileForRead(fileName);
2244 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2245 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2249 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2250 * file. The first mesh in the file is loaded.
2251 * \param [in] fileName - the name of MED file to read.
2252 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2253 * mesh using decrRef() as it is no more needed.
2254 * \throw If the file is not readable.
2255 * \throw If there is no meshes in the file.
2256 * \throw If the mesh in the file is not an unstructured one.
2258 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2260 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
2263 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2264 throw INTERP_KERNEL::Exception(oss.str().c_str());
2266 MEDFileUtilities::CheckFileForRead(fileName);
2267 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2269 MEDCoupling::MEDCouplingMeshType meshType;
2271 MEDCoupling::MEDCouplingAxisType dummy3;
2272 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2273 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2277 * Returns an empty instance of MEDFileUMesh.
2278 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2279 * mesh using decrRef() as it is no more needed.
2281 MEDFileUMesh *MEDFileUMesh::New()
2283 return new MEDFileUMesh;
2287 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2288 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2289 * \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.
2290 * 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
2291 * at most the memory consumtion.
2293 * \param [in] fileName - the name of the file.
2294 * \param [in] mName - the name of the mesh to be read.
2295 * \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.
2296 * \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.
2297 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2298 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2299 * \param [in] mrs - the request for what to be loaded.
2300 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2302 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)
2304 MEDFileUtilities::CheckFileForRead(fileName);
2305 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2306 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2310 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2311 * This method is \b NOT wrapped into python.
2313 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)
2315 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2316 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2320 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2322 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2323 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>));
2327 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2329 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2330 ret.push_back((const DataArrayDouble*)_coords);
2331 ret.push_back((const DataArrayInt *)_fam_coords);
2332 ret.push_back((const DataArrayInt *)_num_coords);
2333 ret.push_back((const DataArrayInt *)_rev_num_coords);
2334 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2335 ret.push_back((const PartDefinition *)_part_coords);
2336 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2337 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2341 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2343 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2347 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2349 return new MEDFileUMesh;
2352 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2354 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2355 ret->deepCpyEquivalences(*this);
2356 if((const DataArrayDouble*)_coords)
2357 ret->_coords=_coords->deepCopy();
2358 if((const DataArrayInt*)_fam_coords)
2359 ret->_fam_coords=_fam_coords->deepCopy();
2360 if((const DataArrayInt*)_num_coords)
2361 ret->_num_coords=_num_coords->deepCopy();
2362 if((const DataArrayInt*)_rev_num_coords)
2363 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2364 if((const DataArrayAsciiChar*)_name_coords)
2365 ret->_name_coords=_name_coords->deepCopy();
2367 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2369 if((const MEDFileUMeshSplitL1 *)(*it))
2370 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2372 if((const PartDefinition*)_part_coords)
2373 ret->_part_coords=_part_coords->deepCopy();
2378 * Checks if \a this and another mesh are equal.
2379 * \param [in] other - the mesh to compare with.
2380 * \param [in] eps - a precision used to compare real values.
2381 * \param [in,out] what - the string returning description of unequal data.
2382 * \return bool - \c true if the meshes are equal, \c false, else.
2384 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2386 if(!MEDFileMesh::isEqual(other,eps,what))
2388 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2391 what="Mesh types differ ! This is unstructured and other is NOT !";
2394 clearNonDiscrAttributes();
2395 otherC->clearNonDiscrAttributes();
2396 const DataArrayDouble *coo1=_coords;
2397 const DataArrayDouble *coo2=otherC->_coords;
2398 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2400 what="Mismatch of coordinates ! One is defined and not other !";
2405 bool ret=coo1->isEqual(*coo2,eps);
2408 what="Coords differ !";
2412 const DataArrayInt *famc1=_fam_coords;
2413 const DataArrayInt *famc2=otherC->_fam_coords;
2414 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2416 what="Mismatch of families arr on nodes ! One is defined and not other !";
2421 bool ret=famc1->isEqual(*famc2);
2424 what="Families arr on node differ !";
2428 const DataArrayInt *numc1=_num_coords;
2429 const DataArrayInt *numc2=otherC->_num_coords;
2430 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2432 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2437 bool ret=numc1->isEqual(*numc2);
2440 what="Numbering arr on node differ !";
2444 const DataArrayAsciiChar *namec1=_name_coords;
2445 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2446 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2448 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2453 bool ret=namec1->isEqual(*namec2);
2456 what="Names arr on node differ !";
2460 if(_ms.size()!=otherC->_ms.size())
2462 what="Number of levels differs !";
2465 std::size_t sz=_ms.size();
2466 for(std::size_t i=0;i<sz;i++)
2468 const MEDFileUMeshSplitL1 *s1=_ms[i];
2469 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2470 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2472 what="Mismatch of presence of sub levels !";
2477 bool ret=s1->isEqual(s2,eps,what);
2482 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2485 if((!pd0 && pd1) || (pd0 && !pd1))
2487 what=std::string("node part def is defined only for one among this or other !");
2490 return pd0->isEqual(pd1,what);
2494 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2495 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2496 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2497 * \throw if internal family array is inconsistent
2498 * \sa checkSMESHConsistency()
2500 void MEDFileUMesh::checkConsistency() const
2502 if(!_coords || !_coords->isAllocated())
2505 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2507 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2508 if (!_num_coords || !_rev_num_coords)
2509 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2513 int nbCoo = _coords->getNumberOfTuples();
2515 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2518 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2520 int maxValue=_num_coords->getMaxValue(pos);
2521 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2522 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2524 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2525 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2526 if (_num_coords && !_num_coords->hasUniqueValues())
2527 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2529 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2530 // Now sub part check:
2531 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2532 it != _ms.end(); it++)
2533 (*it)->checkConsistency();
2538 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2539 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2540 * entities as it likes), or non overlapping between all sub-levels.
2541 * \throw if the condition above is not respected
2543 void MEDFileUMesh::checkSMESHConsistency() const
2546 // For all sub-levels, numbering is either always null or with void intersection:
2549 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2550 std::vector< const DataArrayInt * > v;
2551 bool voidOrNot = ((*it)->_num == 0);
2552 for (it++; it != _ms.end(); it++)
2553 if( ((*it)->_num == 0) != voidOrNot )
2554 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2555 else if (!voidOrNot)
2556 v.push_back((*it)->_num);
2559 // don't forget the 1st one:
2560 v.push_back(_ms[0]->_num);
2561 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2562 if (inter->getNumberOfTuples())
2563 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2569 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2570 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2572 void MEDFileUMesh::clearNodeAndCellNumbers()
2575 _rev_num_coords = 0;
2576 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
2577 it != _ms.end(); it++)
2580 (*it)->_rev_num = 0;
2585 * Clears redundant attributes of incorporated data arrays.
2587 void MEDFileUMesh::clearNonDiscrAttributes() const
2589 MEDFileMesh::clearNonDiscrAttributes();
2590 const DataArrayDouble *coo1=_coords;
2592 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2593 const DataArrayInt *famc1=_fam_coords;
2595 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2596 const DataArrayInt *numc1=_num_coords;
2598 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2599 const DataArrayAsciiChar *namc1=_name_coords;
2601 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2602 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2604 const MEDFileUMeshSplitL1 *tmp=(*it);
2606 tmp->clearNonDiscrAttributes();
2610 void MEDFileUMesh::setName(const std::string& name)
2612 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2613 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2614 (*it)->setName(name);
2615 MEDFileMesh::setName(name);
2618 MEDFileUMesh::MEDFileUMesh()
2622 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2625 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2627 catch(INTERP_KERNEL::Exception& e)
2633 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2634 * See MEDFileUMesh::LoadPartOf for detailed description.
2638 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)
2640 MEDFileUMeshL2 loaderl2;
2641 MEDCoupling::MEDCouplingMeshType meshType;
2644 MEDCoupling::MEDCouplingAxisType dummy3;
2645 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2646 if(meshType!=UNSTRUCTURED)
2648 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2649 throw INTERP_KERNEL::Exception(oss.str().c_str());
2651 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2652 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2656 * \brief Write joints in a file
2658 void MEDFileMesh::writeJoints(med_idt fid) const
2660 if ( (const MEDFileJoints*) _joints )
2661 _joints->write(fid);
2665 * \brief Load joints in a file or use provided ones
2667 //================================================================================
2669 * \brief Load joints in a file or use provided ones
2670 * \param [in] fid - MED file descriptor
2671 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2672 * Usually this joints are those just read by another iteration
2673 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2675 //================================================================================
2677 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2679 if ( toUseInstedOfReading )
2680 setJoints( toUseInstedOfReading );
2682 _joints = MEDFileJoints::New( fid, _name );
2685 void MEDFileMesh::loadEquivalences(med_idt fid)
2687 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2689 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2692 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2694 const MEDFileEquivalences *equiv(other._equiv);
2696 _equiv=equiv->deepCopy(this);
2699 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2701 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2702 if(!thisEq && !otherEq)
2704 if(thisEq && otherEq)
2705 return thisEq->isEqual(otherEq,what);
2708 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2713 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2715 const MEDFileEquivalences *equiv(_equiv);
2718 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2719 _equiv->getRepr(oss);
2722 void MEDFileMesh::checkCartesian() const
2724 if(getAxisType()!=AX_CART)
2726 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()) << ").";
2727 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2728 oss << " - call setAxisType(AX_CART)" << std::endl;
2729 oss << " - call cartesianize()";
2730 throw INTERP_KERNEL::Exception(oss.str().c_str());
2735 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2737 int MEDFileMesh::getNumberOfJoints() const
2739 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2743 * \brief Return joints with all adjacent mesh domains
2745 MEDFileJoints * MEDFileMesh::getJoints() const
2747 return const_cast<MEDFileJoints*>(& (*_joints));
2750 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2752 if ( joints != _joints )
2761 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2763 * \sa loadPartUMeshFromFile
2765 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2767 MEDFileUMeshL2 loaderl2;
2768 MEDCoupling::MEDCouplingMeshType meshType;
2771 MEDCoupling::MEDCouplingAxisType axType;
2772 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2773 setAxisType(axType);
2774 if(meshType!=UNSTRUCTURED)
2776 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2777 throw INTERP_KERNEL::Exception(oss.str().c_str());
2779 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2780 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2783 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2785 int lev=loaderl2.getNumberOfLevels();
2787 for(int i=0;i<lev;i++)
2789 if(!loaderl2.emptyLev(i))
2790 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2794 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2796 setName(loaderl2.getName());
2797 setDescription(loaderl2.getDescription());
2798 setUnivName(loaderl2.getUnivName());
2799 setIteration(loaderl2.getIteration());
2800 setOrder(loaderl2.getOrder());
2801 setTimeValue(loaderl2.getTime());
2802 setTimeUnit(loaderl2.getTimeUnit());
2803 _coords=loaderl2.getCoords();
2804 if(!mrs || mrs->isNodeFamilyFieldReading())
2805 _fam_coords=loaderl2.getCoordsFamily();
2806 if(!mrs || mrs->isNodeNumFieldReading())
2807 _num_coords=loaderl2.getCoordsNum();
2808 if(!mrs || mrs->isNodeNameFieldReading())
2809 _name_coords=loaderl2.getCoordsName();
2810 _part_coords=loaderl2.getPartDefOfCoo();
2814 MEDFileUMesh::~MEDFileUMesh()
2818 void MEDFileUMesh::writeLL(med_idt fid) const
2820 const DataArrayDouble *coo=_coords;
2821 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2822 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2823 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2824 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2825 int spaceDim=coo?coo->getNumberOfComponents():0;
2828 mdim=getMeshDimension();
2829 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2830 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2831 for(int i=0;i<spaceDim;i++)
2833 std::string info=coo->getInfoOnComponent(i);
2835 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2836 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
2837 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
2839 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2841 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2842 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2843 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2844 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2845 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2846 (*it)->write(fid,meshName,mdim);
2847 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2851 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2852 * \return std::vector<int> - a sequence of the relative dimensions.
2854 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2856 std::vector<int> ret;
2858 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2859 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2866 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2867 * \return std::vector<int> - a sequence of the relative dimensions.
2869 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2871 std::vector<int> ret0=getNonEmptyLevels();
2872 if((const DataArrayDouble *) _coords)
2874 std::vector<int> ret(ret0.size()+1);
2876 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2882 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2884 std::vector<int> ret;
2885 const DataArrayInt *famCoo(_fam_coords);
2889 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2891 const MEDFileUMeshSplitL1 *cur(*it);
2893 if(cur->getFamilyField())
2899 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2901 std::vector<int> ret;
2902 const DataArrayInt *numCoo(_num_coords);
2906 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2908 const MEDFileUMeshSplitL1 *cur(*it);
2910 if(cur->getNumberField())
2916 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2918 std::vector<int> ret;
2919 const DataArrayAsciiChar *nameCoo(_name_coords);
2923 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2925 const MEDFileUMeshSplitL1 *cur(*it);
2927 if(cur->getNameField())
2934 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2935 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2936 * \param [in] fams - the name of the family of interest.
2937 * \return std::vector<int> - a sequence of the relative dimensions.
2939 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2941 std::vector<int> ret;
2942 std::vector<int> levs(getNonEmptyLevels());
2943 std::vector<int> famIds(getFamiliesIds(fams));
2944 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2945 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2951 * Returns all relative mesh levels (including nodes) where given families are defined.
2952 * \param [in] fams - the names of the families of interest.
2953 * \return std::vector<int> - a sequence of the relative dimensions.
2955 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2957 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2958 const DataArrayInt *famCoords(_fam_coords);
2961 std::vector<int> famIds(getFamiliesIds(fams));
2962 if(famCoords->presenceOfValue(famIds))
2964 std::vector<int> ret(ret0.size()+1);
2966 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2973 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2975 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2976 if((const DataArrayInt *)_fam_coords)
2978 int val=_fam_coords->getMaxValue(tmp);
2979 ret=std::max(ret,std::abs(val));
2981 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2983 if((const MEDFileUMeshSplitL1 *)(*it))
2985 const DataArrayInt *da=(*it)->getFamilyField();
2988 int val=da->getMaxValue(tmp);
2989 ret=std::max(ret,std::abs(val));
2996 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2998 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2999 if((const DataArrayInt *)_fam_coords)
3001 int val=_fam_coords->getMaxValue(tmp);
3002 ret=std::max(ret,val);
3004 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3006 if((const MEDFileUMeshSplitL1 *)(*it))
3008 const DataArrayInt *da=(*it)->getFamilyField();
3011 int val=da->getMaxValue(tmp);
3012 ret=std::max(ret,val);
3019 int MEDFileUMesh::getMinFamilyIdInArrays() const
3021 int ret=std::numeric_limits<int>::max(),tmp=-1;
3022 if((const DataArrayInt *)_fam_coords)
3024 int val=_fam_coords->getMinValue(tmp);
3025 ret=std::min(ret,val);
3027 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3029 if((const MEDFileUMeshSplitL1 *)(*it))
3031 const DataArrayInt *da=(*it)->getFamilyField();
3034 int val=da->getMinValue(tmp);
3035 ret=std::min(ret,val);
3043 * Returns the dimension on cells in \a this mesh.
3044 * \return int - the mesh dimension.
3045 * \throw If there are no cells in this mesh.
3047 int MEDFileUMesh::getMeshDimension() const
3050 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3051 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3052 return (*it)->getMeshDimension()+lev;
3053 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3057 * Returns the space dimension of \a this mesh that is equal to number of components in
3058 * the node coordinates array.
3059 * \return int - the space dimension of \a this mesh.
3060 * \throw If the node coordinates array is not available.
3062 int MEDFileUMesh::getSpaceDimension() const
3064 const DataArrayDouble *coo=_coords;
3066 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3067 return coo->getNumberOfComponents();
3071 * Returns a string describing \a this mesh.
3072 * \return std::string - the mesh information string.
3074 std::string MEDFileUMesh::simpleRepr() const
3076 std::ostringstream oss;
3077 oss << MEDFileMesh::simpleRepr();
3078 const DataArrayDouble *coo=_coords;
3079 oss << "- The dimension of the space is ";
3080 static const char MSG1[]= "*** NO COORDS SET ***";
3081 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3083 oss << _coords->getNumberOfComponents() << std::endl;
3085 oss << MSG1 << std::endl;
3086 oss << "- Type of the mesh : UNSTRUCTURED\n";
3087 oss << "- Number of nodes : ";
3089 oss << _coords->getNumberOfTuples() << std::endl;
3091 oss << MSG1 << std::endl;
3092 std::size_t nbOfLev=_ms.size();
3093 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3094 for(std::size_t i=0;i<nbOfLev;i++)
3096 const MEDFileUMeshSplitL1 *lev=_ms[i];
3097 oss << " - Level #" << -((int) i) << " has dimension : ";
3100 oss << lev->getMeshDimension() << std::endl;
3101 lev->simpleRepr(oss);
3104 oss << MSG2 << std::endl;
3106 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3109 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3110 oss << "- Names of coordinates :" << std::endl;
3111 std::vector<std::string> vars=coo->getVarsOnComponent();
3112 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3113 oss << std::endl << "- Units of coordinates : " << std::endl;
3114 std::vector<std::string> units=coo->getUnitsOnComponent();
3115 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3117 oss << std::endl << std::endl;
3119 getEquivalencesRepr(oss);
3124 * Returns a full textual description of \a this mesh.
3125 * \return std::string - the string holding the mesh description.
3127 std::string MEDFileUMesh::advancedRepr() const
3129 return simpleRepr();
3133 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3134 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3135 * \return int - the number of entities.
3136 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3138 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3140 if(meshDimRelToMaxExt==1)
3142 if(!((const DataArrayDouble *)_coords))
3143 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3144 return _coords->getNumberOfTuples();
3146 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3150 * Returns the family field for mesh entities of a given dimension.
3151 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3152 * \return const DataArrayInt * - the family field. It is an array of ids of families
3153 * each mesh entity belongs to. It can be \c NULL.
3155 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3157 if(meshDimRelToMaxExt==1)
3159 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3160 return l1->getFamilyField();
3163 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3165 if(meshDimRelToMaxExt==1)
3167 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3168 return l1->getFamilyField();
3172 * Returns the optional numbers of mesh entities of a given dimension.
3173 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3174 * \return const DataArrayInt * - the array of the entity numbers.
3175 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3177 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3179 if(meshDimRelToMaxExt==1)
3181 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3182 return l1->getNumberField();
3185 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3187 if(meshDimRelToMaxExt==1)
3188 return _name_coords;
3189 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3190 return l1->getNameField();
3194 * 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).
3196 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3197 * \param [in] gt - The input geometric type for which the part definition is requested.
3198 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3200 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3202 if(meshDimRelToMaxExt==1)
3203 return _part_coords;
3204 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3205 return l1->getPartDef(gt);
3208 int MEDFileUMesh::getNumberOfNodes() const
3210 const DataArrayDouble *coo(_coords);
3212 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3213 return coo->getNumberOfTuples();
3216 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3218 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3219 return l1->getNumberOfCells();
3222 bool MEDFileUMesh::hasImplicitPart() const
3227 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3229 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3232 void MEDFileUMesh::releaseImplicitPartIfAny() const
3236 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3238 std::size_t sz(st.getNumberOfItems());
3239 for(std::size_t i=0;i<sz;i++)
3241 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3242 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3243 if(st[i].getPflName().empty())
3244 m->computeNodeIdsAlg(nodesFetched);
3247 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3248 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3249 m2->computeNodeIdsAlg(nodesFetched);
3254 MEDFileMesh *MEDFileUMesh::cartesianize() const
3256 if(getAxisType()==AX_CART)
3259 return const_cast<MEDFileUMesh *>(this);
3263 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3264 const DataArrayDouble *coords(_coords);
3266 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3267 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3268 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3269 if((const MEDFileUMeshSplitL1 *)(*it))
3270 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3271 ret->_coords=coordsCart;
3272 ret->setAxisType(AX_CART);
3278 * Returns the optional numbers of mesh entities of a given dimension transformed using
3279 * DataArrayInt::invertArrayN2O2O2N().
3280 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3281 * \return const DataArrayInt * - the array of the entity numbers transformed using
3282 * DataArrayInt::invertArrayN2O2O2N().
3283 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3285 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3287 if(meshDimRelToMaxExt==1)
3289 if(!((const DataArrayInt *)_num_coords))
3290 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3291 return _rev_num_coords;
3293 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3294 return l1->getRevNumberField();
3298 * Returns a pointer to the node coordinates array of \a this mesh \b without
3299 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3301 DataArrayDouble *MEDFileUMesh::getCoords() const
3304 MCAuto<DataArrayDouble> tmp(_coords);
3305 if((DataArrayDouble *)tmp)
3313 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3314 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3316 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3317 * \param [in] grp - the name of the group whose mesh entities are included in the
3319 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3320 * according to the optional numbers of entities, if available.
3321 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3322 * delete this mesh using decrRef() as it is no more needed.
3323 * \throw If the name of a nonexistent group is specified.
3324 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3326 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3329 synchronizeTinyInfoOnLeaves();
3330 std::vector<std::string> tmp(1);
3332 return getGroups(meshDimRelToMaxExt,tmp,renum);
3336 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3337 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3339 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3340 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3342 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3343 * according to the optional numbers of entities, if available.
3344 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3345 * delete this mesh using decrRef() as it is no more needed.
3346 * \throw If a name of a nonexistent group is present in \a grps.
3347 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3349 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3352 synchronizeTinyInfoOnLeaves();
3353 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3354 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3355 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3356 zeRet->setName(grps[0]);
3357 return zeRet.retn();
3361 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3362 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3364 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3365 * \param [in] fam - the name of the family whose mesh entities are included in the
3367 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3368 * according to the optional numbers of entities, if available.
3369 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3370 * delete this mesh using decrRef() as it is no more needed.
3371 * \throw If a name of a nonexistent family is present in \a grps.
3372 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3374 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3377 synchronizeTinyInfoOnLeaves();
3378 std::vector<std::string> tmp(1);
3380 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3384 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3385 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3387 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3388 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3390 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3391 * according to the optional numbers of entities, if available.
3392 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3393 * delete this mesh using decrRef() as it is no more needed.
3394 * \throw If a name of a nonexistent family is present in \a fams.
3395 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3397 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3400 synchronizeTinyInfoOnLeaves();
3401 if(meshDimRelToMaxExt==1)
3403 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3404 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3405 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3409 std::vector<int> famIds=getFamiliesIds(fams);
3410 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3411 MCAuto<MEDCouplingUMesh> zeRet;
3413 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3415 zeRet=l1->getFamilyPart(0,0,renum);
3416 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3417 zeRet->setName(fams[0]);
3418 return zeRet.retn();
3422 * Returns ids of mesh entities contained in given families of a given dimension.
3423 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3425 * \param [in] fams - the names of the families of interest.
3426 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3427 * returned instead of ids.
3428 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3429 * numbers, if available and required, of mesh entities of the families. The caller
3430 * is to delete this array using decrRef() as it is no more needed.
3431 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3433 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3435 std::vector<int> famIds=getFamiliesIds(fams);
3436 if(meshDimRelToMaxExt==1)
3438 if((const DataArrayInt *)_fam_coords)
3440 MCAuto<DataArrayInt> da;
3442 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3444 da=_fam_coords->findIdsEqualList(0,0);
3446 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3451 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3453 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3455 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3457 return l1->getFamilyPartArr(0,0,renum);
3461 * Returns a MEDCouplingUMesh of a given relative dimension.
3462 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3463 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3464 * To build a valid MEDCouplingUMesh from the returned one in this case,
3465 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3466 * \param [in] meshDimRelToMax - the relative dimension of interest.
3467 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3468 * optional numbers of mesh entities.
3469 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3470 * delete using decrRef() as it is no more needed.
3471 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3473 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3476 synchronizeTinyInfoOnLeaves();
3477 if(meshDimRelToMaxExt==1)
3481 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3482 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3483 umesh->setCoords(cc);
3484 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3485 umesh->setName(getName());
3489 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3490 return l1->getWholeMesh(renum);
3493 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3495 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3496 return l1->getDistributionOfTypes();
3500 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3501 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3502 * optional numbers of mesh entities.
3503 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3504 * delete using decrRef() as it is no more needed.
3505 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3507 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3509 return getMeshAtLevel(0,renum);
3513 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3514 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3515 * optional numbers of mesh entities.
3516 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3517 * delete using decrRef() as it is no more needed.
3518 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3520 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3522 return getMeshAtLevel(-1,renum);
3526 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3527 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3528 * optional numbers of mesh entities.
3529 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3530 * delete using decrRef() as it is no more needed.
3531 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3533 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3535 return getMeshAtLevel(-2,renum);
3539 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3540 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3541 * optional numbers of mesh entities.
3542 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3543 * delete using decrRef() as it is no more needed.
3544 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3546 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3548 return getMeshAtLevel(-3,renum);
3552 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3553 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3554 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3555 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3557 void MEDFileUMesh::forceComputationOfParts() const
3559 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3561 const MEDFileUMeshSplitL1 *elt(*it);
3563 elt->forceComputationOfParts();
3568 * This method returns a vector of mesh parts containing each exactly one geometric type.
3569 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3570 * This method is only for memory aware users.
3571 * The returned pointers are **NOT** new object pointer. No need to mange them.
3573 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3576 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3577 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3581 * This method returns the part of \a this having the geometric type \a gt.
3582 * If such part is not existing an exception will be thrown.
3583 * The returned pointer is **NOT** new object pointer. No need to mange it.
3585 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3588 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3589 int lev=(int)cm.getDimension()-getMeshDimension();
3590 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3591 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3595 * This method returns for each geo types in \a this number of cells with this geo type.
3596 * 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.
3597 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3599 * \sa getDistributionOfTypes
3601 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3603 std::vector< std::pair<int,int> > ret;
3604 std::vector<int> nel(getNonEmptyLevels());
3605 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3607 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3608 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3610 int nbCells(getNumberOfCellsWithType(*it1));
3611 ret.push_back(std::pair<int,int>(*it1,nbCells));
3614 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3619 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3620 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3622 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3624 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3625 return sp->getGeoTypes();
3628 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3630 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3631 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3632 return sp->getNumberOfCellsWithType(ct);
3636 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3637 * \param [in] gt - the geometric type for which the family field is asked.
3638 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3639 * delete using decrRef() as it is no more needed.
3640 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3642 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3644 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3645 int lev=(int)cm.getDimension()-getMeshDimension();
3646 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3647 return sp->extractFamilyFieldOnGeoType(gt);
3651 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3652 * \param [in] gt - the geometric type for which the number field is asked.
3653 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3654 * delete using decrRef() as it is no more needed.
3655 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3657 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3659 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3660 int lev=(int)cm.getDimension()-getMeshDimension();
3661 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3662 return sp->extractNumberFieldOnGeoType(gt);
3666 * This method returns for specified geometric type \a gt the relative level to \a this.
3667 * If the relative level is empty an exception will be thrown.
3669 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3671 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3672 int ret((int)cm.getDimension()-getMeshDimension());
3673 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3677 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3679 if(meshDimRelToMaxExt==1)
3680 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3681 if(meshDimRelToMaxExt>1)
3682 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3683 int tracucedRk=-meshDimRelToMaxExt;
3684 if(tracucedRk>=(int)_ms.size())
3685 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3686 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3687 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3688 return _ms[tracucedRk];
3691 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3693 if(meshDimRelToMaxExt==1)
3694 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3695 if(meshDimRelToMaxExt>1)
3696 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3697 int tracucedRk=-meshDimRelToMaxExt;
3698 if(tracucedRk>=(int)_ms.size())
3699 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3700 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3701 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3702 return _ms[tracucedRk];
3705 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3707 if(-meshDimRelToMax>=(int)_ms.size())
3708 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3710 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3712 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3714 int ref=(*it)->getMeshDimension();
3715 if(ref+i!=meshDim-meshDimRelToMax)
3716 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3722 * Sets the node coordinates array of \a this mesh.
3723 * \param [in] coords - the new node coordinates array.
3724 * \throw If \a coords == \c NULL.
3726 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3729 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3730 if(coords==(DataArrayDouble *)_coords)
3732 coords->checkAllocated();
3733 int nbOfTuples(coords->getNumberOfTuples());
3736 _fam_coords=DataArrayInt::New();
3737 _fam_coords->alloc(nbOfTuples,1);
3738 _fam_coords->fillWithZero();
3739 _num_coords=0; _rev_num_coords=0; _name_coords=0;
3740 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3741 if((MEDFileUMeshSplitL1 *)(*it))
3742 (*it)->setCoords(coords);
3746 * Change coords without changing anything concerning families and numbering on nodes.
3748 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3751 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3752 if(coords==(DataArrayDouble *)_coords)
3754 coords->checkAllocated();
3755 int nbOfTuples(coords->getNumberOfTuples());
3756 if(_coords.isNull())
3763 int oldNbTuples(_coords->getNumberOfTuples());
3764 if(oldNbTuples!=nbOfTuples)
3765 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3769 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3770 if((MEDFileUMeshSplitL1 *)(*it))
3771 (*it)->setCoords(coords);
3775 * Removes all groups of a given dimension in \a this mesh.
3776 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3777 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3779 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3781 if(meshDimRelToMaxExt==1)
3783 if((DataArrayInt *)_fam_coords)
3784 _fam_coords->fillWithZero();
3787 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3788 l1->eraseFamilyField();
3793 * Removes all families with ids not present in the family fields of \a this mesh.
3795 void MEDFileUMesh::optimizeFamilies()
3797 std::vector<int> levs=getNonEmptyLevelsExt();
3798 std::set<int> allFamsIds;
3799 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3801 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3802 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3804 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3807 std::set<std::string> famNamesToKill;
3808 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3810 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3811 famNamesToKill.insert((*it).first);
3813 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3814 _families.erase(*it);
3815 std::vector<std::string> grpNamesToKill;
3816 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3818 std::vector<std::string> tmp;
3819 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3821 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3822 tmp.push_back(*it2);
3827 tmp.push_back((*it).first);
3829 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3834 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3835 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3836 * The boundary is built according to the following method:
3837 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3838 * coordinates array is extended).
3839 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3840 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3841 * might not be duplicated at all.
3842 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3843 * other side of the group is no more a neighbor)
3844 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3845 * bordering the newly created boundary use the newly computed nodes.
3846 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3847 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3849 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3850 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3852 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3853 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3854 * \sa clearNodeAndCellNumbers()
3856 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3857 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3859 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3860 typedef MCAuto<DataArrayInt> DAInt;
3862 std::vector<int> levs=getNonEmptyLevels();
3863 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3864 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3865 MUMesh m0=getMeshAtLevel(0);
3866 MUMesh m1=getMeshAtLevel(-1);
3867 int nbNodes=m0->getNumberOfNodes();
3868 MUMesh m11=getGroup(-1,grpNameM1);
3869 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3870 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3871 DAInt nodeIdsToDuplicate(tmp00);
3872 DAInt cellsToModifyConn0(tmp11);
3873 DAInt cellsToModifyConn1(tmp22);
3874 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3875 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3876 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3877 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3878 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3879 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3880 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3881 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3882 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3883 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3884 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3885 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3886 DAInt grpIds=getGroupArr(-1,grpNameM1);
3887 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3888 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3889 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3890 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3891 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3892 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3893 m0->setCoords(tmp0->getCoords());
3894 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3895 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3896 m1->setCoords(m0->getCoords());
3897 _coords=m0->getCoords(); _coords->incrRef();
3898 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3899 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3900 DataArrayInt * duplCells;
3901 m1->areCellsIncludedIn(m11, 0, duplCells);
3902 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3903 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3904 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3905 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3906 DAInt szOfCellGrpOfSameType(tmp00);
3907 DAInt idInMsOfCellGrpOfSameType(tmp11);
3909 newm1->setName(getName());
3910 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3912 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3913 DAInt newFam=DataArrayInt::New();
3914 newFam->alloc(newm1->getNumberOfCells(),1);
3915 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3916 // Positive ID for family of nodes, negative for all the rest.
3918 if (m1->getMeshDimension() == 0)
3919 idd=getMaxFamilyId()+1;
3921 idd=getMinFamilyId()-1;
3922 int globStart=0,start=0,end,globEnd;
3923 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3924 for(int i=0;i<nbOfChunks;i++)
3926 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3927 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3929 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3930 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
3931 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3936 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3940 newm1->setCoords(getCoords());
3941 setMeshAtLevel(-1,newm1);
3942 setFamilyFieldArr(-1,newFam);
3943 std::string grpName2(grpNameM1); grpName2+="_dup";
3944 addFamily(grpName2,idd);
3945 addFamilyOnGrp(grpName2,grpName2);
3950 int newNbOfNodes=getCoords()->getNumberOfTuples();
3951 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3952 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3953 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3958 _rev_num_coords = 0;
3959 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
3960 it != _ms.end(); it++)
3963 (*it)->_rev_num = 0;
3965 nodesDuplicated=nodeIdsToDuplicate.retn();
3966 cellsModified=cellsToModifyConn0.retn();
3967 cellsNotModified=cellsToModifyConn1.retn();
3970 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
3971 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
3974 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3975 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3976 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3978 * \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.
3979 * 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.
3981 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3983 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3984 std::vector<int> levs=getNonEmptyLevels();
3986 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3987 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3990 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3992 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3993 std::vector<int> code1=m->getDistributionOfTypes();
3994 end=PutInThirdComponentOfCodeOffset(code1,start);
3995 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3996 bool hasChanged=m->unPolyze();
3997 DataArrayInt *fake=0;
3998 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3999 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4001 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4004 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4005 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4007 MCAuto<DataArrayInt> famField2,numField2;
4008 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4009 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4010 setMeshAtLevel(*it,m);
4011 std::vector<int> code2=m->getDistributionOfTypes();
4012 end=PutInThirdComponentOfCodeOffset(code2,start);
4013 newCode.insert(newCode.end(),code2.begin(),code2.end());
4015 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4019 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4020 setFamilyFieldArr(*it,newFamField);
4024 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4025 setRenumFieldArr(*it,newNumField);
4030 newCode.insert(newCode.end(),code1.begin(),code1.end());
4036 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4037 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4038 o2nRenumCell=o2nRenumCellRet.retn();
4043 /*! \cond HIDDEN_ITEMS */
4044 struct MEDLoaderAccVisit1
4046 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4047 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4048 int _new_nb_of_nodes;
4053 * 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.
4054 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4055 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4056 * -1 values in returned array means that the corresponding old node is no more used.
4058 * \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
4059 * is modified in \a this.
4060 * \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
4063 DataArrayInt *MEDFileUMesh::zipCoords()
4065 const DataArrayDouble *coo(getCoords());
4067 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4068 int nbOfNodes(coo->getNumberOfTuples());
4069 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4070 std::vector<int> neLevs(getNonEmptyLevels());
4071 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4073 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4074 if(zeLev->isMeshStoredSplitByType())
4076 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4077 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4079 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4083 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4084 mesh->computeNodeIdsAlg(nodeIdsInUse);
4087 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4088 if(nbrOfNodesInUse==nbOfNodes)
4089 return 0;//no need to update _part_coords
4090 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4091 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4092 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4093 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4094 MCAuto<DataArrayInt> newFamCoords;
4095 MCAuto<DataArrayAsciiChar> newNameCoords;
4096 if((const DataArrayInt *)_fam_coords)
4097 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4098 MCAuto<DataArrayInt> newNumCoords;
4099 if((const DataArrayInt *)_num_coords)
4100 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4101 if((const DataArrayAsciiChar *)_name_coords)
4102 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4103 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
4104 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4106 if((MEDFileUMeshSplitL1*)*it)
4108 (*it)->renumberNodesInConn(ret->begin());
4109 (*it)->setCoords(_coords);
4112 // updates _part_coords
4113 const PartDefinition *pc(_part_coords);
4116 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4117 _part_coords=tmpPD->composeWith(pc);
4123 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4124 * The extraction of \a this is specified by the extractDef \a input map.
4125 * This map tells for each level of cells, the cells kept in the extraction.
4127 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4128 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4130 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4132 std::vector<int> levs(getNonEmptyLevels());
4133 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4134 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4137 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4138 if((*it).second.isNull())
4139 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4142 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4144 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4145 throw INTERP_KERNEL::Exception(oss.str());
4147 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4148 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4149 mPart->computeNodeIdsAlg(fetchedNodes);
4151 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4155 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4157 * \return - a new reference of MEDFileUMesh
4158 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4160 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4162 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4163 std::vector<int> levs(getNonEmptyLevels());
4164 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4167 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4168 if((*it).second.isNull())
4169 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4172 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4174 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4175 throw INTERP_KERNEL::Exception(oss.str());
4177 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4178 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4179 ret->setMeshAtLevel((*it).first,mPart);
4180 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4183 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4184 ret->setFamilyFieldArr((*it).first,famPart);
4188 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4189 ret->setFamilyFieldArr((*it).first,numPart);
4192 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4193 if(it2!=extractDef.end())
4195 const DataArrayDouble *coo(ret->getCoords());
4197 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4198 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4199 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4200 ret->setCoords(cooPart);
4201 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4204 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4205 ret->setFamilyFieldArr(1,famPart);
4209 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4210 ret->setFamilyFieldArr(1,numPart);
4212 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4216 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4217 m->renumberNodesInConn(o2nNodes->begin());
4218 ret->setMeshAtLevel((*it3).first,m);
4225 * This method performs an extrusion along a path defined by \a m1D.
4226 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4227 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4228 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4229 * This method scans all levels in \a this
4230 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4232 * \param [in] m1D - the mesh defining the extrusion path.
4233 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4234 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4236 * \sa MEDCouplingUMesh::buildExtrudedMesh
4238 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4241 if(getMeshDimension()!=2)
4242 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4243 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4244 m1D->checkConsistencyLight();
4245 if(m1D->getMeshDimension()!=1)
4246 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4247 int nbRep(m1D->getNumberOfCells());
4248 std::vector<int> levs(getNonEmptyLevels());
4249 std::vector<std::string> grps(getGroupsNames());
4250 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4251 DataArrayDouble *coords(0);
4252 std::size_t nbOfLevsOut(levs.size()+1);
4253 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4254 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4256 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4257 item=item->clone(false);
4258 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4259 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4260 tmp->changeSpaceDimension(3+(*lev),0.);
4261 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4262 zeList.push_back(elt);
4264 coords=elt->getCoords();
4267 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4268 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4270 (*it)->setName(getName());
4271 (*it)->setCoords(coords);
4273 for(std::size_t ii=0;ii!=zeList.size();ii++)
4276 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4279 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4280 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4281 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4282 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4283 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4284 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4285 std::vector<const MEDCouplingUMesh *> elts(3);
4286 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4287 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4288 elt->setName(getName());
4291 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4292 ret->setMeshAtLevel(lev,elt);
4294 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4295 endLev=endLev->clone(false); endLev->setCoords(coords);
4296 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4297 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4298 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4299 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4300 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4301 endLev->setName(getName());
4302 ret->setMeshAtLevel(levs.back()-1,endLev);
4304 for(std::size_t ii=0;ii!=zeList.size();ii++)
4307 std::vector< MCAuto<DataArrayInt> > outGrps;
4308 std::vector< const DataArrayInt * > outGrps2;
4311 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4313 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4314 if(!grpArr->empty())
4316 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4317 int offset0(zeList[ii]->getNumberOfCells());
4318 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4319 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4320 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4321 grpArr2->setName(oss.str());
4322 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4323 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4324 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4325 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4330 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4332 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4333 if(!grpArr->empty())
4335 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4336 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4337 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4338 for(int iii=0;iii<nbRep;iii++)
4340 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4341 grpArrs2[iii]=grpArrs[iii];
4343 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4344 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4345 std::ostringstream grpName; grpName << *grp << "_extruded";
4346 grpArrExt->setName(grpName.str());
4347 outGrps.push_back(grpArrExt);
4348 outGrps2.push_back(grpArrExt);
4351 ret->setGroupsAtLevel(lev,outGrps2);
4353 std::vector< MCAuto<DataArrayInt> > outGrps;
4354 std::vector< const DataArrayInt * > outGrps2;
4355 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4357 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4358 if(grpArr1->empty())
4360 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4361 std::ostringstream grpName; grpName << *grp << "_top";
4362 grpArr2->setName(grpName.str());
4363 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4364 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4365 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4367 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4372 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4373 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4374 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4376 * \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
4377 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4378 * \param [in] eps - detection threshold for coordinates.
4379 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4381 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4383 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4386 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4387 int initialNbNodes(getNumberOfNodes());
4388 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4389 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4391 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4393 DataArrayDouble *zeCoords(m0->getCoords());
4394 ret->setMeshAtLevel(0,m0);
4395 std::vector<int> levs(getNonEmptyLevels());
4396 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4399 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4400 ret->setFamilyFieldArr(0,famFieldCpy);
4402 famField=getFamilyFieldAtLevel(1);
4405 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4406 fam->fillWithZero();
4407 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4408 ret->setFamilyFieldArr(1,fam);
4410 ret->copyFamGrpMapsFrom(*this);
4411 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4412 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4416 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4417 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4418 if(m1->getMeshDimension()!=0)
4421 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4422 }//kill unused notUsed var
4423 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4425 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4426 MCAuto<DataArrayInt> bSafe(b);
4429 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4430 throw INTERP_KERNEL::Exception(oss.str().c_str());
4432 b->applyLin(1,initialNbNodes);
4433 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4434 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4435 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4436 m1->renumberNodesInConn(renum->begin());
4438 m1->setCoords(zeCoords);
4439 ret->setMeshAtLevel(*lev,m1);
4440 famField=getFamilyFieldAtLevel(*lev);
4443 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4444 ret->setFamilyFieldArr(*lev,famFieldCpy);
4451 * This method converts all quadratic cells in \a this into linear cells.
4452 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4453 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4455 * \param [in] eps - detection threshold for coordinates.
4456 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4458 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4460 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4463 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4464 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4465 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4466 m0->convertQuadraticCellsToLinear();
4468 DataArrayDouble *zeCoords(m0->getCoords());
4469 ret->setMeshAtLevel(0,m0);
4470 std::vector<int> levs(getNonEmptyLevels());
4471 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4474 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4475 ret->setFamilyFieldArr(0,famFieldCpy);
4477 famField=getFamilyFieldAtLevel(1);
4480 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4481 ret->setFamilyFieldArr(1,fam);
4483 ret->copyFamGrpMapsFrom(*this);
4484 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4488 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4489 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4490 m1->convertQuadraticCellsToLinear();
4493 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4494 MCAuto<DataArrayInt> bSafe(b);
4497 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4498 throw INTERP_KERNEL::Exception(oss.str().c_str());
4500 m1->renumberNodesInConn(b->begin());
4501 m1->setCoords(zeCoords);
4502 ret->setMeshAtLevel(*lev,m1);
4503 famField=getFamilyFieldAtLevel(*lev);
4506 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4507 ret->setFamilyFieldArr(*lev,famFieldCpy);
4514 * Computes the symmetry of \a this.
4515 * \return a new object.
4517 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4519 MCAuto<MEDFileUMesh> ret(deepCopy());
4520 DataArrayDouble *myCoo(getCoords());
4523 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4524 ret->setCoordsForced(newCoo);
4529 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4532 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4533 std::size_t sz(meshes.size()),i(0);
4534 std::vector<const DataArrayDouble *> coos(sz);
4535 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4536 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4539 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4540 coos[i]=(*it)->getCoords();
4541 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4542 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4544 const MEDFileUMesh *ref(meshes[0]);
4545 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4546 std::vector<int> levs(ref->getNonEmptyLevels());
4547 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4548 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4549 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4550 std::map<std::string,int> map1;
4551 std::map<std::string, std::vector<std::string> > map2;
4552 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4554 if((*it)->getSpaceDimension()!=spaceDim)
4555 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4556 if((*it)->getMeshDimension()!=meshDim)
4557 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4558 if((*it)->getNonEmptyLevels()!=levs)
4559 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4560 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4562 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4563 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4564 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4565 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4567 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4568 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4569 map1[(*it3).first]=(*it3).second;
4570 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4571 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4572 map2[(*it4).first]=(*it4).second;
4574 // Easy part : nodes
4575 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4576 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4577 ret->setCoords(coo);
4578 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4580 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4581 ret->setFamilyFieldArr(1,fam_coo);
4583 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4585 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4586 ret->setRenumFieldArr(1,num_coo);
4589 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4591 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4592 if(it2==m_mesh.end())
4593 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4594 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4595 mesh->setCoords(coo); mesh->setName(ref->getName());
4596 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4597 ret->setMeshAtLevel(*it,mesh);
4598 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4599 if(it3!=m_fam.end())
4601 const std::vector<const DataArrayInt *>& fams((*it3).second);
4602 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4604 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4605 famm->renumberInPlace(renum->begin());
4606 ret->setFamilyFieldArr(*it,famm);
4609 if(it4!=m_renum.end())
4611 const std::vector<const DataArrayInt *>& renums((*it4).second);
4612 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4614 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4615 renumm->renumberInPlace(renum->begin());
4616 ret->setRenumFieldArr(*it,renumm);
4621 ret->setFamilyInfo(map1);
4622 ret->setGroupInfo(map2);
4623 ret->setName(ref->getName());
4627 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4629 clearNonDiscrAttributes();
4630 forceComputationOfParts();
4631 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4632 std::vector<int> layer0;
4633 layer0.push_back(getAxisType());//0 i
4634 layer0.push_back(_order); //1 i
4635 layer0.push_back(_iteration);//2 i
4636 layer0.push_back(getSpaceDimension());//3 i
4637 tinyDouble.push_back(_time);//0 d
4638 tinyStr.push_back(_name);//0 s
4639 tinyStr.push_back(_desc_name);//1 s
4640 for(int i=0;i<getSpaceDimension();i++)
4641 tinyStr.push_back(_coords->getInfoOnComponent(i));
4642 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4643 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4645 tinyStr.push_back((*it).first);
4646 layer0.push_back((*it).second);
4648 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4649 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4651 layer0.push_back((int)(*it0).second.size());
4652 tinyStr.push_back((*it0).first);
4653 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4654 tinyStr.push_back(*it1);
4656 // sizeof(layer0)==4+aa+1+bb layer#0
4657 bigArrayD=_coords;// 0 bd
4658 bigArraysI.push_back(_fam_coords);// 0 bi
4659 bigArraysI.push_back(_num_coords);// 1 bi
4660 const PartDefinition *pd(_part_coords);
4662 layer0.push_back(-1);
4665 std::vector<int> tmp0;
4666 pd->serialize(tmp0,bigArraysI);
4667 tinyInt.push_back(tmp0.size());
4668 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4671 std::vector<int> layer1;
4672 std::vector<int> levs(getNonEmptyLevels());
4673 layer1.push_back((int)levs.size());// 0 i <- key
4674 layer1.insert(layer1.end(),levs.begin(),levs.end());
4675 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4677 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4678 lev->serialize(layer1,bigArraysI);
4680 // put layers all together.
4681 tinyInt.push_back(layer0.size());
4682 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4683 tinyInt.push_back(layer1.size());
4684 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4687 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4688 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4690 int sz0(tinyInt[0]);
4691 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4692 int sz1(tinyInt[sz0+1]);
4693 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4695 std::reverse(layer0.begin(),layer0.end());
4696 std::reverse(layer1.begin(),layer1.end());
4697 std::reverse(tinyDouble.begin(),tinyDouble.end());
4698 std::reverse(tinyStr.begin(),tinyStr.end());
4699 std::reverse(bigArraysI.begin(),bigArraysI.end());
4701 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4702 _order=layer0.back(); layer0.pop_back();
4703 _iteration=layer0.back(); layer0.pop_back();
4704 int spaceDim(layer0.back()); layer0.pop_back();
4705 _time=tinyDouble.back(); tinyDouble.pop_back();
4706 _name=tinyStr.back(); tinyStr.pop_back();
4707 _desc_name=tinyStr.back(); tinyStr.pop_back();
4708 _coords=bigArrayD; _coords->rearrange(spaceDim);
4709 for(int i=0;i<spaceDim;i++)
4711 _coords->setInfoOnComponent(i,tinyStr.back());
4714 int nbOfFams(layer0.back()); layer0.pop_back();
4716 for(int i=0;i<nbOfFams;i++)
4718 _families[tinyStr.back()]=layer0.back();
4719 tinyStr.pop_back(); layer0.pop_back();
4721 int nbGroups(layer0.back()); layer0.pop_back();
4723 for(int i=0;i<nbGroups;i++)
4725 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4726 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4727 std::vector<std::string> fams(nbOfFamsOnGrp);
4728 for(int j=0;j<nbOfFamsOnGrp;j++)
4730 fams[j]=tinyStr.back(); tinyStr.pop_back();
4732 _groups[grpName]=fams;
4734 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4735 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4737 int isPd(layer0.back()); layer0.pop_back();
4740 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4741 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4742 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4745 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4747 int nbLevs(layer1.back()); layer1.pop_back();
4748 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4750 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4751 _ms.resize(maxLev+1);
4752 for(int i=0;i<nbLevs;i++)
4756 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4761 * Adds a group of nodes to \a this mesh.
4762 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4763 * The ids should be sorted and different each other (MED file norm).
4765 * \warning this method can alter default "FAMILLE_ZERO" family.
4766 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4768 * \throw If the node coordinates array is not set.
4769 * \throw If \a ids == \c NULL.
4770 * \throw If \a ids->getName() == "".
4771 * \throw If \a ids does not respect the MED file norm.
4772 * \throw If a group with name \a ids->getName() already exists.
4774 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4776 const DataArrayDouble *coords(_coords);
4778 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4779 int nbOfNodes(coords->getNumberOfTuples());
4780 if(!((DataArrayInt *)_fam_coords))
4781 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4783 addGroupUnderground(true,ids,_fam_coords);
4787 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4789 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4790 * The ids should be sorted and different each other (MED file norm).
4792 * \warning this method can alter default "FAMILLE_ZERO" family.
4793 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4795 * \throw If the node coordinates array is not set.
4796 * \throw If \a ids == \c NULL.
4797 * \throw If \a ids->getName() == "".
4798 * \throw If \a ids does not respect the MED file norm.
4799 * \throw If a group with name \a ids->getName() already exists.
4801 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4803 std::vector<int> levs(getNonEmptyLevelsExt());
4804 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4806 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4807 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4809 if(meshDimRelToMaxExt==1)
4810 { addNodeGroup(ids); return ; }
4811 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4812 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4813 addGroupUnderground(false,ids,fam);
4817 * Changes a name of a family specified by its id.
4818 * \param [in] id - the id of the family of interest.
4819 * \param [in] newFamName - the new family name.
4820 * \throw If no family with the given \a id exists.
4822 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4824 std::string oldName=getFamilyNameGivenId(id);
4825 _families.erase(oldName);
4826 _families[newFamName]=id;
4830 * Removes a mesh of a given dimension.
4831 * \param [in] meshDimRelToMax - the relative dimension of interest.
4832 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4834 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4836 std::vector<int> levSet=getNonEmptyLevels();
4837 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4838 if(it==levSet.end())
4839 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4840 int pos=(-meshDimRelToMax);
4845 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4846 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4847 * \param [in] m - the new mesh to set.
4848 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4850 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4851 * another node coordinates array.
4852 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4853 * to the existing meshes of other levels of \a this mesh.
4855 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4857 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4858 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4862 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4863 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4864 * \param [in] m - the new mesh to set.
4865 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4866 * writing \a this mesh in a MED file.
4867 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4869 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4870 * another node coordinates array.
4871 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4872 * to the existing meshes of other levels of \a this mesh.
4874 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4876 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4877 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4880 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4882 dealWithTinyInfo(m);
4883 std::vector<int> levSet=getNonEmptyLevels();
4884 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4886 if((DataArrayDouble *)_coords==0)
4888 DataArrayDouble *c=m->getCoords();
4893 if(m->getCoords()!=_coords)
4894 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4895 int sz=(-meshDimRelToMax)+1;
4896 if(sz>=(int)_ms.size())
4898 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4902 return _ms[-meshDimRelToMax];
4906 * This method allows to set at once the content of different levels in \a this.
4907 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4909 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4910 * \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.
4911 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4913 * \throw If \a there is a null pointer in \a ms.
4914 * \sa MEDFileUMesh::setMeshAtLevel
4916 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4920 const MEDCouplingUMesh *mRef=ms[0];
4922 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4923 std::string name(mRef->getName());
4924 const DataArrayDouble *coo(mRef->getCoords());
4927 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4929 const MEDCouplingUMesh *cur(*it);
4931 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4932 if(coo!=cur->getCoords())
4933 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4934 int mdim=cur->getMeshDimension();
4935 zeDim=std::max(zeDim,mdim);
4936 if(s.find(mdim)!=s.end())
4937 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4939 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4941 int mdim=(*it)->getMeshDimension();
4942 setName((*it)->getName());
4943 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4949 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4950 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4951 * The given meshes must share the same node coordinates array.
4952 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4953 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4954 * create in \a this mesh.
4955 * \throw If \a ms is empty.
4956 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4957 * to the existing meshes of other levels of \a this mesh.
4958 * \throw If the meshes in \a ms do not share the same node coordinates array.
4959 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4960 * of the given meshes.
4961 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
4962 * \throw If names of some meshes in \a ms are equal.
4963 * \throw If \a ms includes a mesh with an empty name.
4965 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4968 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4969 int sz=(-meshDimRelToMax)+1;
4970 if(sz>=(int)_ms.size())
4972 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4973 DataArrayDouble *coo=checkMultiMesh(ms);
4974 if((DataArrayDouble *)_coords==0)
4980 if((DataArrayDouble *)_coords!=coo)
4981 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4982 std::vector<DataArrayInt *> corr;
4983 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4984 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
4985 setMeshAtLevel(meshDimRelToMax,m,renum);
4986 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4987 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4991 * Creates groups at a given level in \a this mesh from a sequence of
4992 * meshes each representing a group.
4993 * The given meshes must share the same node coordinates array.
4994 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4995 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4996 * create in \a this mesh.
4997 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4999 * \throw If \a ms is empty.
5000 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5001 * to the existing meshes of other levels of \a this mesh.
5002 * \throw If the meshes in \a ms do not share the same node coordinates array.
5003 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5004 * of the given meshes.
5005 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5006 * \throw If names of some meshes in \a ms are equal.
5007 * \throw If \a ms includes a mesh with an empty name.
5009 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5012 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5013 int sz=(-meshDimRelToMax)+1;
5014 if(sz>=(int)_ms.size())
5016 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5017 DataArrayDouble *coo=checkMultiMesh(ms);
5018 if((DataArrayDouble *)_coords==0)
5024 if((DataArrayDouble *)_coords!=coo)
5025 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5026 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5027 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5029 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5031 DataArrayInt *arr=0;
5032 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5036 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5037 throw INTERP_KERNEL::Exception(oss.str().c_str());
5040 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5041 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5044 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5046 const DataArrayDouble *ret=ms[0]->getCoords();
5047 int mdim=ms[0]->getMeshDimension();
5048 for(unsigned int i=1;i<ms.size();i++)
5050 ms[i]->checkConsistencyLight();
5051 if(ms[i]->getCoords()!=ret)
5052 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5053 if(ms[i]->getMeshDimension()!=mdim)
5054 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5056 return const_cast<DataArrayDouble *>(ret);
5060 * Sets the family field of a given relative dimension.
5061 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5062 * the family field is set.
5063 * \param [in] famArr - the array of the family field.
5064 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5065 * \throw If \a famArr has an invalid size.
5067 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5069 if(meshDimRelToMaxExt==1)
5076 DataArrayDouble *coo(_coords);
5078 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5079 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5084 if(meshDimRelToMaxExt>1)
5085 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5086 int traducedRk=-meshDimRelToMaxExt;
5087 if(traducedRk>=(int)_ms.size())
5088 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5089 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5090 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5091 return _ms[traducedRk]->setFamilyArr(famArr);
5095 * Sets the optional numbers of mesh entities of a given dimension.
5096 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5097 * \param [in] renumArr - the array of the numbers.
5098 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5099 * \throw If \a renumArr has an invalid size.
5101 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5103 if(meshDimRelToMaxExt==1)
5111 DataArrayDouble *coo(_coords);
5113 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5114 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5115 renumArr->incrRef();
5116 _num_coords=renumArr;
5120 if(meshDimRelToMaxExt>1)
5121 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5122 int traducedRk=-meshDimRelToMaxExt;
5123 if(traducedRk>=(int)_ms.size())
5124 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5125 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5126 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5127 return _ms[traducedRk]->setRenumArr(renumArr);
5131 * Sets the optional names of mesh entities of a given dimension.
5132 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5133 * \param [in] nameArr - the array of the names.
5134 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5135 * \throw If \a nameArr has an invalid size.
5137 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5139 if(meshDimRelToMaxExt==1)
5146 DataArrayDouble *coo(_coords);
5148 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5149 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5151 _name_coords=nameArr;
5154 if(meshDimRelToMaxExt>1)
5155 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : 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]->setNameArr(nameArr);
5164 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5166 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5167 if((const MEDFileUMeshSplitL1 *)(*it))
5168 (*it)->synchronizeTinyInfo(*this);
5172 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5174 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5176 DataArrayInt *arr=_fam_coords;
5178 arr->changeValue(oldId,newId);
5179 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5181 MEDFileUMeshSplitL1 *sp=(*it);
5184 sp->changeFamilyIdArr(oldId,newId);
5189 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5191 std::list< MCAuto<DataArrayInt> > ret;
5192 const DataArrayInt *da(_fam_coords);
5194 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5195 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5197 const MEDFileUMeshSplitL1 *elt(*it);
5200 da=elt->getFamilyField();
5202 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5208 void MEDFileUMesh::computeRevNum() const
5210 if((const DataArrayInt *)_num_coords)
5213 int maxValue=_num_coords->getMaxValue(pos);
5214 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5218 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5220 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5223 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5225 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5226 ret.push_back((const DataArrayInt *)_fam_nodes);
5227 ret.push_back((const DataArrayInt *)_num_nodes);
5228 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5229 ret.push_back((const DataArrayInt *)_fam_cells);
5230 ret.push_back((const DataArrayInt *)_num_cells);
5231 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5232 ret.push_back((const DataArrayInt *)_fam_faces);
5233 ret.push_back((const DataArrayInt *)_num_faces);
5234 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5235 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5236 ret.push_back((const DataArrayInt *)_rev_num_cells);
5237 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5241 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5243 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5244 if((const DataArrayInt *)_fam_nodes)
5246 int val=_fam_nodes->getMaxValue(tmp);
5247 ret=std::max(ret,std::abs(val));
5249 if((const DataArrayInt *)_fam_cells)
5251 int val=_fam_cells->getMaxValue(tmp);
5252 ret=std::max(ret,std::abs(val));
5254 if((const DataArrayInt *)_fam_faces)
5256 int val=_fam_faces->getMaxValue(tmp);
5257 ret=std::max(ret,std::abs(val));
5262 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5264 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5265 if((const DataArrayInt *)_fam_nodes)
5267 int val=_fam_nodes->getMaxValue(tmp);
5268 ret=std::max(ret,val);
5270 if((const DataArrayInt *)_fam_cells)
5272 int val=_fam_cells->getMaxValue(tmp);
5273 ret=std::max(ret,val);
5275 if((const DataArrayInt *)_fam_faces)
5277 int val=_fam_faces->getMaxValue(tmp);
5278 ret=std::max(ret,val);
5283 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5285 int ret=std::numeric_limits<int>::max(),tmp=-1;
5286 if((const DataArrayInt *)_fam_nodes)
5288 int val=_fam_nodes->getMinValue(tmp);
5289 ret=std::min(ret,val);
5291 if((const DataArrayInt *)_fam_cells)
5293 int val=_fam_cells->getMinValue(tmp);
5294 ret=std::min(ret,val);
5296 if((const DataArrayInt *)_fam_faces)
5298 int val=_fam_faces->getMinValue(tmp);
5299 ret=std::min(ret,val);
5304 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5306 if(!MEDFileMesh::isEqual(other,eps,what))
5308 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5311 what="Mesh types differ ! This is structured and other is NOT !";
5314 const DataArrayInt *famc1=_fam_nodes;
5315 const DataArrayInt *famc2=otherC->_fam_nodes;
5316 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5318 what="Mismatch of families arr on nodes ! One is defined and not other !";
5323 bool ret=famc1->isEqual(*famc2);
5326 what="Families arr on nodes differ !";
5331 famc2=otherC->_fam_cells;
5332 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5334 what="Mismatch of families arr on cells ! One is defined and not other !";
5339 bool ret=famc1->isEqual(*famc2);
5342 what="Families arr on cells differ !";
5347 famc2=otherC->_fam_faces;
5348 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5350 what="Mismatch of families arr on faces ! One is defined and not other !";
5355 bool ret=famc1->isEqual(*famc2);
5358 what="Families arr on faces differ !";
5363 famc2=otherC->_num_nodes;
5364 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5366 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5371 bool ret=famc1->isEqual(*famc2);
5374 what="Numbering arr on nodes differ !";
5379 famc2=otherC->_num_cells;
5380 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5382 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5387 bool ret=famc1->isEqual(*famc2);
5390 what="Numbering arr on cells differ !";
5395 famc2=otherC->_num_faces;
5396 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5398 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5403 bool ret=famc1->isEqual(*famc2);
5406 what="Numbering arr on faces differ !";
5410 const DataArrayAsciiChar *d1=_names_cells;
5411 const DataArrayAsciiChar *d2=otherC->_names_cells;
5412 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5414 what="Mismatch of naming arr on cells ! One is defined and not other !";
5419 bool ret=d1->isEqual(*d2);
5422 what="Naming arr on cells differ !";
5427 d2=otherC->_names_faces;
5428 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5430 what="Mismatch of naming arr on faces ! One is defined and not other !";
5435 bool ret=d1->isEqual(*d2);
5438 what="Naming arr on faces differ !";
5443 d2=otherC->_names_nodes;
5444 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5446 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5451 bool ret=d1->isEqual(*d2);
5454 what="Naming arr on nodes differ !";
5461 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5463 MEDFileMesh::clearNonDiscrAttributes();
5464 const DataArrayInt *tmp=_fam_nodes;
5466 (const_cast<DataArrayInt *>(tmp))->setName("");
5469 (const_cast<DataArrayInt *>(tmp))->setName("");
5472 (const_cast<DataArrayInt *>(tmp))->setName("");
5475 (const_cast<DataArrayInt *>(tmp))->setName("");
5478 (const_cast<DataArrayInt *>(tmp))->setName("");
5481 (const_cast<DataArrayInt *>(tmp))->setName("");
5485 * Returns ids of mesh entities contained in given families of a given dimension.
5486 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5488 * \param [in] fams - the names of the families of interest.
5489 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5490 * returned instead of ids.
5491 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5492 * numbers, if available and required, of mesh entities of the families. The caller
5493 * is to delete this array using decrRef() as it is no more needed.
5494 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5496 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5498 std::vector<int> famIds(getFamiliesIds(fams));
5499 switch(meshDimRelToMaxExt)
5503 if((const DataArrayInt *)_fam_nodes)
5505 MCAuto<DataArrayInt> da;
5507 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5509 da=_fam_nodes->findIdsEqualList(0,0);
5511 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5516 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5521 if((const DataArrayInt *)_fam_cells)
5523 MCAuto<DataArrayInt> da;
5525 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5527 da=_fam_cells->findIdsEqualList(0,0);
5529 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5534 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5539 if((const DataArrayInt *)_fam_faces)
5541 MCAuto<DataArrayInt> da;
5543 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5545 da=_fam_faces->findIdsEqualList(0,0);
5547 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5552 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5556 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5558 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5562 * Sets the family field of a given relative dimension.
5563 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5564 * the family field is set.
5565 * \param [in] famArr - the array of the family field.
5566 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5567 * \throw If \a famArr has an invalid size.
5568 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5570 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5572 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5574 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5575 switch(meshDimRelToMaxExt)
5579 int nbCells(mesh->getNumberOfCells());
5581 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5587 int nbNodes(mesh->getNumberOfNodes());
5589 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5595 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5597 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5602 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5609 * Sets the optional numbers of mesh entities of a given dimension.
5610 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5611 * \param [in] renumArr - the array of the numbers.
5612 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5613 * \throw If \a renumArr has an invalid size.
5614 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5616 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5618 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5620 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5621 switch(meshDimRelToMaxExt)
5625 int nbCells=mesh->getNumberOfCells();
5626 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5627 _num_cells=renumArr;
5632 int nbNodes=mesh->getNumberOfNodes();
5633 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5634 _num_nodes=renumArr;
5639 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5640 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5641 _num_faces=renumArr;
5645 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5648 renumArr->incrRef();
5652 * Sets the optional names of mesh entities of a given dimension.
5653 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5654 * \param [in] nameArr - the array of the names.
5655 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5656 * \throw If \a nameArr has an invalid size.
5658 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5660 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5662 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5663 switch(meshDimRelToMaxExt)
5667 int nbCells=mesh->getNumberOfCells();
5668 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5669 _names_cells=nameArr;
5674 int nbNodes=mesh->getNumberOfNodes();
5675 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5676 _names_nodes=nameArr;
5681 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5682 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5683 _names_cells=nameArr;
5686 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5693 * Adds a group of nodes to \a this mesh.
5694 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5695 * The ids should be sorted and different each other (MED file norm).
5697 * \warning this method can alter default "FAMILLE_ZERO" family.
5698 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5700 * \throw If the node coordinates array is not set.
5701 * \throw If \a ids == \c NULL.
5702 * \throw If \a ids->getName() == "".
5703 * \throw If \a ids does not respect the MED file norm.
5704 * \throw If a group with name \a ids->getName() already exists.
5706 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5712 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5714 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5715 * The ids should be sorted and different each other (MED file norm).
5717 * \warning this method can alter default "FAMILLE_ZERO" family.
5718 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5720 * \throw If the node coordinates array is not set.
5721 * \throw If \a ids == \c NULL.
5722 * \throw If \a ids->getName() == "".
5723 * \throw If \a ids does not respect the MED file norm.
5724 * \throw If a group with name \a ids->getName() already exists.
5726 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5728 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5729 addGroupUnderground(false,ids,fam);
5734 * Returns the family field for mesh entities of a given dimension.
5735 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5736 * \return const DataArrayInt * - the family field. It is an array of ids of families
5737 * each mesh entity belongs to. It can be \c NULL.
5738 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5740 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5742 switch(meshDimRelToMaxExt)
5751 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5756 * Returns the family field for mesh entities of a given dimension.
5757 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5758 * \return const DataArrayInt * - the family field. It is an array of ids of families
5759 * each mesh entity belongs to. It can be \c NULL.
5760 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5762 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5764 switch(meshDimRelToMaxExt)
5773 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5778 * Returns the optional numbers of mesh entities of a given dimension.
5779 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5780 * \return const DataArrayInt * - the array of the entity numbers.
5781 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5782 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5784 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5786 switch(meshDimRelToMaxExt)
5795 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5800 * Returns the optional numbers of mesh entities of a given dimension transformed using
5801 * DataArrayInt::invertArrayN2O2O2N().
5802 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5803 * \return const DataArrayInt * - the array of the entity numbers transformed using
5804 * DataArrayInt::invertArrayN2O2O2N().
5805 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5806 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5808 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5810 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5811 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5812 if(meshDimRelToMaxExt==0)
5814 if((const DataArrayInt *)_num_cells)
5817 int maxValue=_num_cells->getMaxValue(pos);
5818 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5819 return _rev_num_cells;
5822 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5826 if((const DataArrayInt *)_num_nodes)
5829 int maxValue=_num_nodes->getMaxValue(pos);
5830 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5831 return _rev_num_nodes;
5834 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5838 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5840 switch(meshDimRelToMaxExt)
5843 return _names_cells;
5845 return _names_nodes;
5847 return _names_faces;
5849 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5854 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5855 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5857 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5859 std::vector<int> ret(1);
5864 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5865 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5867 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5869 std::vector<int> ret(2);
5875 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5877 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5879 std::vector<int> ret;
5880 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5891 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5893 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5895 std::vector<int> ret;
5896 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5907 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5909 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5911 std::vector<int> ret;
5912 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5923 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5925 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5927 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5931 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5933 DataArrayInt *arr=_fam_nodes;
5935 arr->changeValue(oldId,newId);
5938 arr->changeValue(oldId,newId);
5941 arr->changeValue(oldId,newId);
5944 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5946 std::list< MCAuto<DataArrayInt> > ret;
5947 const DataArrayInt *da(_fam_nodes);
5949 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5952 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5955 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5959 void MEDFileStructuredMesh::deepCpyAttributes()
5961 if((const DataArrayInt*)_fam_nodes)
5962 _fam_nodes=_fam_nodes->deepCopy();
5963 if((const DataArrayInt*)_num_nodes)
5964 _num_nodes=_num_nodes->deepCopy();
5965 if((const DataArrayAsciiChar*)_names_nodes)
5966 _names_nodes=_names_nodes->deepCopy();
5967 if((const DataArrayInt*)_fam_cells)
5968 _fam_cells=_fam_cells->deepCopy();
5969 if((const DataArrayInt*)_num_cells)
5970 _num_cells=_num_cells->deepCopy();
5971 if((const DataArrayAsciiChar*)_names_cells)
5972 _names_cells=_names_cells->deepCopy();
5973 if((const DataArrayInt*)_fam_faces)
5974 _fam_faces=_fam_faces->deepCopy();
5975 if((const DataArrayInt*)_num_faces)
5976 _num_faces=_num_faces->deepCopy();
5977 if((const DataArrayAsciiChar*)_names_faces)
5978 _names_faces=_names_faces->deepCopy();
5979 if((const DataArrayInt*)_rev_num_nodes)
5980 _rev_num_nodes=_rev_num_nodes->deepCopy();
5981 if((const DataArrayInt*)_rev_num_cells)
5982 _rev_num_cells=_rev_num_cells->deepCopy();
5986 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5988 * \return a pointer to cartesian mesh that need to be managed by the caller.
5989 * \warning the returned pointer has to be managed by the caller.
5993 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5994 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5995 * \param [in] renum - it must be \c false.
5996 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5997 * delete using decrRef() as it is no more needed.
5999 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6003 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6004 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6005 switch(meshDimRelToMax)
6011 return const_cast<MEDCouplingStructuredMesh *>(m);
6016 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6017 buildMinusOneImplicitPartIfNeeded();
6018 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6024 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6028 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6030 std::vector<int> ret;
6031 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6032 if(famCells && famCells->presenceOfValue(ret))
6034 if(famFaces && famFaces->presenceOfValue(ret))
6039 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6041 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6042 const DataArrayInt *famNodes(_fam_nodes);
6043 if(famNodes && famNodes->presenceOfValue(ret))
6049 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6050 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6051 * \return int - the number of entities.
6052 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6054 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6056 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6058 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6059 switch(meshDimRelToMaxExt)
6062 return cmesh->getNumberOfCells();
6064 return cmesh->getNumberOfNodes();
6066 return cmesh->getNumberOfCellsOfSubLevelMesh();
6068 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6072 int MEDFileStructuredMesh::getNumberOfNodes() const
6074 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6076 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6077 return cmesh->getNumberOfNodes();
6080 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6082 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6084 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6085 switch(meshDimRelToMaxExt)
6088 return cmesh->getNumberOfCells();
6090 return cmesh->getNumberOfCellsOfSubLevelMesh();
6092 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6096 bool MEDFileStructuredMesh::hasImplicitPart() const
6102 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6104 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6106 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6107 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6110 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6111 if(cm.getReverseExtrudedType()!=gt)
6112 throw INTERP_KERNEL::Exception(MSG);
6113 buildImplicitPart();
6114 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6118 if(gt!=zeFaceMesh->getCellModelEnum())
6119 throw INTERP_KERNEL::Exception(MSG);
6120 return zeFaceMesh->getNumberOfCells();
6124 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6126 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6128 buildImplicitPart();
6131 void MEDFileStructuredMesh::buildImplicitPart() const
6133 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6135 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6136 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6139 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6141 _faces_if_necessary=0;
6145 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6146 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6148 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6150 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6153 return _faces_if_necessary;
6156 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6158 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6160 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6161 switch(meshDimRelToMax)
6165 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6170 int mdim(cmesh->getMeshDimension());
6172 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6173 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6177 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6181 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6183 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6186 return getNumberOfCellsAtLevel(0);
6189 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6191 if(st.getNumberOfItems()!=1)
6192 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 !");
6193 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6194 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6195 if(getNumberOfNodes()!=(int)nodesFetched.size())
6196 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6197 if(st[0].getPflName().empty())
6199 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6202 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6203 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6204 int sz(nodesFetched.size());
6205 for(const int *work=arr->begin();work!=arr->end();work++)
6207 std::vector<int> conn;
6208 cmesh->getNodeIdsOfCell(*work,conn);
6209 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6210 if(*it>=0 && *it<sz)
6211 nodesFetched[*it]=true;
6213 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6217 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6219 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6223 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6224 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6226 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6227 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6229 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6232 if(!mrs || mrs->isCellFamilyFieldReading())
6234 famCells=DataArrayInt::New();
6235 famCells->alloc(nbOfElt,1);
6236 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6239 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6242 if(!mrs || mrs->isCellNumFieldReading())
6244 numCells=DataArrayInt::New();
6245 numCells->alloc(nbOfElt,1);
6246 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6249 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6252 if(!mrs || mrs->isCellNameFieldReading())
6254 namesCells=DataArrayAsciiChar::New();
6255 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6256 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6257 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6262 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6264 setName(strm->getName());
6265 setDescription(strm->getDescription());
6266 setUnivName(strm->getUnivName());
6267 setIteration(strm->getIteration());
6268 setOrder(strm->getOrder());
6269 setTimeValue(strm->getTime());
6270 setTimeUnit(strm->getTimeUnit());
6271 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6272 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6273 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6276 if(!mrs || mrs->isNodeFamilyFieldReading())
6278 int nbNodes(getNumberOfNodes());
6280 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6281 _fam_nodes=DataArrayInt::New();
6282 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6283 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...
6284 _fam_nodes->fillWithZero();
6285 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6288 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6291 if(!mrs || mrs->isNodeNumFieldReading())
6293 _num_nodes=DataArrayInt::New();
6294 _num_nodes->alloc(nbOfElt,1);
6295 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6298 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6301 if(!mrs || mrs->isNodeNameFieldReading())
6303 _names_nodes=DataArrayAsciiChar::New();
6304 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6305 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6306 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6309 int meshDim(getStructuredMesh()->getMeshDimension());
6310 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6312 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6315 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6317 int meshDim(getStructuredMesh()->getMeshDimension());
6318 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6320 if((const DataArrayInt *)_fam_cells)
6321 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6322 if((const DataArrayInt *)_fam_faces)
6323 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6324 if((const DataArrayInt *)_fam_nodes)
6325 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6326 if((const DataArrayInt *)_num_cells)
6327 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6328 if((const DataArrayInt *)_num_faces)
6329 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6330 if((const DataArrayInt *)_num_nodes)
6331 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6332 if((const DataArrayAsciiChar *)_names_cells)
6334 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6336 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6337 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6338 throw INTERP_KERNEL::Exception(oss.str().c_str());
6340 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6342 if((const DataArrayAsciiChar *)_names_faces)
6344 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6346 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6347 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6348 throw INTERP_KERNEL::Exception(oss.str().c_str());
6350 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6352 if((const DataArrayAsciiChar *)_names_nodes)
6354 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6356 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6357 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6358 throw INTERP_KERNEL::Exception(oss.str().c_str());
6360 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6363 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6367 * Returns an empty instance of MEDFileCMesh.
6368 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6369 * mesh using decrRef() as it is no more needed.
6371 MEDFileCMesh *MEDFileCMesh::New()
6373 return new MEDFileCMesh;
6377 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6378 * file. The first mesh in the file is loaded.
6379 * \param [in] fileName - the name of MED file to read.
6380 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6381 * mesh using decrRef() as it is no more needed.
6382 * \throw If the file is not readable.
6383 * \throw If there is no meshes in the file.
6384 * \throw If the mesh in the file is not a Cartesian one.
6386 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6388 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6391 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6392 throw INTERP_KERNEL::Exception(oss.str().c_str());
6394 MEDFileUtilities::CheckFileForRead(fileName);
6395 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6397 MEDCoupling::MEDCouplingMeshType meshType;
6399 MEDCoupling::MEDCouplingAxisType dummy3;
6400 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6401 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
6405 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6406 * file. The mesh to load is specified by its name and numbers of a time step and an
6408 * \param [in] fileName - the name of MED file to read.
6409 * \param [in] mName - the name of the mesh to read.
6410 * \param [in] dt - the number of a time step.
6411 * \param [in] it - the number of an iteration.
6412 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6413 * mesh using decrRef() as it is no more needed.
6414 * \throw If the file is not readable.
6415 * \throw If there is no mesh with given attributes in the file.
6416 * \throw If the mesh in the file is not a Cartesian one.
6418 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6420 MEDFileUtilities::CheckFileForRead(fileName);
6421 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6422 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6425 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6427 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6430 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6432 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6433 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6438 * Returns the dimension on cells in \a this mesh.
6439 * \return int - the mesh dimension.
6440 * \throw If there are no cells in this mesh.
6442 int MEDFileCMesh::getMeshDimension() const
6444 if(!((const MEDCouplingCMesh*)_cmesh))
6445 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6446 return _cmesh->getMeshDimension();
6450 * Returns the dimension on nodes in \a this mesh.
6451 * \return int - the space dimension.
6452 * \throw If there are no cells in this mesh.
6454 int MEDFileCMesh::getSpaceDimension() const
6456 if(!((const MEDCouplingCMesh*)_cmesh))
6457 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6458 return _cmesh->getSpaceDimension();
6462 * Returns a string describing \a this mesh.
6463 * \return std::string - the mesh information string.
6465 std::string MEDFileCMesh::simpleRepr() const
6467 return MEDFileStructuredMesh::simpleRepr();
6471 * Returns a full textual description of \a this mesh.
6472 * \return std::string - the string holding the mesh description.
6474 std::string MEDFileCMesh::advancedRepr() const
6476 return simpleRepr();
6479 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6481 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6485 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6487 return new MEDFileCMesh;
6490 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6492 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6493 ret->deepCpyEquivalences(*this);
6494 if((const MEDCouplingCMesh*)_cmesh)
6495 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6496 ret->deepCpyAttributes();
6501 * Checks if \a this and another mesh are equal.
6502 * \param [in] other - the mesh to compare with.
6503 * \param [in] eps - a precision used to compare real values.
6504 * \param [in,out] what - the string returning description of unequal data.
6505 * \return bool - \c true if the meshes are equal, \c false, else.
6507 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6509 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6511 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6514 what="Mesh types differ ! This is cartesian and other is NOT !";
6517 clearNonDiscrAttributes();
6518 otherC->clearNonDiscrAttributes();
6519 const MEDCouplingCMesh *coo1=_cmesh;
6520 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6521 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6523 what="Mismatch of cartesian meshes ! One is defined and not other !";
6528 bool ret=coo1->isEqual(coo2,eps);
6531 what="cartesian meshes differ !";
6539 * Clears redundant attributes of incorporated data arrays.
6541 void MEDFileCMesh::clearNonDiscrAttributes() const
6543 MEDFileStructuredMesh::clearNonDiscrAttributes();
6544 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6547 MEDFileCMesh::MEDFileCMesh()
6551 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6554 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6556 catch(INTERP_KERNEL::Exception& e)
6561 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6563 MEDCoupling::MEDCouplingMeshType meshType;
6566 MEDCoupling::MEDCouplingAxisType axType;
6567 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6568 if(meshType!=CARTESIAN)
6570 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6571 throw INTERP_KERNEL::Exception(oss.str().c_str());
6573 MEDFileCMeshL2 loaderl2;
6574 loaderl2.loadAll(fid,mid,mName,dt,it);
6575 setAxisType(axType);
6576 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6579 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6583 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6584 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6586 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6588 synchronizeTinyInfoOnLeaves();
6592 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6594 synchronizeTinyInfoOnLeaves();
6599 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6600 * \param [in] m - the new MEDCouplingCMesh to refer to.
6601 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6604 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6606 dealWithTinyInfo(m);
6612 MEDFileMesh *MEDFileCMesh::cartesianize() const
6614 if(getAxisType()==AX_CART)
6617 return const_cast<MEDFileCMesh *>(this);
6621 const MEDCouplingCMesh *cmesh(getMesh());
6623 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6624 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6625 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6626 clmesh->setCoords(coords);
6627 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6628 ret->MEDFileStructuredMesh::operator=(*this);
6629 ret->setMesh(clmesh);
6630 ret->setAxisType(AX_CART);
6635 void MEDFileCMesh::writeLL(med_idt fid) const
6637 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6638 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6639 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6640 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6641 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6642 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6643 int spaceDim(_cmesh->getSpaceDimension());
6644 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6645 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6646 for(int i=0;i<spaceDim;i++)
6648 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6650 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6651 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
6652 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
6654 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6656 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6657 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6658 for(int i=0;i<spaceDim;i++)
6660 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6661 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6664 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6665 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6668 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6670 const MEDCouplingCMesh *cmesh=_cmesh;
6673 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6674 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6675 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6676 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6679 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6681 return new MEDFileCurveLinearMesh;
6684 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6686 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
6689 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6690 throw INTERP_KERNEL::Exception(oss.str().c_str());
6692 MEDFileUtilities::CheckFileForRead(fileName);
6693 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6695 MEDCoupling::MEDCouplingMeshType meshType;
6696 MEDCoupling::MEDCouplingAxisType dummy3;
6698 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
6699 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6702 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6704 MEDFileUtilities::CheckFileForRead(fileName);
6705 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6706 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6709 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6711 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6714 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6716 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6717 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6721 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6723 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6727 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6729 return new MEDFileCurveLinearMesh;
6732 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6734 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6735 ret->deepCpyEquivalences(*this);
6736 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6737 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6738 ret->deepCpyAttributes();
6742 int MEDFileCurveLinearMesh::getMeshDimension() const
6744 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6745 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6746 return _clmesh->getMeshDimension();
6749 std::string MEDFileCurveLinearMesh::simpleRepr() const
6751 return MEDFileStructuredMesh::simpleRepr();
6754 std::string MEDFileCurveLinearMesh::advancedRepr() const
6756 return simpleRepr();
6759 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6761 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6763 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6766 what="Mesh types differ ! This is curve linear and other is NOT !";
6769 clearNonDiscrAttributes();
6770 otherC->clearNonDiscrAttributes();
6771 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6772 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6773 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6775 what="Mismatch of curve linear meshes ! One is defined and not other !";
6780 bool ret=coo1->isEqual(coo2,eps);
6783 what="curve linear meshes differ !";
6790 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6792 MEDFileStructuredMesh::clearNonDiscrAttributes();
6793 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6796 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6798 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6801 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6802 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6803 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6804 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6807 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6809 synchronizeTinyInfoOnLeaves();
6813 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6815 dealWithTinyInfo(m);
6821 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6823 if(getAxisType()==AX_CART)
6826 return const_cast<MEDFileCurveLinearMesh *>(this);
6830 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6832 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6833 const DataArrayDouble *coords(mesh->getCoords());
6835 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6836 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6837 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6838 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6839 mesh2->setCoords(coordsCart);
6840 ret->setMesh(mesh2);
6841 ret->setAxisType(AX_CART);
6846 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6848 synchronizeTinyInfoOnLeaves();
6852 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6856 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6859 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6861 catch(INTERP_KERNEL::Exception& e)
6866 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6868 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6869 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6870 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6871 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6872 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6873 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6874 int spaceDim=_clmesh->getSpaceDimension();
6875 int meshDim=_clmesh->getMeshDimension();
6876 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6877 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6878 const DataArrayDouble *coords=_clmesh->getCoords();
6880 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6881 for(int i=0;i<spaceDim;i++)
6883 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6885 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6886 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
6887 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
6889 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6891 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6892 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6893 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6894 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6896 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6898 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6899 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6902 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6904 MEDCoupling::MEDCouplingMeshType meshType;
6907 MEDCoupling::MEDCouplingAxisType axType;
6908 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6909 setAxisType(axType);
6910 if(meshType!=CURVE_LINEAR)
6912 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6913 throw INTERP_KERNEL::Exception(oss.str().c_str());
6915 MEDFileCLMeshL2 loaderl2;
6916 loaderl2.loadAll(fid,mid,mName,dt,it);
6917 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6920 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6923 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6925 return new MEDFileMeshMultiTS;
6928 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6930 return new MEDFileMeshMultiTS(fileName);
6933 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6935 return new MEDFileMeshMultiTS(fileName,mName);
6938 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
6940 MCAuto<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6941 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6943 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6944 if((const MEDFileMesh *)*it)
6945 meshOneTs[i]=(*it)->deepCopy();
6946 ret->_mesh_one_ts=meshOneTs;
6950 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6952 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
6955 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6957 std::vector<const BigMemoryObject *> ret;
6958 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6959 ret.push_back((const MEDFileMesh *)*it);
6963 std::string MEDFileMeshMultiTS::getName() const
6965 if(_mesh_one_ts.empty())
6966 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6967 return _mesh_one_ts[0]->getName();
6970 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6972 std::string oldName(getName());
6973 std::vector< std::pair<std::string,std::string> > v(1);
6974 v[0].first=oldName; v[0].second=newMeshName;
6978 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6981 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6983 MEDFileMesh *cur(*it);
6985 ret=cur->changeNames(modifTab) || ret;
6990 void MEDFileMeshMultiTS::cartesianizeMe()
6992 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6994 MEDFileMesh *cur(*it);
6997 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7003 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7005 if(_mesh_one_ts.empty())
7006 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7007 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7010 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7013 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7014 _mesh_one_ts.resize(1);
7015 mesh1TimeStep->incrRef();
7016 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7017 _mesh_one_ts[0]=mesh1TimeStep;
7020 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7022 if ( MEDFileMesh* m = getOneTimeStep() )
7023 return m->getJoints();
7028 * \brief Set Joints that are common to all time-stamps
7030 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7032 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7034 (*it)->setJoints( joints );
7038 void MEDFileMeshMultiTS::write(med_idt fid) const
7040 MEDFileJoints *joints(getJoints());
7041 bool jointsWritten(false);
7043 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7045 if ( jointsWritten )
7046 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7048 jointsWritten = true;
7050 (*it)->copyOptionsFrom(*this);
7054 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7057 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
7059 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
7060 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
7061 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
7062 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
7066 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
7068 MEDFileJoints* joints = 0;
7069 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7071 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7072 joints = getOneTimeStep()->getJoints();
7075 _mesh_one_ts.clear(); //for the moment to be improved
7076 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
7079 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7083 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
7086 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
7089 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
7090 throw INTERP_KERNEL::Exception(oss.str().c_str());
7092 MEDFileUtilities::CheckFileForRead(fileName);
7093 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
7095 MEDCoupling::MEDCouplingMeshType meshType;
7097 MEDCoupling::MEDCouplingAxisType dummy3;
7098 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7099 loadFromFile(fileName,ms.front());
7101 catch(INTERP_KERNEL::Exception& e)
7106 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
7109 loadFromFile(fileName,mName);
7111 catch(INTERP_KERNEL::Exception& e)
7116 MEDFileMeshes *MEDFileMeshes::New()
7118 return new MEDFileMeshes;
7121 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7123 return new MEDFileMeshes(fileName);
7126 void MEDFileMeshes::write(med_idt fid) const
7128 checkConsistencyLight();
7129 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7131 (*it)->copyOptionsFrom(*this);
7136 void MEDFileMeshes::write(const std::string& fileName, int mode) const
7138 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
7139 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
7140 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
7141 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
7142 checkConsistencyLight();
7146 int MEDFileMeshes::getNumberOfMeshes() const
7148 return _meshes.size();
7151 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7153 return new MEDFileMeshesIterator(this);
7156 /** Return a borrowed reference (caller is not responsible) */
7157 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7159 if(i<0 || i>=(int)_meshes.size())
7161 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7162 throw INTERP_KERNEL::Exception(oss.str().c_str());
7164 return _meshes[i]->getOneTimeStep();
7167 /** Return a borrowed reference (caller is not responsible) */
7168 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7170 std::vector<std::string> ms=getMeshesNames();
7171 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7174 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7175 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7176 throw INTERP_KERNEL::Exception(oss.str().c_str());
7178 return getMeshAtPos((int)std::distance(ms.begin(),it));
7181 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7183 std::vector<std::string> ret(_meshes.size());
7185 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7187 const MEDFileMeshMultiTS *f=(*it);
7190 ret[i]=f->getName();
7194 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7195 throw INTERP_KERNEL::Exception(oss.str().c_str());
7201 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7204 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7206 MEDFileMeshMultiTS *cur(*it);
7208 ret=cur->changeNames(modifTab) || ret;
7213 void MEDFileMeshes::cartesianizeMe()
7215 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7217 MEDFileMeshMultiTS *cur(*it);
7219 cur->cartesianizeMe();
7223 void MEDFileMeshes::resize(int newSize)
7225 _meshes.resize(newSize);
7228 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7231 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7232 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7233 elt->setOneTimeStep(mesh);
7234 _meshes.push_back(elt);
7237 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7240 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7241 if(i>=(int)_meshes.size())
7242 _meshes.resize(i+1);
7243 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7244 elt->setOneTimeStep(mesh);
7248 void MEDFileMeshes::destroyMeshAtPos(int i)
7250 if(i<0 || i>=(int)_meshes.size())
7252 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7253 throw INTERP_KERNEL::Exception(oss.str().c_str());
7255 _meshes.erase(_meshes.begin()+i);
7258 void MEDFileMeshes::loadFromFile(const std::string& fileName)
7260 std::vector<std::string> ms(MEDCoupling::GetMeshNames(fileName));
7262 _meshes.resize(ms.size());
7263 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7264 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
7267 MEDFileMeshes::MEDFileMeshes()
7271 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
7274 loadFromFile(fileName);
7276 catch(INTERP_KERNEL::Exception& /*e*/)
7280 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7282 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7284 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7285 if((const MEDFileMeshMultiTS *)*it)
7286 meshes[i]=(*it)->deepCopy();
7287 MCAuto<MEDFileMeshes> ret=MEDFileMeshes::New();
7288 ret->_meshes=meshes;
7292 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7294 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7297 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7299 std::vector<const BigMemoryObject *> ret;
7300 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7301 ret.push_back((const MEDFileMeshMultiTS *)*it);
7305 std::string MEDFileMeshes::simpleRepr() const
7307 std::ostringstream oss;
7308 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7309 simpleReprWithoutHeader(oss);
7313 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7315 int nbOfMeshes=getNumberOfMeshes();
7316 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7317 std::vector<std::string> mns=getMeshesNames();
7318 for(int i=0;i<nbOfMeshes;i++)
7319 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7322 void MEDFileMeshes::checkConsistencyLight() const
7324 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7326 std::set<std::string> s;
7327 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7329 const MEDFileMeshMultiTS *elt=(*it);
7332 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7333 throw INTERP_KERNEL::Exception(oss.str().c_str());
7335 std::size_t sz=s.size();
7336 s.insert(std::string((*it)->getName()));
7339 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7340 throw INTERP_KERNEL::Exception(oss.str().c_str());
7345 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7350 _nb_iter=ms->getNumberOfMeshes();
7354 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7358 MEDFileMesh *MEDFileMeshesIterator::nextt()
7360 if(_iter_id<_nb_iter)
7362 MEDFileMeshes *ms(_ms);
7364 return ms->getMeshAtPos(_iter_id++);