1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileUtilities.hxx"
23 #include "MEDFileFieldOverView.hxx"
24 #include "MEDFileField.hxx"
25 #include "MEDLoader.hxx"
26 #include "MEDLoaderBase.hxx"
28 #include "MEDCouplingUMesh.hxx"
30 #include "InterpKernelAutoPtr.hxx"
35 extern med_geometry_type typmai3[34];
37 using namespace ParaMEDMEM;
39 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
41 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
45 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
47 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
48 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
50 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
51 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
52 ret+=(*it2).capacity();
54 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
55 ret+=(*it).first.capacity()+sizeof(int);
59 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
61 return std::vector<const BigMemoryObject *>();
65 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
66 * file. The first mesh in the file is loaded.
67 * \param [in] fileName - the name of MED file to read.
68 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
69 * mesh using decrRef() as it is no more needed.
70 * \throw If the file is not readable.
71 * \throw If there is no meshes in the file.
72 * \throw If the mesh in the file is of a not supported type.
74 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
76 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
79 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
80 throw INTERP_KERNEL::Exception(oss.str().c_str());
82 MEDFileUtilities::CheckFileForRead(fileName);
83 ParaMEDMEM::MEDCouplingMeshType meshType;
84 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
87 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
92 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
93 ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
94 return (MEDFileUMesh *)ret.retn();
98 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
99 ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
100 return (MEDFileCMesh *)ret.retn();
104 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
105 ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
106 return (MEDFileCurveLinearMesh *)ret.retn();
110 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
111 throw INTERP_KERNEL::Exception(oss.str().c_str());
117 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
118 * file. The mesh to load is specified by its name and numbers of a time step and an
120 * \param [in] fileName - the name of MED file to read.
121 * \param [in] mName - the name of the mesh to read.
122 * \param [in] dt - the number of a time step.
123 * \param [in] it - the number of an iteration.
124 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
125 * mesh using decrRef() as it is no more needed.
126 * \throw If the file is not readable.
127 * \throw If there is no mesh with given attributes in the file.
128 * \throw If the mesh in the file is of a not supported type.
130 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
132 MEDFileUtilities::CheckFileForRead(fileName);
133 ParaMEDMEM::MEDCouplingMeshType meshType;
134 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
137 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
142 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
143 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
144 return (MEDFileUMesh *)ret.retn();
148 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
149 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
150 return (MEDFileCMesh *)ret.retn();
154 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
155 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
156 return (MEDFileCurveLinearMesh *)ret.retn();
160 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
161 throw INTERP_KERNEL::Exception(oss.str().c_str());
167 * Writes \a this mesh into an open MED file specified by its descriptor.
168 * \param [in] fid - the MED file descriptor.
169 * \throw If the mesh name is not set.
170 * \throw If the file is open for reading only.
171 * \throw If the writing mode == 1 and the same data is present in an existing file.
173 void MEDFileMesh::write(med_idt fid) const
176 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
178 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
183 * Writes \a this mesh into a MED file specified by its name.
184 * \param [in] fileName - the MED file name.
185 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
186 * - 2 - erase; an existing file is removed.
187 * - 1 - append; same data should not be present in an existing file.
188 * - 0 - overwrite; same data present in an existing file is overwritten.
189 * \throw If the mesh name is not set.
190 * \throw If \a mode == 1 and the same data is present in an existing file.
192 void MEDFileMesh::write(const std::string& fileName, int mode) const
194 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
195 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
196 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
197 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
202 * Checks if \a this and another mesh are equal.
203 * \param [in] other - the mesh to compare with.
204 * \param [in] eps - a precision used to compare real values.
205 * \param [in,out] what - the string returning description of unequal data.
206 * \return bool - \c true if the meshes are equal, \c false, else.
208 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
210 if(_order!=other->_order)
212 what="Orders differ !";
215 if(_iteration!=other->_iteration)
217 what="Iterations differ !";
220 if(fabs(_time-other->_time)>eps)
222 what="Time values differ !";
225 if(_dt_unit!=other->_dt_unit)
227 what="Time units differ !";
230 if(_name!=other->_name)
232 what="Names differ !";
235 //univ_name has been ignored -> not a bug because it is a mutable attribute
236 if(_desc_name!=other->_desc_name)
238 what="Description names differ !";
241 if(!areGrpsEqual(other,what))
243 if(!areFamsEqual(other,what))
248 void MEDFileMesh::setName(const std::string& name)
254 * Clears redundant attributes of incorporated data arrays.
256 void MEDFileMesh::clearNonDiscrAttributes() const
261 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
263 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
265 if((*it).first==_name)
275 * Copies data on groups and families from another mesh.
276 * \param [in] other - the mesh to copy the data from.
278 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
280 _groups=other._groups;
281 _families=other._families;
286 * This method clear all the groups in the map.
287 * So this method does not operate at all on arrays.
288 * So this method can lead to orphan families.
290 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
292 void MEDFileMesh::clearGrpMap()
298 * This method clear all the families in the map.
299 * So this method does not operate at all on arrays.
300 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
302 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
304 void MEDFileMesh::clearFamMap()
310 * This method clear all the families and groups in the map.
311 * So this method does not operate at all on arrays.
312 * As all groups and families entry will be removed after
313 * 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.
315 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
317 void MEDFileMesh::clearFamGrpMaps()
324 * Returns names of families constituting a group.
325 * \param [in] name - the name of the group of interest.
326 * \return std::vector<std::string> - a sequence of names of the families.
327 * \throw If the name of a nonexistent group is specified.
329 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
331 std::string oname(name);
332 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
333 if(it==_groups.end())
335 std::vector<std::string> grps=getGroupsNames();
336 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
337 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
338 throw INTERP_KERNEL::Exception(oss.str().c_str());
344 * Returns names of families constituting some groups.
345 * \param [in] grps - a sequence of names of groups of interest.
346 * \return std::vector<std::string> - a sequence of names of the families.
347 * \throw If a name of a nonexistent group is present in \a grps.
349 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
351 std::set<std::string> fams;
352 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
354 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
355 if(it2==_groups.end())
357 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
358 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
359 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
360 throw INTERP_KERNEL::Exception(oss.str().c_str());
362 fams.insert((*it2).second.begin(),(*it2).second.end());
364 std::vector<std::string> fams2(fams.begin(),fams.end());
369 * Returns ids of families constituting a group.
370 * \param [in] name - the name of the group of interest.
371 * \return std::vector<int> - sequence of ids of the families.
372 * \throw If the name of a nonexistent group is specified.
374 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
376 std::string oname(name);
377 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
378 std::vector<std::string> grps=getGroupsNames();
379 if(it==_groups.end())
381 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
382 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
383 throw INTERP_KERNEL::Exception(oss.str().c_str());
385 return getFamiliesIds((*it).second);
389 * Sets names of families constituting a group. If data on families of this group is
390 * already present, it is overwritten. Every family in \a fams is checked, and if a
391 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
392 * \param [in] name - the name of the group of interest.
393 * \param [in] fams - a sequence of names of families constituting the group.
395 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
397 std::string oname(name);
399 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
401 std::map<std::string,int>::iterator it2=_families.find(*it1);
402 if(it2==_families.end())
408 * Sets families constituting a group. The families are specified by their ids.
409 * If a family name is not found by its id, an exception is thrown.
410 * If several families have same id, the first one in lexical order is taken.
411 * \param [in] name - the name of the group of interest.
412 * \param [in] famIds - a sequence of ids of families constituting the group.
413 * \throw If a family name is not found by its id.
415 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
417 std::string oname(name);
418 std::vector<std::string> fams(famIds.size());
420 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
422 std::string name2=getFamilyNameGivenId(*it1);
429 * Returns names of groups including a given family.
430 * \param [in] name - the name of the family of interest.
431 * \return std::vector<std::string> - a sequence of names of groups including the family.
433 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
435 std::vector<std::string> ret;
436 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
438 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
441 ret.push_back((*it1).first);
449 * Adds an existing family to groups.
450 * \param [in] famName - a name of family to add to \a grps.
451 * \param [in] grps - a sequence of group names to add the family in.
452 * \throw If a family named \a famName not yet exists.
454 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
456 std::string fName(famName);
457 const std::map<std::string,int>::const_iterator it=_families.find(fName);
458 if(it==_families.end())
460 std::vector<std::string> fams=getFamiliesNames();
461 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
462 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
463 throw INTERP_KERNEL::Exception(oss.str().c_str());
465 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
467 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
468 if(it2!=_groups.end())
469 (*it2).second.push_back(fName);
472 std::vector<std::string> grps2(1,fName);
479 * Returns names of all groups of \a this mesh.
480 * \return std::vector<std::string> - a sequence of group names.
482 std::vector<std::string> MEDFileMesh::getGroupsNames() const
484 std::vector<std::string> ret(_groups.size());
486 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
492 * Returns names of all families of \a this mesh.
493 * \return std::vector<std::string> - a sequence of family names.
495 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
497 std::vector<std::string> ret(_families.size());
499 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
505 * Changes a name of every family, included in one group only, to be same as the group name.
506 * \throw If there are families with equal names in \a this mesh.
508 void MEDFileMesh::assignFamilyNameWithGroupName()
510 std::map<std::string, std::vector<std::string> > groups(_groups);
511 std::map<std::string,int> newFams;
512 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
514 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
515 if(grps.size()==1 && groups[grps[0]].size()==1)
517 if(newFams.find(grps[0])!=newFams.end())
519 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
520 throw INTERP_KERNEL::Exception(oss.str().c_str());
522 newFams[grps[0]]=(*it).second;
523 std::vector<std::string>& grps2=groups[grps[0]];
524 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
529 if(newFams.find((*it).first)!=newFams.end())
531 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
532 throw INTERP_KERNEL::Exception(oss.str().c_str());
534 newFams[(*it).first]=(*it).second;
542 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
544 * \return the removed groups.
546 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
548 std::vector<std::string> ret;
549 std::map<std::string, std::vector<std::string> > newGrps;
550 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
552 if((*it).second.empty())
553 ret.push_back((*it).first);
555 newGrps[(*it).first]=(*it).second;
563 * Removes a group from \a this mesh.
564 * \param [in] name - the name of the group to remove.
565 * \throw If no group with such a \a name exists.
567 void MEDFileMesh::removeGroup(const std::string& name)
569 std::string oname(name);
570 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
571 std::vector<std::string> grps=getGroupsNames();
572 if(it==_groups.end())
574 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
575 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
576 throw INTERP_KERNEL::Exception(oss.str().c_str());
582 * Removes a family from \a this mesh.
583 * \param [in] name - the name of the family to remove.
584 * \throw If no family with such a \a name exists.
586 void MEDFileMesh::removeFamily(const std::string& name)
588 std::string oname(name);
589 std::map<std::string, int >::iterator it=_families.find(oname);
590 std::vector<std::string> fams=getFamiliesNames();
591 if(it==_families.end())
593 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
594 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
595 throw INTERP_KERNEL::Exception(oss.str().c_str());
598 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
600 std::vector<std::string>& v=(*it3).second;
601 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
608 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
609 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
610 * family field whatever its level. This method also suppresses the orphan families.
612 * \return - The list of removed groups names.
614 * \sa MEDFileMesh::removeOrphanFamilies.
616 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
618 removeOrphanFamilies();
619 return removeEmptyGroups();
623 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
624 * 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.
626 * \return - The list of removed families names.
627 * \sa MEDFileMesh::removeOrphanGroups.
629 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
632 std::vector<std::string> ret;
633 if(!((DataArrayInt*)allFamIdsInUse))
635 ret=getFamiliesNames();
636 _families.clear(); _groups.clear();
639 std::map<std::string,int> famMap;
640 std::map<std::string, std::vector<std::string> > grps(_groups);
641 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
643 if(allFamIdsInUse->presenceOfValue((*it).second))
644 famMap[(*it).first]=(*it).second;
647 ret.push_back((*it).first);
648 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
649 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
651 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
652 std::vector<std::string>& famv=(*it3).second;
653 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
659 { _families=famMap; _groups=grps; }
664 * Renames a group in \a this mesh.
665 * \param [in] oldName - a current name of the group to rename.
666 * \param [in] newName - a new group name.
667 * \throw If no group named \a oldName exists in \a this mesh.
668 * \throw If a group named \a newName already exists.
670 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
672 std::string oname(oldName);
673 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
674 std::vector<std::string> grps=getGroupsNames();
675 if(it==_groups.end())
677 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
678 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
679 throw INTERP_KERNEL::Exception(oss.str().c_str());
681 std::string nname(newName);
682 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
683 if(it2!=_groups.end())
685 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
686 throw INTERP_KERNEL::Exception(oss.str().c_str());
688 std::vector<std::string> cpy=(*it).second;
690 _groups[newName]=cpy;
694 * Changes an id of a family in \a this mesh.
695 * This method calls changeFamilyIdArr().
696 * \param [in] oldId - a current id of the family.
697 * \param [in] newId - a new family id.
699 void MEDFileMesh::changeFamilyId(int oldId, int newId)
701 changeFamilyIdArr(oldId,newId);
702 std::map<std::string,int> fam2;
703 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
705 if((*it).second==oldId)
706 fam2[(*it).first]=newId;
708 fam2[(*it).first]=(*it).second;
714 * Renames a family in \a this mesh.
715 * \param [in] oldName - a current name of the family to rename.
716 * \param [in] newName - a new family name.
717 * \throw If no family named \a oldName exists in \a this mesh.
718 * \throw If a family named \a newName already exists.
720 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
722 std::string oname(oldName);
723 std::map<std::string, int >::iterator it=_families.find(oname);
724 std::vector<std::string> fams=getFamiliesNames();
725 if(it==_families.end())
727 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
728 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
729 throw INTERP_KERNEL::Exception(oss.str().c_str());
731 std::string nname(newName);
732 std::map<std::string, int >::iterator it2=_families.find(nname);
733 if(it2!=_families.end())
735 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
736 throw INTERP_KERNEL::Exception(oss.str().c_str());
738 int cpy=(*it).second;
740 _families[newName]=cpy;
741 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
743 std::vector<std::string>& v=(*it3).second;
744 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
751 * Checks if \a this and another mesh contains the same families.
752 * \param [in] other - the mesh to compare with \a this one.
753 * \param [in,out] what - an unused parameter.
754 * \return bool - \c true if number of families and their ids are the same in the two
755 * meshes. Families with the id == \c 0 are not considered.
757 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
759 if(_families==other->_families)
761 std::map<std::string,int> fam0;
762 std::map<std::string,int> fam1;
763 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
765 fam0[(*it).first]=(*it).second;
766 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
768 fam1[(*it).first]=(*it).second;
773 * Checks if \a this and another mesh contains the same groups.
774 * \param [in] other - the mesh to compare with \a this one.
775 * \param [in,out] what - a string describing a difference of groups of the two meshes
776 * in case if this method returns \c false.
777 * \return bool - \c true if number of groups and families constituting them are the
778 * same in the two meshes.
780 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
782 if(_groups==other->_groups)
785 std::size_t sz=_groups.size();
786 if(sz!=other->_groups.size())
788 what="Groups differ because not same number !\n";
793 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
794 for(std::size_t i=0;i<sz && ret;i++,it1++)
796 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
797 if(it2!=other->_groups.end())
799 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
800 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
806 what="A group in first mesh exists not in other !\n";
812 std::ostringstream oss; oss << "Groups description differs :\n";
813 oss << "First group description :\n";
814 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
816 oss << " Group \"" << (*it).first << "\" on following families :\n";
817 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
818 oss << " \"" << *it2 << "\n";
820 oss << "Second group description :\n";
821 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
823 oss << " Group \"" << (*it).first << "\" on following families :\n";
824 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
825 oss << " \"" << *it2 << "\n";
833 * Checks if a group with a given name exists in \a this mesh.
834 * \param [in] groupName - the group name.
835 * \return bool - \c true the group \a groupName exists in \a this mesh.
837 bool MEDFileMesh::existsGroup(const std::string& groupName) const
839 std::string grpName(groupName);
840 return _groups.find(grpName)!=_groups.end();
844 * Checks if a family with a given id exists in \a this mesh.
845 * \param [in] famId - the family id.
846 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
848 bool MEDFileMesh::existsFamily(int famId) const
850 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
851 if((*it2).second==famId)
857 * Checks if a family with a given name exists in \a this mesh.
858 * \param [in] familyName - the family name.
859 * \return bool - \c true the family \a familyName exists in \a this mesh.
861 bool MEDFileMesh::existsFamily(const std::string& familyName) const
863 std::string fname(familyName);
864 return _families.find(fname)!=_families.end();
868 * Sets an id of a family.
869 * \param [in] familyName - the family name.
870 * \param [in] id - a new id of the family.
872 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
874 std::string fname(familyName);
878 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
880 std::string fname(familyName);
881 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
884 if((*it).first!=familyName)
886 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
887 throw INTERP_KERNEL::Exception(oss.str().c_str());
894 * Adds a family to \a this mesh.
895 * \param [in] familyName - a name of the family.
896 * \param [in] famId - an id of the family.
897 * \throw If a family with the same name or id already exists in \a this mesh.
899 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
901 std::string fname(familyName);
902 std::map<std::string,int>::const_iterator it=_families.find(fname);
903 if(it==_families.end())
905 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
906 if((*it2).second==famId)
908 std::ostringstream oss;
909 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
910 throw INTERP_KERNEL::Exception(oss.str().c_str());
912 _families[fname]=famId;
916 if((*it).second!=famId)
918 std::ostringstream oss;
919 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
920 throw INTERP_KERNEL::Exception(oss.str().c_str());
926 * Creates a group including all mesh entities of given dimension.
927 * \warning This method does \b not guarantee that the created group includes mesh
928 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
929 * present in family fields of different dimensions. To assure this, call
930 * ensureDifferentFamIdsPerLevel() \b before calling this method.
931 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
933 * \param [in] groupName - a name of the new group.
934 * \throw If a group named \a groupName already exists.
935 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
936 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
938 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
940 std::string grpName(groupName);
941 std::vector<int> levs=getNonEmptyLevelsExt();
942 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
944 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
945 oss << "Available relative ext levels are : ";
946 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
947 throw INTERP_KERNEL::Exception(oss.str().c_str());
949 if(existsGroup(groupName))
951 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
952 oss << "Already existing groups are : ";
953 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
954 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
955 throw INTERP_KERNEL::Exception(oss.str().c_str());
957 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
959 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
960 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
961 std::vector<std::string> familiesOnWholeGroup;
962 for(const int *it=famIds->begin();it!=famIds->end();it++)
965 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
967 _groups[grpName]=familiesOnWholeGroup;
971 * Ensures that given family ids do not present in family fields of dimensions different
972 * than given ones. If a family id is present in the family fields of dimensions different
973 * than the given ones, a new family is created and the whole data is updated accordingly.
974 * \param [in] famIds - a sequence of family ids to check.
975 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
976 * famIds should exclusively belong.
977 * \return bool - \c true if no modification is done in \a this mesh by this method.
979 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
981 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
982 std::vector<int> levs=getNonEmptyLevelsExt();
983 std::set<int> levs2(levs.begin(),levs.end());
984 std::vector<int> levsToTest;
985 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
986 std::set<int> famIds2(famIds.begin(),famIds.end());
989 if(!_families.empty())
990 maxFamId=getMaxFamilyId()+1;
991 std::vector<std::string> allFams=getFamiliesNames();
992 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
994 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
997 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
998 std::vector<int> tmp;
999 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1000 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1003 std::string famName=getFamilyNameGivenId(*it2);
1004 std::ostringstream oss; oss << "Family_" << maxFamId;
1005 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1006 addFamilyOnAllGroupsHaving(famName,zeName);
1007 _families[zeName]=maxFamId;
1008 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1017 * Adds a family to a given group in \a this mesh. If the group with a given name does
1018 * not exist, it is created.
1019 * \param [in] grpName - the name of the group to add the family in.
1020 * \param [in] famName - the name of the family to add to the group named \a grpName.
1021 * \throw If \a grpName or \a famName is an empty string.
1022 * \throw If no family named \a famName is present in \a this mesh.
1024 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1026 std::string grpn(grpName);
1027 std::string famn(famName);
1028 if(grpn.empty() || famn.empty())
1029 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1030 std::vector<std::string> fams=getFamiliesNames();
1031 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1033 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1034 oss << "Create this family or choose an existing one ! Existing fams are : ";
1035 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1036 throw INTERP_KERNEL::Exception(oss.str().c_str());
1038 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1039 if(it==_groups.end())
1041 _groups[grpn].push_back(famn);
1045 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1046 if(it2==(*it).second.end())
1047 (*it).second.push_back(famn);
1052 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1053 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1054 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1056 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1058 std::string famNameCpp(famName);
1059 std::string otherCpp(otherFamName);
1060 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1062 std::vector<std::string>& v=(*it).second;
1063 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1065 v.push_back(otherCpp);
1070 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1072 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1075 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1077 std::string fam(familyNameToChange);
1078 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1080 std::vector<std::string>& fams((*it).second);
1081 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1085 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1091 * Returns a name of the family having a given id or, if no such a family exists, creates
1092 * a new uniquely named family and returns its name.
1093 * \param [in] id - the id of the family whose name is required.
1094 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1095 * \return std::string - the name of the existing or the created family.
1096 * \throw If it is not possible to create a unique family name.
1098 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1100 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1104 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1105 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1106 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1107 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1109 * This method will throws an exception if it is not possible to create a unique family name.
1111 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1113 std::vector<std::string> famAlreadyExisting(families.size());
1115 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1117 if((*it).second!=id)
1119 famAlreadyExisting[ii]=(*it).first;
1128 std::ostringstream oss; oss << "Family_" << id;
1129 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1135 * Sets names and ids of all families in \a this mesh.
1136 * \param [in] info - a map of a family name to a family id.
1138 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1144 * Sets names of all groups and families constituting them in \a this mesh.
1145 * \param [in] info - a map of a group name to a vector of names of families
1146 * constituting the group.
1148 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1154 * Returns an id of the family having a given name.
1155 * \param [in] name - the name of the family of interest.
1156 * \return int - the id of the family of interest.
1157 * \throw If no family with such a \a name exists.
1159 int MEDFileMesh::getFamilyId(const std::string& name) const
1161 std::string oname(name);
1162 std::map<std::string, int>::const_iterator it=_families.find(oname);
1163 std::vector<std::string> fams=getFamiliesNames();
1164 if(it==_families.end())
1166 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1167 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1168 throw INTERP_KERNEL::Exception(oss.str().c_str());
1170 return (*it).second;
1174 * Returns ids of the families having given names.
1175 * \param [in] fams - a sequence of the names of families of interest.
1176 * \return std::vector<int> - a sequence of the ids of families of interest.
1177 * \throw If \a fams contains a name of an inexistent family.
1179 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1181 std::vector<int> ret(fams.size());
1183 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1185 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1186 if(it2==_families.end())
1188 std::vector<std::string> fams2=getFamiliesNames();
1189 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1190 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1191 throw INTERP_KERNEL::Exception(oss.str().c_str());
1193 ret[i]=(*it2).second;
1199 * Returns a maximal abs(id) of families in \a this mesh.
1200 * \return int - the maximal norm of family id.
1201 * \throw If there are no families in \a this mesh.
1203 int MEDFileMesh::getMaxAbsFamilyId() const
1205 if(_families.empty())
1206 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1207 int ret=-std::numeric_limits<int>::max();
1208 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1210 ret=std::max(std::abs((*it).second),ret);
1216 * Returns a maximal id of families in \a this mesh.
1217 * \return int - the maximal family id.
1218 * \throw If there are no families in \a this mesh.
1220 int MEDFileMesh::getMaxFamilyId() const
1222 if(_families.empty())
1223 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1224 int ret=-std::numeric_limits<int>::max();
1225 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1227 ret=std::max((*it).second,ret);
1233 * Returns a minimal id of families in \a this mesh.
1234 * \return int - the minimal family id.
1235 * \throw If there are no families in \a this mesh.
1237 int MEDFileMesh::getMinFamilyId() const
1239 if(_families.empty())
1240 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1241 int ret=std::numeric_limits<int>::max();
1242 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1244 ret=std::min((*it).second,ret);
1250 * Returns a maximal id of families in \a this mesh. Not only named families are
1251 * considered but all family fields as well.
1252 * \return int - the maximal family id.
1254 int MEDFileMesh::getTheMaxAbsFamilyId() const
1256 int m1=-std::numeric_limits<int>::max();
1257 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1258 m1=std::max(std::abs((*it).second),m1);
1259 int m2=getMaxAbsFamilyIdInArrays();
1260 return std::max(m1,m2);
1264 * Returns a maximal id of families in \a this mesh. Not only named families are
1265 * considered but all family fields as well.
1266 * \return int - the maximal family id.
1268 int MEDFileMesh::getTheMaxFamilyId() const
1270 int m1=-std::numeric_limits<int>::max();
1271 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1272 m1=std::max((*it).second,m1);
1273 int m2=getMaxFamilyIdInArrays();
1274 return std::max(m1,m2);
1278 * Returns a minimal id of families in \a this mesh. Not only named families are
1279 * considered but all family fields as well.
1280 * \return int - the minimal family id.
1282 int MEDFileMesh::getTheMinFamilyId() const
1284 int m1=std::numeric_limits<int>::max();
1285 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1286 m1=std::min((*it).second,m1);
1287 int m2=getMinFamilyIdInArrays();
1288 return std::min(m1,m2);
1292 * This method only considers the maps. The contain of family array is ignored here.
1294 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1296 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1298 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1300 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1301 v.insert((*it).second);
1302 ret->alloc((int)v.size(),1);
1303 std::copy(v.begin(),v.end(),ret->getPointer());
1308 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1310 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1312 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1314 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1315 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1316 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1318 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1319 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1320 if((DataArrayInt *) ret)
1321 ret=dv->buildUnion(ret);
1329 * true is returned if no modification has been needed. false if family
1330 * renumbering has been needed.
1332 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1334 std::vector<int> levs=getNonEmptyLevelsExt();
1335 std::set<int> allFamIds;
1336 int maxId=getMaxFamilyId()+1;
1337 std::map<int,std::vector<int> > famIdsToRenum;
1338 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1340 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1343 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1345 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1347 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1349 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1352 if(famIdsToRenum.empty())
1354 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1355 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1357 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1358 int *famIdsToChange=fam->getPointer();
1359 std::map<int,int> ren;
1360 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1362 if(allIds->presenceOfValue(*it3))
1364 std::string famName=getFamilyNameGivenId(*it3);
1365 std::vector<std::string> grps=getGroupsOnFamily(famName);
1368 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1369 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1370 addFamilyOnGrp((*it4),newFam);
1373 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1374 for(const int *id=ids->begin();id!=ids->end();id++)
1375 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1381 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1382 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1383 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1384 * This method will throw an exception if a same family id is detected in different level.
1385 * \warning This policy is the opposite of those in MED file documentation ...
1387 void MEDFileMesh::normalizeFamIdsTrio()
1389 ensureDifferentFamIdsPerLevel();
1390 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1391 std::vector<int> levs=getNonEmptyLevelsExt();
1392 std::set<int> levsS(levs.begin(),levs.end());
1393 std::set<std::string> famsFetched;
1394 std::map<std::string,int> families;
1395 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1398 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1402 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1403 std::map<int,int> ren;
1404 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1406 int nbOfTuples=fam->getNumberOfTuples();
1407 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1408 for(int *w=start;w!=start+nbOfTuples;w++)
1410 for(const int *it=tmp->begin();it!=tmp->end();it++)
1412 if(allIds->presenceOfValue(*it))
1414 std::string famName=getFamilyNameGivenId(*it);
1415 families[famName]=ren[*it];
1416 famsFetched.insert(famName);
1421 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1424 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1428 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1429 std::map<int,int> ren;
1430 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1432 int nbOfTuples=fam->getNumberOfTuples();
1433 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1434 for(int *w=start;w!=start+nbOfTuples;w++)
1436 for(const int *it=tmp->begin();it!=tmp->end();it++)
1438 if(allIds->presenceOfValue(*it))
1440 std::string famName=getFamilyNameGivenId(*it);
1441 families[famName]=ren[*it];
1442 famsFetched.insert(famName);
1447 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1449 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1452 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1453 fam->fillWithZero();
1454 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1455 if(allIds->presenceOfValue(*it3))
1457 std::string famName=getFamilyNameGivenId(*it3);
1458 families[famName]=0;
1459 famsFetched.insert(famName);
1464 std::vector<std::string> allFams=getFamiliesNames();
1465 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1466 std::set<std::string> unFetchedIds;
1467 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1468 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1469 families[*it4]=_families[*it4];
1474 * This method normalizes fam id with the following policy.
1475 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1476 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1477 * This method will throw an exception if a same family id is detected in different level.
1479 void MEDFileMesh::normalizeFamIdsMEDFile()
1481 ensureDifferentFamIdsPerLevel();
1482 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1483 std::vector<int> levs=getNonEmptyLevelsExt();
1484 std::set<int> levsS(levs.begin(),levs.end());
1485 std::set<std::string> famsFetched;
1486 std::map<std::string,int> families;
1488 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1491 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1494 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1495 std::map<int,int> ren;
1496 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1498 int nbOfTuples=fam->getNumberOfTuples();
1499 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1500 for(int *w=start;w!=start+nbOfTuples;w++)
1502 for(const int *it=tmp->begin();it!=tmp->end();it++)
1504 if(allIds->presenceOfValue(*it))
1506 std::string famName=getFamilyNameGivenId(*it);
1507 families[famName]=ren[*it];
1508 famsFetched.insert(famName);
1514 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1516 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1519 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1520 std::map<int,int> ren;
1521 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1523 int nbOfTuples=fam->getNumberOfTuples();
1524 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1525 for(int *w=start;w!=start+nbOfTuples;w++)
1527 for(const int *it=tmp->begin();it!=tmp->end();it++)
1529 if(allIds->presenceOfValue(*it))
1531 std::string famName=getFamilyNameGivenId(*it);
1532 families[famName]=ren[*it];
1533 famsFetched.insert(famName);
1539 std::vector<std::string> allFams=getFamiliesNames();
1540 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1541 std::set<std::string> unFetchedIds;
1542 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1543 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1544 families[*it4]=_families[*it4];
1549 * Returns a name of the family by its id. If there are several families having the given
1550 * id, the name first in lexical order is returned.
1551 * \param [in] id - the id of the family whose name is required.
1552 * \return std::string - the name of the found family.
1553 * \throw If no family with the given \a id exists.
1555 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1557 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1558 if((*it).second==id)
1560 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1561 throw INTERP_KERNEL::Exception(oss.str().c_str());
1565 * Returns a string describing \a this mesh. This description includes the mesh name and
1566 * the mesh description string.
1567 * \return std::string - the mesh information string.
1569 std::string MEDFileMesh::simpleRepr() const
1571 std::ostringstream oss;
1572 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1573 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1574 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1579 * Returns ids of mesh entities contained in a given group of a given dimension.
1580 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1582 * \param [in] grp - the name of the group of interest.
1583 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1584 * returned instead of ids.
1585 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1586 * numbers, if available and required, of mesh entities of the group. The caller
1587 * is to delete this array using decrRef() as it is no more needed.
1588 * \throw If the name of a nonexistent group is specified.
1589 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1591 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1593 std::vector<std::string> tmp(1);
1595 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1601 * Returns ids of mesh entities contained in given groups of a given dimension.
1602 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1604 * \param [in] grps - the names of the groups of interest.
1605 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1606 * returned instead of ids.
1607 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1608 * numbers, if available and required, of mesh entities of the groups. The caller
1609 * is to delete this array using decrRef() as it is no more needed.
1610 * \throw If the name of a nonexistent group is present in \a grps.
1611 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1613 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1615 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1616 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1620 * Returns ids of mesh entities contained in a given family of a given dimension.
1621 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1623 * \param [in] fam - the name of the family of interest.
1624 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1625 * returned instead of ids.
1626 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1627 * numbers, if available and required, of mesh entities of the family. The caller
1628 * is to delete this array using decrRef() as it is no more needed.
1629 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1631 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1633 std::vector<std::string> tmp(1);
1635 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1641 * Returns ids of nodes contained in a given group.
1642 * \param [in] grp - the name of the group of interest.
1643 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1644 * returned instead of ids.
1645 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1646 * numbers, if available and required, of nodes of the group. The caller
1647 * is to delete this array using decrRef() as it is no more needed.
1648 * \throw If the name of a nonexistent group is specified.
1649 * \throw If the family field is missing for nodes.
1651 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1653 std::vector<std::string> tmp(1);
1655 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1661 * Returns ids of nodes contained in given groups.
1662 * \param [in] grps - the names of the groups of interest.
1663 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1664 * returned instead of ids.
1665 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1666 * numbers, if available and required, of nodes of the groups. The caller
1667 * is to delete this array using decrRef() as it is no more needed.
1668 * \throw If the name of a nonexistent group is present in \a grps.
1669 * \throw If the family field is missing for nodes.
1671 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1673 return getGroupsArr(1,grps,renum);
1677 * Returns ids of nodes contained in a given group.
1678 * \param [in] grp - the name of the group of interest.
1679 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1680 * returned instead of ids.
1681 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1682 * numbers, if available and required, of nodes of the group. The caller
1683 * is to delete this array using decrRef() as it is no more needed.
1684 * \throw If the name of a nonexistent group is specified.
1685 * \throw If the family field is missing for nodes.
1687 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1689 std::vector<std::string> tmp(1);
1691 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1697 * Returns ids of nodes contained in given families.
1698 * \param [in] fams - the names of the families of interest.
1699 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1700 * returned instead of ids.
1701 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1702 * numbers, if available and required, of nodes of the families. The caller
1703 * is to delete this array using decrRef() as it is no more needed.
1704 * \throw If the family field is missing for nodes.
1706 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1708 return getFamiliesArr(1,fams,renum);
1712 * Adds groups of given dimension and creates corresponding families and family fields
1713 * given ids of mesh entities of each group.
1714 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1715 * \param [in] grps - a sequence of arrays of ids each describing a group.
1716 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1718 * \throw If names of some groups in \a grps are equal.
1719 * \throw If \a grps includes a group with an empty name.
1720 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1721 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1723 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1727 std::set<std::string> grpsName;
1728 std::vector<std::string> grpsName2(grps.size());
1731 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1733 grpsName.insert((*it)->getName());
1734 grpsName2[i]=(*it)->getName();
1736 if(grpsName.size()!=grps.size())
1737 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1738 if(grpsName.find(std::string(""))!=grpsName.end())
1739 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1740 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1741 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1742 std::vector< std::vector<int> > fidsOfGroups;
1745 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1749 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1750 for(unsigned int ii=0;ii<grps.size();ii++)
1752 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1753 grps2[ii]->setName(grps[ii]->getName());
1755 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1756 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1759 if(!_families.empty())
1760 offset=getMaxAbsFamilyId()+1;
1761 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1762 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1763 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1764 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1768 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1769 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1770 * For the moment, the two last input parameters are not taken into account.
1772 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1774 std::map<int,std::string> famInv;
1775 for(const int *it=famIds->begin();it!=famIds->end();it++)
1777 std::ostringstream oss;
1778 oss << "Family_" << (*it);
1779 _families[oss.str()]=(*it);
1780 famInv[*it]=oss.str();
1783 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1785 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1787 _groups[grpNames[i]].push_back(famInv[*it2]);
1792 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1794 std::vector<int> levs(getNonEmptyLevels());
1795 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1796 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1798 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1799 ret.insert(ret.end(),elts.begin(),elts.end());
1804 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1806 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1807 return mLev->getDistributionOfTypes();
1810 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1812 famArr->applyLin(offset>0?1:-1,offset,0);
1813 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1816 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1817 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1822 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1823 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1824 * If this method fails to find such a name it will throw an exception.
1826 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
1829 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1832 std::size_t len=nameTry.length();
1833 for(std::size_t ii=1;ii<len;ii++)
1835 std::string tmp=nameTry.substr(ii,len-ii);
1836 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1842 for(std::size_t i=1;i<30;i++)
1844 std::string tmp1(nameTry.at(0),i);
1846 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1852 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1854 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1856 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1859 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
1861 std::size_t nbOfChunks=code.size()/3;
1862 if(code.size()%3!=0)
1863 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1865 for(std::size_t i=0;i<nbOfChunks;i++)
1874 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1875 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1876 * If _name is not empty and that 'm' has the same name nothing is done.
1877 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1879 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
1882 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1887 std::string name(m->getName());
1892 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1893 oss << name << "' ! Names must match !";
1894 throw INTERP_KERNEL::Exception(oss.str().c_str());
1898 if(_desc_name.empty())
1899 _desc_name=m->getDescription();
1902 std::string name(m->getDescription());
1905 if(_desc_name!=name)
1907 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1908 oss << name << "' ! Names must match !";
1909 throw INTERP_KERNEL::Exception(oss.str().c_str());
1915 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1917 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1918 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1920 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1921 oss << " - Groups lying on this family : ";
1922 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
1923 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1924 oss << std::endl << std::endl;
1929 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1930 * file. The mesh to load is specified by its name and numbers of a time step and an
1932 * \param [in] fileName - the name of MED file to read.
1933 * \param [in] mName - the name of the mesh to read.
1934 * \param [in] dt - the number of a time step.
1935 * \param [in] it - the number of an iteration.
1936 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1937 * mesh using decrRef() as it is no more needed.
1938 * \throw If the file is not readable.
1939 * \throw If there is no mesh with given attributes in the file.
1940 * \throw If the mesh in the file is not an unstructured one.
1942 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
1944 MEDFileUtilities::CheckFileForRead(fileName);
1945 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1946 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1950 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1951 * file. The first mesh in the file is loaded.
1952 * \param [in] fileName - the name of MED file to read.
1953 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1954 * mesh using decrRef() as it is no more needed.
1955 * \throw If the file is not readable.
1956 * \throw If there is no meshes in the file.
1957 * \throw If the mesh in the file is not an unstructured one.
1959 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
1961 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1964 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1965 throw INTERP_KERNEL::Exception(oss.str().c_str());
1967 MEDFileUtilities::CheckFileForRead(fileName);
1968 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1970 ParaMEDMEM::MEDCouplingMeshType meshType;
1972 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
1973 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
1977 * Returns an empty instance of MEDFileUMesh.
1978 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1979 * mesh using decrRef() as it is no more needed.
1981 MEDFileUMesh *MEDFileUMesh::New()
1983 return new MEDFileUMesh;
1987 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
1988 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
1989 * \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.
1990 * 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
1991 * at most the memory consumtion.
1993 * \param [in] fileName - the name of the file.
1994 * \param [in] mName - the name of the mesh to be read.
1995 * \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.
1996 * \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.
1997 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
1998 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
1999 * \param [in] mrs - the request for what to be loaded.
2000 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2002 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)
2004 MEDFileUtilities::CheckFileForRead(fileName);
2005 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2006 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2010 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2011 * This method is \b NOT wrapped into python.
2013 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)
2015 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2016 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2020 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2022 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2023 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2027 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2029 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2030 ret.push_back((const DataArrayDouble*)_coords);
2031 ret.push_back((const DataArrayInt *)_fam_coords);
2032 ret.push_back((const DataArrayInt *)_num_coords);
2033 ret.push_back((const DataArrayInt *)_rev_num_coords);
2034 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2035 ret.push_back((const PartDefinition *)_part_coords);
2036 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2037 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2041 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2043 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2047 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2049 return new MEDFileUMesh;
2052 MEDFileMesh *MEDFileUMesh::deepCpy() const
2054 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2055 if((const DataArrayDouble*)_coords)
2056 ret->_coords=_coords->deepCpy();
2057 if((const DataArrayInt*)_fam_coords)
2058 ret->_fam_coords=_fam_coords->deepCpy();
2059 if((const DataArrayInt*)_num_coords)
2060 ret->_num_coords=_num_coords->deepCpy();
2061 if((const DataArrayInt*)_rev_num_coords)
2062 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2063 if((const DataArrayAsciiChar*)_name_coords)
2064 ret->_name_coords=_name_coords->deepCpy();
2066 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2068 if((const MEDFileUMeshSplitL1 *)(*it))
2069 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2075 * Checks if \a this and another mesh are equal.
2076 * \param [in] other - the mesh to compare with.
2077 * \param [in] eps - a precision used to compare real values.
2078 * \param [in,out] what - the string returning description of unequal data.
2079 * \return bool - \c true if the meshes are equal, \c false, else.
2081 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2083 if(!MEDFileMesh::isEqual(other,eps,what))
2085 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2088 what="Mesh types differ ! This is unstructured and other is NOT !";
2091 clearNonDiscrAttributes();
2092 otherC->clearNonDiscrAttributes();
2093 const DataArrayDouble *coo1=_coords;
2094 const DataArrayDouble *coo2=otherC->_coords;
2095 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2097 what="Mismatch of coordinates ! One is defined and not other !";
2102 bool ret=coo1->isEqual(*coo2,eps);
2105 what="Coords differ !";
2109 const DataArrayInt *famc1=_fam_coords;
2110 const DataArrayInt *famc2=otherC->_fam_coords;
2111 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2113 what="Mismatch of families arr on nodes ! One is defined and not other !";
2118 bool ret=famc1->isEqual(*famc2);
2121 what="Families arr on node differ !";
2125 const DataArrayInt *numc1=_num_coords;
2126 const DataArrayInt *numc2=otherC->_num_coords;
2127 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2129 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2134 bool ret=numc1->isEqual(*numc2);
2137 what="Numbering arr on node differ !";
2141 const DataArrayAsciiChar *namec1=_name_coords;
2142 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2143 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2145 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2150 bool ret=namec1->isEqual(*namec2);
2153 what="Names arr on node differ !";
2157 if(_ms.size()!=otherC->_ms.size())
2159 what="Number of levels differs !";
2162 std::size_t sz=_ms.size();
2163 for(std::size_t i=0;i<sz;i++)
2165 const MEDFileUMeshSplitL1 *s1=_ms[i];
2166 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2167 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2169 what="Mismatch of presence of sub levels !";
2174 bool ret=s1->isEqual(s2,eps,what);
2183 * Clears redundant attributes of incorporated data arrays.
2185 void MEDFileUMesh::clearNonDiscrAttributes() const
2187 MEDFileMesh::clearNonDiscrAttributes();
2188 const DataArrayDouble *coo1=_coords;
2190 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2191 const DataArrayInt *famc1=_fam_coords;
2193 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2194 const DataArrayInt *numc1=_num_coords;
2196 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2197 const DataArrayAsciiChar *namc1=_name_coords;
2199 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2200 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2202 const MEDFileUMeshSplitL1 *tmp=(*it);
2204 tmp->clearNonDiscrAttributes();
2208 void MEDFileUMesh::setName(const std::string& name)
2210 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2211 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2212 (*it)->setName(name);
2213 MEDFileMesh::setName(name);
2216 MEDFileUMesh::MEDFileUMesh()
2220 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2223 loadUMeshFromFile(fid,mName,dt,it,mrs);
2225 catch(INTERP_KERNEL::Exception& e)
2231 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2232 * See MEDFileUMesh::LoadPartOf for detailed description.
2234 * \sa loadUMeshFromFile
2236 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)
2238 MEDFileUMeshL2 loaderl2;
2239 ParaMEDMEM::MEDCouplingMeshType meshType;
2242 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2243 if(meshType!=UNSTRUCTURED)
2245 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2246 throw INTERP_KERNEL::Exception(oss.str().c_str());
2248 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2249 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2253 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2255 * \sa loadPartUMeshFromFile
2257 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2259 MEDFileUMeshL2 loaderl2;
2260 ParaMEDMEM::MEDCouplingMeshType meshType;
2263 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2264 if(meshType!=UNSTRUCTURED)
2266 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2267 throw INTERP_KERNEL::Exception(oss.str().c_str());
2269 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2270 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2274 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2276 int lev=loaderl2.getNumberOfLevels();
2278 for(int i=0;i<lev;i++)
2280 if(!loaderl2.emptyLev(i))
2281 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2285 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2287 setName(loaderl2.getName());
2288 setDescription(loaderl2.getDescription());
2289 setUnivName(loaderl2.getUnivName());
2290 setIteration(loaderl2.getIteration());
2291 setOrder(loaderl2.getOrder());
2292 setTimeValue(loaderl2.getTime());
2293 setTimeUnit(loaderl2.getTimeUnit());
2294 _coords=loaderl2.getCoords();
2295 if(!mrs || mrs->isNodeFamilyFieldReading())
2296 _fam_coords=loaderl2.getCoordsFamily();
2297 if(!mrs || mrs->isNodeNumFieldReading())
2298 _num_coords=loaderl2.getCoordsNum();
2299 if(!mrs || mrs->isNodeNameFieldReading())
2300 _name_coords=loaderl2.getCoordsName();
2301 _part_coords=loaderl2.getPartDefOfCoo();
2305 MEDFileUMesh::~MEDFileUMesh()
2309 void MEDFileUMesh::writeLL(med_idt fid) const
2311 const DataArrayDouble *coo=_coords;
2312 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2313 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2314 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2315 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2316 int spaceDim=coo?coo->getNumberOfComponents():0;
2319 mdim=getMeshDimension();
2320 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2321 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2322 for(int i=0;i<spaceDim;i++)
2324 std::string info=coo->getInfoOnComponent(i);
2326 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2327 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
2328 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
2330 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2331 MEDmeshUniversalNameWr(fid,maa);
2332 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2333 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2334 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2335 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2336 (*it)->write(fid,meshName,mdim);
2337 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2341 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2342 * \return std::vector<int> - a sequence of the relative dimensions.
2344 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2346 std::vector<int> ret;
2348 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2349 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2356 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2357 * \return std::vector<int> - a sequence of the relative dimensions.
2359 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2361 std::vector<int> ret0=getNonEmptyLevels();
2362 if((const DataArrayDouble *) _coords)
2364 std::vector<int> ret(ret0.size()+1);
2366 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2372 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2374 std::vector<int> ret;
2375 const DataArrayInt *famCoo(_fam_coords);
2379 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2381 const MEDFileUMeshSplitL1 *cur(*it);
2383 if(cur->getFamilyField())
2389 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2391 std::vector<int> ret;
2392 const DataArrayInt *numCoo(_num_coords);
2396 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2398 const MEDFileUMeshSplitL1 *cur(*it);
2400 if(cur->getNumberField())
2406 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2408 std::vector<int> ret;
2409 const DataArrayAsciiChar *nameCoo(_name_coords);
2413 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2415 const MEDFileUMeshSplitL1 *cur(*it);
2417 if(cur->getNameField())
2424 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2425 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2426 * \param [in] grp - the name of the group of interest.
2427 * \return std::vector<int> - a sequence of the relative dimensions.
2429 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2431 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2432 return getFamsNonEmptyLevels(fams);
2436 * Returns all relative mesh levels (including nodes) where a given group is defined.
2437 * \param [in] grp - the name of the group of interest.
2438 * \return std::vector<int> - a sequence of the relative dimensions.
2440 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2442 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2443 return getFamsNonEmptyLevelsExt(fams);
2447 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2448 * To include nodes, call getFamNonEmptyLevelsExt() method.
2449 * \param [in] fam - the name of the family of interest.
2450 * \return std::vector<int> - a sequence of the relative dimensions.
2452 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2454 std::vector<std::string> fams(1,std::string(fam));
2455 return getFamsNonEmptyLevels(fams);
2459 * Returns all relative mesh levels (including nodes) where a given family is defined.
2460 * \param [in] fam - the name of the family of interest.
2461 * \return std::vector<int> - a sequence of the relative dimensions.
2463 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2465 std::vector<std::string> fams(1,std::string(fam));
2466 return getFamsNonEmptyLevelsExt(fams);
2470 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2471 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2472 * \param [in] grps - a sequence of names of the groups of interest.
2473 * \return std::vector<int> - a sequence of the relative dimensions.
2475 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2477 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2478 return getFamsNonEmptyLevels(fams);
2482 * Returns all relative mesh levels (including nodes) where given groups are defined.
2483 * \param [in] grps - a sequence of names of the groups of interest.
2484 * \return std::vector<int> - a sequence of the relative dimensions.
2486 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2488 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2489 return getFamsNonEmptyLevelsExt(fams);
2493 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2494 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2495 * \param [in] fams - the name of the family of interest.
2496 * \return std::vector<int> - a sequence of the relative dimensions.
2498 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2500 std::vector<int> ret;
2501 std::vector<int> levs=getNonEmptyLevels();
2502 std::vector<int> famIds=getFamiliesIds(fams);
2503 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2504 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2510 * Returns all relative mesh levels (including nodes) where given families are defined.
2511 * \param [in] fams - the names of the families of interest.
2512 * \return std::vector<int> - a sequence of the relative dimensions.
2514 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2516 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2517 const DataArrayInt *famCoords=_fam_coords;
2520 std::vector<int> famIds=getFamiliesIds(fams);
2521 if(famCoords->presenceOfValue(famIds))
2523 std::vector<int> ret(ret0.size()+1);
2525 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2533 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2534 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2535 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2538 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2540 std::vector<std::string> ret;
2541 std::vector<std::string> allGrps=getGroupsNames();
2542 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2544 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2545 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2551 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2553 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2554 if((const DataArrayInt *)_fam_coords)
2556 int val=_fam_coords->getMaxValue(tmp);
2557 ret=std::max(ret,std::abs(val));
2559 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2561 if((const MEDFileUMeshSplitL1 *)(*it))
2563 const DataArrayInt *da=(*it)->getFamilyField();
2566 int val=da->getMaxValue(tmp);
2567 ret=std::max(ret,std::abs(val));
2574 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2576 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2577 if((const DataArrayInt *)_fam_coords)
2579 int val=_fam_coords->getMaxValue(tmp);
2580 ret=std::max(ret,val);
2582 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2584 if((const MEDFileUMeshSplitL1 *)(*it))
2586 const DataArrayInt *da=(*it)->getFamilyField();
2589 int val=da->getMaxValue(tmp);
2590 ret=std::max(ret,val);
2597 int MEDFileUMesh::getMinFamilyIdInArrays() const
2599 int ret=std::numeric_limits<int>::max(),tmp=-1;
2600 if((const DataArrayInt *)_fam_coords)
2602 int val=_fam_coords->getMinValue(tmp);
2603 ret=std::min(ret,val);
2605 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2607 if((const MEDFileUMeshSplitL1 *)(*it))
2609 const DataArrayInt *da=(*it)->getFamilyField();
2612 int val=da->getMinValue(tmp);
2613 ret=std::min(ret,val);
2621 * Returns the dimension on cells in \a this mesh.
2622 * \return int - the mesh dimension.
2623 * \throw If there are no cells in this mesh.
2625 int MEDFileUMesh::getMeshDimension() const
2628 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2629 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2630 return (*it)->getMeshDimension()+lev;
2631 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2635 * Returns the space dimension of \a this mesh that is equal to number of components in
2636 * the node coordinates array.
2637 * \return int - the space dimension of \a this mesh.
2638 * \throw If the node coordinates array is not available.
2640 int MEDFileUMesh::getSpaceDimension() const
2642 const DataArrayDouble *coo=_coords;
2644 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2645 return coo->getNumberOfComponents();
2649 * Returns a string describing \a this mesh.
2650 * \return std::string - the mesh information string.
2652 std::string MEDFileUMesh::simpleRepr() const
2654 std::ostringstream oss;
2655 oss << MEDFileMesh::simpleRepr();
2656 const DataArrayDouble *coo=_coords;
2657 oss << "- The dimension of the space is ";
2658 static const char MSG1[]= "*** NO COORDS SET ***";
2659 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2661 oss << _coords->getNumberOfComponents() << std::endl;
2663 oss << MSG1 << std::endl;
2664 oss << "- Type of the mesh : UNSTRUCTURED\n";
2665 oss << "- Number of nodes : ";
2667 oss << _coords->getNumberOfTuples() << std::endl;
2669 oss << MSG1 << std::endl;
2670 std::size_t nbOfLev=_ms.size();
2671 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2672 for(std::size_t i=0;i<nbOfLev;i++)
2674 const MEDFileUMeshSplitL1 *lev=_ms[i];
2675 oss << " - Level #" << -((int) i) << " has dimension : ";
2678 oss << lev->getMeshDimension() << std::endl;
2679 lev->simpleRepr(oss);
2682 oss << MSG2 << std::endl;
2684 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2687 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2688 oss << "- Names of coordinates :" << std::endl;
2689 std::vector<std::string> vars=coo->getVarsOnComponent();
2690 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2691 oss << std::endl << "- Units of coordinates : " << std::endl;
2692 std::vector<std::string> units=coo->getUnitsOnComponent();
2693 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2695 oss << std::endl << std::endl;
2701 * Returns a full textual description of \a this mesh.
2702 * \return std::string - the string holding the mesh description.
2704 std::string MEDFileUMesh::advancedRepr() const
2706 return simpleRepr();
2710 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2711 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2712 * \return int - the number of entities.
2713 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2715 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2717 if(meshDimRelToMaxExt==1)
2719 if(!((const DataArrayDouble *)_coords))
2720 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2721 return _coords->getNumberOfTuples();
2723 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2727 * Returns the family field for mesh entities of a given dimension.
2728 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2729 * \return const DataArrayInt * - the family field. It is an array of ids of families
2730 * each mesh entity belongs to. It can be \c NULL.
2732 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2734 if(meshDimRelToMaxExt==1)
2736 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2737 return l1->getFamilyField();
2741 * Returns the optional numbers of mesh entities of a given dimension.
2742 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2743 * \return const DataArrayInt * - the array of the entity numbers.
2744 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2746 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2748 if(meshDimRelToMaxExt==1)
2750 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2751 return l1->getNumberField();
2754 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2756 if(meshDimRelToMaxExt==1)
2757 return _name_coords;
2758 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2759 return l1->getNameField();
2763 * 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).
2765 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
2766 * \param [in] gt - The input geometric type for which the part definition is requested.
2767 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
2769 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
2771 if(meshDimRelToMaxExt==1)
2772 return _part_coords;
2773 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2774 return l1->getPartDef(gt);
2777 int MEDFileUMesh::getNumberOfNodes() const
2779 const DataArrayDouble *coo=_coords;
2781 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2782 return coo->getNumberOfTuples();
2785 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
2787 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2788 return l1->getNumberOfCells();
2791 bool MEDFileUMesh::hasImplicitPart() const
2796 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
2798 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
2801 void MEDFileUMesh::releaseImplicitPartIfAny() const
2805 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2807 std::size_t sz(st.getNumberOfItems());
2808 for(std::size_t i=0;i<sz;i++)
2810 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2811 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2812 if(st[i].getPflName().empty())
2813 m->computeNodeIdsAlg(nodesFetched);
2816 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
2817 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2818 m2->computeNodeIdsAlg(nodesFetched);
2824 * Returns the optional numbers of mesh entities of a given dimension transformed using
2825 * DataArrayInt::invertArrayN2O2O2N().
2826 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2827 * \return const DataArrayInt * - the array of the entity numbers transformed using
2828 * DataArrayInt::invertArrayN2O2O2N().
2829 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2831 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
2833 if(meshDimRelToMaxExt==1)
2835 if(!((const DataArrayInt *)_num_coords))
2836 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2837 return _rev_num_coords;
2839 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2840 return l1->getRevNumberField();
2844 * Returns a pointer to the node coordinates array of \a this mesh \b without
2845 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2847 DataArrayDouble *MEDFileUMesh::getCoords() const
2849 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2850 if((DataArrayDouble *)tmp)
2858 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2859 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2861 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2862 * \param [in] grp - the name of the group whose mesh entities are included in the
2864 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2865 * according to the optional numbers of entities, if available.
2866 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2867 * delete this mesh using decrRef() as it is no more needed.
2868 * \throw If the name of a nonexistent group is specified.
2869 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2871 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2873 synchronizeTinyInfoOnLeaves();
2874 std::vector<std::string> tmp(1);
2876 return getGroups(meshDimRelToMaxExt,tmp,renum);
2880 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2881 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2883 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2884 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2886 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2887 * according to the optional numbers of entities, if available.
2888 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2889 * delete this mesh using decrRef() as it is no more needed.
2890 * \throw If a name of a nonexistent group is present in \a grps.
2891 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2893 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2895 synchronizeTinyInfoOnLeaves();
2896 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2897 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2898 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2899 zeRet->setName(grps[0]);
2900 return zeRet.retn();
2904 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2905 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2907 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2908 * \param [in] fam - the name of the family whose mesh entities are included in the
2910 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2911 * according to the optional numbers of entities, if available.
2912 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2913 * delete this mesh using decrRef() as it is no more needed.
2914 * \throw If a name of a nonexistent family is present in \a grps.
2915 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2917 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2919 synchronizeTinyInfoOnLeaves();
2920 std::vector<std::string> tmp(1);
2922 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2926 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2927 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2929 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2930 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2932 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2933 * according to the optional numbers of entities, if available.
2934 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2935 * delete this mesh using decrRef() as it is no more needed.
2936 * \throw If a name of a nonexistent family is present in \a fams.
2937 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2939 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2941 synchronizeTinyInfoOnLeaves();
2942 if(meshDimRelToMaxExt==1)
2944 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2945 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2946 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2950 std::vector<int> famIds=getFamiliesIds(fams);
2951 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2952 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2954 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2956 zeRet=l1->getFamilyPart(0,0,renum);
2957 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2958 zeRet->setName(fams[0]);
2959 return zeRet.retn();
2963 * Returns ids of mesh entities contained in given families of a given dimension.
2964 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2966 * \param [in] fams - the names of the families of interest.
2967 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2968 * returned instead of ids.
2969 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2970 * numbers, if available and required, of mesh entities of the families. The caller
2971 * is to delete this array using decrRef() as it is no more needed.
2972 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2974 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2976 std::vector<int> famIds=getFamiliesIds(fams);
2977 if(meshDimRelToMaxExt==1)
2979 if((const DataArrayInt *)_fam_coords)
2981 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2983 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2985 da=_fam_coords->getIdsEqualList(0,0);
2987 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2992 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2994 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2996 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2998 return l1->getFamilyPartArr(0,0,renum);
3002 * Returns a MEDCouplingUMesh of a given relative dimension.
3003 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3004 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3005 * To build a valid MEDCouplingUMesh from the returned one in this case,
3006 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3007 * \param [in] meshDimRelToMax - the relative dimension of interest.
3008 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3009 * optional numbers of mesh entities.
3010 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3011 * delete using decrRef() as it is no more needed.
3012 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3013 * \sa getGenMeshAtLevel()
3015 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3017 synchronizeTinyInfoOnLeaves();
3018 if(meshDimRelToMaxExt==1)
3022 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3023 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3024 umesh->setCoords(cc);
3025 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3026 umesh->setName(getName());
3030 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3031 return l1->getWholeMesh(renum);
3035 * Returns a MEDCouplingUMesh of a given relative dimension.
3036 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3037 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3038 * To build a valid MEDCouplingUMesh from the returned one in this case,
3039 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3040 * \param [in] meshDimRelToMax - the relative dimension of interest.
3041 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3042 * optional numbers of mesh entities.
3043 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3044 * delete using decrRef() as it is no more needed.
3045 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3046 * \sa getMeshAtLevel()
3048 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3050 return getMeshAtLevel(meshDimRelToMax,renum);
3053 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3055 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3056 return l1->getDistributionOfTypes();
3060 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3061 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3062 * optional numbers of mesh entities.
3063 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3064 * delete using decrRef() as it is no more needed.
3065 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3067 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3069 return getMeshAtLevel(0,renum);
3073 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3074 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3075 * optional numbers of mesh entities.
3076 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3077 * delete using decrRef() as it is no more needed.
3078 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3080 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3082 return getMeshAtLevel(-1,renum);
3086 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3087 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3088 * optional numbers of mesh entities.
3089 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3090 * delete using decrRef() as it is no more needed.
3091 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3093 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3095 return getMeshAtLevel(-2,renum);
3099 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3100 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3101 * optional numbers of mesh entities.
3102 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3103 * delete using decrRef() as it is no more needed.
3104 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3106 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3108 return getMeshAtLevel(-3,renum);
3112 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3113 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3114 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3115 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3117 void MEDFileUMesh::forceComputationOfParts() const
3119 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3121 const MEDFileUMeshSplitL1 *elt(*it);
3123 elt->forceComputationOfParts();
3128 * This method returns a vector of mesh parts containing each exactly one geometric type.
3129 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3130 * This method is only for memory aware users.
3131 * The returned pointers are **NOT** new object pointer. No need to mange them.
3133 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3135 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3136 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3140 * This method returns the part of \a this having the geometric type \a gt.
3141 * If such part is not existing an exception will be thrown.
3142 * The returned pointer is **NOT** new object pointer. No need to mange it.
3144 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3146 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3147 int lev=(int)cm.getDimension()-getMeshDimension();
3148 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3149 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3153 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3154 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3156 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3158 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3159 return sp->getGeoTypes();
3163 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3164 * \param [in] gt - the geometric type for which the family field is asked.
3165 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3166 * delete using decrRef() as it is no more needed.
3167 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3169 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3171 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3172 int lev=(int)cm.getDimension()-getMeshDimension();
3173 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3174 return sp->extractFamilyFieldOnGeoType(gt);
3178 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3179 * \param [in] gt - the geometric type for which the number field is asked.
3180 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3181 * delete using decrRef() as it is no more needed.
3182 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3184 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3186 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3187 int lev=(int)cm.getDimension()-getMeshDimension();
3188 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3189 return sp->extractNumberFieldOnGeoType(gt);
3193 * This method returns for specified geometric type \a gt the relative level to \a this.
3194 * If the relative level is empty an exception will be thrown.
3196 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3198 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3199 int ret((int)cm.getDimension()-getMeshDimension());
3200 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3204 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3206 if(meshDimRelToMaxExt==1)
3207 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3208 if(meshDimRelToMaxExt>1)
3209 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3210 int tracucedRk=-meshDimRelToMaxExt;
3211 if(tracucedRk>=(int)_ms.size())
3212 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3213 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3214 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3215 return _ms[tracucedRk];
3218 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3220 if(meshDimRelToMaxExt==1)
3221 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3222 if(meshDimRelToMaxExt>1)
3223 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3224 int tracucedRk=-meshDimRelToMaxExt;
3225 if(tracucedRk>=(int)_ms.size())
3226 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3227 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3228 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3229 return _ms[tracucedRk];
3232 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3234 if(-meshDimRelToMax>=(int)_ms.size())
3235 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3237 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3239 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3241 int ref=(*it)->getMeshDimension();
3242 if(ref+i!=meshDim-meshDimRelToMax)
3243 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3249 * Sets the node coordinates array of \a this mesh.
3250 * \param [in] coords - the new node coordinates array.
3251 * \throw If \a coords == \c NULL.
3253 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3256 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3257 coords->checkAllocated();
3258 int nbOfTuples=coords->getNumberOfTuples();
3261 _fam_coords=DataArrayInt::New();
3262 _fam_coords->alloc(nbOfTuples,1);
3263 _fam_coords->fillWithZero();
3264 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3265 if((MEDFileUMeshSplitL1 *)(*it))
3266 (*it)->setCoords(coords);
3270 * Removes all groups of a given dimension in \a this mesh.
3271 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3272 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3274 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3276 if(meshDimRelToMaxExt==1)
3278 if((DataArrayInt *)_fam_coords)
3279 _fam_coords->fillWithZero();
3282 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3283 l1->eraseFamilyField();
3288 * Removes all families with ids not present in the family fields of \a this mesh.
3290 void MEDFileUMesh::optimizeFamilies()
3292 std::vector<int> levs=getNonEmptyLevelsExt();
3293 std::set<int> allFamsIds;
3294 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3296 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3297 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3299 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3302 std::set<std::string> famNamesToKill;
3303 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3305 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3306 famNamesToKill.insert((*it).first);
3308 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3309 _families.erase(*it);
3310 std::vector<std::string> grpNamesToKill;
3311 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3313 std::vector<std::string> tmp;
3314 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3316 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3317 tmp.push_back(*it2);
3322 tmp.push_back((*it).first);
3324 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3328 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3330 std::vector<int> levs=getNonEmptyLevels();
3331 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3332 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3333 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3334 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3335 int nbNodes=m0->getNumberOfNodes();
3336 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3337 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3338 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3339 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3340 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3341 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3342 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3343 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3344 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3345 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3346 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3347 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3348 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3349 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3350 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3351 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3352 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3353 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3354 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3355 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3356 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3357 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3358 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3359 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3360 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3361 m0->setCoords(tmp0->getCoords());
3362 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3363 m1->setCoords(m0->getCoords());
3364 _coords=m0->getCoords(); _coords->incrRef();
3365 // duplication of cells in group 'grpNameM1' on level -1
3366 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3367 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3368 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3369 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3370 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3372 newm1->setName(getName());
3373 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3375 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3376 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3377 newFam->alloc(newm1->getNumberOfCells(),1);
3378 int idd=getMaxFamilyId()+1;
3379 int globStart=0,start=0,end,globEnd;
3380 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3381 for(int i=0;i<nbOfChunks;i++)
3383 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3384 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3386 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3387 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3388 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3393 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3397 newm1->setCoords(getCoords());
3398 setMeshAtLevel(-1,newm1);
3399 setFamilyFieldArr(-1,newFam);
3400 std::string grpName2(grpNameM1); grpName2+="_dup";
3401 addFamily(grpName2,idd);
3402 addFamilyOnGrp(grpName2,grpName2);
3407 int newNbOfNodes=getCoords()->getNumberOfTuples();
3408 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3409 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3410 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3413 nodesDuplicated=nodeIdsToDuplicate.retn();
3414 cellsModified=cellsToModifyConn0.retn();
3415 cellsNotModified=cellsToModifyConn1.retn();
3419 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3420 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3421 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3423 * \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.
3424 * 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.
3426 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3428 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3429 std::vector<int> levs=getNonEmptyLevels();
3431 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3432 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3435 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3437 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3438 std::vector<int> code1=m->getDistributionOfTypes();
3439 end=PutInThirdComponentOfCodeOffset(code1,start);
3440 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3441 bool hasChanged=m->unPolyze();
3442 DataArrayInt *fake=0;
3443 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3444 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3446 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3449 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3450 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3452 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3453 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3454 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3455 setMeshAtLevel(*it,m);
3456 std::vector<int> code2=m->getDistributionOfTypes();
3457 end=PutInThirdComponentOfCodeOffset(code2,start);
3458 newCode.insert(newCode.end(),code2.begin(),code2.end());
3460 if(o2nCellsPart2->isIdentity())
3464 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3465 setFamilyFieldArr(*it,newFamField);
3469 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3470 setRenumFieldArr(*it,newNumField);
3475 newCode.insert(newCode.end(),code1.begin(),code1.end());
3481 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3482 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3483 o2nRenumCell=o2nRenumCellRet.retn();
3488 struct MEDLoaderAccVisit1
3490 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3491 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3492 int _new_nb_of_nodes;
3496 * 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.
3497 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3498 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3499 * -1 values in returned array means that the corresponding old node is no more used.
3501 * \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
3502 * is modified in \a this.
3503 * \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
3506 DataArrayInt *MEDFileUMesh::zipCoords()
3508 const DataArrayDouble *coo(getCoords());
3510 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3511 int nbOfNodes(coo->getNumberOfTuples());
3512 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3513 std::vector<int> neLevs(getNonEmptyLevels());
3514 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3516 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
3517 if(zeLev->isMeshStoredSplitByType())
3519 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
3520 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3522 (*it)->computeNodeIdsAlg(nodeIdsInUse);
3526 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
3527 mesh->computeNodeIdsAlg(nodeIdsInUse);
3530 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
3531 if(nbrOfNodesInUse==nbOfNodes)
3532 return 0;//no need to update _part_coords
3533 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
3534 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3535 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
3536 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3537 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3538 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3539 if((const DataArrayInt *)_fam_coords)
3540 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3541 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3542 if((const DataArrayInt *)_num_coords)
3543 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3544 if((const DataArrayAsciiChar *)_name_coords)
3545 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3546 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3547 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3549 if((MEDFileUMeshSplitL1*)*it)
3551 (*it)->renumberNodesInConn(ret->begin());
3552 (*it)->setCoords(_coords);
3555 // updates _part_coords
3556 const PartDefinition *pc(_part_coords);
3559 MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
3560 _part_coords=tmpPD->composeWith(pc);
3566 * This method performs an extrusion along a path defined by \a m1D.
3567 * \a this is expected to be a mesh with max mesh dimension equal to 2.
3568 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
3569 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
3570 * This method scans all levels in \a this
3571 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
3573 * \param [in] m1D - the mesh defining the extrusion path.
3574 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
3575 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
3577 * \sa MEDCouplingUMesh::buildExtrudedMesh
3579 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
3581 if(getMeshDimension()!=2)
3582 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3583 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3584 m1D->checkCoherency();
3585 if(m1D->getMeshDimension()!=1)
3586 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3587 int nbRep(m1D->getNumberOfCells());
3588 std::vector<int> levs(getNonEmptyLevels());
3589 std::vector<std::string> grps(getGroupsNames());
3590 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3591 DataArrayDouble *coords(0);
3592 std::size_t nbOfLevsOut(levs.size()+1);
3593 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3594 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3596 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3597 item=item->clone(false);
3598 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3599 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3600 tmp->changeSpaceDimension(3+(*lev),0.);
3601 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3602 zeList.push_back(elt);
3604 coords=elt->getCoords();
3607 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3608 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3610 (*it)->setName(getName());
3611 (*it)->setCoords(coords);
3613 for(std::size_t ii=0;ii!=zeList.size();ii++)
3616 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
3617 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
3620 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
3621 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
3622 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
3623 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
3624 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
3625 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
3626 std::vector<const MEDCouplingUMesh *> elts(3);
3627 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
3628 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
3629 elt->setName(getName());
3632 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
3633 ret->setMeshAtLevel(lev,elt);
3635 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
3636 endLev=endLev->clone(false); endLev->setCoords(coords);
3637 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
3638 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
3639 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
3640 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
3641 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
3642 endLev->setName(getName());
3643 ret->setMeshAtLevel(levs.back()-1,endLev);
3645 for(std::size_t ii=0;ii!=zeList.size();ii++)
3648 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3649 std::vector< const DataArrayInt * > outGrps2;
3652 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3654 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
3655 if(!grpArr->empty())
3657 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
3658 int offset0(zeList[ii]->getNumberOfCells());
3659 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
3660 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
3661 std::ostringstream oss; oss << grpArr2->getName() << "_top";
3662 grpArr2->setName(oss.str());
3663 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3664 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3665 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3666 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3671 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3673 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
3674 if(!grpArr->empty())
3676 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
3677 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
3678 std::vector< const DataArrayInt *> grpArrs2(nbRep);
3679 for(int iii=0;iii<nbRep;iii++)
3681 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
3682 grpArrs2[iii]=grpArrs[iii];
3684 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
3685 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3686 std::ostringstream grpName; grpName << *grp << "_extruded";
3687 grpArrExt->setName(grpName.str());
3688 outGrps.push_back(grpArrExt);
3689 outGrps2.push_back(grpArrExt);
3692 ret->setGroupsAtLevel(lev,outGrps2);
3694 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3695 std::vector< const DataArrayInt * > outGrps2;
3696 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3698 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
3699 if(grpArr1->empty())
3701 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
3702 std::ostringstream grpName; grpName << *grp << "_top";
3703 grpArr2->setName(grpName.str());
3704 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
3705 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3706 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3708 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
3713 * Adds a group of nodes to \a this mesh.
3714 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3715 * The ids should be sorted and different each other (MED file norm).
3716 * \throw If the node coordinates array is not set.
3717 * \throw If \a ids == \c NULL.
3718 * \throw If \a ids->getName() == "".
3719 * \throw If \a ids does not respect the MED file norm.
3720 * \throw If a group with name \a ids->getName() already exists.
3722 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
3724 const DataArrayDouble *coords=_coords;
3726 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3727 int nbOfNodes=coords->getNumberOfTuples();
3728 if(!((DataArrayInt *)_fam_coords))
3729 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3731 addGroupUnderground(true,ids,_fam_coords);
3735 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3736 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3737 * The ids should be sorted and different each other (MED file norm).
3738 * \throw If the node coordinates array is not set.
3739 * \throw If \a ids == \c NULL.
3740 * \throw If \a ids->getName() == "".
3741 * \throw If \a ids does not respect the MED file norm.
3742 * \throw If a group with name \a ids->getName() already exists.
3744 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
3746 std::vector<int> levs=getNonEmptyLevelsExt();
3747 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3749 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3750 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3752 if(meshDimRelToMaxExt==1)
3753 { addNodeGroup(ids); return ; }
3754 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3755 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3756 addGroupUnderground(false,ids,fam);
3760 * \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).
3761 * \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)
3763 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
3766 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3767 std::string grpName(ids->getName());
3769 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3770 ids->checkStrictlyMonotonic(true);
3771 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3772 std::vector<std::string> grpsNames=getGroupsNames();
3773 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3775 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3776 throw INTERP_KERNEL::Exception(oss.str().c_str());
3778 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3779 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3780 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3781 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3782 std::vector<int> familyIds;
3783 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3784 int maxVal=getTheMaxAbsFamilyId()+1;
3785 std::map<std::string,int> families(_families);
3786 std::map<std::string, std::vector<std::string> > groups(_groups);
3787 std::vector<std::string> fams;
3788 bool created(false);
3789 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3791 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3792 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3793 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3794 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3797 bool isFamPresent=false;
3798 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3799 isFamPresent=(*itl)->presenceOfValue(*famId);
3801 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3804 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3805 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3806 fams.push_back(locFamName);
3807 if(existsFamily(*famId))
3809 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3810 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3813 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3817 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3818 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3819 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3820 if(existsFamily(*famId))
3822 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3823 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3828 for(std::size_t i=0;i<familyIds.size();i++)
3830 DataArrayInt *da=idsPerfamiliyIds[i];
3831 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3835 _groups[grpName]=fams;
3839 * Changes a name of a family specified by its id.
3840 * \param [in] id - the id of the family of interest.
3841 * \param [in] newFamName - the new family name.
3842 * \throw If no family with the given \a id exists.
3844 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
3846 std::string oldName=getFamilyNameGivenId(id);
3847 _families.erase(oldName);
3848 _families[newFamName]=id;
3852 * Removes a mesh of a given dimension.
3853 * \param [in] meshDimRelToMax - the relative dimension of interest.
3854 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3856 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
3858 std::vector<int> levSet=getNonEmptyLevels();
3859 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3860 if(it==levSet.end())
3861 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3862 int pos=(-meshDimRelToMax);
3867 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
3868 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3869 * \param [in] m - the new mesh to set.
3870 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3872 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3873 * another node coordinates array.
3874 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3875 * to the existing meshes of other levels of \a this mesh.
3877 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
3879 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
3880 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3884 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3885 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3886 * \param [in] m - the new mesh to set.
3887 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3888 * writing \a this mesh in a MED file.
3889 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3891 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3892 * another node coordinates array.
3893 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3894 * to the existing meshes of other levels of \a this mesh.
3896 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
3898 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
3899 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3902 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
3904 dealWithTinyInfo(m);
3905 std::vector<int> levSet=getNonEmptyLevels();
3906 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3908 if((DataArrayDouble *)_coords==0)
3910 DataArrayDouble *c=m->getCoords();
3915 if(m->getCoords()!=_coords)
3916 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3917 int sz=(-meshDimRelToMax)+1;
3918 if(sz>=(int)_ms.size())
3920 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3924 return _ms[-meshDimRelToMax];
3928 * This method allows to set at once the content of different levels in \a this.
3929 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3931 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3932 * \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.
3933 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3935 * \throw If \a there is a null pointer in \a ms.
3936 * \sa MEDFileUMesh::setMeshAtLevel
3938 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3942 const MEDCouplingUMesh *mRef=ms[0];
3944 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3945 std::string name(mRef->getName());
3946 const DataArrayDouble *coo(mRef->getCoords());
3949 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3951 const MEDCouplingUMesh *cur(*it);
3953 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3954 if(coo!=cur->getCoords())
3955 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3956 int mdim=cur->getMeshDimension();
3957 zeDim=std::max(zeDim,mdim);
3958 if(s.find(mdim)!=s.end())
3959 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3961 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3963 int mdim=(*it)->getMeshDimension();
3964 setName((*it)->getName());
3965 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3971 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3972 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3973 * The given meshes must share the same node coordinates array.
3974 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3975 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3976 * create in \a this mesh.
3977 * \throw If \a ms is empty.
3978 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3979 * to the existing meshes of other levels of \a this mesh.
3980 * \throw If the meshes in \a ms do not share the same node coordinates array.
3981 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3982 * of the given meshes.
3983 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3984 * \throw If names of some meshes in \a ms are equal.
3985 * \throw If \a ms includes a mesh with an empty name.
3987 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3990 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3991 int sz=(-meshDimRelToMax)+1;
3992 if(sz>=(int)_ms.size())
3994 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3995 DataArrayDouble *coo=checkMultiMesh(ms);
3996 if((DataArrayDouble *)_coords==0)
4002 if((DataArrayDouble *)_coords!=coo)
4003 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4004 std::vector<DataArrayInt *> corr;
4005 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4006 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4007 setMeshAtLevel(meshDimRelToMax,m,renum);
4008 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4009 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4013 * Creates groups at a given level in \a this mesh from a sequence of
4014 * meshes each representing a group.
4015 * The given meshes must share the same node coordinates array.
4016 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4017 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4018 * create in \a this mesh.
4019 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4021 * \throw If \a ms is empty.
4022 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4023 * to the existing meshes of other levels of \a this mesh.
4024 * \throw If the meshes in \a ms do not share the same node coordinates array.
4025 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4026 * of the given meshes.
4027 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4028 * \throw If names of some meshes in \a ms are equal.
4029 * \throw If \a ms includes a mesh with an empty name.
4031 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4034 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4035 int sz=(-meshDimRelToMax)+1;
4036 if(sz>=(int)_ms.size())
4038 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4039 DataArrayDouble *coo=checkMultiMesh(ms);
4040 if((DataArrayDouble *)_coords==0)
4046 if((DataArrayDouble *)_coords!=coo)
4047 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4048 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4049 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4051 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4053 DataArrayInt *arr=0;
4054 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4058 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4059 throw INTERP_KERNEL::Exception(oss.str().c_str());
4062 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4063 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4066 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4068 const DataArrayDouble *ret=ms[0]->getCoords();
4069 int mdim=ms[0]->getMeshDimension();
4070 for(unsigned int i=1;i<ms.size();i++)
4072 ms[i]->checkCoherency();
4073 if(ms[i]->getCoords()!=ret)
4074 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4075 if(ms[i]->getMeshDimension()!=mdim)
4076 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4078 return const_cast<DataArrayDouble *>(ret);
4082 * Sets the family field of a given relative dimension.
4083 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4084 * the family field is set.
4085 * \param [in] famArr - the array of the family field.
4086 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4087 * \throw If \a famArr has an invalid size.
4089 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4091 if(meshDimRelToMaxExt==1)
4098 DataArrayDouble *coo(_coords);
4100 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4101 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4106 if(meshDimRelToMaxExt>1)
4107 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4108 int traducedRk=-meshDimRelToMaxExt;
4109 if(traducedRk>=(int)_ms.size())
4110 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
4111 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4112 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4113 return _ms[traducedRk]->setFamilyArr(famArr);
4117 * Sets the optional numbers of mesh entities of a given dimension.
4118 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4119 * \param [in] renumArr - the array of the numbers.
4120 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4121 * \throw If \a renumArr has an invalid size.
4123 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4125 if(meshDimRelToMaxExt==1)
4133 DataArrayDouble *coo(_coords);
4135 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4136 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4137 renumArr->incrRef();
4138 _num_coords=renumArr;
4142 if(meshDimRelToMaxExt>1)
4143 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4144 int traducedRk=-meshDimRelToMaxExt;
4145 if(traducedRk>=(int)_ms.size())
4146 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
4147 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4148 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4149 return _ms[traducedRk]->setRenumArr(renumArr);
4153 * Sets the optional names of mesh entities of a given dimension.
4154 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4155 * \param [in] nameArr - the array of the names.
4156 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4157 * \throw If \a nameArr has an invalid size.
4159 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4161 if(meshDimRelToMaxExt==1)
4168 DataArrayDouble *coo(_coords);
4170 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4171 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4173 _name_coords=nameArr;
4176 if(meshDimRelToMaxExt>1)
4177 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4178 int traducedRk=-meshDimRelToMaxExt;
4179 if(traducedRk>=(int)_ms.size())
4180 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
4181 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4182 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4183 return _ms[traducedRk]->setNameArr(nameArr);
4186 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4188 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4189 if((const MEDFileUMeshSplitL1 *)(*it))
4190 (*it)->synchronizeTinyInfo(*this);
4194 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4196 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4198 DataArrayInt *arr=_fam_coords;
4200 arr->changeValue(oldId,newId);
4201 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4203 MEDFileUMeshSplitL1 *sp=(*it);
4206 sp->changeFamilyIdArr(oldId,newId);
4211 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4213 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4214 const DataArrayInt *da(_fam_coords);
4216 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4217 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4219 const MEDFileUMeshSplitL1 *elt(*it);
4222 da=elt->getFamilyField();
4224 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4230 void MEDFileUMesh::computeRevNum() const
4232 if((const DataArrayInt *)_num_coords)
4235 int maxValue=_num_coords->getMaxValue(pos);
4236 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4240 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4242 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4245 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4247 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4248 ret.push_back((const DataArrayInt *)_fam_nodes);
4249 ret.push_back((const DataArrayInt *)_num_nodes);
4250 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4251 ret.push_back((const DataArrayInt *)_fam_cells);
4252 ret.push_back((const DataArrayInt *)_num_cells);
4253 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4254 ret.push_back((const DataArrayInt *)_fam_faces);
4255 ret.push_back((const DataArrayInt *)_num_faces);
4256 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4257 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4258 ret.push_back((const DataArrayInt *)_rev_num_cells);
4259 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4263 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4265 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4266 if((const DataArrayInt *)_fam_nodes)
4268 int val=_fam_nodes->getMaxValue(tmp);
4269 ret=std::max(ret,std::abs(val));
4271 if((const DataArrayInt *)_fam_cells)
4273 int val=_fam_cells->getMaxValue(tmp);
4274 ret=std::max(ret,std::abs(val));
4276 if((const DataArrayInt *)_fam_faces)
4278 int val=_fam_faces->getMaxValue(tmp);
4279 ret=std::max(ret,std::abs(val));
4284 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4286 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4287 if((const DataArrayInt *)_fam_nodes)
4289 int val=_fam_nodes->getMaxValue(tmp);
4290 ret=std::max(ret,val);
4292 if((const DataArrayInt *)_fam_cells)
4294 int val=_fam_cells->getMaxValue(tmp);
4295 ret=std::max(ret,val);
4297 if((const DataArrayInt *)_fam_faces)
4299 int val=_fam_faces->getMaxValue(tmp);
4300 ret=std::max(ret,val);
4305 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4307 int ret=std::numeric_limits<int>::max(),tmp=-1;
4308 if((const DataArrayInt *)_fam_nodes)
4310 int val=_fam_nodes->getMinValue(tmp);
4311 ret=std::min(ret,val);
4313 if((const DataArrayInt *)_fam_cells)
4315 int val=_fam_cells->getMinValue(tmp);
4316 ret=std::min(ret,val);
4318 if((const DataArrayInt *)_fam_faces)
4320 int val=_fam_faces->getMinValue(tmp);
4321 ret=std::min(ret,val);
4326 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4328 if(!MEDFileMesh::isEqual(other,eps,what))
4330 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4333 what="Mesh types differ ! This is structured and other is NOT !";
4336 const DataArrayInt *famc1=_fam_nodes;
4337 const DataArrayInt *famc2=otherC->_fam_nodes;
4338 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4340 what="Mismatch of families arr on nodes ! One is defined and not other !";
4345 bool ret=famc1->isEqual(*famc2);
4348 what="Families arr on nodes differ !";
4353 famc2=otherC->_fam_cells;
4354 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4356 what="Mismatch of families arr on cells ! One is defined and not other !";
4361 bool ret=famc1->isEqual(*famc2);
4364 what="Families arr on cells differ !";
4369 famc2=otherC->_fam_faces;
4370 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4372 what="Mismatch of families arr on faces ! One is defined and not other !";
4377 bool ret=famc1->isEqual(*famc2);
4380 what="Families arr on faces differ !";
4385 famc2=otherC->_num_nodes;
4386 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4388 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4393 bool ret=famc1->isEqual(*famc2);
4396 what="Numbering arr on nodes differ !";
4401 famc2=otherC->_num_cells;
4402 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4404 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4409 bool ret=famc1->isEqual(*famc2);
4412 what="Numbering arr on cells differ !";
4417 famc2=otherC->_num_faces;
4418 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4420 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4425 bool ret=famc1->isEqual(*famc2);
4428 what="Numbering arr on faces differ !";
4432 const DataArrayAsciiChar *d1=_names_cells;
4433 const DataArrayAsciiChar *d2=otherC->_names_cells;
4434 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4436 what="Mismatch of naming arr on cells ! One is defined and not other !";
4441 bool ret=d1->isEqual(*d2);
4444 what="Naming arr on cells differ !";
4449 d2=otherC->_names_faces;
4450 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4452 what="Mismatch of naming arr on faces ! One is defined and not other !";
4457 bool ret=d1->isEqual(*d2);
4460 what="Naming arr on faces differ !";
4465 d2=otherC->_names_nodes;
4466 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4468 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4473 bool ret=d1->isEqual(*d2);
4476 what="Naming arr on nodes differ !";
4483 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4485 MEDFileMesh::clearNonDiscrAttributes();
4486 const DataArrayInt *tmp=_fam_nodes;
4488 (const_cast<DataArrayInt *>(tmp))->setName("");
4491 (const_cast<DataArrayInt *>(tmp))->setName("");
4494 (const_cast<DataArrayInt *>(tmp))->setName("");
4497 (const_cast<DataArrayInt *>(tmp))->setName("");
4500 (const_cast<DataArrayInt *>(tmp))->setName("");
4503 (const_cast<DataArrayInt *>(tmp))->setName("");
4507 * Returns ids of mesh entities contained in given families of a given dimension.
4508 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4510 * \param [in] fams - the names of the families of interest.
4511 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4512 * returned instead of ids.
4513 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4514 * numbers, if available and required, of mesh entities of the families. The caller
4515 * is to delete this array using decrRef() as it is no more needed.
4516 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4518 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4520 std::vector<int> famIds(getFamiliesIds(fams));
4521 switch(meshDimRelToMaxExt)
4525 if((const DataArrayInt *)_fam_nodes)
4527 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4529 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4531 da=_fam_nodes->getIdsEqualList(0,0);
4533 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4538 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4543 if((const DataArrayInt *)_fam_cells)
4545 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4547 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4549 da=_fam_cells->getIdsEqualList(0,0);
4551 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4556 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4561 if((const DataArrayInt *)_fam_faces)
4563 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4565 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4567 da=_fam_faces->getIdsEqualList(0,0);
4569 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
4574 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
4578 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
4580 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
4584 * Sets the family field of a given relative dimension.
4585 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4586 * the family field is set.
4587 * \param [in] famArr - the array of the family field.
4588 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4589 * \throw If \a famArr has an invalid size.
4590 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
4592 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4594 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4596 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4597 switch(meshDimRelToMaxExt)
4601 int nbCells=mesh->getNumberOfCells();
4602 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4608 int nbNodes=mesh->getNumberOfNodes();
4609 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4615 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4616 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
4621 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
4628 * Sets the optional numbers of mesh entities of a given dimension.
4629 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4630 * \param [in] renumArr - the array of the numbers.
4631 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4632 * \throw If \a renumArr has an invalid size.
4633 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4635 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4637 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4639 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4640 switch(meshDimRelToMaxExt)
4644 int nbCells=mesh->getNumberOfCells();
4645 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4646 _num_cells=renumArr;
4651 int nbNodes=mesh->getNumberOfNodes();
4652 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4653 _num_nodes=renumArr;
4658 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4659 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
4660 _num_faces=renumArr;
4664 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
4667 renumArr->incrRef();
4671 * Sets the optional names of mesh entities of a given dimension.
4672 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4673 * \param [in] nameArr - the array of the names.
4674 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4675 * \throw If \a nameArr has an invalid size.
4677 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4679 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4681 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4682 switch(meshDimRelToMaxExt)
4686 int nbCells=mesh->getNumberOfCells();
4687 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4688 _names_cells=nameArr;
4693 int nbNodes=mesh->getNumberOfNodes();
4694 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4695 _names_nodes=nameArr;
4700 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
4701 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
4702 _names_cells=nameArr;
4705 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4712 * Returns the family field for mesh entities of a given dimension.
4713 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4714 * \return const DataArrayInt * - the family field. It is an array of ids of families
4715 * each mesh entity belongs to. It can be \c NULL.
4716 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4718 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
4720 switch(meshDimRelToMaxExt)
4729 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4734 * Returns the optional numbers of mesh entities of a given dimension.
4735 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4736 * \return const DataArrayInt * - the array of the entity numbers.
4737 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4738 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4740 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
4742 switch(meshDimRelToMaxExt)
4751 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4756 * Returns the optional numbers of mesh entities of a given dimension transformed using
4757 * DataArrayInt::invertArrayN2O2O2N().
4758 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4759 * \return const DataArrayInt * - the array of the entity numbers transformed using
4760 * DataArrayInt::invertArrayN2O2O2N().
4761 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4762 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4764 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
4766 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4767 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4768 if(meshDimRelToMaxExt==0)
4770 if((const DataArrayInt *)_num_cells)
4773 int maxValue=_num_cells->getMaxValue(pos);
4774 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4775 return _rev_num_cells;
4778 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4782 if((const DataArrayInt *)_num_nodes)
4785 int maxValue=_num_nodes->getMaxValue(pos);
4786 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4787 return _rev_num_nodes;
4790 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4794 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
4796 switch(meshDimRelToMaxExt)
4799 return _names_cells;
4801 return _names_nodes;
4803 return _names_faces;
4805 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
4810 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4811 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4813 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4815 std::vector<int> ret(1);
4820 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4821 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4823 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4825 std::vector<int> ret(2);
4831 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4833 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4835 std::vector<int> ret;
4836 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
4847 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4849 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4851 std::vector<int> ret;
4852 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
4863 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4865 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4867 std::vector<int> ret;
4868 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
4879 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4881 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4883 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4887 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
4889 DataArrayInt *arr=_fam_nodes;
4891 arr->changeValue(oldId,newId);
4894 arr->changeValue(oldId,newId);
4897 arr->changeValue(oldId,newId);
4900 void MEDFileStructuredMesh::deepCpyAttributes()
4902 if((const DataArrayInt*)_fam_nodes)
4903 _fam_nodes=_fam_nodes->deepCpy();
4904 if((const DataArrayInt*)_num_nodes)
4905 _num_nodes=_num_nodes->deepCpy();
4906 if((const DataArrayAsciiChar*)_names_nodes)
4907 _names_nodes=_names_nodes->deepCpy();
4908 if((const DataArrayInt*)_fam_cells)
4909 _fam_cells=_fam_cells->deepCpy();
4910 if((const DataArrayInt*)_num_cells)
4911 _num_cells=_num_cells->deepCpy();
4912 if((const DataArrayAsciiChar*)_names_cells)
4913 _names_cells=_names_cells->deepCpy();
4914 if((const DataArrayInt*)_fam_faces)
4915 _fam_faces=_fam_faces->deepCpy();
4916 if((const DataArrayInt*)_num_faces)
4917 _num_faces=_num_faces->deepCpy();
4918 if((const DataArrayAsciiChar*)_names_faces)
4919 _names_faces=_names_faces->deepCpy();
4920 if((const DataArrayInt*)_rev_num_nodes)
4921 _rev_num_nodes=_rev_num_nodes->deepCpy();
4922 if((const DataArrayInt*)_rev_num_cells)
4923 _rev_num_cells=_rev_num_cells->deepCpy();
4927 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4929 * \return a pointer to cartesian mesh that need to be managed by the caller.
4930 * \warning the returned pointer has to be managed by the caller.
4934 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4935 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
4936 * \param [in] renum - it must be \c false.
4937 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4938 * delete using decrRef() as it is no more needed.
4940 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
4943 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4944 const MEDCouplingStructuredMesh *m(getStructuredMesh());
4945 switch(meshDimRelToMax)
4951 return const_cast<MEDCouplingStructuredMesh *>(m);
4956 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
4957 buildMinusOneImplicitPartIfNeeded();
4958 MEDCouplingMesh *ret(_faces_if_necessary);
4964 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4969 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4970 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4971 * \return int - the number of entities.
4972 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4974 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
4976 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4978 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4979 switch(meshDimRelToMaxExt)
4982 return cmesh->getNumberOfCells();
4984 return cmesh->getNumberOfNodes();
4986 return cmesh->getNumberOfCellsOfSubLevelMesh();
4988 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
4992 int MEDFileStructuredMesh::getNumberOfNodes() const
4994 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4996 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4997 return cmesh->getNumberOfNodes();
5000 bool MEDFileStructuredMesh::hasImplicitPart() const
5006 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5008 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5010 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5011 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5014 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5015 if(cm.getReverseExtrudedType()!=gt)
5016 throw INTERP_KERNEL::Exception(MSG);
5017 buildImplicitPart();
5018 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5022 if(gt!=zeFaceMesh->getCellModelEnum())
5023 throw INTERP_KERNEL::Exception(MSG);
5024 return zeFaceMesh->getNumberOfCells();
5028 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5030 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5032 buildImplicitPart();
5035 void MEDFileStructuredMesh::buildImplicitPart() const
5037 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5039 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5040 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5043 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5045 _faces_if_necessary=0;
5049 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5050 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5052 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5054 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5056 return _faces_if_necessary;
5059 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5061 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5063 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5064 switch(meshDimRelToMax)
5068 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5073 int mdim(cmesh->getMeshDimension());
5075 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5076 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5080 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5084 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5086 if(st.getNumberOfItems()!=1)
5087 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 !");
5088 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5089 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5090 if(getNumberOfNodes()!=(int)nodesFetched.size())
5091 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5092 if(st[0].getPflName().empty())
5094 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5097 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5098 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5099 int sz(nodesFetched.size());
5100 for(const int *work=arr->begin();work!=arr->end();work++)
5102 std::vector<int> conn;
5103 cmesh->getNodeIdsOfCell(*work,conn);
5104 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5105 if(*it>=0 && *it<sz)
5106 nodesFetched[*it]=true;
5108 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5112 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5114 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5118 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5119 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5121 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5122 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5124 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5127 if(!mrs || mrs->isCellFamilyFieldReading())
5129 famCells=DataArrayInt::New();
5130 famCells->alloc(nbOfElt,1);
5131 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer());
5134 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5137 if(!mrs || mrs->isCellNumFieldReading())
5139 numCells=DataArrayInt::New();
5140 numCells->alloc(nbOfElt,1);
5141 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer());
5144 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5147 if(!mrs || mrs->isCellNameFieldReading())
5149 namesCells=DataArrayAsciiChar::New();
5150 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5151 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer());
5152 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5157 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5159 setName(strm->getName());
5160 setDescription(strm->getDescription());
5161 setUnivName(strm->getUnivName());
5162 setIteration(strm->getIteration());
5163 setOrder(strm->getOrder());
5164 setTimeValue(strm->getTime());
5165 setTimeUnit(strm->getTimeUnit());
5166 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5167 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5168 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5171 if(!mrs || mrs->isNodeFamilyFieldReading())
5173 int nbNodes(getNumberOfNodes());
5175 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5176 _fam_nodes=DataArrayInt::New();
5177 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5178 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...
5179 _fam_nodes->fillWithZero();
5180 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
5183 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5186 if(!mrs || mrs->isNodeNumFieldReading())
5188 _num_nodes=DataArrayInt::New();
5189 _num_nodes->alloc(nbOfElt,1);
5190 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
5193 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5196 if(!mrs || mrs->isNodeNameFieldReading())
5198 _names_nodes=DataArrayAsciiChar::New();
5199 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5200 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
5201 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5204 int meshDim(getStructuredMesh()->getMeshDimension());
5205 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5207 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5210 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5212 int meshDim(getStructuredMesh()->getMeshDimension());
5213 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5215 if((const DataArrayInt *)_fam_cells)
5216 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
5217 if((const DataArrayInt *)_fam_faces)
5218 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer());
5219 if((const DataArrayInt *)_fam_nodes)
5220 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
5221 if((const DataArrayInt *)_num_cells)
5222 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
5223 if((const DataArrayInt *)_num_faces)
5224 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer());
5225 if((const DataArrayInt *)_num_nodes)
5226 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
5227 if((const DataArrayAsciiChar *)_names_cells)
5229 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5231 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5232 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5233 throw INTERP_KERNEL::Exception(oss.str().c_str());
5235 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
5237 if((const DataArrayAsciiChar *)_names_faces)
5239 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5241 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5242 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5243 throw INTERP_KERNEL::Exception(oss.str().c_str());
5245 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer());
5247 if((const DataArrayAsciiChar *)_names_nodes)
5249 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5251 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5252 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5253 throw INTERP_KERNEL::Exception(oss.str().c_str());
5255 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
5258 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5262 * Returns an empty instance of MEDFileCMesh.
5263 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5264 * mesh using decrRef() as it is no more needed.
5266 MEDFileCMesh *MEDFileCMesh::New()
5268 return new MEDFileCMesh;
5272 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5273 * file. The first mesh in the file is loaded.
5274 * \param [in] fileName - the name of MED file to read.
5275 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5276 * mesh using decrRef() as it is no more needed.
5277 * \throw If the file is not readable.
5278 * \throw If there is no meshes in the file.
5279 * \throw If the mesh in the file is not a Cartesian one.
5281 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5283 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5286 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5287 throw INTERP_KERNEL::Exception(oss.str().c_str());
5289 MEDFileUtilities::CheckFileForRead(fileName);
5290 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5292 ParaMEDMEM::MEDCouplingMeshType meshType;
5294 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5295 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5299 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5300 * file. The mesh to load is specified by its name and numbers of a time step and an
5302 * \param [in] fileName - the name of MED file to read.
5303 * \param [in] mName - the name of the mesh to read.
5304 * \param [in] dt - the number of a time step.
5305 * \param [in] it - the number of an iteration.
5306 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5307 * mesh using decrRef() as it is no more needed.
5308 * \throw If the file is not readable.
5309 * \throw If there is no mesh with given attributes in the file.
5310 * \throw If the mesh in the file is not a Cartesian one.
5312 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5314 MEDFileUtilities::CheckFileForRead(fileName);
5315 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5316 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5319 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5321 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5324 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5326 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5327 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5332 * Returns the dimension on cells in \a this mesh.
5333 * \return int - the mesh dimension.
5334 * \throw If there are no cells in this mesh.
5336 int MEDFileCMesh::getMeshDimension() const
5338 if(!((const MEDCouplingCMesh*)_cmesh))
5339 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5340 return _cmesh->getMeshDimension();
5344 * Returns the dimension on nodes in \a this mesh.
5345 * \return int - the space dimension.
5346 * \throw If there are no cells in this mesh.
5348 int MEDFileCMesh::getSpaceDimension() const
5350 if(!((const MEDCouplingCMesh*)_cmesh))
5351 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5352 return _cmesh->getSpaceDimension();
5356 * Returns a string describing \a this mesh.
5357 * \return std::string - the mesh information string.
5359 std::string MEDFileCMesh::simpleRepr() const
5361 return MEDFileStructuredMesh::simpleRepr();
5365 * Returns a full textual description of \a this mesh.
5366 * \return std::string - the string holding the mesh description.
5368 std::string MEDFileCMesh::advancedRepr() const
5370 return simpleRepr();
5373 MEDFileMesh *MEDFileCMesh::shallowCpy() const
5375 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5379 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
5381 return new MEDFileCMesh;
5384 MEDFileMesh *MEDFileCMesh::deepCpy() const
5386 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5387 if((const MEDCouplingCMesh*)_cmesh)
5388 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
5389 ret->deepCpyAttributes();
5394 * Checks if \a this and another mesh are equal.
5395 * \param [in] other - the mesh to compare with.
5396 * \param [in] eps - a precision used to compare real values.
5397 * \param [in,out] what - the string returning description of unequal data.
5398 * \return bool - \c true if the meshes are equal, \c false, else.
5400 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5402 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5404 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
5407 what="Mesh types differ ! This is cartesian and other is NOT !";
5410 clearNonDiscrAttributes();
5411 otherC->clearNonDiscrAttributes();
5412 const MEDCouplingCMesh *coo1=_cmesh;
5413 const MEDCouplingCMesh *coo2=otherC->_cmesh;
5414 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5416 what="Mismatch of cartesian meshes ! One is defined and not other !";
5421 bool ret=coo1->isEqual(coo2,eps);
5424 what="cartesian meshes differ !";
5432 * Clears redundant attributes of incorporated data arrays.
5434 void MEDFileCMesh::clearNonDiscrAttributes() const
5436 MEDFileStructuredMesh::clearNonDiscrAttributes();
5437 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
5440 MEDFileCMesh::MEDFileCMesh()
5444 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5447 loadCMeshFromFile(fid,mName,dt,it,mrs);
5449 catch(INTERP_KERNEL::Exception& e)
5454 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5456 ParaMEDMEM::MEDCouplingMeshType meshType;
5459 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5460 if(meshType!=CARTESIAN)
5462 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
5463 throw INTERP_KERNEL::Exception(oss.str().c_str());
5465 MEDFileCMeshL2 loaderl2;
5466 loaderl2.loadAll(fid,mid,mName,dt,it);
5467 MEDCouplingCMesh *mesh=loaderl2.getMesh();
5470 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5474 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
5475 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
5477 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
5479 synchronizeTinyInfoOnLeaves();
5483 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
5485 synchronizeTinyInfoOnLeaves();
5490 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
5491 * \param [in] m - the new MEDCouplingCMesh to refer to.
5492 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5495 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
5497 dealWithTinyInfo(m);
5503 void MEDFileCMesh::writeLL(med_idt fid) const
5505 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5506 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5507 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5508 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5509 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5510 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5511 int spaceDim(_cmesh->getSpaceDimension());
5512 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5513 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5514 for(int i=0;i<spaceDim;i++)
5516 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
5518 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5519 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
5520 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
5522 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5523 MEDmeshUniversalNameWr(fid,maa);
5524 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
5525 for(int i=0;i<spaceDim;i++)
5527 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
5528 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
5531 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5532 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5535 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
5537 const MEDCouplingCMesh *cmesh=_cmesh;
5540 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
5541 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
5542 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
5543 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
5546 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
5548 return new MEDFileCurveLinearMesh;
5551 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5553 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5556 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5557 throw INTERP_KERNEL::Exception(oss.str().c_str());
5559 MEDFileUtilities::CheckFileForRead(fileName);
5560 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5562 ParaMEDMEM::MEDCouplingMeshType meshType;
5564 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5565 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
5568 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5570 MEDFileUtilities::CheckFileForRead(fileName);
5571 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5572 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
5575 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
5577 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5580 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
5582 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5583 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
5587 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
5589 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5593 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
5595 return new MEDFileCurveLinearMesh;
5598 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
5600 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5601 if((const MEDCouplingCurveLinearMesh*)_clmesh)
5602 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
5603 ret->deepCpyAttributes();
5607 int MEDFileCurveLinearMesh::getMeshDimension() const
5609 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
5610 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5611 return _clmesh->getMeshDimension();
5614 std::string MEDFileCurveLinearMesh::simpleRepr() const
5616 return MEDFileStructuredMesh::simpleRepr();
5619 std::string MEDFileCurveLinearMesh::advancedRepr() const
5621 return simpleRepr();
5624 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5626 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5628 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
5631 what="Mesh types differ ! This is curve linear and other is NOT !";
5634 clearNonDiscrAttributes();
5635 otherC->clearNonDiscrAttributes();
5636 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
5637 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
5638 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5640 what="Mismatch of curve linear meshes ! One is defined and not other !";
5645 bool ret=coo1->isEqual(coo2,eps);
5648 what="curve linear meshes differ !";
5655 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
5657 MEDFileStructuredMesh::clearNonDiscrAttributes();
5658 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
5661 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
5663 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
5666 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
5667 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
5668 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
5669 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
5672 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
5674 synchronizeTinyInfoOnLeaves();
5678 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
5680 dealWithTinyInfo(m);
5686 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
5688 synchronizeTinyInfoOnLeaves();
5692 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
5696 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5699 loadCLMeshFromFile(fid,mName,dt,it,mrs);
5701 catch(INTERP_KERNEL::Exception& e)
5706 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
5708 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5709 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5710 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5711 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5712 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5713 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5714 int spaceDim=_clmesh->getSpaceDimension();
5715 int meshDim=_clmesh->getMeshDimension();
5716 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5717 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5718 const DataArrayDouble *coords=_clmesh->getCoords();
5720 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
5721 for(int i=0;i<spaceDim;i++)
5723 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
5725 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5726 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
5727 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
5729 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5730 MEDmeshUniversalNameWr(fid,maa);
5731 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5732 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5733 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5735 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5737 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5738 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5741 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5743 ParaMEDMEM::MEDCouplingMeshType meshType;
5746 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5747 if(meshType!=CURVE_LINEAR)
5749 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5750 throw INTERP_KERNEL::Exception(oss.str().c_str());
5752 MEDFileCLMeshL2 loaderl2;
5753 loaderl2.loadAll(fid,mid,mName,dt,it);
5754 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5757 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5760 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5762 return new MEDFileMeshMultiTS;
5765 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
5767 return new MEDFileMeshMultiTS(fileName);
5770 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
5772 return new MEDFileMeshMultiTS(fileName,mName);
5775 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
5777 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5778 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5780 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5781 if((const MEDFileMesh *)*it)
5782 meshOneTs[i]=(*it)->deepCpy();
5783 ret->_mesh_one_ts=meshOneTs;
5787 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
5789 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5792 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
5794 std::vector<const BigMemoryObject *> ret;
5795 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5796 ret.push_back((const MEDFileMesh *)*it);
5800 std::string MEDFileMeshMultiTS::getName() const
5802 if(_mesh_one_ts.empty())
5803 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5804 return _mesh_one_ts[0]->getName();
5807 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
5809 std::string oldName(getName());
5810 std::vector< std::pair<std::string,std::string> > v(1);
5811 v[0].first=oldName; v[0].second=newMeshName;
5815 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5818 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5820 MEDFileMesh *cur(*it);
5822 ret=cur->changeNames(modifTab) || ret;
5827 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
5829 if(_mesh_one_ts.empty())
5830 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5831 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5834 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
5837 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5838 _mesh_one_ts.resize(1);
5839 mesh1TimeStep->incrRef();
5840 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5841 _mesh_one_ts[0]=mesh1TimeStep;
5844 void MEDFileMeshMultiTS::write(med_idt fid) const
5846 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5848 (*it)->copyOptionsFrom(*this);
5853 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
5855 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5856 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5857 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5858 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5862 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
5863 {//for the moment to be improved
5864 _mesh_one_ts.resize(1);
5865 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5868 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5872 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
5875 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5878 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5879 throw INTERP_KERNEL::Exception(oss.str().c_str());
5881 MEDFileUtilities::CheckFileForRead(fileName);
5882 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5884 ParaMEDMEM::MEDCouplingMeshType meshType;
5886 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5887 loadFromFile(fileName,ms.front());
5889 catch(INTERP_KERNEL::Exception& e)
5894 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
5897 loadFromFile(fileName,mName);
5899 catch(INTERP_KERNEL::Exception& e)
5904 MEDFileMeshes *MEDFileMeshes::New()
5906 return new MEDFileMeshes;
5909 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
5911 return new MEDFileMeshes(fileName);
5914 void MEDFileMeshes::write(med_idt fid) const
5917 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5919 (*it)->copyOptionsFrom(*this);
5924 void MEDFileMeshes::write(const std::string& fileName, int mode) const
5926 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5927 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5928 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5929 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5934 int MEDFileMeshes::getNumberOfMeshes() const
5936 return _meshes.size();
5939 MEDFileMeshesIterator *MEDFileMeshes::iterator()
5941 return new MEDFileMeshesIterator(this);
5944 /** Return a borrowed reference (caller is not responsible) */
5945 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
5947 if(i<0 || i>=(int)_meshes.size())
5949 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5950 throw INTERP_KERNEL::Exception(oss.str().c_str());
5952 return _meshes[i]->getOneTimeStep();
5955 /** Return a borrowed reference (caller is not responsible) */
5956 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
5958 std::vector<std::string> ms=getMeshesNames();
5959 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5962 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5963 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5964 throw INTERP_KERNEL::Exception(oss.str().c_str());
5966 return getMeshAtPos((int)std::distance(ms.begin(),it));
5969 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
5971 std::vector<std::string> ret(_meshes.size());
5973 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5975 const MEDFileMeshMultiTS *f=(*it);
5978 ret[i]=f->getName();
5982 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5983 throw INTERP_KERNEL::Exception(oss.str().c_str());
5989 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5992 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5994 MEDFileMeshMultiTS *cur(*it);
5996 ret=cur->changeNames(modifTab) || ret;
6001 void MEDFileMeshes::resize(int newSize)
6003 _meshes.resize(newSize);
6006 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6009 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6010 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6011 elt->setOneTimeStep(mesh);
6012 _meshes.push_back(elt);
6015 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6018 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6019 if(i>=(int)_meshes.size())
6020 _meshes.resize(i+1);
6021 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6022 elt->setOneTimeStep(mesh);
6026 void MEDFileMeshes::destroyMeshAtPos(int i)
6028 if(i<0 || i>=(int)_meshes.size())
6030 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6031 throw INTERP_KERNEL::Exception(oss.str().c_str());
6033 _meshes.erase(_meshes.begin()+i);
6036 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6038 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6040 _meshes.resize(ms.size());
6041 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6042 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6045 MEDFileMeshes::MEDFileMeshes()
6049 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6052 loadFromFile(fileName);
6054 catch(INTERP_KERNEL::Exception& /*e*/)
6058 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6060 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6062 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6063 if((const MEDFileMeshMultiTS *)*it)
6064 meshes[i]=(*it)->deepCpy();
6065 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6066 ret->_meshes=meshes;
6070 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6072 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6075 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6077 std::vector<const BigMemoryObject *> ret;
6078 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6079 ret.push_back((const MEDFileMeshMultiTS *)*it);
6083 std::string MEDFileMeshes::simpleRepr() const
6085 std::ostringstream oss;
6086 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6087 simpleReprWithoutHeader(oss);
6091 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6093 int nbOfMeshes=getNumberOfMeshes();
6094 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6095 std::vector<std::string> mns=getMeshesNames();
6096 for(int i=0;i<nbOfMeshes;i++)
6097 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6100 void MEDFileMeshes::checkCoherency() const
6102 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6104 std::set<std::string> s;
6105 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6107 const MEDFileMeshMultiTS *elt=(*it);
6110 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6111 throw INTERP_KERNEL::Exception(oss.str().c_str());
6113 std::size_t sz=s.size();
6114 s.insert(std::string((*it)->getName()));
6117 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6118 throw INTERP_KERNEL::Exception(oss.str().c_str());
6123 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6128 _nb_iter=ms->getNumberOfMeshes();
6132 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6136 MEDFileMesh *MEDFileMeshesIterator::nextt()
6138 if(_iter_id<_nb_iter)
6140 MEDFileMeshes *ms(_ms);
6142 return ms->getMeshAtPos(_iter_id++);