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 "MEDLoaderNS.hxx"
27 #include "MEDFileSafeCaller.txx"
28 #include "MEDLoaderBase.hxx"
30 #include "MEDCouplingUMesh.hxx"
31 #include "MEDCouplingMappedExtrudedMesh.hxx"
33 #include "InterpKernelAutoPtr.hxx"
38 extern med_geometry_type typmai3[34];
40 using namespace MEDCoupling;
42 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
44 const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
46 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
50 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
52 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
53 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
55 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
56 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
57 ret+=(*it2).capacity();
59 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
60 ret+=(*it).first.capacity()+sizeof(int);
64 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
66 std::vector<const BigMemoryObject *> ret(1);
67 ret[0]=(const MEDFileEquivalences *)_equiv;
72 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
73 * file. The first mesh in the file is loaded.
74 * \param [in] fileName - the name of MED file to read.
75 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
76 * mesh using decrRef() as it is no more needed.
77 * \throw If the file is not readable.
78 * \throw If there is no meshes in the file.
79 * \throw If the mesh in the file is of a not supported type.
81 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
83 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
87 MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
89 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
92 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
93 throw INTERP_KERNEL::Exception(oss.str().c_str());
95 MEDCoupling::MEDCouplingMeshType meshType;
98 MEDCoupling::MEDCouplingAxisType dummy3;
99 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
100 MCAuto<MEDFileMesh> ret;
105 ret=MEDFileUMesh::New();
110 ret=MEDFileCMesh::New();
115 ret=MEDFileCurveLinearMesh::New();
120 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
121 throw INTERP_KERNEL::Exception(oss.str().c_str());
124 ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
129 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
130 * file. The mesh to load is specified by its name and numbers of a time step and an
132 * \param [in] fileName - the name of MED file to read.
133 * \param [in] mName - the name of the mesh to read.
134 * \param [in] dt - the number of a time step.
135 * \param [in] it - the number of an iteration.
136 * \param [in] joints - the sub-domain joints to use instead of those that can be read
137 * from the MED file. Usually this joints are those just read by another iteration
138 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
139 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
140 * mesh using decrRef() as it is no more needed.
141 * \throw If the file is not readable.
142 * \throw If there is no mesh with given attributes in the file.
143 * \throw If the mesh in the file is of a not supported type.
145 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
147 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
148 return New(fid,mName,dt,it,mrs,joints);
151 MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
153 MEDCoupling::MEDCouplingMeshType meshType;
156 MEDCoupling::MEDCouplingAxisType dummy3;
157 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
158 MCAuto<MEDFileMesh> ret;
163 ret=MEDFileUMesh::New();
168 ret=MEDFileCMesh::New();
173 ret=MEDFileCurveLinearMesh::New();
178 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
179 throw INTERP_KERNEL::Exception(oss.str().c_str());
182 ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
187 * Writes \a this mesh into an open MED file specified by its descriptor.
188 * \param [in] fid - the MED file descriptor.
189 * \throw If the mesh name is not set.
190 * \throw If the file is open for reading only.
191 * \throw If the writing mode == 1 and the same data is present in an existing file.
193 void MEDFileMesh::writeLL(med_idt fid) const
196 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
198 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
201 const MEDFileEquivalences *eqs(_equiv);
207 * Checks if \a this and another mesh are equal.
208 * \param [in] other - the mesh to compare with.
209 * \param [in] eps - a precision used to compare real values.
210 * \param [in,out] what - the string returning description of unequal data.
211 * \return bool - \c true if the meshes are equal, \c false, else.
213 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
215 if(_order!=other->_order)
217 what="Orders differ !";
220 if(_iteration!=other->_iteration)
222 what="Iterations differ !";
225 if(fabs(_time-other->_time)>eps)
227 what="Time values differ !";
230 if(_dt_unit!=other->_dt_unit)
232 what="Time units differ !";
235 if(_name!=other->_name)
237 what="Names differ !";
240 //univ_name has been ignored -> not a bug because it is a mutable attribute
241 if(_desc_name!=other->_desc_name)
243 what="Description names differ !";
246 if(!areGrpsEqual(other,what))
248 if(!areFamsEqual(other,what))
250 if(!areEquivalencesEqual(other,what))
255 void MEDFileMesh::setName(const std::string& name)
261 * Clears redundant attributes of incorporated data arrays.
263 void MEDFileMesh::clearNonDiscrAttributes() const
268 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
270 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
272 if((*it).first==_name)
282 * Copies data on groups and families from another mesh.
283 * \param [in] other - the mesh to copy the data from.
285 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
287 _groups=other._groups;
288 _families=other._families;
293 * This method clear all the groups in the map.
294 * So this method does not operate at all on arrays.
295 * So this method can lead to orphan families.
297 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
299 void MEDFileMesh::clearGrpMap()
305 * This method clear all the families in the map.
306 * So this method does not operate at all on arrays.
307 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
309 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
311 void MEDFileMesh::clearFamMap()
317 * This method clear all the families and groups in the map.
318 * So this method does not operate at all on arrays.
319 * As all groups and families entry will be removed after
320 * 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.
322 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
324 void MEDFileMesh::clearFamGrpMaps()
331 * Returns names of families constituting a group.
332 * \param [in] name - the name of the group of interest.
333 * \return std::vector<std::string> - a sequence of names of the families.
334 * \throw If the name of a nonexistent group is specified.
336 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
338 std::string oname(name);
339 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
340 if(it==_groups.end())
342 std::vector<std::string> grps=getGroupsNames();
343 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
344 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
345 throw INTERP_KERNEL::Exception(oss.str().c_str());
351 * Returns names of families constituting some groups.
352 * \param [in] grps - a sequence of names of groups of interest.
353 * \return std::vector<std::string> - a sequence of names of the families.
354 * \throw If a name of a nonexistent group is present in \a grps.
356 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
358 std::set<std::string> fams;
359 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
361 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
362 if(it2==_groups.end())
364 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
365 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
366 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
367 throw INTERP_KERNEL::Exception(oss.str().c_str());
369 fams.insert((*it2).second.begin(),(*it2).second.end());
371 std::vector<std::string> fams2(fams.begin(),fams.end());
376 * Returns ids of families constituting a group.
377 * \param [in] name - the name of the group of interest.
378 * \return std::vector<int> - sequence of ids of the families.
379 * \throw If the name of a nonexistent group is specified.
381 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
383 std::string oname(name);
384 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
385 std::vector<std::string> grps=getGroupsNames();
386 if(it==_groups.end())
388 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
389 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
390 throw INTERP_KERNEL::Exception(oss.str().c_str());
392 return getFamiliesIds((*it).second);
396 * Sets names of families constituting a group. If data on families of this group is
397 * already present, it is overwritten. Every family in \a fams is checked, and if a
398 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
399 * \param [in] name - the name of the group of interest.
400 * \param [in] fams - a sequence of names of families constituting the group.
402 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
404 std::string oname(name);
406 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
408 std::map<std::string,int>::iterator it2=_families.find(*it1);
409 if(it2==_families.end())
415 * Sets families constituting a group. The families are specified by their ids.
416 * If a family name is not found by its id, an exception is thrown.
417 * If several families have same id, the first one in lexical order is taken.
418 * \param [in] name - the name of the group of interest.
419 * \param [in] famIds - a sequence of ids of families constituting the group.
420 * \throw If a family name is not found by its id.
422 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
424 std::string oname(name);
425 std::vector<std::string> fams(famIds.size());
427 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
429 std::string name2=getFamilyNameGivenId(*it1);
436 * Returns names of groups including a given family.
437 * \param [in] name - the name of the family of interest.
438 * \return std::vector<std::string> - a sequence of names of groups including the family.
440 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
442 std::vector<std::string> ret;
443 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
445 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
448 ret.push_back((*it1).first);
456 * Adds an existing family to groups.
457 * \param [in] famName - a name of family to add to \a grps.
458 * \param [in] grps - a sequence of group names to add the family in.
459 * \throw If a family named \a famName not yet exists.
461 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
463 std::string fName(famName);
464 const std::map<std::string,int>::const_iterator it=_families.find(fName);
465 if(it==_families.end())
467 std::vector<std::string> fams=getFamiliesNames();
468 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
469 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
470 throw INTERP_KERNEL::Exception(oss.str().c_str());
472 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
474 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
475 if(it2!=_groups.end())
476 (*it2).second.push_back(fName);
479 std::vector<std::string> grps2(1,fName);
486 * Returns names of all groups of \a this mesh.
487 * \return std::vector<std::string> - a sequence of group names.
489 std::vector<std::string> MEDFileMesh::getGroupsNames() const
491 std::vector<std::string> ret(_groups.size());
493 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
499 * Returns names of all families of \a this mesh.
500 * \return std::vector<std::string> - a sequence of family names.
502 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
504 std::vector<std::string> ret(_families.size());
506 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
512 * Returns names of all families of \a this mesh but like they would be in file.
513 * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
514 * 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 !
515 * For your information internaly in memory such families are renamed to have a nicer API.
517 std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
519 std::vector<std::string> ret(getFamiliesNames());
520 MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
525 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
526 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
527 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
530 std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
532 std::vector<std::string> ret;
533 std::vector<std::string> allGrps(getGroupsNames());
534 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
536 std::vector<int> levs(getGrpNonEmptyLevelsExt((*it)));
537 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
544 * Returns all relative mesh levels (including nodes) where a given group is defined.
545 * \param [in] grp - the name of the group of interest.
546 * \return std::vector<int> - a sequence of the relative dimensions.
548 std::vector<int> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
550 std::vector<std::string> fams(getFamiliesOnGroup(grp));
551 return getFamsNonEmptyLevelsExt(fams);
555 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
556 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
557 * \param [in] grps - a sequence of names of the groups of interest.
558 * \return std::vector<int> - a sequence of the relative dimensions.
560 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
562 std::vector<std::string> fams(getFamiliesOnGroups(grps));
563 return getFamsNonEmptyLevels(fams);
567 * Returns all relative mesh levels (including nodes) where given groups are defined.
568 * \param [in] grps - a sequence of names of the groups of interest.
569 * \return std::vector<int> - a sequence of the relative dimensions.
571 std::vector<int> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
573 std::vector<std::string> fams(getFamiliesOnGroups(grps));
574 return getFamsNonEmptyLevelsExt(fams);
578 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
579 * To include nodes, call getGrpNonEmptyLevelsExt() method.
580 * \param [in] grp - the name of the group of interest.
581 * \return std::vector<int> - a sequence of the relative dimensions.
583 std::vector<int> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
585 std::vector<std::string> fams(getFamiliesOnGroup(grp));
586 return getFamsNonEmptyLevels(fams);
590 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
591 * To include nodes, call getFamNonEmptyLevelsExt() method.
592 * \param [in] fam - the name of the family of interest.
593 * \return std::vector<int> - a sequence of the relative dimensions.
595 std::vector<int> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
597 std::vector<std::string> fams(1,std::string(fam));
598 return getFamsNonEmptyLevels(fams);
602 * Returns all relative mesh levels (including nodes) where a given family is defined.
603 * \param [in] fam - the name of the family of interest.
604 * \return std::vector<int> - a sequence of the relative dimensions.
606 std::vector<int> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
608 std::vector<std::string> fams(1,std::string(fam));
609 return getFamsNonEmptyLevelsExt(fams);
612 std::string MEDFileMesh::GetMagicFamilyStr()
614 return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
618 * Changes a name of every family, included in one group only, to be same as the group name.
619 * \throw If there are families with equal names in \a this mesh.
621 void MEDFileMesh::assignFamilyNameWithGroupName()
623 std::map<std::string, std::vector<std::string> > groups(_groups);
624 std::map<std::string,int> newFams;
625 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
627 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
628 if(grps.size()==1 && groups[grps[0]].size()==1)
630 if(newFams.find(grps[0])!=newFams.end())
632 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
633 throw INTERP_KERNEL::Exception(oss.str().c_str());
635 newFams[grps[0]]=(*it).second;
636 std::vector<std::string>& grps2=groups[grps[0]];
637 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
642 if(newFams.find((*it).first)!=newFams.end())
644 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
645 throw INTERP_KERNEL::Exception(oss.str().c_str());
647 newFams[(*it).first]=(*it).second;
655 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
657 * \return the removed groups.
659 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
661 std::vector<std::string> ret;
662 std::map<std::string, std::vector<std::string> > newGrps;
663 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
665 if((*it).second.empty())
666 ret.push_back((*it).first);
668 newGrps[(*it).first]=(*it).second;
676 * Removes a group from \a this mesh.
677 * \param [in] name - the name of the group to remove.
678 * \throw If no group with such a \a name exists.
680 void MEDFileMesh::removeGroup(const std::string& name)
682 std::string oname(name);
683 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
684 std::vector<std::string> grps=getGroupsNames();
685 if(it==_groups.end())
687 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
688 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
689 throw INTERP_KERNEL::Exception(oss.str().c_str());
695 * Removes a family from \a this mesh.
696 * \param [in] name - the name of the family to remove.
697 * \throw If no family with such a \a name exists.
699 void MEDFileMesh::removeFamily(const std::string& name)
701 std::string oname(name);
702 std::map<std::string, int >::iterator it=_families.find(oname);
703 std::vector<std::string> fams=getFamiliesNames();
704 if(it==_families.end())
706 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
707 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
708 throw INTERP_KERNEL::Exception(oss.str().c_str());
711 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
713 std::vector<std::string>& v=(*it3).second;
714 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
721 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
722 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
723 * family field whatever its level. This method also suppresses the orphan families.
725 * \return - The list of removed groups names.
727 * \sa MEDFileMesh::removeOrphanFamilies.
729 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
731 removeOrphanFamilies();
732 return removeEmptyGroups();
736 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
737 * 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.
739 * \return - The list of removed families names.
740 * \sa MEDFileMesh::removeOrphanGroups.
742 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
744 MCAuto<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
745 std::vector<std::string> ret;
746 if(!((DataArrayInt*)allFamIdsInUse))
748 ret=getFamiliesNames();
749 _families.clear(); _groups.clear();
752 std::map<std::string,int> famMap;
753 std::map<std::string, std::vector<std::string> > grps(_groups);
754 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
756 if(allFamIdsInUse->presenceOfValue((*it).second))
757 famMap[(*it).first]=(*it).second;
760 ret.push_back((*it).first);
761 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
762 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
764 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
765 std::vector<std::string>& famv=(*it3).second;
766 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
772 { _families=famMap; _groups=grps; }
777 * 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
778 * this family is orphan or not.
780 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
782 void MEDFileMesh::removeFamiliesReferedByNoGroups()
784 std::map<std::string,int> fams;
785 std::set<std::string> sfams;
786 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
787 sfams.insert((*it).first);
788 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
789 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
791 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
792 if(*it!=DFT_FAM_NAME)
793 _families.erase(*it);
797 * 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
798 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
799 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
801 * \sa MEDFileMesh::removeOrphanFamilies
803 void MEDFileMesh::rearrangeFamilies()
805 checkOrphanFamilyZero();
806 removeFamiliesReferedByNoGroups();
808 std::vector<int> levels(getNonEmptyLevelsExt());
809 std::set<int> idsRefed;
810 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
811 idsRefed.insert((*it).second);
812 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
814 const DataArrayInt *fams(0);
817 fams=getFamilyFieldAtLevel(*it);
819 catch(INTERP_KERNEL::Exception& e) { }
822 std::vector<bool> v(fams->getNumberOfTuples(),false);
823 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
824 fams->switchOnTupleEqualTo(*pt,v);
825 MCAuto<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
826 if(!unfetchedIds->empty())
828 MCAuto<DataArrayInt> newFams(fams->deepCopy());
829 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
830 setFamilyFieldArr(*it,newFams);
833 removeOrphanFamilies();
837 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
839 void MEDFileMesh::checkOrphanFamilyZero() const
841 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
843 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
845 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
846 throw INTERP_KERNEL::Exception(oss.str().c_str());
852 * Renames a group in \a this mesh.
853 * \param [in] oldName - a current name of the group to rename.
854 * \param [in] newName - a new group name.
855 * \throw If no group named \a oldName exists in \a this mesh.
856 * \throw If a group named \a newName already exists.
858 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
860 std::string oname(oldName);
861 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
862 std::vector<std::string> grps=getGroupsNames();
863 if(it==_groups.end())
865 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
866 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
867 throw INTERP_KERNEL::Exception(oss.str().c_str());
869 std::string nname(newName);
870 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
871 if(it2!=_groups.end())
873 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
874 throw INTERP_KERNEL::Exception(oss.str().c_str());
876 std::vector<std::string> cpy=(*it).second;
878 _groups[newName]=cpy;
882 * Changes an id of a family in \a this mesh.
883 * This method calls changeFamilyIdArr().
884 * \param [in] oldId - a current id of the family.
885 * \param [in] newId - a new family id.
887 void MEDFileMesh::changeFamilyId(int oldId, int newId)
889 changeFamilyIdArr(oldId,newId);
890 std::map<std::string,int> fam2;
891 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
893 if((*it).second==oldId)
894 fam2[(*it).first]=newId;
896 fam2[(*it).first]=(*it).second;
902 * Renames a family in \a this mesh.
903 * \param [in] oldName - a current name of the family to rename.
904 * \param [in] newName - a new family name.
905 * \throw If no family named \a oldName exists in \a this mesh.
906 * \throw If a family named \a newName already exists.
908 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
910 std::string oname(oldName);
911 std::map<std::string, int >::iterator it=_families.find(oname);
912 std::vector<std::string> fams=getFamiliesNames();
913 if(it==_families.end())
915 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
916 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
917 throw INTERP_KERNEL::Exception(oss.str().c_str());
919 std::string nname(newName);
920 std::map<std::string, int >::iterator it2=_families.find(nname);
921 if(it2!=_families.end())
923 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
924 throw INTERP_KERNEL::Exception(oss.str().c_str());
926 int cpy=(*it).second;
928 _families[newName]=cpy;
929 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
931 std::vector<std::string>& v=(*it3).second;
932 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
939 * Checks if \a this and another mesh contains the same families.
940 * \param [in] other - the mesh to compare with \a this one.
941 * \param [in,out] what - an unused parameter.
942 * \return bool - \c true if number of families and their ids are the same in the two
943 * meshes. Families with the id == \c 0 are not considered.
945 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
947 if(_families==other->_families)
949 std::map<std::string,int> fam0;
950 std::map<std::string,int> fam1;
951 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
953 fam0[(*it).first]=(*it).second;
954 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
956 fam1[(*it).first]=(*it).second;
961 * Checks if \a this and another mesh contains the same groups.
962 * \param [in] other - the mesh to compare with \a this one.
963 * \param [in,out] what - a string describing a difference of groups of the two meshes
964 * in case if this method returns \c false.
965 * \return bool - \c true if number of groups and families constituting them are the
966 * same in the two meshes.
968 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
970 if(_groups==other->_groups)
973 std::size_t sz=_groups.size();
974 if(sz!=other->_groups.size())
976 what="Groups differ because not same number !\n";
981 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
982 for(std::size_t i=0;i<sz && ret;i++,it1++)
984 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
985 if(it2!=other->_groups.end())
987 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
988 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
994 what="A group in first mesh exists not in other !\n";
1000 std::ostringstream oss; oss << "Groups description differs :\n";
1001 oss << "First group description :\n";
1002 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
1004 oss << " Group \"" << (*it).first << "\" on following families :\n";
1005 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
1006 oss << " \"" << *it2 << "\n";
1008 oss << "Second group description :\n";
1009 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_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";
1021 * Checks if a group with a given name exists in \a this mesh.
1022 * \param [in] groupName - the group name.
1023 * \return bool - \c true the group \a groupName exists in \a this mesh.
1025 bool MEDFileMesh::existsGroup(const std::string& groupName) const
1027 std::string grpName(groupName);
1028 return _groups.find(grpName)!=_groups.end();
1032 * Checks if a family with a given id exists in \a this mesh.
1033 * \param [in] famId - the family id.
1034 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
1036 bool MEDFileMesh::existsFamily(int famId) const
1038 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1039 if((*it2).second==famId)
1045 * Checks if a family with a given name exists in \a this mesh.
1046 * \param [in] familyName - the family name.
1047 * \return bool - \c true the family \a familyName exists in \a this mesh.
1049 bool MEDFileMesh::existsFamily(const std::string& familyName) const
1051 std::string fname(familyName);
1052 return _families.find(fname)!=_families.end();
1056 * Sets an id of a family.
1057 * \param [in] familyName - the family name.
1058 * \param [in] id - a new id of the family.
1060 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
1062 std::string fname(familyName);
1063 _families[fname]=id;
1066 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
1068 std::string fname(familyName);
1069 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1070 if((*it).second==id)
1072 if((*it).first!=familyName)
1074 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
1075 throw INTERP_KERNEL::Exception(oss.str().c_str());
1078 _families[fname]=id;
1082 * Adds a family to \a this mesh.
1083 * \param [in] familyName - a name of the family.
1084 * \param [in] famId - an id of the family.
1085 * \throw If a family with the same name or id already exists in \a this mesh.
1087 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
1089 std::string fname(familyName);
1090 std::map<std::string,int>::const_iterator it=_families.find(fname);
1091 if(it==_families.end())
1093 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
1094 if((*it2).second==famId)
1096 std::ostringstream oss;
1097 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
1098 throw INTERP_KERNEL::Exception(oss.str().c_str());
1100 _families[fname]=famId;
1104 if((*it).second!=famId)
1106 std::ostringstream oss;
1107 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1108 throw INTERP_KERNEL::Exception(oss.str().c_str());
1114 * Creates a group including all mesh entities of given dimension.
1115 * \warning This method does \b not guarantee that the created group includes mesh
1116 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1117 * present in family fields of different dimensions. To assure this, call
1118 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1119 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1121 * \param [in] groupName - a name of the new group.
1122 * \throw If a group named \a groupName already exists.
1123 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1124 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1126 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1128 std::string grpName(groupName);
1129 std::vector<int> levs=getNonEmptyLevelsExt();
1130 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1132 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1133 oss << "Available relative ext levels are : ";
1134 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1135 throw INTERP_KERNEL::Exception(oss.str().c_str());
1137 if(existsGroup(groupName))
1139 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1140 oss << "Already existing groups are : ";
1141 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1142 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1143 throw INTERP_KERNEL::Exception(oss.str().c_str());
1145 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1147 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1148 MCAuto<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1149 std::vector<std::string> familiesOnWholeGroup;
1150 for(const int *it=famIds->begin();it!=famIds->end();it++)
1153 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1155 _groups[grpName]=familiesOnWholeGroup;
1159 * Ensures that given family ids do not present in family fields of dimensions different
1160 * than given ones. If a family id is present in the family fields of dimensions different
1161 * than the given ones, a new family is created and the whole data is updated accordingly.
1162 * \param [in] famIds - a sequence of family ids to check.
1163 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1164 * famIds should exclusively belong.
1165 * \return bool - \c true if no modification is done in \a this mesh by this method.
1167 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1169 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1170 std::vector<int> levs=getNonEmptyLevelsExt();
1171 std::set<int> levs2(levs.begin(),levs.end());
1172 std::vector<int> levsToTest;
1173 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1174 std::set<int> famIds2(famIds.begin(),famIds.end());
1177 if(!_families.empty())
1178 maxFamId=getMaxFamilyId()+1;
1179 std::vector<std::string> allFams=getFamiliesNames();
1180 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1182 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1185 MCAuto<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1186 std::vector<int> tmp;
1187 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1188 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1191 std::string famName=getFamilyNameGivenId(*it2);
1192 std::ostringstream oss; oss << "Family_" << maxFamId;
1193 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1194 addFamilyOnAllGroupsHaving(famName,zeName);
1195 _families[zeName]=maxFamId;
1196 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1205 * Adds a family to a given group in \a this mesh. If the group with a given name does
1206 * not exist, it is created.
1207 * \param [in] grpName - the name of the group to add the family in.
1208 * \param [in] famName - the name of the family to add to the group named \a grpName.
1209 * \throw If \a grpName or \a famName is an empty string.
1210 * \throw If no family named \a famName is present in \a this mesh.
1212 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1214 std::string grpn(grpName);
1215 std::string famn(famName);
1216 if(grpn.empty() || famn.empty())
1217 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1218 std::vector<std::string> fams=getFamiliesNames();
1219 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1221 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1222 oss << "Create this family or choose an existing one ! Existing fams are : ";
1223 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1224 throw INTERP_KERNEL::Exception(oss.str().c_str());
1226 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1227 if(it==_groups.end())
1229 _groups[grpn].push_back(famn);
1233 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1234 if(it2==(*it).second.end())
1235 (*it).second.push_back(famn);
1240 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1241 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1242 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1244 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1246 std::string famNameCpp(famName);
1247 std::string otherCpp(otherFamName);
1248 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1250 std::vector<std::string>& v=(*it).second;
1251 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1253 v.push_back(otherCpp);
1259 * \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).
1260 * \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)
1262 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1265 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1266 std::string grpName(ids->getName());
1268 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1269 ids->checkStrictlyMonotonic(true);
1270 famArr->incrRef(); MCAuto<DataArrayInt> famArrTmp(famArr);
1271 std::vector<std::string> grpsNames=getGroupsNames();
1272 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1274 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1275 throw INTERP_KERNEL::Exception(oss.str().c_str());
1277 std::list< MCAuto<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1278 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1279 MCAuto<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1280 MCAuto<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1281 std::vector<int> familyIds;
1282 std::vector< MCAuto<DataArrayInt> > idsPerfamiliyIds;
1283 int maxVal=getTheMaxAbsFamilyId()+1;
1284 std::map<std::string,int> families(_families);
1285 std::map<std::string, std::vector<std::string> > groups(_groups);
1286 std::vector<std::string> fams;
1287 bool created(false);
1288 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1290 MCAuto<DataArrayInt> ids2Tmp=famIds->findIdsEqual(*famId);
1291 MCAuto<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1292 MCAuto<DataArrayInt> ids1=famArr->findIdsEqual(*famId);
1293 MCAuto<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1296 bool isFamPresent=false;
1297 for(std::list< MCAuto<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1298 isFamPresent=(*itl)->presenceOfValue(*famId);
1300 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1303 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1304 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1305 fams.push_back(locFamName);
1306 if(existsFamily(*famId))
1308 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1309 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1312 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1316 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1317 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1318 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1319 if(existsFamily(*famId))
1321 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1322 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1327 for(std::size_t i=0;i<familyIds.size();i++)
1329 DataArrayInt *da=idsPerfamiliyIds[i];
1330 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1334 _groups[grpName]=fams;
1337 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1339 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1342 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1344 std::string fam(familyNameToChange);
1345 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1347 std::vector<std::string>& fams((*it).second);
1348 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1352 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1358 * Returns a name of the family having a given id or, if no such a family exists, creates
1359 * a new uniquely named family and returns its name.
1360 * \param [in] id - the id of the family whose name is required.
1361 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1362 * \return std::string - the name of the existing or the created family.
1363 * \throw If it is not possible to create a unique family name.
1365 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1367 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1371 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1372 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1373 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1374 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1376 * This method will throws an exception if it is not possible to create a unique family name.
1378 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1380 std::vector<std::string> famAlreadyExisting(families.size());
1382 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1384 if((*it).second!=id)
1386 famAlreadyExisting[ii]=(*it).first;
1395 std::ostringstream oss; oss << "Family_" << id;
1396 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1402 * Sets names and ids of all families in \a this mesh.
1403 * \param [in] info - a map of a family name to a family id.
1405 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1411 * Sets names of all groups and families constituting them in \a this mesh.
1412 * \param [in] info - a map of a group name to a vector of names of families
1413 * constituting the group.
1415 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1421 * Returns an id of the family having a given name.
1422 * \param [in] name - the name of the family of interest.
1423 * \return int - the id of the family of interest.
1424 * \throw If no family with such a \a name exists.
1426 int MEDFileMesh::getFamilyId(const std::string& name) const
1428 std::map<std::string, int>::const_iterator it=_families.find(name);
1429 if(it==_families.end())
1431 std::vector<std::string> fams(getFamiliesNames());
1432 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1433 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1434 throw INTERP_KERNEL::Exception(oss.str().c_str());
1436 return (*it).second;
1440 * Returns ids of the families having given names.
1441 * \param [in] fams - a sequence of the names of families of interest.
1442 * \return std::vector<int> - a sequence of the ids of families of interest.
1443 * \throw If \a fams contains a name of an inexistent family.
1445 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1447 std::vector<int> ret(fams.size());
1449 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1451 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1452 if(it2==_families.end())
1454 std::vector<std::string> fams2=getFamiliesNames();
1455 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1456 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1457 throw INTERP_KERNEL::Exception(oss.str().c_str());
1459 ret[i]=(*it2).second;
1465 * Returns a maximal abs(id) of families in \a this mesh.
1466 * \return int - the maximal norm of family id.
1467 * \throw If there are no families in \a this mesh.
1469 int MEDFileMesh::getMaxAbsFamilyId() const
1471 if(_families.empty())
1472 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1473 int ret=-std::numeric_limits<int>::max();
1474 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1476 ret=std::max(std::abs((*it).second),ret);
1482 * Returns a maximal id of families in \a this mesh.
1483 * \return int - the maximal family id.
1484 * \throw If there are no families in \a this mesh.
1486 int MEDFileMesh::getMaxFamilyId() const
1488 if(_families.empty())
1489 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1490 int ret=-std::numeric_limits<int>::max();
1491 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1493 ret=std::max((*it).second,ret);
1499 * Returns a minimal id of families in \a this mesh.
1500 * \return int - the minimal family id.
1501 * \throw If there are no families in \a this mesh.
1503 int MEDFileMesh::getMinFamilyId() const
1505 if(_families.empty())
1506 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1507 int ret=std::numeric_limits<int>::max();
1508 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1510 ret=std::min((*it).second,ret);
1516 * Returns a maximal id of families in \a this mesh. Not only named families are
1517 * considered but all family fields as well.
1518 * \return int - the maximal family id.
1520 int MEDFileMesh::getTheMaxAbsFamilyId() const
1522 int m1=-std::numeric_limits<int>::max();
1523 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1524 m1=std::max(std::abs((*it).second),m1);
1525 int m2=getMaxAbsFamilyIdInArrays();
1526 return std::max(m1,m2);
1530 * Returns a maximal id of families in \a this mesh. Not only named families are
1531 * considered but all family fields as well.
1532 * \return int - the maximal family id.
1534 int MEDFileMesh::getTheMaxFamilyId() const
1536 int m1=-std::numeric_limits<int>::max();
1537 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1538 m1=std::max((*it).second,m1);
1539 int m2=getMaxFamilyIdInArrays();
1540 return std::max(m1,m2);
1544 * Returns a minimal id of families in \a this mesh. Not only named families are
1545 * considered but all family fields as well.
1546 * \return int - the minimal family id.
1548 int MEDFileMesh::getTheMinFamilyId() const
1550 int m1=std::numeric_limits<int>::max();
1551 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1552 m1=std::min((*it).second,m1);
1553 int m2=getMinFamilyIdInArrays();
1554 return std::min(m1,m2);
1558 * This method only considers the maps. The contain of family array is ignored here.
1560 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1562 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1564 MCAuto<DataArrayInt> ret=DataArrayInt::New();
1566 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1567 v.insert((*it).second);
1568 ret->alloc((int)v.size(),1);
1569 std::copy(v.begin(),v.end(),ret->getPointer());
1574 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1576 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1578 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1580 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1581 MCAuto<DataArrayInt> ret;
1582 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1584 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1585 MCAuto<DataArrayInt> dv=arr->getDifferentValues();
1586 if((DataArrayInt *) ret)
1587 ret=dv->buildUnion(ret);
1595 * true is returned if no modification has been needed. false if family
1596 * renumbering has been needed.
1598 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1600 std::vector<int> levs=getNonEmptyLevelsExt();
1601 std::set<int> allFamIds;
1602 int maxId=getMaxFamilyId()+1;
1603 std::map<int,std::vector<int> > famIdsToRenum;
1604 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1606 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1609 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1611 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1613 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1615 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1618 if(famIdsToRenum.empty())
1620 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1621 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1623 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1624 int *famIdsToChange=fam->getPointer();
1625 std::map<int,int> ren;
1626 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1628 if(allIds->presenceOfValue(*it3))
1630 std::string famName=getFamilyNameGivenId(*it3);
1631 std::vector<std::string> grps=getGroupsOnFamily(famName);
1634 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1635 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1636 addFamilyOnGrp((*it4),newFam);
1639 MCAuto<DataArrayInt> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1640 for(const int *id=ids->begin();id!=ids->end();id++)
1641 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1647 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1648 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1649 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1650 * This method will throw an exception if a same family id is detected in different level.
1651 * \warning This policy is the opposite of those in MED file documentation ...
1653 void MEDFileMesh::normalizeFamIdsTrio()
1655 ensureDifferentFamIdsPerLevel();
1656 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1657 std::vector<int> levs=getNonEmptyLevelsExt();
1658 std::set<int> levsS(levs.begin(),levs.end());
1659 std::set<std::string> famsFetched;
1660 std::map<std::string,int> families;
1661 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1664 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1668 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1669 std::map<int,int> ren;
1670 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1672 int nbOfTuples=fam->getNumberOfTuples();
1673 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1674 for(int *w=start;w!=start+nbOfTuples;w++)
1676 for(const int *it=tmp->begin();it!=tmp->end();it++)
1678 if(allIds->presenceOfValue(*it))
1680 std::string famName=getFamilyNameGivenId(*it);
1681 families[famName]=ren[*it];
1682 famsFetched.insert(famName);
1687 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1690 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1694 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1695 std::map<int,int> ren;
1696 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1698 int nbOfTuples=fam->getNumberOfTuples();
1699 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1700 for(int *w=start;w!=start+nbOfTuples;w++)
1702 for(const int *it=tmp->begin();it!=tmp->end();it++)
1704 if(allIds->presenceOfValue(*it))
1706 std::string famName=getFamilyNameGivenId(*it);
1707 families[famName]=ren[*it];
1708 famsFetched.insert(famName);
1713 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1715 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1718 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1719 fam->fillWithZero();
1720 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1721 if(allIds->presenceOfValue(*it3))
1723 std::string famName=getFamilyNameGivenId(*it3);
1724 families[famName]=0;
1725 famsFetched.insert(famName);
1730 std::vector<std::string> allFams=getFamiliesNames();
1731 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1732 std::set<std::string> unFetchedIds;
1733 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1734 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1735 families[*it4]=_families[*it4];
1740 * This method normalizes fam id with the following policy.
1741 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1742 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1743 * This method will throw an exception if a same family id is detected in different level.
1745 void MEDFileMesh::normalizeFamIdsMEDFile()
1747 ensureDifferentFamIdsPerLevel();
1748 MCAuto<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1749 std::vector<int> levs=getNonEmptyLevelsExt();
1750 std::set<int> levsS(levs.begin(),levs.end());
1751 std::set<std::string> famsFetched;
1752 std::map<std::string,int> families;
1754 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1757 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1760 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1761 std::map<int,int> ren;
1762 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1764 int nbOfTuples=fam->getNumberOfTuples();
1765 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1766 for(int *w=start;w!=start+nbOfTuples;w++)
1768 for(const int *it=tmp->begin();it!=tmp->end();it++)
1770 if(allIds->presenceOfValue(*it))
1772 std::string famName=getFamilyNameGivenId(*it);
1773 families[famName]=ren[*it];
1774 famsFetched.insert(famName);
1780 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1782 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1785 MCAuto<DataArrayInt> tmp=fam->getDifferentValues();
1786 std::map<int,int> ren;
1787 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1789 int nbOfTuples=fam->getNumberOfTuples();
1790 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1791 for(int *w=start;w!=start+nbOfTuples;w++)
1793 for(const int *it=tmp->begin();it!=tmp->end();it++)
1795 if(allIds->presenceOfValue(*it))
1797 std::string famName=getFamilyNameGivenId(*it);
1798 families[famName]=ren[*it];
1799 famsFetched.insert(famName);
1805 std::vector<std::string> allFams=getFamiliesNames();
1806 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1807 std::set<std::string> unFetchedIds;
1808 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1809 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1810 families[*it4]=_families[*it4];
1815 * Returns a name of the family by its id. If there are several families having the given
1816 * id, the name first in lexical order is returned.
1817 * \param [in] id - the id of the family whose name is required.
1818 * \return std::string - the name of the found family.
1819 * \throw If no family with the given \a id exists.
1821 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1823 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1824 if((*it).second==id)
1826 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1827 throw INTERP_KERNEL::Exception(oss.str().c_str());
1831 * Returns a string describing \a this mesh. This description includes the mesh name and
1832 * the mesh description string.
1833 * \return std::string - the mesh information string.
1835 std::string MEDFileMesh::simpleRepr() const
1837 std::ostringstream oss;
1838 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1839 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1840 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1845 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1846 * an empty one is created.
1848 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1850 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1853 MCAuto<DataArrayInt> arr(DataArrayInt::New());
1854 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1855 arr->fillWithZero();
1856 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1857 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1861 * Returns ids of mesh entities contained in a given group of a given dimension.
1862 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1864 * \param [in] grp - the name of the group of interest.
1865 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1866 * returned instead of ids.
1867 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1868 * numbers, if available and required, of mesh entities of the group. The caller
1869 * is to delete this array using decrRef() as it is no more needed.
1870 * \throw If the name of a nonexistent group is specified.
1871 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1873 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1875 std::vector<std::string> tmp(1);
1877 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1883 * Returns ids of mesh entities contained in given groups of a given dimension.
1884 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1886 * \param [in] grps - the names of the groups of interest.
1887 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1888 * returned instead of ids.
1889 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1890 * numbers, if available and required, of mesh entities of the groups. The caller
1891 * is to delete this array using decrRef() as it is no more needed.
1892 * \throw If the name of a nonexistent group is present in \a grps.
1893 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1895 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1897 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1898 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1902 * Returns ids of mesh entities contained in a given family of a given dimension.
1903 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1905 * \param [in] fam - the name of the family of interest.
1906 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1907 * returned instead of ids.
1908 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1909 * numbers, if available and required, of mesh entities of the family. The caller
1910 * is to delete this array using decrRef() as it is no more needed.
1911 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1913 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1915 std::vector<std::string> tmp(1);
1917 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1923 * Returns ids of nodes contained in a given group.
1924 * \param [in] grp - the name of the group of interest.
1925 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1926 * returned instead of ids.
1927 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1928 * numbers, if available and required, of nodes of the group. The caller
1929 * is to delete this array using decrRef() as it is no more needed.
1930 * \throw If the name of a nonexistent group is specified.
1931 * \throw If the family field is missing for nodes.
1933 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1935 std::vector<std::string> tmp(1);
1937 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1943 * Returns ids of nodes contained in given groups.
1944 * \param [in] grps - the names of the groups of interest.
1945 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1946 * returned instead of ids.
1947 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1948 * numbers, if available and required, of nodes of the groups. The caller
1949 * is to delete this array using decrRef() as it is no more needed.
1950 * \throw If the name of a nonexistent group is present in \a grps.
1951 * \throw If the family field is missing for nodes.
1953 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1955 return getGroupsArr(1,grps,renum);
1959 * Returns ids of nodes contained in a given group.
1960 * \param [in] grp - the name of the group of interest.
1961 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1962 * returned instead of ids.
1963 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1964 * numbers, if available and required, of nodes of the group. The caller
1965 * is to delete this array using decrRef() as it is no more needed.
1966 * \throw If the name of a nonexistent group is specified.
1967 * \throw If the family field is missing for nodes.
1969 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1971 std::vector<std::string> tmp(1);
1973 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1979 * Returns ids of nodes contained in given families.
1980 * \param [in] fams - the names of the families of interest.
1981 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1982 * returned instead of ids.
1983 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1984 * numbers, if available and required, of nodes of the families. The caller
1985 * is to delete this array using decrRef() as it is no more needed.
1986 * \throw If the family field is missing for nodes.
1988 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1990 return getFamiliesArr(1,fams,renum);
1994 * Adds groups of given dimension and creates corresponding families and family fields
1995 * given ids of mesh entities of each group.
1996 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1997 * \param [in] grps - a sequence of arrays of ids each describing a group.
1998 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
2000 * \throw If names of some groups in \a grps are equal.
2001 * \throw If \a grps includes a group with an empty name.
2002 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
2003 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2005 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
2009 std::set<std::string> grpsName;
2010 std::vector<std::string> grpsName2(grps.size());
2013 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
2015 grpsName.insert((*it)->getName());
2016 grpsName2[i]=(*it)->getName();
2018 if(grpsName.size()!=grps.size())
2019 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
2020 if(grpsName.find(std::string(""))!=grpsName.end())
2021 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
2022 int sz=getSizeAtLevel(meshDimRelToMaxExt);
2023 MCAuto<DataArrayInt> fam;
2024 std::vector< std::vector<int> > fidsOfGroups;
2027 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
2031 std::vector< MCAuto<DataArrayInt> > grps2(grps.size());
2032 for(unsigned int ii=0;ii<grps.size();ii++)
2034 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
2035 grps2[ii]->setName(grps[ii]->getName());
2037 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
2038 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
2041 if(!_families.empty())
2042 offset=getMaxAbsFamilyId()+1;
2043 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
2044 MCAuto<DataArrayInt> ids=fam->getDifferentValues();
2045 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
2046 setFamilyFieldArr(meshDimRelToMaxExt,fam);
2050 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
2051 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
2052 * For the moment, the two last input parameters are not taken into account.
2054 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
2056 std::map<int,std::string> famInv;
2057 for(const int *it=famIds->begin();it!=famIds->end();it++)
2059 std::ostringstream oss;
2060 oss << "Family_" << (*it);
2061 _families[oss.str()]=(*it);
2062 famInv[*it]=oss.str();
2065 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
2067 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
2069 _groups[grpNames[i]].push_back(famInv[*it2]);
2074 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
2076 std::vector<int> levs(getNonEmptyLevels());
2077 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
2078 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2080 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
2081 ret.insert(ret.end(),elts.begin(),elts.end());
2087 * \sa getAllDistributionOfTypes
2089 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
2091 MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
2092 return mLev->getDistributionOfTypes();
2095 void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2097 loadLL(fid,mName,dt,it,mrs);
2098 loadJointsFromFile(fid);
2099 loadEquivalences(fid);
2102 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
2104 famArr->applyLin(offset>0?1:-1,offset,0);
2105 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
2108 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
2109 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2114 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2115 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2116 * If this method fails to find such a name it will throw an exception.
2118 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2121 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2124 std::size_t len=nameTry.length();
2125 for(std::size_t ii=1;ii<len;ii++)
2127 std::string tmp=nameTry.substr(ii,len-ii);
2128 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2134 for(std::size_t i=1;i<30;i++)
2136 std::string tmp1(nameTry.at(0),i);
2138 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2144 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2146 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2148 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2151 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2153 std::size_t nbOfChunks=code.size()/3;
2154 if(code.size()%3!=0)
2155 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2157 for(std::size_t i=0;i<nbOfChunks;i++)
2166 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2167 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2168 * If _name is not empty and that 'm' has the same name nothing is done.
2169 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2171 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2174 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2179 std::string name(m->getName());
2184 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2185 oss << name << "' ! Names must match !";
2186 throw INTERP_KERNEL::Exception(oss.str().c_str());
2190 if(_desc_name.empty())
2191 _desc_name=m->getDescription();
2194 std::string name(m->getDescription());
2197 if(_desc_name!=name)
2199 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2200 oss << name << "' ! Names must match !";
2201 throw INTERP_KERNEL::Exception(oss.str().c_str());
2207 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2209 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2210 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2212 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2213 oss << " - Groups lying on this family : ";
2214 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2215 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2216 oss << std::endl << std::endl;
2221 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2222 * file. The mesh to load is specified by its name and numbers of a time step and an
2224 * \param [in] fileName - the name of MED file to read.
2225 * \param [in] mName - the name of the mesh to read.
2226 * \param [in] dt - the number of a time step.
2227 * \param [in] it - the number of an iteration.
2228 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2229 * mesh using decrRef() as it is no more needed.
2230 * \throw If the file is not readable.
2231 * \throw If there is no mesh with given attributes in the file.
2232 * \throw If the mesh in the file is not an unstructured one.
2234 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2236 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2237 return New(fid,mName,dt,it,mrs);
2240 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2242 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2246 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2247 * file. The first mesh in the file is loaded.
2248 * \param [in] fileName - the name of MED file to read.
2249 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2250 * mesh using decrRef() as it is no more needed.
2251 * \throw If the file is not readable.
2252 * \throw If there is no meshes in the file.
2253 * \throw If the mesh in the file is not an unstructured one.
2255 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2257 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
2258 return New(fid,mrs);
2262 T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
2264 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
2267 std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
2268 throw INTERP_KERNEL::Exception(oss.str().c_str());
2271 MEDCoupling::MEDCouplingMeshType meshType;
2273 MEDCoupling::MEDCouplingAxisType dummy3;
2274 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
2275 return T::New(fid,ms.front(),dt,it,mrs);
2278 MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
2280 return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
2284 * \b WARNING this implementation is dependant from MEDCouplingMappedExtrudedMesh::buildUnstructured !
2285 * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
2287 MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
2290 throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
2291 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2292 MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
2293 MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
2295 m2D->setCoords(m3D->getCoords());
2296 ret->setMeshAtLevel(0,m3D);
2297 ret->setMeshAtLevel(-1,m2D);
2298 ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<int>::max()-mem->get2DCellIdForExtrusion());
2303 * Returns an empty instance of MEDFileUMesh.
2304 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2305 * mesh using decrRef() as it is no more needed.
2307 MEDFileUMesh *MEDFileUMesh::New()
2309 return new MEDFileUMesh;
2313 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2314 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2315 * \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.
2316 * 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
2317 * at most the memory consumtion.
2319 * \param [in] fileName - the name of the file.
2320 * \param [in] mName - the name of the mesh to be read.
2321 * \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.
2322 * \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.
2323 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2324 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2325 * \param [in] mrs - the request for what to be loaded.
2326 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2328 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)
2330 MEDFileUtilities::CheckFileForRead(fileName);
2331 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2332 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2336 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2337 * This method is \b NOT wrapped into python.
2339 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)
2341 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
2342 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2346 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2348 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2349 ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>));
2353 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2355 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2356 ret.push_back((const DataArrayDouble*)_coords);
2357 ret.push_back((const DataArrayInt *)_fam_coords);
2358 ret.push_back((const DataArrayInt *)_num_coords);
2359 ret.push_back((const DataArrayInt *)_rev_num_coords);
2360 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2361 ret.push_back((const PartDefinition *)_part_coords);
2362 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2363 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2367 MEDFileUMesh *MEDFileUMesh::shallowCpy() const
2369 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2373 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2375 return new MEDFileUMesh;
2378 MEDFileUMesh *MEDFileUMesh::deepCopy() const
2380 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
2381 ret->deepCpyEquivalences(*this);
2382 if((const DataArrayDouble*)_coords)
2383 ret->_coords=_coords->deepCopy();
2384 if((const DataArrayInt*)_fam_coords)
2385 ret->_fam_coords=_fam_coords->deepCopy();
2386 if((const DataArrayInt*)_num_coords)
2387 ret->_num_coords=_num_coords->deepCopy();
2388 if((const DataArrayInt*)_rev_num_coords)
2389 ret->_rev_num_coords=_rev_num_coords->deepCopy();
2390 if((const DataArrayAsciiChar*)_name_coords)
2391 ret->_name_coords=_name_coords->deepCopy();
2393 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2395 if((const MEDFileUMeshSplitL1 *)(*it))
2396 ret->_ms[i]=(*it)->deepCopy(ret->_coords);
2398 if((const PartDefinition*)_part_coords)
2399 ret->_part_coords=_part_coords->deepCopy();
2404 * Checks if \a this and another mesh are equal.
2405 * \param [in] other - the mesh to compare with.
2406 * \param [in] eps - a precision used to compare real values.
2407 * \param [in,out] what - the string returning description of unequal data.
2408 * \return bool - \c true if the meshes are equal, \c false, else.
2410 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2412 if(!MEDFileMesh::isEqual(other,eps,what))
2414 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2417 what="Mesh types differ ! This is unstructured and other is NOT !";
2420 clearNonDiscrAttributes();
2421 otherC->clearNonDiscrAttributes();
2422 const DataArrayDouble *coo1=_coords;
2423 const DataArrayDouble *coo2=otherC->_coords;
2424 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2426 what="Mismatch of coordinates ! One is defined and not other !";
2431 bool ret=coo1->isEqual(*coo2,eps);
2434 what="Coords differ !";
2438 const DataArrayInt *famc1=_fam_coords;
2439 const DataArrayInt *famc2=otherC->_fam_coords;
2440 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2442 what="Mismatch of families arr on nodes ! One is defined and not other !";
2447 bool ret=famc1->isEqual(*famc2);
2450 what="Families arr on node differ !";
2454 const DataArrayInt *numc1=_num_coords;
2455 const DataArrayInt *numc2=otherC->_num_coords;
2456 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2458 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2463 bool ret=numc1->isEqual(*numc2);
2466 what="Numbering arr on node differ !";
2470 const DataArrayAsciiChar *namec1=_name_coords;
2471 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2472 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2474 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2479 bool ret=namec1->isEqual(*namec2);
2482 what="Names arr on node differ !";
2486 if(_ms.size()!=otherC->_ms.size())
2488 what="Number of levels differs !";
2491 std::size_t sz=_ms.size();
2492 for(std::size_t i=0;i<sz;i++)
2494 const MEDFileUMeshSplitL1 *s1=_ms[i];
2495 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2496 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2498 what="Mismatch of presence of sub levels !";
2503 bool ret=s1->isEqual(s2,eps,what);
2508 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2511 if((!pd0 && pd1) || (pd0 && !pd1))
2513 what=std::string("node part def is defined only for one among this or other !");
2516 return pd0->isEqual(pd1,what);
2520 * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
2521 * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
2522 * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
2523 * \throw if internal family array is inconsistent
2524 * \sa checkSMESHConsistency()
2526 void MEDFileUMesh::checkConsistency() const
2528 if(!_coords || !_coords->isAllocated())
2531 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
2533 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
2534 if (!_num_coords || !_rev_num_coords)
2535 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
2539 int nbCoo = _coords->getNumberOfTuples();
2541 _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
2544 _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
2546 int maxValue=_num_coords->getMaxValue(pos);
2547 if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
2548 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
2550 if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
2551 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
2552 if (_num_coords && !_num_coords->hasUniqueValues())
2553 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
2555 _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
2556 // Now sub part check:
2557 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2558 it != _ms.end(); it++)
2559 (*it)->checkConsistency();
2564 * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
2565 * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
2566 * entities as it likes), or non overlapping between all sub-levels.
2567 * \throw if the condition above is not respected
2569 void MEDFileUMesh::checkSMESHConsistency() const
2572 // For all sub-levels, numbering is either always null or with void intersection:
2575 std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
2576 std::vector< const DataArrayInt * > v;
2577 bool voidOrNot = ((*it)->_num == 0);
2578 for (it++; it != _ms.end(); it++)
2579 if( ((*it)->_num == 0) != voidOrNot )
2580 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
2581 else if (!voidOrNot)
2582 v.push_back((*it)->_num);
2585 // don't forget the 1st one:
2586 v.push_back(_ms[0]->_num);
2587 MCAuto<DataArrayInt> inter = DataArrayInt::BuildIntersection(v);
2588 if (inter->getNumberOfTuples())
2589 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
2595 * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
2596 * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
2598 void MEDFileUMesh::clearNodeAndCellNumbers()
2601 _rev_num_coords = 0;
2602 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
2603 it != _ms.end(); it++)
2606 (*it)->_rev_num = 0;
2611 * Clears redundant attributes of incorporated data arrays.
2613 void MEDFileUMesh::clearNonDiscrAttributes() const
2615 MEDFileMesh::clearNonDiscrAttributes();
2616 const DataArrayDouble *coo1=_coords;
2618 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2619 const DataArrayInt *famc1=_fam_coords;
2621 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2622 const DataArrayInt *numc1=_num_coords;
2624 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2625 const DataArrayAsciiChar *namc1=_name_coords;
2627 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2628 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2630 const MEDFileUMeshSplitL1 *tmp=(*it);
2632 tmp->clearNonDiscrAttributes();
2636 void MEDFileUMesh::setName(const std::string& name)
2638 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2639 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2640 (*it)->setName(name);
2641 MEDFileMesh::setName(name);
2644 MEDFileUMesh::MEDFileUMesh()
2648 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2651 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
2653 catch(INTERP_KERNEL::Exception& e)
2659 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2660 * See MEDFileUMesh::LoadPartOf for detailed description.
2664 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)
2666 MEDFileUMeshL2 loaderl2;
2667 MEDCoupling::MEDCouplingMeshType meshType;
2670 MEDCoupling::MEDCouplingAxisType dummy3;
2671 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
2672 if(meshType!=UNSTRUCTURED)
2674 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2675 throw INTERP_KERNEL::Exception(oss.str().c_str());
2677 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2678 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2682 * \brief Write joints in a file
2684 void MEDFileMesh::writeJoints(med_idt fid) const
2686 if ( _joints.isNotNull() )
2687 _joints->writeLL(fid);
2691 * \brief Load joints in a file or use provided ones
2693 //================================================================================
2695 * \brief Load joints in a file or use provided ones
2696 * \param [in] fid - MED file descriptor
2697 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2698 * Usually this joints are those just read by another iteration
2699 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2701 //================================================================================
2703 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2705 if ( toUseInstedOfReading )
2706 setJoints( toUseInstedOfReading );
2708 _joints = MEDFileJoints::New( fid, _name );
2711 void MEDFileMesh::loadEquivalences(med_idt fid)
2713 int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
2715 _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
2718 void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
2720 const MEDFileEquivalences *equiv(other._equiv);
2722 _equiv=equiv->deepCopy(this);
2725 bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
2727 const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
2728 if(!thisEq && !otherEq)
2730 if(thisEq && otherEq)
2731 return thisEq->isEqual(otherEq,what);
2734 what+="Equivalence differs : defined in this and not in other (or reversely) !";
2739 void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
2741 const MEDFileEquivalences *equiv(_equiv);
2744 oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
2745 _equiv->getRepr(oss);
2748 void MEDFileMesh::checkCartesian() const
2750 if(getAxisType()!=AX_CART)
2752 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()) << ").";
2753 oss << std::endl << "To perform operation you have two possiblities :" << std::endl;
2754 oss << " - call setAxisType(AX_CART)" << std::endl;
2755 oss << " - call cartesianize()";
2756 throw INTERP_KERNEL::Exception(oss.str().c_str());
2761 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2763 int MEDFileMesh::getNumberOfJoints() const
2765 return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
2769 * \brief Return joints with all adjacent mesh domains
2771 MEDFileJoints * MEDFileMesh::getJoints() const
2773 return const_cast<MEDFileJoints*>(& (*_joints));
2776 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2778 if ( joints != _joints )
2787 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2789 * \sa loadPartUMeshFromFile
2791 void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2793 MEDFileUMeshL2 loaderl2;
2794 MEDCoupling::MEDCouplingMeshType meshType;
2797 MEDCoupling::MEDCouplingAxisType axType;
2798 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
2799 setAxisType(axType);
2800 if(meshType!=UNSTRUCTURED)
2802 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2803 throw INTERP_KERNEL::Exception(oss.str().c_str());
2805 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2806 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2809 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2811 int lev=loaderl2.getNumberOfLevels();
2813 for(int i=0;i<lev;i++)
2815 if(!loaderl2.emptyLev(i))
2816 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2820 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2822 setName(loaderl2.getName());
2823 setDescription(loaderl2.getDescription());
2824 setUnivName(loaderl2.getUnivName());
2825 setIteration(loaderl2.getIteration());
2826 setOrder(loaderl2.getOrder());
2827 setTimeValue(loaderl2.getTime());
2828 setTimeUnit(loaderl2.getTimeUnit());
2829 _coords=loaderl2.getCoords();
2830 if(!mrs || mrs->isNodeFamilyFieldReading())
2831 _fam_coords=loaderl2.getCoordsFamily();
2832 if(!mrs || mrs->isNodeNumFieldReading())
2833 _num_coords=loaderl2.getCoordsNum();
2834 if(!mrs || mrs->isNodeNameFieldReading())
2835 _name_coords=loaderl2.getCoordsName();
2836 _part_coords=loaderl2.getPartDefOfCoo();
2840 MEDFileUMesh::~MEDFileUMesh()
2844 void MEDFileUMesh::writeMeshLL(med_idt fid) const
2846 const DataArrayDouble *coo=_coords;
2847 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2848 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2849 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2850 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2851 int spaceDim=coo?coo->getNumberOfComponents():0;
2854 mdim=getMeshDimension();
2855 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2856 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2857 for(int i=0;i<spaceDim;i++)
2859 std::string info=coo->getInfoOnComponent(i);
2861 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2862 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
2863 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
2865 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
2867 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2868 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2869 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2870 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2871 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2872 (*it)->write(fid,meshName,mdim);
2873 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2877 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2878 * \return std::vector<int> - a sequence of the relative dimensions.
2880 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2882 std::vector<int> ret;
2884 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2885 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2892 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2893 * \return std::vector<int> - a sequence of the relative dimensions.
2895 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2897 std::vector<int> ret0=getNonEmptyLevels();
2898 if((const DataArrayDouble *) _coords)
2900 std::vector<int> ret(ret0.size()+1);
2902 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2908 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2910 std::vector<int> ret;
2911 const DataArrayInt *famCoo(_fam_coords);
2915 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2917 const MEDFileUMeshSplitL1 *cur(*it);
2919 if(cur->getFamilyField())
2925 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2927 std::vector<int> ret;
2928 const DataArrayInt *numCoo(_num_coords);
2932 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2934 const MEDFileUMeshSplitL1 *cur(*it);
2936 if(cur->getNumberField())
2942 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2944 std::vector<int> ret;
2945 const DataArrayAsciiChar *nameCoo(_name_coords);
2949 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2951 const MEDFileUMeshSplitL1 *cur(*it);
2953 if(cur->getNameField())
2960 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2961 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2962 * \param [in] fams - the name of the family of interest.
2963 * \return std::vector<int> - a sequence of the relative dimensions.
2965 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2967 std::vector<int> ret;
2968 std::vector<int> levs(getNonEmptyLevels());
2969 std::vector<int> famIds(getFamiliesIds(fams));
2970 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2971 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2977 * Returns all relative mesh levels (including nodes) where given families are defined.
2978 * \param [in] fams - the names of the families of interest.
2979 * \return std::vector<int> - a sequence of the relative dimensions.
2981 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2983 std::vector<int> ret0(getFamsNonEmptyLevels(fams));
2984 const DataArrayInt *famCoords(_fam_coords);
2987 std::vector<int> famIds(getFamiliesIds(fams));
2988 if(famCoords->presenceOfValue(famIds))
2990 std::vector<int> ret(ret0.size()+1);
2992 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2999 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
3001 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3002 if((const DataArrayInt *)_fam_coords)
3004 int val=_fam_coords->getMaxValue(tmp);
3005 ret=std::max(ret,std::abs(val));
3007 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3009 if((const MEDFileUMeshSplitL1 *)(*it))
3011 const DataArrayInt *da=(*it)->getFamilyField();
3014 int val=da->getMaxValue(tmp);
3015 ret=std::max(ret,std::abs(val));
3022 int MEDFileUMesh::getMaxFamilyIdInArrays() const
3024 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3025 if((const DataArrayInt *)_fam_coords)
3027 int val=_fam_coords->getMaxValue(tmp);
3028 ret=std::max(ret,val);
3030 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3032 if((const MEDFileUMeshSplitL1 *)(*it))
3034 const DataArrayInt *da=(*it)->getFamilyField();
3037 int val=da->getMaxValue(tmp);
3038 ret=std::max(ret,val);
3045 int MEDFileUMesh::getMinFamilyIdInArrays() const
3047 int ret=std::numeric_limits<int>::max(),tmp=-1;
3048 if((const DataArrayInt *)_fam_coords)
3050 int val=_fam_coords->getMinValue(tmp);
3051 ret=std::min(ret,val);
3053 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3055 if((const MEDFileUMeshSplitL1 *)(*it))
3057 const DataArrayInt *da=(*it)->getFamilyField();
3060 int val=da->getMinValue(tmp);
3061 ret=std::min(ret,val);
3069 * Returns the dimension on cells in \a this mesh.
3070 * \return int - the mesh dimension.
3071 * \throw If there are no cells in this mesh.
3073 int MEDFileUMesh::getMeshDimension() const
3076 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
3077 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
3078 return (*it)->getMeshDimension()+lev;
3079 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
3083 * Returns the space dimension of \a this mesh that is equal to number of components in
3084 * the node coordinates array.
3085 * \return int - the space dimension of \a this mesh.
3086 * \throw If the node coordinates array is not available.
3088 int MEDFileUMesh::getSpaceDimension() const
3090 const DataArrayDouble *coo=_coords;
3092 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
3093 return coo->getNumberOfComponents();
3097 * Returns a string describing \a this mesh.
3098 * \return std::string - the mesh information string.
3100 std::string MEDFileUMesh::simpleRepr() const
3102 std::ostringstream oss;
3103 oss << MEDFileMesh::simpleRepr();
3104 const DataArrayDouble *coo=_coords;
3105 oss << "- The dimension of the space is ";
3106 static const char MSG1[]= "*** NO COORDS SET ***";
3107 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
3109 oss << _coords->getNumberOfComponents() << std::endl;
3111 oss << MSG1 << std::endl;
3112 oss << "- Type of the mesh : UNSTRUCTURED\n";
3113 oss << "- Number of nodes : ";
3115 oss << _coords->getNumberOfTuples() << std::endl;
3117 oss << MSG1 << std::endl;
3118 std::size_t nbOfLev=_ms.size();
3119 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
3120 for(std::size_t i=0;i<nbOfLev;i++)
3122 const MEDFileUMeshSplitL1 *lev=_ms[i];
3123 oss << " - Level #" << -((int) i) << " has dimension : ";
3126 oss << lev->getMeshDimension() << std::endl;
3127 lev->simpleRepr(oss);
3130 oss << MSG2 << std::endl;
3132 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
3135 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
3136 oss << "- Names of coordinates :" << std::endl;
3137 std::vector<std::string> vars=coo->getVarsOnComponent();
3138 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
3139 oss << std::endl << "- Units of coordinates : " << std::endl;
3140 std::vector<std::string> units=coo->getUnitsOnComponent();
3141 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
3143 oss << std::endl << std::endl;
3145 getEquivalencesRepr(oss);
3150 * Returns a full textual description of \a this mesh.
3151 * \return std::string - the string holding the mesh description.
3153 std::string MEDFileUMesh::advancedRepr() const
3155 return simpleRepr();
3159 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3160 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3161 * \return int - the number of entities.
3162 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3164 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
3166 if(meshDimRelToMaxExt==1)
3168 if(!((const DataArrayDouble *)_coords))
3169 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
3170 return _coords->getNumberOfTuples();
3172 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
3176 * Returns the family field for mesh entities of a given dimension.
3177 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3178 * \return const DataArrayInt * - the family field. It is an array of ids of families
3179 * each mesh entity belongs to. It can be \c NULL.
3181 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
3183 if(meshDimRelToMaxExt==1)
3185 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3186 return l1->getFamilyField();
3189 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
3191 if(meshDimRelToMaxExt==1)
3193 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3194 return l1->getFamilyField();
3198 * Returns the optional numbers of mesh entities of a given dimension.
3199 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3200 * \return const DataArrayInt * - the array of the entity numbers.
3201 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3203 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3205 if(meshDimRelToMaxExt==1)
3207 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3208 return l1->getNumberField();
3211 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3213 if(meshDimRelToMaxExt==1)
3214 return _name_coords;
3215 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3216 return l1->getNameField();
3220 * 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).
3222 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3223 * \param [in] gt - The input geometric type for which the part definition is requested.
3224 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3226 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3228 if(meshDimRelToMaxExt==1)
3229 return _part_coords;
3230 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3231 return l1->getPartDef(gt);
3234 int MEDFileUMesh::getNumberOfNodes() const
3236 const DataArrayDouble *coo(_coords);
3238 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3239 return coo->getNumberOfTuples();
3242 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3244 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3245 return l1->getNumberOfCells();
3248 bool MEDFileUMesh::hasImplicitPart() const
3253 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3255 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3258 void MEDFileUMesh::releaseImplicitPartIfAny() const
3262 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3264 std::size_t sz(st.getNumberOfItems());
3265 for(std::size_t i=0;i<sz;i++)
3267 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3268 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3269 if(st[i].getPflName().empty())
3270 m->computeNodeIdsAlg(nodesFetched);
3273 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3274 MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3275 m2->computeNodeIdsAlg(nodesFetched);
3280 MEDFileMesh *MEDFileUMesh::cartesianize() const
3282 if(getAxisType()==AX_CART)
3285 return const_cast<MEDFileUMesh *>(this);
3289 MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
3290 const DataArrayDouble *coords(_coords);
3292 throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
3293 MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
3294 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
3295 if((const MEDFileUMeshSplitL1 *)(*it))
3296 *it=(*it)->shallowCpyUsingCoords(coordsCart);
3297 ret->_coords=coordsCart;
3298 ret->setAxisType(AX_CART);
3304 * Returns the optional numbers of mesh entities of a given dimension transformed using
3305 * DataArrayInt::invertArrayN2O2O2N().
3306 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3307 * \return const DataArrayInt * - the array of the entity numbers transformed using
3308 * DataArrayInt::invertArrayN2O2O2N().
3309 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3311 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3313 if(meshDimRelToMaxExt==1)
3315 if(!((const DataArrayInt *)_num_coords))
3316 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3317 return _rev_num_coords;
3319 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3320 return l1->getRevNumberField();
3324 * Returns a pointer to the node coordinates array of \a this mesh \b without
3325 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3327 DataArrayDouble *MEDFileUMesh::getCoords() const
3330 MCAuto<DataArrayDouble> tmp(_coords);
3331 if((DataArrayDouble *)tmp)
3339 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3340 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3342 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3343 * \param [in] grp - the name of the group whose mesh entities are included in the
3345 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3346 * according to the optional numbers of entities, if available.
3347 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3348 * delete this mesh using decrRef() as it is no more needed.
3349 * \throw If the name of a nonexistent group is specified.
3350 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3352 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3355 synchronizeTinyInfoOnLeaves();
3356 std::vector<std::string> tmp(1);
3358 return getGroups(meshDimRelToMaxExt,tmp,renum);
3362 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3363 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3365 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3366 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3368 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3369 * according to the optional numbers of entities, if available.
3370 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3371 * delete this mesh using decrRef() as it is no more needed.
3372 * \throw If a name of a nonexistent group is present in \a grps.
3373 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3375 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3378 synchronizeTinyInfoOnLeaves();
3379 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3380 MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3381 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3382 zeRet->setName(grps[0]);
3383 return zeRet.retn();
3387 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3388 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3390 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3391 * \param [in] fam - the name of the family whose mesh entities are included in the
3393 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3394 * according to the optional numbers of entities, if available.
3395 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3396 * delete this mesh using decrRef() as it is no more needed.
3397 * \throw If a name of a nonexistent family is present in \a grps.
3398 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3400 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3403 synchronizeTinyInfoOnLeaves();
3404 std::vector<std::string> tmp(1);
3406 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3410 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3411 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3413 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3414 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3416 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3417 * according to the optional numbers of entities, if available.
3418 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3419 * delete this mesh using decrRef() as it is no more needed.
3420 * \throw If a name of a nonexistent family is present in \a fams.
3421 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3423 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3426 synchronizeTinyInfoOnLeaves();
3427 if(meshDimRelToMaxExt==1)
3429 MCAuto<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3430 MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3431 MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3435 std::vector<int> famIds=getFamiliesIds(fams);
3436 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3437 MCAuto<MEDCouplingUMesh> zeRet;
3439 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3441 zeRet=l1->getFamilyPart(0,0,renum);
3442 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3443 zeRet->setName(fams[0]);
3444 return zeRet.retn();
3448 * Returns ids of mesh entities contained in given families of a given dimension.
3449 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3451 * \param [in] fams - the names of the families of interest.
3452 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3453 * returned instead of ids.
3454 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3455 * numbers, if available and required, of mesh entities of the families. The caller
3456 * is to delete this array using decrRef() as it is no more needed.
3457 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3459 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3461 std::vector<int> famIds=getFamiliesIds(fams);
3462 if(meshDimRelToMaxExt==1)
3464 if((const DataArrayInt *)_fam_coords)
3466 MCAuto<DataArrayInt> da;
3468 da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3470 da=_fam_coords->findIdsEqualList(0,0);
3472 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3477 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3479 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3481 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3483 return l1->getFamilyPartArr(0,0,renum);
3487 * Returns a MEDCouplingUMesh of a given relative dimension.
3488 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3489 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3490 * To build a valid MEDCouplingUMesh from the returned one in this case,
3491 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3492 * \param [in] meshDimRelToMax - the relative dimension of interest.
3493 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3494 * optional numbers of mesh entities.
3495 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3496 * delete using decrRef() as it is no more needed.
3497 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3499 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3502 synchronizeTinyInfoOnLeaves();
3503 if(meshDimRelToMaxExt==1)
3507 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3508 MCAuto<DataArrayDouble> cc=_coords->deepCopy();
3509 umesh->setCoords(cc);
3510 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3511 umesh->setName(getName());
3515 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3516 return l1->getWholeMesh(renum);
3519 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3521 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3522 return l1->getDistributionOfTypes();
3526 * Returns a MEDCouplingUMesh of a relative dimension == 0.
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 == 0 in \a this mesh.
3533 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3535 return getMeshAtLevel(0,renum);
3539 * Returns a MEDCouplingUMesh of a relative dimension == -1.
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 == -1 in \a this mesh.
3546 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3548 return getMeshAtLevel(-1,renum);
3552 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3553 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3554 * optional numbers of mesh entities.
3555 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3556 * delete using decrRef() as it is no more needed.
3557 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3559 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3561 return getMeshAtLevel(-2,renum);
3565 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3566 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3567 * optional numbers of mesh entities.
3568 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3569 * delete using decrRef() as it is no more needed.
3570 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3572 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3574 return getMeshAtLevel(-3,renum);
3578 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3579 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3580 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3581 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3583 void MEDFileUMesh::forceComputationOfParts() const
3585 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3587 const MEDFileUMeshSplitL1 *elt(*it);
3589 elt->forceComputationOfParts();
3594 * This method returns a vector of mesh parts containing each exactly one geometric type.
3595 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3596 * This method is only for memory aware users.
3597 * The returned pointers are **NOT** new object pointer. No need to mange them.
3599 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3602 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3603 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3607 * This method returns the part of \a this having the geometric type \a gt.
3608 * If such part is not existing an exception will be thrown.
3609 * The returned pointer is **NOT** new object pointer. No need to mange it.
3611 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3614 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
3615 int lev=(int)cm.getDimension()-getMeshDimension();
3616 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3617 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3621 * This method returns for each geo types in \a this number of cells with this geo type.
3622 * 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.
3623 * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
3625 * \sa getDistributionOfTypes
3627 std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
3629 std::vector< std::pair<int,int> > ret;
3630 std::vector<int> nel(getNonEmptyLevels());
3631 for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
3633 std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
3634 for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
3636 int nbCells(getNumberOfCellsWithType(*it1));
3637 ret.push_back(std::pair<int,int>(*it1,nbCells));
3640 ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
3645 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3646 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3648 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3650 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3651 return sp->getGeoTypes();
3654 int MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
3656 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
3657 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
3658 return sp->getNumberOfCellsWithType(ct);
3662 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3663 * \param [in] gt - the geometric type for which the family field is asked.
3664 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3665 * delete using decrRef() as it is no more needed.
3666 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3668 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3670 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3671 int lev=(int)cm.getDimension()-getMeshDimension();
3672 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3673 return sp->extractFamilyFieldOnGeoType(gt);
3677 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3678 * \param [in] gt - the geometric type for which the number field is asked.
3679 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3680 * delete using decrRef() as it is no more needed.
3681 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3683 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3685 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3686 int lev=(int)cm.getDimension()-getMeshDimension();
3687 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3688 return sp->extractNumberFieldOnGeoType(gt);
3692 * This method returns for specified geometric type \a gt the relative level to \a this.
3693 * If the relative level is empty an exception will be thrown.
3695 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3697 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3698 int ret((int)cm.getDimension()-getMeshDimension());
3699 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3703 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3705 if(meshDimRelToMaxExt==1)
3706 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3707 if(meshDimRelToMaxExt>1)
3708 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3709 int tracucedRk=-meshDimRelToMaxExt;
3710 if(tracucedRk>=(int)_ms.size())
3711 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3712 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3713 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3714 return _ms[tracucedRk];
3717 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3719 if(meshDimRelToMaxExt==1)
3720 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3721 if(meshDimRelToMaxExt>1)
3722 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3723 int tracucedRk=-meshDimRelToMaxExt;
3724 if(tracucedRk>=(int)_ms.size())
3725 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3726 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3727 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3728 return _ms[tracucedRk];
3731 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3733 if(-meshDimRelToMax>=(int)_ms.size())
3734 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3736 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3738 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3740 int ref=(*it)->getMeshDimension();
3741 if(ref+i!=meshDim-meshDimRelToMax)
3742 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3748 * Sets the node coordinates array of \a this mesh.
3749 * \param [in] coords - the new node coordinates array.
3750 * \throw If \a coords == \c NULL.
3752 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3755 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3756 if(coords==(DataArrayDouble *)_coords)
3758 coords->checkAllocated();
3759 int nbOfTuples(coords->getNumberOfTuples());
3762 _fam_coords=DataArrayInt::New();
3763 _fam_coords->alloc(nbOfTuples,1);
3764 _fam_coords->fillWithZero();
3765 _num_coords=0; _rev_num_coords=0; _name_coords=0;
3766 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3767 if((MEDFileUMeshSplitL1 *)(*it))
3768 (*it)->setCoords(coords);
3772 * Change coords without changing anything concerning families and numbering on nodes.
3774 void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
3777 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
3778 if(coords==(DataArrayDouble *)_coords)
3780 coords->checkAllocated();
3781 int nbOfTuples(coords->getNumberOfTuples());
3782 if(_coords.isNull())
3789 int oldNbTuples(_coords->getNumberOfTuples());
3790 if(oldNbTuples!=nbOfTuples)
3791 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
3795 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3796 if((MEDFileUMeshSplitL1 *)(*it))
3797 (*it)->setCoords(coords);
3801 * Removes all groups of a given dimension in \a this mesh.
3802 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3803 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3805 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3807 if(meshDimRelToMaxExt==1)
3809 if((DataArrayInt *)_fam_coords)
3810 _fam_coords->fillWithZero();
3813 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3814 l1->eraseFamilyField();
3819 * Removes all families with ids not present in the family fields of \a this mesh.
3821 void MEDFileUMesh::optimizeFamilies()
3823 std::vector<int> levs=getNonEmptyLevelsExt();
3824 std::set<int> allFamsIds;
3825 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3827 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3828 MCAuto<DataArrayInt> ids=ffield->getDifferentValues();
3830 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3833 std::set<std::string> famNamesToKill;
3834 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3836 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3837 famNamesToKill.insert((*it).first);
3839 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3840 _families.erase(*it);
3841 std::vector<std::string> grpNamesToKill;
3842 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3844 std::vector<std::string> tmp;
3845 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3847 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3848 tmp.push_back(*it2);
3853 tmp.push_back((*it).first);
3855 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3860 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3861 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3862 * The boundary is built according to the following method:
3863 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3864 * coordinates array is extended).
3865 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
3866 * called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
3867 * might not be duplicated at all.
3868 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3869 * other side of the group is no more a neighbor)
3870 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3871 * bordering the newly created boundary use the newly computed nodes.
3872 * Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
3873 * Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
3875 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3876 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3878 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3879 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3880 * \sa clearNodeAndCellNumbers()
3882 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3883 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3885 typedef MCAuto<MEDCouplingUMesh> MUMesh;
3886 typedef MCAuto<DataArrayInt> DAInt;
3888 std::vector<int> levs=getNonEmptyLevels();
3889 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3890 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3891 MUMesh m0=getMeshAtLevel(0);
3892 MUMesh m1=getMeshAtLevel(-1);
3893 int nbNodes=m0->getNumberOfNodes();
3894 MUMesh m11=getGroup(-1,grpNameM1);
3895 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3896 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3897 DAInt nodeIdsToDuplicate(tmp00);
3898 DAInt cellsToModifyConn0(tmp11);
3899 DAInt cellsToModifyConn1(tmp22);
3900 MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3901 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3902 DAInt descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3903 MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3904 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3905 DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3906 MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3907 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3908 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3909 DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3910 DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
3911 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3912 DAInt grpIds=getGroupArr(-1,grpNameM1);
3913 DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3914 MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3915 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3916 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3917 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3918 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3919 m0->setCoords(tmp0->getCoords());
3920 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3921 _ms[0]->forceComputationOfParts(); // necessary because we modify the connectivity of some internal part
3922 m1->setCoords(m0->getCoords());
3923 _coords=m0->getCoords(); _coords->incrRef();
3924 // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
3925 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3926 DataArrayInt * duplCells;
3927 m1->areCellsIncludedIn(m11, 0, duplCells);
3928 DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
3929 MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
3930 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
3931 MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3932 DAInt szOfCellGrpOfSameType(tmp00);
3933 DAInt idInMsOfCellGrpOfSameType(tmp11);
3935 newm1->setName(getName());
3936 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3938 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
3939 DAInt newFam=DataArrayInt::New();
3940 newFam->alloc(newm1->getNumberOfCells(),1);
3941 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3942 // Positive ID for family of nodes, negative for all the rest.
3944 if (m1->getMeshDimension() == 0)
3945 idd=getMaxFamilyId()+1;
3947 idd=getMinFamilyId()-1;
3948 int globStart=0,start=0,end,globEnd;
3949 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3950 for(int i=0;i<nbOfChunks;i++)
3952 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3953 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3955 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3956 DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
3957 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3962 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3966 newm1->setCoords(getCoords());
3967 setMeshAtLevel(-1,newm1);
3968 setFamilyFieldArr(-1,newFam);
3969 std::string grpName2(grpNameM1); grpName2+="_dup";
3970 addFamily(grpName2,idd);
3971 addFamilyOnGrp(grpName2,grpName2);
3976 int newNbOfNodes=getCoords()->getNumberOfTuples();
3977 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3978 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3979 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3984 _rev_num_coords = 0;
3985 for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
3986 it != _ms.end(); it++)
3989 (*it)->_rev_num = 0;
3991 nodesDuplicated=nodeIdsToDuplicate.retn();
3992 cellsModified=cellsToModifyConn0.retn();
3993 cellsNotModified=cellsToModifyConn1.retn();
3996 /*! Similar to MEDCouplingUMesh::unPolyze(): converts all polygons (if \a this is a 2D mesh) or polyhedrons
3997 * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
4000 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
4001 * \param [out] newCode etrieves the distribution of types after the call if true is returned
4002 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
4004 * \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.
4005 * 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.
4007 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4009 o2nRenumCell=0; oldCode.clear(); newCode.clear();
4010 std::vector<int> levs=getNonEmptyLevels();
4012 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
4013 std::vector< MCAuto<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
4016 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
4018 MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
4019 std::vector<int> code1=m->getDistributionOfTypes();
4020 end=PutInThirdComponentOfCodeOffset(code1,start);
4021 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
4022 bool hasChanged=m->unPolyze();
4023 DataArrayInt *fake=0;
4024 MCAuto<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
4025 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
4027 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
4030 MCAuto<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
4031 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
4033 MCAuto<DataArrayInt> famField2,numField2;
4034 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
4035 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
4036 setMeshAtLevel(*it,m);
4037 std::vector<int> code2=m->getDistributionOfTypes();
4038 end=PutInThirdComponentOfCodeOffset(code2,start);
4039 newCode.insert(newCode.end(),code2.begin(),code2.end());
4041 if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
4045 MCAuto<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
4046 setFamilyFieldArr(*it,newFamField);
4050 MCAuto<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
4051 setRenumFieldArr(*it,newNumField);
4056 newCode.insert(newCode.end(),code1.begin(),code1.end());
4062 MCAuto<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
4063 MCAuto<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
4064 o2nRenumCell=o2nRenumCellRet.retn();
4069 /*! \cond HIDDEN_ITEMS */
4070 struct MEDLoaderAccVisit1
4072 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
4073 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
4074 int _new_nb_of_nodes;
4079 * 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.
4080 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
4081 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
4082 * -1 values in returned array means that the corresponding old node is no more used.
4084 * \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
4085 * is modified in \a this.
4086 * \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
4089 DataArrayInt *MEDFileUMesh::zipCoords()
4091 const DataArrayDouble *coo(getCoords());
4093 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
4094 int nbOfNodes(coo->getNumberOfTuples());
4095 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
4096 std::vector<int> neLevs(getNonEmptyLevels());
4097 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
4099 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
4100 if(zeLev->isMeshStoredSplitByType())
4102 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
4103 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4105 (*it)->computeNodeIdsAlg(nodeIdsInUse);
4109 MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
4110 mesh->computeNodeIdsAlg(nodeIdsInUse);
4113 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
4114 if(nbrOfNodesInUse==nbOfNodes)
4115 return 0;//no need to update _part_coords
4116 MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
4117 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
4118 MCAuto<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
4119 MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4120 MCAuto<DataArrayInt> newFamCoords;
4121 MCAuto<DataArrayAsciiChar> newNameCoords;
4122 if((const DataArrayInt *)_fam_coords)
4123 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4124 MCAuto<DataArrayInt> newNumCoords;
4125 if((const DataArrayInt *)_num_coords)
4126 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
4127 if((const DataArrayAsciiChar *)_name_coords)
4128 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
4129 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
4130 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4132 if((MEDFileUMeshSplitL1*)*it)
4134 (*it)->renumberNodesInConn(ret->begin());
4135 (*it)->setCoords(_coords);
4138 // updates _part_coords
4139 const PartDefinition *pc(_part_coords);
4142 MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
4143 _part_coords=tmpPD->composeWith(pc);
4149 * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
4150 * The extraction of \a this is specified by the extractDef \a input map.
4151 * This map tells for each level of cells, the cells kept in the extraction.
4153 * \return - a new reference of DataArrayInt that represents sorted node ids, the extraction is lying on.
4154 * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
4156 DataArrayInt *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4158 std::vector<int> levs(getNonEmptyLevels());
4159 std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
4160 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4163 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
4164 if((*it).second.isNull())
4165 throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
4168 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4170 std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
4171 throw INTERP_KERNEL::Exception(oss.str());
4173 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4174 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4175 mPart->computeNodeIdsAlg(fetchedNodes);
4177 return DataArrayInt::BuildListOfSwitchedOn(fetchedNodes);
4181 * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
4183 * \return - a new reference of MEDFileUMesh
4184 * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
4186 MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef) const
4188 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
4189 std::vector<int> levs(getNonEmptyLevels());
4190 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
4193 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
4194 if((*it).second.isNull())
4195 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
4198 if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
4200 std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
4201 throw INTERP_KERNEL::Exception(oss.str());
4203 MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
4204 MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
4205 ret->setMeshAtLevel((*it).first,mPart);
4206 const DataArrayInt *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
4209 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4210 ret->setFamilyFieldArr((*it).first,famPart);
4214 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
4215 ret->setFamilyFieldArr((*it).first,numPart);
4218 std::map<int, MCAuto<DataArrayInt> >::const_iterator it2(extractDef.find(1));
4219 if(it2!=extractDef.end())
4221 const DataArrayDouble *coo(ret->getCoords());
4223 throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
4224 MCAuto<DataArrayInt> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
4225 MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4226 ret->setCoords(cooPart);
4227 const DataArrayInt *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
4230 MCAuto<DataArrayInt> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4231 ret->setFamilyFieldArr(1,famPart);
4235 MCAuto<DataArrayInt> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
4236 ret->setFamilyFieldArr(1,numPart);
4238 for(std::map<int, MCAuto<DataArrayInt> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
4242 MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
4243 m->renumberNodesInConn(o2nNodes->begin());
4244 ret->setMeshAtLevel((*it3).first,m);
4251 * This method performs an extrusion along a path defined by \a m1D.
4252 * \a this is expected to be a mesh with max mesh dimension equal to 2.
4253 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
4254 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
4255 * This method scans all levels in \a this
4256 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
4258 * \param [in] m1D - the mesh defining the extrusion path.
4259 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
4260 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
4262 * \sa MEDCouplingUMesh::buildExtrudedMesh
4264 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
4267 if(getMeshDimension()!=2)
4268 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
4269 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4270 m1D->checkConsistencyLight();
4271 if(m1D->getMeshDimension()!=1)
4272 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
4273 int nbRep(m1D->getNumberOfCells());
4274 std::vector<int> levs(getNonEmptyLevels());
4275 std::vector<std::string> grps(getGroupsNames());
4276 std::vector< MCAuto<MEDCouplingUMesh> > zeList;
4277 DataArrayDouble *coords(0);
4278 std::size_t nbOfLevsOut(levs.size()+1);
4279 std::vector< MCAuto<DataArrayInt> > o2ns(nbOfLevsOut);
4280 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4282 MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
4283 item=item->clone(false);
4284 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
4285 MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
4286 tmp->changeSpaceDimension(3+(*lev),0.);
4287 MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
4288 zeList.push_back(elt);
4290 coords=elt->getCoords();
4293 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
4294 for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
4296 (*it)->setName(getName());
4297 (*it)->setCoords(coords);
4299 for(std::size_t ii=0;ii!=zeList.size();ii++)
4302 MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
4305 MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
4306 MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
4307 MCAuto<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCopy());
4308 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
4309 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
4310 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
4311 std::vector<const MEDCouplingUMesh *> elts(3);
4312 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
4313 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
4314 elt->setName(getName());
4317 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
4318 ret->setMeshAtLevel(lev,elt);
4320 MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
4321 endLev=endLev->clone(false); endLev->setCoords(coords);
4322 MCAuto<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCopy());
4323 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
4324 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
4325 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
4326 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
4327 endLev->setName(getName());
4328 ret->setMeshAtLevel(levs.back()-1,endLev);
4330 for(std::size_t ii=0;ii!=zeList.size();ii++)
4333 std::vector< MCAuto<DataArrayInt> > outGrps;
4334 std::vector< const DataArrayInt * > outGrps2;
4337 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4339 MCAuto<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
4340 if(!grpArr->empty())
4342 MCAuto<DataArrayInt> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
4343 int offset0(zeList[ii]->getNumberOfCells());
4344 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
4345 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
4346 std::ostringstream oss; oss << grpArr2->getName() << "_top";
4347 grpArr2->setName(oss.str());
4348 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4349 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4350 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4351 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4356 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4358 MCAuto<DataArrayInt> grpArr(getGroupArr(lev,*grp));
4359 if(!grpArr->empty())
4361 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
4362 std::vector< MCAuto<DataArrayInt> > grpArrs(nbRep);
4363 std::vector< const DataArrayInt *> grpArrs2(nbRep);
4364 for(int iii=0;iii<nbRep;iii++)
4366 grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
4367 grpArrs2[iii]=grpArrs[iii];
4369 MCAuto<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
4370 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
4371 std::ostringstream grpName; grpName << *grp << "_extruded";
4372 grpArrExt->setName(grpName.str());
4373 outGrps.push_back(grpArrExt);
4374 outGrps2.push_back(grpArrExt);
4377 ret->setGroupsAtLevel(lev,outGrps2);
4379 std::vector< MCAuto<DataArrayInt> > outGrps;
4380 std::vector< const DataArrayInt * > outGrps2;
4381 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
4383 MCAuto<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
4384 if(grpArr1->empty())
4386 MCAuto<DataArrayInt> grpArr2(grpArr1->deepCopy());
4387 std::ostringstream grpName; grpName << *grp << "_top";
4388 grpArr2->setName(grpName.str());
4389 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
4390 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
4391 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
4393 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
4398 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
4399 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4400 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4402 * \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
4403 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4404 * \param [in] eps - detection threshold for coordinates.
4405 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4407 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4409 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4412 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4413 int initialNbNodes(getNumberOfNodes());
4414 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4415 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4417 MCAuto<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4419 DataArrayDouble *zeCoords(m0->getCoords());
4420 ret->setMeshAtLevel(0,m0);
4421 std::vector<int> levs(getNonEmptyLevels());
4422 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4425 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4426 ret->setFamilyFieldArr(0,famFieldCpy);
4428 famField=getFamilyFieldAtLevel(1);
4431 MCAuto<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4432 fam->fillWithZero();
4433 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4434 ret->setFamilyFieldArr(1,fam);
4436 ret->copyFamGrpMapsFrom(*this);
4437 MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4438 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4442 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4443 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4444 if(m1->getMeshDimension()!=0)
4447 MCAuto<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4448 }//kill unused notUsed var
4449 MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
4451 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4452 MCAuto<DataArrayInt> bSafe(b);
4455 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4456 throw INTERP_KERNEL::Exception(oss.str().c_str());
4458 b->applyLin(1,initialNbNodes);
4459 MCAuto<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4460 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4461 MCAuto<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4462 m1->renumberNodesInConn(renum->begin());
4464 m1->setCoords(zeCoords);
4465 ret->setMeshAtLevel(*lev,m1);
4466 famField=getFamilyFieldAtLevel(*lev);
4469 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4470 ret->setFamilyFieldArr(*lev,famFieldCpy);
4477 * This method converts all quadratic cells in \a this into linear cells.
4478 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4479 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4481 * \param [in] eps - detection threshold for coordinates.
4482 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4484 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4486 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4489 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4490 MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4491 MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
4492 m0->convertQuadraticCellsToLinear();
4494 DataArrayDouble *zeCoords(m0->getCoords());
4495 ret->setMeshAtLevel(0,m0);
4496 std::vector<int> levs(getNonEmptyLevels());
4497 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4500 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4501 ret->setFamilyFieldArr(0,famFieldCpy);
4503 famField=getFamilyFieldAtLevel(1);
4506 MCAuto<DataArrayInt> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
4507 ret->setFamilyFieldArr(1,fam);
4509 ret->copyFamGrpMapsFrom(*this);
4510 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4514 MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4515 MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
4516 m1->convertQuadraticCellsToLinear();
4519 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4520 MCAuto<DataArrayInt> bSafe(b);
4523 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4524 throw INTERP_KERNEL::Exception(oss.str().c_str());
4526 m1->renumberNodesInConn(b->begin());
4527 m1->setCoords(zeCoords);
4528 ret->setMeshAtLevel(*lev,m1);
4529 famField=getFamilyFieldAtLevel(*lev);
4532 MCAuto<DataArrayInt> famFieldCpy(famField->deepCopy());
4533 ret->setFamilyFieldArr(*lev,famFieldCpy);
4540 * Computes the symmetry of \a this.
4541 * \return a new object.
4543 MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
4545 MCAuto<MEDFileUMesh> ret(deepCopy());
4546 DataArrayDouble *myCoo(getCoords());
4549 MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
4550 ret->setCoordsForced(newCoo);
4555 MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
4558 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
4559 std::size_t sz(meshes.size()),i(0);
4560 std::vector<const DataArrayDouble *> coos(sz);
4561 std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
4562 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4565 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
4566 coos[i]=(*it)->getCoords();
4567 fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
4568 num_coos[i]=(*it)->getNumberFieldAtLevel(1);
4570 const MEDFileUMesh *ref(meshes[0]);
4571 int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
4572 std::vector<int> levs(ref->getNonEmptyLevels());
4573 std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
4574 std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
4575 std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
4576 std::map<std::string,int> map1;
4577 std::map<std::string, std::vector<std::string> > map2;
4578 for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
4580 if((*it)->getSpaceDimension()!=spaceDim)
4581 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
4582 if((*it)->getMeshDimension()!=meshDim)
4583 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
4584 if((*it)->getNonEmptyLevels()!=levs)
4585 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
4586 for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
4588 MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
4589 m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
4590 m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
4591 m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
4593 const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
4594 for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
4595 map1[(*it3).first]=(*it3).second;
4596 const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
4597 for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
4598 map2[(*it4).first]=(*it4).second;
4600 // Easy part : nodes
4601 MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
4602 MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
4603 ret->setCoords(coo);
4604 if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
4606 MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
4607 ret->setFamilyFieldArr(1,fam_coo);
4609 if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
4611 MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
4612 ret->setRenumFieldArr(1,num_coo);
4615 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4617 std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
4618 if(it2==m_mesh.end())
4619 throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
4620 MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
4621 mesh->setCoords(coo); mesh->setName(ref->getName());
4622 MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
4623 ret->setMeshAtLevel(*it,mesh);
4624 std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
4625 if(it3!=m_fam.end())
4627 const std::vector<const DataArrayInt *>& fams((*it3).second);
4628 if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
4630 MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
4631 famm->renumberInPlace(renum->begin());
4632 ret->setFamilyFieldArr(*it,famm);
4635 if(it4!=m_renum.end())
4637 const std::vector<const DataArrayInt *>& renums((*it4).second);
4638 if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
4640 MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
4641 renumm->renumberInPlace(renum->begin());
4642 ret->setRenumFieldArr(*it,renumm);
4647 ret->setFamilyInfo(map1);
4648 ret->setGroupInfo(map2);
4649 ret->setName(ref->getName());
4653 MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
4655 if(getMeshDimension()!=3)
4656 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
4657 MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
4658 if(m3D.isNull() || m2D.isNull())
4659 throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
4660 int zeId(std::numeric_limits<int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
4661 MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
4665 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4667 clearNonDiscrAttributes();
4668 forceComputationOfParts();
4669 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4670 std::vector<int> layer0;
4671 layer0.push_back(getAxisType());//0 i
4672 layer0.push_back(_order); //1 i
4673 layer0.push_back(_iteration);//2 i
4674 layer0.push_back(getSpaceDimension());//3 i
4675 tinyDouble.push_back(_time);//0 d
4676 tinyStr.push_back(_name);//0 s
4677 tinyStr.push_back(_desc_name);//1 s
4678 for(int i=0;i<getSpaceDimension();i++)
4679 tinyStr.push_back(_coords->getInfoOnComponent(i));
4680 layer0.push_back((int)_families.size());//4 i <- key info aa layer#0
4681 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4683 tinyStr.push_back((*it).first);
4684 layer0.push_back((*it).second);
4686 layer0.push_back((int)_groups.size());//4+aa i <- key info bb layer#0
4687 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4689 layer0.push_back((int)(*it0).second.size());
4690 tinyStr.push_back((*it0).first);
4691 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4692 tinyStr.push_back(*it1);
4694 // sizeof(layer0)==4+aa+1+bb layer#0
4695 bigArrayD=_coords;// 0 bd
4696 bigArraysI.push_back(_fam_coords);// 0 bi
4697 bigArraysI.push_back(_num_coords);// 1 bi
4698 const PartDefinition *pd(_part_coords);
4700 layer0.push_back(-1);
4703 std::vector<int> tmp0;
4704 pd->serialize(tmp0,bigArraysI);
4705 tinyInt.push_back(tmp0.size());
4706 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4709 std::vector<int> layer1;
4710 std::vector<int> levs(getNonEmptyLevels());
4711 layer1.push_back((int)levs.size());// 0 i <- key
4712 layer1.insert(layer1.end(),levs.begin(),levs.end());
4713 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4715 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4716 lev->serialize(layer1,bigArraysI);
4718 // put layers all together.
4719 tinyInt.push_back(layer0.size());
4720 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4721 tinyInt.push_back(layer1.size());
4722 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4725 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4726 std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
4728 int sz0(tinyInt[0]);
4729 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4730 int sz1(tinyInt[sz0+1]);
4731 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4733 std::reverse(layer0.begin(),layer0.end());
4734 std::reverse(layer1.begin(),layer1.end());
4735 std::reverse(tinyDouble.begin(),tinyDouble.end());
4736 std::reverse(tinyStr.begin(),tinyStr.end());
4737 std::reverse(bigArraysI.begin(),bigArraysI.end());
4739 setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
4740 _order=layer0.back(); layer0.pop_back();
4741 _iteration=layer0.back(); layer0.pop_back();
4742 int spaceDim(layer0.back()); layer0.pop_back();
4743 _time=tinyDouble.back(); tinyDouble.pop_back();
4744 _name=tinyStr.back(); tinyStr.pop_back();
4745 _desc_name=tinyStr.back(); tinyStr.pop_back();
4746 _coords=bigArrayD; _coords->rearrange(spaceDim);
4747 for(int i=0;i<spaceDim;i++)
4749 _coords->setInfoOnComponent(i,tinyStr.back());
4752 int nbOfFams(layer0.back()); layer0.pop_back();
4754 for(int i=0;i<nbOfFams;i++)
4756 _families[tinyStr.back()]=layer0.back();
4757 tinyStr.pop_back(); layer0.pop_back();
4759 int nbGroups(layer0.back()); layer0.pop_back();
4761 for(int i=0;i<nbGroups;i++)
4763 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4764 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4765 std::vector<std::string> fams(nbOfFamsOnGrp);
4766 for(int j=0;j<nbOfFamsOnGrp;j++)
4768 fams[j]=tinyStr.back(); tinyStr.pop_back();
4770 _groups[grpName]=fams;
4772 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4773 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4775 int isPd(layer0.back()); layer0.pop_back();
4778 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4779 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4780 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4783 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4785 int nbLevs(layer1.back()); layer1.pop_back();
4786 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4788 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4789 _ms.resize(maxLev+1);
4790 for(int i=0;i<nbLevs;i++)
4794 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4799 * Adds a group of nodes to \a this mesh.
4800 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4801 * The ids should be sorted and different each other (MED file norm).
4803 * \warning this method can alter default "FAMILLE_ZERO" family.
4804 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4806 * \throw If the node coordinates array is not set.
4807 * \throw If \a ids == \c NULL.
4808 * \throw If \a ids->getName() == "".
4809 * \throw If \a ids does not respect the MED file norm.
4810 * \throw If a group with name \a ids->getName() already exists.
4812 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4814 const DataArrayDouble *coords(_coords);
4816 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4817 int nbOfNodes(coords->getNumberOfTuples());
4818 if(!((DataArrayInt *)_fam_coords))
4819 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4821 addGroupUnderground(true,ids,_fam_coords);
4825 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4827 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4828 * The ids should be sorted and different each other (MED file norm).
4830 * \warning this method can alter default "FAMILLE_ZERO" family.
4831 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4833 * \throw If the node coordinates array is not set.
4834 * \throw If \a ids == \c NULL.
4835 * \throw If \a ids->getName() == "".
4836 * \throw If \a ids does not respect the MED file norm.
4837 * \throw If a group with name \a ids->getName() already exists.
4839 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4841 std::vector<int> levs(getNonEmptyLevelsExt());
4842 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4844 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4845 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4847 if(meshDimRelToMaxExt==1)
4848 { addNodeGroup(ids); return ; }
4849 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4850 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4851 addGroupUnderground(false,ids,fam);
4855 * Changes a name of a family specified by its id.
4856 * \param [in] id - the id of the family of interest.
4857 * \param [in] newFamName - the new family name.
4858 * \throw If no family with the given \a id exists.
4860 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4862 std::string oldName=getFamilyNameGivenId(id);
4863 _families.erase(oldName);
4864 _families[newFamName]=id;
4868 * Removes a mesh of a given dimension.
4869 * \param [in] meshDimRelToMax - the relative dimension of interest.
4870 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4872 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4874 std::vector<int> levSet=getNonEmptyLevels();
4875 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4876 if(it==levSet.end())
4877 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4878 int pos=(-meshDimRelToMax);
4883 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4884 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4885 * \param [in] m - the new mesh to set.
4886 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4888 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4889 * another node coordinates array.
4890 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4891 * to the existing meshes of other levels of \a this mesh.
4893 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4895 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4896 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4900 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4901 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4902 * \param [in] m - the new mesh to set.
4903 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4904 * writing \a this mesh in a MED file.
4905 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4907 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4908 * another node coordinates array.
4909 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4910 * to the existing meshes of other levels of \a this mesh.
4912 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4914 MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4915 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4918 MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4920 dealWithTinyInfo(m);
4921 std::vector<int> levSet=getNonEmptyLevels();
4922 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4924 if((DataArrayDouble *)_coords==0)
4926 DataArrayDouble *c=m->getCoords();
4931 if(m->getCoords()!=_coords)
4932 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4933 int sz=(-meshDimRelToMax)+1;
4934 if(sz>=(int)_ms.size())
4936 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4940 return _ms[-meshDimRelToMax];
4944 * This method allows to set at once the content of different levels in \a this.
4945 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4947 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4948 * \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.
4949 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4951 * \throw If \a there is a null pointer in \a ms.
4952 * \sa MEDFileUMesh::setMeshAtLevel
4954 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4958 const MEDCouplingUMesh *mRef=ms[0];
4960 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4961 std::string name(mRef->getName());
4962 const DataArrayDouble *coo(mRef->getCoords());
4965 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4967 const MEDCouplingUMesh *cur(*it);
4969 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4970 if(coo!=cur->getCoords())
4971 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4972 int mdim=cur->getMeshDimension();
4973 zeDim=std::max(zeDim,mdim);
4974 if(s.find(mdim)!=s.end())
4975 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4977 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4979 int mdim=(*it)->getMeshDimension();
4980 setName((*it)->getName());
4981 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4987 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4988 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4989 * The given meshes must share the same node coordinates array.
4990 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4991 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4992 * create in \a this mesh.
4993 * \throw If \a ms is empty.
4994 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4995 * to the existing meshes of other levels of \a this mesh.
4996 * \throw If the meshes in \a ms do not share the same node coordinates array.
4997 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4998 * of the given meshes.
4999 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5000 * \throw If names of some meshes in \a ms are equal.
5001 * \throw If \a ms includes a mesh with an empty name.
5003 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5006 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
5007 int sz=(-meshDimRelToMax)+1;
5008 if(sz>=(int)_ms.size())
5010 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5011 DataArrayDouble *coo=checkMultiMesh(ms);
5012 if((DataArrayDouble *)_coords==0)
5018 if((DataArrayDouble *)_coords!=coo)
5019 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
5020 std::vector<DataArrayInt *> corr;
5021 MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
5022 std::vector< MCAuto<DataArrayInt> > corr3(corr.begin(),corr.end());
5023 setMeshAtLevel(meshDimRelToMax,m,renum);
5024 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5025 setGroupsAtLevel(meshDimRelToMax,corr2,true);
5029 * Creates groups at a given level in \a this mesh from a sequence of
5030 * meshes each representing a group.
5031 * The given meshes must share the same node coordinates array.
5032 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
5033 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
5034 * create in \a this mesh.
5035 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
5037 * \throw If \a ms is empty.
5038 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
5039 * to the existing meshes of other levels of \a this mesh.
5040 * \throw If the meshes in \a ms do not share the same node coordinates array.
5041 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
5042 * of the given meshes.
5043 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
5044 * \throw If names of some meshes in \a ms are equal.
5045 * \throw If \a ms includes a mesh with an empty name.
5047 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
5050 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
5051 int sz=(-meshDimRelToMax)+1;
5052 if(sz>=(int)_ms.size())
5054 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
5055 DataArrayDouble *coo=checkMultiMesh(ms);
5056 if((DataArrayDouble *)_coords==0)
5062 if((DataArrayDouble *)_coords!=coo)
5063 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
5064 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
5065 std::vector< MCAuto<DataArrayInt> > corr(ms.size());
5067 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5069 DataArrayInt *arr=0;
5070 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
5074 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
5075 throw INTERP_KERNEL::Exception(oss.str().c_str());
5078 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
5079 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
5082 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
5084 const DataArrayDouble *ret=ms[0]->getCoords();
5085 int mdim=ms[0]->getMeshDimension();
5086 for(unsigned int i=1;i<ms.size();i++)
5088 ms[i]->checkConsistencyLight();
5089 if(ms[i]->getCoords()!=ret)
5090 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
5091 if(ms[i]->getMeshDimension()!=mdim)
5092 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
5094 return const_cast<DataArrayDouble *>(ret);
5098 * Sets the family field of a given relative dimension.
5099 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5100 * the family field is set.
5101 * \param [in] famArr - the array of the family field.
5102 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5103 * \throw If \a famArr has an invalid size.
5105 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5107 if(meshDimRelToMaxExt==1)
5114 DataArrayDouble *coo(_coords);
5116 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
5117 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
5122 if(meshDimRelToMaxExt>1)
5123 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
5124 int traducedRk=-meshDimRelToMaxExt;
5125 if(traducedRk>=(int)_ms.size())
5126 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5127 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5128 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5129 return _ms[traducedRk]->setFamilyArr(famArr);
5133 * Sets the optional numbers of mesh entities of a given dimension.
5134 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5135 * \param [in] renumArr - the array of the numbers.
5136 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5137 * \throw If \a renumArr has an invalid size.
5139 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5141 if(meshDimRelToMaxExt==1)
5149 DataArrayDouble *coo(_coords);
5151 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
5152 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
5153 renumArr->incrRef();
5154 _num_coords=renumArr;
5158 if(meshDimRelToMaxExt>1)
5159 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
5160 int traducedRk=-meshDimRelToMaxExt;
5161 if(traducedRk>=(int)_ms.size())
5162 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5163 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5164 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5165 return _ms[traducedRk]->setRenumArr(renumArr);
5169 * Sets the optional names of mesh entities of a given dimension.
5170 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5171 * \param [in] nameArr - the array of the names.
5172 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5173 * \throw If \a nameArr has an invalid size.
5175 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5177 if(meshDimRelToMaxExt==1)
5184 DataArrayDouble *coo(_coords);
5186 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
5187 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
5189 _name_coords=nameArr;
5192 if(meshDimRelToMaxExt>1)
5193 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
5194 int traducedRk=-meshDimRelToMaxExt;
5195 if(traducedRk>=(int)_ms.size())
5196 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
5197 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
5198 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
5199 return _ms[traducedRk]->setNameArr(nameArr);
5202 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
5204 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5205 if((const MEDFileUMeshSplitL1 *)(*it))
5206 (*it)->synchronizeTinyInfo(*this);
5210 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
5212 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
5214 DataArrayInt *arr=_fam_coords;
5216 arr->changeValue(oldId,newId);
5217 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
5219 MEDFileUMeshSplitL1 *sp=(*it);
5222 sp->changeFamilyIdArr(oldId,newId);
5227 std::list< MCAuto<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
5229 std::list< MCAuto<DataArrayInt> > ret;
5230 const DataArrayInt *da(_fam_coords);
5232 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5233 for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
5235 const MEDFileUMeshSplitL1 *elt(*it);
5238 da=elt->getFamilyField();
5240 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5246 void MEDFileUMesh::computeRevNum() const
5248 if((const DataArrayInt *)_num_coords)
5251 int maxValue=_num_coords->getMaxValue(pos);
5252 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
5256 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
5258 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
5261 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
5263 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
5264 ret.push_back((const DataArrayInt *)_fam_nodes);
5265 ret.push_back((const DataArrayInt *)_num_nodes);
5266 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
5267 ret.push_back((const DataArrayInt *)_fam_cells);
5268 ret.push_back((const DataArrayInt *)_num_cells);
5269 ret.push_back((const DataArrayAsciiChar *)_names_cells);
5270 ret.push_back((const DataArrayInt *)_fam_faces);
5271 ret.push_back((const DataArrayInt *)_num_faces);
5272 ret.push_back((const DataArrayInt *)_rev_num_nodes);
5273 ret.push_back((const DataArrayAsciiChar *)_names_faces);
5274 ret.push_back((const DataArrayInt *)_rev_num_cells);
5275 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
5279 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
5281 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5282 if((const DataArrayInt *)_fam_nodes)
5284 int val=_fam_nodes->getMaxValue(tmp);
5285 ret=std::max(ret,std::abs(val));
5287 if((const DataArrayInt *)_fam_cells)
5289 int val=_fam_cells->getMaxValue(tmp);
5290 ret=std::max(ret,std::abs(val));
5292 if((const DataArrayInt *)_fam_faces)
5294 int val=_fam_faces->getMaxValue(tmp);
5295 ret=std::max(ret,std::abs(val));
5300 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
5302 int ret=-std::numeric_limits<int>::max(),tmp=-1;
5303 if((const DataArrayInt *)_fam_nodes)
5305 int val=_fam_nodes->getMaxValue(tmp);
5306 ret=std::max(ret,val);
5308 if((const DataArrayInt *)_fam_cells)
5310 int val=_fam_cells->getMaxValue(tmp);
5311 ret=std::max(ret,val);
5313 if((const DataArrayInt *)_fam_faces)
5315 int val=_fam_faces->getMaxValue(tmp);
5316 ret=std::max(ret,val);
5321 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
5323 int ret=std::numeric_limits<int>::max(),tmp=-1;
5324 if((const DataArrayInt *)_fam_nodes)
5326 int val=_fam_nodes->getMinValue(tmp);
5327 ret=std::min(ret,val);
5329 if((const DataArrayInt *)_fam_cells)
5331 int val=_fam_cells->getMinValue(tmp);
5332 ret=std::min(ret,val);
5334 if((const DataArrayInt *)_fam_faces)
5336 int val=_fam_faces->getMinValue(tmp);
5337 ret=std::min(ret,val);
5342 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5344 if(!MEDFileMesh::isEqual(other,eps,what))
5346 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
5349 what="Mesh types differ ! This is structured and other is NOT !";
5352 const DataArrayInt *famc1=_fam_nodes;
5353 const DataArrayInt *famc2=otherC->_fam_nodes;
5354 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5356 what="Mismatch of families arr on nodes ! One is defined and not other !";
5361 bool ret=famc1->isEqual(*famc2);
5364 what="Families arr on nodes differ !";
5369 famc2=otherC->_fam_cells;
5370 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5372 what="Mismatch of families arr on cells ! One is defined and not other !";
5377 bool ret=famc1->isEqual(*famc2);
5380 what="Families arr on cells differ !";
5385 famc2=otherC->_fam_faces;
5386 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5388 what="Mismatch of families arr on faces ! One is defined and not other !";
5393 bool ret=famc1->isEqual(*famc2);
5396 what="Families arr on faces differ !";
5401 famc2=otherC->_num_nodes;
5402 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5404 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
5409 bool ret=famc1->isEqual(*famc2);
5412 what="Numbering arr on nodes differ !";
5417 famc2=otherC->_num_cells;
5418 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5420 what="Mismatch of numbering arr on cells ! One is defined and not other !";
5425 bool ret=famc1->isEqual(*famc2);
5428 what="Numbering arr on cells differ !";
5433 famc2=otherC->_num_faces;
5434 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
5436 what="Mismatch of numbering arr on faces ! One is defined and not other !";
5441 bool ret=famc1->isEqual(*famc2);
5444 what="Numbering arr on faces differ !";
5448 const DataArrayAsciiChar *d1=_names_cells;
5449 const DataArrayAsciiChar *d2=otherC->_names_cells;
5450 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5452 what="Mismatch of naming arr on cells ! One is defined and not other !";
5457 bool ret=d1->isEqual(*d2);
5460 what="Naming arr on cells differ !";
5465 d2=otherC->_names_faces;
5466 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5468 what="Mismatch of naming arr on faces ! One is defined and not other !";
5473 bool ret=d1->isEqual(*d2);
5476 what="Naming arr on faces differ !";
5481 d2=otherC->_names_nodes;
5482 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
5484 what="Mismatch of naming arr on nodes ! One is defined and not other !";
5489 bool ret=d1->isEqual(*d2);
5492 what="Naming arr on nodes differ !";
5499 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
5501 MEDFileMesh::clearNonDiscrAttributes();
5502 const DataArrayInt *tmp=_fam_nodes;
5504 (const_cast<DataArrayInt *>(tmp))->setName("");
5507 (const_cast<DataArrayInt *>(tmp))->setName("");
5510 (const_cast<DataArrayInt *>(tmp))->setName("");
5513 (const_cast<DataArrayInt *>(tmp))->setName("");
5516 (const_cast<DataArrayInt *>(tmp))->setName("");
5519 (const_cast<DataArrayInt *>(tmp))->setName("");
5523 * Returns ids of mesh entities contained in given families of a given dimension.
5524 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
5526 * \param [in] fams - the names of the families of interest.
5527 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
5528 * returned instead of ids.
5529 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
5530 * numbers, if available and required, of mesh entities of the families. The caller
5531 * is to delete this array using decrRef() as it is no more needed.
5532 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5534 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5536 std::vector<int> famIds(getFamiliesIds(fams));
5537 switch(meshDimRelToMaxExt)
5541 if((const DataArrayInt *)_fam_nodes)
5543 MCAuto<DataArrayInt> da;
5545 da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5547 da=_fam_nodes->findIdsEqualList(0,0);
5549 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5554 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5559 if((const DataArrayInt *)_fam_cells)
5561 MCAuto<DataArrayInt> da;
5563 da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5565 da=_fam_cells->findIdsEqualList(0,0);
5567 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5572 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5577 if((const DataArrayInt *)_fam_faces)
5579 MCAuto<DataArrayInt> da;
5581 da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5583 da=_fam_faces->findIdsEqualList(0,0);
5585 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5590 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5594 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5596 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5600 * Sets the family field of a given relative dimension.
5601 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5602 * the family field is set.
5603 * \param [in] famArr - the array of the family field.
5604 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5605 * \throw If \a famArr has an invalid size.
5606 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5608 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5610 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5612 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5613 switch(meshDimRelToMaxExt)
5617 int nbCells(mesh->getNumberOfCells());
5619 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5625 int nbNodes(mesh->getNumberOfNodes());
5627 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5633 int nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
5635 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5640 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5647 * Sets the optional numbers of mesh entities of a given dimension.
5648 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5649 * \param [in] renumArr - the array of the numbers.
5650 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5651 * \throw If \a renumArr has an invalid size.
5652 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5654 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5656 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5658 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5659 switch(meshDimRelToMaxExt)
5663 int nbCells=mesh->getNumberOfCells();
5664 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5665 _num_cells=renumArr;
5670 int nbNodes=mesh->getNumberOfNodes();
5671 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5672 _num_nodes=renumArr;
5677 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5678 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5679 _num_faces=renumArr;
5683 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5686 renumArr->incrRef();
5690 * Sets the optional names of mesh entities of a given dimension.
5691 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5692 * \param [in] nameArr - the array of the names.
5693 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5694 * \throw If \a nameArr has an invalid size.
5696 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5698 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5700 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5701 switch(meshDimRelToMaxExt)
5705 int nbCells=mesh->getNumberOfCells();
5706 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5707 _names_cells=nameArr;
5712 int nbNodes=mesh->getNumberOfNodes();
5713 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5714 _names_nodes=nameArr;
5719 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5720 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5721 _names_cells=nameArr;
5724 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5731 * Adds a group of nodes to \a this mesh.
5732 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5733 * The ids should be sorted and different each other (MED file norm).
5735 * \warning this method can alter default "FAMILLE_ZERO" family.
5736 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5738 * \throw If the node coordinates array is not set.
5739 * \throw If \a ids == \c NULL.
5740 * \throw If \a ids->getName() == "".
5741 * \throw If \a ids does not respect the MED file norm.
5742 * \throw If a group with name \a ids->getName() already exists.
5744 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5750 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5752 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5753 * The ids should be sorted and different each other (MED file norm).
5755 * \warning this method can alter default "FAMILLE_ZERO" family.
5756 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5758 * \throw If the node coordinates array is not set.
5759 * \throw If \a ids == \c NULL.
5760 * \throw If \a ids->getName() == "".
5761 * \throw If \a ids does not respect the MED file norm.
5762 * \throw If a group with name \a ids->getName() already exists.
5764 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5766 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5767 addGroupUnderground(false,ids,fam);
5772 * Returns the family field for mesh entities of a given dimension.
5773 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5774 * \return const DataArrayInt * - the family field. It is an array of ids of families
5775 * each mesh entity belongs to. It can be \c NULL.
5776 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5778 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5780 switch(meshDimRelToMaxExt)
5789 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5794 * Returns the family field for mesh entities of a given dimension.
5795 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5796 * \return const DataArrayInt * - the family field. It is an array of ids of families
5797 * each mesh entity belongs to. It can be \c NULL.
5798 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5800 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5802 switch(meshDimRelToMaxExt)
5811 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5816 * Returns the optional numbers of mesh entities of a given dimension.
5817 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5818 * \return const DataArrayInt * - the array of the entity numbers.
5819 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5820 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5822 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5824 switch(meshDimRelToMaxExt)
5833 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5838 * Returns the optional numbers of mesh entities of a given dimension transformed using
5839 * DataArrayInt::invertArrayN2O2O2N().
5840 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5841 * \return const DataArrayInt * - the array of the entity numbers transformed using
5842 * DataArrayInt::invertArrayN2O2O2N().
5843 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5844 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5846 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5848 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5849 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5850 if(meshDimRelToMaxExt==0)
5852 if((const DataArrayInt *)_num_cells)
5855 int maxValue=_num_cells->getMaxValue(pos);
5856 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5857 return _rev_num_cells;
5860 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5864 if((const DataArrayInt *)_num_nodes)
5867 int maxValue=_num_nodes->getMaxValue(pos);
5868 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5869 return _rev_num_nodes;
5872 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5876 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5878 switch(meshDimRelToMaxExt)
5881 return _names_cells;
5883 return _names_nodes;
5885 return _names_faces;
5887 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5892 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5893 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5895 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5897 std::vector<int> ret(1);
5902 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5903 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5905 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5907 std::vector<int> ret(2);
5913 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5915 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5917 std::vector<int> ret;
5918 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5929 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5931 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5933 std::vector<int> ret;
5934 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5945 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5947 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5949 std::vector<int> ret;
5950 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5961 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5963 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5965 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5969 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5971 DataArrayInt *arr=_fam_nodes;
5973 arr->changeValue(oldId,newId);
5976 arr->changeValue(oldId,newId);
5979 arr->changeValue(oldId,newId);
5982 std::list< MCAuto<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5984 std::list< MCAuto<DataArrayInt> > ret;
5985 const DataArrayInt *da(_fam_nodes);
5987 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5990 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5993 { da->incrRef(); ret.push_back(MCAuto<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5997 void MEDFileStructuredMesh::deepCpyAttributes()
5999 if((const DataArrayInt*)_fam_nodes)
6000 _fam_nodes=_fam_nodes->deepCopy();
6001 if((const DataArrayInt*)_num_nodes)
6002 _num_nodes=_num_nodes->deepCopy();
6003 if((const DataArrayAsciiChar*)_names_nodes)
6004 _names_nodes=_names_nodes->deepCopy();
6005 if((const DataArrayInt*)_fam_cells)
6006 _fam_cells=_fam_cells->deepCopy();
6007 if((const DataArrayInt*)_num_cells)
6008 _num_cells=_num_cells->deepCopy();
6009 if((const DataArrayAsciiChar*)_names_cells)
6010 _names_cells=_names_cells->deepCopy();
6011 if((const DataArrayInt*)_fam_faces)
6012 _fam_faces=_fam_faces->deepCopy();
6013 if((const DataArrayInt*)_num_faces)
6014 _num_faces=_num_faces->deepCopy();
6015 if((const DataArrayAsciiChar*)_names_faces)
6016 _names_faces=_names_faces->deepCopy();
6017 if((const DataArrayInt*)_rev_num_nodes)
6018 _rev_num_nodes=_rev_num_nodes->deepCopy();
6019 if((const DataArrayInt*)_rev_num_cells)
6020 _rev_num_cells=_rev_num_cells->deepCopy();
6024 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
6026 * \return a pointer to cartesian mesh that need to be managed by the caller.
6027 * \warning the returned pointer has to be managed by the caller.
6031 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
6032 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
6033 * \param [in] renum - it must be \c false.
6034 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
6035 * delete using decrRef() as it is no more needed.
6037 MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
6041 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
6042 const MEDCouplingStructuredMesh *m(getStructuredMesh());
6043 switch(meshDimRelToMax)
6049 return const_cast<MEDCouplingStructuredMesh *>(m);
6054 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
6055 buildMinusOneImplicitPartIfNeeded();
6056 MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
6062 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
6066 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
6068 std::vector<int> ret;
6069 const DataArrayInt *famCells(_fam_cells),*famFaces(_fam_faces);
6070 if(famCells && famCells->presenceOfValue(ret))
6072 if(famFaces && famFaces->presenceOfValue(ret))
6077 std::vector<int> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
6079 std::vector<int> ret(getFamsNonEmptyLevels(fams));
6080 const DataArrayInt *famNodes(_fam_nodes);
6081 if(famNodes && famNodes->presenceOfValue(ret))
6087 * Returns number of mesh entities of a given relative dimension in \a this mesh.
6088 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
6089 * \return int - the number of entities.
6090 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
6092 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
6094 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6096 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
6097 switch(meshDimRelToMaxExt)
6100 return cmesh->getNumberOfCells();
6102 return cmesh->getNumberOfNodes();
6104 return cmesh->getNumberOfCellsOfSubLevelMesh();
6106 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
6110 int MEDFileStructuredMesh::getNumberOfNodes() const
6112 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6114 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6115 return cmesh->getNumberOfNodes();
6118 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
6120 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6122 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
6123 switch(meshDimRelToMaxExt)
6126 return cmesh->getNumberOfCells();
6128 return cmesh->getNumberOfCellsOfSubLevelMesh();
6130 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
6134 bool MEDFileStructuredMesh::hasImplicitPart() const
6140 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
6142 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
6144 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
6145 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6148 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
6149 if(cm.getReverseExtrudedType()!=gt)
6150 throw INTERP_KERNEL::Exception(MSG);
6151 buildImplicitPart();
6152 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
6156 if(gt!=zeFaceMesh->getCellModelEnum())
6157 throw INTERP_KERNEL::Exception(MSG);
6158 return zeFaceMesh->getNumberOfCells();
6162 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
6164 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
6166 buildImplicitPart();
6169 void MEDFileStructuredMesh::buildImplicitPart() const
6171 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
6173 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
6174 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
6177 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
6179 _faces_if_necessary=0;
6183 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
6184 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
6186 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
6188 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
6191 return _faces_if_necessary;
6194 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
6196 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
6198 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
6199 switch(meshDimRelToMax)
6203 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
6208 int mdim(cmesh->getMeshDimension());
6210 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
6211 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
6215 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
6219 int MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
6221 if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6224 return getNumberOfCellsAtLevel(0);
6227 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
6229 if(st.getNumberOfItems()!=1)
6230 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 !");
6231 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
6232 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
6233 if(getNumberOfNodes()!=(int)nodesFetched.size())
6234 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
6235 if(st[0].getPflName().empty())
6237 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
6240 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
6241 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
6242 int sz(nodesFetched.size());
6243 for(const int *work=arr->begin();work!=arr->end();work++)
6245 std::vector<int> conn;
6246 cmesh->getNodeIdsOfCell(*work,conn);
6247 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
6248 if(*it>=0 && *it<sz)
6249 nodesFetched[*it]=true;
6251 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
6255 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
6257 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
6261 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
6262 MCAuto<DataArrayInt>& famCells, MCAuto<DataArrayInt>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
6264 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6265 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
6267 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
6270 if(!mrs || mrs->isCellFamilyFieldReading())
6272 famCells=DataArrayInt::New();
6273 famCells->alloc(nbOfElt,1);
6274 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
6277 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6280 if(!mrs || mrs->isCellNumFieldReading())
6282 numCells=DataArrayInt::New();
6283 numCells->alloc(nbOfElt,1);
6284 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
6287 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
6290 if(!mrs || mrs->isCellNameFieldReading())
6292 namesCells=DataArrayAsciiChar::New();
6293 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6294 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
6295 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6300 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6302 setName(strm->getName());
6303 setDescription(strm->getDescription());
6304 setUnivName(strm->getUnivName());
6305 setIteration(strm->getIteration());
6306 setOrder(strm->getOrder());
6307 setTimeValue(strm->getTime());
6308 setTimeUnit(strm->getTimeUnit());
6309 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
6310 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
6311 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
6314 if(!mrs || mrs->isNodeFamilyFieldReading())
6316 int nbNodes(getNumberOfNodes());
6318 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
6319 _fam_nodes=DataArrayInt::New();
6320 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
6321 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...
6322 _fam_nodes->fillWithZero();
6323 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
6326 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
6329 if(!mrs || mrs->isNodeNumFieldReading())
6331 _num_nodes=DataArrayInt::New();
6332 _num_nodes->alloc(nbOfElt,1);
6333 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
6336 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
6339 if(!mrs || mrs->isNodeNameFieldReading())
6341 _names_nodes=DataArrayAsciiChar::New();
6342 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
6343 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
6344 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
6347 int meshDim(getStructuredMesh()->getMeshDimension());
6348 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
6350 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
6353 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
6355 int meshDim(getStructuredMesh()->getMeshDimension());
6356 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
6358 if((const DataArrayInt *)_fam_cells)
6359 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
6360 if((const DataArrayInt *)_fam_faces)
6361 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
6362 if((const DataArrayInt *)_fam_nodes)
6363 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
6364 if((const DataArrayInt *)_num_cells)
6365 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
6366 if((const DataArrayInt *)_num_faces)
6367 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
6368 if((const DataArrayInt *)_num_nodes)
6369 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
6370 if((const DataArrayAsciiChar *)_names_cells)
6372 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
6374 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
6375 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6376 throw INTERP_KERNEL::Exception(oss.str().c_str());
6378 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
6380 if((const DataArrayAsciiChar *)_names_faces)
6382 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
6384 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
6385 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
6386 throw INTERP_KERNEL::Exception(oss.str().c_str());
6388 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
6390 if((const DataArrayAsciiChar *)_names_nodes)
6392 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
6394 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
6395 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
6396 throw INTERP_KERNEL::Exception(oss.str().c_str());
6398 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
6401 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
6405 * Returns an empty instance of MEDFileCMesh.
6406 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6407 * mesh using decrRef() as it is no more needed.
6409 MEDFileCMesh *MEDFileCMesh::New()
6411 return new MEDFileCMesh;
6415 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6416 * file. The first mesh in the file is loaded.
6417 * \param [in] fileName - the name of MED file to read.
6418 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6419 * mesh using decrRef() as it is no more needed.
6420 * \throw If the file is not readable.
6421 * \throw If there is no meshes in the file.
6422 * \throw If the mesh in the file is not a Cartesian one.
6424 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6426 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6427 return New(fid,mrs);
6430 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6432 return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
6436 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
6437 * file. The mesh to load is specified by its name and numbers of a time step and an
6439 * \param [in] fileName - the name of MED file to read.
6440 * \param [in] mName - the name of the mesh to read.
6441 * \param [in] dt - the number of a time step.
6442 * \param [in] it - the number of an iteration.
6443 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
6444 * mesh using decrRef() as it is no more needed.
6445 * \throw If the file is not readable.
6446 * \throw If there is no mesh with given attributes in the file.
6447 * \throw If the mesh in the file is not a Cartesian one.
6449 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6451 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6452 return New(fid,mName,dt,it,mrs);
6455 MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6457 return new MEDFileCMesh(fid,mName,dt,it,mrs);
6460 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
6462 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6465 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
6467 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6468 ret.push_back((const MEDCouplingCMesh *)_cmesh);
6473 * Returns the dimension on cells in \a this mesh.
6474 * \return int - the mesh dimension.
6475 * \throw If there are no cells in this mesh.
6477 int MEDFileCMesh::getMeshDimension() const
6479 if(!((const MEDCouplingCMesh*)_cmesh))
6480 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6481 return _cmesh->getMeshDimension();
6485 * Returns the dimension on nodes in \a this mesh.
6486 * \return int - the space dimension.
6487 * \throw If there are no cells in this mesh.
6489 int MEDFileCMesh::getSpaceDimension() const
6491 if(!((const MEDCouplingCMesh*)_cmesh))
6492 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
6493 return _cmesh->getSpaceDimension();
6497 * Returns a string describing \a this mesh.
6498 * \return std::string - the mesh information string.
6500 std::string MEDFileCMesh::simpleRepr() const
6502 return MEDFileStructuredMesh::simpleRepr();
6506 * Returns a full textual description of \a this mesh.
6507 * \return std::string - the string holding the mesh description.
6509 std::string MEDFileCMesh::advancedRepr() const
6511 return simpleRepr();
6514 MEDFileCMesh *MEDFileCMesh::shallowCpy() const
6516 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6520 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
6522 return new MEDFileCMesh;
6525 MEDFileCMesh *MEDFileCMesh::deepCopy() const
6527 MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
6528 ret->deepCpyEquivalences(*this);
6529 if((const MEDCouplingCMesh*)_cmesh)
6530 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
6531 ret->deepCpyAttributes();
6536 * Checks if \a this and another mesh are equal.
6537 * \param [in] other - the mesh to compare with.
6538 * \param [in] eps - a precision used to compare real values.
6539 * \param [in,out] what - the string returning description of unequal data.
6540 * \return bool - \c true if the meshes are equal, \c false, else.
6542 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6544 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6546 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
6549 what="Mesh types differ ! This is cartesian and other is NOT !";
6552 clearNonDiscrAttributes();
6553 otherC->clearNonDiscrAttributes();
6554 const MEDCouplingCMesh *coo1=_cmesh;
6555 const MEDCouplingCMesh *coo2=otherC->_cmesh;
6556 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6558 what="Mismatch of cartesian meshes ! One is defined and not other !";
6563 bool ret=coo1->isEqual(coo2,eps);
6566 what="cartesian meshes differ !";
6574 * Clears redundant attributes of incorporated data arrays.
6576 void MEDFileCMesh::clearNonDiscrAttributes() const
6578 MEDFileStructuredMesh::clearNonDiscrAttributes();
6579 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6582 MEDFileCMesh::MEDFileCMesh()
6586 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6589 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6591 catch(INTERP_KERNEL::Exception& e)
6596 void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6598 MEDCoupling::MEDCouplingMeshType meshType;
6601 MEDCoupling::MEDCouplingAxisType axType;
6602 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6603 if(meshType!=CARTESIAN)
6605 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6606 throw INTERP_KERNEL::Exception(oss.str().c_str());
6608 MEDFileCMeshL2 loaderl2;
6609 loaderl2.loadAll(fid,mid,mName,dt,it);
6610 setAxisType(axType);
6611 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6614 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6618 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6619 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6621 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6623 synchronizeTinyInfoOnLeaves();
6627 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6629 synchronizeTinyInfoOnLeaves();
6634 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6635 * \param [in] m - the new MEDCouplingCMesh to refer to.
6636 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6639 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6641 dealWithTinyInfo(m);
6647 MEDFileMesh *MEDFileCMesh::cartesianize() const
6649 if(getAxisType()==AX_CART)
6652 return const_cast<MEDFileCMesh *>(this);
6656 const MEDCouplingCMesh *cmesh(getMesh());
6658 throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6659 MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
6660 MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
6661 clmesh->setCoords(coords);
6662 MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
6663 ret->MEDFileStructuredMesh::operator=(*this);
6664 ret->setMesh(clmesh);
6665 ret->setAxisType(AX_CART);
6670 void MEDFileCMesh::writeMeshLL(med_idt fid) const
6672 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6673 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6674 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6675 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6676 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6677 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6678 int spaceDim(_cmesh->getSpaceDimension());
6679 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6680 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6681 for(int i=0;i<spaceDim;i++)
6683 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6685 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6686 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
6687 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
6689 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6691 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6692 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
6693 for(int i=0;i<spaceDim;i++)
6695 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6696 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6699 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6700 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6703 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6705 const MEDCouplingCMesh *cmesh=_cmesh;
6708 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6709 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6710 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6711 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6714 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6716 return new MEDFileCurveLinearMesh;
6719 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
6721 return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
6724 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6726 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6727 return New(fid,mrs);
6730 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6732 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6733 return New(fid,mName,dt,it,mrs);
6736 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6738 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6741 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6743 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6746 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6748 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6749 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6753 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
6755 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6759 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6761 return new MEDFileCurveLinearMesh;
6764 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
6766 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6767 ret->deepCpyEquivalences(*this);
6768 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6769 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
6770 ret->deepCpyAttributes();
6774 int MEDFileCurveLinearMesh::getMeshDimension() const
6776 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6777 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6778 return _clmesh->getMeshDimension();
6781 std::string MEDFileCurveLinearMesh::simpleRepr() const
6783 return MEDFileStructuredMesh::simpleRepr();
6786 std::string MEDFileCurveLinearMesh::advancedRepr() const
6788 return simpleRepr();
6791 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6793 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6795 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6798 what="Mesh types differ ! This is curve linear and other is NOT !";
6801 clearNonDiscrAttributes();
6802 otherC->clearNonDiscrAttributes();
6803 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6804 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6805 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6807 what="Mismatch of curve linear meshes ! One is defined and not other !";
6812 bool ret=coo1->isEqual(coo2,eps);
6815 what="curve linear meshes differ !";
6822 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6824 MEDFileStructuredMesh::clearNonDiscrAttributes();
6825 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6828 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6830 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6833 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6834 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6835 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6836 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6839 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6841 synchronizeTinyInfoOnLeaves();
6845 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6847 dealWithTinyInfo(m);
6853 MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
6855 if(getAxisType()==AX_CART)
6858 return const_cast<MEDFileCurveLinearMesh *>(this);
6862 const MEDCouplingCurveLinearMesh *mesh(getMesh());
6864 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
6865 const DataArrayDouble *coords(mesh->getCoords());
6867 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
6868 MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
6869 MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
6870 MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
6871 mesh2->setCoords(coordsCart);
6872 ret->setMesh(mesh2);
6873 ret->setAxisType(AX_CART);
6878 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6880 synchronizeTinyInfoOnLeaves();
6884 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6888 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6891 loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
6893 catch(INTERP_KERNEL::Exception& e)
6898 void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
6900 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6901 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6902 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6903 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6904 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6905 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6906 int spaceDim=_clmesh->getSpaceDimension();
6907 int meshDim=_clmesh->getMeshDimension();
6908 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6909 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6910 const DataArrayDouble *coords=_clmesh->getCoords();
6912 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
6913 for(int i=0;i<spaceDim;i++)
6915 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6917 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6918 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
6919 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
6921 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
6923 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6924 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6925 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6926 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6928 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6930 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6931 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6934 void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6936 MEDCoupling::MEDCouplingMeshType meshType;
6939 MEDCoupling::MEDCouplingAxisType axType;
6940 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit);
6941 setAxisType(axType);
6942 if(meshType!=CURVE_LINEAR)
6944 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6945 throw INTERP_KERNEL::Exception(oss.str().c_str());
6947 MEDFileCLMeshL2 loaderl2;
6948 loaderl2.loadAll(fid,mid,mName,dt,it);
6949 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6952 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6955 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6957 return new MEDFileMeshMultiTS;
6960 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
6962 return new MEDFileMeshMultiTS(fid);
6965 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6967 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6971 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
6973 return new MEDFileMeshMultiTS(fid,mName);
6976 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6978 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
6979 return New(fid,mName);
6982 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
6984 MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
6985 std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6987 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6988 if((const MEDFileMesh *)*it)
6989 meshOneTs[i]=(*it)->deepCopy();
6990 ret->_mesh_one_ts=meshOneTs;
6994 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6996 return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
6999 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
7001 std::vector<const BigMemoryObject *> ret;
7002 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7003 ret.push_back((const MEDFileMesh *)*it);
7007 std::string MEDFileMeshMultiTS::getName() const
7009 if(_mesh_one_ts.empty())
7010 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
7011 return _mesh_one_ts[0]->getName();
7014 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
7016 std::string oldName(getName());
7017 std::vector< std::pair<std::string,std::string> > v(1);
7018 v[0].first=oldName; v[0].second=newMeshName;
7022 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7025 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7027 MEDFileMesh *cur(*it);
7029 ret=cur->changeNames(modifTab) || ret;
7034 void MEDFileMeshMultiTS::cartesianizeMe()
7036 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7038 MEDFileMesh *cur(*it);
7041 MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
7047 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
7049 if(_mesh_one_ts.empty())
7050 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
7051 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
7054 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
7057 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
7058 _mesh_one_ts.resize(1);
7059 mesh1TimeStep->incrRef();
7060 //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
7061 _mesh_one_ts[0]=mesh1TimeStep;
7064 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
7066 if ( MEDFileMesh* m = getOneTimeStep() )
7067 return m->getJoints();
7072 * \brief Set Joints that are common to all time-stamps
7074 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
7076 for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7078 (*it)->setJoints( joints );
7082 void MEDFileMeshMultiTS::writeLL(med_idt fid) const
7084 MEDFileJoints *joints(getJoints());
7085 bool jointsWritten(false);
7087 for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
7089 if ( jointsWritten )
7090 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
7092 jointsWritten = true;
7094 (*it)->copyOptionsFrom(*this);
7095 (*it)->writeLL(fid);
7098 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
7101 void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
7103 MEDFileJoints *joints(0);
7104 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
7106 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
7107 joints = getOneTimeStep()->getJoints();
7109 _mesh_one_ts.clear(); //for the moment to be improved
7110 _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
7113 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
7117 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
7120 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7123 std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
7124 throw INTERP_KERNEL::Exception(oss.str().c_str());
7127 MEDCoupling::MEDCouplingMeshType meshType;
7129 MEDCoupling::MEDCouplingAxisType dummy3;
7130 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
7131 loadFromFile(fid,ms.front());
7133 catch(INTERP_KERNEL::Exception& e)
7138 MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
7141 loadFromFile(fid,mName);
7143 catch(INTERP_KERNEL::Exception& e)
7148 MEDFileMeshes *MEDFileMeshes::New()
7150 return new MEDFileMeshes;
7153 MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
7155 return new MEDFileMeshes(fid);
7158 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
7160 MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
7164 void MEDFileMeshes::writeLL(med_idt fid) const
7166 checkConsistencyLight();
7167 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7169 (*it)->copyOptionsFrom(*this);
7170 (*it)->writeLL(fid);
7174 // MEDFileMeshes::writ checkConsistencyLight();
7176 int MEDFileMeshes::getNumberOfMeshes() const
7178 return _meshes.size();
7181 MEDFileMeshesIterator *MEDFileMeshes::iterator()
7183 return new MEDFileMeshesIterator(this);
7186 /** Return a borrowed reference (caller is not responsible) */
7187 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
7189 if(i<0 || i>=(int)_meshes.size())
7191 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
7192 throw INTERP_KERNEL::Exception(oss.str().c_str());
7194 return _meshes[i]->getOneTimeStep();
7197 /** Return a borrowed reference (caller is not responsible) */
7198 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
7200 std::vector<std::string> ms=getMeshesNames();
7201 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
7204 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
7205 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
7206 throw INTERP_KERNEL::Exception(oss.str().c_str());
7208 return getMeshAtPos((int)std::distance(ms.begin(),it));
7211 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
7213 std::vector<std::string> ret(_meshes.size());
7215 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7217 const MEDFileMeshMultiTS *f=(*it);
7220 ret[i]=f->getName();
7224 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
7225 throw INTERP_KERNEL::Exception(oss.str().c_str());
7231 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
7234 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7236 MEDFileMeshMultiTS *cur(*it);
7238 ret=cur->changeNames(modifTab) || ret;
7243 void MEDFileMeshes::cartesianizeMe()
7245 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
7247 MEDFileMeshMultiTS *cur(*it);
7249 cur->cartesianizeMe();
7253 void MEDFileMeshes::resize(int newSize)
7255 _meshes.resize(newSize);
7258 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
7261 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
7262 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7263 elt->setOneTimeStep(mesh);
7264 _meshes.push_back(elt);
7267 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
7270 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
7271 if(i>=(int)_meshes.size())
7272 _meshes.resize(i+1);
7273 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
7274 elt->setOneTimeStep(mesh);
7278 void MEDFileMeshes::destroyMeshAtPos(int i)
7280 if(i<0 || i>=(int)_meshes.size())
7282 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
7283 throw INTERP_KERNEL::Exception(oss.str().c_str());
7285 _meshes.erase(_meshes.begin()+i);
7288 void MEDFileMeshes::loadFromFile(med_idt fid)
7290 std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
7292 _meshes.resize(ms.size());
7293 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
7294 _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
7297 MEDFileMeshes::MEDFileMeshes()
7301 MEDFileMeshes::MEDFileMeshes(med_idt fid)
7306 catch(INTERP_KERNEL::Exception& /*e*/)
7310 MEDFileMeshes *MEDFileMeshes::deepCopy() const
7312 std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
7314 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7315 if((const MEDFileMeshMultiTS *)*it)
7316 meshes[i]=(*it)->deepCopy();
7317 MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
7318 ret->_meshes=meshes;
7322 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
7324 return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
7327 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
7329 std::vector<const BigMemoryObject *> ret;
7330 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
7331 ret.push_back((const MEDFileMeshMultiTS *)*it);
7335 std::string MEDFileMeshes::simpleRepr() const
7337 std::ostringstream oss;
7338 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
7339 simpleReprWithoutHeader(oss);
7343 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
7345 int nbOfMeshes=getNumberOfMeshes();
7346 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
7347 std::vector<std::string> mns=getMeshesNames();
7348 for(int i=0;i<nbOfMeshes;i++)
7349 oss << " - #" << i << " \"" << mns[i] << "\"\n";
7352 void MEDFileMeshes::checkConsistencyLight() const
7354 static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
7356 std::set<std::string> s;
7357 for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
7359 const MEDFileMeshMultiTS *elt=(*it);
7362 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
7363 throw INTERP_KERNEL::Exception(oss.str().c_str());
7365 std::size_t sz=s.size();
7366 s.insert(std::string((*it)->getName()));
7369 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
7370 throw INTERP_KERNEL::Exception(oss.str().c_str());
7375 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
7380 _nb_iter=ms->getNumberOfMeshes();
7384 MEDFileMeshesIterator::~MEDFileMeshesIterator()
7388 MEDFileMesh *MEDFileMeshesIterator::nextt()
7390 if(_iter_id<_nb_iter)
7392 MEDFileMeshes *ms(_ms);
7394 return ms->getMeshAtPos(_iter_id++);