1 // Copyright (C) 2007-2015 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 "MEDLoaderBase.hxx"
28 #include "MEDCouplingUMesh.hxx"
30 #include "InterpKernelAutoPtr.hxx"
35 extern med_geometry_type typmai3[34];
37 using namespace ParaMEDMEM;
39 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
41 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
45 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
47 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
48 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
50 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
51 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
52 ret+=(*it2).capacity();
54 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
55 ret+=(*it).first.capacity()+sizeof(int);
59 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
61 return std::vector<const BigMemoryObject *>();
65 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
66 * file. The first mesh in the file is loaded.
67 * \param [in] fileName - the name of MED file to read.
68 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
69 * mesh using decrRef() as it is no more needed.
70 * \throw If the file is not readable.
71 * \throw If there is no meshes in the file.
72 * \throw If the mesh in the file is of a not supported type.
74 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
76 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
79 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
80 throw INTERP_KERNEL::Exception(oss.str().c_str());
82 MEDFileUtilities::CheckFileForRead(fileName);
83 ParaMEDMEM::MEDCouplingMeshType meshType;
84 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
87 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
92 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
93 ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
94 ret->loadJointsFromFile(fid);
95 return (MEDFileUMesh *)ret.retn();
99 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
100 ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
101 ret->loadJointsFromFile(fid);
102 return (MEDFileCMesh *)ret.retn();
106 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
107 ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
108 ret->loadJointsFromFile(fid);
109 return (MEDFileCurveLinearMesh *)ret.retn();
113 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
114 throw INTERP_KERNEL::Exception(oss.str().c_str());
120 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
121 * file. The mesh to load is specified by its name and numbers of a time step and an
123 * \param [in] fileName - the name of MED file to read.
124 * \param [in] mName - the name of the mesh to read.
125 * \param [in] dt - the number of a time step.
126 * \param [in] it - the number of an iteration.
127 * \param [in] joints - the sub-domain joints to use instead of those that can be read
128 * from the MED file. Usually this joints are those just read by another iteration
129 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
130 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
131 * mesh using decrRef() as it is no more needed.
132 * \throw If the file is not readable.
133 * \throw If there is no mesh with given attributes in the file.
134 * \throw If the mesh in the file is of a not supported type.
136 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
138 MEDFileUtilities::CheckFileForRead(fileName);
139 ParaMEDMEM::MEDCouplingMeshType meshType;
140 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
143 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
148 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
149 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
150 ret->loadJointsFromFile(fid,joints);
151 return (MEDFileUMesh *)ret.retn();
155 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
156 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
157 ret->loadJointsFromFile(fid,joints);
158 return (MEDFileCMesh *)ret.retn();
162 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
163 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
164 ret->loadJointsFromFile(fid,joints);
165 return (MEDFileCurveLinearMesh *)ret.retn();
169 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
170 throw INTERP_KERNEL::Exception(oss.str().c_str());
176 * Writes \a this mesh into an open MED file specified by its descriptor.
177 * \param [in] fid - the MED file descriptor.
178 * \throw If the mesh name is not set.
179 * \throw If the file is open for reading only.
180 * \throw If the writing mode == 1 and the same data is present in an existing file.
182 void MEDFileMesh::write(med_idt fid) const
185 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
187 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
192 * Writes \a this mesh into a MED file specified by its name.
193 * \param [in] fileName - the MED file name.
194 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
195 * - 2 - erase; an existing file is removed.
196 * - 1 - append; same data should not be present in an existing file.
197 * - 0 - overwrite; same data present in an existing file is overwritten.
198 * \throw If the mesh name is not set.
199 * \throw If \a mode == 1 and the same data is present in an existing file.
201 void MEDFileMesh::write(const std::string& fileName, int mode) const
203 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
204 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
205 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
206 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
211 * Checks if \a this and another mesh are equal.
212 * \param [in] other - the mesh to compare with.
213 * \param [in] eps - a precision used to compare real values.
214 * \param [in,out] what - the string returning description of unequal data.
215 * \return bool - \c true if the meshes are equal, \c false, else.
217 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
219 if(_order!=other->_order)
221 what="Orders differ !";
224 if(_iteration!=other->_iteration)
226 what="Iterations differ !";
229 if(fabs(_time-other->_time)>eps)
231 what="Time values differ !";
234 if(_dt_unit!=other->_dt_unit)
236 what="Time units differ !";
239 if(_name!=other->_name)
241 what="Names differ !";
244 //univ_name has been ignored -> not a bug because it is a mutable attribute
245 if(_desc_name!=other->_desc_name)
247 what="Description names differ !";
250 if(!areGrpsEqual(other,what))
252 if(!areFamsEqual(other,what))
257 void MEDFileMesh::setName(const std::string& name)
263 * Clears redundant attributes of incorporated data arrays.
265 void MEDFileMesh::clearNonDiscrAttributes() const
270 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
272 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
274 if((*it).first==_name)
284 * Copies data on groups and families from another mesh.
285 * \param [in] other - the mesh to copy the data from.
287 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
289 _groups=other._groups;
290 _families=other._families;
295 * This method clear all the groups in the map.
296 * So this method does not operate at all on arrays.
297 * So this method can lead to orphan families.
299 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
301 void MEDFileMesh::clearGrpMap()
307 * This method clear all the families in the map.
308 * So this method does not operate at all on arrays.
309 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
311 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
313 void MEDFileMesh::clearFamMap()
319 * This method clear all the families and groups in the map.
320 * So this method does not operate at all on arrays.
321 * As all groups and families entry will be removed after
322 * 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.
324 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
326 void MEDFileMesh::clearFamGrpMaps()
333 * Returns names of families constituting a group.
334 * \param [in] name - the name of the group of interest.
335 * \return std::vector<std::string> - a sequence of names of the families.
336 * \throw If the name of a nonexistent group is specified.
338 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
340 std::string oname(name);
341 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
342 if(it==_groups.end())
344 std::vector<std::string> grps=getGroupsNames();
345 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
346 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
347 throw INTERP_KERNEL::Exception(oss.str().c_str());
353 * Returns names of families constituting some groups.
354 * \param [in] grps - a sequence of names of groups of interest.
355 * \return std::vector<std::string> - a sequence of names of the families.
356 * \throw If a name of a nonexistent group is present in \a grps.
358 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
360 std::set<std::string> fams;
361 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
363 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
364 if(it2==_groups.end())
366 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
367 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
368 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
369 throw INTERP_KERNEL::Exception(oss.str().c_str());
371 fams.insert((*it2).second.begin(),(*it2).second.end());
373 std::vector<std::string> fams2(fams.begin(),fams.end());
378 * Returns ids of families constituting a group.
379 * \param [in] name - the name of the group of interest.
380 * \return std::vector<int> - sequence of ids of the families.
381 * \throw If the name of a nonexistent group is specified.
383 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
385 std::string oname(name);
386 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
387 std::vector<std::string> grps=getGroupsNames();
388 if(it==_groups.end())
390 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
391 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
392 throw INTERP_KERNEL::Exception(oss.str().c_str());
394 return getFamiliesIds((*it).second);
398 * Sets names of families constituting a group. If data on families of this group is
399 * already present, it is overwritten. Every family in \a fams is checked, and if a
400 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
401 * \param [in] name - the name of the group of interest.
402 * \param [in] fams - a sequence of names of families constituting the group.
404 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
406 std::string oname(name);
408 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
410 std::map<std::string,int>::iterator it2=_families.find(*it1);
411 if(it2==_families.end())
417 * Sets families constituting a group. The families are specified by their ids.
418 * If a family name is not found by its id, an exception is thrown.
419 * If several families have same id, the first one in lexical order is taken.
420 * \param [in] name - the name of the group of interest.
421 * \param [in] famIds - a sequence of ids of families constituting the group.
422 * \throw If a family name is not found by its id.
424 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
426 std::string oname(name);
427 std::vector<std::string> fams(famIds.size());
429 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
431 std::string name2=getFamilyNameGivenId(*it1);
438 * Returns names of groups including a given family.
439 * \param [in] name - the name of the family of interest.
440 * \return std::vector<std::string> - a sequence of names of groups including the family.
442 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
444 std::vector<std::string> ret;
445 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
447 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
450 ret.push_back((*it1).first);
458 * Adds an existing family to groups.
459 * \param [in] famName - a name of family to add to \a grps.
460 * \param [in] grps - a sequence of group names to add the family in.
461 * \throw If a family named \a famName not yet exists.
463 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
465 std::string fName(famName);
466 const std::map<std::string,int>::const_iterator it=_families.find(fName);
467 if(it==_families.end())
469 std::vector<std::string> fams=getFamiliesNames();
470 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
471 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
472 throw INTERP_KERNEL::Exception(oss.str().c_str());
474 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
476 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
477 if(it2!=_groups.end())
478 (*it2).second.push_back(fName);
481 std::vector<std::string> grps2(1,fName);
488 * Returns names of all groups of \a this mesh.
489 * \return std::vector<std::string> - a sequence of group names.
491 std::vector<std::string> MEDFileMesh::getGroupsNames() const
493 std::vector<std::string> ret(_groups.size());
495 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
501 * Returns names of all families of \a this mesh.
502 * \return std::vector<std::string> - a sequence of family names.
504 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
506 std::vector<std::string> ret(_families.size());
508 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
514 * Changes a name of every family, included in one group only, to be same as the group name.
515 * \throw If there are families with equal names in \a this mesh.
517 void MEDFileMesh::assignFamilyNameWithGroupName()
519 std::map<std::string, std::vector<std::string> > groups(_groups);
520 std::map<std::string,int> newFams;
521 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
523 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
524 if(grps.size()==1 && groups[grps[0]].size()==1)
526 if(newFams.find(grps[0])!=newFams.end())
528 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
529 throw INTERP_KERNEL::Exception(oss.str().c_str());
531 newFams[grps[0]]=(*it).second;
532 std::vector<std::string>& grps2=groups[grps[0]];
533 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
538 if(newFams.find((*it).first)!=newFams.end())
540 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
541 throw INTERP_KERNEL::Exception(oss.str().c_str());
543 newFams[(*it).first]=(*it).second;
551 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
553 * \return the removed groups.
555 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
557 std::vector<std::string> ret;
558 std::map<std::string, std::vector<std::string> > newGrps;
559 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
561 if((*it).second.empty())
562 ret.push_back((*it).first);
564 newGrps[(*it).first]=(*it).second;
572 * Removes a group from \a this mesh.
573 * \param [in] name - the name of the group to remove.
574 * \throw If no group with such a \a name exists.
576 void MEDFileMesh::removeGroup(const std::string& name)
578 std::string oname(name);
579 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
580 std::vector<std::string> grps=getGroupsNames();
581 if(it==_groups.end())
583 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
584 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
585 throw INTERP_KERNEL::Exception(oss.str().c_str());
591 * Removes a family from \a this mesh.
592 * \param [in] name - the name of the family to remove.
593 * \throw If no family with such a \a name exists.
595 void MEDFileMesh::removeFamily(const std::string& name)
597 std::string oname(name);
598 std::map<std::string, int >::iterator it=_families.find(oname);
599 std::vector<std::string> fams=getFamiliesNames();
600 if(it==_families.end())
602 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
603 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
604 throw INTERP_KERNEL::Exception(oss.str().c_str());
607 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
609 std::vector<std::string>& v=(*it3).second;
610 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
617 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
618 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
619 * family field whatever its level. This method also suppresses the orphan families.
621 * \return - The list of removed groups names.
623 * \sa MEDFileMesh::removeOrphanFamilies.
625 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
627 removeOrphanFamilies();
628 return removeEmptyGroups();
632 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
633 * 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.
635 * \return - The list of removed families names.
636 * \sa MEDFileMesh::removeOrphanGroups.
638 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
640 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
641 std::vector<std::string> ret;
642 if(!((DataArrayInt*)allFamIdsInUse))
644 ret=getFamiliesNames();
645 _families.clear(); _groups.clear();
648 std::map<std::string,int> famMap;
649 std::map<std::string, std::vector<std::string> > grps(_groups);
650 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
652 if(allFamIdsInUse->presenceOfValue((*it).second))
653 famMap[(*it).first]=(*it).second;
656 ret.push_back((*it).first);
657 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
658 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
660 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
661 std::vector<std::string>& famv=(*it3).second;
662 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
668 { _families=famMap; _groups=grps; }
673 * 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
674 * this family is orphan or not.
676 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
678 void MEDFileMesh::removeFamiliesReferedByNoGroups()
680 std::map<std::string,int> fams;
681 std::set<std::string> sfams;
682 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
683 sfams.insert((*it).first);
684 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
685 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
687 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
688 if(*it!=DFT_FAM_NAME)
689 _families.erase(*it);
693 * 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
694 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
695 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
697 * \sa MEDFileMesh::removeOrphanFamilies
699 void MEDFileMesh::rearrangeFamilies()
701 checkOrphanFamilyZero();
702 removeFamiliesReferedByNoGroups();
704 std::vector<int> levels(getNonEmptyLevelsExt());
705 std::set<int> idsRefed;
706 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
707 idsRefed.insert((*it).second);
708 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
710 const DataArrayInt *fams(0);
713 fams=getFamilyFieldAtLevel(*it);
715 catch(INTERP_KERNEL::Exception& e) { }
718 std::vector<bool> v(fams->getNumberOfTuples(),false);
719 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
720 fams->switchOnTupleEqualTo(*pt,v);
721 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
722 if(!unfetchedIds->empty())
724 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
725 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
726 setFamilyFieldArr(*it,newFams);
729 removeOrphanFamilies();
733 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
735 void MEDFileMesh::checkOrphanFamilyZero() const
737 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
739 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
741 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
742 throw INTERP_KERNEL::Exception(oss.str().c_str());
748 * Renames a group in \a this mesh.
749 * \param [in] oldName - a current name of the group to rename.
750 * \param [in] newName - a new group name.
751 * \throw If no group named \a oldName exists in \a this mesh.
752 * \throw If a group named \a newName already exists.
754 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
756 std::string oname(oldName);
757 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
758 std::vector<std::string> grps=getGroupsNames();
759 if(it==_groups.end())
761 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
762 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
763 throw INTERP_KERNEL::Exception(oss.str().c_str());
765 std::string nname(newName);
766 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
767 if(it2!=_groups.end())
769 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
770 throw INTERP_KERNEL::Exception(oss.str().c_str());
772 std::vector<std::string> cpy=(*it).second;
774 _groups[newName]=cpy;
778 * Changes an id of a family in \a this mesh.
779 * This method calls changeFamilyIdArr().
780 * \param [in] oldId - a current id of the family.
781 * \param [in] newId - a new family id.
783 void MEDFileMesh::changeFamilyId(int oldId, int newId)
785 changeFamilyIdArr(oldId,newId);
786 std::map<std::string,int> fam2;
787 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
789 if((*it).second==oldId)
790 fam2[(*it).first]=newId;
792 fam2[(*it).first]=(*it).second;
798 * Renames a family in \a this mesh.
799 * \param [in] oldName - a current name of the family to rename.
800 * \param [in] newName - a new family name.
801 * \throw If no family named \a oldName exists in \a this mesh.
802 * \throw If a family named \a newName already exists.
804 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
806 std::string oname(oldName);
807 std::map<std::string, int >::iterator it=_families.find(oname);
808 std::vector<std::string> fams=getFamiliesNames();
809 if(it==_families.end())
811 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
812 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
813 throw INTERP_KERNEL::Exception(oss.str().c_str());
815 std::string nname(newName);
816 std::map<std::string, int >::iterator it2=_families.find(nname);
817 if(it2!=_families.end())
819 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
820 throw INTERP_KERNEL::Exception(oss.str().c_str());
822 int cpy=(*it).second;
824 _families[newName]=cpy;
825 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
827 std::vector<std::string>& v=(*it3).second;
828 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
835 * Checks if \a this and another mesh contains the same families.
836 * \param [in] other - the mesh to compare with \a this one.
837 * \param [in,out] what - an unused parameter.
838 * \return bool - \c true if number of families and their ids are the same in the two
839 * meshes. Families with the id == \c 0 are not considered.
841 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
843 if(_families==other->_families)
845 std::map<std::string,int> fam0;
846 std::map<std::string,int> fam1;
847 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
849 fam0[(*it).first]=(*it).second;
850 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
852 fam1[(*it).first]=(*it).second;
857 * Checks if \a this and another mesh contains the same groups.
858 * \param [in] other - the mesh to compare with \a this one.
859 * \param [in,out] what - a string describing a difference of groups of the two meshes
860 * in case if this method returns \c false.
861 * \return bool - \c true if number of groups and families constituting them are the
862 * same in the two meshes.
864 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
866 if(_groups==other->_groups)
869 std::size_t sz=_groups.size();
870 if(sz!=other->_groups.size())
872 what="Groups differ because not same number !\n";
877 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
878 for(std::size_t i=0;i<sz && ret;i++,it1++)
880 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
881 if(it2!=other->_groups.end())
883 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
884 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
890 what="A group in first mesh exists not in other !\n";
896 std::ostringstream oss; oss << "Groups description differs :\n";
897 oss << "First group description :\n";
898 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
900 oss << " Group \"" << (*it).first << "\" on following families :\n";
901 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
902 oss << " \"" << *it2 << "\n";
904 oss << "Second group description :\n";
905 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
907 oss << " Group \"" << (*it).first << "\" on following families :\n";
908 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
909 oss << " \"" << *it2 << "\n";
917 * Checks if a group with a given name exists in \a this mesh.
918 * \param [in] groupName - the group name.
919 * \return bool - \c true the group \a groupName exists in \a this mesh.
921 bool MEDFileMesh::existsGroup(const std::string& groupName) const
923 std::string grpName(groupName);
924 return _groups.find(grpName)!=_groups.end();
928 * Checks if a family with a given id exists in \a this mesh.
929 * \param [in] famId - the family id.
930 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
932 bool MEDFileMesh::existsFamily(int famId) const
934 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
935 if((*it2).second==famId)
941 * Checks if a family with a given name exists in \a this mesh.
942 * \param [in] familyName - the family name.
943 * \return bool - \c true the family \a familyName exists in \a this mesh.
945 bool MEDFileMesh::existsFamily(const std::string& familyName) const
947 std::string fname(familyName);
948 return _families.find(fname)!=_families.end();
952 * Sets an id of a family.
953 * \param [in] familyName - the family name.
954 * \param [in] id - a new id of the family.
956 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
958 std::string fname(familyName);
962 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
964 std::string fname(familyName);
965 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
968 if((*it).first!=familyName)
970 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
971 throw INTERP_KERNEL::Exception(oss.str().c_str());
978 * Adds a family to \a this mesh.
979 * \param [in] familyName - a name of the family.
980 * \param [in] famId - an id of the family.
981 * \throw If a family with the same name or id already exists in \a this mesh.
983 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
985 std::string fname(familyName);
986 std::map<std::string,int>::const_iterator it=_families.find(fname);
987 if(it==_families.end())
989 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
990 if((*it2).second==famId)
992 std::ostringstream oss;
993 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
994 throw INTERP_KERNEL::Exception(oss.str().c_str());
996 _families[fname]=famId;
1000 if((*it).second!=famId)
1002 std::ostringstream oss;
1003 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1004 throw INTERP_KERNEL::Exception(oss.str().c_str());
1010 * Creates a group including all mesh entities of given dimension.
1011 * \warning This method does \b not guarantee that the created group includes mesh
1012 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1013 * present in family fields of different dimensions. To assure this, call
1014 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1015 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1017 * \param [in] groupName - a name of the new group.
1018 * \throw If a group named \a groupName already exists.
1019 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1020 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1022 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1024 std::string grpName(groupName);
1025 std::vector<int> levs=getNonEmptyLevelsExt();
1026 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1028 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1029 oss << "Available relative ext levels are : ";
1030 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1031 throw INTERP_KERNEL::Exception(oss.str().c_str());
1033 if(existsGroup(groupName))
1035 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1036 oss << "Already existing groups are : ";
1037 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1038 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1039 throw INTERP_KERNEL::Exception(oss.str().c_str());
1041 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1043 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1044 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1045 std::vector<std::string> familiesOnWholeGroup;
1046 for(const int *it=famIds->begin();it!=famIds->end();it++)
1049 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1051 _groups[grpName]=familiesOnWholeGroup;
1055 * Ensures that given family ids do not present in family fields of dimensions different
1056 * than given ones. If a family id is present in the family fields of dimensions different
1057 * than the given ones, a new family is created and the whole data is updated accordingly.
1058 * \param [in] famIds - a sequence of family ids to check.
1059 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1060 * famIds should exclusively belong.
1061 * \return bool - \c true if no modification is done in \a this mesh by this method.
1063 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1065 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1066 std::vector<int> levs=getNonEmptyLevelsExt();
1067 std::set<int> levs2(levs.begin(),levs.end());
1068 std::vector<int> levsToTest;
1069 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1070 std::set<int> famIds2(famIds.begin(),famIds.end());
1073 if(!_families.empty())
1074 maxFamId=getMaxFamilyId()+1;
1075 std::vector<std::string> allFams=getFamiliesNames();
1076 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1078 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1081 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1082 std::vector<int> tmp;
1083 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1084 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1087 std::string famName=getFamilyNameGivenId(*it2);
1088 std::ostringstream oss; oss << "Family_" << maxFamId;
1089 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1090 addFamilyOnAllGroupsHaving(famName,zeName);
1091 _families[zeName]=maxFamId;
1092 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1101 * Adds a family to a given group in \a this mesh. If the group with a given name does
1102 * not exist, it is created.
1103 * \param [in] grpName - the name of the group to add the family in.
1104 * \param [in] famName - the name of the family to add to the group named \a grpName.
1105 * \throw If \a grpName or \a famName is an empty string.
1106 * \throw If no family named \a famName is present in \a this mesh.
1108 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1110 std::string grpn(grpName);
1111 std::string famn(famName);
1112 if(grpn.empty() || famn.empty())
1113 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1114 std::vector<std::string> fams=getFamiliesNames();
1115 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1117 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1118 oss << "Create this family or choose an existing one ! Existing fams are : ";
1119 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1120 throw INTERP_KERNEL::Exception(oss.str().c_str());
1122 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1123 if(it==_groups.end())
1125 _groups[grpn].push_back(famn);
1129 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1130 if(it2==(*it).second.end())
1131 (*it).second.push_back(famn);
1136 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1137 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1138 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1140 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1142 std::string famNameCpp(famName);
1143 std::string otherCpp(otherFamName);
1144 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1146 std::vector<std::string>& v=(*it).second;
1147 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1149 v.push_back(otherCpp);
1155 * \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).
1156 * \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)
1158 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1161 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1162 std::string grpName(ids->getName());
1164 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1165 ids->checkStrictlyMonotonic(true);
1166 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
1167 std::vector<std::string> grpsNames=getGroupsNames();
1168 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1170 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1171 throw INTERP_KERNEL::Exception(oss.str().c_str());
1173 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1174 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1175 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1176 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1177 std::vector<int> familyIds;
1178 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
1179 int maxVal=getTheMaxAbsFamilyId()+1;
1180 std::map<std::string,int> families(_families);
1181 std::map<std::string, std::vector<std::string> > groups(_groups);
1182 std::vector<std::string> fams;
1183 bool created(false);
1184 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1186 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
1187 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1188 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
1189 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1192 bool isFamPresent=false;
1193 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1194 isFamPresent=(*itl)->presenceOfValue(*famId);
1196 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1199 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1200 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1201 fams.push_back(locFamName);
1202 if(existsFamily(*famId))
1204 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1205 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1208 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1212 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1213 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1214 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1215 if(existsFamily(*famId))
1217 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1218 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1223 for(std::size_t i=0;i<familyIds.size();i++)
1225 DataArrayInt *da=idsPerfamiliyIds[i];
1226 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1230 _groups[grpName]=fams;
1233 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1235 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1238 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1240 std::string fam(familyNameToChange);
1241 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1243 std::vector<std::string>& fams((*it).second);
1244 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1248 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1254 * Returns a name of the family having a given id or, if no such a family exists, creates
1255 * a new uniquely named family and returns its name.
1256 * \param [in] id - the id of the family whose name is required.
1257 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1258 * \return std::string - the name of the existing or the created family.
1259 * \throw If it is not possible to create a unique family name.
1261 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1263 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1267 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1268 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1269 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1270 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1272 * This method will throws an exception if it is not possible to create a unique family name.
1274 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1276 std::vector<std::string> famAlreadyExisting(families.size());
1278 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1280 if((*it).second!=id)
1282 famAlreadyExisting[ii]=(*it).first;
1291 std::ostringstream oss; oss << "Family_" << id;
1292 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1298 * Sets names and ids of all families in \a this mesh.
1299 * \param [in] info - a map of a family name to a family id.
1301 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1307 * Sets names of all groups and families constituting them in \a this mesh.
1308 * \param [in] info - a map of a group name to a vector of names of families
1309 * constituting the group.
1311 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1317 * Returns an id of the family having a given name.
1318 * \param [in] name - the name of the family of interest.
1319 * \return int - the id of the family of interest.
1320 * \throw If no family with such a \a name exists.
1322 int MEDFileMesh::getFamilyId(const std::string& name) const
1324 std::string oname(name);
1325 std::map<std::string, int>::const_iterator it=_families.find(oname);
1326 std::vector<std::string> fams=getFamiliesNames();
1327 if(it==_families.end())
1329 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1330 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1331 throw INTERP_KERNEL::Exception(oss.str().c_str());
1333 return (*it).second;
1337 * Returns ids of the families having given names.
1338 * \param [in] fams - a sequence of the names of families of interest.
1339 * \return std::vector<int> - a sequence of the ids of families of interest.
1340 * \throw If \a fams contains a name of an inexistent family.
1342 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1344 std::vector<int> ret(fams.size());
1346 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1348 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1349 if(it2==_families.end())
1351 std::vector<std::string> fams2=getFamiliesNames();
1352 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1353 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1354 throw INTERP_KERNEL::Exception(oss.str().c_str());
1356 ret[i]=(*it2).second;
1362 * Returns a maximal abs(id) of families in \a this mesh.
1363 * \return int - the maximal norm of family id.
1364 * \throw If there are no families in \a this mesh.
1366 int MEDFileMesh::getMaxAbsFamilyId() const
1368 if(_families.empty())
1369 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1370 int ret=-std::numeric_limits<int>::max();
1371 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1373 ret=std::max(std::abs((*it).second),ret);
1379 * Returns a maximal id of families in \a this mesh.
1380 * \return int - the maximal family id.
1381 * \throw If there are no families in \a this mesh.
1383 int MEDFileMesh::getMaxFamilyId() const
1385 if(_families.empty())
1386 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1387 int ret=-std::numeric_limits<int>::max();
1388 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1390 ret=std::max((*it).second,ret);
1396 * Returns a minimal id of families in \a this mesh.
1397 * \return int - the minimal family id.
1398 * \throw If there are no families in \a this mesh.
1400 int MEDFileMesh::getMinFamilyId() const
1402 if(_families.empty())
1403 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1404 int ret=std::numeric_limits<int>::max();
1405 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1407 ret=std::min((*it).second,ret);
1413 * Returns a maximal id of families in \a this mesh. Not only named families are
1414 * considered but all family fields as well.
1415 * \return int - the maximal family id.
1417 int MEDFileMesh::getTheMaxAbsFamilyId() const
1419 int m1=-std::numeric_limits<int>::max();
1420 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1421 m1=std::max(std::abs((*it).second),m1);
1422 int m2=getMaxAbsFamilyIdInArrays();
1423 return std::max(m1,m2);
1427 * Returns a maximal id of families in \a this mesh. Not only named families are
1428 * considered but all family fields as well.
1429 * \return int - the maximal family id.
1431 int MEDFileMesh::getTheMaxFamilyId() const
1433 int m1=-std::numeric_limits<int>::max();
1434 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1435 m1=std::max((*it).second,m1);
1436 int m2=getMaxFamilyIdInArrays();
1437 return std::max(m1,m2);
1441 * Returns a minimal id of families in \a this mesh. Not only named families are
1442 * considered but all family fields as well.
1443 * \return int - the minimal family id.
1445 int MEDFileMesh::getTheMinFamilyId() const
1447 int m1=std::numeric_limits<int>::max();
1448 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1449 m1=std::min((*it).second,m1);
1450 int m2=getMinFamilyIdInArrays();
1451 return std::min(m1,m2);
1455 * This method only considers the maps. The contain of family array is ignored here.
1457 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1459 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1461 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1463 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1464 v.insert((*it).second);
1465 ret->alloc((int)v.size(),1);
1466 std::copy(v.begin(),v.end(),ret->getPointer());
1471 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1473 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1475 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1477 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1478 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1479 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1481 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1482 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1483 if((DataArrayInt *) ret)
1484 ret=dv->buildUnion(ret);
1492 * true is returned if no modification has been needed. false if family
1493 * renumbering has been needed.
1495 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1497 std::vector<int> levs=getNonEmptyLevelsExt();
1498 std::set<int> allFamIds;
1499 int maxId=getMaxFamilyId()+1;
1500 std::map<int,std::vector<int> > famIdsToRenum;
1501 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1503 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1506 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1508 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1510 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1512 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1515 if(famIdsToRenum.empty())
1517 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1518 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1520 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1521 int *famIdsToChange=fam->getPointer();
1522 std::map<int,int> ren;
1523 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1525 if(allIds->presenceOfValue(*it3))
1527 std::string famName=getFamilyNameGivenId(*it3);
1528 std::vector<std::string> grps=getGroupsOnFamily(famName);
1531 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1532 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1533 addFamilyOnGrp((*it4),newFam);
1536 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1537 for(const int *id=ids->begin();id!=ids->end();id++)
1538 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1544 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1545 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1546 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1547 * This method will throw an exception if a same family id is detected in different level.
1548 * \warning This policy is the opposite of those in MED file documentation ...
1550 void MEDFileMesh::normalizeFamIdsTrio()
1552 ensureDifferentFamIdsPerLevel();
1553 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1554 std::vector<int> levs=getNonEmptyLevelsExt();
1555 std::set<int> levsS(levs.begin(),levs.end());
1556 std::set<std::string> famsFetched;
1557 std::map<std::string,int> families;
1558 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1561 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1565 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1566 std::map<int,int> ren;
1567 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1569 int nbOfTuples=fam->getNumberOfTuples();
1570 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1571 for(int *w=start;w!=start+nbOfTuples;w++)
1573 for(const int *it=tmp->begin();it!=tmp->end();it++)
1575 if(allIds->presenceOfValue(*it))
1577 std::string famName=getFamilyNameGivenId(*it);
1578 families[famName]=ren[*it];
1579 famsFetched.insert(famName);
1584 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1587 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1591 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1592 std::map<int,int> ren;
1593 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1595 int nbOfTuples=fam->getNumberOfTuples();
1596 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1597 for(int *w=start;w!=start+nbOfTuples;w++)
1599 for(const int *it=tmp->begin();it!=tmp->end();it++)
1601 if(allIds->presenceOfValue(*it))
1603 std::string famName=getFamilyNameGivenId(*it);
1604 families[famName]=ren[*it];
1605 famsFetched.insert(famName);
1610 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1612 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1615 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1616 fam->fillWithZero();
1617 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1618 if(allIds->presenceOfValue(*it3))
1620 std::string famName=getFamilyNameGivenId(*it3);
1621 families[famName]=0;
1622 famsFetched.insert(famName);
1627 std::vector<std::string> allFams=getFamiliesNames();
1628 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1629 std::set<std::string> unFetchedIds;
1630 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1631 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1632 families[*it4]=_families[*it4];
1637 * This method normalizes fam id with the following policy.
1638 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1639 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1640 * This method will throw an exception if a same family id is detected in different level.
1642 void MEDFileMesh::normalizeFamIdsMEDFile()
1644 ensureDifferentFamIdsPerLevel();
1645 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1646 std::vector<int> levs=getNonEmptyLevelsExt();
1647 std::set<int> levsS(levs.begin(),levs.end());
1648 std::set<std::string> famsFetched;
1649 std::map<std::string,int> families;
1651 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1654 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1657 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1658 std::map<int,int> ren;
1659 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1661 int nbOfTuples=fam->getNumberOfTuples();
1662 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1663 for(int *w=start;w!=start+nbOfTuples;w++)
1665 for(const int *it=tmp->begin();it!=tmp->end();it++)
1667 if(allIds->presenceOfValue(*it))
1669 std::string famName=getFamilyNameGivenId(*it);
1670 families[famName]=ren[*it];
1671 famsFetched.insert(famName);
1677 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1679 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1682 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1683 std::map<int,int> ren;
1684 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1686 int nbOfTuples=fam->getNumberOfTuples();
1687 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1688 for(int *w=start;w!=start+nbOfTuples;w++)
1690 for(const int *it=tmp->begin();it!=tmp->end();it++)
1692 if(allIds->presenceOfValue(*it))
1694 std::string famName=getFamilyNameGivenId(*it);
1695 families[famName]=ren[*it];
1696 famsFetched.insert(famName);
1702 std::vector<std::string> allFams=getFamiliesNames();
1703 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1704 std::set<std::string> unFetchedIds;
1705 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1706 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1707 families[*it4]=_families[*it4];
1712 * Returns a name of the family by its id. If there are several families having the given
1713 * id, the name first in lexical order is returned.
1714 * \param [in] id - the id of the family whose name is required.
1715 * \return std::string - the name of the found family.
1716 * \throw If no family with the given \a id exists.
1718 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1720 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1721 if((*it).second==id)
1723 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1724 throw INTERP_KERNEL::Exception(oss.str().c_str());
1728 * Returns a string describing \a this mesh. This description includes the mesh name and
1729 * the mesh description string.
1730 * \return std::string - the mesh information string.
1732 std::string MEDFileMesh::simpleRepr() const
1734 std::ostringstream oss;
1735 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1736 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1737 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1742 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1743 * an empty one is created.
1745 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1747 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1750 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New());
1751 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1752 arr->fillWithZero();
1753 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1754 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1758 * Returns ids of mesh entities contained in a given group of a given dimension.
1759 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1761 * \param [in] grp - the name of the group of interest.
1762 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1763 * returned instead of ids.
1764 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1765 * numbers, if available and required, of mesh entities of the group. The caller
1766 * is to delete this array using decrRef() as it is no more needed.
1767 * \throw If the name of a nonexistent group is specified.
1768 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1770 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1772 std::vector<std::string> tmp(1);
1774 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1780 * Returns ids of mesh entities contained in given groups of a given dimension.
1781 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1783 * \param [in] grps - the names of the groups of interest.
1784 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1785 * returned instead of ids.
1786 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1787 * numbers, if available and required, of mesh entities of the groups. The caller
1788 * is to delete this array using decrRef() as it is no more needed.
1789 * \throw If the name of a nonexistent group is present in \a grps.
1790 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1792 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1794 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1795 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1799 * Returns ids of mesh entities contained in a given family of a given dimension.
1800 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1802 * \param [in] fam - the name of the family of interest.
1803 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1804 * returned instead of ids.
1805 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1806 * numbers, if available and required, of mesh entities of the family. The caller
1807 * is to delete this array using decrRef() as it is no more needed.
1808 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1810 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1812 std::vector<std::string> tmp(1);
1814 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1820 * Returns ids of nodes contained in a given group.
1821 * \param [in] grp - the name of the group of interest.
1822 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1823 * returned instead of ids.
1824 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1825 * numbers, if available and required, of nodes of the group. The caller
1826 * is to delete this array using decrRef() as it is no more needed.
1827 * \throw If the name of a nonexistent group is specified.
1828 * \throw If the family field is missing for nodes.
1830 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1832 std::vector<std::string> tmp(1);
1834 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1840 * Returns ids of nodes contained in given groups.
1841 * \param [in] grps - the names of the groups of interest.
1842 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1843 * returned instead of ids.
1844 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1845 * numbers, if available and required, of nodes of the groups. The caller
1846 * is to delete this array using decrRef() as it is no more needed.
1847 * \throw If the name of a nonexistent group is present in \a grps.
1848 * \throw If the family field is missing for nodes.
1850 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1852 return getGroupsArr(1,grps,renum);
1856 * Returns ids of nodes contained in a given group.
1857 * \param [in] grp - the name of the group of interest.
1858 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1859 * returned instead of ids.
1860 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1861 * numbers, if available and required, of nodes of the group. The caller
1862 * is to delete this array using decrRef() as it is no more needed.
1863 * \throw If the name of a nonexistent group is specified.
1864 * \throw If the family field is missing for nodes.
1866 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1868 std::vector<std::string> tmp(1);
1870 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1876 * Returns ids of nodes contained in given families.
1877 * \param [in] fams - the names of the families of interest.
1878 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1879 * returned instead of ids.
1880 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1881 * numbers, if available and required, of nodes of the families. The caller
1882 * is to delete this array using decrRef() as it is no more needed.
1883 * \throw If the family field is missing for nodes.
1885 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1887 return getFamiliesArr(1,fams,renum);
1891 * Adds groups of given dimension and creates corresponding families and family fields
1892 * given ids of mesh entities of each group.
1893 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1894 * \param [in] grps - a sequence of arrays of ids each describing a group.
1895 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1897 * \throw If names of some groups in \a grps are equal.
1898 * \throw If \a grps includes a group with an empty name.
1899 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1900 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1902 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1906 std::set<std::string> grpsName;
1907 std::vector<std::string> grpsName2(grps.size());
1910 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1912 grpsName.insert((*it)->getName());
1913 grpsName2[i]=(*it)->getName();
1915 if(grpsName.size()!=grps.size())
1916 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1917 if(grpsName.find(std::string(""))!=grpsName.end())
1918 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1919 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1920 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1921 std::vector< std::vector<int> > fidsOfGroups;
1924 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1928 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1929 for(unsigned int ii=0;ii<grps.size();ii++)
1931 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1932 grps2[ii]->setName(grps[ii]->getName());
1934 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1935 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1938 if(!_families.empty())
1939 offset=getMaxAbsFamilyId()+1;
1940 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1941 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1942 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1943 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1947 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1948 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1949 * For the moment, the two last input parameters are not taken into account.
1951 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1953 std::map<int,std::string> famInv;
1954 for(const int *it=famIds->begin();it!=famIds->end();it++)
1956 std::ostringstream oss;
1957 oss << "Family_" << (*it);
1958 _families[oss.str()]=(*it);
1959 famInv[*it]=oss.str();
1962 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1964 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1966 _groups[grpNames[i]].push_back(famInv[*it2]);
1971 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1973 std::vector<int> levs(getNonEmptyLevels());
1974 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1975 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1977 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1978 ret.insert(ret.end(),elts.begin(),elts.end());
1983 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1985 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1986 return mLev->getDistributionOfTypes();
1989 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1991 famArr->applyLin(offset>0?1:-1,offset,0);
1992 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1995 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1996 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2001 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2002 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2003 * If this method fails to find such a name it will throw an exception.
2005 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2008 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2011 std::size_t len=nameTry.length();
2012 for(std::size_t ii=1;ii<len;ii++)
2014 std::string tmp=nameTry.substr(ii,len-ii);
2015 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2021 for(std::size_t i=1;i<30;i++)
2023 std::string tmp1(nameTry.at(0),i);
2025 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2031 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2033 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2035 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2038 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2040 std::size_t nbOfChunks=code.size()/3;
2041 if(code.size()%3!=0)
2042 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2044 for(std::size_t i=0;i<nbOfChunks;i++)
2053 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2054 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2055 * If _name is not empty and that 'm' has the same name nothing is done.
2056 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2058 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2061 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2066 std::string name(m->getName());
2071 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2072 oss << name << "' ! Names must match !";
2073 throw INTERP_KERNEL::Exception(oss.str().c_str());
2077 if(_desc_name.empty())
2078 _desc_name=m->getDescription();
2081 std::string name(m->getDescription());
2084 if(_desc_name!=name)
2086 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2087 oss << name << "' ! Names must match !";
2088 throw INTERP_KERNEL::Exception(oss.str().c_str());
2094 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2096 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2097 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2099 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2100 oss << " - Groups lying on this family : ";
2101 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2102 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2103 oss << std::endl << std::endl;
2108 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2109 * file. The mesh to load is specified by its name and numbers of a time step and an
2111 * \param [in] fileName - the name of MED file to read.
2112 * \param [in] mName - the name of the mesh to read.
2113 * \param [in] dt - the number of a time step.
2114 * \param [in] it - the number of an iteration.
2115 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2116 * mesh using decrRef() as it is no more needed.
2117 * \throw If the file is not readable.
2118 * \throw If there is no mesh with given attributes in the file.
2119 * \throw If the mesh in the file is not an unstructured one.
2121 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2123 MEDFileUtilities::CheckFileForRead(fileName);
2124 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2125 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2129 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2130 * file. The first mesh in the file is loaded.
2131 * \param [in] fileName - the name of MED file to read.
2132 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2133 * mesh using decrRef() as it is no more needed.
2134 * \throw If the file is not readable.
2135 * \throw If there is no meshes in the file.
2136 * \throw If the mesh in the file is not an unstructured one.
2138 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2140 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
2143 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2144 throw INTERP_KERNEL::Exception(oss.str().c_str());
2146 MEDFileUtilities::CheckFileForRead(fileName);
2147 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2149 ParaMEDMEM::MEDCouplingMeshType meshType;
2151 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
2152 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2156 * Returns an empty instance of MEDFileUMesh.
2157 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2158 * mesh using decrRef() as it is no more needed.
2160 MEDFileUMesh *MEDFileUMesh::New()
2162 return new MEDFileUMesh;
2166 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2167 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2168 * \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.
2169 * 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
2170 * at most the memory consumtion.
2172 * \param [in] fileName - the name of the file.
2173 * \param [in] mName - the name of the mesh to be read.
2174 * \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.
2175 * \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.
2176 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2177 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2178 * \param [in] mrs - the request for what to be loaded.
2179 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2181 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)
2183 MEDFileUtilities::CheckFileForRead(fileName);
2184 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2185 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2189 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2190 * This method is \b NOT wrapped into python.
2192 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)
2194 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2195 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2199 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2201 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2202 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2206 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2208 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2209 ret.push_back((const DataArrayDouble*)_coords);
2210 ret.push_back((const DataArrayInt *)_fam_coords);
2211 ret.push_back((const DataArrayInt *)_num_coords);
2212 ret.push_back((const DataArrayInt *)_rev_num_coords);
2213 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2214 ret.push_back((const PartDefinition *)_part_coords);
2215 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2216 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2220 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2222 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2226 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2228 return new MEDFileUMesh;
2231 MEDFileMesh *MEDFileUMesh::deepCpy() const
2233 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2234 if((const DataArrayDouble*)_coords)
2235 ret->_coords=_coords->deepCpy();
2236 if((const DataArrayInt*)_fam_coords)
2237 ret->_fam_coords=_fam_coords->deepCpy();
2238 if((const DataArrayInt*)_num_coords)
2239 ret->_num_coords=_num_coords->deepCpy();
2240 if((const DataArrayInt*)_rev_num_coords)
2241 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2242 if((const DataArrayAsciiChar*)_name_coords)
2243 ret->_name_coords=_name_coords->deepCpy();
2245 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2247 if((const MEDFileUMeshSplitL1 *)(*it))
2248 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2250 if((const PartDefinition*)_part_coords)
2251 ret->_part_coords=_part_coords->deepCpy();
2256 * Checks if \a this and another mesh are equal.
2257 * \param [in] other - the mesh to compare with.
2258 * \param [in] eps - a precision used to compare real values.
2259 * \param [in,out] what - the string returning description of unequal data.
2260 * \return bool - \c true if the meshes are equal, \c false, else.
2262 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2264 if(!MEDFileMesh::isEqual(other,eps,what))
2266 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2269 what="Mesh types differ ! This is unstructured and other is NOT !";
2272 clearNonDiscrAttributes();
2273 otherC->clearNonDiscrAttributes();
2274 const DataArrayDouble *coo1=_coords;
2275 const DataArrayDouble *coo2=otherC->_coords;
2276 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2278 what="Mismatch of coordinates ! One is defined and not other !";
2283 bool ret=coo1->isEqual(*coo2,eps);
2286 what="Coords differ !";
2290 const DataArrayInt *famc1=_fam_coords;
2291 const DataArrayInt *famc2=otherC->_fam_coords;
2292 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2294 what="Mismatch of families arr on nodes ! One is defined and not other !";
2299 bool ret=famc1->isEqual(*famc2);
2302 what="Families arr on node differ !";
2306 const DataArrayInt *numc1=_num_coords;
2307 const DataArrayInt *numc2=otherC->_num_coords;
2308 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2310 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2315 bool ret=numc1->isEqual(*numc2);
2318 what="Numbering arr on node differ !";
2322 const DataArrayAsciiChar *namec1=_name_coords;
2323 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2324 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2326 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2331 bool ret=namec1->isEqual(*namec2);
2334 what="Names arr on node differ !";
2338 if(_ms.size()!=otherC->_ms.size())
2340 what="Number of levels differs !";
2343 std::size_t sz=_ms.size();
2344 for(std::size_t i=0;i<sz;i++)
2346 const MEDFileUMeshSplitL1 *s1=_ms[i];
2347 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2348 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2350 what="Mismatch of presence of sub levels !";
2355 bool ret=s1->isEqual(s2,eps,what);
2360 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2363 if((!pd0 && pd1) || (pd0 && !pd1))
2365 what=std::string("node part def is defined only for one among this or other !");
2368 return pd0->isEqual(pd1,what);
2372 * Clears redundant attributes of incorporated data arrays.
2374 void MEDFileUMesh::clearNonDiscrAttributes() const
2376 MEDFileMesh::clearNonDiscrAttributes();
2377 const DataArrayDouble *coo1=_coords;
2379 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2380 const DataArrayInt *famc1=_fam_coords;
2382 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2383 const DataArrayInt *numc1=_num_coords;
2385 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2386 const DataArrayAsciiChar *namc1=_name_coords;
2388 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2389 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2391 const MEDFileUMeshSplitL1 *tmp=(*it);
2393 tmp->clearNonDiscrAttributes();
2397 void MEDFileUMesh::setName(const std::string& name)
2399 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2400 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2401 (*it)->setName(name);
2402 MEDFileMesh::setName(name);
2405 MEDFileUMesh::MEDFileUMesh()
2409 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2412 loadUMeshFromFile(fid,mName,dt,it,mrs);
2413 loadJointsFromFile(fid);
2415 catch(INTERP_KERNEL::Exception& e)
2421 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2422 * See MEDFileUMesh::LoadPartOf for detailed description.
2424 * \sa loadUMeshFromFile
2426 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)
2428 MEDFileUMeshL2 loaderl2;
2429 ParaMEDMEM::MEDCouplingMeshType meshType;
2432 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2433 if(meshType!=UNSTRUCTURED)
2435 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2436 throw INTERP_KERNEL::Exception(oss.str().c_str());
2438 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2439 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2443 * \brief Write joints in a file
2445 void MEDFileMesh::writeJoints(med_idt fid) const
2447 if ( (const MEDFileJoints*) _joints )
2448 _joints->write(fid);
2452 * \brief Load joints in a file or use provided ones
2454 //================================================================================
2456 * \brief Load joints in a file or use provided ones
2457 * \param [in] fid - MED file descriptor
2458 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2459 * Usually this joints are those just read by another iteration
2460 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2462 //================================================================================
2464 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2466 if ( toUseInstedOfReading )
2467 setJoints( toUseInstedOfReading );
2469 _joints = MEDFileJoints::New( fid, _name );
2473 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2475 int MEDFileMesh::getNumberOfJoints()
2477 return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0;
2481 * \brief Return joints with all adjacent mesh domains
2483 MEDFileJoints * MEDFileMesh::getJoints() const
2485 return (MEDFileJoints*) & (*_joints);
2488 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2490 if ( joints != _joints )
2499 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2501 * \sa loadPartUMeshFromFile
2503 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2505 MEDFileUMeshL2 loaderl2;
2506 ParaMEDMEM::MEDCouplingMeshType meshType;
2509 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2510 if(meshType!=UNSTRUCTURED)
2512 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2513 throw INTERP_KERNEL::Exception(oss.str().c_str());
2515 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2516 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2519 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2521 int lev=loaderl2.getNumberOfLevels();
2523 for(int i=0;i<lev;i++)
2525 if(!loaderl2.emptyLev(i))
2526 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2530 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2532 setName(loaderl2.getName());
2533 setDescription(loaderl2.getDescription());
2534 setUnivName(loaderl2.getUnivName());
2535 setIteration(loaderl2.getIteration());
2536 setOrder(loaderl2.getOrder());
2537 setTimeValue(loaderl2.getTime());
2538 setTimeUnit(loaderl2.getTimeUnit());
2539 _coords=loaderl2.getCoords();
2540 if(!mrs || mrs->isNodeFamilyFieldReading())
2541 _fam_coords=loaderl2.getCoordsFamily();
2542 if(!mrs || mrs->isNodeNumFieldReading())
2543 _num_coords=loaderl2.getCoordsNum();
2544 if(!mrs || mrs->isNodeNameFieldReading())
2545 _name_coords=loaderl2.getCoordsName();
2546 _part_coords=loaderl2.getPartDefOfCoo();
2550 MEDFileUMesh::~MEDFileUMesh()
2554 void MEDFileUMesh::writeLL(med_idt fid) const
2556 const DataArrayDouble *coo=_coords;
2557 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2558 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2559 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2560 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2561 int spaceDim=coo?coo->getNumberOfComponents():0;
2564 mdim=getMeshDimension();
2565 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2566 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2567 for(int i=0;i<spaceDim;i++)
2569 std::string info=coo->getInfoOnComponent(i);
2571 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2572 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
2573 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
2575 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2576 MEDmeshUniversalNameWr(fid,maa);
2577 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2578 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2579 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2580 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2581 (*it)->write(fid,meshName,mdim);
2582 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2588 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2589 * \return std::vector<int> - a sequence of the relative dimensions.
2591 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2593 std::vector<int> ret;
2595 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2596 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2603 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2604 * \return std::vector<int> - a sequence of the relative dimensions.
2606 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2608 std::vector<int> ret0=getNonEmptyLevels();
2609 if((const DataArrayDouble *) _coords)
2611 std::vector<int> ret(ret0.size()+1);
2613 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2619 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2621 std::vector<int> ret;
2622 const DataArrayInt *famCoo(_fam_coords);
2626 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2628 const MEDFileUMeshSplitL1 *cur(*it);
2630 if(cur->getFamilyField())
2636 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2638 std::vector<int> ret;
2639 const DataArrayInt *numCoo(_num_coords);
2643 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2645 const MEDFileUMeshSplitL1 *cur(*it);
2647 if(cur->getNumberField())
2653 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2655 std::vector<int> ret;
2656 const DataArrayAsciiChar *nameCoo(_name_coords);
2660 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2662 const MEDFileUMeshSplitL1 *cur(*it);
2664 if(cur->getNameField())
2671 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2672 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2673 * \param [in] grp - the name of the group of interest.
2674 * \return std::vector<int> - a sequence of the relative dimensions.
2676 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2678 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2679 return getFamsNonEmptyLevels(fams);
2683 * Returns all relative mesh levels (including nodes) where a given group is defined.
2684 * \param [in] grp - the name of the group of interest.
2685 * \return std::vector<int> - a sequence of the relative dimensions.
2687 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2689 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2690 return getFamsNonEmptyLevelsExt(fams);
2694 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2695 * To include nodes, call getFamNonEmptyLevelsExt() method.
2696 * \param [in] fam - the name of the family of interest.
2697 * \return std::vector<int> - a sequence of the relative dimensions.
2699 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2701 std::vector<std::string> fams(1,std::string(fam));
2702 return getFamsNonEmptyLevels(fams);
2706 * Returns all relative mesh levels (including nodes) where a given family is defined.
2707 * \param [in] fam - the name of the family of interest.
2708 * \return std::vector<int> - a sequence of the relative dimensions.
2710 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2712 std::vector<std::string> fams(1,std::string(fam));
2713 return getFamsNonEmptyLevelsExt(fams);
2717 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2718 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2719 * \param [in] grps - a sequence of names of the groups of interest.
2720 * \return std::vector<int> - a sequence of the relative dimensions.
2722 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2724 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2725 return getFamsNonEmptyLevels(fams);
2729 * Returns all relative mesh levels (including nodes) where given groups are defined.
2730 * \param [in] grps - a sequence of names of the groups of interest.
2731 * \return std::vector<int> - a sequence of the relative dimensions.
2733 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2735 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2736 return getFamsNonEmptyLevelsExt(fams);
2740 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2741 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2742 * \param [in] fams - the name of the family of interest.
2743 * \return std::vector<int> - a sequence of the relative dimensions.
2745 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2747 std::vector<int> ret;
2748 std::vector<int> levs=getNonEmptyLevels();
2749 std::vector<int> famIds=getFamiliesIds(fams);
2750 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2751 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2757 * Returns all relative mesh levels (including nodes) where given families are defined.
2758 * \param [in] fams - the names of the families of interest.
2759 * \return std::vector<int> - a sequence of the relative dimensions.
2761 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2763 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2764 const DataArrayInt *famCoords=_fam_coords;
2767 std::vector<int> famIds=getFamiliesIds(fams);
2768 if(famCoords->presenceOfValue(famIds))
2770 std::vector<int> ret(ret0.size()+1);
2772 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2780 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2781 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2782 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2785 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2787 std::vector<std::string> ret;
2788 std::vector<std::string> allGrps=getGroupsNames();
2789 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2791 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2792 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2798 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2800 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2801 if((const DataArrayInt *)_fam_coords)
2803 int val=_fam_coords->getMaxValue(tmp);
2804 ret=std::max(ret,std::abs(val));
2806 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2808 if((const MEDFileUMeshSplitL1 *)(*it))
2810 const DataArrayInt *da=(*it)->getFamilyField();
2813 int val=da->getMaxValue(tmp);
2814 ret=std::max(ret,std::abs(val));
2821 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2823 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2824 if((const DataArrayInt *)_fam_coords)
2826 int val=_fam_coords->getMaxValue(tmp);
2827 ret=std::max(ret,val);
2829 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2831 if((const MEDFileUMeshSplitL1 *)(*it))
2833 const DataArrayInt *da=(*it)->getFamilyField();
2836 int val=da->getMaxValue(tmp);
2837 ret=std::max(ret,val);
2844 int MEDFileUMesh::getMinFamilyIdInArrays() const
2846 int ret=std::numeric_limits<int>::max(),tmp=-1;
2847 if((const DataArrayInt *)_fam_coords)
2849 int val=_fam_coords->getMinValue(tmp);
2850 ret=std::min(ret,val);
2852 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2854 if((const MEDFileUMeshSplitL1 *)(*it))
2856 const DataArrayInt *da=(*it)->getFamilyField();
2859 int val=da->getMinValue(tmp);
2860 ret=std::min(ret,val);
2868 * Returns the dimension on cells in \a this mesh.
2869 * \return int - the mesh dimension.
2870 * \throw If there are no cells in this mesh.
2872 int MEDFileUMesh::getMeshDimension() const
2875 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2876 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2877 return (*it)->getMeshDimension()+lev;
2878 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2882 * Returns the space dimension of \a this mesh that is equal to number of components in
2883 * the node coordinates array.
2884 * \return int - the space dimension of \a this mesh.
2885 * \throw If the node coordinates array is not available.
2887 int MEDFileUMesh::getSpaceDimension() const
2889 const DataArrayDouble *coo=_coords;
2891 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2892 return coo->getNumberOfComponents();
2896 * Returns a string describing \a this mesh.
2897 * \return std::string - the mesh information string.
2899 std::string MEDFileUMesh::simpleRepr() const
2901 std::ostringstream oss;
2902 oss << MEDFileMesh::simpleRepr();
2903 const DataArrayDouble *coo=_coords;
2904 oss << "- The dimension of the space is ";
2905 static const char MSG1[]= "*** NO COORDS SET ***";
2906 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2908 oss << _coords->getNumberOfComponents() << std::endl;
2910 oss << MSG1 << std::endl;
2911 oss << "- Type of the mesh : UNSTRUCTURED\n";
2912 oss << "- Number of nodes : ";
2914 oss << _coords->getNumberOfTuples() << std::endl;
2916 oss << MSG1 << std::endl;
2917 std::size_t nbOfLev=_ms.size();
2918 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2919 for(std::size_t i=0;i<nbOfLev;i++)
2921 const MEDFileUMeshSplitL1 *lev=_ms[i];
2922 oss << " - Level #" << -((int) i) << " has dimension : ";
2925 oss << lev->getMeshDimension() << std::endl;
2926 lev->simpleRepr(oss);
2929 oss << MSG2 << std::endl;
2931 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2934 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2935 oss << "- Names of coordinates :" << std::endl;
2936 std::vector<std::string> vars=coo->getVarsOnComponent();
2937 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2938 oss << std::endl << "- Units of coordinates : " << std::endl;
2939 std::vector<std::string> units=coo->getUnitsOnComponent();
2940 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2942 oss << std::endl << std::endl;
2948 * Returns a full textual description of \a this mesh.
2949 * \return std::string - the string holding the mesh description.
2951 std::string MEDFileUMesh::advancedRepr() const
2953 return simpleRepr();
2957 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2958 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2959 * \return int - the number of entities.
2960 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2962 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2964 if(meshDimRelToMaxExt==1)
2966 if(!((const DataArrayDouble *)_coords))
2967 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2968 return _coords->getNumberOfTuples();
2970 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2974 * Returns the family field for mesh entities of a given dimension.
2975 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2976 * \return const DataArrayInt * - the family field. It is an array of ids of families
2977 * each mesh entity belongs to. It can be \c NULL.
2979 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2981 if(meshDimRelToMaxExt==1)
2983 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2984 return l1->getFamilyField();
2987 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
2989 if(meshDimRelToMaxExt==1)
2991 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2992 return l1->getFamilyField();
2996 * Returns the optional numbers of mesh entities of a given dimension.
2997 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2998 * \return const DataArrayInt * - the array of the entity numbers.
2999 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3001 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3003 if(meshDimRelToMaxExt==1)
3005 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3006 return l1->getNumberField();
3009 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3011 if(meshDimRelToMaxExt==1)
3012 return _name_coords;
3013 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3014 return l1->getNameField();
3018 * 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).
3020 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3021 * \param [in] gt - The input geometric type for which the part definition is requested.
3022 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3024 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3026 if(meshDimRelToMaxExt==1)
3027 return _part_coords;
3028 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3029 return l1->getPartDef(gt);
3032 int MEDFileUMesh::getNumberOfNodes() const
3034 const DataArrayDouble *coo(_coords);
3036 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3037 return coo->getNumberOfTuples();
3040 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3042 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3043 return l1->getNumberOfCells();
3046 bool MEDFileUMesh::hasImplicitPart() const
3051 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3053 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3056 void MEDFileUMesh::releaseImplicitPartIfAny() const
3060 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3062 std::size_t sz(st.getNumberOfItems());
3063 for(std::size_t i=0;i<sz;i++)
3065 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3066 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3067 if(st[i].getPflName().empty())
3068 m->computeNodeIdsAlg(nodesFetched);
3071 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3072 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3073 m2->computeNodeIdsAlg(nodesFetched);
3079 * Returns the optional numbers of mesh entities of a given dimension transformed using
3080 * DataArrayInt::invertArrayN2O2O2N().
3081 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3082 * \return const DataArrayInt * - the array of the entity numbers transformed using
3083 * DataArrayInt::invertArrayN2O2O2N().
3084 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3086 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3088 if(meshDimRelToMaxExt==1)
3090 if(!((const DataArrayInt *)_num_coords))
3091 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3092 return _rev_num_coords;
3094 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3095 return l1->getRevNumberField();
3099 * Returns a pointer to the node coordinates array of \a this mesh \b without
3100 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3102 DataArrayDouble *MEDFileUMesh::getCoords() const
3104 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
3105 if((DataArrayDouble *)tmp)
3113 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3114 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3116 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3117 * \param [in] grp - the name of the group whose mesh entities are included in the
3119 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3120 * according to the optional numbers of entities, if available.
3121 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3122 * delete this mesh using decrRef() as it is no more needed.
3123 * \throw If the name of a nonexistent group is specified.
3124 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3126 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3128 synchronizeTinyInfoOnLeaves();
3129 std::vector<std::string> tmp(1);
3131 return getGroups(meshDimRelToMaxExt,tmp,renum);
3135 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3136 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3138 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3139 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3141 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3142 * according to the optional numbers of entities, if available.
3143 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3144 * delete this mesh using decrRef() as it is no more needed.
3145 * \throw If a name of a nonexistent group is present in \a grps.
3146 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3148 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3150 synchronizeTinyInfoOnLeaves();
3151 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3152 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3153 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3154 zeRet->setName(grps[0]);
3155 return zeRet.retn();
3159 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3160 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3162 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3163 * \param [in] fam - the name of the family whose mesh entities are included in the
3165 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3166 * according to the optional numbers of entities, if available.
3167 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3168 * delete this mesh using decrRef() as it is no more needed.
3169 * \throw If a name of a nonexistent family is present in \a grps.
3170 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3172 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3174 synchronizeTinyInfoOnLeaves();
3175 std::vector<std::string> tmp(1);
3177 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3181 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3182 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3184 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3185 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3187 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3188 * according to the optional numbers of entities, if available.
3189 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3190 * delete this mesh using decrRef() as it is no more needed.
3191 * \throw If a name of a nonexistent family is present in \a fams.
3192 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3194 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3196 synchronizeTinyInfoOnLeaves();
3197 if(meshDimRelToMaxExt==1)
3199 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3200 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3201 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3205 std::vector<int> famIds=getFamiliesIds(fams);
3206 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3207 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
3209 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3211 zeRet=l1->getFamilyPart(0,0,renum);
3212 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3213 zeRet->setName(fams[0]);
3214 return zeRet.retn();
3218 * Returns ids of mesh entities contained in given families of a given dimension.
3219 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3221 * \param [in] fams - the names of the families of interest.
3222 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3223 * returned instead of ids.
3224 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3225 * numbers, if available and required, of mesh entities of the families. The caller
3226 * is to delete this array using decrRef() as it is no more needed.
3227 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3229 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3231 std::vector<int> famIds=getFamiliesIds(fams);
3232 if(meshDimRelToMaxExt==1)
3234 if((const DataArrayInt *)_fam_coords)
3236 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3238 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3240 da=_fam_coords->getIdsEqualList(0,0);
3242 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3247 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3249 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3251 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3253 return l1->getFamilyPartArr(0,0,renum);
3257 * Returns a MEDCouplingUMesh of a given relative dimension.
3258 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3259 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3260 * To build a valid MEDCouplingUMesh from the returned one in this case,
3261 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3262 * \param [in] meshDimRelToMax - the relative dimension of interest.
3263 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3264 * optional numbers of mesh entities.
3265 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3266 * delete using decrRef() as it is no more needed.
3267 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3268 * \sa getGenMeshAtLevel()
3270 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3272 synchronizeTinyInfoOnLeaves();
3273 if(meshDimRelToMaxExt==1)
3277 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3278 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3279 umesh->setCoords(cc);
3280 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3281 umesh->setName(getName());
3285 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3286 return l1->getWholeMesh(renum);
3290 * Returns a MEDCouplingUMesh of a given relative dimension.
3291 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3292 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3293 * To build a valid MEDCouplingUMesh from the returned one in this case,
3294 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3295 * \param [in] meshDimRelToMax - the relative dimension of interest.
3296 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3297 * optional numbers of mesh entities.
3298 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3299 * delete using decrRef() as it is no more needed.
3300 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3301 * \sa getMeshAtLevel()
3303 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3305 return getMeshAtLevel(meshDimRelToMax,renum);
3308 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3310 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3311 return l1->getDistributionOfTypes();
3315 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3316 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3317 * optional numbers of mesh entities.
3318 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3319 * delete using decrRef() as it is no more needed.
3320 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3322 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3324 return getMeshAtLevel(0,renum);
3328 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3329 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3330 * optional numbers of mesh entities.
3331 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3332 * delete using decrRef() as it is no more needed.
3333 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3335 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3337 return getMeshAtLevel(-1,renum);
3341 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3342 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3343 * optional numbers of mesh entities.
3344 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3345 * delete using decrRef() as it is no more needed.
3346 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3348 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3350 return getMeshAtLevel(-2,renum);
3354 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3355 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3356 * optional numbers of mesh entities.
3357 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3358 * delete using decrRef() as it is no more needed.
3359 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3361 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3363 return getMeshAtLevel(-3,renum);
3367 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3368 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3369 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3370 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3372 void MEDFileUMesh::forceComputationOfParts() const
3374 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3376 const MEDFileUMeshSplitL1 *elt(*it);
3378 elt->forceComputationOfParts();
3383 * This method returns a vector of mesh parts containing each exactly one geometric type.
3384 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3385 * This method is only for memory aware users.
3386 * The returned pointers are **NOT** new object pointer. No need to mange them.
3388 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3390 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3391 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3395 * This method returns the part of \a this having the geometric type \a gt.
3396 * If such part is not existing an exception will be thrown.
3397 * The returned pointer is **NOT** new object pointer. No need to mange it.
3399 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3401 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3402 int lev=(int)cm.getDimension()-getMeshDimension();
3403 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3404 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3408 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3409 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3411 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3413 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3414 return sp->getGeoTypes();
3418 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3419 * \param [in] gt - the geometric type for which the family field is asked.
3420 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3421 * delete using decrRef() as it is no more needed.
3422 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3424 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3426 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3427 int lev=(int)cm.getDimension()-getMeshDimension();
3428 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3429 return sp->extractFamilyFieldOnGeoType(gt);
3433 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3434 * \param [in] gt - the geometric type for which the number field is asked.
3435 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3436 * delete using decrRef() as it is no more needed.
3437 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3439 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3441 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3442 int lev=(int)cm.getDimension()-getMeshDimension();
3443 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3444 return sp->extractNumberFieldOnGeoType(gt);
3448 * This method returns for specified geometric type \a gt the relative level to \a this.
3449 * If the relative level is empty an exception will be thrown.
3451 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3453 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3454 int ret((int)cm.getDimension()-getMeshDimension());
3455 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3459 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3461 if(meshDimRelToMaxExt==1)
3462 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3463 if(meshDimRelToMaxExt>1)
3464 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3465 int tracucedRk=-meshDimRelToMaxExt;
3466 if(tracucedRk>=(int)_ms.size())
3467 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3468 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3469 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3470 return _ms[tracucedRk];
3473 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3475 if(meshDimRelToMaxExt==1)
3476 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3477 if(meshDimRelToMaxExt>1)
3478 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3479 int tracucedRk=-meshDimRelToMaxExt;
3480 if(tracucedRk>=(int)_ms.size())
3481 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3482 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3483 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3484 return _ms[tracucedRk];
3487 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3489 if(-meshDimRelToMax>=(int)_ms.size())
3490 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3492 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3494 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3496 int ref=(*it)->getMeshDimension();
3497 if(ref+i!=meshDim-meshDimRelToMax)
3498 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3504 * Sets the node coordinates array of \a this mesh.
3505 * \param [in] coords - the new node coordinates array.
3506 * \throw If \a coords == \c NULL.
3508 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3511 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3512 coords->checkAllocated();
3513 int nbOfTuples=coords->getNumberOfTuples();
3516 _fam_coords=DataArrayInt::New();
3517 _fam_coords->alloc(nbOfTuples,1);
3518 _fam_coords->fillWithZero();
3519 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3520 if((MEDFileUMeshSplitL1 *)(*it))
3521 (*it)->setCoords(coords);
3525 * Removes all groups of a given dimension in \a this mesh.
3526 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3527 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3529 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3531 if(meshDimRelToMaxExt==1)
3533 if((DataArrayInt *)_fam_coords)
3534 _fam_coords->fillWithZero();
3537 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3538 l1->eraseFamilyField();
3543 * Removes all families with ids not present in the family fields of \a this mesh.
3545 void MEDFileUMesh::optimizeFamilies()
3547 std::vector<int> levs=getNonEmptyLevelsExt();
3548 std::set<int> allFamsIds;
3549 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3551 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3552 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3554 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3557 std::set<std::string> famNamesToKill;
3558 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3560 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3561 famNamesToKill.insert((*it).first);
3563 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3564 _families.erase(*it);
3565 std::vector<std::string> grpNamesToKill;
3566 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3568 std::vector<std::string> tmp;
3569 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3571 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3572 tmp.push_back(*it2);
3577 tmp.push_back((*it).first);
3579 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3583 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3585 std::vector<int> levs=getNonEmptyLevels();
3586 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3587 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3588 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3589 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3590 int nbNodes=m0->getNumberOfNodes();
3591 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3592 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3593 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3594 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3595 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3596 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3597 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3598 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3599 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3600 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3601 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3602 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3603 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3604 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3605 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3606 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3607 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3608 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3609 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3610 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3611 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3612 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3613 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3614 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3615 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3616 m0->setCoords(tmp0->getCoords());
3617 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3618 m1->setCoords(m0->getCoords());
3619 _coords=m0->getCoords(); _coords->incrRef();
3620 // duplication of cells in group 'grpNameM1' on level -1
3621 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3622 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3623 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3624 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3625 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3627 newm1->setName(getName());
3628 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3630 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3632 newFam->alloc(newm1->getNumberOfCells(),1);
3633 int idd=getMaxFamilyId()+1;
3634 int globStart=0,start=0,end,globEnd;
3635 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3636 for(int i=0;i<nbOfChunks;i++)
3638 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3639 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3641 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3642 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3643 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3648 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3652 newm1->setCoords(getCoords());
3653 setMeshAtLevel(-1,newm1);
3654 setFamilyFieldArr(-1,newFam);
3655 std::string grpName2(grpNameM1); grpName2+="_dup";
3656 addFamily(grpName2,idd);
3657 addFamilyOnGrp(grpName2,grpName2);
3662 int newNbOfNodes=getCoords()->getNumberOfTuples();
3663 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3664 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3665 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3668 nodesDuplicated=nodeIdsToDuplicate.retn();
3669 cellsModified=cellsToModifyConn0.retn();
3670 cellsNotModified=cellsToModifyConn1.retn();
3674 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3675 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3676 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3678 * \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.
3679 * 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.
3681 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3683 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3684 std::vector<int> levs=getNonEmptyLevels();
3686 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3687 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3690 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3692 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3693 std::vector<int> code1=m->getDistributionOfTypes();
3694 end=PutInThirdComponentOfCodeOffset(code1,start);
3695 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3696 bool hasChanged=m->unPolyze();
3697 DataArrayInt *fake=0;
3698 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3699 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3701 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3704 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3705 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3707 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3708 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3709 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3710 setMeshAtLevel(*it,m);
3711 std::vector<int> code2=m->getDistributionOfTypes();
3712 end=PutInThirdComponentOfCodeOffset(code2,start);
3713 newCode.insert(newCode.end(),code2.begin(),code2.end());
3715 if(o2nCellsPart2->isIdentity())
3719 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3720 setFamilyFieldArr(*it,newFamField);
3724 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3725 setRenumFieldArr(*it,newNumField);
3730 newCode.insert(newCode.end(),code1.begin(),code1.end());
3736 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3737 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3738 o2nRenumCell=o2nRenumCellRet.retn();
3743 struct MEDLoaderAccVisit1
3745 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3746 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3747 int _new_nb_of_nodes;
3751 * 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.
3752 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3753 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3754 * -1 values in returned array means that the corresponding old node is no more used.
3756 * \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
3757 * is modified in \a this.
3758 * \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
3761 DataArrayInt *MEDFileUMesh::zipCoords()
3763 const DataArrayDouble *coo(getCoords());
3765 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3766 int nbOfNodes(coo->getNumberOfTuples());
3767 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3768 std::vector<int> neLevs(getNonEmptyLevels());
3769 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3771 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
3772 if(zeLev->isMeshStoredSplitByType())
3774 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
3775 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3777 (*it)->computeNodeIdsAlg(nodeIdsInUse);
3781 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
3782 mesh->computeNodeIdsAlg(nodeIdsInUse);
3785 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
3786 if(nbrOfNodesInUse==nbOfNodes)
3787 return 0;//no need to update _part_coords
3788 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
3789 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3790 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
3791 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3792 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3793 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3794 if((const DataArrayInt *)_fam_coords)
3795 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3796 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3797 if((const DataArrayInt *)_num_coords)
3798 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3799 if((const DataArrayAsciiChar *)_name_coords)
3800 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3801 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3802 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3804 if((MEDFileUMeshSplitL1*)*it)
3806 (*it)->renumberNodesInConn(ret->begin());
3807 (*it)->setCoords(_coords);
3810 // updates _part_coords
3811 const PartDefinition *pc(_part_coords);
3814 MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
3815 _part_coords=tmpPD->composeWith(pc);
3821 * This method performs an extrusion along a path defined by \a m1D.
3822 * \a this is expected to be a mesh with max mesh dimension equal to 2.
3823 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
3824 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
3825 * This method scans all levels in \a this
3826 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
3828 * \param [in] m1D - the mesh defining the extrusion path.
3829 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
3830 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
3832 * \sa MEDCouplingUMesh::buildExtrudedMesh
3834 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
3836 if(getMeshDimension()!=2)
3837 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3838 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3839 m1D->checkCoherency();
3840 if(m1D->getMeshDimension()!=1)
3841 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3842 int nbRep(m1D->getNumberOfCells());
3843 std::vector<int> levs(getNonEmptyLevels());
3844 std::vector<std::string> grps(getGroupsNames());
3845 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3846 DataArrayDouble *coords(0);
3847 std::size_t nbOfLevsOut(levs.size()+1);
3848 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3849 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3851 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3852 item=item->clone(false);
3853 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3854 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3855 tmp->changeSpaceDimension(3+(*lev),0.);
3856 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3857 zeList.push_back(elt);
3859 coords=elt->getCoords();
3862 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3863 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3865 (*it)->setName(getName());
3866 (*it)->setCoords(coords);
3868 for(std::size_t ii=0;ii!=zeList.size();ii++)
3871 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
3874 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
3875 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
3876 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
3877 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
3878 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
3879 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
3880 std::vector<const MEDCouplingUMesh *> elts(3);
3881 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
3882 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
3883 elt->setName(getName());
3886 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
3887 ret->setMeshAtLevel(lev,elt);
3889 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
3890 endLev=endLev->clone(false); endLev->setCoords(coords);
3891 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
3892 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
3893 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
3894 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
3895 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
3896 endLev->setName(getName());
3897 ret->setMeshAtLevel(levs.back()-1,endLev);
3899 for(std::size_t ii=0;ii!=zeList.size();ii++)
3902 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3903 std::vector< const DataArrayInt * > outGrps2;
3906 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3908 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
3909 if(!grpArr->empty())
3911 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
3912 int offset0(zeList[ii]->getNumberOfCells());
3913 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
3914 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
3915 std::ostringstream oss; oss << grpArr2->getName() << "_top";
3916 grpArr2->setName(oss.str());
3917 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3918 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3919 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3920 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3925 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3927 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
3928 if(!grpArr->empty())
3930 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
3931 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
3932 std::vector< const DataArrayInt *> grpArrs2(nbRep);
3933 for(int iii=0;iii<nbRep;iii++)
3935 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
3936 grpArrs2[iii]=grpArrs[iii];
3938 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
3939 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3940 std::ostringstream grpName; grpName << *grp << "_extruded";
3941 grpArrExt->setName(grpName.str());
3942 outGrps.push_back(grpArrExt);
3943 outGrps2.push_back(grpArrExt);
3946 ret->setGroupsAtLevel(lev,outGrps2);
3948 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3949 std::vector< const DataArrayInt * > outGrps2;
3950 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3952 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
3953 if(grpArr1->empty())
3955 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
3956 std::ostringstream grpName; grpName << *grp << "_top";
3957 grpArr2->setName(grpName.str());
3958 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
3959 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3960 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3962 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
3967 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
3968 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
3969 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
3971 * \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
3972 * corresponding quadratic cells. 1 is those creating the 'most' complex.
3973 * \param [in] eps - detection threshold for coordinates.
3974 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
3976 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
3978 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
3980 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3981 int initialNbNodes(getNumberOfNodes());
3982 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
3983 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
3985 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
3987 DataArrayDouble *zeCoords(m0->getCoords());
3988 ret->setMeshAtLevel(0,m0);
3989 std::vector<int> levs(getNonEmptyLevels());
3990 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
3993 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
3994 ret->setFamilyFieldArr(0,famFieldCpy);
3996 famField=getFamilyFieldAtLevel(1);
3999 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4000 fam->fillWithZero();
4001 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4002 ret->setFamilyFieldArr(1,fam);
4004 ret->copyFamGrpMapsFrom(*this);
4005 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4006 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4010 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4011 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4013 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4015 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
4017 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4018 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4021 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4022 throw INTERP_KERNEL::Exception(oss.str().c_str());
4024 b->applyLin(1,initialNbNodes);
4025 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4026 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4027 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4028 m1->renumberNodesInConn(renum->begin());
4029 m1->setCoords(zeCoords);
4030 ret->setMeshAtLevel(*lev,m1);
4031 famField=getFamilyFieldAtLevel(*lev);
4034 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4035 ret->setFamilyFieldArr(*lev,famFieldCpy);
4042 * This method converts all quadratic cells in \a this into linear cells.
4043 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4044 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4046 * \param [in] eps - detection threshold for coordinates.
4047 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4049 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4051 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4053 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4054 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4055 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4056 m0->convertQuadraticCellsToLinear();
4058 DataArrayDouble *zeCoords(m0->getCoords());
4059 ret->setMeshAtLevel(0,m0);
4060 std::vector<int> levs(getNonEmptyLevels());
4061 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4064 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4065 ret->setFamilyFieldArr(0,famFieldCpy);
4067 famField=getFamilyFieldAtLevel(1);
4070 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
4071 ret->setFamilyFieldArr(1,fam);
4073 ret->copyFamGrpMapsFrom(*this);
4074 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4078 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4079 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4080 m1->convertQuadraticCellsToLinear();
4083 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4084 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4087 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4088 throw INTERP_KERNEL::Exception(oss.str().c_str());
4090 m1->renumberNodesInConn(b->begin());
4091 m1->setCoords(zeCoords);
4092 ret->setMeshAtLevel(*lev,m1);
4093 famField=getFamilyFieldAtLevel(*lev);
4096 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4097 ret->setFamilyFieldArr(*lev,famFieldCpy);
4103 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4105 clearNonDiscrAttributes();
4106 forceComputationOfParts();
4107 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4108 std::vector<int> layer0;
4109 layer0.push_back(_order); //0 i
4110 layer0.push_back(_iteration);//1 i
4111 layer0.push_back(getSpaceDimension());//2 i
4112 tinyDouble.push_back(_time);//0 d
4113 tinyStr.push_back(_name);//0 s
4114 tinyStr.push_back(_desc_name);//1 s
4115 for(int i=0;i<getSpaceDimension();i++)
4116 tinyStr.push_back(_coords->getInfoOnComponent(i));
4117 layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
4118 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4120 tinyStr.push_back((*it).first);
4121 layer0.push_back((*it).second);
4123 layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
4124 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4126 layer0.push_back((int)(*it0).second.size());
4127 tinyStr.push_back((*it0).first);
4128 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4129 tinyStr.push_back(*it1);
4131 // sizeof(layer0)==3+aa+1+bb layer#0
4132 bigArrayD=_coords;// 0 bd
4133 bigArraysI.push_back(_fam_coords);// 0 bi
4134 bigArraysI.push_back(_num_coords);// 1 bi
4135 const PartDefinition *pd(_part_coords);
4137 layer0.push_back(-1);
4140 std::vector<int> tmp0;
4141 pd->serialize(tmp0,bigArraysI);
4142 tinyInt.push_back(tmp0.size());
4143 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4146 std::vector<int> layer1;
4147 std::vector<int> levs(getNonEmptyLevels());
4148 layer1.push_back((int)levs.size());// 0 i <- key
4149 layer1.insert(layer1.end(),levs.begin(),levs.end());
4150 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4152 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4153 lev->serialize(layer1,bigArraysI);
4155 // put layers all together.
4156 tinyInt.push_back(layer0.size());
4157 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4158 tinyInt.push_back(layer1.size());
4159 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4162 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4163 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4165 int sz0(tinyInt[0]);
4166 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4167 int sz1(tinyInt[sz0+1]);
4168 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4170 std::reverse(layer0.begin(),layer0.end());
4171 std::reverse(layer1.begin(),layer1.end());
4172 std::reverse(tinyDouble.begin(),tinyDouble.end());
4173 std::reverse(tinyStr.begin(),tinyStr.end());
4174 std::reverse(bigArraysI.begin(),bigArraysI.end());
4176 _order=layer0.back(); layer0.pop_back();
4177 _iteration=layer0.back(); layer0.pop_back();
4178 int spaceDim(layer0.back()); layer0.pop_back();
4179 _time=tinyDouble.back(); tinyDouble.pop_back();
4180 _name=tinyStr.back(); tinyStr.pop_back();
4181 _desc_name=tinyStr.back(); tinyStr.pop_back();
4182 _coords=bigArrayD; _coords->rearrange(spaceDim);
4183 for(int i=0;i<spaceDim;i++)
4185 _coords->setInfoOnComponent(i,tinyStr.back());
4188 int nbOfFams(layer0.back()); layer0.pop_back();
4190 for(int i=0;i<nbOfFams;i++)
4192 _families[tinyStr.back()]=layer0.back();
4193 tinyStr.pop_back(); layer0.pop_back();
4195 int nbGroups(layer0.back()); layer0.pop_back();
4197 for(int i=0;i<nbGroups;i++)
4199 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4200 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4201 std::vector<std::string> fams(nbOfFamsOnGrp);
4202 for(int j=0;j<nbOfFamsOnGrp;j++)
4204 fams[j]=tinyStr.back(); tinyStr.pop_back();
4206 _groups[grpName]=fams;
4208 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4209 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4211 int isPd(layer0.back()); layer0.pop_back();
4214 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4215 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4216 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4219 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4221 int nbLevs(layer1.back()); layer1.pop_back();
4222 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4224 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4225 _ms.resize(maxLev+1);
4226 for(int i=0;i<nbLevs;i++)
4230 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4235 * Adds a group of nodes to \a this mesh.
4236 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4237 * The ids should be sorted and different each other (MED file norm).
4239 * \warning this method can alter default "FAMILLE_ZERO" family.
4240 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4242 * \throw If the node coordinates array is not set.
4243 * \throw If \a ids == \c NULL.
4244 * \throw If \a ids->getName() == "".
4245 * \throw If \a ids does not respect the MED file norm.
4246 * \throw If a group with name \a ids->getName() already exists.
4248 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4250 const DataArrayDouble *coords(_coords);
4252 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4253 int nbOfNodes(coords->getNumberOfTuples());
4254 if(!((DataArrayInt *)_fam_coords))
4255 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4257 addGroupUnderground(true,ids,_fam_coords);
4261 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4263 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4264 * The ids should be sorted and different each other (MED file norm).
4266 * \warning this method can alter default "FAMILLE_ZERO" family.
4267 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4269 * \throw If the node coordinates array is not set.
4270 * \throw If \a ids == \c NULL.
4271 * \throw If \a ids->getName() == "".
4272 * \throw If \a ids does not respect the MED file norm.
4273 * \throw If a group with name \a ids->getName() already exists.
4275 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4277 std::vector<int> levs(getNonEmptyLevelsExt());
4278 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4280 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4281 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4283 if(meshDimRelToMaxExt==1)
4284 { addNodeGroup(ids); return ; }
4285 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4286 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4287 addGroupUnderground(false,ids,fam);
4291 * Changes a name of a family specified by its id.
4292 * \param [in] id - the id of the family of interest.
4293 * \param [in] newFamName - the new family name.
4294 * \throw If no family with the given \a id exists.
4296 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4298 std::string oldName=getFamilyNameGivenId(id);
4299 _families.erase(oldName);
4300 _families[newFamName]=id;
4304 * Removes a mesh of a given dimension.
4305 * \param [in] meshDimRelToMax - the relative dimension of interest.
4306 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4308 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4310 std::vector<int> levSet=getNonEmptyLevels();
4311 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4312 if(it==levSet.end())
4313 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4314 int pos=(-meshDimRelToMax);
4319 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4320 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4321 * \param [in] m - the new mesh to set.
4322 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4324 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4325 * another node coordinates array.
4326 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4327 * to the existing meshes of other levels of \a this mesh.
4329 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4331 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4332 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4336 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4337 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4338 * \param [in] m - the new mesh to set.
4339 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4340 * writing \a this mesh in a MED file.
4341 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4343 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4344 * another node coordinates array.
4345 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4346 * to the existing meshes of other levels of \a this mesh.
4348 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4350 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4351 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4354 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4356 dealWithTinyInfo(m);
4357 std::vector<int> levSet=getNonEmptyLevels();
4358 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4360 if((DataArrayDouble *)_coords==0)
4362 DataArrayDouble *c=m->getCoords();
4367 if(m->getCoords()!=_coords)
4368 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4369 int sz=(-meshDimRelToMax)+1;
4370 if(sz>=(int)_ms.size())
4372 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4376 return _ms[-meshDimRelToMax];
4380 * This method allows to set at once the content of different levels in \a this.
4381 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4383 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4384 * \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.
4385 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4387 * \throw If \a there is a null pointer in \a ms.
4388 * \sa MEDFileUMesh::setMeshAtLevel
4390 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4394 const MEDCouplingUMesh *mRef=ms[0];
4396 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4397 std::string name(mRef->getName());
4398 const DataArrayDouble *coo(mRef->getCoords());
4401 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4403 const MEDCouplingUMesh *cur(*it);
4405 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4406 if(coo!=cur->getCoords())
4407 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4408 int mdim=cur->getMeshDimension();
4409 zeDim=std::max(zeDim,mdim);
4410 if(s.find(mdim)!=s.end())
4411 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4413 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4415 int mdim=(*it)->getMeshDimension();
4416 setName((*it)->getName());
4417 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4423 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4424 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4425 * The given meshes must share the same node coordinates array.
4426 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4427 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4428 * create in \a this mesh.
4429 * \throw If \a ms is empty.
4430 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4431 * to the existing meshes of other levels of \a this mesh.
4432 * \throw If the meshes in \a ms do not share the same node coordinates array.
4433 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4434 * of the given meshes.
4435 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4436 * \throw If names of some meshes in \a ms are equal.
4437 * \throw If \a ms includes a mesh with an empty name.
4439 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4442 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4443 int sz=(-meshDimRelToMax)+1;
4444 if(sz>=(int)_ms.size())
4446 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4447 DataArrayDouble *coo=checkMultiMesh(ms);
4448 if((DataArrayDouble *)_coords==0)
4454 if((DataArrayDouble *)_coords!=coo)
4455 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4456 std::vector<DataArrayInt *> corr;
4457 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4458 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4459 setMeshAtLevel(meshDimRelToMax,m,renum);
4460 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4461 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4465 * Creates groups at a given level in \a this mesh from a sequence of
4466 * meshes each representing a group.
4467 * The given meshes must share the same node coordinates array.
4468 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4469 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4470 * create in \a this mesh.
4471 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4473 * \throw If \a ms is empty.
4474 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4475 * to the existing meshes of other levels of \a this mesh.
4476 * \throw If the meshes in \a ms do not share the same node coordinates array.
4477 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4478 * of the given meshes.
4479 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4480 * \throw If names of some meshes in \a ms are equal.
4481 * \throw If \a ms includes a mesh with an empty name.
4483 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4486 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4487 int sz=(-meshDimRelToMax)+1;
4488 if(sz>=(int)_ms.size())
4490 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4491 DataArrayDouble *coo=checkMultiMesh(ms);
4492 if((DataArrayDouble *)_coords==0)
4498 if((DataArrayDouble *)_coords!=coo)
4499 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4500 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4501 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4503 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4505 DataArrayInt *arr=0;
4506 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4510 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4511 throw INTERP_KERNEL::Exception(oss.str().c_str());
4514 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4515 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4518 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4520 const DataArrayDouble *ret=ms[0]->getCoords();
4521 int mdim=ms[0]->getMeshDimension();
4522 for(unsigned int i=1;i<ms.size();i++)
4524 ms[i]->checkCoherency();
4525 if(ms[i]->getCoords()!=ret)
4526 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4527 if(ms[i]->getMeshDimension()!=mdim)
4528 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4530 return const_cast<DataArrayDouble *>(ret);
4534 * Sets the family field of a given relative dimension.
4535 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4536 * the family field is set.
4537 * \param [in] famArr - the array of the family field.
4538 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4539 * \throw If \a famArr has an invalid size.
4541 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4543 if(meshDimRelToMaxExt==1)
4550 DataArrayDouble *coo(_coords);
4552 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4553 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4558 if(meshDimRelToMaxExt>1)
4559 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4560 int traducedRk=-meshDimRelToMaxExt;
4561 if(traducedRk>=(int)_ms.size())
4562 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4563 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4564 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4565 return _ms[traducedRk]->setFamilyArr(famArr);
4569 * Sets the optional numbers of mesh entities of a given dimension.
4570 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4571 * \param [in] renumArr - the array of the numbers.
4572 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4573 * \throw If \a renumArr has an invalid size.
4575 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4577 if(meshDimRelToMaxExt==1)
4585 DataArrayDouble *coo(_coords);
4587 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4588 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4589 renumArr->incrRef();
4590 _num_coords=renumArr;
4594 if(meshDimRelToMaxExt>1)
4595 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4596 int traducedRk=-meshDimRelToMaxExt;
4597 if(traducedRk>=(int)_ms.size())
4598 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4599 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4600 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4601 return _ms[traducedRk]->setRenumArr(renumArr);
4605 * Sets the optional names of mesh entities of a given dimension.
4606 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4607 * \param [in] nameArr - the array of the names.
4608 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4609 * \throw If \a nameArr has an invalid size.
4611 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4613 if(meshDimRelToMaxExt==1)
4620 DataArrayDouble *coo(_coords);
4622 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4623 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4625 _name_coords=nameArr;
4628 if(meshDimRelToMaxExt>1)
4629 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4630 int traducedRk=-meshDimRelToMaxExt;
4631 if(traducedRk>=(int)_ms.size())
4632 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4633 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4634 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4635 return _ms[traducedRk]->setNameArr(nameArr);
4638 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4640 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4641 if((const MEDFileUMeshSplitL1 *)(*it))
4642 (*it)->synchronizeTinyInfo(*this);
4646 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4648 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4650 DataArrayInt *arr=_fam_coords;
4652 arr->changeValue(oldId,newId);
4653 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4655 MEDFileUMeshSplitL1 *sp=(*it);
4658 sp->changeFamilyIdArr(oldId,newId);
4663 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4665 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4666 const DataArrayInt *da(_fam_coords);
4668 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4669 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4671 const MEDFileUMeshSplitL1 *elt(*it);
4674 da=elt->getFamilyField();
4676 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4682 void MEDFileUMesh::computeRevNum() const
4684 if((const DataArrayInt *)_num_coords)
4687 int maxValue=_num_coords->getMaxValue(pos);
4688 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4692 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4694 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4697 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4699 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4700 ret.push_back((const DataArrayInt *)_fam_nodes);
4701 ret.push_back((const DataArrayInt *)_num_nodes);
4702 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4703 ret.push_back((const DataArrayInt *)_fam_cells);
4704 ret.push_back((const DataArrayInt *)_num_cells);
4705 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4706 ret.push_back((const DataArrayInt *)_fam_faces);
4707 ret.push_back((const DataArrayInt *)_num_faces);
4708 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4709 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4710 ret.push_back((const DataArrayInt *)_rev_num_cells);
4711 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4715 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4717 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4718 if((const DataArrayInt *)_fam_nodes)
4720 int val=_fam_nodes->getMaxValue(tmp);
4721 ret=std::max(ret,std::abs(val));
4723 if((const DataArrayInt *)_fam_cells)
4725 int val=_fam_cells->getMaxValue(tmp);
4726 ret=std::max(ret,std::abs(val));
4728 if((const DataArrayInt *)_fam_faces)
4730 int val=_fam_faces->getMaxValue(tmp);
4731 ret=std::max(ret,std::abs(val));
4736 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4738 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4739 if((const DataArrayInt *)_fam_nodes)
4741 int val=_fam_nodes->getMaxValue(tmp);
4742 ret=std::max(ret,val);
4744 if((const DataArrayInt *)_fam_cells)
4746 int val=_fam_cells->getMaxValue(tmp);
4747 ret=std::max(ret,val);
4749 if((const DataArrayInt *)_fam_faces)
4751 int val=_fam_faces->getMaxValue(tmp);
4752 ret=std::max(ret,val);
4757 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4759 int ret=std::numeric_limits<int>::max(),tmp=-1;
4760 if((const DataArrayInt *)_fam_nodes)
4762 int val=_fam_nodes->getMinValue(tmp);
4763 ret=std::min(ret,val);
4765 if((const DataArrayInt *)_fam_cells)
4767 int val=_fam_cells->getMinValue(tmp);
4768 ret=std::min(ret,val);
4770 if((const DataArrayInt *)_fam_faces)
4772 int val=_fam_faces->getMinValue(tmp);
4773 ret=std::min(ret,val);
4778 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4780 if(!MEDFileMesh::isEqual(other,eps,what))
4782 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4785 what="Mesh types differ ! This is structured and other is NOT !";
4788 const DataArrayInt *famc1=_fam_nodes;
4789 const DataArrayInt *famc2=otherC->_fam_nodes;
4790 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4792 what="Mismatch of families arr on nodes ! One is defined and not other !";
4797 bool ret=famc1->isEqual(*famc2);
4800 what="Families arr on nodes differ !";
4805 famc2=otherC->_fam_cells;
4806 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4808 what="Mismatch of families arr on cells ! One is defined and not other !";
4813 bool ret=famc1->isEqual(*famc2);
4816 what="Families arr on cells differ !";
4821 famc2=otherC->_fam_faces;
4822 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4824 what="Mismatch of families arr on faces ! One is defined and not other !";
4829 bool ret=famc1->isEqual(*famc2);
4832 what="Families arr on faces differ !";
4837 famc2=otherC->_num_nodes;
4838 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4840 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4845 bool ret=famc1->isEqual(*famc2);
4848 what="Numbering arr on nodes differ !";
4853 famc2=otherC->_num_cells;
4854 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4856 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4861 bool ret=famc1->isEqual(*famc2);
4864 what="Numbering arr on cells differ !";
4869 famc2=otherC->_num_faces;
4870 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4872 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4877 bool ret=famc1->isEqual(*famc2);
4880 what="Numbering arr on faces differ !";
4884 const DataArrayAsciiChar *d1=_names_cells;
4885 const DataArrayAsciiChar *d2=otherC->_names_cells;
4886 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4888 what="Mismatch of naming arr on cells ! One is defined and not other !";
4893 bool ret=d1->isEqual(*d2);
4896 what="Naming arr on cells differ !";
4901 d2=otherC->_names_faces;
4902 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4904 what="Mismatch of naming arr on faces ! One is defined and not other !";
4909 bool ret=d1->isEqual(*d2);
4912 what="Naming arr on faces differ !";
4917 d2=otherC->_names_nodes;
4918 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4920 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4925 bool ret=d1->isEqual(*d2);
4928 what="Naming arr on nodes differ !";
4935 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4937 MEDFileMesh::clearNonDiscrAttributes();
4938 const DataArrayInt *tmp=_fam_nodes;
4940 (const_cast<DataArrayInt *>(tmp))->setName("");
4943 (const_cast<DataArrayInt *>(tmp))->setName("");
4946 (const_cast<DataArrayInt *>(tmp))->setName("");
4949 (const_cast<DataArrayInt *>(tmp))->setName("");
4952 (const_cast<DataArrayInt *>(tmp))->setName("");
4955 (const_cast<DataArrayInt *>(tmp))->setName("");
4959 * Returns ids of mesh entities contained in given families of a given dimension.
4960 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4962 * \param [in] fams - the names of the families of interest.
4963 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4964 * returned instead of ids.
4965 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4966 * numbers, if available and required, of mesh entities of the families. The caller
4967 * is to delete this array using decrRef() as it is no more needed.
4968 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4970 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4972 std::vector<int> famIds(getFamiliesIds(fams));
4973 switch(meshDimRelToMaxExt)
4977 if((const DataArrayInt *)_fam_nodes)
4979 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4981 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4983 da=_fam_nodes->getIdsEqualList(0,0);
4985 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4990 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4995 if((const DataArrayInt *)_fam_cells)
4997 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4999 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5001 da=_fam_cells->getIdsEqualList(0,0);
5003 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5008 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5013 if((const DataArrayInt *)_fam_faces)
5015 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5017 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5019 da=_fam_faces->getIdsEqualList(0,0);
5021 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5026 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5030 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5032 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5036 * Sets the family field of a given relative dimension.
5037 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5038 * the family field is set.
5039 * \param [in] famArr - the array of the family field.
5040 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5041 * \throw If \a famArr has an invalid size.
5042 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5044 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5046 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5048 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5049 switch(meshDimRelToMaxExt)
5053 int nbCells=mesh->getNumberOfCells();
5054 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5060 int nbNodes=mesh->getNumberOfNodes();
5061 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5067 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5068 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5073 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5080 * Sets the optional numbers of mesh entities of a given dimension.
5081 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5082 * \param [in] renumArr - the array of the numbers.
5083 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5084 * \throw If \a renumArr has an invalid size.
5085 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5087 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5089 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5091 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5092 switch(meshDimRelToMaxExt)
5096 int nbCells=mesh->getNumberOfCells();
5097 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5098 _num_cells=renumArr;
5103 int nbNodes=mesh->getNumberOfNodes();
5104 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5105 _num_nodes=renumArr;
5110 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5111 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5112 _num_faces=renumArr;
5116 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5119 renumArr->incrRef();
5123 * Sets the optional names of mesh entities of a given dimension.
5124 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5125 * \param [in] nameArr - the array of the names.
5126 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5127 * \throw If \a nameArr has an invalid size.
5129 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5131 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5133 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5134 switch(meshDimRelToMaxExt)
5138 int nbCells=mesh->getNumberOfCells();
5139 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5140 _names_cells=nameArr;
5145 int nbNodes=mesh->getNumberOfNodes();
5146 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5147 _names_nodes=nameArr;
5152 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5153 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5154 _names_cells=nameArr;
5157 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5164 * Adds a group of nodes to \a this mesh.
5165 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5166 * The ids should be sorted and different each other (MED file norm).
5168 * \warning this method can alter default "FAMILLE_ZERO" family.
5169 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5171 * \throw If the node coordinates array is not set.
5172 * \throw If \a ids == \c NULL.
5173 * \throw If \a ids->getName() == "".
5174 * \throw If \a ids does not respect the MED file norm.
5175 * \throw If a group with name \a ids->getName() already exists.
5177 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5183 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5185 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5186 * The ids should be sorted and different each other (MED file norm).
5188 * \warning this method can alter default "FAMILLE_ZERO" family.
5189 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5191 * \throw If the node coordinates array is not set.
5192 * \throw If \a ids == \c NULL.
5193 * \throw If \a ids->getName() == "".
5194 * \throw If \a ids does not respect the MED file norm.
5195 * \throw If a group with name \a ids->getName() already exists.
5197 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5199 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5200 addGroupUnderground(false,ids,fam);
5205 * Returns the family field for mesh entities of a given dimension.
5206 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5207 * \return const DataArrayInt * - the family field. It is an array of ids of families
5208 * each mesh entity belongs to. It can be \c NULL.
5209 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5211 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5213 switch(meshDimRelToMaxExt)
5222 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5227 * Returns the family field for mesh entities of a given dimension.
5228 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5229 * \return const DataArrayInt * - the family field. It is an array of ids of families
5230 * each mesh entity belongs to. It can be \c NULL.
5231 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5233 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5235 switch(meshDimRelToMaxExt)
5244 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5249 * Returns the optional numbers of mesh entities of a given dimension.
5250 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5251 * \return const DataArrayInt * - the array of the entity numbers.
5252 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5253 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5255 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5257 switch(meshDimRelToMaxExt)
5266 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5271 * Returns the optional numbers of mesh entities of a given dimension transformed using
5272 * DataArrayInt::invertArrayN2O2O2N().
5273 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5274 * \return const DataArrayInt * - the array of the entity numbers transformed using
5275 * DataArrayInt::invertArrayN2O2O2N().
5276 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5277 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5279 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5281 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5282 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5283 if(meshDimRelToMaxExt==0)
5285 if((const DataArrayInt *)_num_cells)
5288 int maxValue=_num_cells->getMaxValue(pos);
5289 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5290 return _rev_num_cells;
5293 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5297 if((const DataArrayInt *)_num_nodes)
5300 int maxValue=_num_nodes->getMaxValue(pos);
5301 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5302 return _rev_num_nodes;
5305 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5309 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5311 switch(meshDimRelToMaxExt)
5314 return _names_cells;
5316 return _names_nodes;
5318 return _names_faces;
5320 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5325 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5326 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5328 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5330 std::vector<int> ret(1);
5335 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5336 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5338 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5340 std::vector<int> ret(2);
5346 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5348 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5350 std::vector<int> ret;
5351 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5362 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5364 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5366 std::vector<int> ret;
5367 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5378 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5380 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5382 std::vector<int> ret;
5383 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5394 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5396 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5398 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5402 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5404 DataArrayInt *arr=_fam_nodes;
5406 arr->changeValue(oldId,newId);
5409 arr->changeValue(oldId,newId);
5412 arr->changeValue(oldId,newId);
5415 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5417 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
5418 const DataArrayInt *da(_fam_nodes);
5420 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5423 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5426 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5430 void MEDFileStructuredMesh::deepCpyAttributes()
5432 if((const DataArrayInt*)_fam_nodes)
5433 _fam_nodes=_fam_nodes->deepCpy();
5434 if((const DataArrayInt*)_num_nodes)
5435 _num_nodes=_num_nodes->deepCpy();
5436 if((const DataArrayAsciiChar*)_names_nodes)
5437 _names_nodes=_names_nodes->deepCpy();
5438 if((const DataArrayInt*)_fam_cells)
5439 _fam_cells=_fam_cells->deepCpy();
5440 if((const DataArrayInt*)_num_cells)
5441 _num_cells=_num_cells->deepCpy();
5442 if((const DataArrayAsciiChar*)_names_cells)
5443 _names_cells=_names_cells->deepCpy();
5444 if((const DataArrayInt*)_fam_faces)
5445 _fam_faces=_fam_faces->deepCpy();
5446 if((const DataArrayInt*)_num_faces)
5447 _num_faces=_num_faces->deepCpy();
5448 if((const DataArrayAsciiChar*)_names_faces)
5449 _names_faces=_names_faces->deepCpy();
5450 if((const DataArrayInt*)_rev_num_nodes)
5451 _rev_num_nodes=_rev_num_nodes->deepCpy();
5452 if((const DataArrayInt*)_rev_num_cells)
5453 _rev_num_cells=_rev_num_cells->deepCpy();
5457 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5459 * \return a pointer to cartesian mesh that need to be managed by the caller.
5460 * \warning the returned pointer has to be managed by the caller.
5464 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5465 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5466 * \param [in] renum - it must be \c false.
5467 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5468 * delete using decrRef() as it is no more needed.
5470 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
5473 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5474 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5475 switch(meshDimRelToMax)
5481 return const_cast<MEDCouplingStructuredMesh *>(m);
5486 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5487 buildMinusOneImplicitPartIfNeeded();
5488 MEDCouplingMesh *ret(_faces_if_necessary);
5494 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5499 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5500 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5501 * \return int - the number of entities.
5502 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5504 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5506 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5508 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5509 switch(meshDimRelToMaxExt)
5512 return cmesh->getNumberOfCells();
5514 return cmesh->getNumberOfNodes();
5516 return cmesh->getNumberOfCellsOfSubLevelMesh();
5518 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5522 int MEDFileStructuredMesh::getNumberOfNodes() const
5524 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5526 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5527 return cmesh->getNumberOfNodes();
5530 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
5532 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5534 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5535 switch(meshDimRelToMaxExt)
5538 return cmesh->getNumberOfCells();
5540 return cmesh->getNumberOfCellsOfSubLevelMesh();
5542 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
5546 bool MEDFileStructuredMesh::hasImplicitPart() const
5552 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5554 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5556 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5557 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5560 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5561 if(cm.getReverseExtrudedType()!=gt)
5562 throw INTERP_KERNEL::Exception(MSG);
5563 buildImplicitPart();
5564 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5568 if(gt!=zeFaceMesh->getCellModelEnum())
5569 throw INTERP_KERNEL::Exception(MSG);
5570 return zeFaceMesh->getNumberOfCells();
5574 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5576 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5578 buildImplicitPart();
5581 void MEDFileStructuredMesh::buildImplicitPart() const
5583 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5585 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5586 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5589 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5591 _faces_if_necessary=0;
5595 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5596 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5598 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5600 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5602 return _faces_if_necessary;
5605 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5607 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5609 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5610 switch(meshDimRelToMax)
5614 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5619 int mdim(cmesh->getMeshDimension());
5621 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5622 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5626 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5630 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5632 if(st.getNumberOfItems()!=1)
5633 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 !");
5634 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5635 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5636 if(getNumberOfNodes()!=(int)nodesFetched.size())
5637 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5638 if(st[0].getPflName().empty())
5640 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5643 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5644 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5645 int sz(nodesFetched.size());
5646 for(const int *work=arr->begin();work!=arr->end();work++)
5648 std::vector<int> conn;
5649 cmesh->getNodeIdsOfCell(*work,conn);
5650 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5651 if(*it>=0 && *it<sz)
5652 nodesFetched[*it]=true;
5654 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5658 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5660 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5664 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5665 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5667 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5668 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5670 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5673 if(!mrs || mrs->isCellFamilyFieldReading())
5675 famCells=DataArrayInt::New();
5676 famCells->alloc(nbOfElt,1);
5677 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer());
5680 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5683 if(!mrs || mrs->isCellNumFieldReading())
5685 numCells=DataArrayInt::New();
5686 numCells->alloc(nbOfElt,1);
5687 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer());
5690 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5693 if(!mrs || mrs->isCellNameFieldReading())
5695 namesCells=DataArrayAsciiChar::New();
5696 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5697 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer());
5698 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5703 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5705 setName(strm->getName());
5706 setDescription(strm->getDescription());
5707 setUnivName(strm->getUnivName());
5708 setIteration(strm->getIteration());
5709 setOrder(strm->getOrder());
5710 setTimeValue(strm->getTime());
5711 setTimeUnit(strm->getTimeUnit());
5712 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5713 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5714 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5717 if(!mrs || mrs->isNodeFamilyFieldReading())
5719 int nbNodes(getNumberOfNodes());
5721 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5722 _fam_nodes=DataArrayInt::New();
5723 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5724 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...
5725 _fam_nodes->fillWithZero();
5726 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
5729 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5732 if(!mrs || mrs->isNodeNumFieldReading())
5734 _num_nodes=DataArrayInt::New();
5735 _num_nodes->alloc(nbOfElt,1);
5736 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
5739 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5742 if(!mrs || mrs->isNodeNameFieldReading())
5744 _names_nodes=DataArrayAsciiChar::New();
5745 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5746 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
5747 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5750 int meshDim(getStructuredMesh()->getMeshDimension());
5751 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5753 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5756 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5758 int meshDim(getStructuredMesh()->getMeshDimension());
5759 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5761 if((const DataArrayInt *)_fam_cells)
5762 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
5763 if((const DataArrayInt *)_fam_faces)
5764 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer());
5765 if((const DataArrayInt *)_fam_nodes)
5766 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
5767 if((const DataArrayInt *)_num_cells)
5768 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
5769 if((const DataArrayInt *)_num_faces)
5770 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer());
5771 if((const DataArrayInt *)_num_nodes)
5772 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
5773 if((const DataArrayAsciiChar *)_names_cells)
5775 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5777 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5778 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5779 throw INTERP_KERNEL::Exception(oss.str().c_str());
5781 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
5783 if((const DataArrayAsciiChar *)_names_faces)
5785 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5787 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5788 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5789 throw INTERP_KERNEL::Exception(oss.str().c_str());
5791 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer());
5793 if((const DataArrayAsciiChar *)_names_nodes)
5795 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5797 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5798 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5799 throw INTERP_KERNEL::Exception(oss.str().c_str());
5801 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
5804 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5808 * Returns an empty instance of MEDFileCMesh.
5809 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5810 * mesh using decrRef() as it is no more needed.
5812 MEDFileCMesh *MEDFileCMesh::New()
5814 return new MEDFileCMesh;
5818 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5819 * file. The first mesh in the file is loaded.
5820 * \param [in] fileName - the name of MED file to read.
5821 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5822 * mesh using decrRef() as it is no more needed.
5823 * \throw If the file is not readable.
5824 * \throw If there is no meshes in the file.
5825 * \throw If the mesh in the file is not a Cartesian one.
5827 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5829 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5832 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5833 throw INTERP_KERNEL::Exception(oss.str().c_str());
5835 MEDFileUtilities::CheckFileForRead(fileName);
5836 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5838 ParaMEDMEM::MEDCouplingMeshType meshType;
5840 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5841 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5845 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5846 * file. The mesh to load is specified by its name and numbers of a time step and an
5848 * \param [in] fileName - the name of MED file to read.
5849 * \param [in] mName - the name of the mesh to read.
5850 * \param [in] dt - the number of a time step.
5851 * \param [in] it - the number of an iteration.
5852 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5853 * mesh using decrRef() as it is no more needed.
5854 * \throw If the file is not readable.
5855 * \throw If there is no mesh with given attributes in the file.
5856 * \throw If the mesh in the file is not a Cartesian one.
5858 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5860 MEDFileUtilities::CheckFileForRead(fileName);
5861 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5862 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5865 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5867 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5870 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5872 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5873 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5878 * Returns the dimension on cells in \a this mesh.
5879 * \return int - the mesh dimension.
5880 * \throw If there are no cells in this mesh.
5882 int MEDFileCMesh::getMeshDimension() const
5884 if(!((const MEDCouplingCMesh*)_cmesh))
5885 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5886 return _cmesh->getMeshDimension();
5890 * Returns the dimension on nodes in \a this mesh.
5891 * \return int - the space dimension.
5892 * \throw If there are no cells in this mesh.
5894 int MEDFileCMesh::getSpaceDimension() const
5896 if(!((const MEDCouplingCMesh*)_cmesh))
5897 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5898 return _cmesh->getSpaceDimension();
5902 * Returns a string describing \a this mesh.
5903 * \return std::string - the mesh information string.
5905 std::string MEDFileCMesh::simpleRepr() const
5907 return MEDFileStructuredMesh::simpleRepr();
5911 * Returns a full textual description of \a this mesh.
5912 * \return std::string - the string holding the mesh description.
5914 std::string MEDFileCMesh::advancedRepr() const
5916 return simpleRepr();
5919 MEDFileMesh *MEDFileCMesh::shallowCpy() const
5921 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5925 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
5927 return new MEDFileCMesh;
5930 MEDFileMesh *MEDFileCMesh::deepCpy() const
5932 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5933 if((const MEDCouplingCMesh*)_cmesh)
5934 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
5935 ret->deepCpyAttributes();
5940 * Checks if \a this and another mesh are equal.
5941 * \param [in] other - the mesh to compare with.
5942 * \param [in] eps - a precision used to compare real values.
5943 * \param [in,out] what - the string returning description of unequal data.
5944 * \return bool - \c true if the meshes are equal, \c false, else.
5946 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5948 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5950 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
5953 what="Mesh types differ ! This is cartesian and other is NOT !";
5956 clearNonDiscrAttributes();
5957 otherC->clearNonDiscrAttributes();
5958 const MEDCouplingCMesh *coo1=_cmesh;
5959 const MEDCouplingCMesh *coo2=otherC->_cmesh;
5960 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5962 what="Mismatch of cartesian meshes ! One is defined and not other !";
5967 bool ret=coo1->isEqual(coo2,eps);
5970 what="cartesian meshes differ !";
5978 * Clears redundant attributes of incorporated data arrays.
5980 void MEDFileCMesh::clearNonDiscrAttributes() const
5982 MEDFileStructuredMesh::clearNonDiscrAttributes();
5983 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
5986 MEDFileCMesh::MEDFileCMesh()
5990 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5993 loadCMeshFromFile(fid,mName,dt,it,mrs);
5994 loadJointsFromFile(fid);
5996 catch(INTERP_KERNEL::Exception& e)
6001 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6003 ParaMEDMEM::MEDCouplingMeshType meshType;
6006 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6007 if(meshType!=CARTESIAN)
6009 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6010 throw INTERP_KERNEL::Exception(oss.str().c_str());
6012 MEDFileCMeshL2 loaderl2;
6013 loaderl2.loadAll(fid,mid,mName,dt,it);
6014 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6017 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6021 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6022 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6024 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6026 synchronizeTinyInfoOnLeaves();
6030 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6032 synchronizeTinyInfoOnLeaves();
6037 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6038 * \param [in] m - the new MEDCouplingCMesh to refer to.
6039 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6042 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6044 dealWithTinyInfo(m);
6050 void MEDFileCMesh::writeLL(med_idt fid) const
6052 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6053 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6054 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6055 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6056 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6057 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6058 int spaceDim(_cmesh->getSpaceDimension());
6059 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6060 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6061 for(int i=0;i<spaceDim;i++)
6063 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6065 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6066 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
6067 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
6069 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
6070 MEDmeshUniversalNameWr(fid,maa);
6071 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
6072 for(int i=0;i<spaceDim;i++)
6074 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6075 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
6078 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6079 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6084 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6086 const MEDCouplingCMesh *cmesh=_cmesh;
6089 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6090 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6091 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6092 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6095 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6097 return new MEDFileCurveLinearMesh;
6100 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6102 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6105 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6106 throw INTERP_KERNEL::Exception(oss.str().c_str());
6108 MEDFileUtilities::CheckFileForRead(fileName);
6109 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6111 ParaMEDMEM::MEDCouplingMeshType meshType;
6113 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6114 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6117 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6119 MEDFileUtilities::CheckFileForRead(fileName);
6120 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6121 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6124 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6126 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6129 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6131 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6132 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6136 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
6138 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6142 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6144 return new MEDFileCurveLinearMesh;
6147 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
6149 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6150 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6151 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
6152 ret->deepCpyAttributes();
6156 int MEDFileCurveLinearMesh::getMeshDimension() const
6158 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6159 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6160 return _clmesh->getMeshDimension();
6163 std::string MEDFileCurveLinearMesh::simpleRepr() const
6165 return MEDFileStructuredMesh::simpleRepr();
6168 std::string MEDFileCurveLinearMesh::advancedRepr() const
6170 return simpleRepr();
6173 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6175 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6177 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6180 what="Mesh types differ ! This is curve linear and other is NOT !";
6183 clearNonDiscrAttributes();
6184 otherC->clearNonDiscrAttributes();
6185 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6186 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6187 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6189 what="Mismatch of curve linear meshes ! One is defined and not other !";
6194 bool ret=coo1->isEqual(coo2,eps);
6197 what="curve linear meshes differ !";
6204 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6206 MEDFileStructuredMesh::clearNonDiscrAttributes();
6207 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6210 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6212 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6215 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6216 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6217 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6218 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6221 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6223 synchronizeTinyInfoOnLeaves();
6227 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6229 dealWithTinyInfo(m);
6235 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6237 synchronizeTinyInfoOnLeaves();
6241 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6245 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6248 loadCLMeshFromFile(fid,mName,dt,it,mrs);
6249 loadJointsFromFile(fid);
6251 catch(INTERP_KERNEL::Exception& e)
6256 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6258 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6259 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6260 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6261 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6262 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6263 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6264 int spaceDim=_clmesh->getSpaceDimension();
6265 int meshDim=_clmesh->getMeshDimension();
6266 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6267 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6268 const DataArrayDouble *coords=_clmesh->getCoords();
6270 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6271 for(int i=0;i<spaceDim;i++)
6273 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6275 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6276 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
6277 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
6279 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
6280 MEDmeshUniversalNameWr(fid,maa);
6281 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
6282 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6283 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
6285 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
6287 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6288 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6293 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6295 ParaMEDMEM::MEDCouplingMeshType meshType;
6298 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6299 if(meshType!=CURVE_LINEAR)
6301 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6302 throw INTERP_KERNEL::Exception(oss.str().c_str());
6304 MEDFileCLMeshL2 loaderl2;
6305 loaderl2.loadAll(fid,mid,mName,dt,it);
6306 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6309 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6312 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6314 return new MEDFileMeshMultiTS;
6317 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6319 return new MEDFileMeshMultiTS(fileName);
6322 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6324 return new MEDFileMeshMultiTS(fileName,mName);
6327 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
6329 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6330 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6332 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6333 if((const MEDFileMesh *)*it)
6334 meshOneTs[i]=(*it)->deepCpy();
6335 ret->_mesh_one_ts=meshOneTs;
6339 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6341 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
6344 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6346 std::vector<const BigMemoryObject *> ret;
6347 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6348 ret.push_back((const MEDFileMesh *)*it);
6352 std::string MEDFileMeshMultiTS::getName() const
6354 if(_mesh_one_ts.empty())
6355 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6356 return _mesh_one_ts[0]->getName();
6359 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6361 std::string oldName(getName());
6362 std::vector< std::pair<std::string,std::string> > v(1);
6363 v[0].first=oldName; v[0].second=newMeshName;
6367 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6370 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6372 MEDFileMesh *cur(*it);
6374 ret=cur->changeNames(modifTab) || ret;
6379 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6381 if(_mesh_one_ts.empty())
6382 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6383 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6386 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6389 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6390 _mesh_one_ts.resize(1);
6391 mesh1TimeStep->incrRef();
6392 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
6393 _mesh_one_ts[0]=mesh1TimeStep;
6396 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
6398 if ( MEDFileMesh* m = getOneTimeStep() )
6399 return m->getJoints();
6404 * \brief Set Joints that are common to all time-stamps
6406 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
6408 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6410 (*it)->setJoints( joints );
6414 void MEDFileMeshMultiTS::write(med_idt fid) const
6416 MEDFileJoints * joints = getJoints();
6417 bool jointsWritten = false;
6419 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6421 if ( jointsWritten )
6422 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
6424 jointsWritten = true;
6426 (*it)->copyOptionsFrom(*this);
6430 ((MEDFileMeshMultiTS*)this)->setJoints( joints ); // restore joints
6433 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6435 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6436 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6437 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6438 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6442 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6444 MEDFileJoints* joints = 0;
6445 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
6447 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
6448 joints = getOneTimeStep()->getJoints();
6451 _mesh_one_ts.clear(); //for the moment to be improved
6452 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
6455 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6459 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6462 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6465 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6466 throw INTERP_KERNEL::Exception(oss.str().c_str());
6468 MEDFileUtilities::CheckFileForRead(fileName);
6469 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6471 ParaMEDMEM::MEDCouplingMeshType meshType;
6473 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6474 loadFromFile(fileName,ms.front());
6476 catch(INTERP_KERNEL::Exception& e)
6481 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6484 loadFromFile(fileName,mName);
6486 catch(INTERP_KERNEL::Exception& e)
6491 MEDFileMeshes *MEDFileMeshes::New()
6493 return new MEDFileMeshes;
6496 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6498 return new MEDFileMeshes(fileName);
6501 void MEDFileMeshes::write(med_idt fid) const
6504 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6506 (*it)->copyOptionsFrom(*this);
6511 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6513 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6514 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6515 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6516 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6521 int MEDFileMeshes::getNumberOfMeshes() const
6523 return _meshes.size();
6526 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6528 return new MEDFileMeshesIterator(this);
6531 /** Return a borrowed reference (caller is not responsible) */
6532 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6534 if(i<0 || i>=(int)_meshes.size())
6536 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6537 throw INTERP_KERNEL::Exception(oss.str().c_str());
6539 return _meshes[i]->getOneTimeStep();
6542 /** Return a borrowed reference (caller is not responsible) */
6543 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6545 std::vector<std::string> ms=getMeshesNames();
6546 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6549 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6550 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6551 throw INTERP_KERNEL::Exception(oss.str().c_str());
6553 return getMeshAtPos((int)std::distance(ms.begin(),it));
6556 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6558 std::vector<std::string> ret(_meshes.size());
6560 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6562 const MEDFileMeshMultiTS *f=(*it);
6565 ret[i]=f->getName();
6569 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6570 throw INTERP_KERNEL::Exception(oss.str().c_str());
6575 /*const MEDFileJoints* MEDFileMeshes::getJoints() const
6577 const MEDFileJoints *ret=_joints;
6580 std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !";
6581 throw INTERP_KERNEL::Exception(oss.str().c_str());
6586 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6589 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6591 MEDFileMeshMultiTS *cur(*it);
6593 ret=cur->changeNames(modifTab) || ret;
6598 void MEDFileMeshes::resize(int newSize)
6600 _meshes.resize(newSize);
6603 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6606 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6607 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6608 elt->setOneTimeStep(mesh);
6609 _meshes.push_back(elt);
6612 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6615 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6616 if(i>=(int)_meshes.size())
6617 _meshes.resize(i+1);
6618 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6619 elt->setOneTimeStep(mesh);
6623 void MEDFileMeshes::destroyMeshAtPos(int i)
6625 if(i<0 || i>=(int)_meshes.size())
6627 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6628 throw INTERP_KERNEL::Exception(oss.str().c_str());
6630 _meshes.erase(_meshes.begin()+i);
6633 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6635 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6637 _meshes.resize(ms.size());
6638 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6639 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6642 MEDFileMeshes::MEDFileMeshes()
6646 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6649 loadFromFile(fileName);
6651 catch(INTERP_KERNEL::Exception& /*e*/)
6655 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6657 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6659 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6660 if((const MEDFileMeshMultiTS *)*it)
6661 meshes[i]=(*it)->deepCpy();
6662 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6663 ret->_meshes=meshes;
6667 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6669 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6672 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6674 std::vector<const BigMemoryObject *> ret;
6675 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6676 ret.push_back((const MEDFileMeshMultiTS *)*it);
6680 std::string MEDFileMeshes::simpleRepr() const
6682 std::ostringstream oss;
6683 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6684 simpleReprWithoutHeader(oss);
6688 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6690 int nbOfMeshes=getNumberOfMeshes();
6691 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6692 std::vector<std::string> mns=getMeshesNames();
6693 for(int i=0;i<nbOfMeshes;i++)
6694 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6697 void MEDFileMeshes::checkCoherency() const
6699 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6701 std::set<std::string> s;
6702 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6704 const MEDFileMeshMultiTS *elt=(*it);
6707 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6708 throw INTERP_KERNEL::Exception(oss.str().c_str());
6710 std::size_t sz=s.size();
6711 s.insert(std::string((*it)->getName()));
6714 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6715 throw INTERP_KERNEL::Exception(oss.str().c_str());
6720 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6725 _nb_iter=ms->getNumberOfMeshes();
6729 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6733 MEDFileMesh *MEDFileMeshesIterator::nextt()
6735 if(_iter_id<_nb_iter)
6737 MEDFileMeshes *ms(_ms);
6739 return ms->getMeshAtPos(_iter_id++);