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 "MEDLoader.hxx"
24 #include "MEDLoaderBase.hxx"
26 #include "MEDCouplingUMesh.hxx"
28 #include "InterpKernelAutoPtr.hxx"
33 using namespace ParaMEDMEM;
35 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
37 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
41 std::size_t MEDFileMesh::getHeapMemorySize() const
43 std::size_t ret=_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity();
44 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
46 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
47 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
48 ret+=(*it2).capacity();
50 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
51 ret+=(*it).first.capacity()+sizeof(int);
56 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
57 * file. The first mesh in the file is loaded.
58 * \param [in] fileName - the name of MED file to read.
59 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
60 * mesh using decrRef() as it is no more needed.
61 * \throw If the file is not readable.
62 * \throw If there is no meshes in the file.
63 * \throw If the mesh in the file is of a not supported type.
65 MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
67 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
70 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
71 throw INTERP_KERNEL::Exception(oss.str().c_str());
73 MEDFileUtilities::CheckFileForRead(fileName);
74 ParaMEDMEM::MEDCouplingMeshType meshType;
75 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
78 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
83 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
84 ret->loadUMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
85 return (MEDFileUMesh *)ret.retn();
89 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
90 ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
91 return (MEDFileCMesh *)ret.retn();
95 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
96 ret->loadCLMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
97 return (MEDFileCurveLinearMesh *)ret.retn();
101 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
102 throw INTERP_KERNEL::Exception(oss.str().c_str());
108 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
109 * file. The mesh to load is specified by its name and numbers of a time step and an
111 * \param [in] fileName - the name of MED file to read.
112 * \param [in] mName - the name of the mesh to read.
113 * \param [in] dt - the number of a time step.
114 * \param [in] it - the number of an iteration.
115 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
116 * mesh using decrRef() as it is no more needed.
117 * \throw If the file is not readable.
118 * \throw If there is no mesh with given attributes in the file.
119 * \throw If the mesh in the file is of a not supported type.
121 MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
123 MEDFileUtilities::CheckFileForRead(fileName);
124 ParaMEDMEM::MEDCouplingMeshType meshType;
125 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
128 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
133 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
134 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
135 return (MEDFileUMesh *)ret.retn();
139 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
140 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
141 return (MEDFileCMesh *)ret.retn();
145 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
146 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
147 return (MEDFileCurveLinearMesh *)ret.retn();
151 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
152 throw INTERP_KERNEL::Exception(oss.str().c_str());
158 * Writes \a this mesh into an open MED file specified by its descriptor.
159 * \param [in] fid - the MED file descriptor.
160 * \throw If the mesh name is not set.
161 * \throw If the file is open for reading only.
162 * \throw If the writing mode == 1 and the same data is present in an existing file.
164 void MEDFileMesh::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
167 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
169 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
174 * Writes \a this mesh into a MED file specified by its name.
175 * \param [in] fileName - the MED file name.
176 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
177 * - 2 - erase; an existing file is removed.
178 * - 1 - append; same data should not be present in an existing file.
179 * - 0 - overwrite; same data present in an existing file is overwritten.
180 * \throw If the mesh name is not set.
181 * \throw If \a mode == 1 and the same data is present in an existing file.
183 void MEDFileMesh::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
185 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
186 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
187 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
188 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
193 * Checks if \a this and another mesh are equal.
194 * \param [in] other - the mesh to compare with.
195 * \param [in] eps - a precision used to compare real values.
196 * \param [in,out] what - the string returning description of unequal data.
197 * \return bool - \c true if the meshes are equal, \c false, else.
199 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
201 if(_order!=other->_order)
203 what="Orders differ !";
206 if(_iteration!=other->_iteration)
208 what="Iterations differ !";
211 if(fabs(_time-other->_time)>eps)
213 what="Time values differ !";
216 if(_dt_unit!=other->_dt_unit)
218 what="Time units differ !";
221 if(_name!=other->_name)
223 what="Names differ !";
226 //univ_name has been ignored -> not a bug because it is a mutable attribute
227 if(_desc_name!=other->_desc_name)
229 what="Description names differ !";
232 if(!areGrpsEqual(other,what))
234 if(!areFamsEqual(other,what))
240 * Clears redundant attributes of incorporated data arrays.
242 void MEDFileMesh::clearNonDiscrAttributes() const
247 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
249 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
251 if((*it).first==_name)
261 * Copies data on groups and families from another mesh.
262 * \param [in] other - the mesh to copy the data from.
264 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
266 _groups=other._groups;
267 _families=other._families;
271 * Returns names of families constituting a group.
272 * \param [in] name - the name of the group of interest.
273 * \return std::vector<std::string> - a sequence of names of the families.
274 * \throw If the name of a nonexistent group is specified.
276 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
278 std::string oname(name);
279 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
280 if(it==_groups.end())
282 std::vector<std::string> grps=getGroupsNames();
283 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
284 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
285 throw INTERP_KERNEL::Exception(oss.str().c_str());
291 * Returns names of families constituting some groups.
292 * \param [in] grps - a sequence of names of groups of interest.
293 * \return std::vector<std::string> - a sequence of names of the families.
294 * \throw If a name of a nonexistent group is present in \a grps.
296 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
298 std::set<std::string> fams;
299 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
301 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
302 if(it2==_groups.end())
304 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
305 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
306 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
307 throw INTERP_KERNEL::Exception(oss.str().c_str());
309 fams.insert((*it2).second.begin(),(*it2).second.end());
311 std::vector<std::string> fams2(fams.begin(),fams.end());
316 * Returns ids of families constituting a group.
317 * \param [in] name - the name of the group of interest.
318 * \return std::vector<int> - sequence of ids of the families.
319 * \throw If the name of a nonexistent group is specified.
321 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
323 std::string oname(name);
324 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
325 std::vector<std::string> grps=getGroupsNames();
326 if(it==_groups.end())
328 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
329 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
330 throw INTERP_KERNEL::Exception(oss.str().c_str());
332 return getFamiliesIds((*it).second);
336 * Sets names of families constituting a group. If data on families of this group is
337 * already present, it is overwritten. Every family in \a fams is checked, and if a
338 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
339 * \param [in] name - the name of the group of interest.
340 * \param [in] fams - a sequence of names of families constituting the group.
342 void MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception)
344 std::string oname(name);
346 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
348 std::map<std::string,int>::iterator it2=_families.find(*it1);
349 if(it2==_families.end())
355 * Sets families constituting a group. The families are specified by their ids.
356 * If a family name is not found by its id, an exception is thrown.
357 * If several families have same id, the first one in lexical order is taken.
358 * \param [in] name - the name of the group of interest.
359 * \param [in] famIds - a sequence of ids of families constituting the group.
360 * \throw If a family name is not found by its id.
362 void MEDFileMesh::setFamiliesIdsOnGroup(const char *name, const std::vector<int>& famIds) throw(INTERP_KERNEL::Exception)
364 std::string oname(name);
365 std::vector<std::string> fams(famIds.size());
367 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
369 std::string name2=getFamilyNameGivenId(*it1);
376 * Returns names of groups including a given family.
377 * \param [in] name - the name of the family of interest.
378 * \return std::vector<std::string> - a sequence of names of groups including the family.
380 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception)
382 std::vector<std::string> ret;
383 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
385 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
388 ret.push_back((*it1).first);
396 * Adds an existing family to groups.
397 * \param [in] famName - a name of family to add to \a grps.
398 * \param [in] grps - a sequence of group names to add the family in.
399 * \throw If a family named \a famName not yet exists.
401 void MEDFileMesh::setGroupsOnFamily(const char *famName, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception)
403 std::string fName(famName);
404 const std::map<std::string,int>::const_iterator it=_families.find(fName);
405 if(it==_families.end())
407 std::vector<std::string> fams=getFamiliesNames();
408 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
409 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
410 throw INTERP_KERNEL::Exception(oss.str().c_str());
412 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
414 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
415 if(it2!=_groups.end())
416 (*it2).second.push_back(fName);
419 std::vector<std::string> grps2(1,fName);
426 * Returns names of all groups of \a this mesh.
427 * \return std::vector<std::string> - a sequence of group names.
429 std::vector<std::string> MEDFileMesh::getGroupsNames() const
431 std::vector<std::string> ret(_groups.size());
433 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
439 * Returns names of all families of \a this mesh.
440 * \return std::vector<std::string> - a sequence of family names.
442 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
444 std::vector<std::string> ret(_families.size());
446 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
452 * Changes a name of every family, included in one group only, to be same as the group name.
453 * \throw If there are families with equal names in \a this mesh.
455 void MEDFileMesh::assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception)
457 std::map<std::string, std::vector<std::string> > groups(_groups);
458 std::map<std::string,int> newFams;
459 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
461 std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
462 if(grps.size()==1 && groups[grps[0]].size()==1)
464 if(newFams.find(grps[0])!=newFams.end())
466 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
467 throw INTERP_KERNEL::Exception(oss.str().c_str());
469 newFams[grps[0]]=(*it).second;
470 std::vector<std::string>& grps2=groups[grps[0]];
471 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
476 if(newFams.find((*it).first)!=newFams.end())
478 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
479 throw INTERP_KERNEL::Exception(oss.str().c_str());
481 newFams[(*it).first]=(*it).second;
489 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
491 * \return the removed groups.
493 std::vector<std::string> MEDFileMesh::removeEmptyGroups() throw(INTERP_KERNEL::Exception)
495 std::vector<std::string> ret;
496 std::map<std::string, std::vector<std::string> > newGrps;
497 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
499 if((*it).second.empty())
500 ret.push_back((*it).first);
502 newGrps[(*it).first]=(*it).second;
510 * Removes a group from \a this mesh.
511 * \param [in] name - the name of the group to remove.
512 * \throw If no group with such a \a name exists.
514 void MEDFileMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception)
516 std::string oname(name);
517 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
518 std::vector<std::string> grps=getGroupsNames();
519 if(it==_groups.end())
521 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
522 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
523 throw INTERP_KERNEL::Exception(oss.str().c_str());
529 * Removes a family from \a this mesh.
530 * \param [in] name - the name of the family to remove.
531 * \throw If no family with such a \a name exists.
533 void MEDFileMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception)
535 std::string oname(name);
536 std::map<std::string, int >::iterator it=_families.find(oname);
537 std::vector<std::string> fams=getFamiliesNames();
538 if(it==_families.end())
540 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
541 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
542 throw INTERP_KERNEL::Exception(oss.str().c_str());
545 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
547 std::vector<std::string>& v=(*it3).second;
548 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
555 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
556 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
557 * family field whatever its level. This method also suppresses the orphan families.
559 * \return - The list of removed groups names.
561 * \sa MEDFileMesh::removeOrphanFamilies.
563 std::vector<std::string> MEDFileMesh::removeOrphanGroups() throw(INTERP_KERNEL::Exception)
565 removeOrphanFamilies();
566 return removeEmptyGroups();
570 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
571 * 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.
573 * \return - The list of removed families names.
574 * \sa MEDFileMesh::removeOrphanGroups.
576 std::vector<std::string> MEDFileMesh::removeOrphanFamilies() throw(INTERP_KERNEL::Exception)
578 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
579 std::vector<std::string> ret;
580 if(!((DataArrayInt*)allFamIdsInUse))
582 ret=getFamiliesNames();
583 _families.clear(); _groups.clear();
586 std::map<std::string,int> famMap;
587 std::map<std::string, std::vector<std::string> > grps(_groups);
588 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
590 if(allFamIdsInUse->presenceOfValue((*it).second))
591 famMap[(*it).first]=(*it).second;
594 ret.push_back((*it).first);
595 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first.c_str());
596 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
598 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
599 std::vector<std::string>& famv=(*it3).second;
600 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
606 { _families=famMap; _groups=grps; }
611 * Renames a group in \a this mesh.
612 * \param [in] oldName - a current name of the group to rename.
613 * \param [in] newName - a new group name.
614 * \throw If no group named \a oldName exists in \a this mesh.
615 * \throw If a group named \a newName already exists.
617 void MEDFileMesh::changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
619 std::string oname(oldName);
620 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
621 std::vector<std::string> grps=getGroupsNames();
622 if(it==_groups.end())
624 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
625 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
626 throw INTERP_KERNEL::Exception(oss.str().c_str());
628 std::string nname(newName);
629 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
630 if(it2!=_groups.end())
632 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
633 throw INTERP_KERNEL::Exception(oss.str().c_str());
635 std::vector<std::string> cpy=(*it).second;
637 _groups[newName]=cpy;
641 * Changes an id of a family in \a this mesh.
642 * This method calls changeFamilyIdArr().
643 * \param [in] oldId - a current id of the family.
644 * \param [in] newId - a new family id.
646 void MEDFileMesh::changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception)
648 changeFamilyIdArr(oldId,newId);
649 std::map<std::string,int> fam2;
650 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
652 if((*it).second==oldId)
653 fam2[(*it).first]=newId;
655 fam2[(*it).first]=(*it).second;
661 * Renames a family in \a this mesh.
662 * \param [in] oldName - a current name of the family to rename.
663 * \param [in] newName - a new family name.
664 * \throw If no family named \a oldName exists in \a this mesh.
665 * \throw If a family named \a newName already exists.
667 void MEDFileMesh::changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
669 std::string oname(oldName);
670 std::map<std::string, int >::iterator it=_families.find(oname);
671 std::vector<std::string> fams=getFamiliesNames();
672 if(it==_families.end())
674 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
675 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
676 throw INTERP_KERNEL::Exception(oss.str().c_str());
678 std::string nname(newName);
679 std::map<std::string, int >::iterator it2=_families.find(nname);
680 if(it2!=_families.end())
682 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
683 throw INTERP_KERNEL::Exception(oss.str().c_str());
685 int cpy=(*it).second;
687 _families[newName]=cpy;
688 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
690 std::vector<std::string>& v=(*it3).second;
691 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
698 * Checks if \a this and another mesh contains the same families.
699 * \param [in] other - the mesh to compare with \a this one.
700 * \param [in,out] what - an unused parameter.
701 * \return bool - \c true if number of families and their ids are the same in the two
702 * meshes. Families with the id == \c 0 are not considered.
704 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
706 if(_families==other->_families)
708 std::map<std::string,int> fam0;
709 std::map<std::string,int> fam1;
710 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
712 fam0[(*it).first]=(*it).second;
713 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
715 fam1[(*it).first]=(*it).second;
720 * Checks if \a this and another mesh contains the same groups.
721 * \param [in] other - the mesh to compare with \a this one.
722 * \param [in,out] what - a string describing a difference of groups of the two meshes
723 * in case if this method returns \c false.
724 * \return bool - \c true if number of groups and families constituting them are the
725 * same in the two meshes.
727 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
729 if(_groups==other->_groups)
732 std::size_t sz=_groups.size();
733 if(sz!=other->_groups.size())
735 what="Groups differ because not same number !\n";
740 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
741 for(std::size_t i=0;i<sz && ret;i++,it1++)
743 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
744 if(it2!=other->_groups.end())
746 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
747 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
753 what="A group in first mesh exists not in other !\n";
759 std::ostringstream oss; oss << "Groups description differs :\n";
760 oss << "First group description :\n";
761 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
763 oss << " Group \"" << (*it).first << "\" on following families :\n";
764 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
765 oss << " \"" << *it2 << "\n";
767 oss << "Second group description :\n";
768 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
770 oss << " Group \"" << (*it).first << "\" on following families :\n";
771 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
772 oss << " \"" << *it2 << "\n";
780 * Checks if a group with a given name exists in \a this mesh.
781 * \param [in] groupName - the group name.
782 * \return bool - \c true the group \a groupName exists in \a this mesh.
784 bool MEDFileMesh::existsGroup(const char *groupName) const
786 std::string grpName(groupName);
787 return _groups.find(grpName)!=_groups.end();
791 * Checks if a family with a given id exists in \a this mesh.
792 * \param [in] famId - the family id.
793 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
795 bool MEDFileMesh::existsFamily(int famId) const
797 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
798 if((*it2).second==famId)
804 * Checks if a family with a given name exists in \a this mesh.
805 * \param [in] familyName - the family name.
806 * \return bool - \c true the family \a familyName exists in \a this mesh.
808 bool MEDFileMesh::existsFamily(const char *familyName) const
810 std::string fname(familyName);
811 return _families.find(fname)!=_families.end();
815 * Sets an id of a family.
816 * \param [in] familyName - the family name.
817 * \param [in] id - a new id of the family.
819 void MEDFileMesh::setFamilyId(const char *familyName, int id)
821 std::string fname(familyName);
825 void MEDFileMesh::setFamilyIdUnique(const char *familyName, int id) throw(INTERP_KERNEL::Exception)
827 std::string fname(familyName);
828 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
831 if((*it).first!=familyName)
833 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
834 throw INTERP_KERNEL::Exception(oss.str().c_str());
841 * Adds a family to \a this mesh.
842 * \param [in] familyName - a name of the family.
843 * \param [in] famId - an id of the family.
844 * \throw If a family with the same name or id already exists in \a this mesh.
846 void MEDFileMesh::addFamily(const char *familyName, int famId) throw(INTERP_KERNEL::Exception)
848 std::string fname(familyName);
849 std::map<std::string,int>::const_iterator it=_families.find(fname);
850 if(it==_families.end())
852 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
853 if((*it2).second==famId)
855 std::ostringstream oss;
856 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
857 throw INTERP_KERNEL::Exception(oss.str().c_str());
859 _families[fname]=famId;
863 if((*it).second!=famId)
865 std::ostringstream oss;
866 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
867 throw INTERP_KERNEL::Exception(oss.str().c_str());
873 * Creates a group including all mesh entities of given dimension.
874 * \warning This method does \b not guarantee that the created group includes mesh
875 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
876 * present in family fields of different dimensions. To assure this, call
877 * ensureDifferentFamIdsPerLevel() \b before calling this method.
878 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
880 * \param [in] groupName - a name of the new group.
881 * \throw If a group named \a groupName already exists.
882 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
883 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
885 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName) throw(INTERP_KERNEL::Exception)
887 std::string grpName(groupName);
888 std::vector<int> levs=getNonEmptyLevelsExt();
889 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
891 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
892 oss << "Available relative ext levels are : ";
893 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
894 throw INTERP_KERNEL::Exception(oss.str().c_str());
896 if(existsGroup(groupName))
898 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
899 oss << "Already existing groups are : ";
900 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
901 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
902 throw INTERP_KERNEL::Exception(oss.str().c_str());
904 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
906 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
907 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
908 std::vector<std::string> familiesOnWholeGroup;
909 for(const int *it=famIds->begin();it!=famIds->end();it++)
912 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
914 _groups[grpName]=familiesOnWholeGroup;
918 * Ensures that given family ids do not present in family fields of dimensions different
919 * than given ones. If a family id is present in the family fields of dimensions different
920 * than the given ones, a new family is created and the whole data is updated accordingly.
921 * \param [in] famIds - a sequence of family ids to check.
922 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
923 * famIds should exclusively belong.
924 * \return bool - \c true if no modification is done in \a this mesh by this method.
926 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
928 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
929 std::vector<int> levs=getNonEmptyLevelsExt();
930 std::set<int> levs2(levs.begin(),levs.end());
931 std::vector<int> levsToTest;
932 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
933 std::set<int> famIds2(famIds.begin(),famIds.end());
936 if(!_families.empty())
937 maxFamId=getMaxFamilyId()+1;
938 std::vector<std::string> allFams=getFamiliesNames();
939 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
941 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
944 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
945 std::vector<int> tmp;
946 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
947 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
950 std::string famName=getFamilyNameGivenId(*it2);
951 std::ostringstream oss; oss << "Family_" << maxFamId;
952 std::string zeName=CreateNameNotIn(oss.str(),allFams);
953 addFamilyOnAllGroupsHaving(famName.c_str(),zeName.c_str());
954 _families[zeName]=maxFamId;
955 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
964 * Adds a family to a given group in \a this mesh. If the group with a given name does
965 * not exist, it is created.
966 * \param [in] grpName - the name of the group to add the family in.
967 * \param [in] famName - the name of the family to add to the group named \a grpName.
968 * \throw If \a grpName or \a famName is an empty string.
969 * \throw If no family named \a famName is present in \a this mesh.
971 void MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName) throw(INTERP_KERNEL::Exception)
973 std::string grpn(grpName);
974 std::string famn(famName);
975 if(grpn.empty() || famn.empty())
976 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
977 std::vector<std::string> fams=getFamiliesNames();
978 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
980 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
981 oss << "Create this family or choose an existing one ! Existing fams are : ";
982 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
983 throw INTERP_KERNEL::Exception(oss.str().c_str());
985 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
986 if(it==_groups.end())
988 _groups[grpn].push_back(famn);
992 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
993 if(it2==(*it).second.end())
994 (*it).second.push_back(famn);
999 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1000 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1001 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1003 void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *otherFamName) throw(INTERP_KERNEL::Exception)
1005 std::string famNameCpp(famName);
1006 std::string otherCpp(otherFamName);
1007 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1009 std::vector<std::string>& v=(*it).second;
1010 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1012 v.push_back(otherCpp);
1017 void MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
1019 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1022 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)
1024 std::string fam(familyNameToChange);
1025 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1027 std::vector<std::string>& fams((*it).second);
1028 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1032 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1038 * Returns a name of the family having a given id or, if no such a family exists, creates
1039 * a new uniquely named family and returns its name.
1040 * \param [in] id - the id of the family whose name is required.
1041 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1042 * \return std::string - the name of the existing or the created family.
1043 * \throw If it is not possible to create a unique family name.
1045 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception)
1047 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1051 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1052 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1053 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1054 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1056 * This method will throws an exception if it is not possible to create a unique family name.
1058 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created) throw(INTERP_KERNEL::Exception)
1060 std::vector<std::string> famAlreadyExisting(families.size());
1062 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1064 if((*it).second!=id)
1066 famAlreadyExisting[ii]=(*it).first;
1075 std::ostringstream oss; oss << "Family_" << id;
1076 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1082 * Sets names and ids of all families in \a this mesh.
1083 * \param [in] info - a map of a family name to a family id.
1085 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1091 * Sets names of all groups and families constituting them in \a this mesh.
1092 * \param [in] info - a map of a group name to a vector of names of families
1093 * constituting the group.
1095 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1101 * Returns an id of the family having a given name.
1102 * \param [in] name - the name of the family of interest.
1103 * \return int - the id of the family of interest.
1104 * \throw If no family with such a \a name exists.
1106 int MEDFileMesh::getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception)
1108 std::string oname(name);
1109 std::map<std::string, int>::const_iterator it=_families.find(oname);
1110 std::vector<std::string> fams=getFamiliesNames();
1111 if(it==_families.end())
1113 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1114 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1115 throw INTERP_KERNEL::Exception(oss.str().c_str());
1117 return (*it).second;
1121 * Returns ids of the families having given names.
1122 * \param [in] fams - a sequence of the names of families of interest.
1123 * \return std::vector<int> - a sequence of the ids of families of interest.
1124 * \throw If \a fams contains a name of an inexistent family.
1126 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
1128 std::vector<int> ret(fams.size());
1130 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1132 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1133 if(it2==_families.end())
1135 std::vector<std::string> fams2=getFamiliesNames();
1136 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1137 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1138 throw INTERP_KERNEL::Exception(oss.str().c_str());
1140 ret[i]=(*it2).second;
1146 * Returns a maximal abs(id) of families in \a this mesh.
1147 * \return int - the maximal norm of family id.
1148 * \throw If there are no families in \a this mesh.
1150 int MEDFileMesh::getMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
1152 if(_families.empty())
1153 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1154 int ret=-std::numeric_limits<int>::max();
1155 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1157 ret=std::max(std::abs((*it).second),ret);
1163 * Returns a maximal id of families in \a this mesh.
1164 * \return int - the maximal family id.
1165 * \throw If there are no families in \a this mesh.
1167 int MEDFileMesh::getMaxFamilyId() const throw(INTERP_KERNEL::Exception)
1169 if(_families.empty())
1170 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1171 int ret=-std::numeric_limits<int>::max();
1172 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1174 ret=std::max((*it).second,ret);
1180 * Returns a minimal id of families in \a this mesh.
1181 * \return int - the minimal family id.
1182 * \throw If there are no families in \a this mesh.
1184 int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception)
1186 if(_families.empty())
1187 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1188 int ret=std::numeric_limits<int>::max();
1189 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1191 ret=std::min((*it).second,ret);
1197 * Returns a maximal id of families in \a this mesh. Not only named families are
1198 * considered but all family fields as well.
1199 * \return int - the maximal family id.
1201 int MEDFileMesh::getTheMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
1203 int m1=-std::numeric_limits<int>::max();
1204 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1205 m1=std::max(std::abs((*it).second),m1);
1206 int m2=getMaxAbsFamilyIdInArrays();
1207 return std::max(m1,m2);
1211 * Returns a maximal id of families in \a this mesh. Not only named families are
1212 * considered but all family fields as well.
1213 * \return int - the maximal family id.
1215 int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception)
1217 int m1=-std::numeric_limits<int>::max();
1218 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1219 m1=std::max((*it).second,m1);
1220 int m2=getMaxFamilyIdInArrays();
1221 return std::max(m1,m2);
1225 * Returns a minimal id of families in \a this mesh. Not only named families are
1226 * considered but all family fields as well.
1227 * \return int - the minimal family id.
1229 int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception)
1231 int m1=std::numeric_limits<int>::max();
1232 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1233 m1=std::min((*it).second,m1);
1234 int m2=getMinFamilyIdInArrays();
1235 return std::min(m1,m2);
1239 * This method only considers the maps. The contain of family array is ignored here.
1241 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1243 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception)
1245 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1247 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1248 v.insert((*it).second);
1249 ret->alloc((int)v.size(),1);
1250 std::copy(v.begin(),v.end(),ret->getPointer());
1255 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1257 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1259 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const throw(INTERP_KERNEL::Exception)
1261 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1262 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1263 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1265 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1266 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1267 if((DataArrayInt *) ret)
1268 ret=dv->buildUnion(ret);
1276 * true is returned if no modification has been needed. false if family
1277 * renumbering has been needed.
1279 bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception)
1281 std::vector<int> levs=getNonEmptyLevelsExt();
1282 std::set<int> allFamIds;
1283 int maxId=getMaxFamilyId()+1;
1284 std::map<int,std::vector<int> > famIdsToRenum;
1285 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1287 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1290 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1292 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1294 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1296 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1299 if(famIdsToRenum.empty())
1301 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1302 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1304 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1305 int *famIdsToChange=fam->getPointer();
1306 std::map<int,int> ren;
1307 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1309 if(allIds->presenceOfValue(*it3))
1311 std::string famName=getFamilyNameGivenId(*it3);
1312 std::vector<std::string> grps=getGroupsOnFamily(famName.c_str());
1315 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1316 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1317 addFamilyOnGrp((*it4).c_str(),newFam.c_str());
1320 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1321 for(const int *id=ids->begin();id!=ids->end();id++)
1322 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1328 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1329 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1330 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1331 * This method will throw an exception if a same family id is detected in different level.
1332 * \warning This policy is the opposite of those in MED file documentation ...
1334 void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
1336 ensureDifferentFamIdsPerLevel();
1337 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1338 std::vector<int> levs=getNonEmptyLevelsExt();
1339 std::set<int> levsS(levs.begin(),levs.end());
1340 std::set<std::string> famsFetched;
1341 std::map<std::string,int> families;
1342 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1345 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1349 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1350 std::map<int,int> ren;
1351 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1353 int nbOfTuples=fam->getNumberOfTuples();
1354 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1355 for(int *w=start;w!=start+nbOfTuples;w++)
1357 for(const int *it=tmp->begin();it!=tmp->end();it++)
1359 if(allIds->presenceOfValue(*it))
1361 std::string famName=getFamilyNameGivenId(*it);
1362 families[famName]=ren[*it];
1363 famsFetched.insert(famName);
1368 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1371 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1375 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1376 std::map<int,int> ren;
1377 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1379 int nbOfTuples=fam->getNumberOfTuples();
1380 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1381 for(int *w=start;w!=start+nbOfTuples;w++)
1383 for(const int *it=tmp->begin();it!=tmp->end();it++)
1385 if(allIds->presenceOfValue(*it))
1387 std::string famName=getFamilyNameGivenId(*it);
1388 families[famName]=ren[*it];
1389 famsFetched.insert(famName);
1394 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1396 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1399 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1400 fam->fillWithZero();
1401 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1402 if(allIds->presenceOfValue(*it3))
1404 std::string famName=getFamilyNameGivenId(*it3);
1405 families[famName]=0;
1406 famsFetched.insert(famName);
1411 std::vector<std::string> allFams=getFamiliesNames();
1412 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1413 std::set<std::string> unFetchedIds;
1414 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1415 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1416 families[*it4]=_families[*it4];
1421 * This method normalizes fam id with the following policy.
1422 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1423 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1424 * This method will throw an exception if a same family id is detected in different level.
1426 void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
1428 ensureDifferentFamIdsPerLevel();
1429 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1430 std::vector<int> levs=getNonEmptyLevelsExt();
1431 std::set<int> levsS(levs.begin(),levs.end());
1432 std::set<std::string> famsFetched;
1433 std::map<std::string,int> families;
1435 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1438 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1441 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1442 std::map<int,int> ren;
1443 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1445 int nbOfTuples=fam->getNumberOfTuples();
1446 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1447 for(int *w=start;w!=start+nbOfTuples;w++)
1449 for(const int *it=tmp->begin();it!=tmp->end();it++)
1451 if(allIds->presenceOfValue(*it))
1453 std::string famName=getFamilyNameGivenId(*it);
1454 families[famName]=ren[*it];
1455 famsFetched.insert(famName);
1461 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1463 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1466 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1467 std::map<int,int> ren;
1468 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1470 int nbOfTuples=fam->getNumberOfTuples();
1471 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1472 for(int *w=start;w!=start+nbOfTuples;w++)
1474 for(const int *it=tmp->begin();it!=tmp->end();it++)
1476 if(allIds->presenceOfValue(*it))
1478 std::string famName=getFamilyNameGivenId(*it);
1479 families[famName]=ren[*it];
1480 famsFetched.insert(famName);
1486 std::vector<std::string> allFams=getFamiliesNames();
1487 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1488 std::set<std::string> unFetchedIds;
1489 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1490 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1491 families[*it4]=_families[*it4];
1496 * Returns a name of the family by its id. If there are several families having the given
1497 * id, the name first in lexical order is returned.
1498 * \param [in] id - the id of the family whose name is required.
1499 * \return std::string - the name of the found family.
1500 * \throw If no family with the given \a id exists.
1502 std::string MEDFileMesh::getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception)
1504 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1505 if((*it).second==id)
1507 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1508 throw INTERP_KERNEL::Exception(oss.str().c_str());
1512 * Returns a string describing \a this mesh. This description includes the mesh name and
1513 * the mesh description string.
1514 * \return std::string - the mesh information string.
1516 std::string MEDFileMesh::simpleRepr() const
1518 std::ostringstream oss;
1519 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1520 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1521 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1526 * Returns ids of mesh entities contained in a given group of a given dimension.
1527 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1529 * \param [in] grp - the name of the group of interest.
1530 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1531 * returned instead of ids.
1532 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1533 * numbers, if available and required, of mesh entities of the group. The caller
1534 * is to delete this array using decrRef() as it is no more needed.
1535 * \throw If the name of a nonexistent group is specified.
1536 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1538 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1540 std::vector<std::string> tmp(1);
1542 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1548 * Returns ids of mesh entities contained in given groups of a given dimension.
1549 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1551 * \param [in] grps - the names of the groups of interest.
1552 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1553 * returned instead of ids.
1554 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1555 * numbers, if available and required, of mesh entities of the groups. The caller
1556 * is to delete this array using decrRef() as it is no more needed.
1557 * \throw If the name of a nonexistent group is present in \a grps.
1558 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1560 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1562 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1563 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1567 * Returns ids of mesh entities contained in a given family of a given dimension.
1568 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1570 * \param [in] fam - the name of the family of interest.
1571 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1572 * returned instead of ids.
1573 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1574 * numbers, if available and required, of mesh entities of the family. The caller
1575 * is to delete this array using decrRef() as it is no more needed.
1576 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1578 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1580 std::vector<std::string> tmp(1);
1582 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1588 * Returns ids of nodes contained in a given group.
1589 * \param [in] grp - the name of the group of interest.
1590 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1591 * returned instead of ids.
1592 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1593 * numbers, if available and required, of nodes of the group. The caller
1594 * is to delete this array using decrRef() as it is no more needed.
1595 * \throw If the name of a nonexistent group is specified.
1596 * \throw If the family field is missing for nodes.
1598 DataArrayInt *MEDFileMesh::getNodeGroupArr(const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1600 std::vector<std::string> tmp(1);
1602 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1608 * Returns ids of nodes contained in given groups.
1609 * \param [in] grps - the names of the groups of interest.
1610 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1611 * returned instead of ids.
1612 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1613 * numbers, if available and required, of nodes of the groups. The caller
1614 * is to delete this array using decrRef() as it is no more needed.
1615 * \throw If the name of a nonexistent group is present in \a grps.
1616 * \throw If the family field is missing for nodes.
1618 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1620 return getGroupsArr(1,grps,renum);
1624 * Returns ids of nodes contained in a given group.
1625 * \param [in] grp - the name of the group of interest.
1626 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1627 * returned instead of ids.
1628 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1629 * numbers, if available and required, of nodes of the group. The caller
1630 * is to delete this array using decrRef() as it is no more needed.
1631 * \throw If the name of a nonexistent group is specified.
1632 * \throw If the family field is missing for nodes.
1634 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1636 std::vector<std::string> tmp(1);
1638 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1644 * Returns ids of nodes contained in given families.
1645 * \param [in] fams - the names of the families of interest.
1646 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1647 * returned instead of ids.
1648 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1649 * numbers, if available and required, of nodes of the families. The caller
1650 * is to delete this array using decrRef() as it is no more needed.
1651 * \throw If the family field is missing for nodes.
1653 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
1655 return getFamiliesArr(1,fams,renum);
1659 * Adds groups of given dimension and creates corresponding families and family fields
1660 * given ids of mesh entities of each group.
1661 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1662 * \param [in] grps - a sequence of arrays of ids each describing a group.
1663 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1665 * \throw If names of some groups in \a grps are equal.
1666 * \throw If \a grps includes a group with an empty name.
1667 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1668 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1670 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum) throw(INTERP_KERNEL::Exception)
1674 std::set<std::string> grpsName;
1675 std::vector<std::string> grpsName2(grps.size());
1678 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1680 grpsName.insert((*it)->getName());
1681 grpsName2[i]=(*it)->getName();
1683 if(grpsName.size()!=grps.size())
1684 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1685 if(grpsName.find(std::string(""))!=grpsName.end())
1686 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1687 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1688 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1689 std::vector< std::vector<int> > fidsOfGroups;
1692 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1696 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1697 for(unsigned int ii=0;ii<grps.size();ii++)
1699 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1700 grps2[ii]->setName(grps[ii]->getName().c_str());
1702 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1703 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1706 if(!_families.empty())
1707 offset=getMaxAbsFamilyId()+1;
1708 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1709 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1710 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1711 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1715 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1716 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1717 * For the moment, the two last input parameters are not taken into account.
1719 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1721 std::map<int,std::string> famInv;
1722 for(const int *it=famIds->begin();it!=famIds->end();it++)
1724 std::ostringstream oss;
1725 oss << "Family_" << (*it);
1726 _families[oss.str()]=(*it);
1727 famInv[*it]=oss.str();
1730 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1732 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1734 _groups[grpNames[i]].push_back(famInv[*it2]);
1739 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1741 famArr->applyLin(offset>0?1:-1,offset,0);
1742 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1745 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1746 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1751 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1752 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1753 * If this method fails to find such a name it will throw an exception.
1755 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid) throw(INTERP_KERNEL::Exception)
1758 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1761 std::size_t len=nameTry.length();
1762 for(std::size_t ii=1;ii<len;ii++)
1764 std::string tmp=nameTry.substr(ii,len-ii);
1765 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1771 for(std::size_t i=1;i<30;i++)
1773 std::string tmp1(nameTry.at(0),i);
1775 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1781 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1783 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1785 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1788 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt) throw(INTERP_KERNEL::Exception)
1790 std::size_t nbOfChunks=code.size()/3;
1791 if(code.size()%3!=0)
1792 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1794 for(std::size_t i=0;i<nbOfChunks;i++)
1803 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1804 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1805 * If _name is not empty and that 'm' has the same name nothing is done.
1806 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1808 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL::Exception)
1811 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1816 std::string name(m->getName());
1821 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1822 oss << name << "' ! Names must match !";
1823 throw INTERP_KERNEL::Exception(oss.str().c_str());
1827 if(_desc_name.empty())
1828 _desc_name=m->getDescription();
1831 std::string name(m->getDescription());
1834 if(_desc_name!=name)
1836 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1837 oss << name << "' ! Names must match !";
1838 throw INTERP_KERNEL::Exception(oss.str().c_str());
1844 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1846 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1847 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1849 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1850 oss << " - Groups lying on this family : ";
1851 std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
1852 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1853 oss << std::endl << std::endl;
1858 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1859 * file. The mesh to load is specified by its name and numbers of a time step and an
1861 * \param [in] fileName - the name of MED file to read.
1862 * \param [in] mName - the name of the mesh to read.
1863 * \param [in] dt - the number of a time step.
1864 * \param [in] it - the number of an iteration.
1865 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1866 * mesh using decrRef() as it is no more needed.
1867 * \throw If the file is not readable.
1868 * \throw If there is no mesh with given attributes in the file.
1869 * \throw If the mesh in the file is not an unstructured one.
1871 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
1873 MEDFileUtilities::CheckFileForRead(fileName);
1874 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1875 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1879 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1880 * file. The first mesh in the file is loaded.
1881 * \param [in] fileName - the name of MED file to read.
1882 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1883 * mesh using decrRef() as it is no more needed.
1884 * \throw If the file is not readable.
1885 * \throw If there is no meshes in the file.
1886 * \throw If the mesh in the file is not an unstructured one.
1888 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
1890 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1893 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1894 throw INTERP_KERNEL::Exception(oss.str().c_str());
1896 MEDFileUtilities::CheckFileForRead(fileName);
1897 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1899 ParaMEDMEM::MEDCouplingMeshType meshType;
1901 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
1902 return new MEDFileUMesh(fid,ms.front().c_str(),dt,it,mrs);
1906 * Returns an empty instance of MEDFileUMesh.
1907 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1908 * mesh using decrRef() as it is no more needed.
1910 MEDFileUMesh *MEDFileUMesh::New()
1912 return new MEDFileUMesh;
1915 std::size_t MEDFileUMesh::getHeapMemorySize() const
1917 std::size_t ret=MEDFileMesh::getHeapMemorySize();
1918 if((const DataArrayDouble*)_coords)
1919 ret+=_coords->getHeapMemorySize();
1920 if((const DataArrayInt *)_fam_coords)
1921 ret+=_fam_coords->getHeapMemorySize();
1922 if((const DataArrayInt *)_num_coords)
1923 ret+=_num_coords->getHeapMemorySize();
1924 if((const DataArrayInt *)_rev_num_coords)
1925 ret+=_rev_num_coords->getHeapMemorySize();
1926 if((const DataArrayAsciiChar *)_name_coords)
1927 ret+=_name_coords->getHeapMemorySize();
1928 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1929 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1930 if((const MEDFileUMeshSplitL1*) *it)
1931 ret+=(*it)->getHeapMemorySize();
1935 MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
1937 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1941 MEDFileMesh *MEDFileUMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
1943 return new MEDFileUMesh;
1946 MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
1948 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1949 if((const DataArrayDouble*)_coords)
1950 ret->_coords=_coords->deepCpy();
1951 if((const DataArrayInt*)_fam_coords)
1952 ret->_fam_coords=_fam_coords->deepCpy();
1953 if((const DataArrayInt*)_num_coords)
1954 ret->_num_coords=_num_coords->deepCpy();
1955 if((const DataArrayInt*)_rev_num_coords)
1956 ret->_rev_num_coords=_rev_num_coords->deepCpy();
1957 if((const DataArrayAsciiChar*)_name_coords)
1958 ret->_name_coords=_name_coords->deepCpy();
1960 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
1962 if((const MEDFileUMeshSplitL1 *)(*it))
1963 ret->_ms[i]=(*it)->deepCpy();
1969 * Checks if \a this and another mesh are equal.
1970 * \param [in] other - the mesh to compare with.
1971 * \param [in] eps - a precision used to compare real values.
1972 * \param [in,out] what - the string returning description of unequal data.
1973 * \return bool - \c true if the meshes are equal, \c false, else.
1975 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
1977 if(!MEDFileMesh::isEqual(other,eps,what))
1979 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
1982 what="Mesh types differ ! This is unstructured and other is NOT !";
1985 clearNonDiscrAttributes();
1986 otherC->clearNonDiscrAttributes();
1987 const DataArrayDouble *coo1=_coords;
1988 const DataArrayDouble *coo2=otherC->_coords;
1989 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
1991 what="Mismatch of coordinates ! One is defined and not other !";
1996 bool ret=coo1->isEqual(*coo2,eps);
1999 what="Coords differ !";
2003 const DataArrayInt *famc1=_fam_coords;
2004 const DataArrayInt *famc2=otherC->_fam_coords;
2005 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2007 what="Mismatch of families arr on nodes ! One is defined and not other !";
2012 bool ret=famc1->isEqual(*famc2);
2015 what="Families arr on node differ !";
2019 const DataArrayInt *numc1=_num_coords;
2020 const DataArrayInt *numc2=otherC->_num_coords;
2021 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2023 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2028 bool ret=numc1->isEqual(*numc2);
2031 what="Numbering arr on node differ !";
2035 const DataArrayAsciiChar *namec1=_name_coords;
2036 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2037 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2039 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2044 bool ret=namec1->isEqual(*namec2);
2047 what="Names arr on node differ !";
2051 if(_ms.size()!=otherC->_ms.size())
2053 what="Number of levels differs !";
2056 std::size_t sz=_ms.size();
2057 for(std::size_t i=0;i<sz;i++)
2059 const MEDFileUMeshSplitL1 *s1=_ms[i];
2060 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2061 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2063 what="Mismatch of presence of sub levels !";
2068 bool ret=s1->isEqual(s2,eps,what);
2077 * Clears redundant attributes of incorporated data arrays.
2079 void MEDFileUMesh::clearNonDiscrAttributes() const
2081 MEDFileMesh::clearNonDiscrAttributes();
2082 const DataArrayDouble *coo1=_coords;
2084 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2085 const DataArrayInt *famc1=_fam_coords;
2087 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2088 const DataArrayInt *numc1=_num_coords;
2090 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2091 const DataArrayAsciiChar *namc1=_name_coords;
2093 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2094 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2096 const MEDFileUMeshSplitL1 *tmp=(*it);
2098 tmp->clearNonDiscrAttributes();
2102 MEDFileUMesh::MEDFileUMesh()
2106 MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
2109 loadUMeshFromFile(fid,mName,dt,it,mrs);
2111 catch(INTERP_KERNEL::Exception& e)
2116 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
2118 MEDFileUMeshL2 loaderl2;
2119 ParaMEDMEM::MEDCouplingMeshType meshType;
2122 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
2123 if(meshType!=UNSTRUCTURED)
2125 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2126 throw INTERP_KERNEL::Exception(oss.str().c_str());
2128 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2129 int lev=loaderl2.getNumberOfLevels();
2131 for(int i=0;i<lev;i++)
2133 if(!loaderl2.emptyLev(i))
2134 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2138 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2140 setName(loaderl2.getName());
2141 setDescription(loaderl2.getDescription());
2142 setUnivName(loaderl2.getUnivName());
2143 setIteration(loaderl2.getIteration());
2144 setOrder(loaderl2.getOrder());
2145 setTimeValue(loaderl2.getTime());
2146 setTimeUnit(loaderl2.getTimeUnit());
2147 _coords=loaderl2.getCoords();
2148 if(!mrs || mrs->isNodeFamilyFieldReading())
2149 _fam_coords=loaderl2.getCoordsFamily();
2150 if(!mrs || mrs->isNodeNumFieldReading())
2151 _num_coords=loaderl2.getCoordsNum();
2152 if(!mrs || mrs->isNodeNameFieldReading())
2153 _name_coords=loaderl2.getCoordsName();
2157 MEDFileUMesh::~MEDFileUMesh()
2161 void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
2163 const DataArrayDouble *coo=_coords;
2164 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2165 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2166 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2167 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2168 int spaceDim=coo?coo->getNumberOfComponents():0;
2169 int mdim=getMeshDimension();
2170 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2171 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2172 for(int i=0;i<spaceDim;i++)
2174 std::string info=coo->getInfoOnComponent(i);
2176 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2177 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
2178 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
2180 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2181 MEDmeshUniversalNameWr(fid,maa);
2182 MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2183 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2184 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2185 (*it)->write(fid,maa,mdim);
2186 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
2190 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2191 * \return std::vector<int> - a sequence of the relative dimensions.
2193 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2195 std::vector<int> ret;
2197 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2198 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2205 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2206 * \return std::vector<int> - a sequence of the relative dimensions.
2208 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2210 std::vector<int> ret0=getNonEmptyLevels();
2211 if((const DataArrayDouble *) _coords)
2213 std::vector<int> ret(ret0.size()+1);
2215 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2221 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2223 std::vector<int> ret;
2224 const DataArrayInt *famCoo(_fam_coords);
2228 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2230 const MEDFileUMeshSplitL1 *cur(*it);
2232 if(cur->getFamilyField())
2238 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2240 std::vector<int> ret;
2241 const DataArrayInt *numCoo(_num_coords);
2245 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2247 const MEDFileUMeshSplitL1 *cur(*it);
2249 if(cur->getNumberField())
2255 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2257 std::vector<int> ret;
2258 const DataArrayAsciiChar *nameCoo(_name_coords);
2262 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2264 const MEDFileUMeshSplitL1 *cur(*it);
2266 if(cur->getNameField())
2273 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2274 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2275 * \param [in] grp - the name of the group of interest.
2276 * \return std::vector<int> - a sequence of the relative dimensions.
2278 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const throw(INTERP_KERNEL::Exception)
2280 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2281 return getFamsNonEmptyLevels(fams);
2285 * Returns all relative mesh levels (including nodes) where a given group is defined.
2286 * \param [in] grp - the name of the group of interest.
2287 * \return std::vector<int> - a sequence of the relative dimensions.
2289 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const throw(INTERP_KERNEL::Exception)
2291 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2292 return getFamsNonEmptyLevelsExt(fams);
2296 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2297 * To include nodes, call getFamNonEmptyLevelsExt() method.
2298 * \param [in] fam - the name of the family of interest.
2299 * \return std::vector<int> - a sequence of the relative dimensions.
2301 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const throw(INTERP_KERNEL::Exception)
2303 std::vector<std::string> fams(1,std::string(fam));
2304 return getFamsNonEmptyLevels(fams);
2308 * Returns all relative mesh levels (including nodes) where a given family is defined.
2309 * \param [in] fam - the name of the family of interest.
2310 * \return std::vector<int> - a sequence of the relative dimensions.
2312 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const throw(INTERP_KERNEL::Exception)
2314 std::vector<std::string> fams(1,std::string(fam));
2315 return getFamsNonEmptyLevelsExt(fams);
2319 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2320 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2321 * \param [in] grps - a sequence of names of the groups of interest.
2322 * \return std::vector<int> - a sequence of the relative dimensions.
2324 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2326 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2327 return getFamsNonEmptyLevels(fams);
2331 * Returns all relative mesh levels (including nodes) where given groups are defined.
2332 * \param [in] grps - a sequence of names of the groups of interest.
2333 * \return std::vector<int> - a sequence of the relative dimensions.
2335 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2337 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2338 return getFamsNonEmptyLevelsExt(fams);
2342 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2343 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2344 * \param [in] fams - the name of the family of interest.
2345 * \return std::vector<int> - a sequence of the relative dimensions.
2347 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2349 std::vector<int> ret;
2350 std::vector<int> levs=getNonEmptyLevels();
2351 std::vector<int> famIds=getFamiliesIds(fams);
2352 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2353 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2359 * Returns all relative mesh levels (including nodes) where given families are defined.
2360 * \param [in] fams - the names of the families of interest.
2361 * \return std::vector<int> - a sequence of the relative dimensions.
2363 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2365 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2366 const DataArrayInt *famCoords=_fam_coords;
2369 std::vector<int> famIds=getFamiliesIds(fams);
2370 if(famCoords->presenceOfValue(famIds))
2372 std::vector<int> ret(ret0.size()+1);
2374 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2382 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2383 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2384 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2387 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2389 std::vector<std::string> ret;
2390 std::vector<std::string> allGrps=getGroupsNames();
2391 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2393 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it).c_str());
2394 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2400 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2402 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2403 if((const DataArrayInt *)_fam_coords)
2405 int val=_fam_coords->getMaxValue(tmp);
2406 ret=std::max(ret,std::abs(val));
2408 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2410 if((const MEDFileUMeshSplitL1 *)(*it))
2412 const DataArrayInt *da=(*it)->getFamilyField();
2415 int val=da->getMaxValue(tmp);
2416 ret=std::max(ret,std::abs(val));
2423 int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2425 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2426 if((const DataArrayInt *)_fam_coords)
2428 int val=_fam_coords->getMaxValue(tmp);
2429 ret=std::max(ret,val);
2431 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2433 if((const MEDFileUMeshSplitL1 *)(*it))
2435 const DataArrayInt *da=(*it)->getFamilyField();
2438 int val=da->getMaxValue(tmp);
2439 ret=std::max(ret,val);
2446 int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2448 int ret=std::numeric_limits<int>::max(),tmp=-1;
2449 if((const DataArrayInt *)_fam_coords)
2451 int val=_fam_coords->getMinValue(tmp);
2452 ret=std::min(ret,val);
2454 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2456 if((const MEDFileUMeshSplitL1 *)(*it))
2458 const DataArrayInt *da=(*it)->getFamilyField();
2461 int val=da->getMinValue(tmp);
2462 ret=std::min(ret,val);
2470 * Returns the dimension on cells in \a this mesh.
2471 * \return int - the mesh dimension.
2472 * \throw If there are no cells in this mesh.
2474 int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
2477 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2478 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2479 return (*it)->getMeshDimension()+lev;
2480 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2484 * Returns the space dimension of \a this mesh that is equal to number of components in
2485 * the node coordinates array.
2486 * \return int - the space dimension of \a this mesh.
2487 * \throw If the node coordinates array is not available.
2489 int MEDFileUMesh::getSpaceDimension() const throw(INTERP_KERNEL::Exception)
2491 const DataArrayDouble *coo=_coords;
2493 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2494 return coo->getNumberOfComponents();
2498 * Returns a string describing \a this mesh.
2499 * \return std::string - the mesh information string.
2501 std::string MEDFileUMesh::simpleRepr() const
2503 std::ostringstream oss;
2504 oss << MEDFileMesh::simpleRepr();
2505 const DataArrayDouble *coo=_coords;
2506 oss << "- The dimension of the space is ";
2507 static const char MSG1[]= "*** NO COORDS SET ***";
2508 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2510 oss << _coords->getNumberOfComponents() << std::endl;
2512 oss << MSG1 << std::endl;
2513 oss << "- Type of the mesh : UNSTRUCTURED\n";
2514 oss << "- Number of nodes : ";
2516 oss << _coords->getNumberOfTuples() << std::endl;
2518 oss << MSG1 << std::endl;
2519 std::size_t nbOfLev=_ms.size();
2520 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2521 for(std::size_t i=0;i<nbOfLev;i++)
2523 const MEDFileUMeshSplitL1 *lev=_ms[i];
2524 oss << " - Level #" << -((int) i) << " has dimension : ";
2527 oss << lev->getMeshDimension() << std::endl;
2528 lev->simpleRepr(oss);
2531 oss << MSG2 << std::endl;
2533 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2536 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2537 oss << "- Names of coordinates :" << std::endl;
2538 std::vector<std::string> vars=coo->getVarsOnComponent();
2539 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2540 oss << std::endl << "- Units of coordinates : " << std::endl;
2541 std::vector<std::string> units=coo->getUnitsOnComponent();
2542 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2544 oss << std::endl << std::endl;
2550 * Returns a full textual description of \a this mesh.
2551 * \return std::string - the string holding the mesh description.
2553 std::string MEDFileUMesh::advancedRepr() const
2555 return simpleRepr();
2559 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2560 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2561 * \return int - the number of entities.
2562 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2564 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2566 if(meshDimRelToMaxExt==1)
2568 if(!((const DataArrayDouble *)_coords))
2569 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2570 return _coords->getNumberOfTuples();
2572 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2576 * Returns the family field for mesh entities of a given dimension.
2577 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2578 * \return const DataArrayInt * - the family field. It is an array of ids of families
2579 * each mesh entity belongs to. It can be \c NULL.
2581 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2583 if(meshDimRelToMaxExt==1)
2585 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2586 return l1->getFamilyField();
2590 * Returns the optional numbers of mesh entities of a given dimension.
2591 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2592 * \return const DataArrayInt * - the array of the entity numbers.
2593 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2595 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2597 if(meshDimRelToMaxExt==1)
2599 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2600 return l1->getNumberField();
2603 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2605 if(meshDimRelToMaxExt==1)
2606 return _name_coords;
2607 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2608 return l1->getNameField();
2611 int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
2613 const DataArrayDouble *coo=_coords;
2615 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2616 return coo->getNumberOfTuples();
2620 * Returns the optional numbers of mesh entities of a given dimension transformed using
2621 * DataArrayInt::invertArrayN2O2O2N().
2622 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2623 * \return const DataArrayInt * - the array of the entity numbers transformed using
2624 * DataArrayInt::invertArrayN2O2O2N().
2625 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2627 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2629 if(meshDimRelToMaxExt==1)
2631 if(!((const DataArrayInt *)_num_coords))
2632 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2633 return _rev_num_coords;
2635 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2636 return l1->getRevNumberField();
2640 * Returns a pointer to the node coordinates array of \a this mesh \b without
2641 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2643 DataArrayDouble *MEDFileUMesh::getCoords() const
2645 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2646 if((DataArrayDouble *)tmp)
2654 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2655 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2657 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2658 * \param [in] grp - the name of the group whose mesh entities are included in the
2660 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2661 * according to the optional numbers of entities, if available.
2662 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2663 * delete this mesh using decrRef() as it is no more needed.
2664 * \throw If the name of a nonexistent group is specified.
2665 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2667 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
2669 synchronizeTinyInfoOnLeaves();
2670 std::vector<std::string> tmp(1);
2672 return getGroups(meshDimRelToMaxExt,tmp,renum);
2676 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2677 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2679 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2680 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2682 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2683 * according to the optional numbers of entities, if available.
2684 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2685 * delete this mesh using decrRef() as it is no more needed.
2686 * \throw If a name of a nonexistent group is present in \a grps.
2687 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2689 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
2691 synchronizeTinyInfoOnLeaves();
2692 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2693 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2694 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2695 zeRet->setName(grps[0].c_str());
2696 return zeRet.retn();
2700 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2701 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2703 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2704 * \param [in] fam - the name of the family whose mesh entities are included in the
2706 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2707 * according to the optional numbers of entities, if available.
2708 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2709 * delete this mesh using decrRef() as it is no more needed.
2710 * \throw If a name of a nonexistent family is present in \a grps.
2711 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2713 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
2715 synchronizeTinyInfoOnLeaves();
2716 std::vector<std::string> tmp(1);
2718 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2722 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2723 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2725 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2726 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2728 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2729 * according to the optional numbers of entities, if available.
2730 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2731 * delete this mesh using decrRef() as it is no more needed.
2732 * \throw If a name of a nonexistent family is present in \a fams.
2733 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2735 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2737 synchronizeTinyInfoOnLeaves();
2738 if(meshDimRelToMaxExt==1)
2740 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2741 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2742 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2746 std::vector<int> famIds=getFamiliesIds(fams);
2747 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2748 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2750 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2752 zeRet=l1->getFamilyPart(0,0,renum);
2753 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2754 zeRet->setName(fams[0].c_str());
2755 return zeRet.retn();
2759 * Returns ids of mesh entities contained in given families of a given dimension.
2760 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2762 * \param [in] fams - the names of the families of interest.
2763 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2764 * returned instead of ids.
2765 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2766 * numbers, if available and required, of mesh entities of the families. The caller
2767 * is to delete this array using decrRef() as it is no more needed.
2768 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2770 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2772 std::vector<int> famIds=getFamiliesIds(fams);
2773 if(meshDimRelToMaxExt==1)
2775 if((const DataArrayInt *)_fam_coords)
2777 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2779 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2781 da=_fam_coords->getIdsEqualList(0,0);
2783 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2788 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2790 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2792 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2794 return l1->getFamilyPartArr(0,0,renum);
2798 * Returns a MEDCouplingUMesh of a given relative dimension.
2799 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2800 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2801 * To build a valid MEDCouplingUMesh from the returned one in this case,
2802 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2803 * \param [in] meshDimRelToMax - the relative dimension of interest.
2804 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2805 * optional numbers of mesh entities.
2806 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2807 * delete using decrRef() as it is no more needed.
2808 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2809 * \sa getGenMeshAtLevel()
2811 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
2813 synchronizeTinyInfoOnLeaves();
2814 if(meshDimRelToMaxExt==1)
2818 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2819 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2820 umesh->setCoords(cc);
2821 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2822 umesh->setName(getName());
2826 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2827 return l1->getWholeMesh(renum);
2831 * Returns a MEDCouplingUMesh of a given relative dimension.
2832 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2833 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2834 * To build a valid MEDCouplingUMesh from the returned one in this case,
2835 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2836 * \param [in] meshDimRelToMax - the relative dimension of interest.
2837 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2838 * optional numbers of mesh entities.
2839 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2840 * delete using decrRef() as it is no more needed.
2841 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2842 * \sa getMeshAtLevel()
2844 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
2846 return getMeshAtLevel(meshDimRelToMax,renum);
2850 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2851 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2852 * optional numbers of mesh entities.
2853 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2854 * delete using decrRef() as it is no more needed.
2855 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2857 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2859 return getMeshAtLevel(0,renum);
2863 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2864 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2865 * optional numbers of mesh entities.
2866 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2867 * delete using decrRef() as it is no more needed.
2868 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2870 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2872 return getMeshAtLevel(-1,renum);
2876 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2877 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2878 * optional numbers of mesh entities.
2879 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2880 * delete using decrRef() as it is no more needed.
2881 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
2883 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2885 return getMeshAtLevel(-2,renum);
2889 * Returns a MEDCouplingUMesh of a relative dimension == -3.
2890 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2891 * optional numbers of mesh entities.
2892 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2893 * delete using decrRef() as it is no more needed.
2894 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
2896 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2898 return getMeshAtLevel(-3,renum);
2901 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2903 if(meshDimRelToMaxExt==1)
2904 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2905 if(meshDimRelToMaxExt>1)
2906 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2907 int tracucedRk=-meshDimRelToMaxExt;
2908 if(tracucedRk>=(int)_ms.size())
2909 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2910 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2911 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2912 return _ms[tracucedRk];
2915 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2917 if(meshDimRelToMaxExt==1)
2918 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2919 if(meshDimRelToMaxExt>1)
2920 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2921 int tracucedRk=-meshDimRelToMaxExt;
2922 if(tracucedRk>=(int)_ms.size())
2923 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2924 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2925 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2926 return _ms[tracucedRk];
2929 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2931 if(-meshDimRelToMax>=(int)_ms.size())
2932 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
2934 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2936 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
2938 int ref=(*it)->getMeshDimension();
2939 if(ref+i!=meshDim-meshDimRelToMax)
2940 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
2946 * Sets the node coordinates array of \a this mesh.
2947 * \param [in] coords - the new node coordinates array.
2948 * \throw If \a coords == \c NULL.
2951 void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
2954 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
2955 coords->checkAllocated();
2956 int nbOfTuples=coords->getNumberOfTuples();
2959 _fam_coords=DataArrayInt::New();
2960 _fam_coords->alloc(nbOfTuples,1);
2961 _fam_coords->fillWithZero();
2965 * Removes all groups of a given dimension in \a this mesh.
2966 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2967 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2969 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2971 if(meshDimRelToMaxExt==1)
2973 if((DataArrayInt *)_fam_coords)
2974 _fam_coords->fillWithZero();
2977 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2978 l1->eraseFamilyField();
2983 * Removes all families with ids not present in the family fields of \a this mesh.
2985 void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
2987 std::vector<int> levs=getNonEmptyLevelsExt();
2988 std::set<int> allFamsIds;
2989 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2991 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
2992 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
2994 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
2997 std::set<std::string> famNamesToKill;
2998 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3000 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3001 famNamesToKill.insert((*it).first);
3003 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3004 _families.erase(*it);
3005 std::vector<std::string> grpNamesToKill;
3006 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3008 std::vector<std::string> tmp;
3009 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3011 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3012 tmp.push_back(*it2);
3017 tmp.push_back((*it).first);
3019 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3023 void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception)
3025 std::vector<int> levs=getNonEmptyLevels();
3026 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3027 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3028 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3029 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3030 int nbNodes=m0->getNumberOfNodes();
3031 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3032 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3033 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3034 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3035 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3036 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3037 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3038 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3039 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3040 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3041 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3042 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3043 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3044 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3045 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3046 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3047 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3048 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3049 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3050 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3051 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3052 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3053 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3054 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3055 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3056 m0->setCoords(tmp0->getCoords());
3057 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3058 m1->setCoords(m0->getCoords());
3059 _coords=m0->getCoords(); _coords->incrRef();
3060 // duplication of cells in group 'grpNameM1' on level -1
3061 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3062 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3063 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3064 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3065 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3067 newm1->setName(getName());
3068 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3070 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3071 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3072 newFam->alloc(newm1->getNumberOfCells(),1);
3073 int idd=getMaxFamilyId()+1;
3074 int globStart=0,start=0,end,globEnd;
3075 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3076 for(int i=0;i<nbOfChunks;i++)
3078 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3079 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3081 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3082 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3083 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3088 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3092 newm1->setCoords(getCoords());
3093 setMeshAtLevel(-1,newm1);
3094 setFamilyFieldArr(-1,newFam);
3095 std::string grpName2(grpNameM1); grpName2+="_dup";
3096 addFamily(grpName2.c_str(),idd);
3097 addFamilyOnGrp(grpName2.c_str(),grpName2.c_str());
3102 int newNbOfNodes=getCoords()->getNumberOfTuples();
3103 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3104 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3105 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3108 nodesDuplicated=nodeIdsToDuplicate.retn();
3109 cellsModified=cellsToModifyConn0.retn();
3110 cellsNotModified=cellsToModifyConn1.retn();
3114 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3115 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3116 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3118 * \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.
3119 * 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.
3121 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
3123 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3124 std::vector<int> levs=getNonEmptyLevels();
3126 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3127 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3130 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3132 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3133 std::vector<int> code1=m->getDistributionOfTypes();
3134 end=PutInThirdComponentOfCodeOffset(code1,start);
3135 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3136 bool hasChanged=m->unPolyze();
3137 DataArrayInt *fake=0;
3138 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3139 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3141 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3144 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3145 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3147 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3148 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3149 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3150 setMeshAtLevel(*it,m);
3151 std::vector<int> code2=m->getDistributionOfTypes();
3152 end=PutInThirdComponentOfCodeOffset(code2,start);
3153 newCode.insert(newCode.end(),code2.begin(),code2.end());
3155 if(o2nCellsPart2->isIdentity())
3159 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3160 setFamilyFieldArr(*it,newFamField);
3164 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3165 setRenumFieldArr(*it,newNumField);
3170 newCode.insert(newCode.end(),code1.begin(),code1.end());
3176 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3177 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3178 o2nRenumCell=o2nRenumCellRet.retn();
3183 struct MEDLoaderAccVisit1
3185 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3186 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3187 int _new_nb_of_nodes;
3191 * 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.
3192 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3193 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3194 * -1 values in returned array means that the corresponding old node is no more used.
3196 * \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
3197 * is modified in \a this.
3198 * \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
3201 DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
3203 const DataArrayDouble *coo=getCoords();
3205 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3206 int nbOfNodes=coo->getNumberOfTuples();
3207 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3208 std::vector<int> neLevs=getNonEmptyLevels();
3209 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3211 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3212 m->computeNodeIdsAlg(nodeIdsInUse);
3214 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3215 if(nbrOfNodesInUse==nbOfNodes)
3217 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3218 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3219 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3220 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3221 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3222 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3223 if((const DataArrayInt *)_fam_coords)
3224 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3225 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3226 if((const DataArrayInt *)_num_coords)
3227 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3228 if((const DataArrayAsciiChar *)_name_coords)
3229 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3230 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3231 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3233 if((MEDFileUMeshSplitL1*)*it)
3234 (*it)->renumberNodesInConn(ret->begin());
3240 * Adds a group of nodes to \a this mesh.
3241 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3242 * The ids should be sorted and different each other (MED file norm).
3243 * \throw If the node coordinates array is not set.
3244 * \throw If \a ids == \c NULL.
3245 * \throw If \a ids->getName() == "".
3246 * \throw If \a ids does not respect the MED file norm.
3247 * \throw If a group with name \a ids->getName() already exists.
3249 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3251 const DataArrayDouble *coords=_coords;
3253 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3254 int nbOfNodes=coords->getNumberOfTuples();
3255 if(!((DataArrayInt *)_fam_coords))
3256 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3258 addGroupUnderground(true,ids,_fam_coords);
3262 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3263 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3264 * The ids should be sorted and different each other (MED file norm).
3265 * \throw If the node coordinates array is not set.
3266 * \throw If \a ids == \c NULL.
3267 * \throw If \a ids->getName() == "".
3268 * \throw If \a ids does not respect the MED file norm.
3269 * \throw If a group with name \a ids->getName() already exists.
3271 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3273 std::vector<int> levs=getNonEmptyLevelsExt();
3274 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3276 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3277 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3279 if(meshDimRelToMaxExt==1)
3280 { addNodeGroup(ids); return ; }
3281 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3282 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3283 addGroupUnderground(false,ids,fam);
3287 * \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).
3288 * \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)
3290 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3293 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3294 std::string grpName(ids->getName());
3296 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3297 ids->checkStrictlyMonotonic(true);
3298 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3299 std::vector<std::string> grpsNames=getGroupsNames();
3300 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3302 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3303 throw INTERP_KERNEL::Exception(oss.str().c_str());
3305 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3306 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3307 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3308 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3309 std::vector<int> familyIds;
3310 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3311 int maxVal=getTheMaxAbsFamilyId()+1;
3312 std::map<std::string,int> families(_families);
3313 std::map<std::string, std::vector<std::string> > groups(_groups);
3314 std::vector<std::string> fams;
3315 bool created(false);
3316 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3318 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3319 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3320 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3321 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3324 bool isFamPresent=false;
3325 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3326 isFamPresent=(*itl)->presenceOfValue(*famId);
3328 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3331 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3332 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3333 fams.push_back(locFamName);
3334 if(existsFamily(*famId))
3336 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3337 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3340 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3344 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3345 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3346 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3347 if(existsFamily(*famId))
3349 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3350 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3355 for(std::size_t i=0;i<familyIds.size();i++)
3357 DataArrayInt *da=idsPerfamiliyIds[i];
3358 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3362 _groups[grpName]=fams;
3366 * Changes a name of a family specified by its id.
3367 * \param [in] id - the id of the family of interest.
3368 * \param [in] newFamName - the new family name.
3369 * \throw If no family with the given \a id exists.
3371 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
3373 std::string oldName=getFamilyNameGivenId(id);
3374 _families.erase(oldName);
3375 _families[newFamName]=id;
3379 * Removes a mesh of a given dimension.
3380 * \param [in] meshDimRelToMax - the relative dimension of interest.
3381 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3383 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
3385 std::vector<int> levSet=getNonEmptyLevels();
3386 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3387 if(it==levSet.end())
3388 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3389 int pos=(-meshDimRelToMax);
3394 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3395 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3396 * \param [in] m - the new mesh to set.
3397 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3398 * writing \a this mesh in a MED file.
3399 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3401 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3402 * another node coordinates array.
3403 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3404 * to the existing meshes of other levels of \a this mesh.
3406 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
3408 dealWithTinyInfo(m);
3409 std::vector<int> levSet=getNonEmptyLevels();
3410 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3412 if((DataArrayDouble *)_coords==0)
3414 DataArrayDouble *c=m->getCoords();
3419 if(m->getCoords()!=_coords)
3420 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3421 int sz=(-meshDimRelToMax)+1;
3422 if(sz>=(int)_ms.size())
3424 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3425 _ms[sz-1]=new MEDFileUMeshSplitL1(m,newOrOld);
3428 _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld);
3432 * This method allows to set at once the content of different levels in \a this.
3433 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3435 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3436 * \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.
3437 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3439 * \throw If \a there is a null pointer in \a ms.
3440 * \sa MEDFileUMesh::setMeshAtLevel
3442 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3446 const MEDCouplingUMesh *mRef=ms[0];
3448 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3449 std::string name(mRef->getName());
3450 const DataArrayDouble *coo(mRef->getCoords());
3453 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3455 const MEDCouplingUMesh *cur(*it);
3457 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3458 if(coo!=cur->getCoords())
3459 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3460 int mdim=cur->getMeshDimension();
3461 zeDim=std::max(zeDim,mdim);
3462 if(s.find(mdim)!=s.end())
3463 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3465 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3467 int mdim=(*it)->getMeshDimension();
3468 setName((*it)->getName());
3469 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3471 setName(name.c_str());
3475 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3476 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3477 * The given meshes must share the same node coordinates array.
3478 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3479 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3480 * create in \a this mesh.
3481 * \throw If \a ms is empty.
3482 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3483 * to the existing meshes of other levels of \a this mesh.
3484 * \throw If the meshes in \a ms do not share the same node coordinates array.
3485 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3486 * of the given meshes.
3487 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3488 * \throw If names of some meshes in \a ms are equal.
3489 * \throw If \a ms includes a mesh with an empty name.
3491 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3494 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3495 int sz=(-meshDimRelToMax)+1;
3496 if(sz>=(int)_ms.size())
3498 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3499 DataArrayDouble *coo=checkMultiMesh(ms);
3500 if((DataArrayDouble *)_coords==0)
3506 if((DataArrayDouble *)_coords!=coo)
3507 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3508 std::vector<DataArrayInt *> corr;
3509 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3510 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3511 setMeshAtLevel(meshDimRelToMax,m,renum);
3512 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3513 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3517 * Creates groups at a given level in \a this mesh from a sequence of
3518 * meshes each representing a group.
3519 * The given meshes must share the same node coordinates array.
3520 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3521 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3522 * create in \a this mesh.
3523 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3525 * \throw If \a ms is empty.
3526 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3527 * to the existing meshes of other levels of \a this mesh.
3528 * \throw If the meshes in \a ms do not share the same node coordinates array.
3529 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3530 * of the given meshes.
3531 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3532 * \throw If names of some meshes in \a ms are equal.
3533 * \throw If \a ms includes a mesh with an empty name.
3535 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3538 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3539 int sz=(-meshDimRelToMax)+1;
3540 if(sz>=(int)_ms.size())
3542 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3543 DataArrayDouble *coo=checkMultiMesh(ms);
3544 if((DataArrayDouble *)_coords==0)
3550 if((DataArrayDouble *)_coords!=coo)
3551 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3552 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3553 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3555 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3557 DataArrayInt *arr=0;
3558 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3562 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3563 throw INTERP_KERNEL::Exception(oss.str().c_str());
3566 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3567 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3570 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const throw(INTERP_KERNEL::Exception)
3572 const DataArrayDouble *ret=ms[0]->getCoords();
3573 int mdim=ms[0]->getMeshDimension();
3574 for(unsigned int i=1;i<ms.size();i++)
3576 ms[i]->checkCoherency();
3577 if(ms[i]->getCoords()!=ret)
3578 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3579 if(ms[i]->getMeshDimension()!=mdim)
3580 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3582 return const_cast<DataArrayDouble *>(ret);
3586 * Sets the family field of a given relative dimension.
3587 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3588 * the family field is set.
3589 * \param [in] famArr - the array of the family field.
3590 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3591 * \throw If \a famArr has an invalid size.
3593 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3595 if(meshDimRelToMaxExt==1)
3602 DataArrayDouble *coo(_coords);
3604 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3605 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3610 if(meshDimRelToMaxExt>1)
3611 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3612 int traducedRk=-meshDimRelToMaxExt;
3613 if(traducedRk>=(int)_ms.size())
3614 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3615 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3616 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3617 return _ms[traducedRk]->setFamilyArr(famArr);
3621 * Sets the optional numbers of mesh entities of a given dimension.
3622 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3623 * \param [in] renumArr - the array of the numbers.
3624 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3625 * \throw If \a renumArr has an invalid size.
3627 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
3629 if(meshDimRelToMaxExt==1)
3637 DataArrayDouble *coo(_coords);
3639 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3640 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3641 renumArr->incrRef();
3642 _num_coords=renumArr;
3646 if(meshDimRelToMaxExt>1)
3647 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3648 int traducedRk=-meshDimRelToMaxExt;
3649 if(traducedRk>=(int)_ms.size())
3650 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3651 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3652 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3653 return _ms[traducedRk]->setRenumArr(renumArr);
3657 * Sets the optional names of mesh entities of a given dimension.
3658 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3659 * \param [in] nameArr - the array of the names.
3660 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3661 * \throw If \a nameArr has an invalid size.
3663 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
3665 if(meshDimRelToMaxExt==1)
3672 DataArrayDouble *coo(_coords);
3674 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3675 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3677 _name_coords=nameArr;
3680 if(meshDimRelToMaxExt>1)
3681 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3682 int traducedRk=-meshDimRelToMaxExt;
3683 if(traducedRk>=(int)_ms.size())
3684 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3685 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3686 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3687 return _ms[traducedRk]->setNameArr(nameArr);
3690 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3692 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3693 if((const MEDFileUMeshSplitL1 *)(*it))
3694 (*it)->synchronizeTinyInfo(*this);
3698 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3700 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
3702 DataArrayInt *arr=_fam_coords;
3704 arr->changeValue(oldId,newId);
3705 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3707 MEDFileUMeshSplitL1 *sp=(*it);
3710 sp->changeFamilyIdArr(oldId,newId);
3715 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3717 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3718 const DataArrayInt *da(_fam_coords);
3720 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3721 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3723 const MEDFileUMeshSplitL1 *elt(*it);
3726 da=elt->getFamilyField();
3728 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3734 void MEDFileUMesh::computeRevNum() const
3736 if((const DataArrayInt *)_num_coords)
3739 int maxValue=_num_coords->getMaxValue(pos);
3740 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3744 std::size_t MEDFileStructuredMesh::getHeapMemorySize() const
3746 std::size_t ret=MEDFileMesh::getHeapMemorySize();
3747 if((const DataArrayInt*)_fam_nodes)
3748 ret+=_fam_nodes->getHeapMemorySize();
3749 if((const DataArrayInt*)_num_nodes)
3750 ret+=_num_nodes->getHeapMemorySize();
3751 if((const DataArrayInt*)_fam_cells)
3752 ret+=_fam_cells->getHeapMemorySize();
3753 if((const DataArrayInt*)_num_cells)
3754 ret+=_num_cells->getHeapMemorySize();
3755 if((const DataArrayInt*)_rev_num_nodes)
3756 ret+=_rev_num_nodes->getHeapMemorySize();
3757 if((const DataArrayInt*)_rev_num_cells)
3758 ret+=_rev_num_cells->getHeapMemorySize();
3762 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3764 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3765 if((const DataArrayInt *)_fam_nodes)
3767 int val=_fam_nodes->getMaxValue(tmp);
3768 ret=std::max(ret,std::abs(val));
3770 if((const DataArrayInt *)_fam_cells)
3772 int val=_fam_cells->getMaxValue(tmp);
3773 ret=std::max(ret,std::abs(val));
3778 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3780 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3781 if((const DataArrayInt *)_fam_nodes)
3783 int val=_fam_nodes->getMaxValue(tmp);
3784 ret=std::max(ret,val);
3786 if((const DataArrayInt *)_fam_cells)
3788 int val=_fam_cells->getMaxValue(tmp);
3789 ret=std::max(ret,val);
3794 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3796 int ret=std::numeric_limits<int>::max(),tmp=-1;
3797 if((const DataArrayInt *)_fam_nodes)
3799 int val=_fam_nodes->getMinValue(tmp);
3800 ret=std::min(ret,val);
3802 if((const DataArrayInt *)_fam_cells)
3804 int val=_fam_cells->getMinValue(tmp);
3805 ret=std::min(ret,val);
3810 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3812 if(!MEDFileMesh::isEqual(other,eps,what))
3814 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
3817 what="Mesh types differ ! This is structured and other is NOT !";
3820 const DataArrayInt *famc1=_fam_nodes;
3821 const DataArrayInt *famc2=otherC->_fam_nodes;
3822 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3824 what="Mismatch of families arr on nodes ! One is defined and not other !";
3829 bool ret=famc1->isEqual(*famc2);
3832 what="Families arr on nodes differ !";
3837 famc2=otherC->_fam_cells;
3838 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3840 what="Mismatch of families arr on cells ! One is defined and not other !";
3845 bool ret=famc1->isEqual(*famc2);
3848 what="Families arr on cells differ !";
3853 famc2=otherC->_num_nodes;
3854 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3856 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
3861 bool ret=famc1->isEqual(*famc2);
3864 what="Numbering arr on nodes differ !";
3869 famc2=otherC->_num_cells;
3870 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3872 what="Mismatch of numbering arr on cells ! One is defined and not other !";
3877 bool ret=famc1->isEqual(*famc2);
3880 what="Numbering arr on cells differ !";
3884 const DataArrayAsciiChar *d1=_names_cells;
3885 const DataArrayAsciiChar *d2=otherC->_names_cells;
3886 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3888 what="Mismatch of naming arr on cells ! One is defined and not other !";
3893 bool ret=d1->isEqual(*d2);
3896 what="Naming arr on cells differ !";
3901 d2=otherC->_names_nodes;
3902 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3904 what="Mismatch of naming arr on nodes ! One is defined and not other !";
3909 bool ret=d1->isEqual(*d2);
3912 what="Naming arr on nodes differ !";
3919 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
3921 MEDFileMesh::clearNonDiscrAttributes();
3922 const DataArrayInt *tmp=_fam_nodes;
3924 (const_cast<DataArrayInt *>(tmp))->setName("");
3927 (const_cast<DataArrayInt *>(tmp))->setName("");
3930 (const_cast<DataArrayInt *>(tmp))->setName("");
3933 (const_cast<DataArrayInt *>(tmp))->setName("");
3937 * Returns ids of mesh entities contained in given families of a given dimension.
3938 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3940 * \param [in] fams - the names of the families of interest.
3941 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3942 * returned instead of ids.
3943 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3944 * numbers, if available and required, of mesh entities of the families. The caller
3945 * is to delete this array using decrRef() as it is no more needed.
3946 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3948 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
3950 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3951 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
3952 std::vector<int> famIds=getFamiliesIds(fams);
3953 if(meshDimRelToMaxExt==1)
3955 if((const DataArrayInt *)_fam_nodes)
3957 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3959 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3961 da=_fam_nodes->getIdsEqualList(0,0);
3963 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
3968 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
3972 if((const DataArrayInt *)_fam_cells)
3974 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3976 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3978 da=_fam_cells->getIdsEqualList(0,0);
3980 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
3985 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
3990 * Sets the family field of a given relative dimension.
3991 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3992 * the family field is set.
3993 * \param [in] famArr - the array of the family field.
3994 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3995 * \throw If \a famArr has an invalid size.
3996 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
3998 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
4000 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4001 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4002 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4004 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4005 if(meshDimRelToMaxExt==0)
4007 int nbCells=mesh->getNumberOfCells();
4008 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4013 int nbNodes=mesh->getNumberOfNodes();
4014 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4022 * Sets the optional numbers of mesh entities of a given dimension.
4023 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4024 * \param [in] renumArr - the array of the numbers.
4025 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4026 * \throw If \a renumArr has an invalid size.
4027 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4029 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
4031 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4032 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4033 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4035 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4036 if(meshDimRelToMaxExt==0)
4038 int nbCells=mesh->getNumberOfCells();
4039 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4040 _num_cells=renumArr;
4044 int nbNodes=mesh->getNumberOfNodes();
4045 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4046 _num_nodes=renumArr;
4049 renumArr->incrRef();
4053 * Sets the optional names of mesh entities of a given dimension.
4054 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4055 * \param [in] nameArr - the array of the names.
4056 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4057 * \throw If \a nameArr has an invalid size.
4059 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
4061 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4062 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
4063 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4065 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4066 if(meshDimRelToMaxExt==0)
4068 int nbCells=mesh->getNumberOfCells();
4069 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4070 _names_cells=nameArr;
4074 int nbNodes=mesh->getNumberOfNodes();
4075 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4076 _names_nodes=nameArr;
4083 * Returns the family field for mesh entities of a given dimension.
4084 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4085 * \return const DataArrayInt * - the family field. It is an array of ids of families
4086 * each mesh entity belongs to. It can be \c NULL.
4087 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4089 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4091 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4092 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
4093 if(meshDimRelToMaxExt==0)
4100 * Returns the optional numbers of mesh entities of a given dimension.
4101 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4102 * \return const DataArrayInt * - the array of the entity numbers.
4103 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4104 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4106 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4108 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4109 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
4110 if(meshDimRelToMaxExt==0)
4117 * Returns the optional numbers of mesh entities of a given dimension transformed using
4118 * DataArrayInt::invertArrayN2O2O2N().
4119 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4120 * \return const DataArrayInt * - the array of the entity numbers transformed using
4121 * DataArrayInt::invertArrayN2O2O2N().
4122 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4123 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4125 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4127 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4128 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4129 if(meshDimRelToMaxExt==0)
4131 if((const DataArrayInt *)_num_cells)
4134 int maxValue=_num_cells->getMaxValue(pos);
4135 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4136 return _rev_num_cells;
4139 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4143 if((const DataArrayInt *)_num_nodes)
4146 int maxValue=_num_nodes->getMaxValue(pos);
4147 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4148 return _rev_num_nodes;
4151 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4155 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4157 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4158 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
4159 if(meshDimRelToMaxExt==0)
4160 return _names_cells;
4162 return _names_nodes;
4166 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4167 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4169 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4171 std::vector<int> ret(1);
4176 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4177 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4179 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4181 std::vector<int> ret(2);
4187 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4189 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4191 std::vector<int> ret;
4192 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells);
4201 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4203 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4205 std::vector<int> ret;
4206 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells);
4215 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4217 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4219 std::vector<int> ret;
4220 const DataArrayAsciiChar *namesCells(_names_cells);
4227 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4229 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
4231 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4235 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
4237 DataArrayInt *arr=_fam_nodes;
4239 arr->changeValue(oldId,newId);
4242 arr->changeValue(oldId,newId);
4245 void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
4247 if((const DataArrayInt*)_fam_nodes)
4248 _fam_nodes=_fam_nodes->deepCpy();
4249 if((const DataArrayInt*)_num_nodes)
4250 _num_nodes=_num_nodes->deepCpy();
4251 if((const DataArrayInt*)_fam_cells)
4252 _fam_cells=_fam_cells->deepCpy();
4253 if((const DataArrayInt*)_num_cells)
4254 _num_cells=_num_cells->deepCpy();
4255 if((const DataArrayInt*)_rev_num_nodes)
4256 _rev_num_nodes=_rev_num_nodes->deepCpy();
4257 if((const DataArrayInt*)_rev_num_cells)
4258 _rev_num_cells=_rev_num_cells->deepCpy();
4262 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4264 * \return a pointer to cartesian mesh that need to be managed by the caller.
4265 * \warning the returned pointer has to be managed by the caller.
4269 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4270 * \param [in] meshDimRelToMax - it must be \c 0.
4271 * \param [in] renum - it must be \c false.
4272 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4273 * delete using decrRef() as it is no more needed.
4275 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
4278 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4279 if(meshDimRelToMax!=0)
4280 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4281 const MEDCouplingStructuredMesh *m=getStructuredMesh();
4284 return const_cast<MEDCouplingStructuredMesh *>(m);
4288 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4289 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4290 * \return int - the number of entities.
4291 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4293 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4295 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4296 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
4297 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4299 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4300 if(meshDimRelToMaxExt==0)
4301 return cmesh->getNumberOfCells();
4303 return cmesh->getNumberOfNodes();
4306 int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
4308 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4310 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4311 return cmesh->getNumberOfNodes();
4314 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
4316 med_geometry_type geoTypeReq=MED_NONE;
4320 geoTypeReq=MED_HEXA8;
4323 geoTypeReq=MED_QUAD4;
4326 geoTypeReq=MED_SEG2;
4329 geoTypeReq=MED_POINT1;
4332 throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
4337 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4339 setName(strm->getName());
4340 setDescription(strm->getDescription());
4341 setUnivName(strm->getUnivName());
4342 setIteration(strm->getIteration());
4343 setOrder(strm->getOrder());
4344 setTimeValue(strm->getTime());
4345 setTimeUnit(strm->getTimeUnit());
4346 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4347 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4348 int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4351 if(!mrs || mrs->isNodeFamilyFieldReading())
4353 _fam_nodes=DataArrayInt::New();
4354 _fam_nodes->alloc(nbOfElt,1);
4355 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4358 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4361 if(!mrs || mrs->isNodeNumFieldReading())
4363 _num_nodes=DataArrayInt::New();
4364 _num_nodes->alloc(nbOfElt,1);
4365 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4368 int meshDim=getStructuredMesh()->getMeshDimension();
4369 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4370 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4373 if(!mrs || mrs->isCellFamilyFieldReading())
4375 _fam_cells=DataArrayInt::New();
4376 _fam_cells->alloc(nbOfElt,1);
4377 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
4380 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4383 if(!mrs || mrs->isCellNumFieldReading())
4385 _num_cells=DataArrayInt::New();
4386 _num_cells->alloc(nbOfElt,1);
4387 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
4390 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4393 if(!mrs || mrs->isCellNameFieldReading())
4395 _names_cells=DataArrayAsciiChar::New();
4396 _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4397 MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
4398 _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4401 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4404 if(!mrs || mrs->isNodeNameFieldReading())
4406 _names_nodes=DataArrayAsciiChar::New();
4407 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4408 MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4409 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4414 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
4416 int meshDim=getStructuredMesh()->getMeshDimension();
4417 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4419 if((const DataArrayInt *)_fam_cells)
4420 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4421 if((const DataArrayInt *)_fam_nodes)
4422 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4423 if((const DataArrayInt *)_num_cells)
4424 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4425 if((const DataArrayInt *)_num_nodes)
4426 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4427 if((const DataArrayAsciiChar *)_names_cells)
4429 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4431 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4432 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4433 throw INTERP_KERNEL::Exception(oss.str().c_str());
4435 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4437 if((const DataArrayAsciiChar *)_names_nodes)
4439 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4441 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4442 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4443 throw INTERP_KERNEL::Exception(oss.str().c_str());
4445 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4448 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
4452 * Returns an empty instance of MEDFileCMesh.
4453 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4454 * mesh using decrRef() as it is no more needed.
4456 MEDFileCMesh *MEDFileCMesh::New()
4458 return new MEDFileCMesh;
4462 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4463 * file. The first mesh in the file is loaded.
4464 * \param [in] fileName - the name of MED file to read.
4465 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4466 * mesh using decrRef() as it is no more needed.
4467 * \throw If the file is not readable.
4468 * \throw If there is no meshes in the file.
4469 * \throw If the mesh in the file is not a Cartesian one.
4471 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4473 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4476 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4477 throw INTERP_KERNEL::Exception(oss.str().c_str());
4479 MEDFileUtilities::CheckFileForRead(fileName);
4480 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4482 ParaMEDMEM::MEDCouplingMeshType meshType;
4484 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4485 return new MEDFileCMesh(fid,ms.front().c_str(),dt,it,mrs);
4489 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4490 * file. The mesh to load is specified by its name and numbers of a time step and an
4492 * \param [in] fileName - the name of MED file to read.
4493 * \param [in] mName - the name of the mesh to read.
4494 * \param [in] dt - the number of a time step.
4495 * \param [in] it - the number of an iteration.
4496 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4497 * mesh using decrRef() as it is no more needed.
4498 * \throw If the file is not readable.
4499 * \throw If there is no mesh with given attributes in the file.
4500 * \throw If the mesh in the file is not a Cartesian one.
4502 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4504 MEDFileUtilities::CheckFileForRead(fileName);
4505 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4506 return new MEDFileCMesh(fid,mName,dt,it,mrs);
4509 std::size_t MEDFileCMesh::getHeapMemorySize() const
4511 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4512 if((const MEDCouplingCMesh *)_cmesh)
4513 ret+=_cmesh->getHeapMemorySize();
4518 * Returns the dimension on cells in \a this mesh.
4519 * \return int - the mesh dimension.
4520 * \throw If there are no cells in this mesh.
4522 int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4524 if(!((const MEDCouplingCMesh*)_cmesh))
4525 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4526 return _cmesh->getMeshDimension();
4530 * Returns a string describing \a this mesh.
4531 * \return std::string - the mesh information string.
4533 std::string MEDFileCMesh::simpleRepr() const
4535 return MEDFileStructuredMesh::simpleRepr();
4539 * Returns a full textual description of \a this mesh.
4540 * \return std::string - the string holding the mesh description.
4542 std::string MEDFileCMesh::advancedRepr() const
4544 return simpleRepr();
4547 MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4549 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4553 MEDFileMesh *MEDFileCMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4555 return new MEDFileCMesh;
4558 MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4560 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4561 if((const MEDCouplingCMesh*)_cmesh)
4562 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
4563 ret->deepCpyAttributes();
4568 * Checks if \a this and another mesh are equal.
4569 * \param [in] other - the mesh to compare with.
4570 * \param [in] eps - a precision used to compare real values.
4571 * \param [in,out] what - the string returning description of unequal data.
4572 * \return bool - \c true if the meshes are equal, \c false, else.
4574 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4576 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4578 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
4581 what="Mesh types differ ! This is cartesian and other is NOT !";
4584 clearNonDiscrAttributes();
4585 otherC->clearNonDiscrAttributes();
4586 const MEDCouplingCMesh *coo1=_cmesh;
4587 const MEDCouplingCMesh *coo2=otherC->_cmesh;
4588 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4590 what="Mismatch of cartesian meshes ! One is defined and not other !";
4595 bool ret=coo1->isEqual(coo2,eps);
4598 what="cartesian meshes differ !";
4606 * Clears redundant attributes of incorporated data arrays.
4608 void MEDFileCMesh::clearNonDiscrAttributes() const
4610 MEDFileStructuredMesh::clearNonDiscrAttributes();
4611 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
4614 MEDFileCMesh::MEDFileCMesh()
4618 MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4621 loadCMeshFromFile(fid,mName,dt,it,mrs);
4623 catch(INTERP_KERNEL::Exception& e)
4628 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4630 ParaMEDMEM::MEDCouplingMeshType meshType;
4633 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4634 if(meshType!=CARTESIAN)
4636 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
4637 throw INTERP_KERNEL::Exception(oss.str().c_str());
4639 MEDFileCMeshL2 loaderl2;
4640 loaderl2.loadAll(fid,mid,mName,dt,it);
4641 MEDCouplingCMesh *mesh=loaderl2.getMesh();
4644 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
4648 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
4649 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
4651 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
4653 synchronizeTinyInfoOnLeaves();
4657 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
4659 synchronizeTinyInfoOnLeaves();
4664 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
4665 * \param [in] m - the new MEDCouplingCMesh to refer to.
4666 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4669 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
4671 dealWithTinyInfo(m);
4677 void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4679 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4680 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4681 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4682 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4683 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4684 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4685 int spaceDim=_cmesh->getSpaceDimension();
4686 int meshDim=_cmesh->getMeshDimension();
4687 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4688 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4689 for(int i=0;i<spaceDim;i++)
4691 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
4693 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4694 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
4695 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
4697 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4698 MEDmeshUniversalNameWr(fid,maa);
4699 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
4700 for(int i=0;i<spaceDim;i++)
4702 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
4703 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
4706 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4709 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
4711 const MEDCouplingCMesh *cmesh=_cmesh;
4714 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
4715 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
4716 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
4717 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
4720 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
4722 return new MEDFileCurveLinearMesh;
4725 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4727 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4730 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4731 throw INTERP_KERNEL::Exception(oss.str().c_str());
4733 MEDFileUtilities::CheckFileForRead(fileName);
4734 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4736 ParaMEDMEM::MEDCouplingMeshType meshType;
4738 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4739 return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it,mrs);
4742 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4744 MEDFileUtilities::CheckFileForRead(fileName);
4745 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4746 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
4749 std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const
4751 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4752 if((const MEDCouplingCurveLinearMesh *)_clmesh)
4753 ret+=_clmesh->getHeapMemorySize();
4757 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4759 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4763 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4765 return new MEDFileCurveLinearMesh;
4768 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4770 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4771 if((const MEDCouplingCurveLinearMesh*)_clmesh)
4772 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
4773 ret->deepCpyAttributes();
4777 int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4779 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
4780 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4781 return _clmesh->getMeshDimension();
4784 std::string MEDFileCurveLinearMesh::simpleRepr() const
4786 return MEDFileStructuredMesh::simpleRepr();
4789 std::string MEDFileCurveLinearMesh::advancedRepr() const
4791 return simpleRepr();
4794 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4796 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4798 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
4801 what="Mesh types differ ! This is curve linear and other is NOT !";
4804 clearNonDiscrAttributes();
4805 otherC->clearNonDiscrAttributes();
4806 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
4807 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
4808 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4810 what="Mismatch of curve linear meshes ! One is defined and not other !";
4815 bool ret=coo1->isEqual(coo2,eps);
4818 what="curve linear meshes differ !";
4825 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
4827 MEDFileStructuredMesh::clearNonDiscrAttributes();
4828 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
4831 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
4833 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
4836 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
4837 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
4838 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
4839 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
4842 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
4844 synchronizeTinyInfoOnLeaves();
4848 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
4850 dealWithTinyInfo(m);
4856 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
4858 synchronizeTinyInfoOnLeaves();
4862 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
4866 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4869 loadCLMeshFromFile(fid,mName,dt,it,mrs);
4871 catch(INTERP_KERNEL::Exception& e)
4876 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4878 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4879 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4880 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4881 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4882 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4883 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4884 int spaceDim=_clmesh->getSpaceDimension();
4885 int meshDim=_clmesh->getMeshDimension();
4886 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4887 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4888 const DataArrayDouble *coords=_clmesh->getCoords();
4890 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
4891 for(int i=0;i<spaceDim;i++)
4893 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
4895 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4896 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
4897 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
4899 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4900 MEDmeshUniversalNameWr(fid,maa);
4901 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
4902 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
4903 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
4905 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
4907 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4910 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4912 ParaMEDMEM::MEDCouplingMeshType meshType;
4915 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4916 if(meshType!=CURVE_LINEAR)
4918 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
4919 throw INTERP_KERNEL::Exception(oss.str().c_str());
4921 MEDFileCLMeshL2 loaderl2;
4922 loaderl2.loadAll(fid,mid,mName,dt,it);
4923 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
4926 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
4929 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
4931 return new MEDFileMeshMultiTS;
4934 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
4936 return new MEDFileMeshMultiTS(fileName);
4939 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
4941 return new MEDFileMeshMultiTS(fileName,mName);
4944 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
4946 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
4947 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
4949 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
4950 if((const MEDFileMesh *)*it)
4951 meshOneTs[i]=(*it)->deepCpy();
4952 ret->_mesh_one_ts=meshOneTs;
4956 std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const
4958 std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
4959 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
4960 ret+=(*it)->getHeapMemorySize();
4964 const char *MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
4966 if(_mesh_one_ts.empty())
4967 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
4968 return _mesh_one_ts[0]->getName();
4971 void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::Exception)
4973 std::string oldName(getName());
4974 std::vector< std::pair<std::string,std::string> > v(1);
4975 v[0].first=oldName; v[0].second=newMeshName;
4979 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
4982 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
4984 MEDFileMesh *cur(*it);
4986 ret=cur->changeNames(modifTab) || ret;
4991 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception)
4993 if(_mesh_one_ts.empty())
4994 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
4995 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
4998 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception)
5001 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5002 _mesh_one_ts.resize(1);
5003 mesh1TimeStep->incrRef();
5004 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5005 _mesh_one_ts[0]=mesh1TimeStep;
5008 void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5010 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5012 (*it)->copyOptionsFrom(*this);
5017 void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5019 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5020 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5021 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5022 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5026 void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5027 {//for the moment to be improved
5028 _mesh_one_ts.resize(1);
5029 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5032 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5036 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception)
5039 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5042 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5043 throw INTERP_KERNEL::Exception(oss.str().c_str());
5045 MEDFileUtilities::CheckFileForRead(fileName);
5046 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
5048 ParaMEDMEM::MEDCouplingMeshType meshType;
5050 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
5051 loadFromFile(fileName,ms.front().c_str());
5053 catch(INTERP_KERNEL::Exception& e)
5058 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5061 loadFromFile(fileName,mName);
5063 catch(INTERP_KERNEL::Exception& e)
5068 MEDFileMeshes *MEDFileMeshes::New()
5070 return new MEDFileMeshes;
5073 MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception)
5075 return new MEDFileMeshes(fileName);
5078 void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5081 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5083 (*it)->copyOptionsFrom(*this);
5088 void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5090 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5091 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5092 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5093 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5098 int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception)
5100 return _meshes.size();
5103 MEDFileMeshesIterator *MEDFileMeshes::iterator() throw(INTERP_KERNEL::Exception)
5105 return new MEDFileMeshesIterator(this);
5108 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception)
5110 if(i<0 || i>=(int)_meshes.size())
5112 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5113 throw INTERP_KERNEL::Exception(oss.str().c_str());
5115 return _meshes[i]->getOneTimeStep();
5118 MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTERP_KERNEL::Exception)
5120 std::vector<std::string> ms=getMeshesNames();
5121 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5124 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5125 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5126 throw INTERP_KERNEL::Exception(oss.str().c_str());
5128 return getMeshAtPos((int)std::distance(ms.begin(),it));
5131 std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERNEL::Exception)
5133 std::vector<std::string> ret(_meshes.size());
5135 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5137 const MEDFileMeshMultiTS *f=(*it);
5140 ret[i]=f->getName();
5144 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5145 throw INTERP_KERNEL::Exception(oss.str().c_str());
5151 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
5154 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5156 MEDFileMeshMultiTS *cur(*it);
5158 ret=cur->changeNames(modifTab) || ret;
5163 void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception)
5165 _meshes.resize(newSize);
5168 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5171 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5172 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5173 elt->setOneTimeStep(mesh);
5174 _meshes.push_back(elt);
5177 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5180 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5181 if(i>=(int)_meshes.size())
5182 _meshes.resize(i+1);
5183 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5184 elt->setOneTimeStep(mesh);
5188 void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
5190 if(i<0 || i>=(int)_meshes.size())
5192 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5193 throw INTERP_KERNEL::Exception(oss.str().c_str());
5195 _meshes.erase(_meshes.begin()+i);
5198 void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception)
5200 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5202 _meshes.resize(ms.size());
5203 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5204 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str());
5207 MEDFileMeshes::MEDFileMeshes()
5211 MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception)
5214 loadFromFile(fileName);
5216 catch(INTERP_KERNEL::Exception& e)
5220 MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
5222 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5224 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5225 if((const MEDFileMeshMultiTS *)*it)
5226 meshes[i]=(*it)->deepCpy();
5227 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5228 ret->_meshes=meshes;
5232 std::size_t MEDFileMeshes::getHeapMemorySize() const
5234 std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5235 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5236 if((const MEDFileMeshMultiTS*)*it)
5237 ret+=(*it)->getHeapMemorySize();
5241 std::string MEDFileMeshes::simpleRepr() const
5243 std::ostringstream oss;
5244 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5245 simpleReprWithoutHeader(oss);
5249 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5251 int nbOfMeshes=getNumberOfMeshes();
5252 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5253 std::vector<std::string> mns=getMeshesNames();
5254 for(int i=0;i<nbOfMeshes;i++)
5255 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5258 void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception)
5260 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5262 std::set<std::string> s;
5263 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5265 const MEDFileMeshMultiTS *elt=(*it);
5268 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5269 throw INTERP_KERNEL::Exception(oss.str().c_str());
5271 std::size_t sz=s.size();
5272 s.insert(std::string((*it)->getName()));
5275 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5276 throw INTERP_KERNEL::Exception(oss.str().c_str());
5281 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5286 _nb_iter=ms->getNumberOfMeshes();
5290 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5294 MEDFileMesh *MEDFileMeshesIterator::nextt()
5296 if(_iter_id<_nb_iter)
5298 MEDFileMeshes *ms(_ms);
5300 return ms->getMeshAtPos(_iter_id++);