1 // Copyright (C) 2007-2014 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 using namespace ParaMEDMEM;
37 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
39 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
43 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
45 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
46 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
48 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
49 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
50 ret+=(*it2).capacity();
52 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
53 ret+=(*it).first.capacity()+sizeof(int);
57 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildren() const
59 return std::vector<const BigMemoryObject *>();
63 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
64 * file. The first mesh in the file is loaded.
65 * \param [in] fileName - the name of MED file to read.
66 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
67 * mesh using decrRef() as it is no more needed.
68 * \throw If the file is not readable.
69 * \throw If there is no meshes in the file.
70 * \throw If the mesh in the file is of a not supported type.
72 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
74 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
77 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
78 throw INTERP_KERNEL::Exception(oss.str().c_str());
80 MEDFileUtilities::CheckFileForRead(fileName);
81 ParaMEDMEM::MEDCouplingMeshType meshType;
82 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
85 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
90 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
91 ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
92 return (MEDFileUMesh *)ret.retn();
96 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
97 ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
98 return (MEDFileCMesh *)ret.retn();
102 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
103 ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
104 return (MEDFileCurveLinearMesh *)ret.retn();
108 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
109 throw INTERP_KERNEL::Exception(oss.str().c_str());
115 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
116 * file. The mesh to load is specified by its name and numbers of a time step and an
118 * \param [in] fileName - the name of MED file to read.
119 * \param [in] mName - the name of the mesh to read.
120 * \param [in] dt - the number of a time step.
121 * \param [in] it - the number of an iteration.
122 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
123 * mesh using decrRef() as it is no more needed.
124 * \throw If the file is not readable.
125 * \throw If there is no mesh with given attributes in the file.
126 * \throw If the mesh in the file is of a not supported type.
128 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
130 MEDFileUtilities::CheckFileForRead(fileName);
131 ParaMEDMEM::MEDCouplingMeshType meshType;
132 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
135 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
140 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
141 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
142 return (MEDFileUMesh *)ret.retn();
146 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
147 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
148 return (MEDFileCMesh *)ret.retn();
152 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
153 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
154 return (MEDFileCurveLinearMesh *)ret.retn();
158 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
159 throw INTERP_KERNEL::Exception(oss.str().c_str());
165 * Writes \a this mesh into an open MED file specified by its descriptor.
166 * \param [in] fid - the MED file descriptor.
167 * \throw If the mesh name is not set.
168 * \throw If the file is open for reading only.
169 * \throw If the writing mode == 1 and the same data is present in an existing file.
171 void MEDFileMesh::write(med_idt fid) const
174 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
176 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
181 * Writes \a this mesh into a MED file specified by its name.
182 * \param [in] fileName - the MED file name.
183 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
184 * - 2 - erase; an existing file is removed.
185 * - 1 - append; same data should not be present in an existing file.
186 * - 0 - overwrite; same data present in an existing file is overwritten.
187 * \throw If the mesh name is not set.
188 * \throw If \a mode == 1 and the same data is present in an existing file.
190 void MEDFileMesh::write(const std::string& fileName, int mode) const
192 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
193 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
194 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
195 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
200 * Checks if \a this and another mesh are equal.
201 * \param [in] other - the mesh to compare with.
202 * \param [in] eps - a precision used to compare real values.
203 * \param [in,out] what - the string returning description of unequal data.
204 * \return bool - \c true if the meshes are equal, \c false, else.
206 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
208 if(_order!=other->_order)
210 what="Orders differ !";
213 if(_iteration!=other->_iteration)
215 what="Iterations differ !";
218 if(fabs(_time-other->_time)>eps)
220 what="Time values differ !";
223 if(_dt_unit!=other->_dt_unit)
225 what="Time units differ !";
228 if(_name!=other->_name)
230 what="Names differ !";
233 //univ_name has been ignored -> not a bug because it is a mutable attribute
234 if(_desc_name!=other->_desc_name)
236 what="Description names differ !";
239 if(!areGrpsEqual(other,what))
241 if(!areFamsEqual(other,what))
246 void MEDFileMesh::setName(const std::string& name)
252 * Clears redundant attributes of incorporated data arrays.
254 void MEDFileMesh::clearNonDiscrAttributes() const
259 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
261 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
263 if((*it).first==_name)
273 * Copies data on groups and families from another mesh.
274 * \param [in] other - the mesh to copy the data from.
276 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
278 _groups=other._groups;
279 _families=other._families;
284 * This method clear all the groups in the map.
285 * So this method does not operate at all on arrays.
286 * So this method can lead to orphan families.
288 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
290 void MEDFileMesh::clearGrpMap()
296 * This method clear all the families in the map.
297 * So this method does not operate at all on arrays.
298 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
300 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
302 void MEDFileMesh::clearFamMap()
308 * This method clear all the families and groups in the map.
309 * So this method does not operate at all on arrays.
310 * As all groups and families entry will be removed after
311 * 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.
313 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
315 void MEDFileMesh::clearFamGrpMaps()
322 * Returns names of families constituting a group.
323 * \param [in] name - the name of the group of interest.
324 * \return std::vector<std::string> - a sequence of names of the families.
325 * \throw If the name of a nonexistent group is specified.
327 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
329 std::string oname(name);
330 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
331 if(it==_groups.end())
333 std::vector<std::string> grps=getGroupsNames();
334 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
335 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
336 throw INTERP_KERNEL::Exception(oss.str().c_str());
342 * Returns names of families constituting some groups.
343 * \param [in] grps - a sequence of names of groups of interest.
344 * \return std::vector<std::string> - a sequence of names of the families.
345 * \throw If a name of a nonexistent group is present in \a grps.
347 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
349 std::set<std::string> fams;
350 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
352 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
353 if(it2==_groups.end())
355 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
356 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
357 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
358 throw INTERP_KERNEL::Exception(oss.str().c_str());
360 fams.insert((*it2).second.begin(),(*it2).second.end());
362 std::vector<std::string> fams2(fams.begin(),fams.end());
367 * Returns ids of families constituting a group.
368 * \param [in] name - the name of the group of interest.
369 * \return std::vector<int> - sequence of ids of the families.
370 * \throw If the name of a nonexistent group is specified.
372 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
374 std::string oname(name);
375 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
376 std::vector<std::string> grps=getGroupsNames();
377 if(it==_groups.end())
379 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
380 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
381 throw INTERP_KERNEL::Exception(oss.str().c_str());
383 return getFamiliesIds((*it).second);
387 * Sets names of families constituting a group. If data on families of this group is
388 * already present, it is overwritten. Every family in \a fams is checked, and if a
389 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
390 * \param [in] name - the name of the group of interest.
391 * \param [in] fams - a sequence of names of families constituting the group.
393 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
395 std::string oname(name);
397 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
399 std::map<std::string,int>::iterator it2=_families.find(*it1);
400 if(it2==_families.end())
406 * Sets families constituting a group. The families are specified by their ids.
407 * If a family name is not found by its id, an exception is thrown.
408 * If several families have same id, the first one in lexical order is taken.
409 * \param [in] name - the name of the group of interest.
410 * \param [in] famIds - a sequence of ids of families constituting the group.
411 * \throw If a family name is not found by its id.
413 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
415 std::string oname(name);
416 std::vector<std::string> fams(famIds.size());
418 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
420 std::string name2=getFamilyNameGivenId(*it1);
427 * Returns names of groups including a given family.
428 * \param [in] name - the name of the family of interest.
429 * \return std::vector<std::string> - a sequence of names of groups including the family.
431 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
433 std::vector<std::string> ret;
434 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
436 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
439 ret.push_back((*it1).first);
447 * Adds an existing family to groups.
448 * \param [in] famName - a name of family to add to \a grps.
449 * \param [in] grps - a sequence of group names to add the family in.
450 * \throw If a family named \a famName not yet exists.
452 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
454 std::string fName(famName);
455 const std::map<std::string,int>::const_iterator it=_families.find(fName);
456 if(it==_families.end())
458 std::vector<std::string> fams=getFamiliesNames();
459 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
460 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
461 throw INTERP_KERNEL::Exception(oss.str().c_str());
463 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
465 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
466 if(it2!=_groups.end())
467 (*it2).second.push_back(fName);
470 std::vector<std::string> grps2(1,fName);
477 * Returns names of all groups of \a this mesh.
478 * \return std::vector<std::string> - a sequence of group names.
480 std::vector<std::string> MEDFileMesh::getGroupsNames() const
482 std::vector<std::string> ret(_groups.size());
484 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
490 * Returns names of all families of \a this mesh.
491 * \return std::vector<std::string> - a sequence of family names.
493 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
495 std::vector<std::string> ret(_families.size());
497 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
503 * Changes a name of every family, included in one group only, to be same as the group name.
504 * \throw If there are families with equal names in \a this mesh.
506 void MEDFileMesh::assignFamilyNameWithGroupName()
508 std::map<std::string, std::vector<std::string> > groups(_groups);
509 std::map<std::string,int> newFams;
510 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
512 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
513 if(grps.size()==1 && groups[grps[0]].size()==1)
515 if(newFams.find(grps[0])!=newFams.end())
517 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
518 throw INTERP_KERNEL::Exception(oss.str().c_str());
520 newFams[grps[0]]=(*it).second;
521 std::vector<std::string>& grps2=groups[grps[0]];
522 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
527 if(newFams.find((*it).first)!=newFams.end())
529 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
530 throw INTERP_KERNEL::Exception(oss.str().c_str());
532 newFams[(*it).first]=(*it).second;
540 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
542 * \return the removed groups.
544 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
546 std::vector<std::string> ret;
547 std::map<std::string, std::vector<std::string> > newGrps;
548 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
550 if((*it).second.empty())
551 ret.push_back((*it).first);
553 newGrps[(*it).first]=(*it).second;
561 * Removes a group from \a this mesh.
562 * \param [in] name - the name of the group to remove.
563 * \throw If no group with such a \a name exists.
565 void MEDFileMesh::removeGroup(const std::string& name)
567 std::string oname(name);
568 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
569 std::vector<std::string> grps=getGroupsNames();
570 if(it==_groups.end())
572 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
573 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
574 throw INTERP_KERNEL::Exception(oss.str().c_str());
580 * Removes a family from \a this mesh.
581 * \param [in] name - the name of the family to remove.
582 * \throw If no family with such a \a name exists.
584 void MEDFileMesh::removeFamily(const std::string& name)
586 std::string oname(name);
587 std::map<std::string, int >::iterator it=_families.find(oname);
588 std::vector<std::string> fams=getFamiliesNames();
589 if(it==_families.end())
591 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
592 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
593 throw INTERP_KERNEL::Exception(oss.str().c_str());
596 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
598 std::vector<std::string>& v=(*it3).second;
599 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
606 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
607 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
608 * family field whatever its level. This method also suppresses the orphan families.
610 * \return - The list of removed groups names.
612 * \sa MEDFileMesh::removeOrphanFamilies.
614 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
616 removeOrphanFamilies();
617 return removeEmptyGroups();
621 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
622 * 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.
624 * \return - The list of removed families names.
625 * \sa MEDFileMesh::removeOrphanGroups.
627 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
629 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
630 std::vector<std::string> ret;
631 if(!((DataArrayInt*)allFamIdsInUse))
633 ret=getFamiliesNames();
634 _families.clear(); _groups.clear();
637 std::map<std::string,int> famMap;
638 std::map<std::string, std::vector<std::string> > grps(_groups);
639 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
641 if(allFamIdsInUse->presenceOfValue((*it).second))
642 famMap[(*it).first]=(*it).second;
645 ret.push_back((*it).first);
646 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
647 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
649 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
650 std::vector<std::string>& famv=(*it3).second;
651 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
657 { _families=famMap; _groups=grps; }
662 * Renames a group in \a this mesh.
663 * \param [in] oldName - a current name of the group to rename.
664 * \param [in] newName - a new group name.
665 * \throw If no group named \a oldName exists in \a this mesh.
666 * \throw If a group named \a newName already exists.
668 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
670 std::string oname(oldName);
671 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
672 std::vector<std::string> grps=getGroupsNames();
673 if(it==_groups.end())
675 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
676 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
677 throw INTERP_KERNEL::Exception(oss.str().c_str());
679 std::string nname(newName);
680 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
681 if(it2!=_groups.end())
683 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
684 throw INTERP_KERNEL::Exception(oss.str().c_str());
686 std::vector<std::string> cpy=(*it).second;
688 _groups[newName]=cpy;
692 * Changes an id of a family in \a this mesh.
693 * This method calls changeFamilyIdArr().
694 * \param [in] oldId - a current id of the family.
695 * \param [in] newId - a new family id.
697 void MEDFileMesh::changeFamilyId(int oldId, int newId)
699 changeFamilyIdArr(oldId,newId);
700 std::map<std::string,int> fam2;
701 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
703 if((*it).second==oldId)
704 fam2[(*it).first]=newId;
706 fam2[(*it).first]=(*it).second;
712 * Renames a family in \a this mesh.
713 * \param [in] oldName - a current name of the family to rename.
714 * \param [in] newName - a new family name.
715 * \throw If no family named \a oldName exists in \a this mesh.
716 * \throw If a family named \a newName already exists.
718 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
720 std::string oname(oldName);
721 std::map<std::string, int >::iterator it=_families.find(oname);
722 std::vector<std::string> fams=getFamiliesNames();
723 if(it==_families.end())
725 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
726 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
727 throw INTERP_KERNEL::Exception(oss.str().c_str());
729 std::string nname(newName);
730 std::map<std::string, int >::iterator it2=_families.find(nname);
731 if(it2!=_families.end())
733 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
734 throw INTERP_KERNEL::Exception(oss.str().c_str());
736 int cpy=(*it).second;
738 _families[newName]=cpy;
739 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
741 std::vector<std::string>& v=(*it3).second;
742 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
749 * Checks if \a this and another mesh contains the same families.
750 * \param [in] other - the mesh to compare with \a this one.
751 * \param [in,out] what - an unused parameter.
752 * \return bool - \c true if number of families and their ids are the same in the two
753 * meshes. Families with the id == \c 0 are not considered.
755 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
757 if(_families==other->_families)
759 std::map<std::string,int> fam0;
760 std::map<std::string,int> fam1;
761 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
763 fam0[(*it).first]=(*it).second;
764 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
766 fam1[(*it).first]=(*it).second;
771 * Checks if \a this and another mesh contains the same groups.
772 * \param [in] other - the mesh to compare with \a this one.
773 * \param [in,out] what - a string describing a difference of groups of the two meshes
774 * in case if this method returns \c false.
775 * \return bool - \c true if number of groups and families constituting them are the
776 * same in the two meshes.
778 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
780 if(_groups==other->_groups)
783 std::size_t sz=_groups.size();
784 if(sz!=other->_groups.size())
786 what="Groups differ because not same number !\n";
791 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
792 for(std::size_t i=0;i<sz && ret;i++,it1++)
794 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
795 if(it2!=other->_groups.end())
797 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
798 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
804 what="A group in first mesh exists not in other !\n";
810 std::ostringstream oss; oss << "Groups description differs :\n";
811 oss << "First group description :\n";
812 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
814 oss << " Group \"" << (*it).first << "\" on following families :\n";
815 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
816 oss << " \"" << *it2 << "\n";
818 oss << "Second group description :\n";
819 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
821 oss << " Group \"" << (*it).first << "\" on following families :\n";
822 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
823 oss << " \"" << *it2 << "\n";
831 * Checks if a group with a given name exists in \a this mesh.
832 * \param [in] groupName - the group name.
833 * \return bool - \c true the group \a groupName exists in \a this mesh.
835 bool MEDFileMesh::existsGroup(const std::string& groupName) const
837 std::string grpName(groupName);
838 return _groups.find(grpName)!=_groups.end();
842 * Checks if a family with a given id exists in \a this mesh.
843 * \param [in] famId - the family id.
844 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
846 bool MEDFileMesh::existsFamily(int famId) const
848 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
849 if((*it2).second==famId)
855 * Checks if a family with a given name exists in \a this mesh.
856 * \param [in] familyName - the family name.
857 * \return bool - \c true the family \a familyName exists in \a this mesh.
859 bool MEDFileMesh::existsFamily(const std::string& familyName) const
861 std::string fname(familyName);
862 return _families.find(fname)!=_families.end();
866 * Sets an id of a family.
867 * \param [in] familyName - the family name.
868 * \param [in] id - a new id of the family.
870 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
872 std::string fname(familyName);
876 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
878 std::string fname(familyName);
879 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
882 if((*it).first!=familyName)
884 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
885 throw INTERP_KERNEL::Exception(oss.str().c_str());
892 * Adds a family to \a this mesh.
893 * \param [in] familyName - a name of the family.
894 * \param [in] famId - an id of the family.
895 * \throw If a family with the same name or id already exists in \a this mesh.
897 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
899 std::string fname(familyName);
900 std::map<std::string,int>::const_iterator it=_families.find(fname);
901 if(it==_families.end())
903 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
904 if((*it2).second==famId)
906 std::ostringstream oss;
907 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
908 throw INTERP_KERNEL::Exception(oss.str().c_str());
910 _families[fname]=famId;
914 if((*it).second!=famId)
916 std::ostringstream oss;
917 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
918 throw INTERP_KERNEL::Exception(oss.str().c_str());
924 * Creates a group including all mesh entities of given dimension.
925 * \warning This method does \b not guarantee that the created group includes mesh
926 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
927 * present in family fields of different dimensions. To assure this, call
928 * ensureDifferentFamIdsPerLevel() \b before calling this method.
929 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
931 * \param [in] groupName - a name of the new group.
932 * \throw If a group named \a groupName already exists.
933 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
934 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
936 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
938 std::string grpName(groupName);
939 std::vector<int> levs=getNonEmptyLevelsExt();
940 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
942 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
943 oss << "Available relative ext levels are : ";
944 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
945 throw INTERP_KERNEL::Exception(oss.str().c_str());
947 if(existsGroup(groupName))
949 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
950 oss << "Already existing groups are : ";
951 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
952 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
953 throw INTERP_KERNEL::Exception(oss.str().c_str());
955 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
957 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
959 std::vector<std::string> familiesOnWholeGroup;
960 for(const int *it=famIds->begin();it!=famIds->end();it++)
963 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
965 _groups[grpName]=familiesOnWholeGroup;
969 * Ensures that given family ids do not present in family fields of dimensions different
970 * than given ones. If a family id is present in the family fields of dimensions different
971 * than the given ones, a new family is created and the whole data is updated accordingly.
972 * \param [in] famIds - a sequence of family ids to check.
973 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
974 * famIds should exclusively belong.
975 * \return bool - \c true if no modification is done in \a this mesh by this method.
977 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
979 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
980 std::vector<int> levs=getNonEmptyLevelsExt();
981 std::set<int> levs2(levs.begin(),levs.end());
982 std::vector<int> levsToTest;
983 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
984 std::set<int> famIds2(famIds.begin(),famIds.end());
987 if(!_families.empty())
988 maxFamId=getMaxFamilyId()+1;
989 std::vector<std::string> allFams=getFamiliesNames();
990 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
992 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
995 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
996 std::vector<int> tmp;
997 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
998 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1001 std::string famName=getFamilyNameGivenId(*it2);
1002 std::ostringstream oss; oss << "Family_" << maxFamId;
1003 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1004 addFamilyOnAllGroupsHaving(famName,zeName);
1005 _families[zeName]=maxFamId;
1006 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1015 * Adds a family to a given group in \a this mesh. If the group with a given name does
1016 * not exist, it is created.
1017 * \param [in] grpName - the name of the group to add the family in.
1018 * \param [in] famName - the name of the family to add to the group named \a grpName.
1019 * \throw If \a grpName or \a famName is an empty string.
1020 * \throw If no family named \a famName is present in \a this mesh.
1022 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1024 std::string grpn(grpName);
1025 std::string famn(famName);
1026 if(grpn.empty() || famn.empty())
1027 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1028 std::vector<std::string> fams=getFamiliesNames();
1029 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1031 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1032 oss << "Create this family or choose an existing one ! Existing fams are : ";
1033 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1034 throw INTERP_KERNEL::Exception(oss.str().c_str());
1036 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1037 if(it==_groups.end())
1039 _groups[grpn].push_back(famn);
1043 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1044 if(it2==(*it).second.end())
1045 (*it).second.push_back(famn);
1050 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1051 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1052 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1054 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1056 std::string famNameCpp(famName);
1057 std::string otherCpp(otherFamName);
1058 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1060 std::vector<std::string>& v=(*it).second;
1061 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1063 v.push_back(otherCpp);
1068 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1070 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1073 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1075 std::string fam(familyNameToChange);
1076 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1078 std::vector<std::string>& fams((*it).second);
1079 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1083 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1089 * Returns a name of the family having a given id or, if no such a family exists, creates
1090 * a new uniquely named family and returns its name.
1091 * \param [in] id - the id of the family whose name is required.
1092 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1093 * \return std::string - the name of the existing or the created family.
1094 * \throw If it is not possible to create a unique family name.
1096 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1098 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1102 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1103 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1104 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1105 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1107 * This method will throws an exception if it is not possible to create a unique family name.
1109 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1111 std::vector<std::string> famAlreadyExisting(families.size());
1113 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1115 if((*it).second!=id)
1117 famAlreadyExisting[ii]=(*it).first;
1126 std::ostringstream oss; oss << "Family_" << id;
1127 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1133 * Sets names and ids of all families in \a this mesh.
1134 * \param [in] info - a map of a family name to a family id.
1136 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1142 * Sets names of all groups and families constituting them in \a this mesh.
1143 * \param [in] info - a map of a group name to a vector of names of families
1144 * constituting the group.
1146 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1152 * Returns an id of the family having a given name.
1153 * \param [in] name - the name of the family of interest.
1154 * \return int - the id of the family of interest.
1155 * \throw If no family with such a \a name exists.
1157 int MEDFileMesh::getFamilyId(const std::string& name) const
1159 std::string oname(name);
1160 std::map<std::string, int>::const_iterator it=_families.find(oname);
1161 std::vector<std::string> fams=getFamiliesNames();
1162 if(it==_families.end())
1164 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1165 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1166 throw INTERP_KERNEL::Exception(oss.str().c_str());
1168 return (*it).second;
1172 * Returns ids of the families having given names.
1173 * \param [in] fams - a sequence of the names of families of interest.
1174 * \return std::vector<int> - a sequence of the ids of families of interest.
1175 * \throw If \a fams contains a name of an inexistent family.
1177 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1179 std::vector<int> ret(fams.size());
1181 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1183 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1184 if(it2==_families.end())
1186 std::vector<std::string> fams2=getFamiliesNames();
1187 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1188 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1189 throw INTERP_KERNEL::Exception(oss.str().c_str());
1191 ret[i]=(*it2).second;
1197 * Returns a maximal abs(id) of families in \a this mesh.
1198 * \return int - the maximal norm of family id.
1199 * \throw If there are no families in \a this mesh.
1201 int MEDFileMesh::getMaxAbsFamilyId() const
1203 if(_families.empty())
1204 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1205 int ret=-std::numeric_limits<int>::max();
1206 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1208 ret=std::max(std::abs((*it).second),ret);
1214 * Returns a maximal id of families in \a this mesh.
1215 * \return int - the maximal family id.
1216 * \throw If there are no families in \a this mesh.
1218 int MEDFileMesh::getMaxFamilyId() const
1220 if(_families.empty())
1221 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1222 int ret=-std::numeric_limits<int>::max();
1223 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1225 ret=std::max((*it).second,ret);
1231 * Returns a minimal id of families in \a this mesh.
1232 * \return int - the minimal family id.
1233 * \throw If there are no families in \a this mesh.
1235 int MEDFileMesh::getMinFamilyId() const
1237 if(_families.empty())
1238 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1239 int ret=std::numeric_limits<int>::max();
1240 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1242 ret=std::min((*it).second,ret);
1248 * Returns a maximal id of families in \a this mesh. Not only named families are
1249 * considered but all family fields as well.
1250 * \return int - the maximal family id.
1252 int MEDFileMesh::getTheMaxAbsFamilyId() const
1254 int m1=-std::numeric_limits<int>::max();
1255 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1256 m1=std::max(std::abs((*it).second),m1);
1257 int m2=getMaxAbsFamilyIdInArrays();
1258 return std::max(m1,m2);
1262 * Returns a maximal id of families in \a this mesh. Not only named families are
1263 * considered but all family fields as well.
1264 * \return int - the maximal family id.
1266 int MEDFileMesh::getTheMaxFamilyId() const
1268 int m1=-std::numeric_limits<int>::max();
1269 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1270 m1=std::max((*it).second,m1);
1271 int m2=getMaxFamilyIdInArrays();
1272 return std::max(m1,m2);
1276 * Returns a minimal id of families in \a this mesh. Not only named families are
1277 * considered but all family fields as well.
1278 * \return int - the minimal family id.
1280 int MEDFileMesh::getTheMinFamilyId() const
1282 int m1=std::numeric_limits<int>::max();
1283 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1284 m1=std::min((*it).second,m1);
1285 int m2=getMinFamilyIdInArrays();
1286 return std::min(m1,m2);
1290 * This method only considers the maps. The contain of family array is ignored here.
1292 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1294 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1296 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1298 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1299 v.insert((*it).second);
1300 ret->alloc((int)v.size(),1);
1301 std::copy(v.begin(),v.end(),ret->getPointer());
1306 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1308 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1310 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1312 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1313 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1314 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1316 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1317 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1318 if((DataArrayInt *) ret)
1319 ret=dv->buildUnion(ret);
1327 * true is returned if no modification has been needed. false if family
1328 * renumbering has been needed.
1330 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1332 std::vector<int> levs=getNonEmptyLevelsExt();
1333 std::set<int> allFamIds;
1334 int maxId=getMaxFamilyId()+1;
1335 std::map<int,std::vector<int> > famIdsToRenum;
1336 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1338 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1341 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1343 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1345 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1347 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1350 if(famIdsToRenum.empty())
1352 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1353 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1355 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1356 int *famIdsToChange=fam->getPointer();
1357 std::map<int,int> ren;
1358 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1360 if(allIds->presenceOfValue(*it3))
1362 std::string famName=getFamilyNameGivenId(*it3);
1363 std::vector<std::string> grps=getGroupsOnFamily(famName);
1366 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1367 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1368 addFamilyOnGrp((*it4),newFam);
1371 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1372 for(const int *id=ids->begin();id!=ids->end();id++)
1373 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1379 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1380 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1381 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1382 * This method will throw an exception if a same family id is detected in different level.
1383 * \warning This policy is the opposite of those in MED file documentation ...
1385 void MEDFileMesh::normalizeFamIdsTrio()
1387 ensureDifferentFamIdsPerLevel();
1388 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1389 std::vector<int> levs=getNonEmptyLevelsExt();
1390 std::set<int> levsS(levs.begin(),levs.end());
1391 std::set<std::string> famsFetched;
1392 std::map<std::string,int> families;
1393 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1396 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1400 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1401 std::map<int,int> ren;
1402 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1404 int nbOfTuples=fam->getNumberOfTuples();
1405 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1406 for(int *w=start;w!=start+nbOfTuples;w++)
1408 for(const int *it=tmp->begin();it!=tmp->end();it++)
1410 if(allIds->presenceOfValue(*it))
1412 std::string famName=getFamilyNameGivenId(*it);
1413 families[famName]=ren[*it];
1414 famsFetched.insert(famName);
1419 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1422 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1426 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1427 std::map<int,int> ren;
1428 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1430 int nbOfTuples=fam->getNumberOfTuples();
1431 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1432 for(int *w=start;w!=start+nbOfTuples;w++)
1434 for(const int *it=tmp->begin();it!=tmp->end();it++)
1436 if(allIds->presenceOfValue(*it))
1438 std::string famName=getFamilyNameGivenId(*it);
1439 families[famName]=ren[*it];
1440 famsFetched.insert(famName);
1445 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1447 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1450 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1451 fam->fillWithZero();
1452 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1453 if(allIds->presenceOfValue(*it3))
1455 std::string famName=getFamilyNameGivenId(*it3);
1456 families[famName]=0;
1457 famsFetched.insert(famName);
1462 std::vector<std::string> allFams=getFamiliesNames();
1463 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1464 std::set<std::string> unFetchedIds;
1465 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1466 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1467 families[*it4]=_families[*it4];
1472 * This method normalizes fam id with the following policy.
1473 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1474 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1475 * This method will throw an exception if a same family id is detected in different level.
1477 void MEDFileMesh::normalizeFamIdsMEDFile()
1479 ensureDifferentFamIdsPerLevel();
1480 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1481 std::vector<int> levs=getNonEmptyLevelsExt();
1482 std::set<int> levsS(levs.begin(),levs.end());
1483 std::set<std::string> famsFetched;
1484 std::map<std::string,int> families;
1486 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1489 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1492 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1493 std::map<int,int> ren;
1494 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1496 int nbOfTuples=fam->getNumberOfTuples();
1497 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1498 for(int *w=start;w!=start+nbOfTuples;w++)
1500 for(const int *it=tmp->begin();it!=tmp->end();it++)
1502 if(allIds->presenceOfValue(*it))
1504 std::string famName=getFamilyNameGivenId(*it);
1505 families[famName]=ren[*it];
1506 famsFetched.insert(famName);
1512 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1514 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1517 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1518 std::map<int,int> ren;
1519 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1521 int nbOfTuples=fam->getNumberOfTuples();
1522 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1523 for(int *w=start;w!=start+nbOfTuples;w++)
1525 for(const int *it=tmp->begin();it!=tmp->end();it++)
1527 if(allIds->presenceOfValue(*it))
1529 std::string famName=getFamilyNameGivenId(*it);
1530 families[famName]=ren[*it];
1531 famsFetched.insert(famName);
1537 std::vector<std::string> allFams=getFamiliesNames();
1538 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1539 std::set<std::string> unFetchedIds;
1540 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1541 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1542 families[*it4]=_families[*it4];
1547 * Returns a name of the family by its id. If there are several families having the given
1548 * id, the name first in lexical order is returned.
1549 * \param [in] id - the id of the family whose name is required.
1550 * \return std::string - the name of the found family.
1551 * \throw If no family with the given \a id exists.
1553 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1555 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1556 if((*it).second==id)
1558 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1559 throw INTERP_KERNEL::Exception(oss.str().c_str());
1563 * Returns a string describing \a this mesh. This description includes the mesh name and
1564 * the mesh description string.
1565 * \return std::string - the mesh information string.
1567 std::string MEDFileMesh::simpleRepr() const
1569 std::ostringstream oss;
1570 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1571 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1572 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1577 * Returns ids of mesh entities contained in a given group of a given dimension.
1578 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1580 * \param [in] grp - the name of the group of interest.
1581 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1582 * returned instead of ids.
1583 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1584 * numbers, if available and required, of mesh entities of the group. The caller
1585 * is to delete this array using decrRef() as it is no more needed.
1586 * \throw If the name of a nonexistent group is specified.
1587 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1589 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1591 std::vector<std::string> tmp(1);
1593 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1599 * Returns ids of mesh entities contained in given groups of a given dimension.
1600 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1602 * \param [in] grps - the names of the groups of interest.
1603 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1604 * returned instead of ids.
1605 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1606 * numbers, if available and required, of mesh entities of the groups. The caller
1607 * is to delete this array using decrRef() as it is no more needed.
1608 * \throw If the name of a nonexistent group is present in \a grps.
1609 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1611 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1613 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1614 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1618 * Returns ids of mesh entities contained in a given family of a given dimension.
1619 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1621 * \param [in] fam - the name of the family of interest.
1622 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1623 * returned instead of ids.
1624 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1625 * numbers, if available and required, of mesh entities of the family. The caller
1626 * is to delete this array using decrRef() as it is no more needed.
1627 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1629 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1631 std::vector<std::string> tmp(1);
1633 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1639 * Returns ids of nodes contained in a given group.
1640 * \param [in] grp - the name of the group of interest.
1641 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1642 * returned instead of ids.
1643 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1644 * numbers, if available and required, of nodes of the group. The caller
1645 * is to delete this array using decrRef() as it is no more needed.
1646 * \throw If the name of a nonexistent group is specified.
1647 * \throw If the family field is missing for nodes.
1649 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1651 std::vector<std::string> tmp(1);
1653 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1659 * Returns ids of nodes contained in given groups.
1660 * \param [in] grps - the names of the groups of interest.
1661 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1662 * returned instead of ids.
1663 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1664 * numbers, if available and required, of nodes of the groups. The caller
1665 * is to delete this array using decrRef() as it is no more needed.
1666 * \throw If the name of a nonexistent group is present in \a grps.
1667 * \throw If the family field is missing for nodes.
1669 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1671 return getGroupsArr(1,grps,renum);
1675 * Returns ids of nodes contained in a given group.
1676 * \param [in] grp - the name of the group of interest.
1677 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1678 * returned instead of ids.
1679 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1680 * numbers, if available and required, of nodes of the group. The caller
1681 * is to delete this array using decrRef() as it is no more needed.
1682 * \throw If the name of a nonexistent group is specified.
1683 * \throw If the family field is missing for nodes.
1685 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1687 std::vector<std::string> tmp(1);
1689 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1695 * Returns ids of nodes contained in given families.
1696 * \param [in] fams - the names of the families of interest.
1697 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1698 * returned instead of ids.
1699 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1700 * numbers, if available and required, of nodes of the families. The caller
1701 * is to delete this array using decrRef() as it is no more needed.
1702 * \throw If the family field is missing for nodes.
1704 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1706 return getFamiliesArr(1,fams,renum);
1710 * Adds groups of given dimension and creates corresponding families and family fields
1711 * given ids of mesh entities of each group.
1712 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1713 * \param [in] grps - a sequence of arrays of ids each describing a group.
1714 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1716 * \throw If names of some groups in \a grps are equal.
1717 * \throw If \a grps includes a group with an empty name.
1718 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1719 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1721 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1725 std::set<std::string> grpsName;
1726 std::vector<std::string> grpsName2(grps.size());
1729 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1731 grpsName.insert((*it)->getName());
1732 grpsName2[i]=(*it)->getName();
1734 if(grpsName.size()!=grps.size())
1735 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1736 if(grpsName.find(std::string(""))!=grpsName.end())
1737 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1738 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1739 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1740 std::vector< std::vector<int> > fidsOfGroups;
1743 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1747 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1748 for(unsigned int ii=0;ii<grps.size();ii++)
1750 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1751 grps2[ii]->setName(grps[ii]->getName());
1753 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1754 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1757 if(!_families.empty())
1758 offset=getMaxAbsFamilyId()+1;
1759 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1760 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1761 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1762 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1766 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1767 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1768 * For the moment, the two last input parameters are not taken into account.
1770 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1772 std::map<int,std::string> famInv;
1773 for(const int *it=famIds->begin();it!=famIds->end();it++)
1775 std::ostringstream oss;
1776 oss << "Family_" << (*it);
1777 _families[oss.str()]=(*it);
1778 famInv[*it]=oss.str();
1781 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1783 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1785 _groups[grpNames[i]].push_back(famInv[*it2]);
1790 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1792 std::vector<int> levs(getNonEmptyLevels());
1793 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1794 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1796 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1797 ret.insert(ret.end(),elts.begin(),elts.end());
1802 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1804 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1805 return mLev->getDistributionOfTypes();
1808 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1810 famArr->applyLin(offset>0?1:-1,offset,0);
1811 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1814 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1815 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1820 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1821 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1822 * If this method fails to find such a name it will throw an exception.
1824 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
1827 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1830 std::size_t len=nameTry.length();
1831 for(std::size_t ii=1;ii<len;ii++)
1833 std::string tmp=nameTry.substr(ii,len-ii);
1834 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1840 for(std::size_t i=1;i<30;i++)
1842 std::string tmp1(nameTry.at(0),i);
1844 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1850 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1852 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1854 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1857 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
1859 std::size_t nbOfChunks=code.size()/3;
1860 if(code.size()%3!=0)
1861 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1863 for(std::size_t i=0;i<nbOfChunks;i++)
1872 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1873 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1874 * If _name is not empty and that 'm' has the same name nothing is done.
1875 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1877 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
1880 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1885 std::string name(m->getName());
1890 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1891 oss << name << "' ! Names must match !";
1892 throw INTERP_KERNEL::Exception(oss.str().c_str());
1896 if(_desc_name.empty())
1897 _desc_name=m->getDescription();
1900 std::string name(m->getDescription());
1903 if(_desc_name!=name)
1905 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1906 oss << name << "' ! Names must match !";
1907 throw INTERP_KERNEL::Exception(oss.str().c_str());
1913 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1915 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1916 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1918 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1919 oss << " - Groups lying on this family : ";
1920 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
1921 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1922 oss << std::endl << std::endl;
1927 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1928 * file. The mesh to load is specified by its name and numbers of a time step and an
1930 * \param [in] fileName - the name of MED file to read.
1931 * \param [in] mName - the name of the mesh to read.
1932 * \param [in] dt - the number of a time step.
1933 * \param [in] it - the number of an iteration.
1934 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1935 * mesh using decrRef() as it is no more needed.
1936 * \throw If the file is not readable.
1937 * \throw If there is no mesh with given attributes in the file.
1938 * \throw If the mesh in the file is not an unstructured one.
1940 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
1942 MEDFileUtilities::CheckFileForRead(fileName);
1943 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1944 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1948 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1949 * file. The first mesh in the file is loaded.
1950 * \param [in] fileName - the name of MED file to read.
1951 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1952 * mesh using decrRef() as it is no more needed.
1953 * \throw If the file is not readable.
1954 * \throw If there is no meshes in the file.
1955 * \throw If the mesh in the file is not an unstructured one.
1957 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
1959 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1962 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1963 throw INTERP_KERNEL::Exception(oss.str().c_str());
1965 MEDFileUtilities::CheckFileForRead(fileName);
1966 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1968 ParaMEDMEM::MEDCouplingMeshType meshType;
1970 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
1971 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
1975 * Returns an empty instance of MEDFileUMesh.
1976 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1977 * mesh using decrRef() as it is no more needed.
1979 MEDFileUMesh *MEDFileUMesh::New()
1981 return new MEDFileUMesh;
1984 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
1986 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
1987 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1991 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildren() const
1993 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
1994 if((const DataArrayDouble*)_coords)
1995 ret.push_back((const DataArrayDouble*)_coords);
1996 if((const DataArrayInt *)_fam_coords)
1997 ret.push_back((const DataArrayInt *)_fam_coords);
1998 if((const DataArrayInt *)_num_coords)
1999 ret.push_back((const DataArrayInt *)_num_coords);
2000 if((const DataArrayInt *)_rev_num_coords)
2001 ret.push_back((const DataArrayInt *)_rev_num_coords);
2002 if((const DataArrayAsciiChar *)_name_coords)
2003 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2004 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2005 if((const MEDFileUMeshSplitL1*) *it)
2006 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2010 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2012 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2016 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2018 return new MEDFileUMesh;
2021 MEDFileMesh *MEDFileUMesh::deepCpy() const
2023 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2024 if((const DataArrayDouble*)_coords)
2025 ret->_coords=_coords->deepCpy();
2026 if((const DataArrayInt*)_fam_coords)
2027 ret->_fam_coords=_fam_coords->deepCpy();
2028 if((const DataArrayInt*)_num_coords)
2029 ret->_num_coords=_num_coords->deepCpy();
2030 if((const DataArrayInt*)_rev_num_coords)
2031 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2032 if((const DataArrayAsciiChar*)_name_coords)
2033 ret->_name_coords=_name_coords->deepCpy();
2035 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2037 if((const MEDFileUMeshSplitL1 *)(*it))
2038 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2044 * Checks if \a this and another mesh are equal.
2045 * \param [in] other - the mesh to compare with.
2046 * \param [in] eps - a precision used to compare real values.
2047 * \param [in,out] what - the string returning description of unequal data.
2048 * \return bool - \c true if the meshes are equal, \c false, else.
2050 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2052 if(!MEDFileMesh::isEqual(other,eps,what))
2054 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2057 what="Mesh types differ ! This is unstructured and other is NOT !";
2060 clearNonDiscrAttributes();
2061 otherC->clearNonDiscrAttributes();
2062 const DataArrayDouble *coo1=_coords;
2063 const DataArrayDouble *coo2=otherC->_coords;
2064 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2066 what="Mismatch of coordinates ! One is defined and not other !";
2071 bool ret=coo1->isEqual(*coo2,eps);
2074 what="Coords differ !";
2078 const DataArrayInt *famc1=_fam_coords;
2079 const DataArrayInt *famc2=otherC->_fam_coords;
2080 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2082 what="Mismatch of families arr on nodes ! One is defined and not other !";
2087 bool ret=famc1->isEqual(*famc2);
2090 what="Families arr on node differ !";
2094 const DataArrayInt *numc1=_num_coords;
2095 const DataArrayInt *numc2=otherC->_num_coords;
2096 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2098 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2103 bool ret=numc1->isEqual(*numc2);
2106 what="Numbering arr on node differ !";
2110 const DataArrayAsciiChar *namec1=_name_coords;
2111 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2112 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2114 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2119 bool ret=namec1->isEqual(*namec2);
2122 what="Names arr on node differ !";
2126 if(_ms.size()!=otherC->_ms.size())
2128 what="Number of levels differs !";
2131 std::size_t sz=_ms.size();
2132 for(std::size_t i=0;i<sz;i++)
2134 const MEDFileUMeshSplitL1 *s1=_ms[i];
2135 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2136 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2138 what="Mismatch of presence of sub levels !";
2143 bool ret=s1->isEqual(s2,eps,what);
2152 * Clears redundant attributes of incorporated data arrays.
2154 void MEDFileUMesh::clearNonDiscrAttributes() const
2156 MEDFileMesh::clearNonDiscrAttributes();
2157 const DataArrayDouble *coo1=_coords;
2159 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2160 const DataArrayInt *famc1=_fam_coords;
2162 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2163 const DataArrayInt *numc1=_num_coords;
2165 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2166 const DataArrayAsciiChar *namc1=_name_coords;
2168 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2169 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2171 const MEDFileUMeshSplitL1 *tmp=(*it);
2173 tmp->clearNonDiscrAttributes();
2177 void MEDFileUMesh::setName(const std::string& name)
2179 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2180 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2181 (*it)->setName(name);
2182 MEDFileMesh::setName(name);
2185 MEDFileUMesh::MEDFileUMesh()
2189 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2192 loadUMeshFromFile(fid,mName,dt,it,mrs);
2194 catch(INTERP_KERNEL::Exception& e)
2199 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2201 MEDFileUMeshL2 loaderl2;
2202 ParaMEDMEM::MEDCouplingMeshType meshType;
2205 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
2206 if(meshType!=UNSTRUCTURED)
2208 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2209 throw INTERP_KERNEL::Exception(oss.str().c_str());
2211 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2212 int lev=loaderl2.getNumberOfLevels();
2214 for(int i=0;i<lev;i++)
2216 if(!loaderl2.emptyLev(i))
2217 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2221 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2223 setName(loaderl2.getName());
2224 setDescription(loaderl2.getDescription());
2225 setUnivName(loaderl2.getUnivName());
2226 setIteration(loaderl2.getIteration());
2227 setOrder(loaderl2.getOrder());
2228 setTimeValue(loaderl2.getTime());
2229 setTimeUnit(loaderl2.getTimeUnit());
2230 _coords=loaderl2.getCoords();
2231 if(!mrs || mrs->isNodeFamilyFieldReading())
2232 _fam_coords=loaderl2.getCoordsFamily();
2233 if(!mrs || mrs->isNodeNumFieldReading())
2234 _num_coords=loaderl2.getCoordsNum();
2235 if(!mrs || mrs->isNodeNameFieldReading())
2236 _name_coords=loaderl2.getCoordsName();
2240 MEDFileUMesh::~MEDFileUMesh()
2244 void MEDFileUMesh::writeLL(med_idt fid) const
2246 const DataArrayDouble *coo=_coords;
2247 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2248 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2249 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2250 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2251 int spaceDim=coo?coo->getNumberOfComponents():0;
2252 int mdim=getMeshDimension();
2253 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2254 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2255 for(int i=0;i<spaceDim;i++)
2257 std::string info=coo->getInfoOnComponent(i);
2259 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2260 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
2261 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
2263 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2264 MEDmeshUniversalNameWr(fid,maa);
2265 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2266 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2267 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2268 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2269 (*it)->write(fid,meshName,mdim);
2270 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2274 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2275 * \return std::vector<int> - a sequence of the relative dimensions.
2277 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2279 std::vector<int> ret;
2281 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2282 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2289 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2290 * \return std::vector<int> - a sequence of the relative dimensions.
2292 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2294 std::vector<int> ret0=getNonEmptyLevels();
2295 if((const DataArrayDouble *) _coords)
2297 std::vector<int> ret(ret0.size()+1);
2299 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2305 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2307 std::vector<int> ret;
2308 const DataArrayInt *famCoo(_fam_coords);
2312 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2314 const MEDFileUMeshSplitL1 *cur(*it);
2316 if(cur->getFamilyField())
2322 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2324 std::vector<int> ret;
2325 const DataArrayInt *numCoo(_num_coords);
2329 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2331 const MEDFileUMeshSplitL1 *cur(*it);
2333 if(cur->getNumberField())
2339 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2341 std::vector<int> ret;
2342 const DataArrayAsciiChar *nameCoo(_name_coords);
2346 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2348 const MEDFileUMeshSplitL1 *cur(*it);
2350 if(cur->getNameField())
2357 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2358 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2359 * \param [in] grp - the name of the group of interest.
2360 * \return std::vector<int> - a sequence of the relative dimensions.
2362 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2364 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2365 return getFamsNonEmptyLevels(fams);
2369 * Returns all relative mesh levels (including nodes) where a given group is defined.
2370 * \param [in] grp - the name of the group of interest.
2371 * \return std::vector<int> - a sequence of the relative dimensions.
2373 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2375 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2376 return getFamsNonEmptyLevelsExt(fams);
2380 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2381 * To include nodes, call getFamNonEmptyLevelsExt() method.
2382 * \param [in] fam - the name of the family of interest.
2383 * \return std::vector<int> - a sequence of the relative dimensions.
2385 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2387 std::vector<std::string> fams(1,std::string(fam));
2388 return getFamsNonEmptyLevels(fams);
2392 * Returns all relative mesh levels (including nodes) where a given family is defined.
2393 * \param [in] fam - the name of the family of interest.
2394 * \return std::vector<int> - a sequence of the relative dimensions.
2396 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2398 std::vector<std::string> fams(1,std::string(fam));
2399 return getFamsNonEmptyLevelsExt(fams);
2403 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2404 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2405 * \param [in] grps - a sequence of names of the groups of interest.
2406 * \return std::vector<int> - a sequence of the relative dimensions.
2408 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2410 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2411 return getFamsNonEmptyLevels(fams);
2415 * Returns all relative mesh levels (including nodes) where given groups are defined.
2416 * \param [in] grps - a sequence of names of the groups of interest.
2417 * \return std::vector<int> - a sequence of the relative dimensions.
2419 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2421 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2422 return getFamsNonEmptyLevelsExt(fams);
2426 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2427 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2428 * \param [in] fams - the name of the family of interest.
2429 * \return std::vector<int> - a sequence of the relative dimensions.
2431 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2433 std::vector<int> ret;
2434 std::vector<int> levs=getNonEmptyLevels();
2435 std::vector<int> famIds=getFamiliesIds(fams);
2436 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2437 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2443 * Returns all relative mesh levels (including nodes) where given families are defined.
2444 * \param [in] fams - the names of the families of interest.
2445 * \return std::vector<int> - a sequence of the relative dimensions.
2447 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2449 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2450 const DataArrayInt *famCoords=_fam_coords;
2453 std::vector<int> famIds=getFamiliesIds(fams);
2454 if(famCoords->presenceOfValue(famIds))
2456 std::vector<int> ret(ret0.size()+1);
2458 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2466 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2467 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2468 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2471 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2473 std::vector<std::string> ret;
2474 std::vector<std::string> allGrps=getGroupsNames();
2475 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2477 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2478 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2484 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2486 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2487 if((const DataArrayInt *)_fam_coords)
2489 int val=_fam_coords->getMaxValue(tmp);
2490 ret=std::max(ret,std::abs(val));
2492 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2494 if((const MEDFileUMeshSplitL1 *)(*it))
2496 const DataArrayInt *da=(*it)->getFamilyField();
2499 int val=da->getMaxValue(tmp);
2500 ret=std::max(ret,std::abs(val));
2507 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2509 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2510 if((const DataArrayInt *)_fam_coords)
2512 int val=_fam_coords->getMaxValue(tmp);
2513 ret=std::max(ret,val);
2515 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2517 if((const MEDFileUMeshSplitL1 *)(*it))
2519 const DataArrayInt *da=(*it)->getFamilyField();
2522 int val=da->getMaxValue(tmp);
2523 ret=std::max(ret,val);
2530 int MEDFileUMesh::getMinFamilyIdInArrays() const
2532 int ret=std::numeric_limits<int>::max(),tmp=-1;
2533 if((const DataArrayInt *)_fam_coords)
2535 int val=_fam_coords->getMinValue(tmp);
2536 ret=std::min(ret,val);
2538 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2540 if((const MEDFileUMeshSplitL1 *)(*it))
2542 const DataArrayInt *da=(*it)->getFamilyField();
2545 int val=da->getMinValue(tmp);
2546 ret=std::min(ret,val);
2554 * Returns the dimension on cells in \a this mesh.
2555 * \return int - the mesh dimension.
2556 * \throw If there are no cells in this mesh.
2558 int MEDFileUMesh::getMeshDimension() const
2561 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2562 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2563 return (*it)->getMeshDimension()+lev;
2564 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2568 * Returns the space dimension of \a this mesh that is equal to number of components in
2569 * the node coordinates array.
2570 * \return int - the space dimension of \a this mesh.
2571 * \throw If the node coordinates array is not available.
2573 int MEDFileUMesh::getSpaceDimension() const
2575 const DataArrayDouble *coo=_coords;
2577 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2578 return coo->getNumberOfComponents();
2582 * Returns a string describing \a this mesh.
2583 * \return std::string - the mesh information string.
2585 std::string MEDFileUMesh::simpleRepr() const
2587 std::ostringstream oss;
2588 oss << MEDFileMesh::simpleRepr();
2589 const DataArrayDouble *coo=_coords;
2590 oss << "- The dimension of the space is ";
2591 static const char MSG1[]= "*** NO COORDS SET ***";
2592 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2594 oss << _coords->getNumberOfComponents() << std::endl;
2596 oss << MSG1 << std::endl;
2597 oss << "- Type of the mesh : UNSTRUCTURED\n";
2598 oss << "- Number of nodes : ";
2600 oss << _coords->getNumberOfTuples() << std::endl;
2602 oss << MSG1 << std::endl;
2603 std::size_t nbOfLev=_ms.size();
2604 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2605 for(std::size_t i=0;i<nbOfLev;i++)
2607 const MEDFileUMeshSplitL1 *lev=_ms[i];
2608 oss << " - Level #" << -((int) i) << " has dimension : ";
2611 oss << lev->getMeshDimension() << std::endl;
2612 lev->simpleRepr(oss);
2615 oss << MSG2 << std::endl;
2617 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2620 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2621 oss << "- Names of coordinates :" << std::endl;
2622 std::vector<std::string> vars=coo->getVarsOnComponent();
2623 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2624 oss << std::endl << "- Units of coordinates : " << std::endl;
2625 std::vector<std::string> units=coo->getUnitsOnComponent();
2626 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2628 oss << std::endl << std::endl;
2634 * Returns a full textual description of \a this mesh.
2635 * \return std::string - the string holding the mesh description.
2637 std::string MEDFileUMesh::advancedRepr() const
2639 return simpleRepr();
2643 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2644 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2645 * \return int - the number of entities.
2646 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2648 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2650 if(meshDimRelToMaxExt==1)
2652 if(!((const DataArrayDouble *)_coords))
2653 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2654 return _coords->getNumberOfTuples();
2656 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2660 * Returns the family field for mesh entities of a given dimension.
2661 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2662 * \return const DataArrayInt * - the family field. It is an array of ids of families
2663 * each mesh entity belongs to. It can be \c NULL.
2665 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2667 if(meshDimRelToMaxExt==1)
2669 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2670 return l1->getFamilyField();
2674 * Returns the optional numbers of mesh entities of a given dimension.
2675 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2676 * \return const DataArrayInt * - the array of the entity numbers.
2677 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2679 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2681 if(meshDimRelToMaxExt==1)
2683 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2684 return l1->getNumberField();
2687 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2689 if(meshDimRelToMaxExt==1)
2690 return _name_coords;
2691 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2692 return l1->getNameField();
2695 int MEDFileUMesh::getNumberOfNodes() const
2697 const DataArrayDouble *coo=_coords;
2699 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2700 return coo->getNumberOfTuples();
2703 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2705 std::size_t sz(st.getNumberOfItems());
2706 for(std::size_t i=0;i<sz;i++)
2708 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2709 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2710 if(st[i].getPflName().empty())
2711 m->computeNodeIdsAlg(nodesFetched);
2714 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
2715 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2716 m2->computeNodeIdsAlg(nodesFetched);
2722 * Returns the optional numbers of mesh entities of a given dimension transformed using
2723 * DataArrayInt::invertArrayN2O2O2N().
2724 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2725 * \return const DataArrayInt * - the array of the entity numbers transformed using
2726 * DataArrayInt::invertArrayN2O2O2N().
2727 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2729 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
2731 if(meshDimRelToMaxExt==1)
2733 if(!((const DataArrayInt *)_num_coords))
2734 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2735 return _rev_num_coords;
2737 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2738 return l1->getRevNumberField();
2742 * Returns a pointer to the node coordinates array of \a this mesh \b without
2743 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2745 DataArrayDouble *MEDFileUMesh::getCoords() const
2747 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2748 if((DataArrayDouble *)tmp)
2756 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2757 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2759 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2760 * \param [in] grp - the name of the group whose mesh entities are included in the
2762 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2763 * according to the optional numbers of entities, if available.
2764 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2765 * delete this mesh using decrRef() as it is no more needed.
2766 * \throw If the name of a nonexistent group is specified.
2767 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2769 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2771 synchronizeTinyInfoOnLeaves();
2772 std::vector<std::string> tmp(1);
2774 return getGroups(meshDimRelToMaxExt,tmp,renum);
2778 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2779 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2781 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2782 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2784 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2785 * according to the optional numbers of entities, if available.
2786 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2787 * delete this mesh using decrRef() as it is no more needed.
2788 * \throw If a name of a nonexistent group is present in \a grps.
2789 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2791 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2793 synchronizeTinyInfoOnLeaves();
2794 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2795 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2796 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2797 zeRet->setName(grps[0]);
2798 return zeRet.retn();
2802 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2803 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2805 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2806 * \param [in] fam - the name of the family whose mesh entities are included in the
2808 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2809 * according to the optional numbers of entities, if available.
2810 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2811 * delete this mesh using decrRef() as it is no more needed.
2812 * \throw If a name of a nonexistent family is present in \a grps.
2813 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2815 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2817 synchronizeTinyInfoOnLeaves();
2818 std::vector<std::string> tmp(1);
2820 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2824 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2825 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2827 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2828 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2830 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2831 * according to the optional numbers of entities, if available.
2832 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2833 * delete this mesh using decrRef() as it is no more needed.
2834 * \throw If a name of a nonexistent family is present in \a fams.
2835 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2837 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2839 synchronizeTinyInfoOnLeaves();
2840 if(meshDimRelToMaxExt==1)
2842 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2843 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2844 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2848 std::vector<int> famIds=getFamiliesIds(fams);
2849 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2850 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2852 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2854 zeRet=l1->getFamilyPart(0,0,renum);
2855 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2856 zeRet->setName(fams[0]);
2857 return zeRet.retn();
2861 * Returns ids of mesh entities contained in given families of a given dimension.
2862 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2864 * \param [in] fams - the names of the families of interest.
2865 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2866 * returned instead of ids.
2867 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2868 * numbers, if available and required, of mesh entities of the families. The caller
2869 * is to delete this array using decrRef() as it is no more needed.
2870 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2872 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2874 std::vector<int> famIds=getFamiliesIds(fams);
2875 if(meshDimRelToMaxExt==1)
2877 if((const DataArrayInt *)_fam_coords)
2879 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2881 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2883 da=_fam_coords->getIdsEqualList(0,0);
2885 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2890 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2892 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2894 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2896 return l1->getFamilyPartArr(0,0,renum);
2900 * Returns a MEDCouplingUMesh of a given relative dimension.
2901 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2902 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2903 * To build a valid MEDCouplingUMesh from the returned one in this case,
2904 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2905 * \param [in] meshDimRelToMax - the relative dimension of interest.
2906 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2907 * optional numbers of mesh entities.
2908 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2909 * delete using decrRef() as it is no more needed.
2910 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2911 * \sa getGenMeshAtLevel()
2913 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
2915 synchronizeTinyInfoOnLeaves();
2916 if(meshDimRelToMaxExt==1)
2920 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2921 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2922 umesh->setCoords(cc);
2923 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2924 umesh->setName(getName());
2928 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2929 return l1->getWholeMesh(renum);
2933 * Returns a MEDCouplingUMesh of a given relative dimension.
2934 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2935 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2936 * To build a valid MEDCouplingUMesh from the returned one in this case,
2937 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2938 * \param [in] meshDimRelToMax - the relative dimension of interest.
2939 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2940 * optional numbers of mesh entities.
2941 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2942 * delete using decrRef() as it is no more needed.
2943 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2944 * \sa getMeshAtLevel()
2946 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
2948 return getMeshAtLevel(meshDimRelToMax,renum);
2951 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
2953 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
2954 return l1->getDistributionOfTypes();
2958 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2959 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2960 * optional numbers of mesh entities.
2961 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2962 * delete using decrRef() as it is no more needed.
2963 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2965 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
2967 return getMeshAtLevel(0,renum);
2971 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2972 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2973 * optional numbers of mesh entities.
2974 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2975 * delete using decrRef() as it is no more needed.
2976 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2978 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
2980 return getMeshAtLevel(-1,renum);
2984 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2985 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2986 * optional numbers of mesh entities.
2987 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2988 * delete using decrRef() as it is no more needed.
2989 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
2991 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
2993 return getMeshAtLevel(-2,renum);
2997 * Returns a MEDCouplingUMesh of a relative dimension == -3.
2998 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2999 * optional numbers of mesh entities.
3000 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3001 * delete using decrRef() as it is no more needed.
3002 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3004 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3006 return getMeshAtLevel(-3,renum);
3010 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3011 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3012 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3013 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3015 void MEDFileUMesh::forceComputationOfParts() const
3017 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3019 const MEDFileUMeshSplitL1 *elt(*it);
3021 elt->forceComputationOfParts();
3026 * This method returns a vector of mesh parts containing each exactly one geometric type.
3027 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3028 * This method is only for memory aware users.
3029 * The returned pointers are **NOT** new object pointer. No need to mange them.
3031 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3033 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3034 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3038 * This method returns the part of \a this having the geometric type \a gt.
3039 * If such part is not existing an exception will be thrown.
3040 * The returned pointer is **NOT** new object pointer. No need to mange it.
3042 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3044 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3045 int lev=(int)cm.getDimension()-getMeshDimension();
3046 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3047 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3051 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3052 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3054 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3056 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3057 return sp->getGeoTypes();
3061 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3062 * \param [in] gt - the geometric type for which the family field is asked.
3063 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3064 * delete using decrRef() as it is no more needed.
3065 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3067 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3069 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3070 int lev=(int)cm.getDimension()-getMeshDimension();
3071 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3072 return sp->extractFamilyFieldOnGeoType(gt);
3076 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3077 * \param [in] gt - the geometric type for which the number field is asked.
3078 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3079 * delete using decrRef() as it is no more needed.
3080 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3082 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3084 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3085 int lev=(int)cm.getDimension()-getMeshDimension();
3086 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3087 return sp->extractNumberFieldOnGeoType(gt);
3090 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3092 if(meshDimRelToMaxExt==1)
3093 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3094 if(meshDimRelToMaxExt>1)
3095 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3096 int tracucedRk=-meshDimRelToMaxExt;
3097 if(tracucedRk>=(int)_ms.size())
3098 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3099 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3100 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3101 return _ms[tracucedRk];
3104 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3106 if(meshDimRelToMaxExt==1)
3107 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3108 if(meshDimRelToMaxExt>1)
3109 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3110 int tracucedRk=-meshDimRelToMaxExt;
3111 if(tracucedRk>=(int)_ms.size())
3112 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3113 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3114 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3115 return _ms[tracucedRk];
3118 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3120 if(-meshDimRelToMax>=(int)_ms.size())
3121 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3123 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3125 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3127 int ref=(*it)->getMeshDimension();
3128 if(ref+i!=meshDim-meshDimRelToMax)
3129 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3135 * Sets the node coordinates array of \a this mesh.
3136 * \param [in] coords - the new node coordinates array.
3137 * \throw If \a coords == \c NULL.
3139 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3142 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3143 coords->checkAllocated();
3144 int nbOfTuples=coords->getNumberOfTuples();
3147 _fam_coords=DataArrayInt::New();
3148 _fam_coords->alloc(nbOfTuples,1);
3149 _fam_coords->fillWithZero();
3150 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3151 if((MEDFileUMeshSplitL1 *)(*it))
3152 (*it)->setCoords(coords);
3156 * Removes all groups of a given dimension in \a this mesh.
3157 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3158 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3160 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3162 if(meshDimRelToMaxExt==1)
3164 if((DataArrayInt *)_fam_coords)
3165 _fam_coords->fillWithZero();
3168 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3169 l1->eraseFamilyField();
3174 * Removes all families with ids not present in the family fields of \a this mesh.
3176 void MEDFileUMesh::optimizeFamilies()
3178 std::vector<int> levs=getNonEmptyLevelsExt();
3179 std::set<int> allFamsIds;
3180 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3182 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3183 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3185 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3188 std::set<std::string> famNamesToKill;
3189 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3191 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3192 famNamesToKill.insert((*it).first);
3194 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3195 _families.erase(*it);
3196 std::vector<std::string> grpNamesToKill;
3197 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3199 std::vector<std::string> tmp;
3200 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3202 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3203 tmp.push_back(*it2);
3208 tmp.push_back((*it).first);
3210 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3214 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3216 std::vector<int> levs=getNonEmptyLevels();
3217 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3218 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3219 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3220 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3221 int nbNodes=m0->getNumberOfNodes();
3222 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3223 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3224 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3225 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3226 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3227 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3228 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3229 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3230 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3231 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3232 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3233 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3234 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3235 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3236 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3237 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3238 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3239 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3240 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3241 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3242 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3243 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3244 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3245 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3246 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3247 m0->setCoords(tmp0->getCoords());
3248 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3249 m1->setCoords(m0->getCoords());
3250 _coords=m0->getCoords(); _coords->incrRef();
3251 // duplication of cells in group 'grpNameM1' on level -1
3252 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3253 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3254 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3255 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3256 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3258 newm1->setName(getName());
3259 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3261 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3262 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3263 newFam->alloc(newm1->getNumberOfCells(),1);
3264 int idd=getMaxFamilyId()+1;
3265 int globStart=0,start=0,end,globEnd;
3266 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3267 for(int i=0;i<nbOfChunks;i++)
3269 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3270 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3272 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3273 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3274 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3279 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3283 newm1->setCoords(getCoords());
3284 setMeshAtLevel(-1,newm1);
3285 setFamilyFieldArr(-1,newFam);
3286 std::string grpName2(grpNameM1); grpName2+="_dup";
3287 addFamily(grpName2,idd);
3288 addFamilyOnGrp(grpName2,grpName2);
3293 int newNbOfNodes=getCoords()->getNumberOfTuples();
3294 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3295 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3296 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3299 nodesDuplicated=nodeIdsToDuplicate.retn();
3300 cellsModified=cellsToModifyConn0.retn();
3301 cellsNotModified=cellsToModifyConn1.retn();
3305 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3306 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3307 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3309 * \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.
3310 * 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.
3312 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3314 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3315 std::vector<int> levs=getNonEmptyLevels();
3317 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3318 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3321 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3323 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3324 std::vector<int> code1=m->getDistributionOfTypes();
3325 end=PutInThirdComponentOfCodeOffset(code1,start);
3326 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3327 bool hasChanged=m->unPolyze();
3328 DataArrayInt *fake=0;
3329 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3330 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3332 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3335 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3336 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3338 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3339 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3340 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3341 setMeshAtLevel(*it,m);
3342 std::vector<int> code2=m->getDistributionOfTypes();
3343 end=PutInThirdComponentOfCodeOffset(code2,start);
3344 newCode.insert(newCode.end(),code2.begin(),code2.end());
3346 if(o2nCellsPart2->isIdentity())
3350 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3351 setFamilyFieldArr(*it,newFamField);
3355 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3356 setRenumFieldArr(*it,newNumField);
3361 newCode.insert(newCode.end(),code1.begin(),code1.end());
3367 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3368 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3369 o2nRenumCell=o2nRenumCellRet.retn();
3374 struct MEDLoaderAccVisit1
3376 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3377 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3378 int _new_nb_of_nodes;
3382 * 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.
3383 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3384 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3385 * -1 values in returned array means that the corresponding old node is no more used.
3387 * \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
3388 * is modified in \a this.
3389 * \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
3392 DataArrayInt *MEDFileUMesh::zipCoords()
3394 const DataArrayDouble *coo=getCoords();
3396 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3397 int nbOfNodes=coo->getNumberOfTuples();
3398 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3399 std::vector<int> neLevs=getNonEmptyLevels();
3400 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3402 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3403 m->computeNodeIdsAlg(nodeIdsInUse);
3405 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3406 if(nbrOfNodesInUse==nbOfNodes)
3408 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3409 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3410 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3411 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3412 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3413 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3414 if((const DataArrayInt *)_fam_coords)
3415 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3416 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3417 if((const DataArrayInt *)_num_coords)
3418 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3419 if((const DataArrayAsciiChar *)_name_coords)
3420 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3421 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3422 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3424 if((MEDFileUMeshSplitL1*)*it)
3425 (*it)->renumberNodesInConn(ret->begin());
3431 * Adds a group of nodes to \a this mesh.
3432 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3433 * The ids should be sorted and different each other (MED file norm).
3434 * \throw If the node coordinates array is not set.
3435 * \throw If \a ids == \c NULL.
3436 * \throw If \a ids->getName() == "".
3437 * \throw If \a ids does not respect the MED file norm.
3438 * \throw If a group with name \a ids->getName() already exists.
3440 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
3442 const DataArrayDouble *coords=_coords;
3444 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3445 int nbOfNodes=coords->getNumberOfTuples();
3446 if(!((DataArrayInt *)_fam_coords))
3447 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3449 addGroupUnderground(true,ids,_fam_coords);
3453 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3454 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3455 * The ids should be sorted and different each other (MED file norm).
3456 * \throw If the node coordinates array is not set.
3457 * \throw If \a ids == \c NULL.
3458 * \throw If \a ids->getName() == "".
3459 * \throw If \a ids does not respect the MED file norm.
3460 * \throw If a group with name \a ids->getName() already exists.
3462 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
3464 std::vector<int> levs=getNonEmptyLevelsExt();
3465 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3467 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3468 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3470 if(meshDimRelToMaxExt==1)
3471 { addNodeGroup(ids); return ; }
3472 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3473 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3474 addGroupUnderground(false,ids,fam);
3478 * \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).
3479 * \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)
3481 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
3484 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3485 std::string grpName(ids->getName());
3487 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3488 ids->checkStrictlyMonotonic(true);
3489 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3490 std::vector<std::string> grpsNames=getGroupsNames();
3491 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3493 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3494 throw INTERP_KERNEL::Exception(oss.str().c_str());
3496 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3497 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3498 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3499 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3500 std::vector<int> familyIds;
3501 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3502 int maxVal=getTheMaxAbsFamilyId()+1;
3503 std::map<std::string,int> families(_families);
3504 std::map<std::string, std::vector<std::string> > groups(_groups);
3505 std::vector<std::string> fams;
3506 bool created(false);
3507 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3509 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3510 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3511 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3512 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3515 bool isFamPresent=false;
3516 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3517 isFamPresent=(*itl)->presenceOfValue(*famId);
3519 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3522 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3523 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3524 fams.push_back(locFamName);
3525 if(existsFamily(*famId))
3527 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3528 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3531 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3535 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3536 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3537 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3538 if(existsFamily(*famId))
3540 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3541 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3546 for(std::size_t i=0;i<familyIds.size();i++)
3548 DataArrayInt *da=idsPerfamiliyIds[i];
3549 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3553 _groups[grpName]=fams;
3557 * Changes a name of a family specified by its id.
3558 * \param [in] id - the id of the family of interest.
3559 * \param [in] newFamName - the new family name.
3560 * \throw If no family with the given \a id exists.
3562 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
3564 std::string oldName=getFamilyNameGivenId(id);
3565 _families.erase(oldName);
3566 _families[newFamName]=id;
3570 * Removes a mesh of a given dimension.
3571 * \param [in] meshDimRelToMax - the relative dimension of interest.
3572 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3574 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
3576 std::vector<int> levSet=getNonEmptyLevels();
3577 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3578 if(it==levSet.end())
3579 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3580 int pos=(-meshDimRelToMax);
3585 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
3586 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3587 * \param [in] m - the new mesh to set.
3588 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3590 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3591 * another node coordinates array.
3592 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3593 * to the existing meshes of other levels of \a this mesh.
3595 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
3597 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
3598 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3602 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3603 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3604 * \param [in] m - the new mesh to set.
3605 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3606 * writing \a this mesh in a MED file.
3607 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3609 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3610 * another node coordinates array.
3611 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3612 * to the existing meshes of other levels of \a this mesh.
3614 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
3616 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
3617 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3620 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
3622 dealWithTinyInfo(m);
3623 std::vector<int> levSet=getNonEmptyLevels();
3624 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3626 if((DataArrayDouble *)_coords==0)
3628 DataArrayDouble *c=m->getCoords();
3633 if(m->getCoords()!=_coords)
3634 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3635 int sz=(-meshDimRelToMax)+1;
3636 if(sz>=(int)_ms.size())
3638 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3642 return _ms[-meshDimRelToMax];
3646 * This method allows to set at once the content of different levels in \a this.
3647 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3649 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3650 * \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.
3651 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3653 * \throw If \a there is a null pointer in \a ms.
3654 * \sa MEDFileUMesh::setMeshAtLevel
3656 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3660 const MEDCouplingUMesh *mRef=ms[0];
3662 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3663 std::string name(mRef->getName());
3664 const DataArrayDouble *coo(mRef->getCoords());
3667 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3669 const MEDCouplingUMesh *cur(*it);
3671 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3672 if(coo!=cur->getCoords())
3673 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3674 int mdim=cur->getMeshDimension();
3675 zeDim=std::max(zeDim,mdim);
3676 if(s.find(mdim)!=s.end())
3677 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3679 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3681 int mdim=(*it)->getMeshDimension();
3682 setName((*it)->getName());
3683 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3689 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3690 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3691 * The given meshes must share the same node coordinates array.
3692 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3693 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3694 * create in \a this mesh.
3695 * \throw If \a ms is empty.
3696 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3697 * to the existing meshes of other levels of \a this mesh.
3698 * \throw If the meshes in \a ms do not share the same node coordinates array.
3699 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3700 * of the given meshes.
3701 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3702 * \throw If names of some meshes in \a ms are equal.
3703 * \throw If \a ms includes a mesh with an empty name.
3705 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3708 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3709 int sz=(-meshDimRelToMax)+1;
3710 if(sz>=(int)_ms.size())
3712 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3713 DataArrayDouble *coo=checkMultiMesh(ms);
3714 if((DataArrayDouble *)_coords==0)
3720 if((DataArrayDouble *)_coords!=coo)
3721 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3722 std::vector<DataArrayInt *> corr;
3723 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3724 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3725 setMeshAtLevel(meshDimRelToMax,m,renum);
3726 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3727 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3731 * Creates groups at a given level in \a this mesh from a sequence of
3732 * meshes each representing a group.
3733 * The given meshes must share the same node coordinates array.
3734 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3735 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3736 * create in \a this mesh.
3737 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3739 * \throw If \a ms is empty.
3740 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3741 * to the existing meshes of other levels of \a this mesh.
3742 * \throw If the meshes in \a ms do not share the same node coordinates array.
3743 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3744 * of the given meshes.
3745 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3746 * \throw If names of some meshes in \a ms are equal.
3747 * \throw If \a ms includes a mesh with an empty name.
3749 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3752 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3753 int sz=(-meshDimRelToMax)+1;
3754 if(sz>=(int)_ms.size())
3756 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3757 DataArrayDouble *coo=checkMultiMesh(ms);
3758 if((DataArrayDouble *)_coords==0)
3764 if((DataArrayDouble *)_coords!=coo)
3765 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3766 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3767 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3769 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3771 DataArrayInt *arr=0;
3772 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3776 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3777 throw INTERP_KERNEL::Exception(oss.str().c_str());
3780 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3781 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3784 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
3786 const DataArrayDouble *ret=ms[0]->getCoords();
3787 int mdim=ms[0]->getMeshDimension();
3788 for(unsigned int i=1;i<ms.size();i++)
3790 ms[i]->checkCoherency();
3791 if(ms[i]->getCoords()!=ret)
3792 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3793 if(ms[i]->getMeshDimension()!=mdim)
3794 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3796 return const_cast<DataArrayDouble *>(ret);
3800 * Sets the family field of a given relative dimension.
3801 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3802 * the family field is set.
3803 * \param [in] famArr - the array of the family field.
3804 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3805 * \throw If \a famArr has an invalid size.
3807 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
3809 if(meshDimRelToMaxExt==1)
3816 DataArrayDouble *coo(_coords);
3818 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3819 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3824 if(meshDimRelToMaxExt>1)
3825 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3826 int traducedRk=-meshDimRelToMaxExt;
3827 if(traducedRk>=(int)_ms.size())
3828 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3829 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3830 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3831 return _ms[traducedRk]->setFamilyArr(famArr);
3835 * Sets the optional numbers of mesh entities of a given dimension.
3836 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3837 * \param [in] renumArr - the array of the numbers.
3838 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3839 * \throw If \a renumArr has an invalid size.
3841 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
3843 if(meshDimRelToMaxExt==1)
3851 DataArrayDouble *coo(_coords);
3853 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3854 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3855 renumArr->incrRef();
3856 _num_coords=renumArr;
3860 if(meshDimRelToMaxExt>1)
3861 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3862 int traducedRk=-meshDimRelToMaxExt;
3863 if(traducedRk>=(int)_ms.size())
3864 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3865 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3866 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3867 return _ms[traducedRk]->setRenumArr(renumArr);
3871 * Sets the optional names of mesh entities of a given dimension.
3872 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3873 * \param [in] nameArr - the array of the names.
3874 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3875 * \throw If \a nameArr has an invalid size.
3877 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
3879 if(meshDimRelToMaxExt==1)
3886 DataArrayDouble *coo(_coords);
3888 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3889 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3891 _name_coords=nameArr;
3894 if(meshDimRelToMaxExt>1)
3895 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3896 int traducedRk=-meshDimRelToMaxExt;
3897 if(traducedRk>=(int)_ms.size())
3898 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3899 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3900 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3901 return _ms[traducedRk]->setNameArr(nameArr);
3904 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3906 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3907 if((const MEDFileUMeshSplitL1 *)(*it))
3908 (*it)->synchronizeTinyInfo(*this);
3912 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3914 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
3916 DataArrayInt *arr=_fam_coords;
3918 arr->changeValue(oldId,newId);
3919 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3921 MEDFileUMeshSplitL1 *sp=(*it);
3924 sp->changeFamilyIdArr(oldId,newId);
3929 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3931 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3932 const DataArrayInt *da(_fam_coords);
3934 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3935 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3937 const MEDFileUMeshSplitL1 *elt(*it);
3940 da=elt->getFamilyField();
3942 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3948 void MEDFileUMesh::computeRevNum() const
3950 if((const DataArrayInt *)_num_coords)
3953 int maxValue=_num_coords->getMaxValue(pos);
3954 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3958 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
3960 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
3963 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildren() const
3965 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
3966 if((const DataArrayInt *)_fam_nodes)
3967 ret.push_back((const DataArrayInt *)_fam_nodes);
3968 if((const DataArrayInt *)_num_nodes)
3969 ret.push_back((const DataArrayInt *)_num_nodes);
3970 if((const DataArrayInt *)_fam_cells)
3971 ret.push_back((const DataArrayInt *)_fam_cells);
3972 if((const DataArrayInt *)_num_cells)
3973 ret.push_back((const DataArrayInt *)_num_nodes);
3974 if((const DataArrayInt *)_rev_num_nodes)
3975 ret.push_back((const DataArrayInt *)_rev_num_nodes);
3976 if((const DataArrayInt *)_rev_num_cells)
3977 ret.push_back((const DataArrayInt *)_rev_num_cells);
3981 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
3983 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3984 if((const DataArrayInt *)_fam_nodes)
3986 int val=_fam_nodes->getMaxValue(tmp);
3987 ret=std::max(ret,std::abs(val));
3989 if((const DataArrayInt *)_fam_cells)
3991 int val=_fam_cells->getMaxValue(tmp);
3992 ret=std::max(ret,std::abs(val));
3997 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
3999 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4000 if((const DataArrayInt *)_fam_nodes)
4002 int val=_fam_nodes->getMaxValue(tmp);
4003 ret=std::max(ret,val);
4005 if((const DataArrayInt *)_fam_cells)
4007 int val=_fam_cells->getMaxValue(tmp);
4008 ret=std::max(ret,val);
4013 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4015 int ret=std::numeric_limits<int>::max(),tmp=-1;
4016 if((const DataArrayInt *)_fam_nodes)
4018 int val=_fam_nodes->getMinValue(tmp);
4019 ret=std::min(ret,val);
4021 if((const DataArrayInt *)_fam_cells)
4023 int val=_fam_cells->getMinValue(tmp);
4024 ret=std::min(ret,val);
4029 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4031 if(!MEDFileMesh::isEqual(other,eps,what))
4033 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4036 what="Mesh types differ ! This is structured and other is NOT !";
4039 const DataArrayInt *famc1=_fam_nodes;
4040 const DataArrayInt *famc2=otherC->_fam_nodes;
4041 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4043 what="Mismatch of families arr on nodes ! One is defined and not other !";
4048 bool ret=famc1->isEqual(*famc2);
4051 what="Families arr on nodes differ !";
4056 famc2=otherC->_fam_cells;
4057 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4059 what="Mismatch of families arr on cells ! One is defined and not other !";
4064 bool ret=famc1->isEqual(*famc2);
4067 what="Families arr on cells differ !";
4072 famc2=otherC->_num_nodes;
4073 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4075 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4080 bool ret=famc1->isEqual(*famc2);
4083 what="Numbering arr on nodes differ !";
4088 famc2=otherC->_num_cells;
4089 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4091 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4096 bool ret=famc1->isEqual(*famc2);
4099 what="Numbering arr on cells differ !";
4103 const DataArrayAsciiChar *d1=_names_cells;
4104 const DataArrayAsciiChar *d2=otherC->_names_cells;
4105 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4107 what="Mismatch of naming arr on cells ! One is defined and not other !";
4112 bool ret=d1->isEqual(*d2);
4115 what="Naming arr on cells differ !";
4120 d2=otherC->_names_nodes;
4121 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4123 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4128 bool ret=d1->isEqual(*d2);
4131 what="Naming arr on nodes differ !";
4138 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4140 MEDFileMesh::clearNonDiscrAttributes();
4141 const DataArrayInt *tmp=_fam_nodes;
4143 (const_cast<DataArrayInt *>(tmp))->setName("");
4146 (const_cast<DataArrayInt *>(tmp))->setName("");
4149 (const_cast<DataArrayInt *>(tmp))->setName("");
4152 (const_cast<DataArrayInt *>(tmp))->setName("");
4156 * Returns ids of mesh entities contained in given families of a given dimension.
4157 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4159 * \param [in] fams - the names of the families of interest.
4160 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4161 * returned instead of ids.
4162 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4163 * numbers, if available and required, of mesh entities of the families. The caller
4164 * is to delete this array using decrRef() as it is no more needed.
4165 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4167 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4169 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4170 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
4171 std::vector<int> famIds=getFamiliesIds(fams);
4172 if(meshDimRelToMaxExt==1)
4174 if((const DataArrayInt *)_fam_nodes)
4176 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4178 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4180 da=_fam_nodes->getIdsEqualList(0,0);
4182 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4187 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4191 if((const DataArrayInt *)_fam_cells)
4193 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4195 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4197 da=_fam_cells->getIdsEqualList(0,0);
4199 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4204 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4209 * Sets the family field of a given relative dimension.
4210 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4211 * the family field is set.
4212 * \param [in] famArr - the array of the family field.
4213 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4214 * \throw If \a famArr has an invalid size.
4215 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4217 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4219 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4220 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4221 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4223 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4224 if(meshDimRelToMaxExt==0)
4226 int nbCells=mesh->getNumberOfCells();
4227 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4232 int nbNodes=mesh->getNumberOfNodes();
4233 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4241 * Sets the optional numbers of mesh entities of a given dimension.
4242 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4243 * \param [in] renumArr - the array of the numbers.
4244 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4245 * \throw If \a renumArr has an invalid size.
4246 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4248 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4250 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4251 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4252 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4254 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4255 if(meshDimRelToMaxExt==0)
4257 int nbCells=mesh->getNumberOfCells();
4258 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4259 _num_cells=renumArr;
4263 int nbNodes=mesh->getNumberOfNodes();
4264 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4265 _num_nodes=renumArr;
4268 renumArr->incrRef();
4272 * Sets the optional names of mesh entities of a given dimension.
4273 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4274 * \param [in] nameArr - the array of the names.
4275 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4276 * \throw If \a nameArr has an invalid size.
4278 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4280 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4281 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
4282 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4284 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4285 if(meshDimRelToMaxExt==0)
4287 int nbCells=mesh->getNumberOfCells();
4288 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4289 _names_cells=nameArr;
4293 int nbNodes=mesh->getNumberOfNodes();
4294 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4295 _names_nodes=nameArr;
4302 * Returns the family field for mesh entities of a given dimension.
4303 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4304 * \return const DataArrayInt * - the family field. It is an array of ids of families
4305 * each mesh entity belongs to. It can be \c NULL.
4306 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4308 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
4310 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4311 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
4312 if(meshDimRelToMaxExt==0)
4319 * Returns the optional numbers of mesh entities of a given dimension.
4320 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4321 * \return const DataArrayInt * - the array of the entity numbers.
4322 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4323 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4325 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
4327 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4328 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
4329 if(meshDimRelToMaxExt==0)
4336 * Returns the optional numbers of mesh entities of a given dimension transformed using
4337 * DataArrayInt::invertArrayN2O2O2N().
4338 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4339 * \return const DataArrayInt * - the array of the entity numbers transformed using
4340 * DataArrayInt::invertArrayN2O2O2N().
4341 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4342 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4344 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
4346 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4347 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4348 if(meshDimRelToMaxExt==0)
4350 if((const DataArrayInt *)_num_cells)
4353 int maxValue=_num_cells->getMaxValue(pos);
4354 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4355 return _rev_num_cells;
4358 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4362 if((const DataArrayInt *)_num_nodes)
4365 int maxValue=_num_nodes->getMaxValue(pos);
4366 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4367 return _rev_num_nodes;
4370 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4374 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
4376 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4377 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
4378 if(meshDimRelToMaxExt==0)
4379 return _names_cells;
4381 return _names_nodes;
4385 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4386 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4388 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4390 std::vector<int> ret(1);
4395 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4396 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4398 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4400 std::vector<int> ret(2);
4406 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4408 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4410 std::vector<int> ret;
4411 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells);
4420 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4422 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4424 std::vector<int> ret;
4425 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells);
4434 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4436 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4438 std::vector<int> ret;
4439 const DataArrayAsciiChar *namesCells(_names_cells);
4446 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4448 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4450 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4454 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
4456 DataArrayInt *arr=_fam_nodes;
4458 arr->changeValue(oldId,newId);
4461 arr->changeValue(oldId,newId);
4464 void MEDFileStructuredMesh::deepCpyAttributes()
4466 if((const DataArrayInt*)_fam_nodes)
4467 _fam_nodes=_fam_nodes->deepCpy();
4468 if((const DataArrayInt*)_num_nodes)
4469 _num_nodes=_num_nodes->deepCpy();
4470 if((const DataArrayInt*)_fam_cells)
4471 _fam_cells=_fam_cells->deepCpy();
4472 if((const DataArrayInt*)_num_cells)
4473 _num_cells=_num_cells->deepCpy();
4474 if((const DataArrayInt*)_rev_num_nodes)
4475 _rev_num_nodes=_rev_num_nodes->deepCpy();
4476 if((const DataArrayInt*)_rev_num_cells)
4477 _rev_num_cells=_rev_num_cells->deepCpy();
4481 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4483 * \return a pointer to cartesian mesh that need to be managed by the caller.
4484 * \warning the returned pointer has to be managed by the caller.
4488 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4489 * \param [in] meshDimRelToMax - it must be \c 0.
4490 * \param [in] renum - it must be \c false.
4491 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4492 * delete using decrRef() as it is no more needed.
4494 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
4497 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4498 if(meshDimRelToMax!=0)
4499 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4500 const MEDCouplingStructuredMesh *m=getStructuredMesh();
4503 return const_cast<MEDCouplingStructuredMesh *>(m);
4507 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4508 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4509 * \return int - the number of entities.
4510 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4512 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
4514 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4515 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
4516 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4518 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4519 if(meshDimRelToMaxExt==0)
4520 return cmesh->getNumberOfCells();
4522 return cmesh->getNumberOfNodes();
4525 int MEDFileStructuredMesh::getNumberOfNodes() const
4527 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4529 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4530 return cmesh->getNumberOfNodes();
4533 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
4535 if(meshDimRelToMax!=0)
4536 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory !");
4537 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4538 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
4542 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
4544 if(st.getNumberOfItems()!=1)
4545 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 !");
4546 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4547 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4548 if(getNumberOfNodes()!=(int)nodesFetched.size())
4549 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4550 if(st[0].getPflName().empty())
4552 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4555 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
4556 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4557 int sz(nodesFetched.size());
4558 for(const int *work=arr->begin();work!=arr->end();work++)
4560 std::vector<int> conn;
4561 cmesh->getNodeIdsOfCell(*work,conn);
4562 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4563 if(*it>=0 && *it<sz)
4564 nodesFetched[*it]=true;
4566 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4570 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
4572 med_geometry_type geoTypeReq=MED_NONE;
4576 geoTypeReq=MED_HEXA8;
4579 geoTypeReq=MED_QUAD4;
4582 geoTypeReq=MED_SEG2;
4585 geoTypeReq=MED_POINT1;
4588 throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
4593 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4595 setName(strm->getName());
4596 setDescription(strm->getDescription());
4597 setUnivName(strm->getUnivName());
4598 setIteration(strm->getIteration());
4599 setOrder(strm->getOrder());
4600 setTimeValue(strm->getTime());
4601 setTimeUnit(strm->getTimeUnit());
4602 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4603 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4604 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4607 if(!mrs || mrs->isNodeFamilyFieldReading())
4609 _fam_nodes=DataArrayInt::New();
4610 _fam_nodes->alloc(nbOfElt,1);
4611 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4614 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4617 if(!mrs || mrs->isNodeNumFieldReading())
4619 _num_nodes=DataArrayInt::New();
4620 _num_nodes->alloc(nbOfElt,1);
4621 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4624 int meshDim=getStructuredMesh()->getMeshDimension();
4625 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4626 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4629 if(!mrs || mrs->isCellFamilyFieldReading())
4631 _fam_cells=DataArrayInt::New();
4632 _fam_cells->alloc(nbOfElt,1);
4633 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
4636 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4639 if(!mrs || mrs->isCellNumFieldReading())
4641 _num_cells=DataArrayInt::New();
4642 _num_cells->alloc(nbOfElt,1);
4643 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
4646 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4649 if(!mrs || mrs->isCellNameFieldReading())
4651 _names_cells=DataArrayAsciiChar::New();
4652 _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4653 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
4654 _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4657 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4660 if(!mrs || mrs->isNodeNameFieldReading())
4662 _names_nodes=DataArrayAsciiChar::New();
4663 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4664 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4665 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4670 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
4672 int meshDim=getStructuredMesh()->getMeshDimension();
4673 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4675 if((const DataArrayInt *)_fam_cells)
4676 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4677 if((const DataArrayInt *)_fam_nodes)
4678 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4679 if((const DataArrayInt *)_num_cells)
4680 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4681 if((const DataArrayInt *)_num_nodes)
4682 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4683 if((const DataArrayAsciiChar *)_names_cells)
4685 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4687 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4688 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4689 throw INTERP_KERNEL::Exception(oss.str().c_str());
4691 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4693 if((const DataArrayAsciiChar *)_names_nodes)
4695 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4697 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4698 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4699 throw INTERP_KERNEL::Exception(oss.str().c_str());
4701 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4704 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
4708 * Returns an empty instance of MEDFileCMesh.
4709 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4710 * mesh using decrRef() as it is no more needed.
4712 MEDFileCMesh *MEDFileCMesh::New()
4714 return new MEDFileCMesh;
4718 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4719 * file. The first mesh in the file is loaded.
4720 * \param [in] fileName - the name of MED file to read.
4721 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4722 * mesh using decrRef() as it is no more needed.
4723 * \throw If the file is not readable.
4724 * \throw If there is no meshes in the file.
4725 * \throw If the mesh in the file is not a Cartesian one.
4727 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
4729 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4732 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4733 throw INTERP_KERNEL::Exception(oss.str().c_str());
4735 MEDFileUtilities::CheckFileForRead(fileName);
4736 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4738 ParaMEDMEM::MEDCouplingMeshType meshType;
4740 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
4741 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
4745 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4746 * file. The mesh to load is specified by its name and numbers of a time step and an
4748 * \param [in] fileName - the name of MED file to read.
4749 * \param [in] mName - the name of the mesh to read.
4750 * \param [in] dt - the number of a time step.
4751 * \param [in] it - the number of an iteration.
4752 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4753 * mesh using decrRef() as it is no more needed.
4754 * \throw If the file is not readable.
4755 * \throw If there is no mesh with given attributes in the file.
4756 * \throw If the mesh in the file is not a Cartesian one.
4758 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4760 MEDFileUtilities::CheckFileForRead(fileName);
4761 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4762 return new MEDFileCMesh(fid,mName,dt,it,mrs);
4765 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
4767 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
4770 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildren() const
4772 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
4773 if((const MEDCouplingCMesh *)_cmesh)
4774 ret.push_back((const MEDCouplingCMesh *)_cmesh);
4779 * Returns the dimension on cells in \a this mesh.
4780 * \return int - the mesh dimension.
4781 * \throw If there are no cells in this mesh.
4783 int MEDFileCMesh::getMeshDimension() const
4785 if(!((const MEDCouplingCMesh*)_cmesh))
4786 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4787 return _cmesh->getMeshDimension();
4791 * Returns the dimension on nodes in \a this mesh.
4792 * \return int - the space dimension.
4793 * \throw If there are no cells in this mesh.
4795 int MEDFileCMesh::getSpaceDimension() const
4797 if(!((const MEDCouplingCMesh*)_cmesh))
4798 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
4799 return _cmesh->getSpaceDimension();
4803 * Returns a string describing \a this mesh.
4804 * \return std::string - the mesh information string.
4806 std::string MEDFileCMesh::simpleRepr() const
4808 return MEDFileStructuredMesh::simpleRepr();
4812 * Returns a full textual description of \a this mesh.
4813 * \return std::string - the string holding the mesh description.
4815 std::string MEDFileCMesh::advancedRepr() const
4817 return simpleRepr();
4820 MEDFileMesh *MEDFileCMesh::shallowCpy() const
4822 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4826 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
4828 return new MEDFileCMesh;
4831 MEDFileMesh *MEDFileCMesh::deepCpy() const
4833 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4834 if((const MEDCouplingCMesh*)_cmesh)
4835 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
4836 ret->deepCpyAttributes();
4841 * Checks if \a this and another mesh are equal.
4842 * \param [in] other - the mesh to compare with.
4843 * \param [in] eps - a precision used to compare real values.
4844 * \param [in,out] what - the string returning description of unequal data.
4845 * \return bool - \c true if the meshes are equal, \c false, else.
4847 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4849 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4851 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
4854 what="Mesh types differ ! This is cartesian and other is NOT !";
4857 clearNonDiscrAttributes();
4858 otherC->clearNonDiscrAttributes();
4859 const MEDCouplingCMesh *coo1=_cmesh;
4860 const MEDCouplingCMesh *coo2=otherC->_cmesh;
4861 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4863 what="Mismatch of cartesian meshes ! One is defined and not other !";
4868 bool ret=coo1->isEqual(coo2,eps);
4871 what="cartesian meshes differ !";
4879 * Clears redundant attributes of incorporated data arrays.
4881 void MEDFileCMesh::clearNonDiscrAttributes() const
4883 MEDFileStructuredMesh::clearNonDiscrAttributes();
4884 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
4887 MEDFileCMesh::MEDFileCMesh()
4891 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4894 loadCMeshFromFile(fid,mName,dt,it,mrs);
4896 catch(INTERP_KERNEL::Exception& e)
4901 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4903 ParaMEDMEM::MEDCouplingMeshType meshType;
4906 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4907 if(meshType!=CARTESIAN)
4909 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
4910 throw INTERP_KERNEL::Exception(oss.str().c_str());
4912 MEDFileCMeshL2 loaderl2;
4913 loaderl2.loadAll(fid,mid,mName,dt,it);
4914 MEDCouplingCMesh *mesh=loaderl2.getMesh();
4917 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
4921 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
4922 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
4924 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
4926 synchronizeTinyInfoOnLeaves();
4930 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
4932 synchronizeTinyInfoOnLeaves();
4937 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
4938 * \param [in] m - the new MEDCouplingCMesh to refer to.
4939 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4942 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
4944 dealWithTinyInfo(m);
4950 void MEDFileCMesh::writeLL(med_idt fid) const
4952 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4953 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4954 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4955 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4956 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4957 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4958 int spaceDim(_cmesh->getSpaceDimension());
4959 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4960 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4961 for(int i=0;i<spaceDim;i++)
4963 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
4965 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4966 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
4967 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
4969 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4970 MEDmeshUniversalNameWr(fid,maa);
4971 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
4972 for(int i=0;i<spaceDim;i++)
4974 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
4975 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
4978 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
4979 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
4982 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
4984 const MEDCouplingCMesh *cmesh=_cmesh;
4987 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
4988 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
4989 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
4990 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
4993 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
4995 return new MEDFileCurveLinearMesh;
4998 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5000 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5003 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5004 throw INTERP_KERNEL::Exception(oss.str().c_str());
5006 MEDFileUtilities::CheckFileForRead(fileName);
5007 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5009 ParaMEDMEM::MEDCouplingMeshType meshType;
5011 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5012 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
5015 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5017 MEDFileUtilities::CheckFileForRead(fileName);
5018 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5019 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
5022 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
5024 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5027 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildren() const
5029 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
5030 if((const MEDCouplingCurveLinearMesh *)_clmesh)
5031 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
5035 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
5037 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5041 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
5043 return new MEDFileCurveLinearMesh;
5046 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
5048 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5049 if((const MEDCouplingCurveLinearMesh*)_clmesh)
5050 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
5051 ret->deepCpyAttributes();
5055 int MEDFileCurveLinearMesh::getMeshDimension() const
5057 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
5058 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5059 return _clmesh->getMeshDimension();
5062 std::string MEDFileCurveLinearMesh::simpleRepr() const
5064 return MEDFileStructuredMesh::simpleRepr();
5067 std::string MEDFileCurveLinearMesh::advancedRepr() const
5069 return simpleRepr();
5072 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5074 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5076 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
5079 what="Mesh types differ ! This is curve linear and other is NOT !";
5082 clearNonDiscrAttributes();
5083 otherC->clearNonDiscrAttributes();
5084 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
5085 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
5086 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5088 what="Mismatch of curve linear meshes ! One is defined and not other !";
5093 bool ret=coo1->isEqual(coo2,eps);
5096 what="curve linear meshes differ !";
5103 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
5105 MEDFileStructuredMesh::clearNonDiscrAttributes();
5106 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
5109 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
5111 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
5114 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
5115 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
5116 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
5117 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
5120 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
5122 synchronizeTinyInfoOnLeaves();
5126 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
5128 dealWithTinyInfo(m);
5134 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
5136 synchronizeTinyInfoOnLeaves();
5140 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
5144 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5147 loadCLMeshFromFile(fid,mName,dt,it,mrs);
5149 catch(INTERP_KERNEL::Exception& e)
5154 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
5156 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5157 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5158 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5159 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5160 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5161 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5162 int spaceDim=_clmesh->getSpaceDimension();
5163 int meshDim=_clmesh->getMeshDimension();
5164 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5165 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5166 const DataArrayDouble *coords=_clmesh->getCoords();
5168 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
5169 for(int i=0;i<spaceDim;i++)
5171 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
5173 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5174 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
5175 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
5177 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5178 MEDmeshUniversalNameWr(fid,maa);
5179 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5180 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5181 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5183 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5185 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5186 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5189 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5191 ParaMEDMEM::MEDCouplingMeshType meshType;
5194 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5195 if(meshType!=CURVE_LINEAR)
5197 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5198 throw INTERP_KERNEL::Exception(oss.str().c_str());
5200 MEDFileCLMeshL2 loaderl2;
5201 loaderl2.loadAll(fid,mid,mName,dt,it);
5202 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5205 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5208 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5210 return new MEDFileMeshMultiTS;
5213 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
5215 return new MEDFileMeshMultiTS(fileName);
5218 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
5220 return new MEDFileMeshMultiTS(fileName,mName);
5223 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
5225 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5226 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5228 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5229 if((const MEDFileMesh *)*it)
5230 meshOneTs[i]=(*it)->deepCpy();
5231 ret->_mesh_one_ts=meshOneTs;
5235 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
5237 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5240 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildren() const
5242 std::vector<const BigMemoryObject *> ret;
5243 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5245 const MEDFileMesh *cur(*it);
5252 std::string MEDFileMeshMultiTS::getName() const
5254 if(_mesh_one_ts.empty())
5255 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5256 return _mesh_one_ts[0]->getName();
5259 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
5261 std::string oldName(getName());
5262 std::vector< std::pair<std::string,std::string> > v(1);
5263 v[0].first=oldName; v[0].second=newMeshName;
5267 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5270 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5272 MEDFileMesh *cur(*it);
5274 ret=cur->changeNames(modifTab) || ret;
5279 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
5281 if(_mesh_one_ts.empty())
5282 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5283 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5286 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
5289 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5290 _mesh_one_ts.resize(1);
5291 mesh1TimeStep->incrRef();
5292 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5293 _mesh_one_ts[0]=mesh1TimeStep;
5296 void MEDFileMeshMultiTS::write(med_idt fid) const
5298 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5300 (*it)->copyOptionsFrom(*this);
5305 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
5307 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5308 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5309 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5310 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5314 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
5315 {//for the moment to be improved
5316 _mesh_one_ts.resize(1);
5317 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5320 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5324 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
5327 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5330 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5331 throw INTERP_KERNEL::Exception(oss.str().c_str());
5333 MEDFileUtilities::CheckFileForRead(fileName);
5334 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5336 ParaMEDMEM::MEDCouplingMeshType meshType;
5338 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5339 loadFromFile(fileName,ms.front());
5341 catch(INTERP_KERNEL::Exception& e)
5346 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
5349 loadFromFile(fileName,mName);
5351 catch(INTERP_KERNEL::Exception& e)
5356 MEDFileMeshes *MEDFileMeshes::New()
5358 return new MEDFileMeshes;
5361 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
5363 return new MEDFileMeshes(fileName);
5366 void MEDFileMeshes::write(med_idt fid) const
5369 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5371 (*it)->copyOptionsFrom(*this);
5376 void MEDFileMeshes::write(const std::string& fileName, int mode) const
5378 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5379 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5380 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5381 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5386 int MEDFileMeshes::getNumberOfMeshes() const
5388 return _meshes.size();
5391 MEDFileMeshesIterator *MEDFileMeshes::iterator()
5393 return new MEDFileMeshesIterator(this);
5396 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
5398 if(i<0 || i>=(int)_meshes.size())
5400 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5401 throw INTERP_KERNEL::Exception(oss.str().c_str());
5403 return _meshes[i]->getOneTimeStep();
5406 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
5408 std::vector<std::string> ms=getMeshesNames();
5409 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5412 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5413 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5414 throw INTERP_KERNEL::Exception(oss.str().c_str());
5416 return getMeshAtPos((int)std::distance(ms.begin(),it));
5419 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
5421 std::vector<std::string> ret(_meshes.size());
5423 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5425 const MEDFileMeshMultiTS *f=(*it);
5428 ret[i]=f->getName();
5432 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5433 throw INTERP_KERNEL::Exception(oss.str().c_str());
5439 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5442 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5444 MEDFileMeshMultiTS *cur(*it);
5446 ret=cur->changeNames(modifTab) || ret;
5451 void MEDFileMeshes::resize(int newSize)
5453 _meshes.resize(newSize);
5456 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
5459 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5460 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5461 elt->setOneTimeStep(mesh);
5462 _meshes.push_back(elt);
5465 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
5468 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5469 if(i>=(int)_meshes.size())
5470 _meshes.resize(i+1);
5471 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5472 elt->setOneTimeStep(mesh);
5476 void MEDFileMeshes::destroyMeshAtPos(int i)
5478 if(i<0 || i>=(int)_meshes.size())
5480 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5481 throw INTERP_KERNEL::Exception(oss.str().c_str());
5483 _meshes.erase(_meshes.begin()+i);
5486 void MEDFileMeshes::loadFromFile(const std::string& fileName)
5488 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5490 _meshes.resize(ms.size());
5491 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5492 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
5495 MEDFileMeshes::MEDFileMeshes()
5499 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
5502 loadFromFile(fileName);
5504 catch(INTERP_KERNEL::Exception& /*e*/)
5508 MEDFileMeshes *MEDFileMeshes::deepCpy() const
5510 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5512 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5513 if((const MEDFileMeshMultiTS *)*it)
5514 meshes[i]=(*it)->deepCpy();
5515 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5516 ret->_meshes=meshes;
5520 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
5522 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5525 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildren() const
5527 std::vector<const BigMemoryObject *> ret;
5528 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5530 const MEDFileMeshMultiTS *cur(*it);
5537 std::string MEDFileMeshes::simpleRepr() const
5539 std::ostringstream oss;
5540 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5541 simpleReprWithoutHeader(oss);
5545 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5547 int nbOfMeshes=getNumberOfMeshes();
5548 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5549 std::vector<std::string> mns=getMeshesNames();
5550 for(int i=0;i<nbOfMeshes;i++)
5551 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5554 void MEDFileMeshes::checkCoherency() const
5556 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5558 std::set<std::string> s;
5559 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5561 const MEDFileMeshMultiTS *elt=(*it);
5564 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5565 throw INTERP_KERNEL::Exception(oss.str().c_str());
5567 std::size_t sz=s.size();
5568 s.insert(std::string((*it)->getName()));
5571 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5572 throw INTERP_KERNEL::Exception(oss.str().c_str());
5577 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5582 _nb_iter=ms->getNumberOfMeshes();
5586 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5590 MEDFileMesh *MEDFileMeshesIterator::nextt()
5592 if(_iter_id<_nb_iter)
5594 MEDFileMeshes *ms(_ms);
5596 return ms->getMeshAtPos(_iter_id++);