1 // Copyright (C) 2007-2013 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.
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::getHeapMemorySize() 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);
58 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
59 * file. The first mesh in the file is loaded.
60 * \param [in] fileName - the name of MED file to read.
61 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
62 * mesh using decrRef() as it is no more needed.
63 * \throw If the file is not readable.
64 * \throw If there is no meshes in the file.
65 * \throw If the mesh in the file is of a not supported type.
67 MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
69 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
72 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
73 throw INTERP_KERNEL::Exception(oss.str().c_str());
75 MEDFileUtilities::CheckFileForRead(fileName);
76 ParaMEDMEM::MEDCouplingMeshType meshType;
77 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
80 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
85 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
86 ret->loadUMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
87 return (MEDFileUMesh *)ret.retn();
91 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
92 ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
93 return (MEDFileCMesh *)ret.retn();
97 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
98 ret->loadCLMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
99 return (MEDFileCurveLinearMesh *)ret.retn();
103 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
104 throw INTERP_KERNEL::Exception(oss.str().c_str());
110 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
111 * file. The mesh to load is specified by its name and numbers of a time step and an
113 * \param [in] fileName - the name of MED file to read.
114 * \param [in] mName - the name of the mesh to read.
115 * \param [in] dt - the number of a time step.
116 * \param [in] it - the number of an iteration.
117 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
118 * mesh using decrRef() as it is no more needed.
119 * \throw If the file is not readable.
120 * \throw If there is no mesh with given attributes in the file.
121 * \throw If the mesh in the file is of a not supported type.
123 MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
125 MEDFileUtilities::CheckFileForRead(fileName);
126 ParaMEDMEM::MEDCouplingMeshType meshType;
127 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
130 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
135 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
136 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
137 return (MEDFileUMesh *)ret.retn();
141 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
142 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
143 return (MEDFileCMesh *)ret.retn();
147 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
148 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
149 return (MEDFileCurveLinearMesh *)ret.retn();
153 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
154 throw INTERP_KERNEL::Exception(oss.str().c_str());
160 * Writes \a this mesh into an open MED file specified by its descriptor.
161 * \param [in] fid - the MED file descriptor.
162 * \throw If the mesh name is not set.
163 * \throw If the file is open for reading only.
164 * \throw If the writing mode == 1 and the same data is present in an existing file.
166 void MEDFileMesh::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
169 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
171 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
176 * Writes \a this mesh into a MED file specified by its name.
177 * \param [in] fileName - the MED file name.
178 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
179 * - 2 - erase; an existing file is removed.
180 * - 1 - append; same data should not be present in an existing file.
181 * - 0 - overwrite; same data present in an existing file is overwritten.
182 * \throw If the mesh name is not set.
183 * \throw If \a mode == 1 and the same data is present in an existing file.
185 void MEDFileMesh::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
187 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
188 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
189 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
190 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
195 * Checks if \a this and another mesh are equal.
196 * \param [in] other - the mesh to compare with.
197 * \param [in] eps - a precision used to compare real values.
198 * \param [in,out] what - the string returning description of unequal data.
199 * \return bool - \c true if the meshes are equal, \c false, else.
201 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
203 if(_order!=other->_order)
205 what="Orders differ !";
208 if(_iteration!=other->_iteration)
210 what="Iterations differ !";
213 if(fabs(_time-other->_time)>eps)
215 what="Time values differ !";
218 if(_dt_unit!=other->_dt_unit)
220 what="Time units differ !";
223 if(_name!=other->_name)
225 what="Names differ !";
228 //univ_name has been ignored -> not a bug because it is a mutable attribute
229 if(_desc_name!=other->_desc_name)
231 what="Description names differ !";
234 if(!areGrpsEqual(other,what))
236 if(!areFamsEqual(other,what))
242 * Clears redundant attributes of incorporated data arrays.
244 void MEDFileMesh::clearNonDiscrAttributes() const
249 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
251 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
253 if((*it).first==_name)
263 * Copies data on groups and families from another mesh.
264 * \param [in] other - the mesh to copy the data from.
266 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
268 _groups=other._groups;
269 _families=other._families;
273 * Returns names of families constituting a group.
274 * \param [in] name - the name of the group of interest.
275 * \return std::vector<std::string> - a sequence of names of the families.
276 * \throw If the name of a nonexistent group is specified.
278 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
280 std::string oname(name);
281 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
282 if(it==_groups.end())
284 std::vector<std::string> grps=getGroupsNames();
285 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
286 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
287 throw INTERP_KERNEL::Exception(oss.str().c_str());
293 * Returns names of families constituting some groups.
294 * \param [in] grps - a sequence of names of groups of interest.
295 * \return std::vector<std::string> - a sequence of names of the families.
296 * \throw If a name of a nonexistent group is present in \a grps.
298 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
300 std::set<std::string> fams;
301 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
303 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
304 if(it2==_groups.end())
306 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
307 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
308 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
309 throw INTERP_KERNEL::Exception(oss.str().c_str());
311 fams.insert((*it2).second.begin(),(*it2).second.end());
313 std::vector<std::string> fams2(fams.begin(),fams.end());
318 * Returns ids of families constituting a group.
319 * \param [in] name - the name of the group of interest.
320 * \return std::vector<int> - sequence of ids of the families.
321 * \throw If the name of a nonexistent group is specified.
323 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
325 std::string oname(name);
326 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
327 std::vector<std::string> grps=getGroupsNames();
328 if(it==_groups.end())
330 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
331 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
332 throw INTERP_KERNEL::Exception(oss.str().c_str());
334 return getFamiliesIds((*it).second);
338 * Sets names of families constituting a group. If data on families of this group is
339 * already present, it is overwritten. Every family in \a fams is checked, and if a
340 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
341 * \param [in] name - the name of the group of interest.
342 * \param [in] fams - a sequence of names of families constituting the group.
344 void MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception)
346 std::string oname(name);
348 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
350 std::map<std::string,int>::iterator it2=_families.find(*it1);
351 if(it2==_families.end())
357 * Sets families constituting a group. The families are specified by their ids.
358 * If a family name is not found by its id, an exception is thrown.
359 * If several families have same id, the first one in lexical order is taken.
360 * \param [in] name - the name of the group of interest.
361 * \param [in] famIds - a sequence of ids of families constituting the group.
362 * \throw If a family name is not found by its id.
364 void MEDFileMesh::setFamiliesIdsOnGroup(const char *name, const std::vector<int>& famIds) throw(INTERP_KERNEL::Exception)
366 std::string oname(name);
367 std::vector<std::string> fams(famIds.size());
369 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
371 std::string name2=getFamilyNameGivenId(*it1);
378 * Returns names of groups including a given family.
379 * \param [in] name - the name of the family of interest.
380 * \return std::vector<std::string> - a sequence of names of groups including the family.
382 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception)
384 std::vector<std::string> ret;
385 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
387 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
390 ret.push_back((*it1).first);
398 * Adds an existing family to groups.
399 * \param [in] famName - a name of family to add to \a grps.
400 * \param [in] grps - a sequence of group names to add the family in.
401 * \throw If a family named \a famName not yet exists.
403 void MEDFileMesh::setGroupsOnFamily(const char *famName, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception)
405 std::string fName(famName);
406 const std::map<std::string,int>::const_iterator it=_families.find(fName);
407 if(it==_families.end())
409 std::vector<std::string> fams=getFamiliesNames();
410 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
411 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
412 throw INTERP_KERNEL::Exception(oss.str().c_str());
414 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
416 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
417 if(it2!=_groups.end())
418 (*it2).second.push_back(fName);
421 std::vector<std::string> grps2(1,fName);
428 * Returns names of all groups of \a this mesh.
429 * \return std::vector<std::string> - a sequence of group names.
431 std::vector<std::string> MEDFileMesh::getGroupsNames() const
433 std::vector<std::string> ret(_groups.size());
435 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
441 * Returns names of all families of \a this mesh.
442 * \return std::vector<std::string> - a sequence of family names.
444 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
446 std::vector<std::string> ret(_families.size());
448 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
454 * Changes a name of every family, included in one group only, to be same as the group name.
455 * \throw If there are families with equal names in \a this mesh.
457 void MEDFileMesh::assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception)
459 std::map<std::string, std::vector<std::string> > groups(_groups);
460 std::map<std::string,int> newFams;
461 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
463 std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
464 if(grps.size()==1 && groups[grps[0]].size()==1)
466 if(newFams.find(grps[0])!=newFams.end())
468 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
469 throw INTERP_KERNEL::Exception(oss.str().c_str());
471 newFams[grps[0]]=(*it).second;
472 std::vector<std::string>& grps2=groups[grps[0]];
473 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
478 if(newFams.find((*it).first)!=newFams.end())
480 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
481 throw INTERP_KERNEL::Exception(oss.str().c_str());
483 newFams[(*it).first]=(*it).second;
491 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
493 * \return the removed groups.
495 std::vector<std::string> MEDFileMesh::removeEmptyGroups() throw(INTERP_KERNEL::Exception)
497 std::vector<std::string> ret;
498 std::map<std::string, std::vector<std::string> > newGrps;
499 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
501 if((*it).second.empty())
502 ret.push_back((*it).first);
504 newGrps[(*it).first]=(*it).second;
512 * Removes a group from \a this mesh.
513 * \param [in] name - the name of the group to remove.
514 * \throw If no group with such a \a name exists.
516 void MEDFileMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception)
518 std::string oname(name);
519 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
520 std::vector<std::string> grps=getGroupsNames();
521 if(it==_groups.end())
523 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
524 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
525 throw INTERP_KERNEL::Exception(oss.str().c_str());
531 * Removes a family from \a this mesh.
532 * \param [in] name - the name of the family to remove.
533 * \throw If no family with such a \a name exists.
535 void MEDFileMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception)
537 std::string oname(name);
538 std::map<std::string, int >::iterator it=_families.find(oname);
539 std::vector<std::string> fams=getFamiliesNames();
540 if(it==_families.end())
542 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
543 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
544 throw INTERP_KERNEL::Exception(oss.str().c_str());
547 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
549 std::vector<std::string>& v=(*it3).second;
550 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
557 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
558 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
559 * family field whatever its level. This method also suppresses the orphan families.
561 * \return - The list of removed groups names.
563 * \sa MEDFileMesh::removeOrphanFamilies.
565 std::vector<std::string> MEDFileMesh::removeOrphanGroups() throw(INTERP_KERNEL::Exception)
567 removeOrphanFamilies();
568 return removeEmptyGroups();
572 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
573 * 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.
575 * \return - The list of removed families names.
576 * \sa MEDFileMesh::removeOrphanGroups.
578 std::vector<std::string> MEDFileMesh::removeOrphanFamilies() throw(INTERP_KERNEL::Exception)
580 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
581 std::vector<std::string> ret;
582 if(!((DataArrayInt*)allFamIdsInUse))
584 ret=getFamiliesNames();
585 _families.clear(); _groups.clear();
588 std::map<std::string,int> famMap;
589 std::map<std::string, std::vector<std::string> > grps(_groups);
590 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
592 if(allFamIdsInUse->presenceOfValue((*it).second))
593 famMap[(*it).first]=(*it).second;
596 ret.push_back((*it).first);
597 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first.c_str());
598 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
600 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
601 std::vector<std::string>& famv=(*it3).second;
602 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
608 { _families=famMap; _groups=grps; }
613 * Renames a group in \a this mesh.
614 * \param [in] oldName - a current name of the group to rename.
615 * \param [in] newName - a new group name.
616 * \throw If no group named \a oldName exists in \a this mesh.
617 * \throw If a group named \a newName already exists.
619 void MEDFileMesh::changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
621 std::string oname(oldName);
622 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
623 std::vector<std::string> grps=getGroupsNames();
624 if(it==_groups.end())
626 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
627 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
628 throw INTERP_KERNEL::Exception(oss.str().c_str());
630 std::string nname(newName);
631 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
632 if(it2!=_groups.end())
634 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
635 throw INTERP_KERNEL::Exception(oss.str().c_str());
637 std::vector<std::string> cpy=(*it).second;
639 _groups[newName]=cpy;
643 * Changes an id of a family in \a this mesh.
644 * This method calls changeFamilyIdArr().
645 * \param [in] oldId - a current id of the family.
646 * \param [in] newId - a new family id.
648 void MEDFileMesh::changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception)
650 changeFamilyIdArr(oldId,newId);
651 std::map<std::string,int> fam2;
652 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
654 if((*it).second==oldId)
655 fam2[(*it).first]=newId;
657 fam2[(*it).first]=(*it).second;
663 * Renames a family in \a this mesh.
664 * \param [in] oldName - a current name of the family to rename.
665 * \param [in] newName - a new family name.
666 * \throw If no family named \a oldName exists in \a this mesh.
667 * \throw If a family named \a newName already exists.
669 void MEDFileMesh::changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
671 std::string oname(oldName);
672 std::map<std::string, int >::iterator it=_families.find(oname);
673 std::vector<std::string> fams=getFamiliesNames();
674 if(it==_families.end())
676 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
677 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
678 throw INTERP_KERNEL::Exception(oss.str().c_str());
680 std::string nname(newName);
681 std::map<std::string, int >::iterator it2=_families.find(nname);
682 if(it2!=_families.end())
684 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
685 throw INTERP_KERNEL::Exception(oss.str().c_str());
687 int cpy=(*it).second;
689 _families[newName]=cpy;
690 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
692 std::vector<std::string>& v=(*it3).second;
693 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
700 * Checks if \a this and another mesh contains the same families.
701 * \param [in] other - the mesh to compare with \a this one.
702 * \param [in,out] what - an unused parameter.
703 * \return bool - \c true if number of families and their ids are the same in the two
704 * meshes. Families with the id == \c 0 are not considered.
706 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
708 if(_families==other->_families)
710 std::map<std::string,int> fam0;
711 std::map<std::string,int> fam1;
712 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
714 fam0[(*it).first]=(*it).second;
715 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
717 fam1[(*it).first]=(*it).second;
722 * Checks if \a this and another mesh contains the same groups.
723 * \param [in] other - the mesh to compare with \a this one.
724 * \param [in,out] what - a string describing a difference of groups of the two meshes
725 * in case if this method returns \c false.
726 * \return bool - \c true if number of groups and families constituting them are the
727 * same in the two meshes.
729 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
731 if(_groups==other->_groups)
734 std::size_t sz=_groups.size();
735 if(sz!=other->_groups.size())
737 what="Groups differ because not same number !\n";
742 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
743 for(std::size_t i=0;i<sz && ret;i++,it1++)
745 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
746 if(it2!=other->_groups.end())
748 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
749 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
755 what="A group in first mesh exists not in other !\n";
761 std::ostringstream oss; oss << "Groups description differs :\n";
762 oss << "First group description :\n";
763 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
765 oss << " Group \"" << (*it).first << "\" on following families :\n";
766 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
767 oss << " \"" << *it2 << "\n";
769 oss << "Second group description :\n";
770 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
772 oss << " Group \"" << (*it).first << "\" on following families :\n";
773 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
774 oss << " \"" << *it2 << "\n";
782 * Checks if a group with a given name exists in \a this mesh.
783 * \param [in] groupName - the group name.
784 * \return bool - \c true the group \a groupName exists in \a this mesh.
786 bool MEDFileMesh::existsGroup(const char *groupName) const
788 std::string grpName(groupName);
789 return _groups.find(grpName)!=_groups.end();
793 * Checks if a family with a given id exists in \a this mesh.
794 * \param [in] famId - the family id.
795 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
797 bool MEDFileMesh::existsFamily(int famId) const
799 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
800 if((*it2).second==famId)
806 * Checks if a family with a given name exists in \a this mesh.
807 * \param [in] familyName - the family name.
808 * \return bool - \c true the family \a familyName exists in \a this mesh.
810 bool MEDFileMesh::existsFamily(const char *familyName) const
812 std::string fname(familyName);
813 return _families.find(fname)!=_families.end();
817 * Sets an id of a family.
818 * \param [in] familyName - the family name.
819 * \param [in] id - a new id of the family.
821 void MEDFileMesh::setFamilyId(const char *familyName, int id)
823 std::string fname(familyName);
827 void MEDFileMesh::setFamilyIdUnique(const char *familyName, int id) throw(INTERP_KERNEL::Exception)
829 std::string fname(familyName);
830 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
833 if((*it).first!=familyName)
835 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
836 throw INTERP_KERNEL::Exception(oss.str().c_str());
843 * Adds a family to \a this mesh.
844 * \param [in] familyName - a name of the family.
845 * \param [in] famId - an id of the family.
846 * \throw If a family with the same name or id already exists in \a this mesh.
848 void MEDFileMesh::addFamily(const char *familyName, int famId) throw(INTERP_KERNEL::Exception)
850 std::string fname(familyName);
851 std::map<std::string,int>::const_iterator it=_families.find(fname);
852 if(it==_families.end())
854 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
855 if((*it2).second==famId)
857 std::ostringstream oss;
858 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
859 throw INTERP_KERNEL::Exception(oss.str().c_str());
861 _families[fname]=famId;
865 if((*it).second!=famId)
867 std::ostringstream oss;
868 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
869 throw INTERP_KERNEL::Exception(oss.str().c_str());
875 * Creates a group including all mesh entities of given dimension.
876 * \warning This method does \b not guarantee that the created group includes mesh
877 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
878 * present in family fields of different dimensions. To assure this, call
879 * ensureDifferentFamIdsPerLevel() \b before calling this method.
880 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
882 * \param [in] groupName - a name of the new group.
883 * \throw If a group named \a groupName already exists.
884 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
885 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
887 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName) throw(INTERP_KERNEL::Exception)
889 std::string grpName(groupName);
890 std::vector<int> levs=getNonEmptyLevelsExt();
891 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
893 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
894 oss << "Available relative ext levels are : ";
895 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
896 throw INTERP_KERNEL::Exception(oss.str().c_str());
898 if(existsGroup(groupName))
900 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
901 oss << "Already existing groups are : ";
902 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
903 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
904 throw INTERP_KERNEL::Exception(oss.str().c_str());
906 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
908 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
909 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
910 std::vector<std::string> familiesOnWholeGroup;
911 for(const int *it=famIds->begin();it!=famIds->end();it++)
914 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
916 _groups[grpName]=familiesOnWholeGroup;
920 * Ensures that given family ids do not present in family fields of dimensions different
921 * than given ones. If a family id is present in the family fields of dimensions different
922 * than the given ones, a new family is created and the whole data is updated accordingly.
923 * \param [in] famIds - a sequence of family ids to check.
924 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
925 * famIds should exclusively belong.
926 * \return bool - \c true if no modification is done in \a this mesh by this method.
928 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
930 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
931 std::vector<int> levs=getNonEmptyLevelsExt();
932 std::set<int> levs2(levs.begin(),levs.end());
933 std::vector<int> levsToTest;
934 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
935 std::set<int> famIds2(famIds.begin(),famIds.end());
938 if(!_families.empty())
939 maxFamId=getMaxFamilyId()+1;
940 std::vector<std::string> allFams=getFamiliesNames();
941 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
943 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
946 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
947 std::vector<int> tmp;
948 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
949 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
952 std::string famName=getFamilyNameGivenId(*it2);
953 std::ostringstream oss; oss << "Family_" << maxFamId;
954 std::string zeName=CreateNameNotIn(oss.str(),allFams);
955 addFamilyOnAllGroupsHaving(famName.c_str(),zeName.c_str());
956 _families[zeName]=maxFamId;
957 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
966 * Adds a family to a given group in \a this mesh. If the group with a given name does
967 * not exist, it is created.
968 * \param [in] grpName - the name of the group to add the family in.
969 * \param [in] famName - the name of the family to add to the group named \a grpName.
970 * \throw If \a grpName or \a famName is an empty string.
971 * \throw If no family named \a famName is present in \a this mesh.
973 void MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName) throw(INTERP_KERNEL::Exception)
975 std::string grpn(grpName);
976 std::string famn(famName);
977 if(grpn.empty() || famn.empty())
978 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
979 std::vector<std::string> fams=getFamiliesNames();
980 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
982 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
983 oss << "Create this family or choose an existing one ! Existing fams are : ";
984 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
985 throw INTERP_KERNEL::Exception(oss.str().c_str());
987 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
988 if(it==_groups.end())
990 _groups[grpn].push_back(famn);
994 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
995 if(it2==(*it).second.end())
996 (*it).second.push_back(famn);
1001 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1002 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1003 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1005 void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *otherFamName) throw(INTERP_KERNEL::Exception)
1007 std::string famNameCpp(famName);
1008 std::string otherCpp(otherFamName);
1009 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1011 std::vector<std::string>& v=(*it).second;
1012 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1014 v.push_back(otherCpp);
1019 void MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
1021 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1024 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
1026 std::string fam(familyNameToChange);
1027 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1029 std::vector<std::string>& fams((*it).second);
1030 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1034 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1040 * Returns a name of the family having a given id or, if no such a family exists, creates
1041 * a new uniquely named family and returns its name.
1042 * \param [in] id - the id of the family whose name is required.
1043 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1044 * \return std::string - the name of the existing or the created family.
1045 * \throw If it is not possible to create a unique family name.
1047 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception)
1049 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1053 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1054 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1055 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1056 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1058 * This method will throws an exception if it is not possible to create a unique family name.
1060 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created) throw(INTERP_KERNEL::Exception)
1062 std::vector<std::string> famAlreadyExisting(families.size());
1064 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1066 if((*it).second!=id)
1068 famAlreadyExisting[ii]=(*it).first;
1077 std::ostringstream oss; oss << "Family_" << id;
1078 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1084 * Sets names and ids of all families in \a this mesh.
1085 * \param [in] info - a map of a family name to a family id.
1087 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1093 * Sets names of all groups and families constituting them in \a this mesh.
1094 * \param [in] info - a map of a group name to a vector of names of families
1095 * constituting the group.
1097 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1103 * Returns an id of the family having a given name.
1104 * \param [in] name - the name of the family of interest.
1105 * \return int - the id of the family of interest.
1106 * \throw If no family with such a \a name exists.
1108 int MEDFileMesh::getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception)
1110 std::string oname(name);
1111 std::map<std::string, int>::const_iterator it=_families.find(oname);
1112 std::vector<std::string> fams=getFamiliesNames();
1113 if(it==_families.end())
1115 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1116 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1117 throw INTERP_KERNEL::Exception(oss.str().c_str());
1119 return (*it).second;
1123 * Returns ids of the families having given names.
1124 * \param [in] fams - a sequence of the names of families of interest.
1125 * \return std::vector<int> - a sequence of the ids of families of interest.
1126 * \throw If \a fams contains a name of an inexistent family.
1128 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
1130 std::vector<int> ret(fams.size());
1132 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1134 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1135 if(it2==_families.end())
1137 std::vector<std::string> fams2=getFamiliesNames();
1138 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1139 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1140 throw INTERP_KERNEL::Exception(oss.str().c_str());
1142 ret[i]=(*it2).second;
1148 * Returns a maximal abs(id) of families in \a this mesh.
1149 * \return int - the maximal norm of family id.
1150 * \throw If there are no families in \a this mesh.
1152 int MEDFileMesh::getMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
1154 if(_families.empty())
1155 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1156 int ret=-std::numeric_limits<int>::max();
1157 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1159 ret=std::max(std::abs((*it).second),ret);
1165 * Returns a maximal id of families in \a this mesh.
1166 * \return int - the maximal family id.
1167 * \throw If there are no families in \a this mesh.
1169 int MEDFileMesh::getMaxFamilyId() const throw(INTERP_KERNEL::Exception)
1171 if(_families.empty())
1172 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1173 int ret=-std::numeric_limits<int>::max();
1174 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1176 ret=std::max((*it).second,ret);
1182 * Returns a minimal id of families in \a this mesh.
1183 * \return int - the minimal family id.
1184 * \throw If there are no families in \a this mesh.
1186 int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception)
1188 if(_families.empty())
1189 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1190 int ret=std::numeric_limits<int>::max();
1191 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1193 ret=std::min((*it).second,ret);
1199 * Returns a maximal id of families in \a this mesh. Not only named families are
1200 * considered but all family fields as well.
1201 * \return int - the maximal family id.
1203 int MEDFileMesh::getTheMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
1205 int m1=-std::numeric_limits<int>::max();
1206 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1207 m1=std::max(std::abs((*it).second),m1);
1208 int m2=getMaxAbsFamilyIdInArrays();
1209 return std::max(m1,m2);
1213 * Returns a maximal id of families in \a this mesh. Not only named families are
1214 * considered but all family fields as well.
1215 * \return int - the maximal family id.
1217 int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception)
1219 int m1=-std::numeric_limits<int>::max();
1220 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1221 m1=std::max((*it).second,m1);
1222 int m2=getMaxFamilyIdInArrays();
1223 return std::max(m1,m2);
1227 * Returns a minimal id of families in \a this mesh. Not only named families are
1228 * considered but all family fields as well.
1229 * \return int - the minimal family id.
1231 int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception)
1233 int m1=std::numeric_limits<int>::max();
1234 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1235 m1=std::min((*it).second,m1);
1236 int m2=getMinFamilyIdInArrays();
1237 return std::min(m1,m2);
1241 * This method only considers the maps. The contain of family array is ignored here.
1243 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1245 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception)
1247 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1249 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1250 v.insert((*it).second);
1251 ret->alloc((int)v.size(),1);
1252 std::copy(v.begin(),v.end(),ret->getPointer());
1257 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1259 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1261 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const throw(INTERP_KERNEL::Exception)
1263 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1264 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1265 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1267 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1268 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1269 if((DataArrayInt *) ret)
1270 ret=dv->buildUnion(ret);
1278 * true is returned if no modification has been needed. false if family
1279 * renumbering has been needed.
1281 bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception)
1283 std::vector<int> levs=getNonEmptyLevelsExt();
1284 std::set<int> allFamIds;
1285 int maxId=getMaxFamilyId()+1;
1286 std::map<int,std::vector<int> > famIdsToRenum;
1287 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1289 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1292 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1294 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1296 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1298 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1301 if(famIdsToRenum.empty())
1303 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1304 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1306 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1307 int *famIdsToChange=fam->getPointer();
1308 std::map<int,int> ren;
1309 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1311 if(allIds->presenceOfValue(*it3))
1313 std::string famName=getFamilyNameGivenId(*it3);
1314 std::vector<std::string> grps=getGroupsOnFamily(famName.c_str());
1317 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1318 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1319 addFamilyOnGrp((*it4).c_str(),newFam.c_str());
1322 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1323 for(const int *id=ids->begin();id!=ids->end();id++)
1324 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1330 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1331 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1332 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1333 * This method will throw an exception if a same family id is detected in different level.
1334 * \warning This policy is the opposite of those in MED file documentation ...
1336 void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
1338 ensureDifferentFamIdsPerLevel();
1339 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1340 std::vector<int> levs=getNonEmptyLevelsExt();
1341 std::set<int> levsS(levs.begin(),levs.end());
1342 std::set<std::string> famsFetched;
1343 std::map<std::string,int> families;
1344 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1347 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1351 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1352 std::map<int,int> ren;
1353 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1355 int nbOfTuples=fam->getNumberOfTuples();
1356 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1357 for(int *w=start;w!=start+nbOfTuples;w++)
1359 for(const int *it=tmp->begin();it!=tmp->end();it++)
1361 if(allIds->presenceOfValue(*it))
1363 std::string famName=getFamilyNameGivenId(*it);
1364 families[famName]=ren[*it];
1365 famsFetched.insert(famName);
1370 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1373 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1377 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1378 std::map<int,int> ren;
1379 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1381 int nbOfTuples=fam->getNumberOfTuples();
1382 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1383 for(int *w=start;w!=start+nbOfTuples;w++)
1385 for(const int *it=tmp->begin();it!=tmp->end();it++)
1387 if(allIds->presenceOfValue(*it))
1389 std::string famName=getFamilyNameGivenId(*it);
1390 families[famName]=ren[*it];
1391 famsFetched.insert(famName);
1396 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1398 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1401 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1402 fam->fillWithZero();
1403 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1404 if(allIds->presenceOfValue(*it3))
1406 std::string famName=getFamilyNameGivenId(*it3);
1407 families[famName]=0;
1408 famsFetched.insert(famName);
1413 std::vector<std::string> allFams=getFamiliesNames();
1414 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1415 std::set<std::string> unFetchedIds;
1416 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1417 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1418 families[*it4]=_families[*it4];
1423 * This method normalizes fam id with the following policy.
1424 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1425 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1426 * This method will throw an exception if a same family id is detected in different level.
1428 void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
1430 ensureDifferentFamIdsPerLevel();
1431 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1432 std::vector<int> levs=getNonEmptyLevelsExt();
1433 std::set<int> levsS(levs.begin(),levs.end());
1434 std::set<std::string> famsFetched;
1435 std::map<std::string,int> families;
1437 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1440 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1443 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1444 std::map<int,int> ren;
1445 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1447 int nbOfTuples=fam->getNumberOfTuples();
1448 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1449 for(int *w=start;w!=start+nbOfTuples;w++)
1451 for(const int *it=tmp->begin();it!=tmp->end();it++)
1453 if(allIds->presenceOfValue(*it))
1455 std::string famName=getFamilyNameGivenId(*it);
1456 families[famName]=ren[*it];
1457 famsFetched.insert(famName);
1463 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1465 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1468 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1469 std::map<int,int> ren;
1470 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1472 int nbOfTuples=fam->getNumberOfTuples();
1473 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1474 for(int *w=start;w!=start+nbOfTuples;w++)
1476 for(const int *it=tmp->begin();it!=tmp->end();it++)
1478 if(allIds->presenceOfValue(*it))
1480 std::string famName=getFamilyNameGivenId(*it);
1481 families[famName]=ren[*it];
1482 famsFetched.insert(famName);
1488 std::vector<std::string> allFams=getFamiliesNames();
1489 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1490 std::set<std::string> unFetchedIds;
1491 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1492 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1493 families[*it4]=_families[*it4];
1498 * Returns a name of the family by its id. If there are several families having the given
1499 * id, the name first in lexical order is returned.
1500 * \param [in] id - the id of the family whose name is required.
1501 * \return std::string - the name of the found family.
1502 * \throw If no family with the given \a id exists.
1504 std::string MEDFileMesh::getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception)
1506 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1507 if((*it).second==id)
1509 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1510 throw INTERP_KERNEL::Exception(oss.str().c_str());
1514 * Returns a string describing \a this mesh. This description includes the mesh name and
1515 * the mesh description string.
1516 * \return std::string - the mesh information string.
1518 std::string MEDFileMesh::simpleRepr() const
1520 std::ostringstream oss;
1521 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1522 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1523 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1528 * Returns ids of mesh entities contained in a given group of a given dimension.
1529 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1531 * \param [in] grp - the name of the group of interest.
1532 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1533 * returned instead of ids.
1534 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1535 * numbers, if available and required, of mesh entities of the group. The caller
1536 * is to delete this array using decrRef() as it is no more needed.
1537 * \throw If the name of a nonexistent group is specified.
1538 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1540 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1542 std::vector<std::string> tmp(1);
1544 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1550 * Returns ids of mesh entities contained in given groups of a given dimension.
1551 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1553 * \param [in] grps - the names of the groups of interest.
1554 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1555 * returned instead of ids.
1556 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1557 * numbers, if available and required, of mesh entities of the groups. The caller
1558 * is to delete this array using decrRef() as it is no more needed.
1559 * \throw If the name of a nonexistent group is present in \a grps.
1560 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1562 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1564 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1565 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1569 * Returns ids of mesh entities contained in a given family of a given dimension.
1570 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1572 * \param [in] fam - the name of the family of interest.
1573 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1574 * returned instead of ids.
1575 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1576 * numbers, if available and required, of mesh entities of the family. The caller
1577 * is to delete this array using decrRef() as it is no more needed.
1578 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1580 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1582 std::vector<std::string> tmp(1);
1584 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1590 * Returns ids of nodes contained in a given group.
1591 * \param [in] grp - the name of the group of interest.
1592 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1593 * returned instead of ids.
1594 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1595 * numbers, if available and required, of nodes of the group. The caller
1596 * is to delete this array using decrRef() as it is no more needed.
1597 * \throw If the name of a nonexistent group is specified.
1598 * \throw If the family field is missing for nodes.
1600 DataArrayInt *MEDFileMesh::getNodeGroupArr(const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1602 std::vector<std::string> tmp(1);
1604 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1610 * Returns ids of nodes contained in given groups.
1611 * \param [in] grps - the names of the groups of interest.
1612 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1613 * returned instead of ids.
1614 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1615 * numbers, if available and required, of nodes of the groups. The caller
1616 * is to delete this array using decrRef() as it is no more needed.
1617 * \throw If the name of a nonexistent group is present in \a grps.
1618 * \throw If the family field is missing for nodes.
1620 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1622 return getGroupsArr(1,grps,renum);
1626 * Returns ids of nodes contained in a given group.
1627 * \param [in] grp - the name of the group of interest.
1628 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1629 * returned instead of ids.
1630 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1631 * numbers, if available and required, of nodes of the group. The caller
1632 * is to delete this array using decrRef() as it is no more needed.
1633 * \throw If the name of a nonexistent group is specified.
1634 * \throw If the family field is missing for nodes.
1636 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1638 std::vector<std::string> tmp(1);
1640 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1646 * Returns ids of nodes contained in given families.
1647 * \param [in] fams - the names of the families of interest.
1648 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1649 * returned instead of ids.
1650 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1651 * numbers, if available and required, of nodes of the families. The caller
1652 * is to delete this array using decrRef() as it is no more needed.
1653 * \throw If the family field is missing for nodes.
1655 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
1657 return getFamiliesArr(1,fams,renum);
1661 * Adds groups of given dimension and creates corresponding families and family fields
1662 * given ids of mesh entities of each group.
1663 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1664 * \param [in] grps - a sequence of arrays of ids each describing a group.
1665 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1667 * \throw If names of some groups in \a grps are equal.
1668 * \throw If \a grps includes a group with an empty name.
1669 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1670 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1672 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum) throw(INTERP_KERNEL::Exception)
1676 std::set<std::string> grpsName;
1677 std::vector<std::string> grpsName2(grps.size());
1680 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1682 grpsName.insert((*it)->getName());
1683 grpsName2[i]=(*it)->getName();
1685 if(grpsName.size()!=grps.size())
1686 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1687 if(grpsName.find(std::string(""))!=grpsName.end())
1688 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1689 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1690 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1691 std::vector< std::vector<int> > fidsOfGroups;
1694 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1698 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1699 for(unsigned int ii=0;ii<grps.size();ii++)
1701 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1702 grps2[ii]->setName(grps[ii]->getName().c_str());
1704 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1705 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1708 if(!_families.empty())
1709 offset=getMaxAbsFamilyId()+1;
1710 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1711 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1712 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1713 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1717 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1718 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1719 * For the moment, the two last input parameters are not taken into account.
1721 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1723 std::map<int,std::string> famInv;
1724 for(const int *it=famIds->begin();it!=famIds->end();it++)
1726 std::ostringstream oss;
1727 oss << "Family_" << (*it);
1728 _families[oss.str()]=(*it);
1729 famInv[*it]=oss.str();
1732 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1734 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1736 _groups[grpNames[i]].push_back(famInv[*it2]);
1741 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
1743 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1744 return mLev->getDistributionOfTypes();
1747 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1749 famArr->applyLin(offset>0?1:-1,offset,0);
1750 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1753 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1754 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1759 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1760 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1761 * If this method fails to find such a name it will throw an exception.
1763 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid) throw(INTERP_KERNEL::Exception)
1766 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1769 std::size_t len=nameTry.length();
1770 for(std::size_t ii=1;ii<len;ii++)
1772 std::string tmp=nameTry.substr(ii,len-ii);
1773 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1779 for(std::size_t i=1;i<30;i++)
1781 std::string tmp1(nameTry.at(0),i);
1783 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1789 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1791 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1793 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1796 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt) throw(INTERP_KERNEL::Exception)
1798 std::size_t nbOfChunks=code.size()/3;
1799 if(code.size()%3!=0)
1800 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1802 for(std::size_t i=0;i<nbOfChunks;i++)
1811 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1812 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1813 * If _name is not empty and that 'm' has the same name nothing is done.
1814 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1816 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL::Exception)
1819 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1824 std::string name(m->getName());
1829 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1830 oss << name << "' ! Names must match !";
1831 throw INTERP_KERNEL::Exception(oss.str().c_str());
1835 if(_desc_name.empty())
1836 _desc_name=m->getDescription();
1839 std::string name(m->getDescription());
1842 if(_desc_name!=name)
1844 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1845 oss << name << "' ! Names must match !";
1846 throw INTERP_KERNEL::Exception(oss.str().c_str());
1852 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1854 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1855 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1857 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1858 oss << " - Groups lying on this family : ";
1859 std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
1860 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1861 oss << std::endl << std::endl;
1866 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1867 * file. The mesh to load is specified by its name and numbers of a time step and an
1869 * \param [in] fileName - the name of MED file to read.
1870 * \param [in] mName - the name of the mesh to read.
1871 * \param [in] dt - the number of a time step.
1872 * \param [in] it - the number of an iteration.
1873 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1874 * mesh using decrRef() as it is no more needed.
1875 * \throw If the file is not readable.
1876 * \throw If there is no mesh with given attributes in the file.
1877 * \throw If the mesh in the file is not an unstructured one.
1879 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
1881 MEDFileUtilities::CheckFileForRead(fileName);
1882 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1883 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1887 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1888 * file. The first mesh in the file is loaded.
1889 * \param [in] fileName - the name of MED file to read.
1890 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1891 * mesh using decrRef() as it is no more needed.
1892 * \throw If the file is not readable.
1893 * \throw If there is no meshes in the file.
1894 * \throw If the mesh in the file is not an unstructured one.
1896 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
1898 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1901 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1902 throw INTERP_KERNEL::Exception(oss.str().c_str());
1904 MEDFileUtilities::CheckFileForRead(fileName);
1905 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1907 ParaMEDMEM::MEDCouplingMeshType meshType;
1909 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
1910 return new MEDFileUMesh(fid,ms.front().c_str(),dt,it,mrs);
1914 * Returns an empty instance of MEDFileUMesh.
1915 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1916 * mesh using decrRef() as it is no more needed.
1918 MEDFileUMesh *MEDFileUMesh::New()
1920 return new MEDFileUMesh;
1923 std::size_t MEDFileUMesh::getHeapMemorySize() const
1925 std::size_t ret=MEDFileMesh::getHeapMemorySize();
1926 if((const DataArrayDouble*)_coords)
1927 ret+=_coords->getHeapMemorySize();
1928 if((const DataArrayInt *)_fam_coords)
1929 ret+=_fam_coords->getHeapMemorySize();
1930 if((const DataArrayInt *)_num_coords)
1931 ret+=_num_coords->getHeapMemorySize();
1932 if((const DataArrayInt *)_rev_num_coords)
1933 ret+=_rev_num_coords->getHeapMemorySize();
1934 if((const DataArrayAsciiChar *)_name_coords)
1935 ret+=_name_coords->getHeapMemorySize();
1936 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1937 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1938 if((const MEDFileUMeshSplitL1*) *it)
1939 ret+=(*it)->getHeapMemorySize();
1943 MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
1945 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1949 MEDFileMesh *MEDFileUMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
1951 return new MEDFileUMesh;
1954 MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
1956 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1957 if((const DataArrayDouble*)_coords)
1958 ret->_coords=_coords->deepCpy();
1959 if((const DataArrayInt*)_fam_coords)
1960 ret->_fam_coords=_fam_coords->deepCpy();
1961 if((const DataArrayInt*)_num_coords)
1962 ret->_num_coords=_num_coords->deepCpy();
1963 if((const DataArrayInt*)_rev_num_coords)
1964 ret->_rev_num_coords=_rev_num_coords->deepCpy();
1965 if((const DataArrayAsciiChar*)_name_coords)
1966 ret->_name_coords=_name_coords->deepCpy();
1968 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
1970 if((const MEDFileUMeshSplitL1 *)(*it))
1971 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
1977 * Checks if \a this and another mesh are equal.
1978 * \param [in] other - the mesh to compare with.
1979 * \param [in] eps - a precision used to compare real values.
1980 * \param [in,out] what - the string returning description of unequal data.
1981 * \return bool - \c true if the meshes are equal, \c false, else.
1983 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
1985 if(!MEDFileMesh::isEqual(other,eps,what))
1987 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
1990 what="Mesh types differ ! This is unstructured and other is NOT !";
1993 clearNonDiscrAttributes();
1994 otherC->clearNonDiscrAttributes();
1995 const DataArrayDouble *coo1=_coords;
1996 const DataArrayDouble *coo2=otherC->_coords;
1997 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
1999 what="Mismatch of coordinates ! One is defined and not other !";
2004 bool ret=coo1->isEqual(*coo2,eps);
2007 what="Coords differ !";
2011 const DataArrayInt *famc1=_fam_coords;
2012 const DataArrayInt *famc2=otherC->_fam_coords;
2013 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2015 what="Mismatch of families arr on nodes ! One is defined and not other !";
2020 bool ret=famc1->isEqual(*famc2);
2023 what="Families arr on node differ !";
2027 const DataArrayInt *numc1=_num_coords;
2028 const DataArrayInt *numc2=otherC->_num_coords;
2029 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2031 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2036 bool ret=numc1->isEqual(*numc2);
2039 what="Numbering arr on node differ !";
2043 const DataArrayAsciiChar *namec1=_name_coords;
2044 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2045 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2047 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2052 bool ret=namec1->isEqual(*namec2);
2055 what="Names arr on node differ !";
2059 if(_ms.size()!=otherC->_ms.size())
2061 what="Number of levels differs !";
2064 std::size_t sz=_ms.size();
2065 for(std::size_t i=0;i<sz;i++)
2067 const MEDFileUMeshSplitL1 *s1=_ms[i];
2068 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2069 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2071 what="Mismatch of presence of sub levels !";
2076 bool ret=s1->isEqual(s2,eps,what);
2085 * Clears redundant attributes of incorporated data arrays.
2087 void MEDFileUMesh::clearNonDiscrAttributes() const
2089 MEDFileMesh::clearNonDiscrAttributes();
2090 const DataArrayDouble *coo1=_coords;
2092 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2093 const DataArrayInt *famc1=_fam_coords;
2095 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2096 const DataArrayInt *numc1=_num_coords;
2098 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2099 const DataArrayAsciiChar *namc1=_name_coords;
2101 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2102 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2104 const MEDFileUMeshSplitL1 *tmp=(*it);
2106 tmp->clearNonDiscrAttributes();
2110 MEDFileUMesh::MEDFileUMesh()
2114 MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
2117 loadUMeshFromFile(fid,mName,dt,it,mrs);
2119 catch(INTERP_KERNEL::Exception& e)
2124 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
2126 MEDFileUMeshL2 loaderl2;
2127 ParaMEDMEM::MEDCouplingMeshType meshType;
2130 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
2131 if(meshType!=UNSTRUCTURED)
2133 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2134 throw INTERP_KERNEL::Exception(oss.str().c_str());
2136 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2137 int lev=loaderl2.getNumberOfLevels();
2139 for(int i=0;i<lev;i++)
2141 if(!loaderl2.emptyLev(i))
2142 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2146 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2148 setName(loaderl2.getName());
2149 setDescription(loaderl2.getDescription());
2150 setUnivName(loaderl2.getUnivName());
2151 setIteration(loaderl2.getIteration());
2152 setOrder(loaderl2.getOrder());
2153 setTimeValue(loaderl2.getTime());
2154 setTimeUnit(loaderl2.getTimeUnit());
2155 _coords=loaderl2.getCoords();
2156 if(!mrs || mrs->isNodeFamilyFieldReading())
2157 _fam_coords=loaderl2.getCoordsFamily();
2158 if(!mrs || mrs->isNodeNumFieldReading())
2159 _num_coords=loaderl2.getCoordsNum();
2160 if(!mrs || mrs->isNodeNameFieldReading())
2161 _name_coords=loaderl2.getCoordsName();
2165 MEDFileUMesh::~MEDFileUMesh()
2169 void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
2171 const DataArrayDouble *coo=_coords;
2172 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2173 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2174 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2175 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2176 int spaceDim=coo?coo->getNumberOfComponents():0;
2177 int mdim=getMeshDimension();
2178 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2179 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2180 for(int i=0;i<spaceDim;i++)
2182 std::string info=coo->getInfoOnComponent(i);
2184 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2185 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
2186 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
2188 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2189 MEDmeshUniversalNameWr(fid,maa);
2190 MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2191 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2192 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2193 (*it)->write(fid,maa,mdim);
2194 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
2198 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2199 * \return std::vector<int> - a sequence of the relative dimensions.
2201 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2203 std::vector<int> ret;
2205 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2206 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2213 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2214 * \return std::vector<int> - a sequence of the relative dimensions.
2216 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2218 std::vector<int> ret0=getNonEmptyLevels();
2219 if((const DataArrayDouble *) _coords)
2221 std::vector<int> ret(ret0.size()+1);
2223 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2229 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2231 std::vector<int> ret;
2232 const DataArrayInt *famCoo(_fam_coords);
2236 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2238 const MEDFileUMeshSplitL1 *cur(*it);
2240 if(cur->getFamilyField())
2246 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2248 std::vector<int> ret;
2249 const DataArrayInt *numCoo(_num_coords);
2253 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2255 const MEDFileUMeshSplitL1 *cur(*it);
2257 if(cur->getNumberField())
2263 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2265 std::vector<int> ret;
2266 const DataArrayAsciiChar *nameCoo(_name_coords);
2270 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2272 const MEDFileUMeshSplitL1 *cur(*it);
2274 if(cur->getNameField())
2281 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2282 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2283 * \param [in] grp - the name of the group of interest.
2284 * \return std::vector<int> - a sequence of the relative dimensions.
2286 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const throw(INTERP_KERNEL::Exception)
2288 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2289 return getFamsNonEmptyLevels(fams);
2293 * Returns all relative mesh levels (including nodes) where a given group is defined.
2294 * \param [in] grp - the name of the group of interest.
2295 * \return std::vector<int> - a sequence of the relative dimensions.
2297 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const throw(INTERP_KERNEL::Exception)
2299 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2300 return getFamsNonEmptyLevelsExt(fams);
2304 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2305 * To include nodes, call getFamNonEmptyLevelsExt() method.
2306 * \param [in] fam - the name of the family of interest.
2307 * \return std::vector<int> - a sequence of the relative dimensions.
2309 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const throw(INTERP_KERNEL::Exception)
2311 std::vector<std::string> fams(1,std::string(fam));
2312 return getFamsNonEmptyLevels(fams);
2316 * Returns all relative mesh levels (including nodes) where a given family is defined.
2317 * \param [in] fam - the name of the family of interest.
2318 * \return std::vector<int> - a sequence of the relative dimensions.
2320 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const throw(INTERP_KERNEL::Exception)
2322 std::vector<std::string> fams(1,std::string(fam));
2323 return getFamsNonEmptyLevelsExt(fams);
2327 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2328 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2329 * \param [in] grps - a sequence of names of the groups of interest.
2330 * \return std::vector<int> - a sequence of the relative dimensions.
2332 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2334 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2335 return getFamsNonEmptyLevels(fams);
2339 * Returns all relative mesh levels (including nodes) where given groups are defined.
2340 * \param [in] grps - a sequence of names of the groups of interest.
2341 * \return std::vector<int> - a sequence of the relative dimensions.
2343 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2345 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2346 return getFamsNonEmptyLevelsExt(fams);
2350 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2351 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2352 * \param [in] fams - the name of the family of interest.
2353 * \return std::vector<int> - a sequence of the relative dimensions.
2355 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2357 std::vector<int> ret;
2358 std::vector<int> levs=getNonEmptyLevels();
2359 std::vector<int> famIds=getFamiliesIds(fams);
2360 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2361 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2367 * Returns all relative mesh levels (including nodes) where given families are defined.
2368 * \param [in] fams - the names of the families of interest.
2369 * \return std::vector<int> - a sequence of the relative dimensions.
2371 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2373 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2374 const DataArrayInt *famCoords=_fam_coords;
2377 std::vector<int> famIds=getFamiliesIds(fams);
2378 if(famCoords->presenceOfValue(famIds))
2380 std::vector<int> ret(ret0.size()+1);
2382 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2390 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2391 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2392 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2395 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2397 std::vector<std::string> ret;
2398 std::vector<std::string> allGrps=getGroupsNames();
2399 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2401 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it).c_str());
2402 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2408 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2410 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2411 if((const DataArrayInt *)_fam_coords)
2413 int val=_fam_coords->getMaxValue(tmp);
2414 ret=std::max(ret,std::abs(val));
2416 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2418 if((const MEDFileUMeshSplitL1 *)(*it))
2420 const DataArrayInt *da=(*it)->getFamilyField();
2423 int val=da->getMaxValue(tmp);
2424 ret=std::max(ret,std::abs(val));
2431 int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2433 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2434 if((const DataArrayInt *)_fam_coords)
2436 int val=_fam_coords->getMaxValue(tmp);
2437 ret=std::max(ret,val);
2439 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2441 if((const MEDFileUMeshSplitL1 *)(*it))
2443 const DataArrayInt *da=(*it)->getFamilyField();
2446 int val=da->getMaxValue(tmp);
2447 ret=std::max(ret,val);
2454 int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2456 int ret=std::numeric_limits<int>::max(),tmp=-1;
2457 if((const DataArrayInt *)_fam_coords)
2459 int val=_fam_coords->getMinValue(tmp);
2460 ret=std::min(ret,val);
2462 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2464 if((const MEDFileUMeshSplitL1 *)(*it))
2466 const DataArrayInt *da=(*it)->getFamilyField();
2469 int val=da->getMinValue(tmp);
2470 ret=std::min(ret,val);
2478 * Returns the dimension on cells in \a this mesh.
2479 * \return int - the mesh dimension.
2480 * \throw If there are no cells in this mesh.
2482 int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
2485 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2486 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2487 return (*it)->getMeshDimension()+lev;
2488 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2492 * Returns the space dimension of \a this mesh that is equal to number of components in
2493 * the node coordinates array.
2494 * \return int - the space dimension of \a this mesh.
2495 * \throw If the node coordinates array is not available.
2497 int MEDFileUMesh::getSpaceDimension() const throw(INTERP_KERNEL::Exception)
2499 const DataArrayDouble *coo=_coords;
2501 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2502 return coo->getNumberOfComponents();
2506 * Returns a string describing \a this mesh.
2507 * \return std::string - the mesh information string.
2509 std::string MEDFileUMesh::simpleRepr() const
2511 std::ostringstream oss;
2512 oss << MEDFileMesh::simpleRepr();
2513 const DataArrayDouble *coo=_coords;
2514 oss << "- The dimension of the space is ";
2515 static const char MSG1[]= "*** NO COORDS SET ***";
2516 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2518 oss << _coords->getNumberOfComponents() << std::endl;
2520 oss << MSG1 << std::endl;
2521 oss << "- Type of the mesh : UNSTRUCTURED\n";
2522 oss << "- Number of nodes : ";
2524 oss << _coords->getNumberOfTuples() << std::endl;
2526 oss << MSG1 << std::endl;
2527 std::size_t nbOfLev=_ms.size();
2528 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2529 for(std::size_t i=0;i<nbOfLev;i++)
2531 const MEDFileUMeshSplitL1 *lev=_ms[i];
2532 oss << " - Level #" << -((int) i) << " has dimension : ";
2535 oss << lev->getMeshDimension() << std::endl;
2536 lev->simpleRepr(oss);
2539 oss << MSG2 << std::endl;
2541 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2544 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2545 oss << "- Names of coordinates :" << std::endl;
2546 std::vector<std::string> vars=coo->getVarsOnComponent();
2547 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2548 oss << std::endl << "- Units of coordinates : " << std::endl;
2549 std::vector<std::string> units=coo->getUnitsOnComponent();
2550 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2552 oss << std::endl << std::endl;
2558 * Returns a full textual description of \a this mesh.
2559 * \return std::string - the string holding the mesh description.
2561 std::string MEDFileUMesh::advancedRepr() const
2563 return simpleRepr();
2567 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2568 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2569 * \return int - the number of entities.
2570 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2572 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2574 if(meshDimRelToMaxExt==1)
2576 if(!((const DataArrayDouble *)_coords))
2577 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2578 return _coords->getNumberOfTuples();
2580 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2584 * Returns the family field for mesh entities of a given dimension.
2585 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2586 * \return const DataArrayInt * - the family field. It is an array of ids of families
2587 * each mesh entity belongs to. It can be \c NULL.
2589 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2591 if(meshDimRelToMaxExt==1)
2593 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2594 return l1->getFamilyField();
2598 * Returns the optional numbers of mesh entities of a given dimension.
2599 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2600 * \return const DataArrayInt * - the array of the entity numbers.
2601 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2603 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2605 if(meshDimRelToMaxExt==1)
2607 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2608 return l1->getNumberField();
2611 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2613 if(meshDimRelToMaxExt==1)
2614 return _name_coords;
2615 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2616 return l1->getNameField();
2619 int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
2621 const DataArrayDouble *coo=_coords;
2623 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2624 return coo->getNumberOfTuples();
2627 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
2629 std::size_t sz(st.getNumberOfItems());
2630 int mdim(getMeshDimension());
2631 for(std::size_t i=0;i<sz;i++)
2633 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2634 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(curGt);
2635 int relDim((int)cm.getDimension()-mdim);
2636 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(getMeshAtLevel(relDim));
2637 std::vector<int> d(um->getDistributionOfTypes());
2638 std::size_t nbOfTypes(d.size()/3);
2639 int offset=0,nbOfEltWT=-1;
2640 for(std::size_t j=0;j<nbOfTypes;j++)
2642 if(d[3*j]!=(int)curGt)
2645 { break; nbOfEltWT=d[3*j+1]; }
2648 throw INTERP_KERNEL::Exception("MEDFileUMesh::whichAreNodesFetched : asking for a geo type not present in this !");
2649 um=dynamic_cast<MEDCouplingUMesh *>(um->buildPartOfMySelf2(offset,offset+nbOfEltWT,1,true));
2650 if(st[i].getPflName().empty())
2651 um->computeNodeIdsAlg(nodesFetched);
2654 const DataArrayInt *arr(globs->getProfile(st[i].getPflName().c_str()));
2655 um=dynamic_cast<MEDCouplingUMesh *>(um->buildPartOfMySelf(arr->begin(),arr->end(),true));
2656 um->computeNodeIdsAlg(nodesFetched);
2662 * Returns the optional numbers of mesh entities of a given dimension transformed using
2663 * DataArrayInt::invertArrayN2O2O2N().
2664 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2665 * \return const DataArrayInt * - the array of the entity numbers transformed using
2666 * DataArrayInt::invertArrayN2O2O2N().
2667 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2669 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2671 if(meshDimRelToMaxExt==1)
2673 if(!((const DataArrayInt *)_num_coords))
2674 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2675 return _rev_num_coords;
2677 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2678 return l1->getRevNumberField();
2682 * Returns a pointer to the node coordinates array of \a this mesh \b without
2683 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2685 DataArrayDouble *MEDFileUMesh::getCoords() const
2687 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2688 if((DataArrayDouble *)tmp)
2696 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2697 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2699 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2700 * \param [in] grp - the name of the group whose mesh entities are included in the
2702 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2703 * according to the optional numbers of entities, if available.
2704 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2705 * delete this mesh using decrRef() as it is no more needed.
2706 * \throw If the name of a nonexistent group is specified.
2707 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2709 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
2711 synchronizeTinyInfoOnLeaves();
2712 std::vector<std::string> tmp(1);
2714 return getGroups(meshDimRelToMaxExt,tmp,renum);
2718 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2719 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2721 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2722 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2724 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2725 * according to the optional numbers of entities, if available.
2726 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2727 * delete this mesh using decrRef() as it is no more needed.
2728 * \throw If a name of a nonexistent group is present in \a grps.
2729 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2731 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
2733 synchronizeTinyInfoOnLeaves();
2734 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2735 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2736 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2737 zeRet->setName(grps[0].c_str());
2738 return zeRet.retn();
2742 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2743 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2745 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2746 * \param [in] fam - the name of the family whose mesh entities are included in the
2748 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2749 * according to the optional numbers of entities, if available.
2750 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2751 * delete this mesh using decrRef() as it is no more needed.
2752 * \throw If a name of a nonexistent family is present in \a grps.
2753 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2755 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
2757 synchronizeTinyInfoOnLeaves();
2758 std::vector<std::string> tmp(1);
2760 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2764 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2765 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2767 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2768 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2770 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2771 * according to the optional numbers of entities, if available.
2772 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2773 * delete this mesh using decrRef() as it is no more needed.
2774 * \throw If a name of a nonexistent family is present in \a fams.
2775 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2777 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2779 synchronizeTinyInfoOnLeaves();
2780 if(meshDimRelToMaxExt==1)
2782 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2783 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2784 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2788 std::vector<int> famIds=getFamiliesIds(fams);
2789 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2790 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2792 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2794 zeRet=l1->getFamilyPart(0,0,renum);
2795 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2796 zeRet->setName(fams[0].c_str());
2797 return zeRet.retn();
2801 * Returns ids of mesh entities contained in given families of a given dimension.
2802 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2804 * \param [in] fams - the names of the families of interest.
2805 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2806 * returned instead of ids.
2807 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2808 * numbers, if available and required, of mesh entities of the families. The caller
2809 * is to delete this array using decrRef() as it is no more needed.
2810 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2812 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2814 std::vector<int> famIds=getFamiliesIds(fams);
2815 if(meshDimRelToMaxExt==1)
2817 if((const DataArrayInt *)_fam_coords)
2819 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2821 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2823 da=_fam_coords->getIdsEqualList(0,0);
2825 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2830 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2832 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2834 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2836 return l1->getFamilyPartArr(0,0,renum);
2840 * Returns a MEDCouplingUMesh of a given relative dimension.
2841 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2842 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2843 * To build a valid MEDCouplingUMesh from the returned one in this case,
2844 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2845 * \param [in] meshDimRelToMax - the relative dimension of interest.
2846 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2847 * optional numbers of mesh entities.
2848 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2849 * delete using decrRef() as it is no more needed.
2850 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2851 * \sa getGenMeshAtLevel()
2853 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
2855 synchronizeTinyInfoOnLeaves();
2856 if(meshDimRelToMaxExt==1)
2860 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2861 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2862 umesh->setCoords(cc);
2863 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2864 umesh->setName(getName().c_str());
2868 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2869 return l1->getWholeMesh(renum);
2873 * Returns a MEDCouplingUMesh of a given relative dimension.
2874 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2875 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2876 * To build a valid MEDCouplingUMesh from the returned one in this case,
2877 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2878 * \param [in] meshDimRelToMax - the relative dimension of interest.
2879 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2880 * optional numbers of mesh entities.
2881 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2882 * delete using decrRef() as it is no more needed.
2883 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2884 * \sa getMeshAtLevel()
2886 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
2888 return getMeshAtLevel(meshDimRelToMax,renum);
2891 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2893 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
2894 return l1->getDistributionOfTypes();
2898 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2899 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2900 * optional numbers of mesh entities.
2901 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2902 * delete using decrRef() as it is no more needed.
2903 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2905 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2907 return getMeshAtLevel(0,renum);
2911 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2912 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2913 * optional numbers of mesh entities.
2914 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2915 * delete using decrRef() as it is no more needed.
2916 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2918 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2920 return getMeshAtLevel(-1,renum);
2924 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2925 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2926 * optional numbers of mesh entities.
2927 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2928 * delete using decrRef() as it is no more needed.
2929 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
2931 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2933 return getMeshAtLevel(-2,renum);
2937 * Returns a MEDCouplingUMesh of a relative dimension == -3.
2938 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2939 * optional numbers of mesh entities.
2940 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2941 * delete using decrRef() as it is no more needed.
2942 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
2944 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2946 return getMeshAtLevel(-3,renum);
2950 * This method returns a vector of mesh parts containing each exactly one geometric type.
2951 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
2952 * This method is only for memory aware users.
2953 * The returned pointers are **NOT** new object pointer. No need to mange them.
2955 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2957 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
2958 return sp->getDirectUndergroundSingleGeoTypeMeshes();
2962 * This method returns the part of \a this having the geometric type \a gt.
2963 * If such part is not existing an exception will be thrown.
2964 * The returned pointer is **NOT** new object pointer. No need to mange it.
2966 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception)
2968 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
2969 int lev=(int)cm.getDimension()-getMeshDimension();
2970 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
2971 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
2974 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2976 if(meshDimRelToMaxExt==1)
2977 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2978 if(meshDimRelToMaxExt>1)
2979 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2980 int tracucedRk=-meshDimRelToMaxExt;
2981 if(tracucedRk>=(int)_ms.size())
2982 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2983 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2984 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2985 return _ms[tracucedRk];
2988 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2990 if(meshDimRelToMaxExt==1)
2991 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2992 if(meshDimRelToMaxExt>1)
2993 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2994 int tracucedRk=-meshDimRelToMaxExt;
2995 if(tracucedRk>=(int)_ms.size())
2996 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2997 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2998 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2999 return _ms[tracucedRk];
3002 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
3004 if(-meshDimRelToMax>=(int)_ms.size())
3005 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3007 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3009 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3011 int ref=(*it)->getMeshDimension();
3012 if(ref+i!=meshDim-meshDimRelToMax)
3013 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3019 * Sets the node coordinates array of \a this mesh.
3020 * \param [in] coords - the new node coordinates array.
3021 * \throw If \a coords == \c NULL.
3023 void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
3026 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3027 coords->checkAllocated();
3028 int nbOfTuples=coords->getNumberOfTuples();
3031 _fam_coords=DataArrayInt::New();
3032 _fam_coords->alloc(nbOfTuples,1);
3033 _fam_coords->fillWithZero();
3034 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3035 if((MEDFileUMeshSplitL1 *)(*it))
3036 (*it)->setCoords(coords);
3040 * Removes all groups of a given dimension in \a this mesh.
3041 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3042 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3044 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
3046 if(meshDimRelToMaxExt==1)
3048 if((DataArrayInt *)_fam_coords)
3049 _fam_coords->fillWithZero();
3052 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3053 l1->eraseFamilyField();
3058 * Removes all families with ids not present in the family fields of \a this mesh.
3060 void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
3062 std::vector<int> levs=getNonEmptyLevelsExt();
3063 std::set<int> allFamsIds;
3064 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3066 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3067 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3069 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3072 std::set<std::string> famNamesToKill;
3073 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3075 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3076 famNamesToKill.insert((*it).first);
3078 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3079 _families.erase(*it);
3080 std::vector<std::string> grpNamesToKill;
3081 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3083 std::vector<std::string> tmp;
3084 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3086 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3087 tmp.push_back(*it2);
3092 tmp.push_back((*it).first);
3094 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3098 void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception)
3100 std::vector<int> levs=getNonEmptyLevels();
3101 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3102 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3103 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3104 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3105 int nbNodes=m0->getNumberOfNodes();
3106 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3107 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3108 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3109 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3110 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3111 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3112 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3113 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3114 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3115 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3116 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3117 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3118 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3119 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3120 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3121 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3122 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3123 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3124 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3125 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3126 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3127 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3128 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3129 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3130 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3131 m0->setCoords(tmp0->getCoords());
3132 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3133 m1->setCoords(m0->getCoords());
3134 _coords=m0->getCoords(); _coords->incrRef();
3135 // duplication of cells in group 'grpNameM1' on level -1
3136 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3137 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3138 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3139 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3140 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3142 newm1->setName(getName().c_str());
3143 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3145 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3146 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3147 newFam->alloc(newm1->getNumberOfCells(),1);
3148 int idd=getMaxFamilyId()+1;
3149 int globStart=0,start=0,end,globEnd;
3150 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3151 for(int i=0;i<nbOfChunks;i++)
3153 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3154 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3156 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3157 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3158 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3163 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3167 newm1->setCoords(getCoords());
3168 setMeshAtLevel(-1,newm1);
3169 setFamilyFieldArr(-1,newFam);
3170 std::string grpName2(grpNameM1); grpName2+="_dup";
3171 addFamily(grpName2.c_str(),idd);
3172 addFamilyOnGrp(grpName2.c_str(),grpName2.c_str());
3177 int newNbOfNodes=getCoords()->getNumberOfTuples();
3178 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3179 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3180 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3183 nodesDuplicated=nodeIdsToDuplicate.retn();
3184 cellsModified=cellsToModifyConn0.retn();
3185 cellsNotModified=cellsToModifyConn1.retn();
3189 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3190 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3191 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3193 * \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.
3194 * 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.
3196 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
3198 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3199 std::vector<int> levs=getNonEmptyLevels();
3201 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3202 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3205 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3207 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3208 std::vector<int> code1=m->getDistributionOfTypes();
3209 end=PutInThirdComponentOfCodeOffset(code1,start);
3210 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3211 bool hasChanged=m->unPolyze();
3212 DataArrayInt *fake=0;
3213 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3214 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3216 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3219 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3220 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3222 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3223 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3224 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3225 setMeshAtLevel(*it,m);
3226 std::vector<int> code2=m->getDistributionOfTypes();
3227 end=PutInThirdComponentOfCodeOffset(code2,start);
3228 newCode.insert(newCode.end(),code2.begin(),code2.end());
3230 if(o2nCellsPart2->isIdentity())
3234 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3235 setFamilyFieldArr(*it,newFamField);
3239 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3240 setRenumFieldArr(*it,newNumField);
3245 newCode.insert(newCode.end(),code1.begin(),code1.end());
3251 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3252 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3253 o2nRenumCell=o2nRenumCellRet.retn();
3258 struct MEDLoaderAccVisit1
3260 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3261 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3262 int _new_nb_of_nodes;
3266 * 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.
3267 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3268 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3269 * -1 values in returned array means that the corresponding old node is no more used.
3271 * \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
3272 * is modified in \a this.
3273 * \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
3276 DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
3278 const DataArrayDouble *coo=getCoords();
3280 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3281 int nbOfNodes=coo->getNumberOfTuples();
3282 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3283 std::vector<int> neLevs=getNonEmptyLevels();
3284 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3286 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3287 m->computeNodeIdsAlg(nodeIdsInUse);
3289 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3290 if(nbrOfNodesInUse==nbOfNodes)
3292 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3293 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3294 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3295 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3296 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3297 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3298 if((const DataArrayInt *)_fam_coords)
3299 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3300 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3301 if((const DataArrayInt *)_num_coords)
3302 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3303 if((const DataArrayAsciiChar *)_name_coords)
3304 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3305 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3306 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3308 if((MEDFileUMeshSplitL1*)*it)
3309 (*it)->renumberNodesInConn(ret->begin());
3315 * Adds a group of nodes to \a this mesh.
3316 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3317 * The ids should be sorted and different each other (MED file norm).
3318 * \throw If the node coordinates array is not set.
3319 * \throw If \a ids == \c NULL.
3320 * \throw If \a ids->getName() == "".
3321 * \throw If \a ids does not respect the MED file norm.
3322 * \throw If a group with name \a ids->getName() already exists.
3324 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3326 const DataArrayDouble *coords=_coords;
3328 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3329 int nbOfNodes=coords->getNumberOfTuples();
3330 if(!((DataArrayInt *)_fam_coords))
3331 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3333 addGroupUnderground(true,ids,_fam_coords);
3337 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3338 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3339 * The ids should be sorted and different each other (MED file norm).
3340 * \throw If the node coordinates array is not set.
3341 * \throw If \a ids == \c NULL.
3342 * \throw If \a ids->getName() == "".
3343 * \throw If \a ids does not respect the MED file norm.
3344 * \throw If a group with name \a ids->getName() already exists.
3346 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3348 std::vector<int> levs=getNonEmptyLevelsExt();
3349 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3351 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3352 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3354 if(meshDimRelToMaxExt==1)
3355 { addNodeGroup(ids); return ; }
3356 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3357 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3358 addGroupUnderground(false,ids,fam);
3362 * \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).
3363 * \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)
3365 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3368 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3369 std::string grpName(ids->getName());
3371 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3372 ids->checkStrictlyMonotonic(true);
3373 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3374 std::vector<std::string> grpsNames=getGroupsNames();
3375 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3377 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3378 throw INTERP_KERNEL::Exception(oss.str().c_str());
3380 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3381 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3382 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3383 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3384 std::vector<int> familyIds;
3385 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3386 int maxVal=getTheMaxAbsFamilyId()+1;
3387 std::map<std::string,int> families(_families);
3388 std::map<std::string, std::vector<std::string> > groups(_groups);
3389 std::vector<std::string> fams;
3390 bool created(false);
3391 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3393 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3394 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3395 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3396 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3399 bool isFamPresent=false;
3400 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3401 isFamPresent=(*itl)->presenceOfValue(*famId);
3403 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3406 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3407 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3408 fams.push_back(locFamName);
3409 if(existsFamily(*famId))
3411 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3412 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3415 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3419 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3420 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3421 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3422 if(existsFamily(*famId))
3424 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3425 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3430 for(std::size_t i=0;i<familyIds.size();i++)
3432 DataArrayInt *da=idsPerfamiliyIds[i];
3433 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3437 _groups[grpName]=fams;
3441 * Changes a name of a family specified by its id.
3442 * \param [in] id - the id of the family of interest.
3443 * \param [in] newFamName - the new family name.
3444 * \throw If no family with the given \a id exists.
3446 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
3448 std::string oldName=getFamilyNameGivenId(id);
3449 _families.erase(oldName);
3450 _families[newFamName]=id;
3454 * Removes a mesh of a given dimension.
3455 * \param [in] meshDimRelToMax - the relative dimension of interest.
3456 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3458 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
3460 std::vector<int> levSet=getNonEmptyLevels();
3461 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3462 if(it==levSet.end())
3463 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3464 int pos=(-meshDimRelToMax);
3469 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3470 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3471 * \param [in] m - the new mesh to set.
3472 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3473 * writing \a this mesh in a MED file.
3474 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3476 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3477 * another node coordinates array.
3478 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3479 * to the existing meshes of other levels of \a this mesh.
3481 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
3483 dealWithTinyInfo(m);
3484 std::vector<int> levSet=getNonEmptyLevels();
3485 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3487 if((DataArrayDouble *)_coords==0)
3489 DataArrayDouble *c=m->getCoords();
3494 if(m->getCoords()!=_coords)
3495 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3496 int sz=(-meshDimRelToMax)+1;
3497 if(sz>=(int)_ms.size())
3499 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3500 _ms[sz-1]=new MEDFileUMeshSplitL1(m,newOrOld);
3503 _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld);
3507 * This method allows to set at once the content of different levels in \a this.
3508 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3510 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3511 * \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.
3512 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3514 * \throw If \a there is a null pointer in \a ms.
3515 * \sa MEDFileUMesh::setMeshAtLevel
3517 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3521 const MEDCouplingUMesh *mRef=ms[0];
3523 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3524 std::string name(mRef->getName());
3525 const DataArrayDouble *coo(mRef->getCoords());
3528 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3530 const MEDCouplingUMesh *cur(*it);
3532 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3533 if(coo!=cur->getCoords())
3534 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3535 int mdim=cur->getMeshDimension();
3536 zeDim=std::max(zeDim,mdim);
3537 if(s.find(mdim)!=s.end())
3538 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3540 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3542 int mdim=(*it)->getMeshDimension();
3543 setName((*it)->getName().c_str());
3544 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3546 setName(name.c_str());
3550 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3551 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3552 * The given meshes must share the same node coordinates array.
3553 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3554 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3555 * create in \a this mesh.
3556 * \throw If \a ms is empty.
3557 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3558 * to the existing meshes of other levels of \a this mesh.
3559 * \throw If the meshes in \a ms do not share the same node coordinates array.
3560 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3561 * of the given meshes.
3562 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3563 * \throw If names of some meshes in \a ms are equal.
3564 * \throw If \a ms includes a mesh with an empty name.
3566 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3569 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3570 int sz=(-meshDimRelToMax)+1;
3571 if(sz>=(int)_ms.size())
3573 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3574 DataArrayDouble *coo=checkMultiMesh(ms);
3575 if((DataArrayDouble *)_coords==0)
3581 if((DataArrayDouble *)_coords!=coo)
3582 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3583 std::vector<DataArrayInt *> corr;
3584 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3585 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3586 setMeshAtLevel(meshDimRelToMax,m,renum);
3587 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3588 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3592 * Creates groups at a given level in \a this mesh from a sequence of
3593 * meshes each representing a group.
3594 * The given meshes must share the same node coordinates array.
3595 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3596 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3597 * create in \a this mesh.
3598 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3600 * \throw If \a ms is empty.
3601 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3602 * to the existing meshes of other levels of \a this mesh.
3603 * \throw If the meshes in \a ms do not share the same node coordinates array.
3604 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3605 * of the given meshes.
3606 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3607 * \throw If names of some meshes in \a ms are equal.
3608 * \throw If \a ms includes a mesh with an empty name.
3610 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3613 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3614 int sz=(-meshDimRelToMax)+1;
3615 if(sz>=(int)_ms.size())
3617 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3618 DataArrayDouble *coo=checkMultiMesh(ms);
3619 if((DataArrayDouble *)_coords==0)
3625 if((DataArrayDouble *)_coords!=coo)
3626 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3627 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3628 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3630 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3632 DataArrayInt *arr=0;
3633 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3637 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3638 throw INTERP_KERNEL::Exception(oss.str().c_str());
3641 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3642 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3645 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const throw(INTERP_KERNEL::Exception)
3647 const DataArrayDouble *ret=ms[0]->getCoords();
3648 int mdim=ms[0]->getMeshDimension();
3649 for(unsigned int i=1;i<ms.size();i++)
3651 ms[i]->checkCoherency();
3652 if(ms[i]->getCoords()!=ret)
3653 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3654 if(ms[i]->getMeshDimension()!=mdim)
3655 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3657 return const_cast<DataArrayDouble *>(ret);
3661 * Sets the family field of a given relative dimension.
3662 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3663 * the family field is set.
3664 * \param [in] famArr - the array of the family field.
3665 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3666 * \throw If \a famArr has an invalid size.
3668 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3670 if(meshDimRelToMaxExt==1)
3677 DataArrayDouble *coo(_coords);
3679 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3680 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3685 if(meshDimRelToMaxExt>1)
3686 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3687 int traducedRk=-meshDimRelToMaxExt;
3688 if(traducedRk>=(int)_ms.size())
3689 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3690 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3691 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3692 return _ms[traducedRk]->setFamilyArr(famArr);
3696 * Sets the optional numbers of mesh entities of a given dimension.
3697 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3698 * \param [in] renumArr - the array of the numbers.
3699 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3700 * \throw If \a renumArr has an invalid size.
3702 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
3704 if(meshDimRelToMaxExt==1)
3712 DataArrayDouble *coo(_coords);
3714 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3715 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3716 renumArr->incrRef();
3717 _num_coords=renumArr;
3721 if(meshDimRelToMaxExt>1)
3722 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3723 int traducedRk=-meshDimRelToMaxExt;
3724 if(traducedRk>=(int)_ms.size())
3725 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3726 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3727 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3728 return _ms[traducedRk]->setRenumArr(renumArr);
3732 * Sets the optional names of mesh entities of a given dimension.
3733 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3734 * \param [in] nameArr - the array of the names.
3735 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3736 * \throw If \a nameArr has an invalid size.
3738 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
3740 if(meshDimRelToMaxExt==1)
3747 DataArrayDouble *coo(_coords);
3749 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3750 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3752 _name_coords=nameArr;
3755 if(meshDimRelToMaxExt>1)
3756 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3757 int traducedRk=-meshDimRelToMaxExt;
3758 if(traducedRk>=(int)_ms.size())
3759 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3760 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3761 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3762 return _ms[traducedRk]->setNameArr(nameArr);
3765 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3767 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3768 if((const MEDFileUMeshSplitL1 *)(*it))
3769 (*it)->synchronizeTinyInfo(*this);
3773 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3775 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
3777 DataArrayInt *arr=_fam_coords;
3779 arr->changeValue(oldId,newId);
3780 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3782 MEDFileUMeshSplitL1 *sp=(*it);
3785 sp->changeFamilyIdArr(oldId,newId);
3790 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3792 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3793 const DataArrayInt *da(_fam_coords);
3795 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3796 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3798 const MEDFileUMeshSplitL1 *elt(*it);
3801 da=elt->getFamilyField();
3803 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3809 void MEDFileUMesh::computeRevNum() const
3811 if((const DataArrayInt *)_num_coords)
3814 int maxValue=_num_coords->getMaxValue(pos);
3815 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3819 std::size_t MEDFileStructuredMesh::getHeapMemorySize() const
3821 std::size_t ret=MEDFileMesh::getHeapMemorySize();
3822 if((const DataArrayInt*)_fam_nodes)
3823 ret+=_fam_nodes->getHeapMemorySize();
3824 if((const DataArrayInt*)_num_nodes)
3825 ret+=_num_nodes->getHeapMemorySize();
3826 if((const DataArrayInt*)_fam_cells)
3827 ret+=_fam_cells->getHeapMemorySize();
3828 if((const DataArrayInt*)_num_cells)
3829 ret+=_num_cells->getHeapMemorySize();
3830 if((const DataArrayInt*)_rev_num_nodes)
3831 ret+=_rev_num_nodes->getHeapMemorySize();
3832 if((const DataArrayInt*)_rev_num_cells)
3833 ret+=_rev_num_cells->getHeapMemorySize();
3837 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3839 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3840 if((const DataArrayInt *)_fam_nodes)
3842 int val=_fam_nodes->getMaxValue(tmp);
3843 ret=std::max(ret,std::abs(val));
3845 if((const DataArrayInt *)_fam_cells)
3847 int val=_fam_cells->getMaxValue(tmp);
3848 ret=std::max(ret,std::abs(val));
3853 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3855 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3856 if((const DataArrayInt *)_fam_nodes)
3858 int val=_fam_nodes->getMaxValue(tmp);
3859 ret=std::max(ret,val);
3861 if((const DataArrayInt *)_fam_cells)
3863 int val=_fam_cells->getMaxValue(tmp);
3864 ret=std::max(ret,val);
3869 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3871 int ret=std::numeric_limits<int>::max(),tmp=-1;
3872 if((const DataArrayInt *)_fam_nodes)
3874 int val=_fam_nodes->getMinValue(tmp);
3875 ret=std::min(ret,val);
3877 if((const DataArrayInt *)_fam_cells)
3879 int val=_fam_cells->getMinValue(tmp);
3880 ret=std::min(ret,val);
3885 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3887 if(!MEDFileMesh::isEqual(other,eps,what))
3889 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
3892 what="Mesh types differ ! This is structured and other is NOT !";
3895 const DataArrayInt *famc1=_fam_nodes;
3896 const DataArrayInt *famc2=otherC->_fam_nodes;
3897 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3899 what="Mismatch of families arr on nodes ! One is defined and not other !";
3904 bool ret=famc1->isEqual(*famc2);
3907 what="Families arr on nodes differ !";
3912 famc2=otherC->_fam_cells;
3913 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3915 what="Mismatch of families arr on cells ! One is defined and not other !";
3920 bool ret=famc1->isEqual(*famc2);
3923 what="Families arr on cells differ !";
3928 famc2=otherC->_num_nodes;
3929 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3931 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
3936 bool ret=famc1->isEqual(*famc2);
3939 what="Numbering arr on nodes differ !";
3944 famc2=otherC->_num_cells;
3945 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3947 what="Mismatch of numbering arr on cells ! One is defined and not other !";
3952 bool ret=famc1->isEqual(*famc2);
3955 what="Numbering arr on cells differ !";
3959 const DataArrayAsciiChar *d1=_names_cells;
3960 const DataArrayAsciiChar *d2=otherC->_names_cells;
3961 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3963 what="Mismatch of naming arr on cells ! One is defined and not other !";
3968 bool ret=d1->isEqual(*d2);
3971 what="Naming arr on cells differ !";
3976 d2=otherC->_names_nodes;
3977 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3979 what="Mismatch of naming arr on nodes ! One is defined and not other !";
3984 bool ret=d1->isEqual(*d2);
3987 what="Naming arr on nodes differ !";
3994 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
3996 MEDFileMesh::clearNonDiscrAttributes();
3997 const DataArrayInt *tmp=_fam_nodes;
3999 (const_cast<DataArrayInt *>(tmp))->setName("");
4002 (const_cast<DataArrayInt *>(tmp))->setName("");
4005 (const_cast<DataArrayInt *>(tmp))->setName("");
4008 (const_cast<DataArrayInt *>(tmp))->setName("");
4012 * Returns ids of mesh entities contained in given families of a given dimension.
4013 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4015 * \param [in] fams - the names of the families of interest.
4016 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4017 * returned instead of ids.
4018 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4019 * numbers, if available and required, of mesh entities of the families. The caller
4020 * is to delete this array using decrRef() as it is no more needed.
4021 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4023 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
4025 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4026 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
4027 std::vector<int> famIds=getFamiliesIds(fams);
4028 if(meshDimRelToMaxExt==1)
4030 if((const DataArrayInt *)_fam_nodes)
4032 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4034 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4036 da=_fam_nodes->getIdsEqualList(0,0);
4038 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4043 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4047 if((const DataArrayInt *)_fam_cells)
4049 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4051 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4053 da=_fam_cells->getIdsEqualList(0,0);
4055 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4060 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4065 * Sets the family field of a given relative dimension.
4066 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4067 * the family field is set.
4068 * \param [in] famArr - the array of the family field.
4069 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4070 * \throw If \a famArr has an invalid size.
4071 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4073 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
4075 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4076 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4077 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4079 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4080 if(meshDimRelToMaxExt==0)
4082 int nbCells=mesh->getNumberOfCells();
4083 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4088 int nbNodes=mesh->getNumberOfNodes();
4089 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4097 * Sets the optional numbers of mesh entities of a given dimension.
4098 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4099 * \param [in] renumArr - the array of the numbers.
4100 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4101 * \throw If \a renumArr has an invalid size.
4102 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4104 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
4106 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4107 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4108 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4110 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4111 if(meshDimRelToMaxExt==0)
4113 int nbCells=mesh->getNumberOfCells();
4114 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4115 _num_cells=renumArr;
4119 int nbNodes=mesh->getNumberOfNodes();
4120 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4121 _num_nodes=renumArr;
4124 renumArr->incrRef();
4128 * Sets the optional names of mesh entities of a given dimension.
4129 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4130 * \param [in] nameArr - the array of the names.
4131 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4132 * \throw If \a nameArr has an invalid size.
4134 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
4136 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4137 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
4138 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4140 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4141 if(meshDimRelToMaxExt==0)
4143 int nbCells=mesh->getNumberOfCells();
4144 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4145 _names_cells=nameArr;
4149 int nbNodes=mesh->getNumberOfNodes();
4150 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4151 _names_nodes=nameArr;
4158 * Returns the family field for mesh entities of a given dimension.
4159 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4160 * \return const DataArrayInt * - the family field. It is an array of ids of families
4161 * each mesh entity belongs to. It can be \c NULL.
4162 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4164 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4166 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4167 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
4168 if(meshDimRelToMaxExt==0)
4175 * Returns the optional numbers of mesh entities of a given dimension.
4176 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4177 * \return const DataArrayInt * - the array of the entity numbers.
4178 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4179 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4181 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4183 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4184 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
4185 if(meshDimRelToMaxExt==0)
4192 * Returns the optional numbers of mesh entities of a given dimension transformed using
4193 * DataArrayInt::invertArrayN2O2O2N().
4194 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4195 * \return const DataArrayInt * - the array of the entity numbers transformed using
4196 * DataArrayInt::invertArrayN2O2O2N().
4197 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4198 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4200 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4202 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4203 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4204 if(meshDimRelToMaxExt==0)
4206 if((const DataArrayInt *)_num_cells)
4209 int maxValue=_num_cells->getMaxValue(pos);
4210 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4211 return _rev_num_cells;
4214 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4218 if((const DataArrayInt *)_num_nodes)
4221 int maxValue=_num_nodes->getMaxValue(pos);
4222 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4223 return _rev_num_nodes;
4226 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4230 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4232 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4233 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
4234 if(meshDimRelToMaxExt==0)
4235 return _names_cells;
4237 return _names_nodes;
4241 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4242 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4244 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4246 std::vector<int> ret(1);
4251 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4252 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4254 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4256 std::vector<int> ret(2);
4262 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4264 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4266 std::vector<int> ret;
4267 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells);
4276 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4278 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4280 std::vector<int> ret;
4281 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells);
4290 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4292 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4294 std::vector<int> ret;
4295 const DataArrayAsciiChar *namesCells(_names_cells);
4302 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4304 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
4306 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4310 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
4312 DataArrayInt *arr=_fam_nodes;
4314 arr->changeValue(oldId,newId);
4317 arr->changeValue(oldId,newId);
4320 void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
4322 if((const DataArrayInt*)_fam_nodes)
4323 _fam_nodes=_fam_nodes->deepCpy();
4324 if((const DataArrayInt*)_num_nodes)
4325 _num_nodes=_num_nodes->deepCpy();
4326 if((const DataArrayInt*)_fam_cells)
4327 _fam_cells=_fam_cells->deepCpy();
4328 if((const DataArrayInt*)_num_cells)
4329 _num_cells=_num_cells->deepCpy();
4330 if((const DataArrayInt*)_rev_num_nodes)
4331 _rev_num_nodes=_rev_num_nodes->deepCpy();
4332 if((const DataArrayInt*)_rev_num_cells)
4333 _rev_num_cells=_rev_num_cells->deepCpy();
4337 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4339 * \return a pointer to cartesian mesh that need to be managed by the caller.
4340 * \warning the returned pointer has to be managed by the caller.
4344 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4345 * \param [in] meshDimRelToMax - it must be \c 0.
4346 * \param [in] renum - it must be \c false.
4347 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4348 * delete using decrRef() as it is no more needed.
4350 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
4353 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4354 if(meshDimRelToMax!=0)
4355 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4356 const MEDCouplingStructuredMesh *m=getStructuredMesh();
4359 return const_cast<MEDCouplingStructuredMesh *>(m);
4363 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4364 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4365 * \return int - the number of entities.
4366 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4368 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4370 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4371 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
4372 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4374 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4375 if(meshDimRelToMaxExt==0)
4376 return cmesh->getNumberOfCells();
4378 return cmesh->getNumberOfNodes();
4381 int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
4383 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4385 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4386 return cmesh->getNumberOfNodes();
4389 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
4391 if(st.getNumberOfItems()!=1)
4392 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 !");
4393 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4394 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4395 if(getNumberOfNodes()!=(int)nodesFetched.size())
4396 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4397 if(st[0].getPflName().empty())
4399 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4402 const DataArrayInt *arr(globs->getProfile(st[0].getPflName().c_str()));
4403 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4404 int sz(nodesFetched.size());
4405 for(const int *work=arr->begin();work!=arr->end();work++)
4407 std::vector<int> conn;
4408 cmesh->getNodeIdsOfCell(*work,conn);
4409 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4410 if(*it>=0 && *it<sz)
4411 nodesFetched[*it]=true;
4413 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4417 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
4419 med_geometry_type geoTypeReq=MED_NONE;
4423 geoTypeReq=MED_HEXA8;
4426 geoTypeReq=MED_QUAD4;
4429 geoTypeReq=MED_SEG2;
4432 geoTypeReq=MED_POINT1;
4435 throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
4440 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4442 setName(strm->getName());
4443 setDescription(strm->getDescription());
4444 setUnivName(strm->getUnivName());
4445 setIteration(strm->getIteration());
4446 setOrder(strm->getOrder());
4447 setTimeValue(strm->getTime());
4448 setTimeUnit(strm->getTimeUnit());
4449 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4450 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4451 int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4454 if(!mrs || mrs->isNodeFamilyFieldReading())
4456 _fam_nodes=DataArrayInt::New();
4457 _fam_nodes->alloc(nbOfElt,1);
4458 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4461 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4464 if(!mrs || mrs->isNodeNumFieldReading())
4466 _num_nodes=DataArrayInt::New();
4467 _num_nodes->alloc(nbOfElt,1);
4468 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4471 int meshDim=getStructuredMesh()->getMeshDimension();
4472 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4473 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4476 if(!mrs || mrs->isCellFamilyFieldReading())
4478 _fam_cells=DataArrayInt::New();
4479 _fam_cells->alloc(nbOfElt,1);
4480 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
4483 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4486 if(!mrs || mrs->isCellNumFieldReading())
4488 _num_cells=DataArrayInt::New();
4489 _num_cells->alloc(nbOfElt,1);
4490 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
4493 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4496 if(!mrs || mrs->isCellNameFieldReading())
4498 _names_cells=DataArrayAsciiChar::New();
4499 _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4500 MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
4501 _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4504 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4507 if(!mrs || mrs->isNodeNameFieldReading())
4509 _names_nodes=DataArrayAsciiChar::New();
4510 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4511 MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4512 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4517 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
4519 int meshDim=getStructuredMesh()->getMeshDimension();
4520 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4522 if((const DataArrayInt *)_fam_cells)
4523 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4524 if((const DataArrayInt *)_fam_nodes)
4525 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4526 if((const DataArrayInt *)_num_cells)
4527 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4528 if((const DataArrayInt *)_num_nodes)
4529 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4530 if((const DataArrayAsciiChar *)_names_cells)
4532 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4534 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4535 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4536 throw INTERP_KERNEL::Exception(oss.str().c_str());
4538 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4540 if((const DataArrayAsciiChar *)_names_nodes)
4542 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4544 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4545 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4546 throw INTERP_KERNEL::Exception(oss.str().c_str());
4548 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4551 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
4555 * Returns an empty instance of MEDFileCMesh.
4556 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4557 * mesh using decrRef() as it is no more needed.
4559 MEDFileCMesh *MEDFileCMesh::New()
4561 return new MEDFileCMesh;
4565 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4566 * file. The first mesh in the file is loaded.
4567 * \param [in] fileName - the name of MED file to read.
4568 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4569 * mesh using decrRef() as it is no more needed.
4570 * \throw If the file is not readable.
4571 * \throw If there is no meshes in the file.
4572 * \throw If the mesh in the file is not a Cartesian one.
4574 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4576 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4579 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4580 throw INTERP_KERNEL::Exception(oss.str().c_str());
4582 MEDFileUtilities::CheckFileForRead(fileName);
4583 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4585 ParaMEDMEM::MEDCouplingMeshType meshType;
4587 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4588 return new MEDFileCMesh(fid,ms.front().c_str(),dt,it,mrs);
4592 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4593 * file. The mesh to load is specified by its name and numbers of a time step and an
4595 * \param [in] fileName - the name of MED file to read.
4596 * \param [in] mName - the name of the mesh to read.
4597 * \param [in] dt - the number of a time step.
4598 * \param [in] it - the number of an iteration.
4599 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4600 * mesh using decrRef() as it is no more needed.
4601 * \throw If the file is not readable.
4602 * \throw If there is no mesh with given attributes in the file.
4603 * \throw If the mesh in the file is not a Cartesian one.
4605 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4607 MEDFileUtilities::CheckFileForRead(fileName);
4608 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4609 return new MEDFileCMesh(fid,mName,dt,it,mrs);
4612 std::size_t MEDFileCMesh::getHeapMemorySize() const
4614 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4615 if((const MEDCouplingCMesh *)_cmesh)
4616 ret+=_cmesh->getHeapMemorySize();
4621 * Returns the dimension on cells in \a this mesh.
4622 * \return int - the mesh dimension.
4623 * \throw If there are no cells in this mesh.
4625 int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4627 if(!((const MEDCouplingCMesh*)_cmesh))
4628 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4629 return _cmesh->getMeshDimension();
4633 * Returns a string describing \a this mesh.
4634 * \return std::string - the mesh information string.
4636 std::string MEDFileCMesh::simpleRepr() const
4638 return MEDFileStructuredMesh::simpleRepr();
4642 * Returns a full textual description of \a this mesh.
4643 * \return std::string - the string holding the mesh description.
4645 std::string MEDFileCMesh::advancedRepr() const
4647 return simpleRepr();
4650 MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4652 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4656 MEDFileMesh *MEDFileCMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4658 return new MEDFileCMesh;
4661 MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4663 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4664 if((const MEDCouplingCMesh*)_cmesh)
4665 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
4666 ret->deepCpyAttributes();
4671 * Checks if \a this and another mesh are equal.
4672 * \param [in] other - the mesh to compare with.
4673 * \param [in] eps - a precision used to compare real values.
4674 * \param [in,out] what - the string returning description of unequal data.
4675 * \return bool - \c true if the meshes are equal, \c false, else.
4677 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4679 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4681 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
4684 what="Mesh types differ ! This is cartesian and other is NOT !";
4687 clearNonDiscrAttributes();
4688 otherC->clearNonDiscrAttributes();
4689 const MEDCouplingCMesh *coo1=_cmesh;
4690 const MEDCouplingCMesh *coo2=otherC->_cmesh;
4691 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4693 what="Mismatch of cartesian meshes ! One is defined and not other !";
4698 bool ret=coo1->isEqual(coo2,eps);
4701 what="cartesian meshes differ !";
4709 * Clears redundant attributes of incorporated data arrays.
4711 void MEDFileCMesh::clearNonDiscrAttributes() const
4713 MEDFileStructuredMesh::clearNonDiscrAttributes();
4714 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
4717 MEDFileCMesh::MEDFileCMesh()
4721 MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4724 loadCMeshFromFile(fid,mName,dt,it,mrs);
4726 catch(INTERP_KERNEL::Exception& e)
4731 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4733 ParaMEDMEM::MEDCouplingMeshType meshType;
4736 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4737 if(meshType!=CARTESIAN)
4739 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
4740 throw INTERP_KERNEL::Exception(oss.str().c_str());
4742 MEDFileCMeshL2 loaderl2;
4743 loaderl2.loadAll(fid,mid,mName,dt,it);
4744 MEDCouplingCMesh *mesh=loaderl2.getMesh();
4747 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
4751 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
4752 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
4754 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
4756 synchronizeTinyInfoOnLeaves();
4760 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
4762 synchronizeTinyInfoOnLeaves();
4767 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
4768 * \param [in] m - the new MEDCouplingCMesh to refer to.
4769 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4772 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
4774 dealWithTinyInfo(m);
4780 void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4782 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4783 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4784 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4785 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4786 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4787 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4788 int spaceDim=_cmesh->getSpaceDimension();
4789 int meshDim=_cmesh->getMeshDimension();
4790 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4791 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4792 for(int i=0;i<spaceDim;i++)
4794 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
4796 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4797 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
4798 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
4800 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4801 MEDmeshUniversalNameWr(fid,maa);
4802 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
4803 for(int i=0;i<spaceDim;i++)
4805 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
4806 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
4809 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4812 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
4814 const MEDCouplingCMesh *cmesh=_cmesh;
4817 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
4818 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
4819 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
4820 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
4823 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
4825 return new MEDFileCurveLinearMesh;
4828 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4830 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4833 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4834 throw INTERP_KERNEL::Exception(oss.str().c_str());
4836 MEDFileUtilities::CheckFileForRead(fileName);
4837 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4839 ParaMEDMEM::MEDCouplingMeshType meshType;
4841 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4842 return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it,mrs);
4845 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4847 MEDFileUtilities::CheckFileForRead(fileName);
4848 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4849 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
4852 std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const
4854 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4855 if((const MEDCouplingCurveLinearMesh *)_clmesh)
4856 ret+=_clmesh->getHeapMemorySize();
4860 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4862 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4866 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4868 return new MEDFileCurveLinearMesh;
4871 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4873 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4874 if((const MEDCouplingCurveLinearMesh*)_clmesh)
4875 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
4876 ret->deepCpyAttributes();
4880 int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4882 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
4883 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4884 return _clmesh->getMeshDimension();
4887 std::string MEDFileCurveLinearMesh::simpleRepr() const
4889 return MEDFileStructuredMesh::simpleRepr();
4892 std::string MEDFileCurveLinearMesh::advancedRepr() const
4894 return simpleRepr();
4897 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4899 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4901 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
4904 what="Mesh types differ ! This is curve linear and other is NOT !";
4907 clearNonDiscrAttributes();
4908 otherC->clearNonDiscrAttributes();
4909 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
4910 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
4911 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4913 what="Mismatch of curve linear meshes ! One is defined and not other !";
4918 bool ret=coo1->isEqual(coo2,eps);
4921 what="curve linear meshes differ !";
4928 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
4930 MEDFileStructuredMesh::clearNonDiscrAttributes();
4931 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
4934 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
4936 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
4939 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
4940 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
4941 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
4942 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
4945 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
4947 synchronizeTinyInfoOnLeaves();
4951 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
4953 dealWithTinyInfo(m);
4959 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
4961 synchronizeTinyInfoOnLeaves();
4965 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
4969 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4972 loadCLMeshFromFile(fid,mName,dt,it,mrs);
4974 catch(INTERP_KERNEL::Exception& e)
4979 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4981 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4982 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4983 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4984 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4985 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4986 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4987 int spaceDim=_clmesh->getSpaceDimension();
4988 int meshDim=_clmesh->getMeshDimension();
4989 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4990 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4991 const DataArrayDouble *coords=_clmesh->getCoords();
4993 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
4994 for(int i=0;i<spaceDim;i++)
4996 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
4998 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4999 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
5000 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
5002 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5003 MEDmeshUniversalNameWr(fid,maa);
5004 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5005 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5006 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5008 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5010 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
5013 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
5015 ParaMEDMEM::MEDCouplingMeshType meshType;
5018 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5019 if(meshType!=CURVE_LINEAR)
5021 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5022 throw INTERP_KERNEL::Exception(oss.str().c_str());
5024 MEDFileCLMeshL2 loaderl2;
5025 loaderl2.loadAll(fid,mid,mName,dt,it);
5026 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5029 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5032 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5034 return new MEDFileMeshMultiTS;
5037 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
5039 return new MEDFileMeshMultiTS(fileName);
5042 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5044 return new MEDFileMeshMultiTS(fileName,mName);
5047 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
5049 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5050 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5052 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5053 if((const MEDFileMesh *)*it)
5054 meshOneTs[i]=(*it)->deepCpy();
5055 ret->_mesh_one_ts=meshOneTs;
5059 std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const
5061 std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5062 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5063 ret+=(*it)->getHeapMemorySize();
5067 std::string MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
5069 if(_mesh_one_ts.empty())
5070 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5071 return _mesh_one_ts[0]->getName();
5074 void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::Exception)
5076 std::string oldName(getName());
5077 std::vector< std::pair<std::string,std::string> > v(1);
5078 v[0].first=oldName; v[0].second=newMeshName;
5082 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
5085 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5087 MEDFileMesh *cur(*it);
5089 ret=cur->changeNames(modifTab) || ret;
5094 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception)
5096 if(_mesh_one_ts.empty())
5097 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5098 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5101 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception)
5104 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5105 _mesh_one_ts.resize(1);
5106 mesh1TimeStep->incrRef();
5107 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5108 _mesh_one_ts[0]=mesh1TimeStep;
5111 void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5113 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5115 (*it)->copyOptionsFrom(*this);
5120 void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5122 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5123 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5124 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5125 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5129 void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5130 {//for the moment to be improved
5131 _mesh_one_ts.resize(1);
5132 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5135 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5139 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception)
5142 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5145 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5146 throw INTERP_KERNEL::Exception(oss.str().c_str());
5148 MEDFileUtilities::CheckFileForRead(fileName);
5149 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
5151 ParaMEDMEM::MEDCouplingMeshType meshType;
5153 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
5154 loadFromFile(fileName,ms.front().c_str());
5156 catch(INTERP_KERNEL::Exception& e)
5161 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5164 loadFromFile(fileName,mName);
5166 catch(INTERP_KERNEL::Exception& e)
5171 MEDFileMeshes *MEDFileMeshes::New()
5173 return new MEDFileMeshes;
5176 MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception)
5178 return new MEDFileMeshes(fileName);
5181 void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5184 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5186 (*it)->copyOptionsFrom(*this);
5191 void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5193 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5194 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5195 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5196 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5201 int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception)
5203 return _meshes.size();
5206 MEDFileMeshesIterator *MEDFileMeshes::iterator() throw(INTERP_KERNEL::Exception)
5208 return new MEDFileMeshesIterator(this);
5211 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception)
5213 if(i<0 || i>=(int)_meshes.size())
5215 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5216 throw INTERP_KERNEL::Exception(oss.str().c_str());
5218 return _meshes[i]->getOneTimeStep();
5221 MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTERP_KERNEL::Exception)
5223 std::vector<std::string> ms=getMeshesNames();
5224 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5227 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5228 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5229 throw INTERP_KERNEL::Exception(oss.str().c_str());
5231 return getMeshAtPos((int)std::distance(ms.begin(),it));
5234 std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERNEL::Exception)
5236 std::vector<std::string> ret(_meshes.size());
5238 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5240 const MEDFileMeshMultiTS *f=(*it);
5243 ret[i]=f->getName();
5247 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5248 throw INTERP_KERNEL::Exception(oss.str().c_str());
5254 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
5257 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5259 MEDFileMeshMultiTS *cur(*it);
5261 ret=cur->changeNames(modifTab) || ret;
5266 void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception)
5268 _meshes.resize(newSize);
5271 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5274 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5275 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5276 elt->setOneTimeStep(mesh);
5277 _meshes.push_back(elt);
5280 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5283 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5284 if(i>=(int)_meshes.size())
5285 _meshes.resize(i+1);
5286 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5287 elt->setOneTimeStep(mesh);
5291 void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
5293 if(i<0 || i>=(int)_meshes.size())
5295 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5296 throw INTERP_KERNEL::Exception(oss.str().c_str());
5298 _meshes.erase(_meshes.begin()+i);
5301 void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception)
5303 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5305 _meshes.resize(ms.size());
5306 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5307 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str());
5310 MEDFileMeshes::MEDFileMeshes()
5314 MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception)
5317 loadFromFile(fileName);
5319 catch(INTERP_KERNEL::Exception& e)
5323 MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
5325 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5327 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5328 if((const MEDFileMeshMultiTS *)*it)
5329 meshes[i]=(*it)->deepCpy();
5330 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5331 ret->_meshes=meshes;
5335 std::size_t MEDFileMeshes::getHeapMemorySize() const
5337 std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5338 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5339 if((const MEDFileMeshMultiTS*)*it)
5340 ret+=(*it)->getHeapMemorySize();
5344 std::string MEDFileMeshes::simpleRepr() const
5346 std::ostringstream oss;
5347 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5348 simpleReprWithoutHeader(oss);
5352 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5354 int nbOfMeshes=getNumberOfMeshes();
5355 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5356 std::vector<std::string> mns=getMeshesNames();
5357 for(int i=0;i<nbOfMeshes;i++)
5358 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5361 void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception)
5363 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5365 std::set<std::string> s;
5366 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5368 const MEDFileMeshMultiTS *elt=(*it);
5371 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5372 throw INTERP_KERNEL::Exception(oss.str().c_str());
5374 std::size_t sz=s.size();
5375 s.insert(std::string((*it)->getName()));
5378 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5379 throw INTERP_KERNEL::Exception(oss.str().c_str());
5384 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5389 _nb_iter=ms->getNumberOfMeshes();
5393 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5397 MEDFileMesh *MEDFileMeshesIterator::nextt()
5399 if(_iter_id<_nb_iter)
5401 MEDFileMeshes *ms(_ms);
5403 return ms->getMeshAtPos(_iter_id++);