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 MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2635 if(st[i].getPflName().empty())
2636 m->computeNodeIdsAlg(nodesFetched);
2639 const DataArrayInt *arr(globs->getProfile(st[i].getPflName().c_str()));
2640 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2641 m2->computeNodeIdsAlg(nodesFetched);
2647 * Returns the optional numbers of mesh entities of a given dimension transformed using
2648 * DataArrayInt::invertArrayN2O2O2N().
2649 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2650 * \return const DataArrayInt * - the array of the entity numbers transformed using
2651 * DataArrayInt::invertArrayN2O2O2N().
2652 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2654 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2656 if(meshDimRelToMaxExt==1)
2658 if(!((const DataArrayInt *)_num_coords))
2659 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2660 return _rev_num_coords;
2662 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2663 return l1->getRevNumberField();
2667 * Returns a pointer to the node coordinates array of \a this mesh \b without
2668 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2670 DataArrayDouble *MEDFileUMesh::getCoords() const
2672 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2673 if((DataArrayDouble *)tmp)
2681 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2682 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2684 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2685 * \param [in] grp - the name of the group whose mesh entities are included in the
2687 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2688 * according to the optional numbers of entities, if available.
2689 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2690 * delete this mesh using decrRef() as it is no more needed.
2691 * \throw If the name of a nonexistent group is specified.
2692 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2694 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
2696 synchronizeTinyInfoOnLeaves();
2697 std::vector<std::string> tmp(1);
2699 return getGroups(meshDimRelToMaxExt,tmp,renum);
2703 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2704 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2706 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2707 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2709 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2710 * according to the optional numbers of entities, if available.
2711 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2712 * delete this mesh using decrRef() as it is no more needed.
2713 * \throw If a name of a nonexistent group is present in \a grps.
2714 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2716 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
2718 synchronizeTinyInfoOnLeaves();
2719 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2720 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2721 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2722 zeRet->setName(grps[0].c_str());
2723 return zeRet.retn();
2727 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2728 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2730 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2731 * \param [in] fam - the name of the family whose mesh entities are included in the
2733 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2734 * according to the optional numbers of entities, if available.
2735 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2736 * delete this mesh using decrRef() as it is no more needed.
2737 * \throw If a name of a nonexistent family is present in \a grps.
2738 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2740 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
2742 synchronizeTinyInfoOnLeaves();
2743 std::vector<std::string> tmp(1);
2745 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2749 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2750 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2752 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2753 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2755 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2756 * according to the optional numbers of entities, if available.
2757 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2758 * delete this mesh using decrRef() as it is no more needed.
2759 * \throw If a name of a nonexistent family is present in \a fams.
2760 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2762 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2764 synchronizeTinyInfoOnLeaves();
2765 if(meshDimRelToMaxExt==1)
2767 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2768 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2769 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2773 std::vector<int> famIds=getFamiliesIds(fams);
2774 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2775 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2777 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2779 zeRet=l1->getFamilyPart(0,0,renum);
2780 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2781 zeRet->setName(fams[0].c_str());
2782 return zeRet.retn();
2786 * Returns ids of mesh entities contained in given families of a given dimension.
2787 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2789 * \param [in] fams - the names of the families of interest.
2790 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2791 * returned instead of ids.
2792 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2793 * numbers, if available and required, of mesh entities of the families. The caller
2794 * is to delete this array using decrRef() as it is no more needed.
2795 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2797 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2799 std::vector<int> famIds=getFamiliesIds(fams);
2800 if(meshDimRelToMaxExt==1)
2802 if((const DataArrayInt *)_fam_coords)
2804 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2806 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2808 da=_fam_coords->getIdsEqualList(0,0);
2810 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2815 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2817 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2819 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2821 return l1->getFamilyPartArr(0,0,renum);
2825 * Returns a MEDCouplingUMesh of a given relative dimension.
2826 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2827 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2828 * To build a valid MEDCouplingUMesh from the returned one in this case,
2829 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2830 * \param [in] meshDimRelToMax - the relative dimension of interest.
2831 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2832 * optional numbers of mesh entities.
2833 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2834 * delete using decrRef() as it is no more needed.
2835 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2836 * \sa getGenMeshAtLevel()
2838 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
2840 synchronizeTinyInfoOnLeaves();
2841 if(meshDimRelToMaxExt==1)
2845 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2846 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2847 umesh->setCoords(cc);
2848 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2849 umesh->setName(getName().c_str());
2853 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2854 return l1->getWholeMesh(renum);
2858 * Returns a MEDCouplingUMesh of a given relative dimension.
2859 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2860 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2861 * To build a valid MEDCouplingUMesh from the returned one in this case,
2862 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2863 * \param [in] meshDimRelToMax - the relative dimension of interest.
2864 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2865 * optional numbers of mesh entities.
2866 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2867 * delete using decrRef() as it is no more needed.
2868 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2869 * \sa getMeshAtLevel()
2871 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
2873 return getMeshAtLevel(meshDimRelToMax,renum);
2876 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2878 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
2879 return l1->getDistributionOfTypes();
2883 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2884 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2885 * optional numbers of mesh entities.
2886 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2887 * delete using decrRef() as it is no more needed.
2888 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2890 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2892 return getMeshAtLevel(0,renum);
2896 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2897 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2898 * optional numbers of mesh entities.
2899 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2900 * delete using decrRef() as it is no more needed.
2901 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2903 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2905 return getMeshAtLevel(-1,renum);
2909 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2910 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2911 * optional numbers of mesh entities.
2912 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2913 * delete using decrRef() as it is no more needed.
2914 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
2916 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2918 return getMeshAtLevel(-2,renum);
2922 * Returns a MEDCouplingUMesh of a relative dimension == -3.
2923 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2924 * optional numbers of mesh entities.
2925 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2926 * delete using decrRef() as it is no more needed.
2927 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
2929 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2931 return getMeshAtLevel(-3,renum);
2935 * This method returns a vector of mesh parts containing each exactly one geometric type.
2936 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
2937 * This method is only for memory aware users.
2938 * The returned pointers are **NOT** new object pointer. No need to mange them.
2940 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2942 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
2943 return sp->getDirectUndergroundSingleGeoTypeMeshes();
2947 * This method returns the part of \a this having the geometric type \a gt.
2948 * If such part is not existing an exception will be thrown.
2949 * The returned pointer is **NOT** new object pointer. No need to mange it.
2951 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception)
2953 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
2954 int lev=(int)cm.getDimension()-getMeshDimension();
2955 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
2956 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
2959 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2961 if(meshDimRelToMaxExt==1)
2962 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2963 if(meshDimRelToMaxExt>1)
2964 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2965 int tracucedRk=-meshDimRelToMaxExt;
2966 if(tracucedRk>=(int)_ms.size())
2967 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2968 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2969 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2970 return _ms[tracucedRk];
2973 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2975 if(meshDimRelToMaxExt==1)
2976 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2977 if(meshDimRelToMaxExt>1)
2978 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2979 int tracucedRk=-meshDimRelToMaxExt;
2980 if(tracucedRk>=(int)_ms.size())
2981 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2982 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2983 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2984 return _ms[tracucedRk];
2987 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2989 if(-meshDimRelToMax>=(int)_ms.size())
2990 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
2992 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2994 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
2996 int ref=(*it)->getMeshDimension();
2997 if(ref+i!=meshDim-meshDimRelToMax)
2998 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3004 * Sets the node coordinates array of \a this mesh.
3005 * \param [in] coords - the new node coordinates array.
3006 * \throw If \a coords == \c NULL.
3008 void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
3011 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3012 coords->checkAllocated();
3013 int nbOfTuples=coords->getNumberOfTuples();
3016 _fam_coords=DataArrayInt::New();
3017 _fam_coords->alloc(nbOfTuples,1);
3018 _fam_coords->fillWithZero();
3019 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3020 if((MEDFileUMeshSplitL1 *)(*it))
3021 (*it)->setCoords(coords);
3025 * Removes all groups of a given dimension in \a this mesh.
3026 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3027 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3029 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
3031 if(meshDimRelToMaxExt==1)
3033 if((DataArrayInt *)_fam_coords)
3034 _fam_coords->fillWithZero();
3037 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3038 l1->eraseFamilyField();
3043 * Removes all families with ids not present in the family fields of \a this mesh.
3045 void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
3047 std::vector<int> levs=getNonEmptyLevelsExt();
3048 std::set<int> allFamsIds;
3049 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3051 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3052 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3054 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3057 std::set<std::string> famNamesToKill;
3058 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3060 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3061 famNamesToKill.insert((*it).first);
3063 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3064 _families.erase(*it);
3065 std::vector<std::string> grpNamesToKill;
3066 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3068 std::vector<std::string> tmp;
3069 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3071 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3072 tmp.push_back(*it2);
3077 tmp.push_back((*it).first);
3079 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3083 void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception)
3085 std::vector<int> levs=getNonEmptyLevels();
3086 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3087 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3088 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3089 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3090 int nbNodes=m0->getNumberOfNodes();
3091 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3092 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3093 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3094 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3095 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3096 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3097 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3098 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3099 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3100 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3101 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3102 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3103 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3104 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3105 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3106 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3107 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3108 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3109 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3110 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3111 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3112 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3113 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3114 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3115 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3116 m0->setCoords(tmp0->getCoords());
3117 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3118 m1->setCoords(m0->getCoords());
3119 _coords=m0->getCoords(); _coords->incrRef();
3120 // duplication of cells in group 'grpNameM1' on level -1
3121 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3122 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3123 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3124 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3125 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3127 newm1->setName(getName().c_str());
3128 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3130 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3131 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3132 newFam->alloc(newm1->getNumberOfCells(),1);
3133 int idd=getMaxFamilyId()+1;
3134 int globStart=0,start=0,end,globEnd;
3135 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3136 for(int i=0;i<nbOfChunks;i++)
3138 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3139 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3141 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3142 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3143 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3148 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3152 newm1->setCoords(getCoords());
3153 setMeshAtLevel(-1,newm1);
3154 setFamilyFieldArr(-1,newFam);
3155 std::string grpName2(grpNameM1); grpName2+="_dup";
3156 addFamily(grpName2.c_str(),idd);
3157 addFamilyOnGrp(grpName2.c_str(),grpName2.c_str());
3162 int newNbOfNodes=getCoords()->getNumberOfTuples();
3163 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3164 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3165 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3168 nodesDuplicated=nodeIdsToDuplicate.retn();
3169 cellsModified=cellsToModifyConn0.retn();
3170 cellsNotModified=cellsToModifyConn1.retn();
3174 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3175 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3176 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3178 * \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.
3179 * 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.
3181 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
3183 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3184 std::vector<int> levs=getNonEmptyLevels();
3186 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3187 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3190 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3192 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3193 std::vector<int> code1=m->getDistributionOfTypes();
3194 end=PutInThirdComponentOfCodeOffset(code1,start);
3195 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3196 bool hasChanged=m->unPolyze();
3197 DataArrayInt *fake=0;
3198 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3199 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3201 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3204 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3205 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3207 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3208 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3209 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3210 setMeshAtLevel(*it,m);
3211 std::vector<int> code2=m->getDistributionOfTypes();
3212 end=PutInThirdComponentOfCodeOffset(code2,start);
3213 newCode.insert(newCode.end(),code2.begin(),code2.end());
3215 if(o2nCellsPart2->isIdentity())
3219 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3220 setFamilyFieldArr(*it,newFamField);
3224 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3225 setRenumFieldArr(*it,newNumField);
3230 newCode.insert(newCode.end(),code1.begin(),code1.end());
3236 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3237 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3238 o2nRenumCell=o2nRenumCellRet.retn();
3243 struct MEDLoaderAccVisit1
3245 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3246 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3247 int _new_nb_of_nodes;
3251 * 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.
3252 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3253 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3254 * -1 values in returned array means that the corresponding old node is no more used.
3256 * \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
3257 * is modified in \a this.
3258 * \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
3261 DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
3263 const DataArrayDouble *coo=getCoords();
3265 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3266 int nbOfNodes=coo->getNumberOfTuples();
3267 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3268 std::vector<int> neLevs=getNonEmptyLevels();
3269 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3271 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3272 m->computeNodeIdsAlg(nodeIdsInUse);
3274 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3275 if(nbrOfNodesInUse==nbOfNodes)
3277 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3278 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3279 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3280 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3281 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3282 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3283 if((const DataArrayInt *)_fam_coords)
3284 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3285 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3286 if((const DataArrayInt *)_num_coords)
3287 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3288 if((const DataArrayAsciiChar *)_name_coords)
3289 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3290 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3291 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3293 if((MEDFileUMeshSplitL1*)*it)
3294 (*it)->renumberNodesInConn(ret->begin());
3300 * Adds a group of nodes to \a this mesh.
3301 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3302 * The ids should be sorted and different each other (MED file norm).
3303 * \throw If the node coordinates array is not set.
3304 * \throw If \a ids == \c NULL.
3305 * \throw If \a ids->getName() == "".
3306 * \throw If \a ids does not respect the MED file norm.
3307 * \throw If a group with name \a ids->getName() already exists.
3309 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3311 const DataArrayDouble *coords=_coords;
3313 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3314 int nbOfNodes=coords->getNumberOfTuples();
3315 if(!((DataArrayInt *)_fam_coords))
3316 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3318 addGroupUnderground(true,ids,_fam_coords);
3322 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3323 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3324 * The ids should be sorted and different each other (MED file norm).
3325 * \throw If the node coordinates array is not set.
3326 * \throw If \a ids == \c NULL.
3327 * \throw If \a ids->getName() == "".
3328 * \throw If \a ids does not respect the MED file norm.
3329 * \throw If a group with name \a ids->getName() already exists.
3331 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3333 std::vector<int> levs=getNonEmptyLevelsExt();
3334 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3336 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3337 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3339 if(meshDimRelToMaxExt==1)
3340 { addNodeGroup(ids); return ; }
3341 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3342 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3343 addGroupUnderground(false,ids,fam);
3347 * \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).
3348 * \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)
3350 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3353 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3354 std::string grpName(ids->getName());
3356 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3357 ids->checkStrictlyMonotonic(true);
3358 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3359 std::vector<std::string> grpsNames=getGroupsNames();
3360 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3362 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3363 throw INTERP_KERNEL::Exception(oss.str().c_str());
3365 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3366 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3367 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3368 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3369 std::vector<int> familyIds;
3370 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3371 int maxVal=getTheMaxAbsFamilyId()+1;
3372 std::map<std::string,int> families(_families);
3373 std::map<std::string, std::vector<std::string> > groups(_groups);
3374 std::vector<std::string> fams;
3375 bool created(false);
3376 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3378 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3379 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3380 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3381 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3384 bool isFamPresent=false;
3385 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3386 isFamPresent=(*itl)->presenceOfValue(*famId);
3388 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3391 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3392 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3393 fams.push_back(locFamName);
3394 if(existsFamily(*famId))
3396 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3397 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3400 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3404 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3405 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3406 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3407 if(existsFamily(*famId))
3409 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3410 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3415 for(std::size_t i=0;i<familyIds.size();i++)
3417 DataArrayInt *da=idsPerfamiliyIds[i];
3418 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3422 _groups[grpName]=fams;
3426 * Changes a name of a family specified by its id.
3427 * \param [in] id - the id of the family of interest.
3428 * \param [in] newFamName - the new family name.
3429 * \throw If no family with the given \a id exists.
3431 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
3433 std::string oldName=getFamilyNameGivenId(id);
3434 _families.erase(oldName);
3435 _families[newFamName]=id;
3439 * Removes a mesh of a given dimension.
3440 * \param [in] meshDimRelToMax - the relative dimension of interest.
3441 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3443 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
3445 std::vector<int> levSet=getNonEmptyLevels();
3446 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3447 if(it==levSet.end())
3448 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3449 int pos=(-meshDimRelToMax);
3454 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3455 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3456 * \param [in] m - the new mesh to set.
3457 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3458 * writing \a this mesh in a MED file.
3459 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3461 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3462 * another node coordinates array.
3463 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3464 * to the existing meshes of other levels of \a this mesh.
3466 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
3468 dealWithTinyInfo(m);
3469 std::vector<int> levSet=getNonEmptyLevels();
3470 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3472 if((DataArrayDouble *)_coords==0)
3474 DataArrayDouble *c=m->getCoords();
3479 if(m->getCoords()!=_coords)
3480 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3481 int sz=(-meshDimRelToMax)+1;
3482 if(sz>=(int)_ms.size())
3484 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3485 _ms[sz-1]=new MEDFileUMeshSplitL1(m,newOrOld);
3488 _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld);
3492 * This method allows to set at once the content of different levels in \a this.
3493 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3495 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3496 * \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.
3497 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3499 * \throw If \a there is a null pointer in \a ms.
3500 * \sa MEDFileUMesh::setMeshAtLevel
3502 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3506 const MEDCouplingUMesh *mRef=ms[0];
3508 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3509 std::string name(mRef->getName());
3510 const DataArrayDouble *coo(mRef->getCoords());
3513 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3515 const MEDCouplingUMesh *cur(*it);
3517 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3518 if(coo!=cur->getCoords())
3519 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3520 int mdim=cur->getMeshDimension();
3521 zeDim=std::max(zeDim,mdim);
3522 if(s.find(mdim)!=s.end())
3523 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3525 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3527 int mdim=(*it)->getMeshDimension();
3528 setName((*it)->getName().c_str());
3529 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3531 setName(name.c_str());
3535 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3536 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3537 * The given meshes must share the same node coordinates array.
3538 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3539 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3540 * create in \a this mesh.
3541 * \throw If \a ms is empty.
3542 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3543 * to the existing meshes of other levels of \a this mesh.
3544 * \throw If the meshes in \a ms do not share the same node coordinates array.
3545 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3546 * of the given meshes.
3547 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3548 * \throw If names of some meshes in \a ms are equal.
3549 * \throw If \a ms includes a mesh with an empty name.
3551 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3554 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3555 int sz=(-meshDimRelToMax)+1;
3556 if(sz>=(int)_ms.size())
3558 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3559 DataArrayDouble *coo=checkMultiMesh(ms);
3560 if((DataArrayDouble *)_coords==0)
3566 if((DataArrayDouble *)_coords!=coo)
3567 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3568 std::vector<DataArrayInt *> corr;
3569 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3570 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3571 setMeshAtLevel(meshDimRelToMax,m,renum);
3572 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3573 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3577 * Creates groups at a given level in \a this mesh from a sequence of
3578 * meshes each representing a group.
3579 * The given meshes must share the same node coordinates array.
3580 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3581 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3582 * create in \a this mesh.
3583 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3585 * \throw If \a ms is empty.
3586 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3587 * to the existing meshes of other levels of \a this mesh.
3588 * \throw If the meshes in \a ms do not share the same node coordinates array.
3589 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3590 * of the given meshes.
3591 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3592 * \throw If names of some meshes in \a ms are equal.
3593 * \throw If \a ms includes a mesh with an empty name.
3595 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3598 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3599 int sz=(-meshDimRelToMax)+1;
3600 if(sz>=(int)_ms.size())
3602 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3603 DataArrayDouble *coo=checkMultiMesh(ms);
3604 if((DataArrayDouble *)_coords==0)
3610 if((DataArrayDouble *)_coords!=coo)
3611 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3612 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3613 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3615 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3617 DataArrayInt *arr=0;
3618 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3622 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3623 throw INTERP_KERNEL::Exception(oss.str().c_str());
3626 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3627 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3630 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const throw(INTERP_KERNEL::Exception)
3632 const DataArrayDouble *ret=ms[0]->getCoords();
3633 int mdim=ms[0]->getMeshDimension();
3634 for(unsigned int i=1;i<ms.size();i++)
3636 ms[i]->checkCoherency();
3637 if(ms[i]->getCoords()!=ret)
3638 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3639 if(ms[i]->getMeshDimension()!=mdim)
3640 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3642 return const_cast<DataArrayDouble *>(ret);
3646 * Sets the family field of a given relative dimension.
3647 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3648 * the family field is set.
3649 * \param [in] famArr - the array of the family field.
3650 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3651 * \throw If \a famArr has an invalid size.
3653 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3655 if(meshDimRelToMaxExt==1)
3662 DataArrayDouble *coo(_coords);
3664 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3665 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3670 if(meshDimRelToMaxExt>1)
3671 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3672 int traducedRk=-meshDimRelToMaxExt;
3673 if(traducedRk>=(int)_ms.size())
3674 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3675 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3676 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3677 return _ms[traducedRk]->setFamilyArr(famArr);
3681 * Sets the optional numbers of mesh entities of a given dimension.
3682 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3683 * \param [in] renumArr - the array of the numbers.
3684 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3685 * \throw If \a renumArr has an invalid size.
3687 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
3689 if(meshDimRelToMaxExt==1)
3697 DataArrayDouble *coo(_coords);
3699 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3700 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3701 renumArr->incrRef();
3702 _num_coords=renumArr;
3706 if(meshDimRelToMaxExt>1)
3707 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3708 int traducedRk=-meshDimRelToMaxExt;
3709 if(traducedRk>=(int)_ms.size())
3710 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3711 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3712 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3713 return _ms[traducedRk]->setRenumArr(renumArr);
3717 * Sets the optional names of mesh entities of a given dimension.
3718 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3719 * \param [in] nameArr - the array of the names.
3720 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3721 * \throw If \a nameArr has an invalid size.
3723 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
3725 if(meshDimRelToMaxExt==1)
3732 DataArrayDouble *coo(_coords);
3734 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3735 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3737 _name_coords=nameArr;
3740 if(meshDimRelToMaxExt>1)
3741 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3742 int traducedRk=-meshDimRelToMaxExt;
3743 if(traducedRk>=(int)_ms.size())
3744 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3745 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3746 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3747 return _ms[traducedRk]->setNameArr(nameArr);
3750 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3752 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3753 if((const MEDFileUMeshSplitL1 *)(*it))
3754 (*it)->synchronizeTinyInfo(*this);
3758 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3760 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
3762 DataArrayInt *arr=_fam_coords;
3764 arr->changeValue(oldId,newId);
3765 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3767 MEDFileUMeshSplitL1 *sp=(*it);
3770 sp->changeFamilyIdArr(oldId,newId);
3775 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3777 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3778 const DataArrayInt *da(_fam_coords);
3780 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3781 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3783 const MEDFileUMeshSplitL1 *elt(*it);
3786 da=elt->getFamilyField();
3788 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3794 void MEDFileUMesh::computeRevNum() const
3796 if((const DataArrayInt *)_num_coords)
3799 int maxValue=_num_coords->getMaxValue(pos);
3800 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3804 std::size_t MEDFileStructuredMesh::getHeapMemorySize() const
3806 std::size_t ret=MEDFileMesh::getHeapMemorySize();
3807 if((const DataArrayInt*)_fam_nodes)
3808 ret+=_fam_nodes->getHeapMemorySize();
3809 if((const DataArrayInt*)_num_nodes)
3810 ret+=_num_nodes->getHeapMemorySize();
3811 if((const DataArrayInt*)_fam_cells)
3812 ret+=_fam_cells->getHeapMemorySize();
3813 if((const DataArrayInt*)_num_cells)
3814 ret+=_num_cells->getHeapMemorySize();
3815 if((const DataArrayInt*)_rev_num_nodes)
3816 ret+=_rev_num_nodes->getHeapMemorySize();
3817 if((const DataArrayInt*)_rev_num_cells)
3818 ret+=_rev_num_cells->getHeapMemorySize();
3822 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3824 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3825 if((const DataArrayInt *)_fam_nodes)
3827 int val=_fam_nodes->getMaxValue(tmp);
3828 ret=std::max(ret,std::abs(val));
3830 if((const DataArrayInt *)_fam_cells)
3832 int val=_fam_cells->getMaxValue(tmp);
3833 ret=std::max(ret,std::abs(val));
3838 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3840 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3841 if((const DataArrayInt *)_fam_nodes)
3843 int val=_fam_nodes->getMaxValue(tmp);
3844 ret=std::max(ret,val);
3846 if((const DataArrayInt *)_fam_cells)
3848 int val=_fam_cells->getMaxValue(tmp);
3849 ret=std::max(ret,val);
3854 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3856 int ret=std::numeric_limits<int>::max(),tmp=-1;
3857 if((const DataArrayInt *)_fam_nodes)
3859 int val=_fam_nodes->getMinValue(tmp);
3860 ret=std::min(ret,val);
3862 if((const DataArrayInt *)_fam_cells)
3864 int val=_fam_cells->getMinValue(tmp);
3865 ret=std::min(ret,val);
3870 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3872 if(!MEDFileMesh::isEqual(other,eps,what))
3874 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
3877 what="Mesh types differ ! This is structured and other is NOT !";
3880 const DataArrayInt *famc1=_fam_nodes;
3881 const DataArrayInt *famc2=otherC->_fam_nodes;
3882 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3884 what="Mismatch of families arr on nodes ! One is defined and not other !";
3889 bool ret=famc1->isEqual(*famc2);
3892 what="Families arr on nodes differ !";
3897 famc2=otherC->_fam_cells;
3898 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3900 what="Mismatch of families arr on cells ! One is defined and not other !";
3905 bool ret=famc1->isEqual(*famc2);
3908 what="Families arr on cells differ !";
3913 famc2=otherC->_num_nodes;
3914 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3916 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
3921 bool ret=famc1->isEqual(*famc2);
3924 what="Numbering arr on nodes differ !";
3929 famc2=otherC->_num_cells;
3930 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3932 what="Mismatch of numbering arr on cells ! One is defined and not other !";
3937 bool ret=famc1->isEqual(*famc2);
3940 what="Numbering arr on cells differ !";
3944 const DataArrayAsciiChar *d1=_names_cells;
3945 const DataArrayAsciiChar *d2=otherC->_names_cells;
3946 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3948 what="Mismatch of naming arr on cells ! One is defined and not other !";
3953 bool ret=d1->isEqual(*d2);
3956 what="Naming arr on cells differ !";
3961 d2=otherC->_names_nodes;
3962 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3964 what="Mismatch of naming arr on nodes ! One is defined and not other !";
3969 bool ret=d1->isEqual(*d2);
3972 what="Naming arr on nodes differ !";
3979 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
3981 MEDFileMesh::clearNonDiscrAttributes();
3982 const DataArrayInt *tmp=_fam_nodes;
3984 (const_cast<DataArrayInt *>(tmp))->setName("");
3987 (const_cast<DataArrayInt *>(tmp))->setName("");
3990 (const_cast<DataArrayInt *>(tmp))->setName("");
3993 (const_cast<DataArrayInt *>(tmp))->setName("");
3997 * Returns ids of mesh entities contained in given families of a given dimension.
3998 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4000 * \param [in] fams - the names of the families of interest.
4001 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4002 * returned instead of ids.
4003 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4004 * numbers, if available and required, of mesh entities of the families. The caller
4005 * is to delete this array using decrRef() as it is no more needed.
4006 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4008 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
4010 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4011 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
4012 std::vector<int> famIds=getFamiliesIds(fams);
4013 if(meshDimRelToMaxExt==1)
4015 if((const DataArrayInt *)_fam_nodes)
4017 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4019 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4021 da=_fam_nodes->getIdsEqualList(0,0);
4023 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4028 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4032 if((const DataArrayInt *)_fam_cells)
4034 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4036 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4038 da=_fam_cells->getIdsEqualList(0,0);
4040 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4045 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4050 * Sets the family field of a given relative dimension.
4051 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4052 * the family field is set.
4053 * \param [in] famArr - the array of the family field.
4054 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4055 * \throw If \a famArr has an invalid size.
4056 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4058 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
4060 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4061 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4062 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4064 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4065 if(meshDimRelToMaxExt==0)
4067 int nbCells=mesh->getNumberOfCells();
4068 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4073 int nbNodes=mesh->getNumberOfNodes();
4074 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4082 * Sets the optional numbers of mesh entities of a given dimension.
4083 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4084 * \param [in] renumArr - the array of the numbers.
4085 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4086 * \throw If \a renumArr has an invalid size.
4087 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4089 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
4091 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4092 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4093 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4095 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4096 if(meshDimRelToMaxExt==0)
4098 int nbCells=mesh->getNumberOfCells();
4099 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4100 _num_cells=renumArr;
4104 int nbNodes=mesh->getNumberOfNodes();
4105 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4106 _num_nodes=renumArr;
4109 renumArr->incrRef();
4113 * Sets the optional names of mesh entities of a given dimension.
4114 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4115 * \param [in] nameArr - the array of the names.
4116 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4117 * \throw If \a nameArr has an invalid size.
4119 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
4121 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4122 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
4123 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4125 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4126 if(meshDimRelToMaxExt==0)
4128 int nbCells=mesh->getNumberOfCells();
4129 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4130 _names_cells=nameArr;
4134 int nbNodes=mesh->getNumberOfNodes();
4135 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4136 _names_nodes=nameArr;
4143 * Returns the family field for mesh entities of a given dimension.
4144 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4145 * \return const DataArrayInt * - the family field. It is an array of ids of families
4146 * each mesh entity belongs to. It can be \c NULL.
4147 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4149 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4151 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4152 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
4153 if(meshDimRelToMaxExt==0)
4160 * Returns the optional numbers of mesh entities of a given dimension.
4161 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4162 * \return const DataArrayInt * - the array of the entity numbers.
4163 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4164 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4166 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4168 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4169 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
4170 if(meshDimRelToMaxExt==0)
4177 * Returns the optional numbers of mesh entities of a given dimension transformed using
4178 * DataArrayInt::invertArrayN2O2O2N().
4179 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4180 * \return const DataArrayInt * - the array of the entity numbers transformed using
4181 * DataArrayInt::invertArrayN2O2O2N().
4182 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4183 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4185 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4187 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4188 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4189 if(meshDimRelToMaxExt==0)
4191 if((const DataArrayInt *)_num_cells)
4194 int maxValue=_num_cells->getMaxValue(pos);
4195 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4196 return _rev_num_cells;
4199 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4203 if((const DataArrayInt *)_num_nodes)
4206 int maxValue=_num_nodes->getMaxValue(pos);
4207 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4208 return _rev_num_nodes;
4211 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4215 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4217 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4218 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
4219 if(meshDimRelToMaxExt==0)
4220 return _names_cells;
4222 return _names_nodes;
4226 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4227 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4229 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4231 std::vector<int> ret(1);
4236 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4237 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4239 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4241 std::vector<int> ret(2);
4247 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4249 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4251 std::vector<int> ret;
4252 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells);
4261 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4263 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4265 std::vector<int> ret;
4266 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells);
4275 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4277 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4279 std::vector<int> ret;
4280 const DataArrayAsciiChar *namesCells(_names_cells);
4287 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4289 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
4291 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4295 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
4297 DataArrayInt *arr=_fam_nodes;
4299 arr->changeValue(oldId,newId);
4302 arr->changeValue(oldId,newId);
4305 void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
4307 if((const DataArrayInt*)_fam_nodes)
4308 _fam_nodes=_fam_nodes->deepCpy();
4309 if((const DataArrayInt*)_num_nodes)
4310 _num_nodes=_num_nodes->deepCpy();
4311 if((const DataArrayInt*)_fam_cells)
4312 _fam_cells=_fam_cells->deepCpy();
4313 if((const DataArrayInt*)_num_cells)
4314 _num_cells=_num_cells->deepCpy();
4315 if((const DataArrayInt*)_rev_num_nodes)
4316 _rev_num_nodes=_rev_num_nodes->deepCpy();
4317 if((const DataArrayInt*)_rev_num_cells)
4318 _rev_num_cells=_rev_num_cells->deepCpy();
4322 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4324 * \return a pointer to cartesian mesh that need to be managed by the caller.
4325 * \warning the returned pointer has to be managed by the caller.
4329 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4330 * \param [in] meshDimRelToMax - it must be \c 0.
4331 * \param [in] renum - it must be \c false.
4332 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4333 * delete using decrRef() as it is no more needed.
4335 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
4338 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4339 if(meshDimRelToMax!=0)
4340 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4341 const MEDCouplingStructuredMesh *m=getStructuredMesh();
4344 return const_cast<MEDCouplingStructuredMesh *>(m);
4348 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4349 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4350 * \return int - the number of entities.
4351 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4353 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4355 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4356 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
4357 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4359 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4360 if(meshDimRelToMaxExt==0)
4361 return cmesh->getNumberOfCells();
4363 return cmesh->getNumberOfNodes();
4366 int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
4368 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4370 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4371 return cmesh->getNumberOfNodes();
4374 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
4376 if(st.getNumberOfItems()!=1)
4377 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 !");
4378 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4379 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4380 if(getNumberOfNodes()!=(int)nodesFetched.size())
4381 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4382 if(st[0].getPflName().empty())
4384 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4387 const DataArrayInt *arr(globs->getProfile(st[0].getPflName().c_str()));
4388 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4389 int sz(nodesFetched.size());
4390 for(const int *work=arr->begin();work!=arr->end();work++)
4392 std::vector<int> conn;
4393 cmesh->getNodeIdsOfCell(*work,conn);
4394 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4395 if(*it>=0 && *it<sz)
4396 nodesFetched[*it]=true;
4398 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4402 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
4404 med_geometry_type geoTypeReq=MED_NONE;
4408 geoTypeReq=MED_HEXA8;
4411 geoTypeReq=MED_QUAD4;
4414 geoTypeReq=MED_SEG2;
4417 geoTypeReq=MED_POINT1;
4420 throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
4425 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4427 setName(strm->getName());
4428 setDescription(strm->getDescription());
4429 setUnivName(strm->getUnivName());
4430 setIteration(strm->getIteration());
4431 setOrder(strm->getOrder());
4432 setTimeValue(strm->getTime());
4433 setTimeUnit(strm->getTimeUnit());
4434 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4435 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4436 int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4439 if(!mrs || mrs->isNodeFamilyFieldReading())
4441 _fam_nodes=DataArrayInt::New();
4442 _fam_nodes->alloc(nbOfElt,1);
4443 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4446 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4449 if(!mrs || mrs->isNodeNumFieldReading())
4451 _num_nodes=DataArrayInt::New();
4452 _num_nodes->alloc(nbOfElt,1);
4453 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4456 int meshDim=getStructuredMesh()->getMeshDimension();
4457 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4458 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4461 if(!mrs || mrs->isCellFamilyFieldReading())
4463 _fam_cells=DataArrayInt::New();
4464 _fam_cells->alloc(nbOfElt,1);
4465 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
4468 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4471 if(!mrs || mrs->isCellNumFieldReading())
4473 _num_cells=DataArrayInt::New();
4474 _num_cells->alloc(nbOfElt,1);
4475 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
4478 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4481 if(!mrs || mrs->isCellNameFieldReading())
4483 _names_cells=DataArrayAsciiChar::New();
4484 _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4485 MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
4486 _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4489 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4492 if(!mrs || mrs->isNodeNameFieldReading())
4494 _names_nodes=DataArrayAsciiChar::New();
4495 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4496 MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4497 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4502 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
4504 int meshDim=getStructuredMesh()->getMeshDimension();
4505 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4507 if((const DataArrayInt *)_fam_cells)
4508 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4509 if((const DataArrayInt *)_fam_nodes)
4510 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4511 if((const DataArrayInt *)_num_cells)
4512 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4513 if((const DataArrayInt *)_num_nodes)
4514 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4515 if((const DataArrayAsciiChar *)_names_cells)
4517 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4519 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4520 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4521 throw INTERP_KERNEL::Exception(oss.str().c_str());
4523 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4525 if((const DataArrayAsciiChar *)_names_nodes)
4527 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4529 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4530 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4531 throw INTERP_KERNEL::Exception(oss.str().c_str());
4533 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4536 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
4540 * Returns an empty instance of MEDFileCMesh.
4541 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4542 * mesh using decrRef() as it is no more needed.
4544 MEDFileCMesh *MEDFileCMesh::New()
4546 return new MEDFileCMesh;
4550 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4551 * file. The first mesh in the file is loaded.
4552 * \param [in] fileName - the name of MED file to read.
4553 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4554 * mesh using decrRef() as it is no more needed.
4555 * \throw If the file is not readable.
4556 * \throw If there is no meshes in the file.
4557 * \throw If the mesh in the file is not a Cartesian one.
4559 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4561 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4564 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4565 throw INTERP_KERNEL::Exception(oss.str().c_str());
4567 MEDFileUtilities::CheckFileForRead(fileName);
4568 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4570 ParaMEDMEM::MEDCouplingMeshType meshType;
4572 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4573 return new MEDFileCMesh(fid,ms.front().c_str(),dt,it,mrs);
4577 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4578 * file. The mesh to load is specified by its name and numbers of a time step and an
4580 * \param [in] fileName - the name of MED file to read.
4581 * \param [in] mName - the name of the mesh to read.
4582 * \param [in] dt - the number of a time step.
4583 * \param [in] it - the number of an iteration.
4584 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4585 * mesh using decrRef() as it is no more needed.
4586 * \throw If the file is not readable.
4587 * \throw If there is no mesh with given attributes in the file.
4588 * \throw If the mesh in the file is not a Cartesian one.
4590 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4592 MEDFileUtilities::CheckFileForRead(fileName);
4593 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4594 return new MEDFileCMesh(fid,mName,dt,it,mrs);
4597 std::size_t MEDFileCMesh::getHeapMemorySize() const
4599 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4600 if((const MEDCouplingCMesh *)_cmesh)
4601 ret+=_cmesh->getHeapMemorySize();
4606 * Returns the dimension on cells in \a this mesh.
4607 * \return int - the mesh dimension.
4608 * \throw If there are no cells in this mesh.
4610 int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4612 if(!((const MEDCouplingCMesh*)_cmesh))
4613 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4614 return _cmesh->getMeshDimension();
4618 * Returns a string describing \a this mesh.
4619 * \return std::string - the mesh information string.
4621 std::string MEDFileCMesh::simpleRepr() const
4623 return MEDFileStructuredMesh::simpleRepr();
4627 * Returns a full textual description of \a this mesh.
4628 * \return std::string - the string holding the mesh description.
4630 std::string MEDFileCMesh::advancedRepr() const
4632 return simpleRepr();
4635 MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4637 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4641 MEDFileMesh *MEDFileCMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4643 return new MEDFileCMesh;
4646 MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4648 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4649 if((const MEDCouplingCMesh*)_cmesh)
4650 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
4651 ret->deepCpyAttributes();
4656 * Checks if \a this and another mesh are equal.
4657 * \param [in] other - the mesh to compare with.
4658 * \param [in] eps - a precision used to compare real values.
4659 * \param [in,out] what - the string returning description of unequal data.
4660 * \return bool - \c true if the meshes are equal, \c false, else.
4662 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4664 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4666 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
4669 what="Mesh types differ ! This is cartesian and other is NOT !";
4672 clearNonDiscrAttributes();
4673 otherC->clearNonDiscrAttributes();
4674 const MEDCouplingCMesh *coo1=_cmesh;
4675 const MEDCouplingCMesh *coo2=otherC->_cmesh;
4676 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4678 what="Mismatch of cartesian meshes ! One is defined and not other !";
4683 bool ret=coo1->isEqual(coo2,eps);
4686 what="cartesian meshes differ !";
4694 * Clears redundant attributes of incorporated data arrays.
4696 void MEDFileCMesh::clearNonDiscrAttributes() const
4698 MEDFileStructuredMesh::clearNonDiscrAttributes();
4699 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
4702 MEDFileCMesh::MEDFileCMesh()
4706 MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4709 loadCMeshFromFile(fid,mName,dt,it,mrs);
4711 catch(INTERP_KERNEL::Exception& e)
4716 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4718 ParaMEDMEM::MEDCouplingMeshType meshType;
4721 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4722 if(meshType!=CARTESIAN)
4724 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
4725 throw INTERP_KERNEL::Exception(oss.str().c_str());
4727 MEDFileCMeshL2 loaderl2;
4728 loaderl2.loadAll(fid,mid,mName,dt,it);
4729 MEDCouplingCMesh *mesh=loaderl2.getMesh();
4732 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
4736 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
4737 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
4739 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
4741 synchronizeTinyInfoOnLeaves();
4745 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
4747 synchronizeTinyInfoOnLeaves();
4752 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
4753 * \param [in] m - the new MEDCouplingCMesh to refer to.
4754 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4757 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
4759 dealWithTinyInfo(m);
4765 void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4767 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4768 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4769 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4770 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4771 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4772 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4773 int spaceDim=_cmesh->getSpaceDimension();
4774 int meshDim=_cmesh->getMeshDimension();
4775 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4776 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4777 for(int i=0;i<spaceDim;i++)
4779 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
4781 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4782 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
4783 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
4785 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4786 MEDmeshUniversalNameWr(fid,maa);
4787 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
4788 for(int i=0;i<spaceDim;i++)
4790 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
4791 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
4794 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4797 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
4799 const MEDCouplingCMesh *cmesh=_cmesh;
4802 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
4803 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
4804 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
4805 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
4808 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
4810 return new MEDFileCurveLinearMesh;
4813 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4815 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4818 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4819 throw INTERP_KERNEL::Exception(oss.str().c_str());
4821 MEDFileUtilities::CheckFileForRead(fileName);
4822 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4824 ParaMEDMEM::MEDCouplingMeshType meshType;
4826 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4827 return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it,mrs);
4830 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4832 MEDFileUtilities::CheckFileForRead(fileName);
4833 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4834 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
4837 std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const
4839 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4840 if((const MEDCouplingCurveLinearMesh *)_clmesh)
4841 ret+=_clmesh->getHeapMemorySize();
4845 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4847 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4851 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4853 return new MEDFileCurveLinearMesh;
4856 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4858 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4859 if((const MEDCouplingCurveLinearMesh*)_clmesh)
4860 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
4861 ret->deepCpyAttributes();
4865 int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4867 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
4868 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4869 return _clmesh->getMeshDimension();
4872 std::string MEDFileCurveLinearMesh::simpleRepr() const
4874 return MEDFileStructuredMesh::simpleRepr();
4877 std::string MEDFileCurveLinearMesh::advancedRepr() const
4879 return simpleRepr();
4882 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4884 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4886 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
4889 what="Mesh types differ ! This is curve linear and other is NOT !";
4892 clearNonDiscrAttributes();
4893 otherC->clearNonDiscrAttributes();
4894 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
4895 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
4896 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4898 what="Mismatch of curve linear meshes ! One is defined and not other !";
4903 bool ret=coo1->isEqual(coo2,eps);
4906 what="curve linear meshes differ !";
4913 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
4915 MEDFileStructuredMesh::clearNonDiscrAttributes();
4916 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
4919 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
4921 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
4924 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
4925 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
4926 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
4927 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
4930 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
4932 synchronizeTinyInfoOnLeaves();
4936 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
4938 dealWithTinyInfo(m);
4944 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
4946 synchronizeTinyInfoOnLeaves();
4950 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
4954 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4957 loadCLMeshFromFile(fid,mName,dt,it,mrs);
4959 catch(INTERP_KERNEL::Exception& e)
4964 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4966 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4967 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4968 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4969 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4970 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4971 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4972 int spaceDim=_clmesh->getSpaceDimension();
4973 int meshDim=_clmesh->getMeshDimension();
4974 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4975 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4976 const DataArrayDouble *coords=_clmesh->getCoords();
4978 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
4979 for(int i=0;i<spaceDim;i++)
4981 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
4983 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4984 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
4985 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
4987 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4988 MEDmeshUniversalNameWr(fid,maa);
4989 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
4990 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
4991 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
4993 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
4995 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4998 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
5000 ParaMEDMEM::MEDCouplingMeshType meshType;
5003 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5004 if(meshType!=CURVE_LINEAR)
5006 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5007 throw INTERP_KERNEL::Exception(oss.str().c_str());
5009 MEDFileCLMeshL2 loaderl2;
5010 loaderl2.loadAll(fid,mid,mName,dt,it);
5011 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5014 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5017 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5019 return new MEDFileMeshMultiTS;
5022 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
5024 return new MEDFileMeshMultiTS(fileName);
5027 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5029 return new MEDFileMeshMultiTS(fileName,mName);
5032 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
5034 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5035 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5037 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5038 if((const MEDFileMesh *)*it)
5039 meshOneTs[i]=(*it)->deepCpy();
5040 ret->_mesh_one_ts=meshOneTs;
5044 std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const
5046 std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5047 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5048 ret+=(*it)->getHeapMemorySize();
5052 std::string MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
5054 if(_mesh_one_ts.empty())
5055 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5056 return _mesh_one_ts[0]->getName();
5059 void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::Exception)
5061 std::string oldName(getName());
5062 std::vector< std::pair<std::string,std::string> > v(1);
5063 v[0].first=oldName; v[0].second=newMeshName;
5067 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
5070 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5072 MEDFileMesh *cur(*it);
5074 ret=cur->changeNames(modifTab) || ret;
5079 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception)
5081 if(_mesh_one_ts.empty())
5082 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5083 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5086 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception)
5089 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5090 _mesh_one_ts.resize(1);
5091 mesh1TimeStep->incrRef();
5092 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5093 _mesh_one_ts[0]=mesh1TimeStep;
5096 void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5098 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5100 (*it)->copyOptionsFrom(*this);
5105 void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5107 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5108 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5109 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5110 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5114 void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5115 {//for the moment to be improved
5116 _mesh_one_ts.resize(1);
5117 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5120 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5124 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception)
5127 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5130 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5131 throw INTERP_KERNEL::Exception(oss.str().c_str());
5133 MEDFileUtilities::CheckFileForRead(fileName);
5134 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
5136 ParaMEDMEM::MEDCouplingMeshType meshType;
5138 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
5139 loadFromFile(fileName,ms.front().c_str());
5141 catch(INTERP_KERNEL::Exception& e)
5146 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5149 loadFromFile(fileName,mName);
5151 catch(INTERP_KERNEL::Exception& e)
5156 MEDFileMeshes *MEDFileMeshes::New()
5158 return new MEDFileMeshes;
5161 MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception)
5163 return new MEDFileMeshes(fileName);
5166 void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5169 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5171 (*it)->copyOptionsFrom(*this);
5176 void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5178 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5179 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5180 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5181 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5186 int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception)
5188 return _meshes.size();
5191 MEDFileMeshesIterator *MEDFileMeshes::iterator() throw(INTERP_KERNEL::Exception)
5193 return new MEDFileMeshesIterator(this);
5196 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception)
5198 if(i<0 || i>=(int)_meshes.size())
5200 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5201 throw INTERP_KERNEL::Exception(oss.str().c_str());
5203 return _meshes[i]->getOneTimeStep();
5206 MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTERP_KERNEL::Exception)
5208 std::vector<std::string> ms=getMeshesNames();
5209 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5212 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5213 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5214 throw INTERP_KERNEL::Exception(oss.str().c_str());
5216 return getMeshAtPos((int)std::distance(ms.begin(),it));
5219 std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERNEL::Exception)
5221 std::vector<std::string> ret(_meshes.size());
5223 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5225 const MEDFileMeshMultiTS *f=(*it);
5228 ret[i]=f->getName();
5232 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5233 throw INTERP_KERNEL::Exception(oss.str().c_str());
5239 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
5242 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5244 MEDFileMeshMultiTS *cur(*it);
5246 ret=cur->changeNames(modifTab) || ret;
5251 void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception)
5253 _meshes.resize(newSize);
5256 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5259 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5260 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5261 elt->setOneTimeStep(mesh);
5262 _meshes.push_back(elt);
5265 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5268 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5269 if(i>=(int)_meshes.size())
5270 _meshes.resize(i+1);
5271 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5272 elt->setOneTimeStep(mesh);
5276 void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
5278 if(i<0 || i>=(int)_meshes.size())
5280 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5281 throw INTERP_KERNEL::Exception(oss.str().c_str());
5283 _meshes.erase(_meshes.begin()+i);
5286 void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception)
5288 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5290 _meshes.resize(ms.size());
5291 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5292 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str());
5295 MEDFileMeshes::MEDFileMeshes()
5299 MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception)
5302 loadFromFile(fileName);
5304 catch(INTERP_KERNEL::Exception& /*e*/)
5308 MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
5310 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5312 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5313 if((const MEDFileMeshMultiTS *)*it)
5314 meshes[i]=(*it)->deepCpy();
5315 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5316 ret->_meshes=meshes;
5320 std::size_t MEDFileMeshes::getHeapMemorySize() const
5322 std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5323 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5324 if((const MEDFileMeshMultiTS*)*it)
5325 ret+=(*it)->getHeapMemorySize();
5329 std::string MEDFileMeshes::simpleRepr() const
5331 std::ostringstream oss;
5332 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5333 simpleReprWithoutHeader(oss);
5337 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5339 int nbOfMeshes=getNumberOfMeshes();
5340 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5341 std::vector<std::string> mns=getMeshesNames();
5342 for(int i=0;i<nbOfMeshes;i++)
5343 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5346 void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception)
5348 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5350 std::set<std::string> s;
5351 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5353 const MEDFileMeshMultiTS *elt=(*it);
5356 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5357 throw INTERP_KERNEL::Exception(oss.str().c_str());
5359 std::size_t sz=s.size();
5360 s.insert(std::string((*it)->getName()));
5363 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5364 throw INTERP_KERNEL::Exception(oss.str().c_str());
5369 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5374 _nb_iter=ms->getNumberOfMeshes();
5378 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5382 MEDFileMesh *MEDFileMeshesIterator::nextt()
5384 if(_iter_id<_nb_iter)
5386 MEDFileMeshes *ms(_ms);
5388 return ms->getMeshAtPos(_iter_id++);