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 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1743 famArr->applyLin(offset>0?1:-1,offset,0);
1744 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1747 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1748 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1753 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1754 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1755 * If this method fails to find such a name it will throw an exception.
1757 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid) throw(INTERP_KERNEL::Exception)
1760 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1763 std::size_t len=nameTry.length();
1764 for(std::size_t ii=1;ii<len;ii++)
1766 std::string tmp=nameTry.substr(ii,len-ii);
1767 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1773 for(std::size_t i=1;i<30;i++)
1775 std::string tmp1(nameTry.at(0),i);
1777 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1783 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1785 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1787 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1790 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt) throw(INTERP_KERNEL::Exception)
1792 std::size_t nbOfChunks=code.size()/3;
1793 if(code.size()%3!=0)
1794 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1796 for(std::size_t i=0;i<nbOfChunks;i++)
1805 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1806 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1807 * If _name is not empty and that 'm' has the same name nothing is done.
1808 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1810 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL::Exception)
1813 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1818 std::string name(m->getName());
1823 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1824 oss << name << "' ! Names must match !";
1825 throw INTERP_KERNEL::Exception(oss.str().c_str());
1829 if(_desc_name.empty())
1830 _desc_name=m->getDescription();
1833 std::string name(m->getDescription());
1836 if(_desc_name!=name)
1838 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1839 oss << name << "' ! Names must match !";
1840 throw INTERP_KERNEL::Exception(oss.str().c_str());
1846 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1848 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1849 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1851 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1852 oss << " - Groups lying on this family : ";
1853 std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
1854 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1855 oss << std::endl << std::endl;
1860 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1861 * file. The mesh to load is specified by its name and numbers of a time step and an
1863 * \param [in] fileName - the name of MED file to read.
1864 * \param [in] mName - the name of the mesh to read.
1865 * \param [in] dt - the number of a time step.
1866 * \param [in] it - the number of an iteration.
1867 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1868 * mesh using decrRef() as it is no more needed.
1869 * \throw If the file is not readable.
1870 * \throw If there is no mesh with given attributes in the file.
1871 * \throw If the mesh in the file is not an unstructured one.
1873 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
1875 MEDFileUtilities::CheckFileForRead(fileName);
1876 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1877 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1881 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1882 * file. The first mesh in the file is loaded.
1883 * \param [in] fileName - the name of MED file to read.
1884 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1885 * mesh using decrRef() as it is no more needed.
1886 * \throw If the file is not readable.
1887 * \throw If there is no meshes in the file.
1888 * \throw If the mesh in the file is not an unstructured one.
1890 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
1892 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1895 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1896 throw INTERP_KERNEL::Exception(oss.str().c_str());
1898 MEDFileUtilities::CheckFileForRead(fileName);
1899 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1901 ParaMEDMEM::MEDCouplingMeshType meshType;
1903 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
1904 return new MEDFileUMesh(fid,ms.front().c_str(),dt,it,mrs);
1908 * Returns an empty instance of MEDFileUMesh.
1909 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1910 * mesh using decrRef() as it is no more needed.
1912 MEDFileUMesh *MEDFileUMesh::New()
1914 return new MEDFileUMesh;
1917 std::size_t MEDFileUMesh::getHeapMemorySize() const
1919 std::size_t ret=MEDFileMesh::getHeapMemorySize();
1920 if((const DataArrayDouble*)_coords)
1921 ret+=_coords->getHeapMemorySize();
1922 if((const DataArrayInt *)_fam_coords)
1923 ret+=_fam_coords->getHeapMemorySize();
1924 if((const DataArrayInt *)_num_coords)
1925 ret+=_num_coords->getHeapMemorySize();
1926 if((const DataArrayInt *)_rev_num_coords)
1927 ret+=_rev_num_coords->getHeapMemorySize();
1928 if((const DataArrayAsciiChar *)_name_coords)
1929 ret+=_name_coords->getHeapMemorySize();
1930 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1931 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1932 if((const MEDFileUMeshSplitL1*) *it)
1933 ret+=(*it)->getHeapMemorySize();
1937 MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
1939 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1943 MEDFileMesh *MEDFileUMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
1945 return new MEDFileUMesh;
1948 MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
1950 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1951 if((const DataArrayDouble*)_coords)
1952 ret->_coords=_coords->deepCpy();
1953 if((const DataArrayInt*)_fam_coords)
1954 ret->_fam_coords=_fam_coords->deepCpy();
1955 if((const DataArrayInt*)_num_coords)
1956 ret->_num_coords=_num_coords->deepCpy();
1957 if((const DataArrayInt*)_rev_num_coords)
1958 ret->_rev_num_coords=_rev_num_coords->deepCpy();
1959 if((const DataArrayAsciiChar*)_name_coords)
1960 ret->_name_coords=_name_coords->deepCpy();
1962 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
1964 if((const MEDFileUMeshSplitL1 *)(*it))
1965 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
1971 * Checks if \a this and another mesh are equal.
1972 * \param [in] other - the mesh to compare with.
1973 * \param [in] eps - a precision used to compare real values.
1974 * \param [in,out] what - the string returning description of unequal data.
1975 * \return bool - \c true if the meshes are equal, \c false, else.
1977 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
1979 if(!MEDFileMesh::isEqual(other,eps,what))
1981 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
1984 what="Mesh types differ ! This is unstructured and other is NOT !";
1987 clearNonDiscrAttributes();
1988 otherC->clearNonDiscrAttributes();
1989 const DataArrayDouble *coo1=_coords;
1990 const DataArrayDouble *coo2=otherC->_coords;
1991 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
1993 what="Mismatch of coordinates ! One is defined and not other !";
1998 bool ret=coo1->isEqual(*coo2,eps);
2001 what="Coords differ !";
2005 const DataArrayInt *famc1=_fam_coords;
2006 const DataArrayInt *famc2=otherC->_fam_coords;
2007 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2009 what="Mismatch of families arr on nodes ! One is defined and not other !";
2014 bool ret=famc1->isEqual(*famc2);
2017 what="Families arr on node differ !";
2021 const DataArrayInt *numc1=_num_coords;
2022 const DataArrayInt *numc2=otherC->_num_coords;
2023 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2025 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2030 bool ret=numc1->isEqual(*numc2);
2033 what="Numbering arr on node differ !";
2037 const DataArrayAsciiChar *namec1=_name_coords;
2038 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2039 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2041 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2046 bool ret=namec1->isEqual(*namec2);
2049 what="Names arr on node differ !";
2053 if(_ms.size()!=otherC->_ms.size())
2055 what="Number of levels differs !";
2058 std::size_t sz=_ms.size();
2059 for(std::size_t i=0;i<sz;i++)
2061 const MEDFileUMeshSplitL1 *s1=_ms[i];
2062 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2063 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2065 what="Mismatch of presence of sub levels !";
2070 bool ret=s1->isEqual(s2,eps,what);
2079 * Clears redundant attributes of incorporated data arrays.
2081 void MEDFileUMesh::clearNonDiscrAttributes() const
2083 MEDFileMesh::clearNonDiscrAttributes();
2084 const DataArrayDouble *coo1=_coords;
2086 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2087 const DataArrayInt *famc1=_fam_coords;
2089 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2090 const DataArrayInt *numc1=_num_coords;
2092 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2093 const DataArrayAsciiChar *namc1=_name_coords;
2095 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2096 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2098 const MEDFileUMeshSplitL1 *tmp=(*it);
2100 tmp->clearNonDiscrAttributes();
2104 MEDFileUMesh::MEDFileUMesh()
2108 MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
2111 loadUMeshFromFile(fid,mName,dt,it,mrs);
2113 catch(INTERP_KERNEL::Exception& e)
2118 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
2120 MEDFileUMeshL2 loaderl2;
2121 ParaMEDMEM::MEDCouplingMeshType meshType;
2124 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
2125 if(meshType!=UNSTRUCTURED)
2127 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2128 throw INTERP_KERNEL::Exception(oss.str().c_str());
2130 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2131 int lev=loaderl2.getNumberOfLevels();
2133 for(int i=0;i<lev;i++)
2135 if(!loaderl2.emptyLev(i))
2136 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2140 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2142 setName(loaderl2.getName());
2143 setDescription(loaderl2.getDescription());
2144 setUnivName(loaderl2.getUnivName());
2145 setIteration(loaderl2.getIteration());
2146 setOrder(loaderl2.getOrder());
2147 setTimeValue(loaderl2.getTime());
2148 setTimeUnit(loaderl2.getTimeUnit());
2149 _coords=loaderl2.getCoords();
2150 if(!mrs || mrs->isNodeFamilyFieldReading())
2151 _fam_coords=loaderl2.getCoordsFamily();
2152 if(!mrs || mrs->isNodeNumFieldReading())
2153 _num_coords=loaderl2.getCoordsNum();
2154 if(!mrs || mrs->isNodeNameFieldReading())
2155 _name_coords=loaderl2.getCoordsName();
2159 MEDFileUMesh::~MEDFileUMesh()
2163 void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
2165 const DataArrayDouble *coo=_coords;
2166 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2167 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2168 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2169 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2170 int spaceDim=coo?coo->getNumberOfComponents():0;
2171 int mdim=getMeshDimension();
2172 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2173 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2174 for(int i=0;i<spaceDim;i++)
2176 std::string info=coo->getInfoOnComponent(i);
2178 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2179 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
2180 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
2182 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2183 MEDmeshUniversalNameWr(fid,maa);
2184 MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2185 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2186 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2187 (*it)->write(fid,maa,mdim);
2188 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
2192 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2193 * \return std::vector<int> - a sequence of the relative dimensions.
2195 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2197 std::vector<int> ret;
2199 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2200 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2207 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2208 * \return std::vector<int> - a sequence of the relative dimensions.
2210 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2212 std::vector<int> ret0=getNonEmptyLevels();
2213 if((const DataArrayDouble *) _coords)
2215 std::vector<int> ret(ret0.size()+1);
2217 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2223 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2225 std::vector<int> ret;
2226 const DataArrayInt *famCoo(_fam_coords);
2230 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2232 const MEDFileUMeshSplitL1 *cur(*it);
2234 if(cur->getFamilyField())
2240 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2242 std::vector<int> ret;
2243 const DataArrayInt *numCoo(_num_coords);
2247 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2249 const MEDFileUMeshSplitL1 *cur(*it);
2251 if(cur->getNumberField())
2257 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2259 std::vector<int> ret;
2260 const DataArrayAsciiChar *nameCoo(_name_coords);
2264 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2266 const MEDFileUMeshSplitL1 *cur(*it);
2268 if(cur->getNameField())
2275 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2276 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2277 * \param [in] grp - the name of the group of interest.
2278 * \return std::vector<int> - a sequence of the relative dimensions.
2280 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const throw(INTERP_KERNEL::Exception)
2282 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2283 return getFamsNonEmptyLevels(fams);
2287 * Returns all relative mesh levels (including nodes) where a given group is defined.
2288 * \param [in] grp - the name of the group of interest.
2289 * \return std::vector<int> - a sequence of the relative dimensions.
2291 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const throw(INTERP_KERNEL::Exception)
2293 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2294 return getFamsNonEmptyLevelsExt(fams);
2298 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2299 * To include nodes, call getFamNonEmptyLevelsExt() method.
2300 * \param [in] fam - the name of the family of interest.
2301 * \return std::vector<int> - a sequence of the relative dimensions.
2303 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const throw(INTERP_KERNEL::Exception)
2305 std::vector<std::string> fams(1,std::string(fam));
2306 return getFamsNonEmptyLevels(fams);
2310 * Returns all relative mesh levels (including nodes) where a given family is defined.
2311 * \param [in] fam - the name of the family of interest.
2312 * \return std::vector<int> - a sequence of the relative dimensions.
2314 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const throw(INTERP_KERNEL::Exception)
2316 std::vector<std::string> fams(1,std::string(fam));
2317 return getFamsNonEmptyLevelsExt(fams);
2321 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2322 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2323 * \param [in] grps - a sequence of names of the groups of interest.
2324 * \return std::vector<int> - a sequence of the relative dimensions.
2326 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2328 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2329 return getFamsNonEmptyLevels(fams);
2333 * Returns all relative mesh levels (including nodes) where given groups are defined.
2334 * \param [in] grps - a sequence of names of the groups of interest.
2335 * \return std::vector<int> - a sequence of the relative dimensions.
2337 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2339 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2340 return getFamsNonEmptyLevelsExt(fams);
2344 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2345 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2346 * \param [in] fams - the name of the family of interest.
2347 * \return std::vector<int> - a sequence of the relative dimensions.
2349 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2351 std::vector<int> ret;
2352 std::vector<int> levs=getNonEmptyLevels();
2353 std::vector<int> famIds=getFamiliesIds(fams);
2354 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2355 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2361 * Returns all relative mesh levels (including nodes) where given families are defined.
2362 * \param [in] fams - the names of the families of interest.
2363 * \return std::vector<int> - a sequence of the relative dimensions.
2365 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2367 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2368 const DataArrayInt *famCoords=_fam_coords;
2371 std::vector<int> famIds=getFamiliesIds(fams);
2372 if(famCoords->presenceOfValue(famIds))
2374 std::vector<int> ret(ret0.size()+1);
2376 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2384 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2385 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2386 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2389 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2391 std::vector<std::string> ret;
2392 std::vector<std::string> allGrps=getGroupsNames();
2393 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2395 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it).c_str());
2396 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2402 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2404 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2405 if((const DataArrayInt *)_fam_coords)
2407 int val=_fam_coords->getMaxValue(tmp);
2408 ret=std::max(ret,std::abs(val));
2410 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2412 if((const MEDFileUMeshSplitL1 *)(*it))
2414 const DataArrayInt *da=(*it)->getFamilyField();
2417 int val=da->getMaxValue(tmp);
2418 ret=std::max(ret,std::abs(val));
2425 int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2427 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2428 if((const DataArrayInt *)_fam_coords)
2430 int val=_fam_coords->getMaxValue(tmp);
2431 ret=std::max(ret,val);
2433 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2435 if((const MEDFileUMeshSplitL1 *)(*it))
2437 const DataArrayInt *da=(*it)->getFamilyField();
2440 int val=da->getMaxValue(tmp);
2441 ret=std::max(ret,val);
2448 int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2450 int ret=std::numeric_limits<int>::max(),tmp=-1;
2451 if((const DataArrayInt *)_fam_coords)
2453 int val=_fam_coords->getMinValue(tmp);
2454 ret=std::min(ret,val);
2456 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2458 if((const MEDFileUMeshSplitL1 *)(*it))
2460 const DataArrayInt *da=(*it)->getFamilyField();
2463 int val=da->getMinValue(tmp);
2464 ret=std::min(ret,val);
2472 * Returns the dimension on cells in \a this mesh.
2473 * \return int - the mesh dimension.
2474 * \throw If there are no cells in this mesh.
2476 int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
2479 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2480 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2481 return (*it)->getMeshDimension()+lev;
2482 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2486 * Returns the space dimension of \a this mesh that is equal to number of components in
2487 * the node coordinates array.
2488 * \return int - the space dimension of \a this mesh.
2489 * \throw If the node coordinates array is not available.
2491 int MEDFileUMesh::getSpaceDimension() const throw(INTERP_KERNEL::Exception)
2493 const DataArrayDouble *coo=_coords;
2495 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2496 return coo->getNumberOfComponents();
2500 * Returns a string describing \a this mesh.
2501 * \return std::string - the mesh information string.
2503 std::string MEDFileUMesh::simpleRepr() const
2505 std::ostringstream oss;
2506 oss << MEDFileMesh::simpleRepr();
2507 const DataArrayDouble *coo=_coords;
2508 oss << "- The dimension of the space is ";
2509 static const char MSG1[]= "*** NO COORDS SET ***";
2510 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2512 oss << _coords->getNumberOfComponents() << std::endl;
2514 oss << MSG1 << std::endl;
2515 oss << "- Type of the mesh : UNSTRUCTURED\n";
2516 oss << "- Number of nodes : ";
2518 oss << _coords->getNumberOfTuples() << std::endl;
2520 oss << MSG1 << std::endl;
2521 std::size_t nbOfLev=_ms.size();
2522 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2523 for(std::size_t i=0;i<nbOfLev;i++)
2525 const MEDFileUMeshSplitL1 *lev=_ms[i];
2526 oss << " - Level #" << -((int) i) << " has dimension : ";
2529 oss << lev->getMeshDimension() << std::endl;
2530 lev->simpleRepr(oss);
2533 oss << MSG2 << std::endl;
2535 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2538 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2539 oss << "- Names of coordinates :" << std::endl;
2540 std::vector<std::string> vars=coo->getVarsOnComponent();
2541 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2542 oss << std::endl << "- Units of coordinates : " << std::endl;
2543 std::vector<std::string> units=coo->getUnitsOnComponent();
2544 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2546 oss << std::endl << std::endl;
2552 * Returns a full textual description of \a this mesh.
2553 * \return std::string - the string holding the mesh description.
2555 std::string MEDFileUMesh::advancedRepr() const
2557 return simpleRepr();
2561 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2562 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2563 * \return int - the number of entities.
2564 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2566 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2568 if(meshDimRelToMaxExt==1)
2570 if(!((const DataArrayDouble *)_coords))
2571 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2572 return _coords->getNumberOfTuples();
2574 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2578 * Returns the family field for mesh entities of a given dimension.
2579 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2580 * \return const DataArrayInt * - the family field. It is an array of ids of families
2581 * each mesh entity belongs to. It can be \c NULL.
2583 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2585 if(meshDimRelToMaxExt==1)
2587 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2588 return l1->getFamilyField();
2592 * Returns the optional numbers of mesh entities of a given dimension.
2593 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2594 * \return const DataArrayInt * - the array of the entity numbers.
2595 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2597 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2599 if(meshDimRelToMaxExt==1)
2601 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2602 return l1->getNumberField();
2605 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2607 if(meshDimRelToMaxExt==1)
2608 return _name_coords;
2609 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2610 return l1->getNameField();
2613 int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
2615 const DataArrayDouble *coo=_coords;
2617 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2618 return coo->getNumberOfTuples();
2621 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
2623 std::size_t sz(st.getNumberOfItems());
2624 int mdim(getMeshDimension());
2625 for(std::size_t i=0;i<sz;i++)
2627 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2628 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(curGt);
2629 int relDim((int)cm.getDimension()-mdim);
2630 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(getMeshAtLevel(relDim));
2631 std::vector<int> d(um->getDistributionOfTypes());
2632 std::size_t nbOfTypes(d.size()/3);
2633 int offset=0,nbOfEltWT=-1;
2634 for(std::size_t j=0;j<nbOfTypes;j++)
2636 if(d[3*j]!=(int)curGt)
2639 { break; nbOfEltWT=d[3*j+1]; }
2642 throw INTERP_KERNEL::Exception("MEDFileUMesh::whichAreNodesFetched : asking for a geo type not present in this !");
2643 um=dynamic_cast<MEDCouplingUMesh *>(um->buildPartOfMySelf2(offset,offset+nbOfEltWT,1,true));
2644 if(st[i].getPflName().empty())
2645 um->computeNodeIdsAlg(nodesFetched);
2648 const DataArrayInt *arr(globs->getProfile(st[i].getPflName().c_str()));
2649 um=dynamic_cast<MEDCouplingUMesh *>(um->buildPartOfMySelf(arr->begin(),arr->end(),true));
2650 um->computeNodeIdsAlg(nodesFetched);
2656 * Returns the optional numbers of mesh entities of a given dimension transformed using
2657 * DataArrayInt::invertArrayN2O2O2N().
2658 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2659 * \return const DataArrayInt * - the array of the entity numbers transformed using
2660 * DataArrayInt::invertArrayN2O2O2N().
2661 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2663 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2665 if(meshDimRelToMaxExt==1)
2667 if(!((const DataArrayInt *)_num_coords))
2668 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2669 return _rev_num_coords;
2671 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2672 return l1->getRevNumberField();
2676 * Returns a pointer to the node coordinates array of \a this mesh \b without
2677 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2679 DataArrayDouble *MEDFileUMesh::getCoords() const
2681 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2682 if((DataArrayDouble *)tmp)
2690 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2691 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2693 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2694 * \param [in] grp - the name of the group whose mesh entities are included in the
2696 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2697 * according to the optional numbers of entities, if available.
2698 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2699 * delete this mesh using decrRef() as it is no more needed.
2700 * \throw If the name of a nonexistent group is specified.
2701 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2703 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
2705 synchronizeTinyInfoOnLeaves();
2706 std::vector<std::string> tmp(1);
2708 return getGroups(meshDimRelToMaxExt,tmp,renum);
2712 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2713 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2715 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2716 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2718 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2719 * according to the optional numbers of entities, if available.
2720 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2721 * delete this mesh using decrRef() as it is no more needed.
2722 * \throw If a name of a nonexistent group is present in \a grps.
2723 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2725 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
2727 synchronizeTinyInfoOnLeaves();
2728 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2729 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2730 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2731 zeRet->setName(grps[0].c_str());
2732 return zeRet.retn();
2736 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2737 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2739 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2740 * \param [in] fam - the name of the family whose mesh entities are included in the
2742 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2743 * according to the optional numbers of entities, if available.
2744 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2745 * delete this mesh using decrRef() as it is no more needed.
2746 * \throw If a name of a nonexistent family is present in \a grps.
2747 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2749 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
2751 synchronizeTinyInfoOnLeaves();
2752 std::vector<std::string> tmp(1);
2754 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2758 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2759 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2761 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2762 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2764 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2765 * according to the optional numbers of entities, if available.
2766 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2767 * delete this mesh using decrRef() as it is no more needed.
2768 * \throw If a name of a nonexistent family is present in \a fams.
2769 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2771 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2773 synchronizeTinyInfoOnLeaves();
2774 if(meshDimRelToMaxExt==1)
2776 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2777 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2778 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2782 std::vector<int> famIds=getFamiliesIds(fams);
2783 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2784 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2786 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2788 zeRet=l1->getFamilyPart(0,0,renum);
2789 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2790 zeRet->setName(fams[0].c_str());
2791 return zeRet.retn();
2795 * Returns ids of mesh entities contained in given families of a given dimension.
2796 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2798 * \param [in] fams - the names of the families of interest.
2799 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2800 * returned instead of ids.
2801 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2802 * numbers, if available and required, of mesh entities of the families. The caller
2803 * is to delete this array using decrRef() as it is no more needed.
2804 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2806 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2808 std::vector<int> famIds=getFamiliesIds(fams);
2809 if(meshDimRelToMaxExt==1)
2811 if((const DataArrayInt *)_fam_coords)
2813 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2815 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2817 da=_fam_coords->getIdsEqualList(0,0);
2819 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2824 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2826 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2828 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2830 return l1->getFamilyPartArr(0,0,renum);
2834 * Returns a MEDCouplingUMesh of a given relative dimension.
2835 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2836 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2837 * To build a valid MEDCouplingUMesh from the returned one in this case,
2838 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2839 * \param [in] meshDimRelToMax - the relative dimension of interest.
2840 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2841 * optional numbers of mesh entities.
2842 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2843 * delete using decrRef() as it is no more needed.
2844 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2845 * \sa getGenMeshAtLevel()
2847 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
2849 synchronizeTinyInfoOnLeaves();
2850 if(meshDimRelToMaxExt==1)
2854 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2855 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2856 umesh->setCoords(cc);
2857 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2858 umesh->setName(getName().c_str());
2862 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2863 return l1->getWholeMesh(renum);
2867 * Returns a MEDCouplingUMesh of a given relative dimension.
2868 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2869 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2870 * To build a valid MEDCouplingUMesh from the returned one in this case,
2871 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2872 * \param [in] meshDimRelToMax - the relative dimension of interest.
2873 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2874 * optional numbers of mesh entities.
2875 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2876 * delete using decrRef() as it is no more needed.
2877 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2878 * \sa getMeshAtLevel()
2880 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
2882 return getMeshAtLevel(meshDimRelToMax,renum);
2886 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2887 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2888 * optional numbers of mesh entities.
2889 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2890 * delete using decrRef() as it is no more needed.
2891 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2893 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2895 return getMeshAtLevel(0,renum);
2899 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2900 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2901 * optional numbers of mesh entities.
2902 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2903 * delete using decrRef() as it is no more needed.
2904 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2906 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2908 return getMeshAtLevel(-1,renum);
2912 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2913 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2914 * optional numbers of mesh entities.
2915 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2916 * delete using decrRef() as it is no more needed.
2917 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
2919 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2921 return getMeshAtLevel(-2,renum);
2925 * Returns a MEDCouplingUMesh of a relative dimension == -3.
2926 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2927 * optional numbers of mesh entities.
2928 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2929 * delete using decrRef() as it is no more needed.
2930 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
2932 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2934 return getMeshAtLevel(-3,renum);
2938 * This method returns a vector of mesh parts containing each exactly one geometric type.
2939 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
2940 * This method is only for memory aware users.
2942 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2944 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
2945 return sp->getDirectUndergroundSingleGeoTypeMeshes();
2949 * This method returns the part of \a this having the geometric type \a gt.
2950 * If such part is not existing an exception will be thrown.
2952 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception)
2954 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
2955 int lev=(int)cm.getDimension()-getMeshDimension();
2956 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
2957 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
2960 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2962 if(meshDimRelToMaxExt==1)
2963 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2964 if(meshDimRelToMaxExt>1)
2965 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2966 int tracucedRk=-meshDimRelToMaxExt;
2967 if(tracucedRk>=(int)_ms.size())
2968 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2969 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2970 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2971 return _ms[tracucedRk];
2974 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2976 if(meshDimRelToMaxExt==1)
2977 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2978 if(meshDimRelToMaxExt>1)
2979 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2980 int tracucedRk=-meshDimRelToMaxExt;
2981 if(tracucedRk>=(int)_ms.size())
2982 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2983 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2984 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2985 return _ms[tracucedRk];
2988 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2990 if(-meshDimRelToMax>=(int)_ms.size())
2991 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
2993 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2995 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
2997 int ref=(*it)->getMeshDimension();
2998 if(ref+i!=meshDim-meshDimRelToMax)
2999 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3005 * Sets the node coordinates array of \a this mesh.
3006 * \param [in] coords - the new node coordinates array.
3007 * \throw If \a coords == \c NULL.
3009 void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
3012 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3013 coords->checkAllocated();
3014 int nbOfTuples=coords->getNumberOfTuples();
3017 _fam_coords=DataArrayInt::New();
3018 _fam_coords->alloc(nbOfTuples,1);
3019 _fam_coords->fillWithZero();
3020 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3021 if((MEDFileUMeshSplitL1 *)(*it))
3022 (*it)->setCoords(coords);
3026 * Removes all groups of a given dimension in \a this mesh.
3027 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3028 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3030 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
3032 if(meshDimRelToMaxExt==1)
3034 if((DataArrayInt *)_fam_coords)
3035 _fam_coords->fillWithZero();
3038 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3039 l1->eraseFamilyField();
3044 * Removes all families with ids not present in the family fields of \a this mesh.
3046 void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
3048 std::vector<int> levs=getNonEmptyLevelsExt();
3049 std::set<int> allFamsIds;
3050 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3052 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3053 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3055 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3058 std::set<std::string> famNamesToKill;
3059 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3061 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3062 famNamesToKill.insert((*it).first);
3064 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3065 _families.erase(*it);
3066 std::vector<std::string> grpNamesToKill;
3067 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3069 std::vector<std::string> tmp;
3070 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3072 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3073 tmp.push_back(*it2);
3078 tmp.push_back((*it).first);
3080 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3084 void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception)
3086 std::vector<int> levs=getNonEmptyLevels();
3087 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3088 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3089 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3090 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3091 int nbNodes=m0->getNumberOfNodes();
3092 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3093 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3094 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3095 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3096 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3097 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3098 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3099 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3100 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3101 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3102 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3103 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3104 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3105 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3106 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3107 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3108 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3109 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3110 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3111 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3112 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3113 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3114 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3115 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3116 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3117 m0->setCoords(tmp0->getCoords());
3118 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3119 m1->setCoords(m0->getCoords());
3120 _coords=m0->getCoords(); _coords->incrRef();
3121 // duplication of cells in group 'grpNameM1' on level -1
3122 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3123 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3124 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3125 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3126 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3128 newm1->setName(getName().c_str());
3129 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3131 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3132 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3133 newFam->alloc(newm1->getNumberOfCells(),1);
3134 int idd=getMaxFamilyId()+1;
3135 int globStart=0,start=0,end,globEnd;
3136 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3137 for(int i=0;i<nbOfChunks;i++)
3139 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3140 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3142 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3143 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3144 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3149 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3153 newm1->setCoords(getCoords());
3154 setMeshAtLevel(-1,newm1);
3155 setFamilyFieldArr(-1,newFam);
3156 std::string grpName2(grpNameM1); grpName2+="_dup";
3157 addFamily(grpName2.c_str(),idd);
3158 addFamilyOnGrp(grpName2.c_str(),grpName2.c_str());
3163 int newNbOfNodes=getCoords()->getNumberOfTuples();
3164 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3165 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3166 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3169 nodesDuplicated=nodeIdsToDuplicate.retn();
3170 cellsModified=cellsToModifyConn0.retn();
3171 cellsNotModified=cellsToModifyConn1.retn();
3175 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3176 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3177 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3179 * \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.
3180 * 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.
3182 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
3184 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3185 std::vector<int> levs=getNonEmptyLevels();
3187 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3188 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3191 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3193 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3194 std::vector<int> code1=m->getDistributionOfTypes();
3195 end=PutInThirdComponentOfCodeOffset(code1,start);
3196 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3197 bool hasChanged=m->unPolyze();
3198 DataArrayInt *fake=0;
3199 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3200 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3202 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3205 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3206 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3208 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3209 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3210 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3211 setMeshAtLevel(*it,m);
3212 std::vector<int> code2=m->getDistributionOfTypes();
3213 end=PutInThirdComponentOfCodeOffset(code2,start);
3214 newCode.insert(newCode.end(),code2.begin(),code2.end());
3216 if(o2nCellsPart2->isIdentity())
3220 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3221 setFamilyFieldArr(*it,newFamField);
3225 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3226 setRenumFieldArr(*it,newNumField);
3231 newCode.insert(newCode.end(),code1.begin(),code1.end());
3237 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3238 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3239 o2nRenumCell=o2nRenumCellRet.retn();
3244 struct MEDLoaderAccVisit1
3246 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3247 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3248 int _new_nb_of_nodes;
3252 * 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.
3253 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3254 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3255 * -1 values in returned array means that the corresponding old node is no more used.
3257 * \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
3258 * is modified in \a this.
3259 * \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
3262 DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
3264 const DataArrayDouble *coo=getCoords();
3266 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3267 int nbOfNodes=coo->getNumberOfTuples();
3268 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3269 std::vector<int> neLevs=getNonEmptyLevels();
3270 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3272 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3273 m->computeNodeIdsAlg(nodeIdsInUse);
3275 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3276 if(nbrOfNodesInUse==nbOfNodes)
3278 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3279 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3280 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3281 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3282 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3283 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3284 if((const DataArrayInt *)_fam_coords)
3285 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3286 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3287 if((const DataArrayInt *)_num_coords)
3288 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3289 if((const DataArrayAsciiChar *)_name_coords)
3290 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3291 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3292 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3294 if((MEDFileUMeshSplitL1*)*it)
3295 (*it)->renumberNodesInConn(ret->begin());
3301 * Adds a group of nodes to \a this mesh.
3302 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3303 * The ids should be sorted and different each other (MED file norm).
3304 * \throw If the node coordinates array is not set.
3305 * \throw If \a ids == \c NULL.
3306 * \throw If \a ids->getName() == "".
3307 * \throw If \a ids does not respect the MED file norm.
3308 * \throw If a group with name \a ids->getName() already exists.
3310 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3312 const DataArrayDouble *coords=_coords;
3314 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3315 int nbOfNodes=coords->getNumberOfTuples();
3316 if(!((DataArrayInt *)_fam_coords))
3317 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3319 addGroupUnderground(true,ids,_fam_coords);
3323 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3324 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3325 * The ids should be sorted and different each other (MED file norm).
3326 * \throw If the node coordinates array is not set.
3327 * \throw If \a ids == \c NULL.
3328 * \throw If \a ids->getName() == "".
3329 * \throw If \a ids does not respect the MED file norm.
3330 * \throw If a group with name \a ids->getName() already exists.
3332 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3334 std::vector<int> levs=getNonEmptyLevelsExt();
3335 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3337 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3338 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3340 if(meshDimRelToMaxExt==1)
3341 { addNodeGroup(ids); return ; }
3342 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3343 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3344 addGroupUnderground(false,ids,fam);
3348 * \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).
3349 * \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)
3351 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3354 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3355 std::string grpName(ids->getName());
3357 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3358 ids->checkStrictlyMonotonic(true);
3359 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3360 std::vector<std::string> grpsNames=getGroupsNames();
3361 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3363 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3364 throw INTERP_KERNEL::Exception(oss.str().c_str());
3366 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3367 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3368 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3369 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3370 std::vector<int> familyIds;
3371 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3372 int maxVal=getTheMaxAbsFamilyId()+1;
3373 std::map<std::string,int> families(_families);
3374 std::map<std::string, std::vector<std::string> > groups(_groups);
3375 std::vector<std::string> fams;
3376 bool created(false);
3377 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3379 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3380 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3381 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3382 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3385 bool isFamPresent=false;
3386 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3387 isFamPresent=(*itl)->presenceOfValue(*famId);
3389 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3392 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3393 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3394 fams.push_back(locFamName);
3395 if(existsFamily(*famId))
3397 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3398 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3401 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3405 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3406 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3407 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3408 if(existsFamily(*famId))
3410 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3411 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3416 for(std::size_t i=0;i<familyIds.size();i++)
3418 DataArrayInt *da=idsPerfamiliyIds[i];
3419 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3423 _groups[grpName]=fams;
3427 * Changes a name of a family specified by its id.
3428 * \param [in] id - the id of the family of interest.
3429 * \param [in] newFamName - the new family name.
3430 * \throw If no family with the given \a id exists.
3432 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
3434 std::string oldName=getFamilyNameGivenId(id);
3435 _families.erase(oldName);
3436 _families[newFamName]=id;
3440 * Removes a mesh of a given dimension.
3441 * \param [in] meshDimRelToMax - the relative dimension of interest.
3442 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3444 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
3446 std::vector<int> levSet=getNonEmptyLevels();
3447 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3448 if(it==levSet.end())
3449 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3450 int pos=(-meshDimRelToMax);
3455 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3456 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3457 * \param [in] m - the new mesh to set.
3458 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3459 * writing \a this mesh in a MED file.
3460 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3462 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3463 * another node coordinates array.
3464 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3465 * to the existing meshes of other levels of \a this mesh.
3467 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
3469 dealWithTinyInfo(m);
3470 std::vector<int> levSet=getNonEmptyLevels();
3471 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3473 if((DataArrayDouble *)_coords==0)
3475 DataArrayDouble *c=m->getCoords();
3480 if(m->getCoords()!=_coords)
3481 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3482 int sz=(-meshDimRelToMax)+1;
3483 if(sz>=(int)_ms.size())
3485 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3486 _ms[sz-1]=new MEDFileUMeshSplitL1(m,newOrOld);
3489 _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld);
3493 * This method allows to set at once the content of different levels in \a this.
3494 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3496 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3497 * \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.
3498 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3500 * \throw If \a there is a null pointer in \a ms.
3501 * \sa MEDFileUMesh::setMeshAtLevel
3503 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3507 const MEDCouplingUMesh *mRef=ms[0];
3509 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3510 std::string name(mRef->getName());
3511 const DataArrayDouble *coo(mRef->getCoords());
3514 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3516 const MEDCouplingUMesh *cur(*it);
3518 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3519 if(coo!=cur->getCoords())
3520 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3521 int mdim=cur->getMeshDimension();
3522 zeDim=std::max(zeDim,mdim);
3523 if(s.find(mdim)!=s.end())
3524 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3526 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3528 int mdim=(*it)->getMeshDimension();
3529 setName((*it)->getName().c_str());
3530 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3532 setName(name.c_str());
3536 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3537 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3538 * The given meshes must share the same node coordinates array.
3539 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3540 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3541 * create in \a this mesh.
3542 * \throw If \a ms is empty.
3543 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3544 * to the existing meshes of other levels of \a this mesh.
3545 * \throw If the meshes in \a ms do not share the same node coordinates array.
3546 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3547 * of the given meshes.
3548 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3549 * \throw If names of some meshes in \a ms are equal.
3550 * \throw If \a ms includes a mesh with an empty name.
3552 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3555 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3556 int sz=(-meshDimRelToMax)+1;
3557 if(sz>=(int)_ms.size())
3559 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3560 DataArrayDouble *coo=checkMultiMesh(ms);
3561 if((DataArrayDouble *)_coords==0)
3567 if((DataArrayDouble *)_coords!=coo)
3568 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3569 std::vector<DataArrayInt *> corr;
3570 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3571 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3572 setMeshAtLevel(meshDimRelToMax,m,renum);
3573 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3574 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3578 * Creates groups at a given level in \a this mesh from a sequence of
3579 * meshes each representing a group.
3580 * The given meshes must share the same node coordinates array.
3581 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3582 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3583 * create in \a this mesh.
3584 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3586 * \throw If \a ms is empty.
3587 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3588 * to the existing meshes of other levels of \a this mesh.
3589 * \throw If the meshes in \a ms do not share the same node coordinates array.
3590 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3591 * of the given meshes.
3592 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3593 * \throw If names of some meshes in \a ms are equal.
3594 * \throw If \a ms includes a mesh with an empty name.
3596 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3599 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3600 int sz=(-meshDimRelToMax)+1;
3601 if(sz>=(int)_ms.size())
3603 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3604 DataArrayDouble *coo=checkMultiMesh(ms);
3605 if((DataArrayDouble *)_coords==0)
3611 if((DataArrayDouble *)_coords!=coo)
3612 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3613 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3614 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3616 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3618 DataArrayInt *arr=0;
3619 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3623 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3624 throw INTERP_KERNEL::Exception(oss.str().c_str());
3627 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3628 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3631 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const throw(INTERP_KERNEL::Exception)
3633 const DataArrayDouble *ret=ms[0]->getCoords();
3634 int mdim=ms[0]->getMeshDimension();
3635 for(unsigned int i=1;i<ms.size();i++)
3637 ms[i]->checkCoherency();
3638 if(ms[i]->getCoords()!=ret)
3639 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3640 if(ms[i]->getMeshDimension()!=mdim)
3641 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3643 return const_cast<DataArrayDouble *>(ret);
3647 * Sets the family field of a given relative dimension.
3648 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3649 * the family field is set.
3650 * \param [in] famArr - the array of the family field.
3651 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3652 * \throw If \a famArr has an invalid size.
3654 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3656 if(meshDimRelToMaxExt==1)
3663 DataArrayDouble *coo(_coords);
3665 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3666 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3671 if(meshDimRelToMaxExt>1)
3672 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3673 int traducedRk=-meshDimRelToMaxExt;
3674 if(traducedRk>=(int)_ms.size())
3675 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3676 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3677 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3678 return _ms[traducedRk]->setFamilyArr(famArr);
3682 * Sets the optional numbers of mesh entities of a given dimension.
3683 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3684 * \param [in] renumArr - the array of the numbers.
3685 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3686 * \throw If \a renumArr has an invalid size.
3688 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
3690 if(meshDimRelToMaxExt==1)
3698 DataArrayDouble *coo(_coords);
3700 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3701 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3702 renumArr->incrRef();
3703 _num_coords=renumArr;
3707 if(meshDimRelToMaxExt>1)
3708 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3709 int traducedRk=-meshDimRelToMaxExt;
3710 if(traducedRk>=(int)_ms.size())
3711 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3712 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3713 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3714 return _ms[traducedRk]->setRenumArr(renumArr);
3718 * Sets the optional names of mesh entities of a given dimension.
3719 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3720 * \param [in] nameArr - the array of the names.
3721 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3722 * \throw If \a nameArr has an invalid size.
3724 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
3726 if(meshDimRelToMaxExt==1)
3733 DataArrayDouble *coo(_coords);
3735 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3736 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3738 _name_coords=nameArr;
3741 if(meshDimRelToMaxExt>1)
3742 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3743 int traducedRk=-meshDimRelToMaxExt;
3744 if(traducedRk>=(int)_ms.size())
3745 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3746 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3747 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3748 return _ms[traducedRk]->setNameArr(nameArr);
3751 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3753 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3754 if((const MEDFileUMeshSplitL1 *)(*it))
3755 (*it)->synchronizeTinyInfo(*this);
3759 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3761 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
3763 DataArrayInt *arr=_fam_coords;
3765 arr->changeValue(oldId,newId);
3766 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3768 MEDFileUMeshSplitL1 *sp=(*it);
3771 sp->changeFamilyIdArr(oldId,newId);
3776 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3778 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3779 const DataArrayInt *da(_fam_coords);
3781 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3782 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3784 const MEDFileUMeshSplitL1 *elt(*it);
3787 da=elt->getFamilyField();
3789 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3795 void MEDFileUMesh::computeRevNum() const
3797 if((const DataArrayInt *)_num_coords)
3800 int maxValue=_num_coords->getMaxValue(pos);
3801 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3805 std::size_t MEDFileStructuredMesh::getHeapMemorySize() const
3807 std::size_t ret=MEDFileMesh::getHeapMemorySize();
3808 if((const DataArrayInt*)_fam_nodes)
3809 ret+=_fam_nodes->getHeapMemorySize();
3810 if((const DataArrayInt*)_num_nodes)
3811 ret+=_num_nodes->getHeapMemorySize();
3812 if((const DataArrayInt*)_fam_cells)
3813 ret+=_fam_cells->getHeapMemorySize();
3814 if((const DataArrayInt*)_num_cells)
3815 ret+=_num_cells->getHeapMemorySize();
3816 if((const DataArrayInt*)_rev_num_nodes)
3817 ret+=_rev_num_nodes->getHeapMemorySize();
3818 if((const DataArrayInt*)_rev_num_cells)
3819 ret+=_rev_num_cells->getHeapMemorySize();
3823 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3825 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3826 if((const DataArrayInt *)_fam_nodes)
3828 int val=_fam_nodes->getMaxValue(tmp);
3829 ret=std::max(ret,std::abs(val));
3831 if((const DataArrayInt *)_fam_cells)
3833 int val=_fam_cells->getMaxValue(tmp);
3834 ret=std::max(ret,std::abs(val));
3839 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3841 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3842 if((const DataArrayInt *)_fam_nodes)
3844 int val=_fam_nodes->getMaxValue(tmp);
3845 ret=std::max(ret,val);
3847 if((const DataArrayInt *)_fam_cells)
3849 int val=_fam_cells->getMaxValue(tmp);
3850 ret=std::max(ret,val);
3855 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3857 int ret=std::numeric_limits<int>::max(),tmp=-1;
3858 if((const DataArrayInt *)_fam_nodes)
3860 int val=_fam_nodes->getMinValue(tmp);
3861 ret=std::min(ret,val);
3863 if((const DataArrayInt *)_fam_cells)
3865 int val=_fam_cells->getMinValue(tmp);
3866 ret=std::min(ret,val);
3871 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3873 if(!MEDFileMesh::isEqual(other,eps,what))
3875 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
3878 what="Mesh types differ ! This is structured and other is NOT !";
3881 const DataArrayInt *famc1=_fam_nodes;
3882 const DataArrayInt *famc2=otherC->_fam_nodes;
3883 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3885 what="Mismatch of families arr on nodes ! One is defined and not other !";
3890 bool ret=famc1->isEqual(*famc2);
3893 what="Families arr on nodes differ !";
3898 famc2=otherC->_fam_cells;
3899 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3901 what="Mismatch of families arr on cells ! One is defined and not other !";
3906 bool ret=famc1->isEqual(*famc2);
3909 what="Families arr on cells differ !";
3914 famc2=otherC->_num_nodes;
3915 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3917 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
3922 bool ret=famc1->isEqual(*famc2);
3925 what="Numbering arr on nodes differ !";
3930 famc2=otherC->_num_cells;
3931 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3933 what="Mismatch of numbering arr on cells ! One is defined and not other !";
3938 bool ret=famc1->isEqual(*famc2);
3941 what="Numbering arr on cells differ !";
3945 const DataArrayAsciiChar *d1=_names_cells;
3946 const DataArrayAsciiChar *d2=otherC->_names_cells;
3947 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3949 what="Mismatch of naming arr on cells ! One is defined and not other !";
3954 bool ret=d1->isEqual(*d2);
3957 what="Naming arr on cells differ !";
3962 d2=otherC->_names_nodes;
3963 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3965 what="Mismatch of naming arr on nodes ! One is defined and not other !";
3970 bool ret=d1->isEqual(*d2);
3973 what="Naming arr on nodes differ !";
3980 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
3982 MEDFileMesh::clearNonDiscrAttributes();
3983 const DataArrayInt *tmp=_fam_nodes;
3985 (const_cast<DataArrayInt *>(tmp))->setName("");
3988 (const_cast<DataArrayInt *>(tmp))->setName("");
3991 (const_cast<DataArrayInt *>(tmp))->setName("");
3994 (const_cast<DataArrayInt *>(tmp))->setName("");
3998 * Returns ids of mesh entities contained in given families of a given dimension.
3999 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4001 * \param [in] fams - the names of the families of interest.
4002 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4003 * returned instead of ids.
4004 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4005 * numbers, if available and required, of mesh entities of the families. The caller
4006 * is to delete this array using decrRef() as it is no more needed.
4007 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4009 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
4011 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4012 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
4013 std::vector<int> famIds=getFamiliesIds(fams);
4014 if(meshDimRelToMaxExt==1)
4016 if((const DataArrayInt *)_fam_nodes)
4018 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4020 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4022 da=_fam_nodes->getIdsEqualList(0,0);
4024 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4029 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4033 if((const DataArrayInt *)_fam_cells)
4035 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4037 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4039 da=_fam_cells->getIdsEqualList(0,0);
4041 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4046 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4051 * Sets the family field of a given relative dimension.
4052 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4053 * the family field is set.
4054 * \param [in] famArr - the array of the family field.
4055 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4056 * \throw If \a famArr has an invalid size.
4057 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4059 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
4061 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4062 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4063 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4065 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4066 if(meshDimRelToMaxExt==0)
4068 int nbCells=mesh->getNumberOfCells();
4069 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4074 int nbNodes=mesh->getNumberOfNodes();
4075 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4083 * Sets the optional numbers of mesh entities of a given dimension.
4084 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4085 * \param [in] renumArr - the array of the numbers.
4086 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4087 * \throw If \a renumArr has an invalid size.
4088 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4090 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
4092 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4093 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4094 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4096 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4097 if(meshDimRelToMaxExt==0)
4099 int nbCells=mesh->getNumberOfCells();
4100 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4101 _num_cells=renumArr;
4105 int nbNodes=mesh->getNumberOfNodes();
4106 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4107 _num_nodes=renumArr;
4110 renumArr->incrRef();
4114 * Sets the optional names of mesh entities of a given dimension.
4115 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4116 * \param [in] nameArr - the array of the names.
4117 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4118 * \throw If \a nameArr has an invalid size.
4120 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
4122 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4123 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
4124 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4126 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4127 if(meshDimRelToMaxExt==0)
4129 int nbCells=mesh->getNumberOfCells();
4130 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4131 _names_cells=nameArr;
4135 int nbNodes=mesh->getNumberOfNodes();
4136 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4137 _names_nodes=nameArr;
4144 * Returns the family field for mesh entities of a given dimension.
4145 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4146 * \return const DataArrayInt * - the family field. It is an array of ids of families
4147 * each mesh entity belongs to. It can be \c NULL.
4148 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4150 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4152 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4153 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
4154 if(meshDimRelToMaxExt==0)
4161 * Returns the optional numbers of mesh entities of a given dimension.
4162 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4163 * \return const DataArrayInt * - the array of the entity numbers.
4164 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4165 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4167 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4169 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4170 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
4171 if(meshDimRelToMaxExt==0)
4178 * Returns the optional numbers of mesh entities of a given dimension transformed using
4179 * DataArrayInt::invertArrayN2O2O2N().
4180 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4181 * \return const DataArrayInt * - the array of the entity numbers transformed using
4182 * DataArrayInt::invertArrayN2O2O2N().
4183 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4184 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4186 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4188 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4189 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4190 if(meshDimRelToMaxExt==0)
4192 if((const DataArrayInt *)_num_cells)
4195 int maxValue=_num_cells->getMaxValue(pos);
4196 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4197 return _rev_num_cells;
4200 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4204 if((const DataArrayInt *)_num_nodes)
4207 int maxValue=_num_nodes->getMaxValue(pos);
4208 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4209 return _rev_num_nodes;
4212 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4216 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4218 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4219 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
4220 if(meshDimRelToMaxExt==0)
4221 return _names_cells;
4223 return _names_nodes;
4227 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4228 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4230 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4232 std::vector<int> ret(1);
4237 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4238 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4240 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4242 std::vector<int> ret(2);
4248 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4250 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4252 std::vector<int> ret;
4253 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells);
4262 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4264 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4266 std::vector<int> ret;
4267 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells);
4276 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4278 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4280 std::vector<int> ret;
4281 const DataArrayAsciiChar *namesCells(_names_cells);
4288 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4290 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
4292 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4296 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
4298 DataArrayInt *arr=_fam_nodes;
4300 arr->changeValue(oldId,newId);
4303 arr->changeValue(oldId,newId);
4306 void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
4308 if((const DataArrayInt*)_fam_nodes)
4309 _fam_nodes=_fam_nodes->deepCpy();
4310 if((const DataArrayInt*)_num_nodes)
4311 _num_nodes=_num_nodes->deepCpy();
4312 if((const DataArrayInt*)_fam_cells)
4313 _fam_cells=_fam_cells->deepCpy();
4314 if((const DataArrayInt*)_num_cells)
4315 _num_cells=_num_cells->deepCpy();
4316 if((const DataArrayInt*)_rev_num_nodes)
4317 _rev_num_nodes=_rev_num_nodes->deepCpy();
4318 if((const DataArrayInt*)_rev_num_cells)
4319 _rev_num_cells=_rev_num_cells->deepCpy();
4323 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4325 * \return a pointer to cartesian mesh that need to be managed by the caller.
4326 * \warning the returned pointer has to be managed by the caller.
4330 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4331 * \param [in] meshDimRelToMax - it must be \c 0.
4332 * \param [in] renum - it must be \c false.
4333 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4334 * delete using decrRef() as it is no more needed.
4336 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
4339 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4340 if(meshDimRelToMax!=0)
4341 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4342 const MEDCouplingStructuredMesh *m=getStructuredMesh();
4345 return const_cast<MEDCouplingStructuredMesh *>(m);
4349 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4350 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4351 * \return int - the number of entities.
4352 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4354 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4356 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4357 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
4358 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4360 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4361 if(meshDimRelToMaxExt==0)
4362 return cmesh->getNumberOfCells();
4364 return cmesh->getNumberOfNodes();
4367 int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
4369 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4371 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4372 return cmesh->getNumberOfNodes();
4375 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
4377 if(st.getNumberOfItems()!=1)
4378 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 !");
4379 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4380 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4381 if(getNumberOfNodes()!=(int)nodesFetched.size())
4382 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4383 if(st[0].getPflName().empty())
4385 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4388 const DataArrayInt *arr(globs->getProfile(st[0].getPflName().c_str()));
4389 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4390 int sz(nodesFetched.size());
4391 for(const int *work=arr->begin();work!=arr->end();work++)
4393 std::vector<int> conn;
4394 cmesh->getNodeIdsOfCell(*work,conn);
4395 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4396 if(*it>=0 && *it<sz)
4397 nodesFetched[*it]=true;
4399 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4403 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
4405 med_geometry_type geoTypeReq=MED_NONE;
4409 geoTypeReq=MED_HEXA8;
4412 geoTypeReq=MED_QUAD4;
4415 geoTypeReq=MED_SEG2;
4418 geoTypeReq=MED_POINT1;
4421 throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
4426 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4428 setName(strm->getName());
4429 setDescription(strm->getDescription());
4430 setUnivName(strm->getUnivName());
4431 setIteration(strm->getIteration());
4432 setOrder(strm->getOrder());
4433 setTimeValue(strm->getTime());
4434 setTimeUnit(strm->getTimeUnit());
4435 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4436 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4437 int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4440 if(!mrs || mrs->isNodeFamilyFieldReading())
4442 _fam_nodes=DataArrayInt::New();
4443 _fam_nodes->alloc(nbOfElt,1);
4444 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4447 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4450 if(!mrs || mrs->isNodeNumFieldReading())
4452 _num_nodes=DataArrayInt::New();
4453 _num_nodes->alloc(nbOfElt,1);
4454 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4457 int meshDim=getStructuredMesh()->getMeshDimension();
4458 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4459 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4462 if(!mrs || mrs->isCellFamilyFieldReading())
4464 _fam_cells=DataArrayInt::New();
4465 _fam_cells->alloc(nbOfElt,1);
4466 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
4469 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4472 if(!mrs || mrs->isCellNumFieldReading())
4474 _num_cells=DataArrayInt::New();
4475 _num_cells->alloc(nbOfElt,1);
4476 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
4479 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4482 if(!mrs || mrs->isCellNameFieldReading())
4484 _names_cells=DataArrayAsciiChar::New();
4485 _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4486 MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
4487 _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4490 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4493 if(!mrs || mrs->isNodeNameFieldReading())
4495 _names_nodes=DataArrayAsciiChar::New();
4496 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4497 MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4498 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4503 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
4505 int meshDim=getStructuredMesh()->getMeshDimension();
4506 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4508 if((const DataArrayInt *)_fam_cells)
4509 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4510 if((const DataArrayInt *)_fam_nodes)
4511 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4512 if((const DataArrayInt *)_num_cells)
4513 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4514 if((const DataArrayInt *)_num_nodes)
4515 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4516 if((const DataArrayAsciiChar *)_names_cells)
4518 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4520 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4521 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4522 throw INTERP_KERNEL::Exception(oss.str().c_str());
4524 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4526 if((const DataArrayAsciiChar *)_names_nodes)
4528 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4530 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4531 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4532 throw INTERP_KERNEL::Exception(oss.str().c_str());
4534 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4537 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
4541 * Returns an empty instance of MEDFileCMesh.
4542 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4543 * mesh using decrRef() as it is no more needed.
4545 MEDFileCMesh *MEDFileCMesh::New()
4547 return new MEDFileCMesh;
4551 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4552 * file. The first mesh in the file is loaded.
4553 * \param [in] fileName - the name of MED file to read.
4554 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4555 * mesh using decrRef() as it is no more needed.
4556 * \throw If the file is not readable.
4557 * \throw If there is no meshes in the file.
4558 * \throw If the mesh in the file is not a Cartesian one.
4560 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4562 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4565 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4566 throw INTERP_KERNEL::Exception(oss.str().c_str());
4568 MEDFileUtilities::CheckFileForRead(fileName);
4569 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4571 ParaMEDMEM::MEDCouplingMeshType meshType;
4573 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4574 return new MEDFileCMesh(fid,ms.front().c_str(),dt,it,mrs);
4578 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4579 * file. The mesh to load is specified by its name and numbers of a time step and an
4581 * \param [in] fileName - the name of MED file to read.
4582 * \param [in] mName - the name of the mesh to read.
4583 * \param [in] dt - the number of a time step.
4584 * \param [in] it - the number of an iteration.
4585 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4586 * mesh using decrRef() as it is no more needed.
4587 * \throw If the file is not readable.
4588 * \throw If there is no mesh with given attributes in the file.
4589 * \throw If the mesh in the file is not a Cartesian one.
4591 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4593 MEDFileUtilities::CheckFileForRead(fileName);
4594 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4595 return new MEDFileCMesh(fid,mName,dt,it,mrs);
4598 std::size_t MEDFileCMesh::getHeapMemorySize() const
4600 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4601 if((const MEDCouplingCMesh *)_cmesh)
4602 ret+=_cmesh->getHeapMemorySize();
4607 * Returns the dimension on cells in \a this mesh.
4608 * \return int - the mesh dimension.
4609 * \throw If there are no cells in this mesh.
4611 int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4613 if(!((const MEDCouplingCMesh*)_cmesh))
4614 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4615 return _cmesh->getMeshDimension();
4619 * Returns a string describing \a this mesh.
4620 * \return std::string - the mesh information string.
4622 std::string MEDFileCMesh::simpleRepr() const
4624 return MEDFileStructuredMesh::simpleRepr();
4628 * Returns a full textual description of \a this mesh.
4629 * \return std::string - the string holding the mesh description.
4631 std::string MEDFileCMesh::advancedRepr() const
4633 return simpleRepr();
4636 MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4638 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4642 MEDFileMesh *MEDFileCMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4644 return new MEDFileCMesh;
4647 MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4649 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4650 if((const MEDCouplingCMesh*)_cmesh)
4651 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
4652 ret->deepCpyAttributes();
4657 * Checks if \a this and another mesh are equal.
4658 * \param [in] other - the mesh to compare with.
4659 * \param [in] eps - a precision used to compare real values.
4660 * \param [in,out] what - the string returning description of unequal data.
4661 * \return bool - \c true if the meshes are equal, \c false, else.
4663 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4665 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4667 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
4670 what="Mesh types differ ! This is cartesian and other is NOT !";
4673 clearNonDiscrAttributes();
4674 otherC->clearNonDiscrAttributes();
4675 const MEDCouplingCMesh *coo1=_cmesh;
4676 const MEDCouplingCMesh *coo2=otherC->_cmesh;
4677 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4679 what="Mismatch of cartesian meshes ! One is defined and not other !";
4684 bool ret=coo1->isEqual(coo2,eps);
4687 what="cartesian meshes differ !";
4695 * Clears redundant attributes of incorporated data arrays.
4697 void MEDFileCMesh::clearNonDiscrAttributes() const
4699 MEDFileStructuredMesh::clearNonDiscrAttributes();
4700 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
4703 MEDFileCMesh::MEDFileCMesh()
4707 MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4710 loadCMeshFromFile(fid,mName,dt,it,mrs);
4712 catch(INTERP_KERNEL::Exception& e)
4717 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4719 ParaMEDMEM::MEDCouplingMeshType meshType;
4722 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4723 if(meshType!=CARTESIAN)
4725 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
4726 throw INTERP_KERNEL::Exception(oss.str().c_str());
4728 MEDFileCMeshL2 loaderl2;
4729 loaderl2.loadAll(fid,mid,mName,dt,it);
4730 MEDCouplingCMesh *mesh=loaderl2.getMesh();
4733 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
4737 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
4738 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
4740 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
4742 synchronizeTinyInfoOnLeaves();
4746 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
4748 synchronizeTinyInfoOnLeaves();
4753 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
4754 * \param [in] m - the new MEDCouplingCMesh to refer to.
4755 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4758 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
4760 dealWithTinyInfo(m);
4766 void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4768 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4769 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4770 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4771 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4772 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4773 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4774 int spaceDim=_cmesh->getSpaceDimension();
4775 int meshDim=_cmesh->getMeshDimension();
4776 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4777 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4778 for(int i=0;i<spaceDim;i++)
4780 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
4782 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4783 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
4784 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
4786 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4787 MEDmeshUniversalNameWr(fid,maa);
4788 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
4789 for(int i=0;i<spaceDim;i++)
4791 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
4792 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
4795 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4798 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
4800 const MEDCouplingCMesh *cmesh=_cmesh;
4803 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
4804 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
4805 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
4806 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
4809 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
4811 return new MEDFileCurveLinearMesh;
4814 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4816 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4819 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4820 throw INTERP_KERNEL::Exception(oss.str().c_str());
4822 MEDFileUtilities::CheckFileForRead(fileName);
4823 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4825 ParaMEDMEM::MEDCouplingMeshType meshType;
4827 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4828 return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it,mrs);
4831 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4833 MEDFileUtilities::CheckFileForRead(fileName);
4834 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4835 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
4838 std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const
4840 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4841 if((const MEDCouplingCurveLinearMesh *)_clmesh)
4842 ret+=_clmesh->getHeapMemorySize();
4846 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4848 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4852 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4854 return new MEDFileCurveLinearMesh;
4857 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4859 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4860 if((const MEDCouplingCurveLinearMesh*)_clmesh)
4861 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
4862 ret->deepCpyAttributes();
4866 int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4868 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
4869 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4870 return _clmesh->getMeshDimension();
4873 std::string MEDFileCurveLinearMesh::simpleRepr() const
4875 return MEDFileStructuredMesh::simpleRepr();
4878 std::string MEDFileCurveLinearMesh::advancedRepr() const
4880 return simpleRepr();
4883 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4885 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4887 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
4890 what="Mesh types differ ! This is curve linear and other is NOT !";
4893 clearNonDiscrAttributes();
4894 otherC->clearNonDiscrAttributes();
4895 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
4896 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
4897 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4899 what="Mismatch of curve linear meshes ! One is defined and not other !";
4904 bool ret=coo1->isEqual(coo2,eps);
4907 what="curve linear meshes differ !";
4914 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
4916 MEDFileStructuredMesh::clearNonDiscrAttributes();
4917 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
4920 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
4922 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
4925 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
4926 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
4927 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
4928 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
4931 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
4933 synchronizeTinyInfoOnLeaves();
4937 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
4939 dealWithTinyInfo(m);
4945 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
4947 synchronizeTinyInfoOnLeaves();
4951 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
4955 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4958 loadCLMeshFromFile(fid,mName,dt,it,mrs);
4960 catch(INTERP_KERNEL::Exception& e)
4965 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4967 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4968 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4969 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4970 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4971 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4972 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4973 int spaceDim=_clmesh->getSpaceDimension();
4974 int meshDim=_clmesh->getMeshDimension();
4975 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4976 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4977 const DataArrayDouble *coords=_clmesh->getCoords();
4979 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
4980 for(int i=0;i<spaceDim;i++)
4982 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
4984 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4985 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
4986 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
4988 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4989 MEDmeshUniversalNameWr(fid,maa);
4990 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
4991 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
4992 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
4994 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
4996 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4999 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
5001 ParaMEDMEM::MEDCouplingMeshType meshType;
5004 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5005 if(meshType!=CURVE_LINEAR)
5007 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5008 throw INTERP_KERNEL::Exception(oss.str().c_str());
5010 MEDFileCLMeshL2 loaderl2;
5011 loaderl2.loadAll(fid,mid,mName,dt,it);
5012 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5015 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5018 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5020 return new MEDFileMeshMultiTS;
5023 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
5025 return new MEDFileMeshMultiTS(fileName);
5028 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5030 return new MEDFileMeshMultiTS(fileName,mName);
5033 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
5035 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5036 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5038 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5039 if((const MEDFileMesh *)*it)
5040 meshOneTs[i]=(*it)->deepCpy();
5041 ret->_mesh_one_ts=meshOneTs;
5045 std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const
5047 std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5048 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5049 ret+=(*it)->getHeapMemorySize();
5053 std::string MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
5055 if(_mesh_one_ts.empty())
5056 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5057 return _mesh_one_ts[0]->getName();
5060 void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::Exception)
5062 std::string oldName(getName());
5063 std::vector< std::pair<std::string,std::string> > v(1);
5064 v[0].first=oldName; v[0].second=newMeshName;
5068 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
5071 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5073 MEDFileMesh *cur(*it);
5075 ret=cur->changeNames(modifTab) || ret;
5080 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception)
5082 if(_mesh_one_ts.empty())
5083 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5084 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5087 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception)
5090 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5091 _mesh_one_ts.resize(1);
5092 mesh1TimeStep->incrRef();
5093 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5094 _mesh_one_ts[0]=mesh1TimeStep;
5097 void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5099 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5101 (*it)->copyOptionsFrom(*this);
5106 void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5108 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5109 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5110 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5111 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5115 void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5116 {//for the moment to be improved
5117 _mesh_one_ts.resize(1);
5118 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5121 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5125 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception)
5128 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5131 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5132 throw INTERP_KERNEL::Exception(oss.str().c_str());
5134 MEDFileUtilities::CheckFileForRead(fileName);
5135 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
5137 ParaMEDMEM::MEDCouplingMeshType meshType;
5139 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
5140 loadFromFile(fileName,ms.front().c_str());
5142 catch(INTERP_KERNEL::Exception& e)
5147 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5150 loadFromFile(fileName,mName);
5152 catch(INTERP_KERNEL::Exception& e)
5157 MEDFileMeshes *MEDFileMeshes::New()
5159 return new MEDFileMeshes;
5162 MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception)
5164 return new MEDFileMeshes(fileName);
5167 void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5170 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5172 (*it)->copyOptionsFrom(*this);
5177 void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5179 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5180 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5181 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5182 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5187 int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception)
5189 return _meshes.size();
5192 MEDFileMeshesIterator *MEDFileMeshes::iterator() throw(INTERP_KERNEL::Exception)
5194 return new MEDFileMeshesIterator(this);
5197 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception)
5199 if(i<0 || i>=(int)_meshes.size())
5201 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5202 throw INTERP_KERNEL::Exception(oss.str().c_str());
5204 return _meshes[i]->getOneTimeStep();
5207 MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTERP_KERNEL::Exception)
5209 std::vector<std::string> ms=getMeshesNames();
5210 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5213 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5214 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5215 throw INTERP_KERNEL::Exception(oss.str().c_str());
5217 return getMeshAtPos((int)std::distance(ms.begin(),it));
5220 std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERNEL::Exception)
5222 std::vector<std::string> ret(_meshes.size());
5224 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5226 const MEDFileMeshMultiTS *f=(*it);
5229 ret[i]=f->getName();
5233 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5234 throw INTERP_KERNEL::Exception(oss.str().c_str());
5240 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
5243 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5245 MEDFileMeshMultiTS *cur(*it);
5247 ret=cur->changeNames(modifTab) || ret;
5252 void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception)
5254 _meshes.resize(newSize);
5257 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5260 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5261 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5262 elt->setOneTimeStep(mesh);
5263 _meshes.push_back(elt);
5266 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5269 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5270 if(i>=(int)_meshes.size())
5271 _meshes.resize(i+1);
5272 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5273 elt->setOneTimeStep(mesh);
5277 void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
5279 if(i<0 || i>=(int)_meshes.size())
5281 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5282 throw INTERP_KERNEL::Exception(oss.str().c_str());
5284 _meshes.erase(_meshes.begin()+i);
5287 void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception)
5289 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5291 _meshes.resize(ms.size());
5292 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5293 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str());
5296 MEDFileMeshes::MEDFileMeshes()
5300 MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception)
5303 loadFromFile(fileName);
5305 catch(INTERP_KERNEL::Exception& e)
5309 MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
5311 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5313 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5314 if((const MEDFileMeshMultiTS *)*it)
5315 meshes[i]=(*it)->deepCpy();
5316 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5317 ret->_meshes=meshes;
5321 std::size_t MEDFileMeshes::getHeapMemorySize() const
5323 std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5324 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5325 if((const MEDFileMeshMultiTS*)*it)
5326 ret+=(*it)->getHeapMemorySize();
5330 std::string MEDFileMeshes::simpleRepr() const
5332 std::ostringstream oss;
5333 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5334 simpleReprWithoutHeader(oss);
5338 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5340 int nbOfMeshes=getNumberOfMeshes();
5341 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5342 std::vector<std::string> mns=getMeshesNames();
5343 for(int i=0;i<nbOfMeshes;i++)
5344 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5347 void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception)
5349 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5351 std::set<std::string> s;
5352 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5354 const MEDFileMeshMultiTS *elt=(*it);
5357 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5358 throw INTERP_KERNEL::Exception(oss.str().c_str());
5360 std::size_t sz=s.size();
5361 s.insert(std::string((*it)->getName()));
5364 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5365 throw INTERP_KERNEL::Exception(oss.str().c_str());
5370 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5375 _nb_iter=ms->getNumberOfMeshes();
5379 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5383 MEDFileMesh *MEDFileMeshesIterator::nextt()
5385 if(_iter_id<_nb_iter)
5387 MEDFileMeshes *ms(_ms);
5389 return ms->getMeshAtPos(_iter_id++);