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 "MEDFileSafeCaller.txx"
27 #include "MEDLoaderBase.hxx"
29 #include "MEDCouplingUMesh.hxx"
31 #include "InterpKernelAutoPtr.hxx"
36 extern med_geometry_type typmai3[34];
38 using namespace ParaMEDMEM;
40 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
42 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
46 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
48 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
49 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
51 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
52 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
53 ret+=(*it2).capacity();
55 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
56 ret+=(*it).first.capacity()+sizeof(int);
60 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
62 return std::vector<const BigMemoryObject *>();
66 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
67 * file. The first mesh in the file is loaded.
68 * \param [in] fileName - the name of MED file to read.
69 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
70 * mesh using decrRef() as it is no more needed.
71 * \throw If the file is not readable.
72 * \throw If there is no meshes in the file.
73 * \throw If the mesh in the file is of a not supported type.
75 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
77 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
80 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
81 throw INTERP_KERNEL::Exception(oss.str().c_str());
83 MEDFileUtilities::CheckFileForRead(fileName);
84 ParaMEDMEM::MEDCouplingMeshType meshType;
85 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
88 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
93 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
94 ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
95 ret->loadJointsFromFile(fid);
96 return (MEDFileUMesh *)ret.retn();
100 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
101 ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
102 ret->loadJointsFromFile(fid);
103 return (MEDFileCMesh *)ret.retn();
107 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
108 ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
109 ret->loadJointsFromFile(fid);
110 return (MEDFileCurveLinearMesh *)ret.retn();
114 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
115 throw INTERP_KERNEL::Exception(oss.str().c_str());
121 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
122 * file. The mesh to load is specified by its name and numbers of a time step and an
124 * \param [in] fileName - the name of MED file to read.
125 * \param [in] mName - the name of the mesh to read.
126 * \param [in] dt - the number of a time step.
127 * \param [in] it - the number of an iteration.
128 * \param [in] joints - the sub-domain joints to use instead of those that can be read
129 * from the MED file. Usually this joints are those just read by another iteration
130 * of mName mesh, when this method is called by MEDFileMeshMultiTS::New()
131 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
132 * mesh using decrRef() as it is no more needed.
133 * \throw If the file is not readable.
134 * \throw If there is no mesh with given attributes in the file.
135 * \throw If the mesh in the file is of a not supported type.
137 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
139 MEDFileUtilities::CheckFileForRead(fileName);
140 ParaMEDMEM::MEDCouplingMeshType meshType;
141 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
144 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
149 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
150 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
151 ret->loadJointsFromFile(fid,joints);
152 return (MEDFileUMesh *)ret.retn();
156 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
157 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
158 ret->loadJointsFromFile(fid,joints);
159 return (MEDFileCMesh *)ret.retn();
163 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
164 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
165 ret->loadJointsFromFile(fid,joints);
166 return (MEDFileCurveLinearMesh *)ret.retn();
170 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
171 throw INTERP_KERNEL::Exception(oss.str().c_str());
177 * Writes \a this mesh into an open MED file specified by its descriptor.
178 * \param [in] fid - the MED file descriptor.
179 * \throw If the mesh name is not set.
180 * \throw If the file is open for reading only.
181 * \throw If the writing mode == 1 and the same data is present in an existing file.
183 void MEDFileMesh::write(med_idt fid) const
186 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
188 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
193 * Writes \a this mesh into a MED file specified by its name.
194 * \param [in] fileName - the MED file name.
195 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
196 * - 2 - erase; an existing file is removed.
197 * - 1 - append; same data should not be present in an existing file.
198 * - 0 - overwrite; same data present in an existing file is overwritten.
199 * \throw If the mesh name is not set.
200 * \throw If \a mode == 1 and the same data is present in an existing file.
202 void MEDFileMesh::write(const std::string& fileName, int mode) const
204 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
205 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
206 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
207 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
212 * Checks if \a this and another mesh are equal.
213 * \param [in] other - the mesh to compare with.
214 * \param [in] eps - a precision used to compare real values.
215 * \param [in,out] what - the string returning description of unequal data.
216 * \return bool - \c true if the meshes are equal, \c false, else.
218 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
220 if(_order!=other->_order)
222 what="Orders differ !";
225 if(_iteration!=other->_iteration)
227 what="Iterations differ !";
230 if(fabs(_time-other->_time)>eps)
232 what="Time values differ !";
235 if(_dt_unit!=other->_dt_unit)
237 what="Time units differ !";
240 if(_name!=other->_name)
242 what="Names differ !";
245 //univ_name has been ignored -> not a bug because it is a mutable attribute
246 if(_desc_name!=other->_desc_name)
248 what="Description names differ !";
251 if(!areGrpsEqual(other,what))
253 if(!areFamsEqual(other,what))
258 void MEDFileMesh::setName(const std::string& name)
264 * Clears redundant attributes of incorporated data arrays.
266 void MEDFileMesh::clearNonDiscrAttributes() const
271 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
273 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
275 if((*it).first==_name)
285 * Copies data on groups and families from another mesh.
286 * \param [in] other - the mesh to copy the data from.
288 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
290 _groups=other._groups;
291 _families=other._families;
296 * This method clear all the groups in the map.
297 * So this method does not operate at all on arrays.
298 * So this method can lead to orphan families.
300 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
302 void MEDFileMesh::clearGrpMap()
308 * This method clear all the families in the map.
309 * So this method does not operate at all on arrays.
310 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
312 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
314 void MEDFileMesh::clearFamMap()
320 * This method clear all the families and groups in the map.
321 * So this method does not operate at all on arrays.
322 * As all groups and families entry will be removed after
323 * 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.
325 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
327 void MEDFileMesh::clearFamGrpMaps()
334 * Returns names of families constituting a group.
335 * \param [in] name - the name of the group of interest.
336 * \return std::vector<std::string> - a sequence of names of the families.
337 * \throw If the name of a nonexistent group is specified.
339 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
341 std::string oname(name);
342 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
343 if(it==_groups.end())
345 std::vector<std::string> grps=getGroupsNames();
346 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
347 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
348 throw INTERP_KERNEL::Exception(oss.str().c_str());
354 * Returns names of families constituting some groups.
355 * \param [in] grps - a sequence of names of groups of interest.
356 * \return std::vector<std::string> - a sequence of names of the families.
357 * \throw If a name of a nonexistent group is present in \a grps.
359 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
361 std::set<std::string> fams;
362 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
364 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
365 if(it2==_groups.end())
367 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
368 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
369 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
370 throw INTERP_KERNEL::Exception(oss.str().c_str());
372 fams.insert((*it2).second.begin(),(*it2).second.end());
374 std::vector<std::string> fams2(fams.begin(),fams.end());
379 * Returns ids of families constituting a group.
380 * \param [in] name - the name of the group of interest.
381 * \return std::vector<int> - sequence of ids of the families.
382 * \throw If the name of a nonexistent group is specified.
384 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
386 std::string oname(name);
387 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
388 std::vector<std::string> grps=getGroupsNames();
389 if(it==_groups.end())
391 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
392 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
393 throw INTERP_KERNEL::Exception(oss.str().c_str());
395 return getFamiliesIds((*it).second);
399 * Sets names of families constituting a group. If data on families of this group is
400 * already present, it is overwritten. Every family in \a fams is checked, and if a
401 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
402 * \param [in] name - the name of the group of interest.
403 * \param [in] fams - a sequence of names of families constituting the group.
405 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
407 std::string oname(name);
409 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
411 std::map<std::string,int>::iterator it2=_families.find(*it1);
412 if(it2==_families.end())
418 * Sets families constituting a group. The families are specified by their ids.
419 * If a family name is not found by its id, an exception is thrown.
420 * If several families have same id, the first one in lexical order is taken.
421 * \param [in] name - the name of the group of interest.
422 * \param [in] famIds - a sequence of ids of families constituting the group.
423 * \throw If a family name is not found by its id.
425 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
427 std::string oname(name);
428 std::vector<std::string> fams(famIds.size());
430 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
432 std::string name2=getFamilyNameGivenId(*it1);
439 * Returns names of groups including a given family.
440 * \param [in] name - the name of the family of interest.
441 * \return std::vector<std::string> - a sequence of names of groups including the family.
443 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
445 std::vector<std::string> ret;
446 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
448 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
451 ret.push_back((*it1).first);
459 * Adds an existing family to groups.
460 * \param [in] famName - a name of family to add to \a grps.
461 * \param [in] grps - a sequence of group names to add the family in.
462 * \throw If a family named \a famName not yet exists.
464 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
466 std::string fName(famName);
467 const std::map<std::string,int>::const_iterator it=_families.find(fName);
468 if(it==_families.end())
470 std::vector<std::string> fams=getFamiliesNames();
471 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
472 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
473 throw INTERP_KERNEL::Exception(oss.str().c_str());
475 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
477 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
478 if(it2!=_groups.end())
479 (*it2).second.push_back(fName);
482 std::vector<std::string> grps2(1,fName);
489 * Returns names of all groups of \a this mesh.
490 * \return std::vector<std::string> - a sequence of group names.
492 std::vector<std::string> MEDFileMesh::getGroupsNames() const
494 std::vector<std::string> ret(_groups.size());
496 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
502 * Returns names of all families of \a this mesh.
503 * \return std::vector<std::string> - a sequence of family names.
505 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
507 std::vector<std::string> ret(_families.size());
509 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
515 * Changes a name of every family, included in one group only, to be same as the group name.
516 * \throw If there are families with equal names in \a this mesh.
518 void MEDFileMesh::assignFamilyNameWithGroupName()
520 std::map<std::string, std::vector<std::string> > groups(_groups);
521 std::map<std::string,int> newFams;
522 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
524 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
525 if(grps.size()==1 && groups[grps[0]].size()==1)
527 if(newFams.find(grps[0])!=newFams.end())
529 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
530 throw INTERP_KERNEL::Exception(oss.str().c_str());
532 newFams[grps[0]]=(*it).second;
533 std::vector<std::string>& grps2=groups[grps[0]];
534 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
539 if(newFams.find((*it).first)!=newFams.end())
541 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
542 throw INTERP_KERNEL::Exception(oss.str().c_str());
544 newFams[(*it).first]=(*it).second;
552 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
554 * \return the removed groups.
556 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
558 std::vector<std::string> ret;
559 std::map<std::string, std::vector<std::string> > newGrps;
560 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
562 if((*it).second.empty())
563 ret.push_back((*it).first);
565 newGrps[(*it).first]=(*it).second;
573 * Removes a group from \a this mesh.
574 * \param [in] name - the name of the group to remove.
575 * \throw If no group with such a \a name exists.
577 void MEDFileMesh::removeGroup(const std::string& name)
579 std::string oname(name);
580 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
581 std::vector<std::string> grps=getGroupsNames();
582 if(it==_groups.end())
584 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
585 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
586 throw INTERP_KERNEL::Exception(oss.str().c_str());
592 * Removes a family from \a this mesh.
593 * \param [in] name - the name of the family to remove.
594 * \throw If no family with such a \a name exists.
596 void MEDFileMesh::removeFamily(const std::string& name)
598 std::string oname(name);
599 std::map<std::string, int >::iterator it=_families.find(oname);
600 std::vector<std::string> fams=getFamiliesNames();
601 if(it==_families.end())
603 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
604 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
605 throw INTERP_KERNEL::Exception(oss.str().c_str());
608 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
610 std::vector<std::string>& v=(*it3).second;
611 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
618 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
619 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
620 * family field whatever its level. This method also suppresses the orphan families.
622 * \return - The list of removed groups names.
624 * \sa MEDFileMesh::removeOrphanFamilies.
626 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
628 removeOrphanFamilies();
629 return removeEmptyGroups();
633 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
634 * 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.
636 * \return - The list of removed families names.
637 * \sa MEDFileMesh::removeOrphanGroups.
639 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
641 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
642 std::vector<std::string> ret;
643 if(!((DataArrayInt*)allFamIdsInUse))
645 ret=getFamiliesNames();
646 _families.clear(); _groups.clear();
649 std::map<std::string,int> famMap;
650 std::map<std::string, std::vector<std::string> > grps(_groups);
651 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
653 if(allFamIdsInUse->presenceOfValue((*it).second))
654 famMap[(*it).first]=(*it).second;
657 ret.push_back((*it).first);
658 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
659 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
661 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
662 std::vector<std::string>& famv=(*it3).second;
663 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
669 { _families=famMap; _groups=grps; }
674 * 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
675 * this family is orphan or not.
677 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
679 void MEDFileMesh::removeFamiliesReferedByNoGroups()
681 std::map<std::string,int> fams;
682 std::set<std::string> sfams;
683 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
684 sfams.insert((*it).first);
685 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
686 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
688 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
689 if(*it!=DFT_FAM_NAME)
690 _families.erase(*it);
694 * 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
695 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
696 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
698 * \sa MEDFileMesh::removeOrphanFamilies
700 void MEDFileMesh::rearrangeFamilies()
702 checkOrphanFamilyZero();
703 removeFamiliesReferedByNoGroups();
705 std::vector<int> levels(getNonEmptyLevelsExt());
706 std::set<int> idsRefed;
707 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
708 idsRefed.insert((*it).second);
709 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
711 const DataArrayInt *fams(0);
714 fams=getFamilyFieldAtLevel(*it);
716 catch(INTERP_KERNEL::Exception& e) { }
719 std::vector<bool> v(fams->getNumberOfTuples(),false);
720 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
721 fams->switchOnTupleEqualTo(*pt,v);
722 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
723 if(!unfetchedIds->empty())
725 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
726 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
727 setFamilyFieldArr(*it,newFams);
730 removeOrphanFamilies();
734 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
736 void MEDFileMesh::checkOrphanFamilyZero() const
738 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
740 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
742 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
743 throw INTERP_KERNEL::Exception(oss.str().c_str());
749 * Renames a group in \a this mesh.
750 * \param [in] oldName - a current name of the group to rename.
751 * \param [in] newName - a new group name.
752 * \throw If no group named \a oldName exists in \a this mesh.
753 * \throw If a group named \a newName already exists.
755 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
757 std::string oname(oldName);
758 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
759 std::vector<std::string> grps=getGroupsNames();
760 if(it==_groups.end())
762 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
763 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
764 throw INTERP_KERNEL::Exception(oss.str().c_str());
766 std::string nname(newName);
767 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
768 if(it2!=_groups.end())
770 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
771 throw INTERP_KERNEL::Exception(oss.str().c_str());
773 std::vector<std::string> cpy=(*it).second;
775 _groups[newName]=cpy;
779 * Changes an id of a family in \a this mesh.
780 * This method calls changeFamilyIdArr().
781 * \param [in] oldId - a current id of the family.
782 * \param [in] newId - a new family id.
784 void MEDFileMesh::changeFamilyId(int oldId, int newId)
786 changeFamilyIdArr(oldId,newId);
787 std::map<std::string,int> fam2;
788 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
790 if((*it).second==oldId)
791 fam2[(*it).first]=newId;
793 fam2[(*it).first]=(*it).second;
799 * Renames a family in \a this mesh.
800 * \param [in] oldName - a current name of the family to rename.
801 * \param [in] newName - a new family name.
802 * \throw If no family named \a oldName exists in \a this mesh.
803 * \throw If a family named \a newName already exists.
805 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
807 std::string oname(oldName);
808 std::map<std::string, int >::iterator it=_families.find(oname);
809 std::vector<std::string> fams=getFamiliesNames();
810 if(it==_families.end())
812 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
813 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
814 throw INTERP_KERNEL::Exception(oss.str().c_str());
816 std::string nname(newName);
817 std::map<std::string, int >::iterator it2=_families.find(nname);
818 if(it2!=_families.end())
820 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
821 throw INTERP_KERNEL::Exception(oss.str().c_str());
823 int cpy=(*it).second;
825 _families[newName]=cpy;
826 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
828 std::vector<std::string>& v=(*it3).second;
829 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
836 * Checks if \a this and another mesh contains the same families.
837 * \param [in] other - the mesh to compare with \a this one.
838 * \param [in,out] what - an unused parameter.
839 * \return bool - \c true if number of families and their ids are the same in the two
840 * meshes. Families with the id == \c 0 are not considered.
842 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
844 if(_families==other->_families)
846 std::map<std::string,int> fam0;
847 std::map<std::string,int> fam1;
848 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
850 fam0[(*it).first]=(*it).second;
851 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
853 fam1[(*it).first]=(*it).second;
858 * Checks if \a this and another mesh contains the same groups.
859 * \param [in] other - the mesh to compare with \a this one.
860 * \param [in,out] what - a string describing a difference of groups of the two meshes
861 * in case if this method returns \c false.
862 * \return bool - \c true if number of groups and families constituting them are the
863 * same in the two meshes.
865 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
867 if(_groups==other->_groups)
870 std::size_t sz=_groups.size();
871 if(sz!=other->_groups.size())
873 what="Groups differ because not same number !\n";
878 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
879 for(std::size_t i=0;i<sz && ret;i++,it1++)
881 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
882 if(it2!=other->_groups.end())
884 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
885 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
891 what="A group in first mesh exists not in other !\n";
897 std::ostringstream oss; oss << "Groups description differs :\n";
898 oss << "First group description :\n";
899 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
901 oss << " Group \"" << (*it).first << "\" on following families :\n";
902 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
903 oss << " \"" << *it2 << "\n";
905 oss << "Second group description :\n";
906 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
908 oss << " Group \"" << (*it).first << "\" on following families :\n";
909 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
910 oss << " \"" << *it2 << "\n";
918 * Checks if a group with a given name exists in \a this mesh.
919 * \param [in] groupName - the group name.
920 * \return bool - \c true the group \a groupName exists in \a this mesh.
922 bool MEDFileMesh::existsGroup(const std::string& groupName) const
924 std::string grpName(groupName);
925 return _groups.find(grpName)!=_groups.end();
929 * Checks if a family with a given id exists in \a this mesh.
930 * \param [in] famId - the family id.
931 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
933 bool MEDFileMesh::existsFamily(int famId) const
935 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
936 if((*it2).second==famId)
942 * Checks if a family with a given name exists in \a this mesh.
943 * \param [in] familyName - the family name.
944 * \return bool - \c true the family \a familyName exists in \a this mesh.
946 bool MEDFileMesh::existsFamily(const std::string& familyName) const
948 std::string fname(familyName);
949 return _families.find(fname)!=_families.end();
953 * Sets an id of a family.
954 * \param [in] familyName - the family name.
955 * \param [in] id - a new id of the family.
957 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
959 std::string fname(familyName);
963 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
965 std::string fname(familyName);
966 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
969 if((*it).first!=familyName)
971 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
972 throw INTERP_KERNEL::Exception(oss.str().c_str());
979 * Adds a family to \a this mesh.
980 * \param [in] familyName - a name of the family.
981 * \param [in] famId - an id of the family.
982 * \throw If a family with the same name or id already exists in \a this mesh.
984 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
986 std::string fname(familyName);
987 std::map<std::string,int>::const_iterator it=_families.find(fname);
988 if(it==_families.end())
990 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
991 if((*it2).second==famId)
993 std::ostringstream oss;
994 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
995 throw INTERP_KERNEL::Exception(oss.str().c_str());
997 _families[fname]=famId;
1001 if((*it).second!=famId)
1003 std::ostringstream oss;
1004 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
1005 throw INTERP_KERNEL::Exception(oss.str().c_str());
1011 * Creates a group including all mesh entities of given dimension.
1012 * \warning This method does \b not guarantee that the created group includes mesh
1013 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1014 * present in family fields of different dimensions. To assure this, call
1015 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1016 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1018 * \param [in] groupName - a name of the new group.
1019 * \throw If a group named \a groupName already exists.
1020 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1021 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1023 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1025 std::string grpName(groupName);
1026 std::vector<int> levs=getNonEmptyLevelsExt();
1027 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1029 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1030 oss << "Available relative ext levels are : ";
1031 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1032 throw INTERP_KERNEL::Exception(oss.str().c_str());
1034 if(existsGroup(groupName))
1036 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1037 oss << "Already existing groups are : ";
1038 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1039 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1040 throw INTERP_KERNEL::Exception(oss.str().c_str());
1042 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1044 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1045 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1046 std::vector<std::string> familiesOnWholeGroup;
1047 for(const int *it=famIds->begin();it!=famIds->end();it++)
1050 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1052 _groups[grpName]=familiesOnWholeGroup;
1056 * Ensures that given family ids do not present in family fields of dimensions different
1057 * than given ones. If a family id is present in the family fields of dimensions different
1058 * than the given ones, a new family is created and the whole data is updated accordingly.
1059 * \param [in] famIds - a sequence of family ids to check.
1060 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1061 * famIds should exclusively belong.
1062 * \return bool - \c true if no modification is done in \a this mesh by this method.
1064 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1066 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1067 std::vector<int> levs=getNonEmptyLevelsExt();
1068 std::set<int> levs2(levs.begin(),levs.end());
1069 std::vector<int> levsToTest;
1070 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1071 std::set<int> famIds2(famIds.begin(),famIds.end());
1074 if(!_families.empty())
1075 maxFamId=getMaxFamilyId()+1;
1076 std::vector<std::string> allFams=getFamiliesNames();
1077 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1079 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1082 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1083 std::vector<int> tmp;
1084 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1085 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1088 std::string famName=getFamilyNameGivenId(*it2);
1089 std::ostringstream oss; oss << "Family_" << maxFamId;
1090 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1091 addFamilyOnAllGroupsHaving(famName,zeName);
1092 _families[zeName]=maxFamId;
1093 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1102 * Adds a family to a given group in \a this mesh. If the group with a given name does
1103 * not exist, it is created.
1104 * \param [in] grpName - the name of the group to add the family in.
1105 * \param [in] famName - the name of the family to add to the group named \a grpName.
1106 * \throw If \a grpName or \a famName is an empty string.
1107 * \throw If no family named \a famName is present in \a this mesh.
1109 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1111 std::string grpn(grpName);
1112 std::string famn(famName);
1113 if(grpn.empty() || famn.empty())
1114 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1115 std::vector<std::string> fams=getFamiliesNames();
1116 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1118 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1119 oss << "Create this family or choose an existing one ! Existing fams are : ";
1120 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1121 throw INTERP_KERNEL::Exception(oss.str().c_str());
1123 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1124 if(it==_groups.end())
1126 _groups[grpn].push_back(famn);
1130 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1131 if(it2==(*it).second.end())
1132 (*it).second.push_back(famn);
1137 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1138 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1139 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1141 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1143 std::string famNameCpp(famName);
1144 std::string otherCpp(otherFamName);
1145 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1147 std::vector<std::string>& v=(*it).second;
1148 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1150 v.push_back(otherCpp);
1156 * \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).
1157 * \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)
1159 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1162 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1163 std::string grpName(ids->getName());
1165 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1166 ids->checkStrictlyMonotonic(true);
1167 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
1168 std::vector<std::string> grpsNames=getGroupsNames();
1169 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1171 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1172 throw INTERP_KERNEL::Exception(oss.str().c_str());
1174 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1175 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1176 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1177 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1178 std::vector<int> familyIds;
1179 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
1180 int maxVal=getTheMaxAbsFamilyId()+1;
1181 std::map<std::string,int> families(_families);
1182 std::map<std::string, std::vector<std::string> > groups(_groups);
1183 std::vector<std::string> fams;
1184 bool created(false);
1185 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1187 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
1188 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1189 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
1190 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1193 bool isFamPresent=false;
1194 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1195 isFamPresent=(*itl)->presenceOfValue(*famId);
1197 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1200 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1201 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1202 fams.push_back(locFamName);
1203 if(existsFamily(*famId))
1205 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1206 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1209 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1213 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1214 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1215 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1216 if(existsFamily(*famId))
1218 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1219 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1224 for(std::size_t i=0;i<familyIds.size();i++)
1226 DataArrayInt *da=idsPerfamiliyIds[i];
1227 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1231 _groups[grpName]=fams;
1234 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1236 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1239 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1241 std::string fam(familyNameToChange);
1242 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1244 std::vector<std::string>& fams((*it).second);
1245 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1249 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1255 * Returns a name of the family having a given id or, if no such a family exists, creates
1256 * a new uniquely named family and returns its name.
1257 * \param [in] id - the id of the family whose name is required.
1258 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1259 * \return std::string - the name of the existing or the created family.
1260 * \throw If it is not possible to create a unique family name.
1262 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1264 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1268 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1269 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1270 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1271 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1273 * This method will throws an exception if it is not possible to create a unique family name.
1275 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1277 std::vector<std::string> famAlreadyExisting(families.size());
1279 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1281 if((*it).second!=id)
1283 famAlreadyExisting[ii]=(*it).first;
1292 std::ostringstream oss; oss << "Family_" << id;
1293 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1299 * Sets names and ids of all families in \a this mesh.
1300 * \param [in] info - a map of a family name to a family id.
1302 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1308 * Sets names of all groups and families constituting them in \a this mesh.
1309 * \param [in] info - a map of a group name to a vector of names of families
1310 * constituting the group.
1312 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1318 * Returns an id of the family having a given name.
1319 * \param [in] name - the name of the family of interest.
1320 * \return int - the id of the family of interest.
1321 * \throw If no family with such a \a name exists.
1323 int MEDFileMesh::getFamilyId(const std::string& name) const
1325 std::string oname(name);
1326 std::map<std::string, int>::const_iterator it=_families.find(oname);
1327 std::vector<std::string> fams=getFamiliesNames();
1328 if(it==_families.end())
1330 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1331 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1332 throw INTERP_KERNEL::Exception(oss.str().c_str());
1334 return (*it).second;
1338 * Returns ids of the families having given names.
1339 * \param [in] fams - a sequence of the names of families of interest.
1340 * \return std::vector<int> - a sequence of the ids of families of interest.
1341 * \throw If \a fams contains a name of an inexistent family.
1343 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1345 std::vector<int> ret(fams.size());
1347 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1349 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1350 if(it2==_families.end())
1352 std::vector<std::string> fams2=getFamiliesNames();
1353 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1354 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1355 throw INTERP_KERNEL::Exception(oss.str().c_str());
1357 ret[i]=(*it2).second;
1363 * Returns a maximal abs(id) of families in \a this mesh.
1364 * \return int - the maximal norm of family id.
1365 * \throw If there are no families in \a this mesh.
1367 int MEDFileMesh::getMaxAbsFamilyId() const
1369 if(_families.empty())
1370 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1371 int ret=-std::numeric_limits<int>::max();
1372 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1374 ret=std::max(std::abs((*it).second),ret);
1380 * Returns a maximal id of families in \a this mesh.
1381 * \return int - the maximal family id.
1382 * \throw If there are no families in \a this mesh.
1384 int MEDFileMesh::getMaxFamilyId() const
1386 if(_families.empty())
1387 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1388 int ret=-std::numeric_limits<int>::max();
1389 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1391 ret=std::max((*it).second,ret);
1397 * Returns a minimal id of families in \a this mesh.
1398 * \return int - the minimal family id.
1399 * \throw If there are no families in \a this mesh.
1401 int MEDFileMesh::getMinFamilyId() const
1403 if(_families.empty())
1404 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1405 int ret=std::numeric_limits<int>::max();
1406 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1408 ret=std::min((*it).second,ret);
1414 * Returns a maximal id of families in \a this mesh. Not only named families are
1415 * considered but all family fields as well.
1416 * \return int - the maximal family id.
1418 int MEDFileMesh::getTheMaxAbsFamilyId() const
1420 int m1=-std::numeric_limits<int>::max();
1421 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1422 m1=std::max(std::abs((*it).second),m1);
1423 int m2=getMaxAbsFamilyIdInArrays();
1424 return std::max(m1,m2);
1428 * Returns a maximal id of families in \a this mesh. Not only named families are
1429 * considered but all family fields as well.
1430 * \return int - the maximal family id.
1432 int MEDFileMesh::getTheMaxFamilyId() const
1434 int m1=-std::numeric_limits<int>::max();
1435 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1436 m1=std::max((*it).second,m1);
1437 int m2=getMaxFamilyIdInArrays();
1438 return std::max(m1,m2);
1442 * Returns a minimal id of families in \a this mesh. Not only named families are
1443 * considered but all family fields as well.
1444 * \return int - the minimal family id.
1446 int MEDFileMesh::getTheMinFamilyId() const
1448 int m1=std::numeric_limits<int>::max();
1449 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1450 m1=std::min((*it).second,m1);
1451 int m2=getMinFamilyIdInArrays();
1452 return std::min(m1,m2);
1456 * This method only considers the maps. The contain of family array is ignored here.
1458 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1460 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1462 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1464 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1465 v.insert((*it).second);
1466 ret->alloc((int)v.size(),1);
1467 std::copy(v.begin(),v.end(),ret->getPointer());
1472 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1474 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1476 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1478 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1479 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1480 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1482 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1483 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1484 if((DataArrayInt *) ret)
1485 ret=dv->buildUnion(ret);
1493 * true is returned if no modification has been needed. false if family
1494 * renumbering has been needed.
1496 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1498 std::vector<int> levs=getNonEmptyLevelsExt();
1499 std::set<int> allFamIds;
1500 int maxId=getMaxFamilyId()+1;
1501 std::map<int,std::vector<int> > famIdsToRenum;
1502 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1504 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1507 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1509 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1511 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1513 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1516 if(famIdsToRenum.empty())
1518 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1519 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1521 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1522 int *famIdsToChange=fam->getPointer();
1523 std::map<int,int> ren;
1524 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1526 if(allIds->presenceOfValue(*it3))
1528 std::string famName=getFamilyNameGivenId(*it3);
1529 std::vector<std::string> grps=getGroupsOnFamily(famName);
1532 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1533 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1534 addFamilyOnGrp((*it4),newFam);
1537 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1538 for(const int *id=ids->begin();id!=ids->end();id++)
1539 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1545 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1546 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1547 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1548 * This method will throw an exception if a same family id is detected in different level.
1549 * \warning This policy is the opposite of those in MED file documentation ...
1551 void MEDFileMesh::normalizeFamIdsTrio()
1553 ensureDifferentFamIdsPerLevel();
1554 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1555 std::vector<int> levs=getNonEmptyLevelsExt();
1556 std::set<int> levsS(levs.begin(),levs.end());
1557 std::set<std::string> famsFetched;
1558 std::map<std::string,int> families;
1559 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1562 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1566 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1567 std::map<int,int> ren;
1568 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1570 int nbOfTuples=fam->getNumberOfTuples();
1571 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1572 for(int *w=start;w!=start+nbOfTuples;w++)
1574 for(const int *it=tmp->begin();it!=tmp->end();it++)
1576 if(allIds->presenceOfValue(*it))
1578 std::string famName=getFamilyNameGivenId(*it);
1579 families[famName]=ren[*it];
1580 famsFetched.insert(famName);
1585 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1588 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1592 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1593 std::map<int,int> ren;
1594 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1596 int nbOfTuples=fam->getNumberOfTuples();
1597 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1598 for(int *w=start;w!=start+nbOfTuples;w++)
1600 for(const int *it=tmp->begin();it!=tmp->end();it++)
1602 if(allIds->presenceOfValue(*it))
1604 std::string famName=getFamilyNameGivenId(*it);
1605 families[famName]=ren[*it];
1606 famsFetched.insert(famName);
1611 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1613 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1616 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1617 fam->fillWithZero();
1618 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1619 if(allIds->presenceOfValue(*it3))
1621 std::string famName=getFamilyNameGivenId(*it3);
1622 families[famName]=0;
1623 famsFetched.insert(famName);
1628 std::vector<std::string> allFams=getFamiliesNames();
1629 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1630 std::set<std::string> unFetchedIds;
1631 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1632 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1633 families[*it4]=_families[*it4];
1638 * This method normalizes fam id with the following policy.
1639 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1640 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1641 * This method will throw an exception if a same family id is detected in different level.
1643 void MEDFileMesh::normalizeFamIdsMEDFile()
1645 ensureDifferentFamIdsPerLevel();
1646 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1647 std::vector<int> levs=getNonEmptyLevelsExt();
1648 std::set<int> levsS(levs.begin(),levs.end());
1649 std::set<std::string> famsFetched;
1650 std::map<std::string,int> families;
1652 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1655 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1658 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1659 std::map<int,int> ren;
1660 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1662 int nbOfTuples=fam->getNumberOfTuples();
1663 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1664 for(int *w=start;w!=start+nbOfTuples;w++)
1666 for(const int *it=tmp->begin();it!=tmp->end();it++)
1668 if(allIds->presenceOfValue(*it))
1670 std::string famName=getFamilyNameGivenId(*it);
1671 families[famName]=ren[*it];
1672 famsFetched.insert(famName);
1678 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1680 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1683 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1684 std::map<int,int> ren;
1685 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1687 int nbOfTuples=fam->getNumberOfTuples();
1688 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1689 for(int *w=start;w!=start+nbOfTuples;w++)
1691 for(const int *it=tmp->begin();it!=tmp->end();it++)
1693 if(allIds->presenceOfValue(*it))
1695 std::string famName=getFamilyNameGivenId(*it);
1696 families[famName]=ren[*it];
1697 famsFetched.insert(famName);
1703 std::vector<std::string> allFams=getFamiliesNames();
1704 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1705 std::set<std::string> unFetchedIds;
1706 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1707 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1708 families[*it4]=_families[*it4];
1713 * Returns a name of the family by its id. If there are several families having the given
1714 * id, the name first in lexical order is returned.
1715 * \param [in] id - the id of the family whose name is required.
1716 * \return std::string - the name of the found family.
1717 * \throw If no family with the given \a id exists.
1719 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1721 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1722 if((*it).second==id)
1724 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1725 throw INTERP_KERNEL::Exception(oss.str().c_str());
1729 * Returns a string describing \a this mesh. This description includes the mesh name and
1730 * the mesh description string.
1731 * \return std::string - the mesh information string.
1733 std::string MEDFileMesh::simpleRepr() const
1735 std::ostringstream oss;
1736 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1737 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1738 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1743 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1744 * an empty one is created.
1746 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1748 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1751 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New());
1752 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1753 arr->fillWithZero();
1754 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1755 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1759 * Returns ids of mesh entities contained in a given group of a given dimension.
1760 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1762 * \param [in] grp - the name of the group of interest.
1763 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1764 * returned instead of ids.
1765 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1766 * numbers, if available and required, of mesh entities of the group. The caller
1767 * is to delete this array using decrRef() as it is no more needed.
1768 * \throw If the name of a nonexistent group is specified.
1769 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1771 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1773 std::vector<std::string> tmp(1);
1775 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1781 * Returns ids of mesh entities contained in given groups of a given dimension.
1782 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1784 * \param [in] grps - the names of the groups of interest.
1785 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1786 * returned instead of ids.
1787 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1788 * numbers, if available and required, of mesh entities of the groups. The caller
1789 * is to delete this array using decrRef() as it is no more needed.
1790 * \throw If the name of a nonexistent group is present in \a grps.
1791 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1793 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1795 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1796 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1800 * Returns ids of mesh entities contained in a given family of a given dimension.
1801 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1803 * \param [in] fam - the name of the family of interest.
1804 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1805 * returned instead of ids.
1806 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1807 * numbers, if available and required, of mesh entities of the family. The caller
1808 * is to delete this array using decrRef() as it is no more needed.
1809 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1811 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1813 std::vector<std::string> tmp(1);
1815 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1821 * Returns ids of nodes contained in a given group.
1822 * \param [in] grp - the name of the group of interest.
1823 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1824 * returned instead of ids.
1825 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1826 * numbers, if available and required, of nodes of the group. The caller
1827 * is to delete this array using decrRef() as it is no more needed.
1828 * \throw If the name of a nonexistent group is specified.
1829 * \throw If the family field is missing for nodes.
1831 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1833 std::vector<std::string> tmp(1);
1835 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1841 * Returns ids of nodes contained in given groups.
1842 * \param [in] grps - the names of the groups of interest.
1843 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1844 * returned instead of ids.
1845 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1846 * numbers, if available and required, of nodes of the groups. The caller
1847 * is to delete this array using decrRef() as it is no more needed.
1848 * \throw If the name of a nonexistent group is present in \a grps.
1849 * \throw If the family field is missing for nodes.
1851 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1853 return getGroupsArr(1,grps,renum);
1857 * Returns ids of nodes contained in a given group.
1858 * \param [in] grp - the name of the group of interest.
1859 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1860 * returned instead of ids.
1861 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1862 * numbers, if available and required, of nodes of the group. The caller
1863 * is to delete this array using decrRef() as it is no more needed.
1864 * \throw If the name of a nonexistent group is specified.
1865 * \throw If the family field is missing for nodes.
1867 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1869 std::vector<std::string> tmp(1);
1871 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1877 * Returns ids of nodes contained in given families.
1878 * \param [in] fams - the names of the families of interest.
1879 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1880 * returned instead of ids.
1881 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1882 * numbers, if available and required, of nodes of the families. The caller
1883 * is to delete this array using decrRef() as it is no more needed.
1884 * \throw If the family field is missing for nodes.
1886 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1888 return getFamiliesArr(1,fams,renum);
1892 * Adds groups of given dimension and creates corresponding families and family fields
1893 * given ids of mesh entities of each group.
1894 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1895 * \param [in] grps - a sequence of arrays of ids each describing a group.
1896 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1898 * \throw If names of some groups in \a grps are equal.
1899 * \throw If \a grps includes a group with an empty name.
1900 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1901 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1903 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1907 std::set<std::string> grpsName;
1908 std::vector<std::string> grpsName2(grps.size());
1911 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1913 grpsName.insert((*it)->getName());
1914 grpsName2[i]=(*it)->getName();
1916 if(grpsName.size()!=grps.size())
1917 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1918 if(grpsName.find(std::string(""))!=grpsName.end())
1919 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1920 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1921 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1922 std::vector< std::vector<int> > fidsOfGroups;
1925 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1929 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1930 for(unsigned int ii=0;ii<grps.size();ii++)
1932 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1933 grps2[ii]->setName(grps[ii]->getName());
1935 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1936 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1939 if(!_families.empty())
1940 offset=getMaxAbsFamilyId()+1;
1941 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1942 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1943 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1944 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1948 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1949 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1950 * For the moment, the two last input parameters are not taken into account.
1952 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1954 std::map<int,std::string> famInv;
1955 for(const int *it=famIds->begin();it!=famIds->end();it++)
1957 std::ostringstream oss;
1958 oss << "Family_" << (*it);
1959 _families[oss.str()]=(*it);
1960 famInv[*it]=oss.str();
1963 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1965 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1967 _groups[grpNames[i]].push_back(famInv[*it2]);
1972 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1974 std::vector<int> levs(getNonEmptyLevels());
1975 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1976 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1978 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1979 ret.insert(ret.end(),elts.begin(),elts.end());
1984 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1986 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1987 return mLev->getDistributionOfTypes();
1990 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1992 famArr->applyLin(offset>0?1:-1,offset,0);
1993 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1996 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1997 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
2002 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
2003 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
2004 * If this method fails to find such a name it will throw an exception.
2006 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
2009 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2012 std::size_t len=nameTry.length();
2013 for(std::size_t ii=1;ii<len;ii++)
2015 std::string tmp=nameTry.substr(ii,len-ii);
2016 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2022 for(std::size_t i=1;i<30;i++)
2024 std::string tmp1(nameTry.at(0),i);
2026 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2032 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2034 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2036 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2039 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2041 std::size_t nbOfChunks=code.size()/3;
2042 if(code.size()%3!=0)
2043 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2045 for(std::size_t i=0;i<nbOfChunks;i++)
2054 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2055 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2056 * If _name is not empty and that 'm' has the same name nothing is done.
2057 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2059 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2062 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2067 std::string name(m->getName());
2072 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2073 oss << name << "' ! Names must match !";
2074 throw INTERP_KERNEL::Exception(oss.str().c_str());
2078 if(_desc_name.empty())
2079 _desc_name=m->getDescription();
2082 std::string name(m->getDescription());
2085 if(_desc_name!=name)
2087 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2088 oss << name << "' ! Names must match !";
2089 throw INTERP_KERNEL::Exception(oss.str().c_str());
2095 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2097 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2098 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2100 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2101 oss << " - Groups lying on this family : ";
2102 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2103 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2104 oss << std::endl << std::endl;
2109 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2110 * file. The mesh to load is specified by its name and numbers of a time step and an
2112 * \param [in] fileName - the name of MED file to read.
2113 * \param [in] mName - the name of the mesh to read.
2114 * \param [in] dt - the number of a time step.
2115 * \param [in] it - the number of an iteration.
2116 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2117 * mesh using decrRef() as it is no more needed.
2118 * \throw If the file is not readable.
2119 * \throw If there is no mesh with given attributes in the file.
2120 * \throw If the mesh in the file is not an unstructured one.
2122 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2124 MEDFileUtilities::CheckFileForRead(fileName);
2125 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2126 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2130 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2131 * file. The first mesh in the file is loaded.
2132 * \param [in] fileName - the name of MED file to read.
2133 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2134 * mesh using decrRef() as it is no more needed.
2135 * \throw If the file is not readable.
2136 * \throw If there is no meshes in the file.
2137 * \throw If the mesh in the file is not an unstructured one.
2139 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2141 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
2144 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2145 throw INTERP_KERNEL::Exception(oss.str().c_str());
2147 MEDFileUtilities::CheckFileForRead(fileName);
2148 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2150 ParaMEDMEM::MEDCouplingMeshType meshType;
2152 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
2153 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2157 * Returns an empty instance of MEDFileUMesh.
2158 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2159 * mesh using decrRef() as it is no more needed.
2161 MEDFileUMesh *MEDFileUMesh::New()
2163 return new MEDFileUMesh;
2167 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2168 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2169 * \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.
2170 * 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
2171 * at most the memory consumtion.
2173 * \param [in] fileName - the name of the file.
2174 * \param [in] mName - the name of the mesh to be read.
2175 * \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.
2176 * \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.
2177 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2178 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2179 * \param [in] mrs - the request for what to be loaded.
2180 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2182 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)
2184 MEDFileUtilities::CheckFileForRead(fileName);
2185 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2186 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2190 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2191 * This method is \b NOT wrapped into python.
2193 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)
2195 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2196 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2200 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2202 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2203 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2207 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2209 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2210 ret.push_back((const DataArrayDouble*)_coords);
2211 ret.push_back((const DataArrayInt *)_fam_coords);
2212 ret.push_back((const DataArrayInt *)_num_coords);
2213 ret.push_back((const DataArrayInt *)_rev_num_coords);
2214 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2215 ret.push_back((const PartDefinition *)_part_coords);
2216 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2217 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2221 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2223 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2227 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2229 return new MEDFileUMesh;
2232 MEDFileMesh *MEDFileUMesh::deepCpy() const
2234 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2235 if((const DataArrayDouble*)_coords)
2236 ret->_coords=_coords->deepCpy();
2237 if((const DataArrayInt*)_fam_coords)
2238 ret->_fam_coords=_fam_coords->deepCpy();
2239 if((const DataArrayInt*)_num_coords)
2240 ret->_num_coords=_num_coords->deepCpy();
2241 if((const DataArrayInt*)_rev_num_coords)
2242 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2243 if((const DataArrayAsciiChar*)_name_coords)
2244 ret->_name_coords=_name_coords->deepCpy();
2246 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2248 if((const MEDFileUMeshSplitL1 *)(*it))
2249 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2251 if((const PartDefinition*)_part_coords)
2252 ret->_part_coords=_part_coords->deepCpy();
2257 * Checks if \a this and another mesh are equal.
2258 * \param [in] other - the mesh to compare with.
2259 * \param [in] eps - a precision used to compare real values.
2260 * \param [in,out] what - the string returning description of unequal data.
2261 * \return bool - \c true if the meshes are equal, \c false, else.
2263 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2265 if(!MEDFileMesh::isEqual(other,eps,what))
2267 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2270 what="Mesh types differ ! This is unstructured and other is NOT !";
2273 clearNonDiscrAttributes();
2274 otherC->clearNonDiscrAttributes();
2275 const DataArrayDouble *coo1=_coords;
2276 const DataArrayDouble *coo2=otherC->_coords;
2277 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2279 what="Mismatch of coordinates ! One is defined and not other !";
2284 bool ret=coo1->isEqual(*coo2,eps);
2287 what="Coords differ !";
2291 const DataArrayInt *famc1=_fam_coords;
2292 const DataArrayInt *famc2=otherC->_fam_coords;
2293 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2295 what="Mismatch of families arr on nodes ! One is defined and not other !";
2300 bool ret=famc1->isEqual(*famc2);
2303 what="Families arr on node differ !";
2307 const DataArrayInt *numc1=_num_coords;
2308 const DataArrayInt *numc2=otherC->_num_coords;
2309 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2311 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2316 bool ret=numc1->isEqual(*numc2);
2319 what="Numbering arr on node differ !";
2323 const DataArrayAsciiChar *namec1=_name_coords;
2324 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2325 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2327 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2332 bool ret=namec1->isEqual(*namec2);
2335 what="Names arr on node differ !";
2339 if(_ms.size()!=otherC->_ms.size())
2341 what="Number of levels differs !";
2344 std::size_t sz=_ms.size();
2345 for(std::size_t i=0;i<sz;i++)
2347 const MEDFileUMeshSplitL1 *s1=_ms[i];
2348 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2349 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2351 what="Mismatch of presence of sub levels !";
2356 bool ret=s1->isEqual(s2,eps,what);
2361 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2364 if((!pd0 && pd1) || (pd0 && !pd1))
2366 what=std::string("node part def is defined only for one among this or other !");
2369 return pd0->isEqual(pd1,what);
2373 * Clears redundant attributes of incorporated data arrays.
2375 void MEDFileUMesh::clearNonDiscrAttributes() const
2377 MEDFileMesh::clearNonDiscrAttributes();
2378 const DataArrayDouble *coo1=_coords;
2380 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2381 const DataArrayInt *famc1=_fam_coords;
2383 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2384 const DataArrayInt *numc1=_num_coords;
2386 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2387 const DataArrayAsciiChar *namc1=_name_coords;
2389 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2390 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2392 const MEDFileUMeshSplitL1 *tmp=(*it);
2394 tmp->clearNonDiscrAttributes();
2398 void MEDFileUMesh::setName(const std::string& name)
2400 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2401 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2402 (*it)->setName(name);
2403 MEDFileMesh::setName(name);
2406 MEDFileUMesh::MEDFileUMesh()
2410 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2413 loadUMeshFromFile(fid,mName,dt,it,mrs);
2414 loadJointsFromFile(fid);
2416 catch(INTERP_KERNEL::Exception& e)
2422 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2423 * See MEDFileUMesh::LoadPartOf for detailed description.
2425 * \sa loadUMeshFromFile
2427 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)
2429 MEDFileUMeshL2 loaderl2;
2430 ParaMEDMEM::MEDCouplingMeshType meshType;
2433 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2434 if(meshType!=UNSTRUCTURED)
2436 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2437 throw INTERP_KERNEL::Exception(oss.str().c_str());
2439 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2440 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2444 * \brief Write joints in a file
2446 void MEDFileMesh::writeJoints(med_idt fid) const
2448 if ( (const MEDFileJoints*) _joints )
2449 _joints->write(fid);
2453 * \brief Load joints in a file or use provided ones
2455 //================================================================================
2457 * \brief Load joints in a file or use provided ones
2458 * \param [in] fid - MED file descriptor
2459 * \param [in] toUseInstedOfReading - optional joints to use instead of reading,
2460 * Usually this joints are those just read by another iteration
2461 * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New()
2463 //================================================================================
2465 void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading)
2467 if ( toUseInstedOfReading )
2468 setJoints( toUseInstedOfReading );
2470 _joints = MEDFileJoints::New( fid, _name );
2474 * \brief Return number of joints, which is equal to number of adjacent mesh domains
2476 int MEDFileMesh::getNumberOfJoints()
2478 return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0;
2482 * \brief Return joints with all adjacent mesh domains
2484 MEDFileJoints * MEDFileMesh::getJoints() const
2486 return const_cast<MEDFileJoints*>(& (*_joints));
2489 void MEDFileMesh::setJoints( MEDFileJoints* joints )
2491 if ( joints != _joints )
2500 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2502 * \sa loadPartUMeshFromFile
2504 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2506 MEDFileUMeshL2 loaderl2;
2507 ParaMEDMEM::MEDCouplingMeshType meshType;
2510 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2511 if(meshType!=UNSTRUCTURED)
2513 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2514 throw INTERP_KERNEL::Exception(oss.str().c_str());
2516 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2517 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2520 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2522 int lev=loaderl2.getNumberOfLevels();
2524 for(int i=0;i<lev;i++)
2526 if(!loaderl2.emptyLev(i))
2527 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2531 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2533 setName(loaderl2.getName());
2534 setDescription(loaderl2.getDescription());
2535 setUnivName(loaderl2.getUnivName());
2536 setIteration(loaderl2.getIteration());
2537 setOrder(loaderl2.getOrder());
2538 setTimeValue(loaderl2.getTime());
2539 setTimeUnit(loaderl2.getTimeUnit());
2540 _coords=loaderl2.getCoords();
2541 if(!mrs || mrs->isNodeFamilyFieldReading())
2542 _fam_coords=loaderl2.getCoordsFamily();
2543 if(!mrs || mrs->isNodeNumFieldReading())
2544 _num_coords=loaderl2.getCoordsNum();
2545 if(!mrs || mrs->isNodeNameFieldReading())
2546 _name_coords=loaderl2.getCoordsName();
2547 _part_coords=loaderl2.getPartDefOfCoo();
2551 MEDFileUMesh::~MEDFileUMesh()
2555 void MEDFileUMesh::writeLL(med_idt fid) const
2557 const DataArrayDouble *coo=_coords;
2558 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2559 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2560 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2561 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2562 int spaceDim=coo?coo->getNumberOfComponents():0;
2565 mdim=getMeshDimension();
2566 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2567 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2568 for(int i=0;i<spaceDim;i++)
2570 std::string info=coo->getInfoOnComponent(i);
2572 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2573 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
2574 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
2576 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
2578 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
2579 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2580 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2581 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2582 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2583 (*it)->write(fid,meshName,mdim);
2584 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2590 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2591 * \return std::vector<int> - a sequence of the relative dimensions.
2593 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2595 std::vector<int> ret;
2597 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2598 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2605 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2606 * \return std::vector<int> - a sequence of the relative dimensions.
2608 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2610 std::vector<int> ret0=getNonEmptyLevels();
2611 if((const DataArrayDouble *) _coords)
2613 std::vector<int> ret(ret0.size()+1);
2615 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2621 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2623 std::vector<int> ret;
2624 const DataArrayInt *famCoo(_fam_coords);
2628 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2630 const MEDFileUMeshSplitL1 *cur(*it);
2632 if(cur->getFamilyField())
2638 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2640 std::vector<int> ret;
2641 const DataArrayInt *numCoo(_num_coords);
2645 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2647 const MEDFileUMeshSplitL1 *cur(*it);
2649 if(cur->getNumberField())
2655 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2657 std::vector<int> ret;
2658 const DataArrayAsciiChar *nameCoo(_name_coords);
2662 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2664 const MEDFileUMeshSplitL1 *cur(*it);
2666 if(cur->getNameField())
2673 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2674 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2675 * \param [in] grp - the name of the group of interest.
2676 * \return std::vector<int> - a sequence of the relative dimensions.
2678 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2680 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2681 return getFamsNonEmptyLevels(fams);
2685 * Returns all relative mesh levels (including nodes) where a given group is defined.
2686 * \param [in] grp - the name of the group of interest.
2687 * \return std::vector<int> - a sequence of the relative dimensions.
2689 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2691 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2692 return getFamsNonEmptyLevelsExt(fams);
2696 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2697 * To include nodes, call getFamNonEmptyLevelsExt() method.
2698 * \param [in] fam - the name of the family of interest.
2699 * \return std::vector<int> - a sequence of the relative dimensions.
2701 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2703 std::vector<std::string> fams(1,std::string(fam));
2704 return getFamsNonEmptyLevels(fams);
2708 * Returns all relative mesh levels (including nodes) where a given family is defined.
2709 * \param [in] fam - the name of the family of interest.
2710 * \return std::vector<int> - a sequence of the relative dimensions.
2712 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2714 std::vector<std::string> fams(1,std::string(fam));
2715 return getFamsNonEmptyLevelsExt(fams);
2719 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2720 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2721 * \param [in] grps - a sequence of names of the groups of interest.
2722 * \return std::vector<int> - a sequence of the relative dimensions.
2724 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2726 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2727 return getFamsNonEmptyLevels(fams);
2731 * Returns all relative mesh levels (including nodes) where given groups are defined.
2732 * \param [in] grps - a sequence of names of the groups of interest.
2733 * \return std::vector<int> - a sequence of the relative dimensions.
2735 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2737 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2738 return getFamsNonEmptyLevelsExt(fams);
2742 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2743 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2744 * \param [in] fams - the name of the family of interest.
2745 * \return std::vector<int> - a sequence of the relative dimensions.
2747 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2749 std::vector<int> ret;
2750 std::vector<int> levs=getNonEmptyLevels();
2751 std::vector<int> famIds=getFamiliesIds(fams);
2752 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2753 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2759 * Returns all relative mesh levels (including nodes) where given families are defined.
2760 * \param [in] fams - the names of the families of interest.
2761 * \return std::vector<int> - a sequence of the relative dimensions.
2763 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2765 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2766 const DataArrayInt *famCoords=_fam_coords;
2769 std::vector<int> famIds=getFamiliesIds(fams);
2770 if(famCoords->presenceOfValue(famIds))
2772 std::vector<int> ret(ret0.size()+1);
2774 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2782 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2783 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2784 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2787 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2789 std::vector<std::string> ret;
2790 std::vector<std::string> allGrps=getGroupsNames();
2791 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2793 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2794 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2800 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2802 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2803 if((const DataArrayInt *)_fam_coords)
2805 int val=_fam_coords->getMaxValue(tmp);
2806 ret=std::max(ret,std::abs(val));
2808 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2810 if((const MEDFileUMeshSplitL1 *)(*it))
2812 const DataArrayInt *da=(*it)->getFamilyField();
2815 int val=da->getMaxValue(tmp);
2816 ret=std::max(ret,std::abs(val));
2823 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2825 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2826 if((const DataArrayInt *)_fam_coords)
2828 int val=_fam_coords->getMaxValue(tmp);
2829 ret=std::max(ret,val);
2831 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2833 if((const MEDFileUMeshSplitL1 *)(*it))
2835 const DataArrayInt *da=(*it)->getFamilyField();
2838 int val=da->getMaxValue(tmp);
2839 ret=std::max(ret,val);
2846 int MEDFileUMesh::getMinFamilyIdInArrays() const
2848 int ret=std::numeric_limits<int>::max(),tmp=-1;
2849 if((const DataArrayInt *)_fam_coords)
2851 int val=_fam_coords->getMinValue(tmp);
2852 ret=std::min(ret,val);
2854 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2856 if((const MEDFileUMeshSplitL1 *)(*it))
2858 const DataArrayInt *da=(*it)->getFamilyField();
2861 int val=da->getMinValue(tmp);
2862 ret=std::min(ret,val);
2870 * Returns the dimension on cells in \a this mesh.
2871 * \return int - the mesh dimension.
2872 * \throw If there are no cells in this mesh.
2874 int MEDFileUMesh::getMeshDimension() const
2877 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2878 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2879 return (*it)->getMeshDimension()+lev;
2880 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2884 * Returns the space dimension of \a this mesh that is equal to number of components in
2885 * the node coordinates array.
2886 * \return int - the space dimension of \a this mesh.
2887 * \throw If the node coordinates array is not available.
2889 int MEDFileUMesh::getSpaceDimension() const
2891 const DataArrayDouble *coo=_coords;
2893 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2894 return coo->getNumberOfComponents();
2898 * Returns a string describing \a this mesh.
2899 * \return std::string - the mesh information string.
2901 std::string MEDFileUMesh::simpleRepr() const
2903 std::ostringstream oss;
2904 oss << MEDFileMesh::simpleRepr();
2905 const DataArrayDouble *coo=_coords;
2906 oss << "- The dimension of the space is ";
2907 static const char MSG1[]= "*** NO COORDS SET ***";
2908 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2910 oss << _coords->getNumberOfComponents() << std::endl;
2912 oss << MSG1 << std::endl;
2913 oss << "- Type of the mesh : UNSTRUCTURED\n";
2914 oss << "- Number of nodes : ";
2916 oss << _coords->getNumberOfTuples() << std::endl;
2918 oss << MSG1 << std::endl;
2919 std::size_t nbOfLev=_ms.size();
2920 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2921 for(std::size_t i=0;i<nbOfLev;i++)
2923 const MEDFileUMeshSplitL1 *lev=_ms[i];
2924 oss << " - Level #" << -((int) i) << " has dimension : ";
2927 oss << lev->getMeshDimension() << std::endl;
2928 lev->simpleRepr(oss);
2931 oss << MSG2 << std::endl;
2933 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2936 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2937 oss << "- Names of coordinates :" << std::endl;
2938 std::vector<std::string> vars=coo->getVarsOnComponent();
2939 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2940 oss << std::endl << "- Units of coordinates : " << std::endl;
2941 std::vector<std::string> units=coo->getUnitsOnComponent();
2942 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2944 oss << std::endl << std::endl;
2950 * Returns a full textual description of \a this mesh.
2951 * \return std::string - the string holding the mesh description.
2953 std::string MEDFileUMesh::advancedRepr() const
2955 return simpleRepr();
2959 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2960 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2961 * \return int - the number of entities.
2962 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2964 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2966 if(meshDimRelToMaxExt==1)
2968 if(!((const DataArrayDouble *)_coords))
2969 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2970 return _coords->getNumberOfTuples();
2972 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2976 * Returns the family field for mesh entities of a given dimension.
2977 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2978 * \return const DataArrayInt * - the family field. It is an array of ids of families
2979 * each mesh entity belongs to. It can be \c NULL.
2981 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2983 if(meshDimRelToMaxExt==1)
2985 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2986 return l1->getFamilyField();
2989 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
2991 if(meshDimRelToMaxExt==1)
2993 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2994 return l1->getFamilyField();
2998 * Returns the optional numbers of mesh entities of a given dimension.
2999 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3000 * \return const DataArrayInt * - the array of the entity numbers.
3001 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3003 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
3005 if(meshDimRelToMaxExt==1)
3007 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3008 return l1->getNumberField();
3011 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
3013 if(meshDimRelToMaxExt==1)
3014 return _name_coords;
3015 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3016 return l1->getNameField();
3020 * 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).
3022 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
3023 * \param [in] gt - The input geometric type for which the part definition is requested.
3024 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
3026 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
3028 if(meshDimRelToMaxExt==1)
3029 return _part_coords;
3030 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3031 return l1->getPartDef(gt);
3034 int MEDFileUMesh::getNumberOfNodes() const
3036 const DataArrayDouble *coo(_coords);
3038 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
3039 return coo->getNumberOfTuples();
3042 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
3044 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
3045 return l1->getNumberOfCells();
3048 bool MEDFileUMesh::hasImplicitPart() const
3053 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
3055 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
3058 void MEDFileUMesh::releaseImplicitPartIfAny() const
3062 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
3064 std::size_t sz(st.getNumberOfItems());
3065 for(std::size_t i=0;i<sz;i++)
3067 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
3068 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3069 if(st[i].getPflName().empty())
3070 m->computeNodeIdsAlg(nodesFetched);
3073 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3074 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3075 m2->computeNodeIdsAlg(nodesFetched);
3081 * Returns the optional numbers of mesh entities of a given dimension transformed using
3082 * DataArrayInt::invertArrayN2O2O2N().
3083 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3084 * \return const DataArrayInt * - the array of the entity numbers transformed using
3085 * DataArrayInt::invertArrayN2O2O2N().
3086 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3088 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3090 if(meshDimRelToMaxExt==1)
3092 if(!((const DataArrayInt *)_num_coords))
3093 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3094 return _rev_num_coords;
3096 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3097 return l1->getRevNumberField();
3101 * Returns a pointer to the node coordinates array of \a this mesh \b without
3102 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3104 DataArrayDouble *MEDFileUMesh::getCoords() const
3106 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
3107 if((DataArrayDouble *)tmp)
3115 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3116 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3118 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3119 * \param [in] grp - the name of the group whose mesh entities are included in the
3121 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3122 * according to the optional numbers of entities, if available.
3123 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3124 * delete this mesh using decrRef() as it is no more needed.
3125 * \throw If the name of a nonexistent group is specified.
3126 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3128 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3130 synchronizeTinyInfoOnLeaves();
3131 std::vector<std::string> tmp(1);
3133 return getGroups(meshDimRelToMaxExt,tmp,renum);
3137 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3138 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3140 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3141 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3143 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3144 * according to the optional numbers of entities, if available.
3145 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3146 * delete this mesh using decrRef() as it is no more needed.
3147 * \throw If a name of a nonexistent group is present in \a grps.
3148 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3150 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3152 synchronizeTinyInfoOnLeaves();
3153 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3154 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3155 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3156 zeRet->setName(grps[0]);
3157 return zeRet.retn();
3161 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3162 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3164 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3165 * \param [in] fam - the name of the family whose mesh entities are included in the
3167 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3168 * according to the optional numbers of entities, if available.
3169 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3170 * delete this mesh using decrRef() as it is no more needed.
3171 * \throw If a name of a nonexistent family is present in \a grps.
3172 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3174 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3176 synchronizeTinyInfoOnLeaves();
3177 std::vector<std::string> tmp(1);
3179 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3183 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3184 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3186 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3187 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3189 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3190 * according to the optional numbers of entities, if available.
3191 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3192 * delete this mesh using decrRef() as it is no more needed.
3193 * \throw If a name of a nonexistent family is present in \a fams.
3194 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3196 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3198 synchronizeTinyInfoOnLeaves();
3199 if(meshDimRelToMaxExt==1)
3201 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3202 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3203 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3207 std::vector<int> famIds=getFamiliesIds(fams);
3208 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3209 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
3211 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3213 zeRet=l1->getFamilyPart(0,0,renum);
3214 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3215 zeRet->setName(fams[0]);
3216 return zeRet.retn();
3220 * Returns ids of mesh entities contained in given families of a given dimension.
3221 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3223 * \param [in] fams - the names of the families of interest.
3224 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3225 * returned instead of ids.
3226 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3227 * numbers, if available and required, of mesh entities of the families. The caller
3228 * is to delete this array using decrRef() as it is no more needed.
3229 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3231 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3233 std::vector<int> famIds=getFamiliesIds(fams);
3234 if(meshDimRelToMaxExt==1)
3236 if((const DataArrayInt *)_fam_coords)
3238 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3240 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3242 da=_fam_coords->getIdsEqualList(0,0);
3244 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3249 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3251 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3253 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3255 return l1->getFamilyPartArr(0,0,renum);
3259 * Returns a MEDCouplingUMesh of a given relative dimension.
3260 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3261 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3262 * To build a valid MEDCouplingUMesh from the returned one in this case,
3263 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3264 * \param [in] meshDimRelToMax - the relative dimension of interest.
3265 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3266 * optional numbers of mesh entities.
3267 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3268 * delete using decrRef() as it is no more needed.
3269 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3270 * \sa getGenMeshAtLevel()
3272 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3274 synchronizeTinyInfoOnLeaves();
3275 if(meshDimRelToMaxExt==1)
3279 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3280 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3281 umesh->setCoords(cc);
3282 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3283 umesh->setName(getName());
3287 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3288 return l1->getWholeMesh(renum);
3292 * Returns a MEDCouplingUMesh of a given relative dimension.
3293 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3294 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3295 * To build a valid MEDCouplingUMesh from the returned one in this case,
3296 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3297 * \param [in] meshDimRelToMax - the relative dimension of interest.
3298 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3299 * optional numbers of mesh entities.
3300 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3301 * delete using decrRef() as it is no more needed.
3302 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3303 * \sa getMeshAtLevel()
3305 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3307 return getMeshAtLevel(meshDimRelToMax,renum);
3310 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3312 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3313 return l1->getDistributionOfTypes();
3317 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3318 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3319 * optional numbers of mesh entities.
3320 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3321 * delete using decrRef() as it is no more needed.
3322 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3324 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3326 return getMeshAtLevel(0,renum);
3330 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3331 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3332 * optional numbers of mesh entities.
3333 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3334 * delete using decrRef() as it is no more needed.
3335 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3337 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3339 return getMeshAtLevel(-1,renum);
3343 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3344 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3345 * optional numbers of mesh entities.
3346 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3347 * delete using decrRef() as it is no more needed.
3348 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3350 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3352 return getMeshAtLevel(-2,renum);
3356 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3357 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3358 * optional numbers of mesh entities.
3359 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3360 * delete using decrRef() as it is no more needed.
3361 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3363 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3365 return getMeshAtLevel(-3,renum);
3369 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3370 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3371 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3372 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3374 void MEDFileUMesh::forceComputationOfParts() const
3376 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3378 const MEDFileUMeshSplitL1 *elt(*it);
3380 elt->forceComputationOfParts();
3385 * This method returns a vector of mesh parts containing each exactly one geometric type.
3386 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3387 * This method is only for memory aware users.
3388 * The returned pointers are **NOT** new object pointer. No need to mange them.
3390 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3392 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3393 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3397 * This method returns the part of \a this having the geometric type \a gt.
3398 * If such part is not existing an exception will be thrown.
3399 * The returned pointer is **NOT** new object pointer. No need to mange it.
3401 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3403 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3404 int lev=(int)cm.getDimension()-getMeshDimension();
3405 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3406 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3410 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3411 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3413 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3415 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3416 return sp->getGeoTypes();
3420 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3421 * \param [in] gt - the geometric type for which the family field is asked.
3422 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3423 * delete using decrRef() as it is no more needed.
3424 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3426 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3428 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3429 int lev=(int)cm.getDimension()-getMeshDimension();
3430 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3431 return sp->extractFamilyFieldOnGeoType(gt);
3435 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3436 * \param [in] gt - the geometric type for which the number field is asked.
3437 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3438 * delete using decrRef() as it is no more needed.
3439 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3441 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3443 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3444 int lev=(int)cm.getDimension()-getMeshDimension();
3445 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3446 return sp->extractNumberFieldOnGeoType(gt);
3450 * This method returns for specified geometric type \a gt the relative level to \a this.
3451 * If the relative level is empty an exception will be thrown.
3453 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3455 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3456 int ret((int)cm.getDimension()-getMeshDimension());
3457 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3461 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3463 if(meshDimRelToMaxExt==1)
3464 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3465 if(meshDimRelToMaxExt>1)
3466 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3467 int tracucedRk=-meshDimRelToMaxExt;
3468 if(tracucedRk>=(int)_ms.size())
3469 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3470 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3471 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3472 return _ms[tracucedRk];
3475 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3477 if(meshDimRelToMaxExt==1)
3478 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3479 if(meshDimRelToMaxExt>1)
3480 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3481 int tracucedRk=-meshDimRelToMaxExt;
3482 if(tracucedRk>=(int)_ms.size())
3483 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3484 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3485 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3486 return _ms[tracucedRk];
3489 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3491 if(-meshDimRelToMax>=(int)_ms.size())
3492 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3494 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3496 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3498 int ref=(*it)->getMeshDimension();
3499 if(ref+i!=meshDim-meshDimRelToMax)
3500 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3506 * Sets the node coordinates array of \a this mesh.
3507 * \param [in] coords - the new node coordinates array.
3508 * \throw If \a coords == \c NULL.
3510 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3513 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3514 coords->checkAllocated();
3515 int nbOfTuples=coords->getNumberOfTuples();
3518 _fam_coords=DataArrayInt::New();
3519 _fam_coords->alloc(nbOfTuples,1);
3520 _fam_coords->fillWithZero();
3521 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3522 if((MEDFileUMeshSplitL1 *)(*it))
3523 (*it)->setCoords(coords);
3527 * Removes all groups of a given dimension in \a this mesh.
3528 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3529 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3531 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3533 if(meshDimRelToMaxExt==1)
3535 if((DataArrayInt *)_fam_coords)
3536 _fam_coords->fillWithZero();
3539 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3540 l1->eraseFamilyField();
3545 * Removes all families with ids not present in the family fields of \a this mesh.
3547 void MEDFileUMesh::optimizeFamilies()
3549 std::vector<int> levs=getNonEmptyLevelsExt();
3550 std::set<int> allFamsIds;
3551 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3553 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3554 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3556 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3559 std::set<std::string> famNamesToKill;
3560 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3562 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3563 famNamesToKill.insert((*it).first);
3565 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3566 _families.erase(*it);
3567 std::vector<std::string> grpNamesToKill;
3568 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3570 std::vector<std::string> tmp;
3571 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3573 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3574 tmp.push_back(*it2);
3579 tmp.push_back((*it).first);
3581 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3586 * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity
3587 * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1.
3588 * The boundary is built according to the following method:
3589 * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
3590 * coordinates array is extended).
3591 * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated.
3592 * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the
3593 * other side of the group is no more a neighbor)
3594 * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
3595 * bordering the newly created boundary use the newly computed nodes.
3597 * \param[in] grpNameM1 name of the (-1)-level group defining the boundary
3598 * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
3600 * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
3601 * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
3603 void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
3604 DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3606 std::vector<int> levs=getNonEmptyLevels();
3607 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3608 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
3609 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3610 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3611 int nbNodes=m0->getNumberOfNodes();
3612 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3613 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3614 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3615 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3616 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3617 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3618 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3619 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3620 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3621 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3622 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3623 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3624 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3625 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3626 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3627 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3628 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3629 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3630 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3632 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3633 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3634 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3635 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3636 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3637 m0->setCoords(tmp0->getCoords());
3638 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3639 m1->setCoords(m0->getCoords());
3640 _coords=m0->getCoords(); _coords->incrRef();
3641 // duplication of cells in group 'grpNameM1' on level -1
3642 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3643 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3644 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3645 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3646 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3648 newm1->setName(getName());
3649 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3651 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !");
3652 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3653 newFam->alloc(newm1->getNumberOfCells(),1);
3654 // Get a new family ID: care must be taken if we need a positive ID or a negative one:
3655 // Positive ID for family of nodes, negative for all the rest.
3657 if (m1->getMeshDimension() == 0)
3658 idd=getMaxFamilyId()+1;
3660 idd=getMinFamilyId()-1;
3661 int globStart=0,start=0,end,globEnd;
3662 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3663 for(int i=0;i<nbOfChunks;i++)
3665 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3666 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3668 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3669 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3670 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3675 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3679 newm1->setCoords(getCoords());
3680 setMeshAtLevel(-1,newm1);
3681 setFamilyFieldArr(-1,newFam);
3682 std::string grpName2(grpNameM1); grpName2+="_dup";
3683 addFamily(grpName2,idd);
3684 addFamilyOnGrp(grpName2,grpName2);
3689 int newNbOfNodes=getCoords()->getNumberOfTuples();
3690 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3691 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3692 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3695 nodesDuplicated=nodeIdsToDuplicate.retn();
3696 cellsModified=cellsToModifyConn0.retn();
3697 cellsNotModified=cellsToModifyConn1.retn();
3701 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3702 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3703 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3705 * \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.
3706 * 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.
3708 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3710 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3711 std::vector<int> levs=getNonEmptyLevels();
3713 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3714 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3717 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3719 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3720 std::vector<int> code1=m->getDistributionOfTypes();
3721 end=PutInThirdComponentOfCodeOffset(code1,start);
3722 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3723 bool hasChanged=m->unPolyze();
3724 DataArrayInt *fake=0;
3725 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3726 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3728 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3731 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3732 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3734 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3735 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3736 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3737 setMeshAtLevel(*it,m);
3738 std::vector<int> code2=m->getDistributionOfTypes();
3739 end=PutInThirdComponentOfCodeOffset(code2,start);
3740 newCode.insert(newCode.end(),code2.begin(),code2.end());
3742 if(o2nCellsPart2->isIdentity())
3746 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3747 setFamilyFieldArr(*it,newFamField);
3751 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3752 setRenumFieldArr(*it,newNumField);
3757 newCode.insert(newCode.end(),code1.begin(),code1.end());
3763 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3764 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3765 o2nRenumCell=o2nRenumCellRet.retn();
3770 /*! \cond HIDDEN_ITEMS */
3771 struct MEDLoaderAccVisit1
3773 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3774 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3775 int _new_nb_of_nodes;
3780 * 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.
3781 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3782 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3783 * -1 values in returned array means that the corresponding old node is no more used.
3785 * \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
3786 * is modified in \a this.
3787 * \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
3790 DataArrayInt *MEDFileUMesh::zipCoords()
3792 const DataArrayDouble *coo(getCoords());
3794 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3795 int nbOfNodes(coo->getNumberOfTuples());
3796 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3797 std::vector<int> neLevs(getNonEmptyLevels());
3798 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3800 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
3801 if(zeLev->isMeshStoredSplitByType())
3803 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
3804 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3806 (*it)->computeNodeIdsAlg(nodeIdsInUse);
3810 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
3811 mesh->computeNodeIdsAlg(nodeIdsInUse);
3814 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
3815 if(nbrOfNodesInUse==nbOfNodes)
3816 return 0;//no need to update _part_coords
3817 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
3818 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3819 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
3820 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3821 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3822 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3823 if((const DataArrayInt *)_fam_coords)
3824 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3825 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3826 if((const DataArrayInt *)_num_coords)
3827 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3828 if((const DataArrayAsciiChar *)_name_coords)
3829 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3830 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3831 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3833 if((MEDFileUMeshSplitL1*)*it)
3835 (*it)->renumberNodesInConn(ret->begin());
3836 (*it)->setCoords(_coords);
3839 // updates _part_coords
3840 const PartDefinition *pc(_part_coords);
3843 MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
3844 _part_coords=tmpPD->composeWith(pc);
3850 * This method performs an extrusion along a path defined by \a m1D.
3851 * \a this is expected to be a mesh with max mesh dimension equal to 2.
3852 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
3853 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
3854 * This method scans all levels in \a this
3855 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
3857 * \param [in] m1D - the mesh defining the extrusion path.
3858 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
3859 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
3861 * \sa MEDCouplingUMesh::buildExtrudedMesh
3863 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
3865 if(getMeshDimension()!=2)
3866 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3867 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3868 m1D->checkCoherency();
3869 if(m1D->getMeshDimension()!=1)
3870 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3871 int nbRep(m1D->getNumberOfCells());
3872 std::vector<int> levs(getNonEmptyLevels());
3873 std::vector<std::string> grps(getGroupsNames());
3874 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3875 DataArrayDouble *coords(0);
3876 std::size_t nbOfLevsOut(levs.size()+1);
3877 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3878 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3880 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3881 item=item->clone(false);
3882 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3883 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3884 tmp->changeSpaceDimension(3+(*lev),0.);
3885 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3886 zeList.push_back(elt);
3888 coords=elt->getCoords();
3891 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3892 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3894 (*it)->setName(getName());
3895 (*it)->setCoords(coords);
3897 for(std::size_t ii=0;ii!=zeList.size();ii++)
3900 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
3903 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
3904 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
3905 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
3906 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
3907 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
3908 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
3909 std::vector<const MEDCouplingUMesh *> elts(3);
3910 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
3911 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
3912 elt->setName(getName());
3915 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
3916 ret->setMeshAtLevel(lev,elt);
3918 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
3919 endLev=endLev->clone(false); endLev->setCoords(coords);
3920 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
3921 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
3922 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
3923 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
3924 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
3925 endLev->setName(getName());
3926 ret->setMeshAtLevel(levs.back()-1,endLev);
3928 for(std::size_t ii=0;ii!=zeList.size();ii++)
3931 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3932 std::vector< const DataArrayInt * > outGrps2;
3935 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3937 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
3938 if(!grpArr->empty())
3940 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
3941 int offset0(zeList[ii]->getNumberOfCells());
3942 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
3943 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
3944 std::ostringstream oss; oss << grpArr2->getName() << "_top";
3945 grpArr2->setName(oss.str());
3946 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3947 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3948 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3949 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3954 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3956 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
3957 if(!grpArr->empty())
3959 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
3960 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
3961 std::vector< const DataArrayInt *> grpArrs2(nbRep);
3962 for(int iii=0;iii<nbRep;iii++)
3964 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
3965 grpArrs2[iii]=grpArrs[iii];
3967 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
3968 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3969 std::ostringstream grpName; grpName << *grp << "_extruded";
3970 grpArrExt->setName(grpName.str());
3971 outGrps.push_back(grpArrExt);
3972 outGrps2.push_back(grpArrExt);
3975 ret->setGroupsAtLevel(lev,outGrps2);
3977 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3978 std::vector< const DataArrayInt * > outGrps2;
3979 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3981 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
3982 if(grpArr1->empty())
3984 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
3985 std::ostringstream grpName; grpName << *grp << "_top";
3986 grpArr2->setName(grpName.str());
3987 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
3988 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3989 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3991 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
3996 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
3997 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
3998 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4000 * \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
4001 * corresponding quadratic cells. 1 is those creating the 'most' complex.
4002 * \param [in] eps - detection threshold for coordinates.
4003 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4005 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
4007 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
4009 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4010 int initialNbNodes(getNumberOfNodes());
4011 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4012 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4014 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
4016 DataArrayDouble *zeCoords(m0->getCoords());
4017 ret->setMeshAtLevel(0,m0);
4018 std::vector<int> levs(getNonEmptyLevels());
4019 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4022 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4023 ret->setFamilyFieldArr(0,famFieldCpy);
4025 famField=getFamilyFieldAtLevel(1);
4028 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
4029 fam->fillWithZero();
4030 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
4031 ret->setFamilyFieldArr(1,fam);
4033 ret->copyFamGrpMapsFrom(*this);
4034 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
4035 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4039 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4040 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4041 if(m1->getMeshDimension()!=0)
4044 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
4045 }//kill unused notUsed var
4046 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
4048 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
4049 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4052 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
4053 throw INTERP_KERNEL::Exception(oss.str().c_str());
4055 b->applyLin(1,initialNbNodes);
4056 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
4057 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
4058 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
4059 m1->renumberNodesInConn(renum->begin());
4061 m1->setCoords(zeCoords);
4062 ret->setMeshAtLevel(*lev,m1);
4063 famField=getFamilyFieldAtLevel(*lev);
4066 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4067 ret->setFamilyFieldArr(*lev,famFieldCpy);
4074 * This method converts all quadratic cells in \a this into linear cells.
4075 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
4076 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
4078 * \param [in] eps - detection threshold for coordinates.
4079 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
4081 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
4083 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
4085 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
4086 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
4087 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
4088 m0->convertQuadraticCellsToLinear();
4090 DataArrayDouble *zeCoords(m0->getCoords());
4091 ret->setMeshAtLevel(0,m0);
4092 std::vector<int> levs(getNonEmptyLevels());
4093 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
4096 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4097 ret->setFamilyFieldArr(0,famFieldCpy);
4099 famField=getFamilyFieldAtLevel(1);
4102 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
4103 ret->setFamilyFieldArr(1,fam);
4105 ret->copyFamGrpMapsFrom(*this);
4106 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4110 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4111 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4112 m1->convertQuadraticCellsToLinear();
4115 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4116 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4119 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4120 throw INTERP_KERNEL::Exception(oss.str().c_str());
4122 m1->renumberNodesInConn(b->begin());
4123 m1->setCoords(zeCoords);
4124 ret->setMeshAtLevel(*lev,m1);
4125 famField=getFamilyFieldAtLevel(*lev);
4128 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4129 ret->setFamilyFieldArr(*lev,famFieldCpy);
4135 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4137 clearNonDiscrAttributes();
4138 forceComputationOfParts();
4139 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4140 std::vector<int> layer0;
4141 layer0.push_back(_order); //0 i
4142 layer0.push_back(_iteration);//1 i
4143 layer0.push_back(getSpaceDimension());//2 i
4144 tinyDouble.push_back(_time);//0 d
4145 tinyStr.push_back(_name);//0 s
4146 tinyStr.push_back(_desc_name);//1 s
4147 for(int i=0;i<getSpaceDimension();i++)
4148 tinyStr.push_back(_coords->getInfoOnComponent(i));
4149 layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
4150 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4152 tinyStr.push_back((*it).first);
4153 layer0.push_back((*it).second);
4155 layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
4156 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4158 layer0.push_back((int)(*it0).second.size());
4159 tinyStr.push_back((*it0).first);
4160 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4161 tinyStr.push_back(*it1);
4163 // sizeof(layer0)==3+aa+1+bb layer#0
4164 bigArrayD=_coords;// 0 bd
4165 bigArraysI.push_back(_fam_coords);// 0 bi
4166 bigArraysI.push_back(_num_coords);// 1 bi
4167 const PartDefinition *pd(_part_coords);
4169 layer0.push_back(-1);
4172 std::vector<int> tmp0;
4173 pd->serialize(tmp0,bigArraysI);
4174 tinyInt.push_back(tmp0.size());
4175 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4178 std::vector<int> layer1;
4179 std::vector<int> levs(getNonEmptyLevels());
4180 layer1.push_back((int)levs.size());// 0 i <- key
4181 layer1.insert(layer1.end(),levs.begin(),levs.end());
4182 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4184 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4185 lev->serialize(layer1,bigArraysI);
4187 // put layers all together.
4188 tinyInt.push_back(layer0.size());
4189 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4190 tinyInt.push_back(layer1.size());
4191 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4194 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4195 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4197 int sz0(tinyInt[0]);
4198 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4199 int sz1(tinyInt[sz0+1]);
4200 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4202 std::reverse(layer0.begin(),layer0.end());
4203 std::reverse(layer1.begin(),layer1.end());
4204 std::reverse(tinyDouble.begin(),tinyDouble.end());
4205 std::reverse(tinyStr.begin(),tinyStr.end());
4206 std::reverse(bigArraysI.begin(),bigArraysI.end());
4208 _order=layer0.back(); layer0.pop_back();
4209 _iteration=layer0.back(); layer0.pop_back();
4210 int spaceDim(layer0.back()); layer0.pop_back();
4211 _time=tinyDouble.back(); tinyDouble.pop_back();
4212 _name=tinyStr.back(); tinyStr.pop_back();
4213 _desc_name=tinyStr.back(); tinyStr.pop_back();
4214 _coords=bigArrayD; _coords->rearrange(spaceDim);
4215 for(int i=0;i<spaceDim;i++)
4217 _coords->setInfoOnComponent(i,tinyStr.back());
4220 int nbOfFams(layer0.back()); layer0.pop_back();
4222 for(int i=0;i<nbOfFams;i++)
4224 _families[tinyStr.back()]=layer0.back();
4225 tinyStr.pop_back(); layer0.pop_back();
4227 int nbGroups(layer0.back()); layer0.pop_back();
4229 for(int i=0;i<nbGroups;i++)
4231 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4232 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4233 std::vector<std::string> fams(nbOfFamsOnGrp);
4234 for(int j=0;j<nbOfFamsOnGrp;j++)
4236 fams[j]=tinyStr.back(); tinyStr.pop_back();
4238 _groups[grpName]=fams;
4240 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4241 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4243 int isPd(layer0.back()); layer0.pop_back();
4246 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4247 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4248 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4251 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4253 int nbLevs(layer1.back()); layer1.pop_back();
4254 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4256 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4257 _ms.resize(maxLev+1);
4258 for(int i=0;i<nbLevs;i++)
4262 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4267 * Adds a group of nodes to \a this mesh.
4268 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4269 * The ids should be sorted and different each other (MED file norm).
4271 * \warning this method can alter default "FAMILLE_ZERO" family.
4272 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4274 * \throw If the node coordinates array is not set.
4275 * \throw If \a ids == \c NULL.
4276 * \throw If \a ids->getName() == "".
4277 * \throw If \a ids does not respect the MED file norm.
4278 * \throw If a group with name \a ids->getName() already exists.
4280 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4282 const DataArrayDouble *coords(_coords);
4284 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4285 int nbOfNodes(coords->getNumberOfTuples());
4286 if(!((DataArrayInt *)_fam_coords))
4287 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4289 addGroupUnderground(true,ids,_fam_coords);
4293 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4295 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4296 * The ids should be sorted and different each other (MED file norm).
4298 * \warning this method can alter default "FAMILLE_ZERO" family.
4299 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4301 * \throw If the node coordinates array is not set.
4302 * \throw If \a ids == \c NULL.
4303 * \throw If \a ids->getName() == "".
4304 * \throw If \a ids does not respect the MED file norm.
4305 * \throw If a group with name \a ids->getName() already exists.
4307 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4309 std::vector<int> levs(getNonEmptyLevelsExt());
4310 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4312 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4313 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4315 if(meshDimRelToMaxExt==1)
4316 { addNodeGroup(ids); return ; }
4317 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4318 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4319 addGroupUnderground(false,ids,fam);
4323 * Changes a name of a family specified by its id.
4324 * \param [in] id - the id of the family of interest.
4325 * \param [in] newFamName - the new family name.
4326 * \throw If no family with the given \a id exists.
4328 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4330 std::string oldName=getFamilyNameGivenId(id);
4331 _families.erase(oldName);
4332 _families[newFamName]=id;
4336 * Removes a mesh of a given dimension.
4337 * \param [in] meshDimRelToMax - the relative dimension of interest.
4338 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4340 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4342 std::vector<int> levSet=getNonEmptyLevels();
4343 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4344 if(it==levSet.end())
4345 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4346 int pos=(-meshDimRelToMax);
4351 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4352 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4353 * \param [in] m - the new mesh to set.
4354 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4356 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4357 * another node coordinates array.
4358 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4359 * to the existing meshes of other levels of \a this mesh.
4361 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4363 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4364 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4368 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4369 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4370 * \param [in] m - the new mesh to set.
4371 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4372 * writing \a this mesh in a MED file.
4373 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4375 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4376 * another node coordinates array.
4377 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4378 * to the existing meshes of other levels of \a this mesh.
4380 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4382 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4383 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4386 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4388 dealWithTinyInfo(m);
4389 std::vector<int> levSet=getNonEmptyLevels();
4390 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4392 if((DataArrayDouble *)_coords==0)
4394 DataArrayDouble *c=m->getCoords();
4399 if(m->getCoords()!=_coords)
4400 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4401 int sz=(-meshDimRelToMax)+1;
4402 if(sz>=(int)_ms.size())
4404 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4408 return _ms[-meshDimRelToMax];
4412 * This method allows to set at once the content of different levels in \a this.
4413 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4415 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4416 * \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.
4417 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4419 * \throw If \a there is a null pointer in \a ms.
4420 * \sa MEDFileUMesh::setMeshAtLevel
4422 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4426 const MEDCouplingUMesh *mRef=ms[0];
4428 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4429 std::string name(mRef->getName());
4430 const DataArrayDouble *coo(mRef->getCoords());
4433 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4435 const MEDCouplingUMesh *cur(*it);
4437 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4438 if(coo!=cur->getCoords())
4439 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4440 int mdim=cur->getMeshDimension();
4441 zeDim=std::max(zeDim,mdim);
4442 if(s.find(mdim)!=s.end())
4443 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4445 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4447 int mdim=(*it)->getMeshDimension();
4448 setName((*it)->getName());
4449 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4455 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4456 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4457 * The given meshes must share the same node coordinates array.
4458 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4459 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4460 * create in \a this mesh.
4461 * \throw If \a ms is empty.
4462 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4463 * to the existing meshes of other levels of \a this mesh.
4464 * \throw If the meshes in \a ms do not share the same node coordinates array.
4465 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4466 * of the given meshes.
4467 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4468 * \throw If names of some meshes in \a ms are equal.
4469 * \throw If \a ms includes a mesh with an empty name.
4471 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4474 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4475 int sz=(-meshDimRelToMax)+1;
4476 if(sz>=(int)_ms.size())
4478 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4479 DataArrayDouble *coo=checkMultiMesh(ms);
4480 if((DataArrayDouble *)_coords==0)
4486 if((DataArrayDouble *)_coords!=coo)
4487 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4488 std::vector<DataArrayInt *> corr;
4489 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4490 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4491 setMeshAtLevel(meshDimRelToMax,m,renum);
4492 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4493 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4497 * Creates groups at a given level in \a this mesh from a sequence of
4498 * meshes each representing a group.
4499 * The given meshes must share the same node coordinates array.
4500 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4501 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4502 * create in \a this mesh.
4503 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4505 * \throw If \a ms is empty.
4506 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4507 * to the existing meshes of other levels of \a this mesh.
4508 * \throw If the meshes in \a ms do not share the same node coordinates array.
4509 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4510 * of the given meshes.
4511 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4512 * \throw If names of some meshes in \a ms are equal.
4513 * \throw If \a ms includes a mesh with an empty name.
4515 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4518 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4519 int sz=(-meshDimRelToMax)+1;
4520 if(sz>=(int)_ms.size())
4522 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4523 DataArrayDouble *coo=checkMultiMesh(ms);
4524 if((DataArrayDouble *)_coords==0)
4530 if((DataArrayDouble *)_coords!=coo)
4531 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4532 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4533 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4535 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4537 DataArrayInt *arr=0;
4538 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4542 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4543 throw INTERP_KERNEL::Exception(oss.str().c_str());
4546 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4547 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4550 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4552 const DataArrayDouble *ret=ms[0]->getCoords();
4553 int mdim=ms[0]->getMeshDimension();
4554 for(unsigned int i=1;i<ms.size();i++)
4556 ms[i]->checkCoherency();
4557 if(ms[i]->getCoords()!=ret)
4558 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4559 if(ms[i]->getMeshDimension()!=mdim)
4560 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4562 return const_cast<DataArrayDouble *>(ret);
4566 * Sets the family field of a given relative dimension.
4567 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4568 * the family field is set.
4569 * \param [in] famArr - the array of the family field.
4570 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4571 * \throw If \a famArr has an invalid size.
4573 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4575 if(meshDimRelToMaxExt==1)
4582 DataArrayDouble *coo(_coords);
4584 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4585 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4590 if(meshDimRelToMaxExt>1)
4591 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4592 int traducedRk=-meshDimRelToMaxExt;
4593 if(traducedRk>=(int)_ms.size())
4594 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4595 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4596 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4597 return _ms[traducedRk]->setFamilyArr(famArr);
4601 * Sets the optional numbers of mesh entities of a given dimension.
4602 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4603 * \param [in] renumArr - the array of the numbers.
4604 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4605 * \throw If \a renumArr has an invalid size.
4607 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4609 if(meshDimRelToMaxExt==1)
4617 DataArrayDouble *coo(_coords);
4619 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4620 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4621 renumArr->incrRef();
4622 _num_coords=renumArr;
4626 if(meshDimRelToMaxExt>1)
4627 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4628 int traducedRk=-meshDimRelToMaxExt;
4629 if(traducedRk>=(int)_ms.size())
4630 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4631 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4632 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4633 return _ms[traducedRk]->setRenumArr(renumArr);
4637 * Sets the optional names of mesh entities of a given dimension.
4638 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4639 * \param [in] nameArr - the array of the names.
4640 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4641 * \throw If \a nameArr has an invalid size.
4643 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4645 if(meshDimRelToMaxExt==1)
4652 DataArrayDouble *coo(_coords);
4654 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4655 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4657 _name_coords=nameArr;
4660 if(meshDimRelToMaxExt>1)
4661 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4662 int traducedRk=-meshDimRelToMaxExt;
4663 if(traducedRk>=(int)_ms.size())
4664 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4665 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4666 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4667 return _ms[traducedRk]->setNameArr(nameArr);
4670 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4672 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4673 if((const MEDFileUMeshSplitL1 *)(*it))
4674 (*it)->synchronizeTinyInfo(*this);
4678 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4680 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4682 DataArrayInt *arr=_fam_coords;
4684 arr->changeValue(oldId,newId);
4685 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4687 MEDFileUMeshSplitL1 *sp=(*it);
4690 sp->changeFamilyIdArr(oldId,newId);
4695 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4697 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4698 const DataArrayInt *da(_fam_coords);
4700 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4701 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4703 const MEDFileUMeshSplitL1 *elt(*it);
4706 da=elt->getFamilyField();
4708 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4714 void MEDFileUMesh::computeRevNum() const
4716 if((const DataArrayInt *)_num_coords)
4719 int maxValue=_num_coords->getMaxValue(pos);
4720 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4724 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4726 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4729 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4731 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4732 ret.push_back((const DataArrayInt *)_fam_nodes);
4733 ret.push_back((const DataArrayInt *)_num_nodes);
4734 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4735 ret.push_back((const DataArrayInt *)_fam_cells);
4736 ret.push_back((const DataArrayInt *)_num_cells);
4737 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4738 ret.push_back((const DataArrayInt *)_fam_faces);
4739 ret.push_back((const DataArrayInt *)_num_faces);
4740 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4741 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4742 ret.push_back((const DataArrayInt *)_rev_num_cells);
4743 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4747 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4749 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4750 if((const DataArrayInt *)_fam_nodes)
4752 int val=_fam_nodes->getMaxValue(tmp);
4753 ret=std::max(ret,std::abs(val));
4755 if((const DataArrayInt *)_fam_cells)
4757 int val=_fam_cells->getMaxValue(tmp);
4758 ret=std::max(ret,std::abs(val));
4760 if((const DataArrayInt *)_fam_faces)
4762 int val=_fam_faces->getMaxValue(tmp);
4763 ret=std::max(ret,std::abs(val));
4768 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4770 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4771 if((const DataArrayInt *)_fam_nodes)
4773 int val=_fam_nodes->getMaxValue(tmp);
4774 ret=std::max(ret,val);
4776 if((const DataArrayInt *)_fam_cells)
4778 int val=_fam_cells->getMaxValue(tmp);
4779 ret=std::max(ret,val);
4781 if((const DataArrayInt *)_fam_faces)
4783 int val=_fam_faces->getMaxValue(tmp);
4784 ret=std::max(ret,val);
4789 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4791 int ret=std::numeric_limits<int>::max(),tmp=-1;
4792 if((const DataArrayInt *)_fam_nodes)
4794 int val=_fam_nodes->getMinValue(tmp);
4795 ret=std::min(ret,val);
4797 if((const DataArrayInt *)_fam_cells)
4799 int val=_fam_cells->getMinValue(tmp);
4800 ret=std::min(ret,val);
4802 if((const DataArrayInt *)_fam_faces)
4804 int val=_fam_faces->getMinValue(tmp);
4805 ret=std::min(ret,val);
4810 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4812 if(!MEDFileMesh::isEqual(other,eps,what))
4814 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4817 what="Mesh types differ ! This is structured and other is NOT !";
4820 const DataArrayInt *famc1=_fam_nodes;
4821 const DataArrayInt *famc2=otherC->_fam_nodes;
4822 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4824 what="Mismatch of families arr on nodes ! One is defined and not other !";
4829 bool ret=famc1->isEqual(*famc2);
4832 what="Families arr on nodes differ !";
4837 famc2=otherC->_fam_cells;
4838 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4840 what="Mismatch of families arr on cells ! One is defined and not other !";
4845 bool ret=famc1->isEqual(*famc2);
4848 what="Families arr on cells differ !";
4853 famc2=otherC->_fam_faces;
4854 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4856 what="Mismatch of families arr on faces ! One is defined and not other !";
4861 bool ret=famc1->isEqual(*famc2);
4864 what="Families arr on faces differ !";
4869 famc2=otherC->_num_nodes;
4870 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4872 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4877 bool ret=famc1->isEqual(*famc2);
4880 what="Numbering arr on nodes differ !";
4885 famc2=otherC->_num_cells;
4886 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4888 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4893 bool ret=famc1->isEqual(*famc2);
4896 what="Numbering arr on cells differ !";
4901 famc2=otherC->_num_faces;
4902 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4904 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4909 bool ret=famc1->isEqual(*famc2);
4912 what="Numbering arr on faces differ !";
4916 const DataArrayAsciiChar *d1=_names_cells;
4917 const DataArrayAsciiChar *d2=otherC->_names_cells;
4918 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4920 what="Mismatch of naming arr on cells ! One is defined and not other !";
4925 bool ret=d1->isEqual(*d2);
4928 what="Naming arr on cells differ !";
4933 d2=otherC->_names_faces;
4934 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4936 what="Mismatch of naming arr on faces ! One is defined and not other !";
4941 bool ret=d1->isEqual(*d2);
4944 what="Naming arr on faces differ !";
4949 d2=otherC->_names_nodes;
4950 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4952 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4957 bool ret=d1->isEqual(*d2);
4960 what="Naming arr on nodes differ !";
4967 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4969 MEDFileMesh::clearNonDiscrAttributes();
4970 const DataArrayInt *tmp=_fam_nodes;
4972 (const_cast<DataArrayInt *>(tmp))->setName("");
4975 (const_cast<DataArrayInt *>(tmp))->setName("");
4978 (const_cast<DataArrayInt *>(tmp))->setName("");
4981 (const_cast<DataArrayInt *>(tmp))->setName("");
4984 (const_cast<DataArrayInt *>(tmp))->setName("");
4987 (const_cast<DataArrayInt *>(tmp))->setName("");
4991 * Returns ids of mesh entities contained in given families of a given dimension.
4992 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4994 * \param [in] fams - the names of the families of interest.
4995 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4996 * returned instead of ids.
4997 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4998 * numbers, if available and required, of mesh entities of the families. The caller
4999 * is to delete this array using decrRef() as it is no more needed.
5000 * \throw If the family field is missing for \a meshDimRelToMaxExt.
5002 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
5004 std::vector<int> famIds(getFamiliesIds(fams));
5005 switch(meshDimRelToMaxExt)
5009 if((const DataArrayInt *)_fam_nodes)
5011 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5013 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5015 da=_fam_nodes->getIdsEqualList(0,0);
5017 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
5022 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
5027 if((const DataArrayInt *)_fam_cells)
5029 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5031 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5033 da=_fam_cells->getIdsEqualList(0,0);
5035 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
5040 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
5045 if((const DataArrayInt *)_fam_faces)
5047 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
5049 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
5051 da=_fam_faces->getIdsEqualList(0,0);
5053 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
5058 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
5062 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
5064 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
5068 * Sets the family field of a given relative dimension.
5069 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
5070 * the family field is set.
5071 * \param [in] famArr - the array of the family field.
5072 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5073 * \throw If \a famArr has an invalid size.
5074 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
5076 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
5078 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5080 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
5081 switch(meshDimRelToMaxExt)
5085 int nbCells=mesh->getNumberOfCells();
5086 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
5092 int nbNodes=mesh->getNumberOfNodes();
5093 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5099 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5100 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5105 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5112 * Sets the optional numbers of mesh entities of a given dimension.
5113 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5114 * \param [in] renumArr - the array of the numbers.
5115 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5116 * \throw If \a renumArr has an invalid size.
5117 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5119 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5121 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5123 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5124 switch(meshDimRelToMaxExt)
5128 int nbCells=mesh->getNumberOfCells();
5129 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5130 _num_cells=renumArr;
5135 int nbNodes=mesh->getNumberOfNodes();
5136 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5137 _num_nodes=renumArr;
5142 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5143 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5144 _num_faces=renumArr;
5148 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5151 renumArr->incrRef();
5155 * Sets the optional names of mesh entities of a given dimension.
5156 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5157 * \param [in] nameArr - the array of the names.
5158 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5159 * \throw If \a nameArr has an invalid size.
5161 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5163 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5165 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5166 switch(meshDimRelToMaxExt)
5170 int nbCells=mesh->getNumberOfCells();
5171 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5172 _names_cells=nameArr;
5177 int nbNodes=mesh->getNumberOfNodes();
5178 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5179 _names_nodes=nameArr;
5184 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5185 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5186 _names_cells=nameArr;
5189 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5196 * Adds a group of nodes to \a this mesh.
5197 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5198 * The ids should be sorted and different each other (MED file norm).
5200 * \warning this method can alter default "FAMILLE_ZERO" family.
5201 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5203 * \throw If the node coordinates array is not set.
5204 * \throw If \a ids == \c NULL.
5205 * \throw If \a ids->getName() == "".
5206 * \throw If \a ids does not respect the MED file norm.
5207 * \throw If a group with name \a ids->getName() already exists.
5209 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5215 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5217 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5218 * The ids should be sorted and different each other (MED file norm).
5220 * \warning this method can alter default "FAMILLE_ZERO" family.
5221 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5223 * \throw If the node coordinates array is not set.
5224 * \throw If \a ids == \c NULL.
5225 * \throw If \a ids->getName() == "".
5226 * \throw If \a ids does not respect the MED file norm.
5227 * \throw If a group with name \a ids->getName() already exists.
5229 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5231 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5232 addGroupUnderground(false,ids,fam);
5237 * Returns the family field for mesh entities of a given dimension.
5238 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5239 * \return const DataArrayInt * - the family field. It is an array of ids of families
5240 * each mesh entity belongs to. It can be \c NULL.
5241 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5243 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5245 switch(meshDimRelToMaxExt)
5254 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5259 * Returns the family field for mesh entities of a given dimension.
5260 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5261 * \return const DataArrayInt * - the family field. It is an array of ids of families
5262 * each mesh entity belongs to. It can be \c NULL.
5263 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5265 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5267 switch(meshDimRelToMaxExt)
5276 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5281 * Returns the optional numbers of mesh entities of a given dimension.
5282 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5283 * \return const DataArrayInt * - the array of the entity numbers.
5284 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5285 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5287 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5289 switch(meshDimRelToMaxExt)
5298 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5303 * Returns the optional numbers of mesh entities of a given dimension transformed using
5304 * DataArrayInt::invertArrayN2O2O2N().
5305 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5306 * \return const DataArrayInt * - the array of the entity numbers transformed using
5307 * DataArrayInt::invertArrayN2O2O2N().
5308 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5309 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5311 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5313 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5314 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5315 if(meshDimRelToMaxExt==0)
5317 if((const DataArrayInt *)_num_cells)
5320 int maxValue=_num_cells->getMaxValue(pos);
5321 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5322 return _rev_num_cells;
5325 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5329 if((const DataArrayInt *)_num_nodes)
5332 int maxValue=_num_nodes->getMaxValue(pos);
5333 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5334 return _rev_num_nodes;
5337 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5341 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5343 switch(meshDimRelToMaxExt)
5346 return _names_cells;
5348 return _names_nodes;
5350 return _names_faces;
5352 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5357 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5358 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5360 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5362 std::vector<int> ret(1);
5367 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5368 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5370 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5372 std::vector<int> ret(2);
5378 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5380 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5382 std::vector<int> ret;
5383 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5394 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5396 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5398 std::vector<int> ret;
5399 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5410 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5412 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5414 std::vector<int> ret;
5415 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5426 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5428 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5430 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5434 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5436 DataArrayInt *arr=_fam_nodes;
5438 arr->changeValue(oldId,newId);
5441 arr->changeValue(oldId,newId);
5444 arr->changeValue(oldId,newId);
5447 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5449 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
5450 const DataArrayInt *da(_fam_nodes);
5452 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5455 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5458 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5462 void MEDFileStructuredMesh::deepCpyAttributes()
5464 if((const DataArrayInt*)_fam_nodes)
5465 _fam_nodes=_fam_nodes->deepCpy();
5466 if((const DataArrayInt*)_num_nodes)
5467 _num_nodes=_num_nodes->deepCpy();
5468 if((const DataArrayAsciiChar*)_names_nodes)
5469 _names_nodes=_names_nodes->deepCpy();
5470 if((const DataArrayInt*)_fam_cells)
5471 _fam_cells=_fam_cells->deepCpy();
5472 if((const DataArrayInt*)_num_cells)
5473 _num_cells=_num_cells->deepCpy();
5474 if((const DataArrayAsciiChar*)_names_cells)
5475 _names_cells=_names_cells->deepCpy();
5476 if((const DataArrayInt*)_fam_faces)
5477 _fam_faces=_fam_faces->deepCpy();
5478 if((const DataArrayInt*)_num_faces)
5479 _num_faces=_num_faces->deepCpy();
5480 if((const DataArrayAsciiChar*)_names_faces)
5481 _names_faces=_names_faces->deepCpy();
5482 if((const DataArrayInt*)_rev_num_nodes)
5483 _rev_num_nodes=_rev_num_nodes->deepCpy();
5484 if((const DataArrayInt*)_rev_num_cells)
5485 _rev_num_cells=_rev_num_cells->deepCpy();
5489 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5491 * \return a pointer to cartesian mesh that need to be managed by the caller.
5492 * \warning the returned pointer has to be managed by the caller.
5496 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5497 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5498 * \param [in] renum - it must be \c false.
5499 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5500 * delete using decrRef() as it is no more needed.
5502 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
5505 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5506 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5507 switch(meshDimRelToMax)
5513 return const_cast<MEDCouplingStructuredMesh *>(m);
5518 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5519 buildMinusOneImplicitPartIfNeeded();
5520 MEDCouplingMesh *ret(_faces_if_necessary);
5526 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5531 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5532 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5533 * \return int - the number of entities.
5534 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5536 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5538 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5540 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5541 switch(meshDimRelToMaxExt)
5544 return cmesh->getNumberOfCells();
5546 return cmesh->getNumberOfNodes();
5548 return cmesh->getNumberOfCellsOfSubLevelMesh();
5550 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5554 int MEDFileStructuredMesh::getNumberOfNodes() const
5556 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5558 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5559 return cmesh->getNumberOfNodes();
5562 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
5564 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5566 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5567 switch(meshDimRelToMaxExt)
5570 return cmesh->getNumberOfCells();
5572 return cmesh->getNumberOfCellsOfSubLevelMesh();
5574 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
5578 bool MEDFileStructuredMesh::hasImplicitPart() const
5584 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5586 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5588 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5589 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5592 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5593 if(cm.getReverseExtrudedType()!=gt)
5594 throw INTERP_KERNEL::Exception(MSG);
5595 buildImplicitPart();
5596 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5600 if(gt!=zeFaceMesh->getCellModelEnum())
5601 throw INTERP_KERNEL::Exception(MSG);
5602 return zeFaceMesh->getNumberOfCells();
5606 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5608 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5610 buildImplicitPart();
5613 void MEDFileStructuredMesh::buildImplicitPart() const
5615 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5617 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5618 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5621 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5623 _faces_if_necessary=0;
5627 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5628 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5630 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5632 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5634 return _faces_if_necessary;
5637 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5639 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5641 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5642 switch(meshDimRelToMax)
5646 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5651 int mdim(cmesh->getMeshDimension());
5653 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5654 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5658 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5662 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5664 if(st.getNumberOfItems()!=1)
5665 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 !");
5666 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5667 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5668 if(getNumberOfNodes()!=(int)nodesFetched.size())
5669 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5670 if(st[0].getPflName().empty())
5672 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5675 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5676 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5677 int sz(nodesFetched.size());
5678 for(const int *work=arr->begin();work!=arr->end();work++)
5680 std::vector<int> conn;
5681 cmesh->getNodeIdsOfCell(*work,conn);
5682 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5683 if(*it>=0 && *it<sz)
5684 nodesFetched[*it]=true;
5686 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5690 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5692 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5696 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5697 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5699 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5700 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5702 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5705 if(!mrs || mrs->isCellFamilyFieldReading())
5707 famCells=DataArrayInt::New();
5708 famCells->alloc(nbOfElt,1);
5709 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
5712 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5715 if(!mrs || mrs->isCellNumFieldReading())
5717 numCells=DataArrayInt::New();
5718 numCells->alloc(nbOfElt,1);
5719 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
5722 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5725 if(!mrs || mrs->isCellNameFieldReading())
5727 namesCells=DataArrayAsciiChar::New();
5728 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5729 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer()));
5730 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5735 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5737 setName(strm->getName());
5738 setDescription(strm->getDescription());
5739 setUnivName(strm->getUnivName());
5740 setIteration(strm->getIteration());
5741 setOrder(strm->getOrder());
5742 setTimeValue(strm->getTime());
5743 setTimeUnit(strm->getTimeUnit());
5744 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5745 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5746 int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
5749 if(!mrs || mrs->isNodeFamilyFieldReading())
5751 int nbNodes(getNumberOfNodes());
5753 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5754 _fam_nodes=DataArrayInt::New();
5755 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5756 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...
5757 _fam_nodes->fillWithZero();
5758 MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
5761 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5764 if(!mrs || mrs->isNodeNumFieldReading())
5766 _num_nodes=DataArrayInt::New();
5767 _num_nodes->alloc(nbOfElt,1);
5768 MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
5771 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5774 if(!mrs || mrs->isNodeNameFieldReading())
5776 _names_nodes=DataArrayAsciiChar::New();
5777 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5778 MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer()));
5779 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5782 int meshDim(getStructuredMesh()->getMeshDimension());
5783 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5785 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5788 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5790 int meshDim(getStructuredMesh()->getMeshDimension());
5791 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5793 if((const DataArrayInt *)_fam_cells)
5794 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
5795 if((const DataArrayInt *)_fam_faces)
5796 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
5797 if((const DataArrayInt *)_fam_nodes)
5798 MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
5799 if((const DataArrayInt *)_num_cells)
5800 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
5801 if((const DataArrayInt *)_num_faces)
5802 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
5803 if((const DataArrayInt *)_num_nodes)
5804 MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
5805 if((const DataArrayAsciiChar *)_names_cells)
5807 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5809 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5810 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5811 throw INTERP_KERNEL::Exception(oss.str().c_str());
5813 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
5815 if((const DataArrayAsciiChar *)_names_faces)
5817 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5819 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5820 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5821 throw INTERP_KERNEL::Exception(oss.str().c_str());
5823 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
5825 if((const DataArrayAsciiChar *)_names_nodes)
5827 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5829 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5830 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5831 throw INTERP_KERNEL::Exception(oss.str().c_str());
5833 MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
5836 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5840 * Returns an empty instance of MEDFileCMesh.
5841 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5842 * mesh using decrRef() as it is no more needed.
5844 MEDFileCMesh *MEDFileCMesh::New()
5846 return new MEDFileCMesh;
5850 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5851 * file. The first mesh in the file is loaded.
5852 * \param [in] fileName - the name of MED file to read.
5853 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5854 * mesh using decrRef() as it is no more needed.
5855 * \throw If the file is not readable.
5856 * \throw If there is no meshes in the file.
5857 * \throw If the mesh in the file is not a Cartesian one.
5859 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5861 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5864 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5865 throw INTERP_KERNEL::Exception(oss.str().c_str());
5867 MEDFileUtilities::CheckFileForRead(fileName);
5868 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5870 ParaMEDMEM::MEDCouplingMeshType meshType;
5872 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5873 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5877 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5878 * file. The mesh to load is specified by its name and numbers of a time step and an
5880 * \param [in] fileName - the name of MED file to read.
5881 * \param [in] mName - the name of the mesh to read.
5882 * \param [in] dt - the number of a time step.
5883 * \param [in] it - the number of an iteration.
5884 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5885 * mesh using decrRef() as it is no more needed.
5886 * \throw If the file is not readable.
5887 * \throw If there is no mesh with given attributes in the file.
5888 * \throw If the mesh in the file is not a Cartesian one.
5890 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5892 MEDFileUtilities::CheckFileForRead(fileName);
5893 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5894 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5897 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5899 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5902 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5904 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5905 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5910 * Returns the dimension on cells in \a this mesh.
5911 * \return int - the mesh dimension.
5912 * \throw If there are no cells in this mesh.
5914 int MEDFileCMesh::getMeshDimension() const
5916 if(!((const MEDCouplingCMesh*)_cmesh))
5917 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5918 return _cmesh->getMeshDimension();
5922 * Returns the dimension on nodes in \a this mesh.
5923 * \return int - the space dimension.
5924 * \throw If there are no cells in this mesh.
5926 int MEDFileCMesh::getSpaceDimension() const
5928 if(!((const MEDCouplingCMesh*)_cmesh))
5929 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5930 return _cmesh->getSpaceDimension();
5934 * Returns a string describing \a this mesh.
5935 * \return std::string - the mesh information string.
5937 std::string MEDFileCMesh::simpleRepr() const
5939 return MEDFileStructuredMesh::simpleRepr();
5943 * Returns a full textual description of \a this mesh.
5944 * \return std::string - the string holding the mesh description.
5946 std::string MEDFileCMesh::advancedRepr() const
5948 return simpleRepr();
5951 MEDFileMesh *MEDFileCMesh::shallowCpy() const
5953 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5957 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
5959 return new MEDFileCMesh;
5962 MEDFileMesh *MEDFileCMesh::deepCpy() const
5964 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5965 if((const MEDCouplingCMesh*)_cmesh)
5966 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
5967 ret->deepCpyAttributes();
5972 * Checks if \a this and another mesh are equal.
5973 * \param [in] other - the mesh to compare with.
5974 * \param [in] eps - a precision used to compare real values.
5975 * \param [in,out] what - the string returning description of unequal data.
5976 * \return bool - \c true if the meshes are equal, \c false, else.
5978 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5980 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5982 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
5985 what="Mesh types differ ! This is cartesian and other is NOT !";
5988 clearNonDiscrAttributes();
5989 otherC->clearNonDiscrAttributes();
5990 const MEDCouplingCMesh *coo1=_cmesh;
5991 const MEDCouplingCMesh *coo2=otherC->_cmesh;
5992 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5994 what="Mismatch of cartesian meshes ! One is defined and not other !";
5999 bool ret=coo1->isEqual(coo2,eps);
6002 what="cartesian meshes differ !";
6010 * Clears redundant attributes of incorporated data arrays.
6012 void MEDFileCMesh::clearNonDiscrAttributes() const
6014 MEDFileStructuredMesh::clearNonDiscrAttributes();
6015 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
6018 MEDFileCMesh::MEDFileCMesh()
6022 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6025 loadCMeshFromFile(fid,mName,dt,it,mrs);
6026 loadJointsFromFile(fid);
6028 catch(INTERP_KERNEL::Exception& e)
6033 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6035 ParaMEDMEM::MEDCouplingMeshType meshType;
6038 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6039 if(meshType!=CARTESIAN)
6041 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
6042 throw INTERP_KERNEL::Exception(oss.str().c_str());
6044 MEDFileCMeshL2 loaderl2;
6045 loaderl2.loadAll(fid,mid,mName,dt,it);
6046 MEDCouplingCMesh *mesh=loaderl2.getMesh();
6049 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6053 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
6054 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
6056 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
6058 synchronizeTinyInfoOnLeaves();
6062 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
6064 synchronizeTinyInfoOnLeaves();
6069 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
6070 * \param [in] m - the new MEDCouplingCMesh to refer to.
6071 * \throw If the name or the description of \a this mesh and \a m are not empty and are
6074 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
6076 dealWithTinyInfo(m);
6082 void MEDFileCMesh::writeLL(med_idt fid) const
6084 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6085 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6086 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6087 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6088 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6089 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6090 int spaceDim(_cmesh->getSpaceDimension());
6091 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6092 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6093 for(int i=0;i<spaceDim;i++)
6095 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
6097 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6098 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
6099 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
6101 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
6103 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6104 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID));
6105 for(int i=0;i<spaceDim;i++)
6107 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6108 MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
6111 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6112 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6117 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6119 const MEDCouplingCMesh *cmesh=_cmesh;
6122 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6123 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6124 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6125 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6128 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6130 return new MEDFileCurveLinearMesh;
6133 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6135 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6138 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6139 throw INTERP_KERNEL::Exception(oss.str().c_str());
6141 MEDFileUtilities::CheckFileForRead(fileName);
6142 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6144 ParaMEDMEM::MEDCouplingMeshType meshType;
6146 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6147 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6150 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6152 MEDFileUtilities::CheckFileForRead(fileName);
6153 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6154 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6157 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6159 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6162 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6164 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6165 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6169 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
6171 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6175 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6177 return new MEDFileCurveLinearMesh;
6180 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
6182 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6183 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6184 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
6185 ret->deepCpyAttributes();
6189 int MEDFileCurveLinearMesh::getMeshDimension() const
6191 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6192 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6193 return _clmesh->getMeshDimension();
6196 std::string MEDFileCurveLinearMesh::simpleRepr() const
6198 return MEDFileStructuredMesh::simpleRepr();
6201 std::string MEDFileCurveLinearMesh::advancedRepr() const
6203 return simpleRepr();
6206 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6208 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6210 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6213 what="Mesh types differ ! This is curve linear and other is NOT !";
6216 clearNonDiscrAttributes();
6217 otherC->clearNonDiscrAttributes();
6218 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6219 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6220 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6222 what="Mismatch of curve linear meshes ! One is defined and not other !";
6227 bool ret=coo1->isEqual(coo2,eps);
6230 what="curve linear meshes differ !";
6237 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6239 MEDFileStructuredMesh::clearNonDiscrAttributes();
6240 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6243 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6245 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6248 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6249 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6250 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6251 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6254 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6256 synchronizeTinyInfoOnLeaves();
6260 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6262 dealWithTinyInfo(m);
6268 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6270 synchronizeTinyInfoOnLeaves();
6274 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6278 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6281 loadCLMeshFromFile(fid,mName,dt,it,mrs);
6282 loadJointsFromFile(fid);
6284 catch(INTERP_KERNEL::Exception& e)
6289 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6291 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6292 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6293 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6294 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6295 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6296 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6297 int spaceDim=_clmesh->getSpaceDimension();
6298 int meshDim=_clmesh->getMeshDimension();
6299 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6300 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6301 const DataArrayDouble *coords=_clmesh->getCoords();
6303 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6304 for(int i=0;i<spaceDim;i++)
6306 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6308 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6309 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
6310 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
6312 MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
6314 MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
6315 MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
6316 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6317 MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
6319 MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
6321 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6322 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6327 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6329 ParaMEDMEM::MEDCouplingMeshType meshType;
6332 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6333 if(meshType!=CURVE_LINEAR)
6335 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6336 throw INTERP_KERNEL::Exception(oss.str().c_str());
6338 MEDFileCLMeshL2 loaderl2;
6339 loaderl2.loadAll(fid,mid,mName,dt,it);
6340 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6343 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6346 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6348 return new MEDFileMeshMultiTS;
6351 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6353 return new MEDFileMeshMultiTS(fileName);
6356 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6358 return new MEDFileMeshMultiTS(fileName,mName);
6361 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
6363 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6364 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6366 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6367 if((const MEDFileMesh *)*it)
6368 meshOneTs[i]=(*it)->deepCpy();
6369 ret->_mesh_one_ts=meshOneTs;
6373 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6375 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
6378 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6380 std::vector<const BigMemoryObject *> ret;
6381 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6382 ret.push_back((const MEDFileMesh *)*it);
6386 std::string MEDFileMeshMultiTS::getName() const
6388 if(_mesh_one_ts.empty())
6389 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6390 return _mesh_one_ts[0]->getName();
6393 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6395 std::string oldName(getName());
6396 std::vector< std::pair<std::string,std::string> > v(1);
6397 v[0].first=oldName; v[0].second=newMeshName;
6401 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6404 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6406 MEDFileMesh *cur(*it);
6408 ret=cur->changeNames(modifTab) || ret;
6413 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6415 if(_mesh_one_ts.empty())
6416 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6417 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6420 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6423 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6424 _mesh_one_ts.resize(1);
6425 mesh1TimeStep->incrRef();
6426 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
6427 _mesh_one_ts[0]=mesh1TimeStep;
6430 MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
6432 if ( MEDFileMesh* m = getOneTimeStep() )
6433 return m->getJoints();
6438 * \brief Set Joints that are common to all time-stamps
6440 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
6442 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6444 (*it)->setJoints( joints );
6448 void MEDFileMeshMultiTS::write(med_idt fid) const
6450 MEDFileJoints *joints(getJoints());
6451 bool jointsWritten(false);
6453 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6455 if ( jointsWritten )
6456 const_cast<MEDFileMesh&>(**it).setJoints( 0 );
6458 jointsWritten = true;
6460 (*it)->copyOptionsFrom(*this);
6464 (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
6467 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6469 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6470 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6471 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6472 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6476 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6478 MEDFileJoints* joints = 0;
6479 if ( !_mesh_one_ts.empty() && getOneTimeStep() )
6481 // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
6482 joints = getOneTimeStep()->getJoints();
6485 _mesh_one_ts.clear(); //for the moment to be improved
6486 _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
6489 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6493 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6496 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6499 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6500 throw INTERP_KERNEL::Exception(oss.str().c_str());
6502 MEDFileUtilities::CheckFileForRead(fileName);
6503 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6505 ParaMEDMEM::MEDCouplingMeshType meshType;
6507 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6508 loadFromFile(fileName,ms.front());
6510 catch(INTERP_KERNEL::Exception& e)
6515 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6518 loadFromFile(fileName,mName);
6520 catch(INTERP_KERNEL::Exception& e)
6525 MEDFileMeshes *MEDFileMeshes::New()
6527 return new MEDFileMeshes;
6530 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6532 return new MEDFileMeshes(fileName);
6535 void MEDFileMeshes::write(med_idt fid) const
6538 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6540 (*it)->copyOptionsFrom(*this);
6545 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6547 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6548 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6549 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6550 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6555 int MEDFileMeshes::getNumberOfMeshes() const
6557 return _meshes.size();
6560 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6562 return new MEDFileMeshesIterator(this);
6565 /** Return a borrowed reference (caller is not responsible) */
6566 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6568 if(i<0 || i>=(int)_meshes.size())
6570 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6571 throw INTERP_KERNEL::Exception(oss.str().c_str());
6573 return _meshes[i]->getOneTimeStep();
6576 /** Return a borrowed reference (caller is not responsible) */
6577 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6579 std::vector<std::string> ms=getMeshesNames();
6580 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6583 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6584 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6585 throw INTERP_KERNEL::Exception(oss.str().c_str());
6587 return getMeshAtPos((int)std::distance(ms.begin(),it));
6590 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6592 std::vector<std::string> ret(_meshes.size());
6594 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6596 const MEDFileMeshMultiTS *f=(*it);
6599 ret[i]=f->getName();
6603 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6604 throw INTERP_KERNEL::Exception(oss.str().c_str());
6609 /*const MEDFileJoints* MEDFileMeshes::getJoints() const
6611 const MEDFileJoints *ret=_joints;
6614 std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !";
6615 throw INTERP_KERNEL::Exception(oss.str().c_str());
6620 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6623 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6625 MEDFileMeshMultiTS *cur(*it);
6627 ret=cur->changeNames(modifTab) || ret;
6632 void MEDFileMeshes::resize(int newSize)
6634 _meshes.resize(newSize);
6637 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6640 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6641 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6642 elt->setOneTimeStep(mesh);
6643 _meshes.push_back(elt);
6646 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6649 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6650 if(i>=(int)_meshes.size())
6651 _meshes.resize(i+1);
6652 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6653 elt->setOneTimeStep(mesh);
6657 void MEDFileMeshes::destroyMeshAtPos(int i)
6659 if(i<0 || i>=(int)_meshes.size())
6661 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6662 throw INTERP_KERNEL::Exception(oss.str().c_str());
6664 _meshes.erase(_meshes.begin()+i);
6667 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6669 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6671 _meshes.resize(ms.size());
6672 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6673 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6676 MEDFileMeshes::MEDFileMeshes()
6680 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6683 loadFromFile(fileName);
6685 catch(INTERP_KERNEL::Exception& /*e*/)
6689 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6691 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6693 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6694 if((const MEDFileMeshMultiTS *)*it)
6695 meshes[i]=(*it)->deepCpy();
6696 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6697 ret->_meshes=meshes;
6701 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6703 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6706 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6708 std::vector<const BigMemoryObject *> ret;
6709 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6710 ret.push_back((const MEDFileMeshMultiTS *)*it);
6714 std::string MEDFileMeshes::simpleRepr() const
6716 std::ostringstream oss;
6717 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6718 simpleReprWithoutHeader(oss);
6722 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6724 int nbOfMeshes=getNumberOfMeshes();
6725 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6726 std::vector<std::string> mns=getMeshesNames();
6727 for(int i=0;i<nbOfMeshes;i++)
6728 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6731 void MEDFileMeshes::checkCoherency() const
6733 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6735 std::set<std::string> s;
6736 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6738 const MEDFileMeshMultiTS *elt=(*it);
6741 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6742 throw INTERP_KERNEL::Exception(oss.str().c_str());
6744 std::size_t sz=s.size();
6745 s.insert(std::string((*it)->getName()));
6748 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6749 throw INTERP_KERNEL::Exception(oss.str().c_str());
6754 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6759 _nb_iter=ms->getNumberOfMeshes();
6763 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6767 MEDFileMesh *MEDFileMeshesIterator::nextt()
6769 if(_iter_id<_nb_iter)
6771 MEDFileMeshes *ms(_ms);
6773 return ms->getMeshAtPos(_iter_id++);