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) 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);
85 return (MEDFileUMesh *)ret.retn();
89 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
90 ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it);
91 return (MEDFileCMesh *)ret.retn();
95 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
96 ret->loadCLMeshFromFile(fid,ms.front().c_str(),dt,it);
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) 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);
135 return (MEDFileUMesh *)ret.retn();
139 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
140 ret->loadCMeshFromFile(fid,mName,dt,it);
141 return (MEDFileCMesh *)ret.retn();
145 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
146 ret->loadCLMeshFromFile(fid,mName,dt,it);
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 a group from \a this mesh.
490 * \param [in] name - the name of the group to remove.
491 * \throw If no group with such a \a name exists.
493 void MEDFileMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception)
495 std::string oname(name);
496 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
497 std::vector<std::string> grps=getGroupsNames();
498 if(it==_groups.end())
500 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
501 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
502 throw INTERP_KERNEL::Exception(oss.str().c_str());
508 * Removes a family from \a this mesh.
509 * \param [in] name - the name of the family to remove.
510 * \throw If no family with such a \a name exists.
512 void MEDFileMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception)
514 std::string oname(name);
515 std::map<std::string, int >::iterator it=_families.find(oname);
516 std::vector<std::string> fams=getFamiliesNames();
517 if(it==_families.end())
519 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
520 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
521 throw INTERP_KERNEL::Exception(oss.str().c_str());
524 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
526 std::vector<std::string>& v=(*it3).second;
527 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
534 * Renames a group in \a this mesh.
535 * \param [in] oldName - a current name of the group to rename.
536 * \param [in] newName - a new group name.
537 * \throw If no group named \a oldName exists in \a this mesh.
538 * \throw If a group named \a newName already exists.
540 void MEDFileMesh::changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
542 std::string oname(oldName);
543 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
544 std::vector<std::string> grps=getGroupsNames();
545 if(it==_groups.end())
547 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
548 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
549 throw INTERP_KERNEL::Exception(oss.str().c_str());
551 std::string nname(newName);
552 it=_groups.find(nname);
553 if(it!=_groups.end())
555 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
556 throw INTERP_KERNEL::Exception(oss.str().c_str());
558 std::vector<std::string> cpy=(*it).second;
560 _groups[newName]=cpy;
564 * Changes an id of a family in \a this mesh.
565 * This method calls changeFamilyIdArr().
566 * \param [in] oldId - a current id of the family.
567 * \param [in] newId - a new family id.
569 void MEDFileMesh::changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception)
571 changeFamilyIdArr(oldId,newId);
572 std::map<std::string,int> fam2;
573 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
575 if((*it).second==oldId)
576 fam2[(*it).first]=newId;
578 fam2[(*it).first]=(*it).second;
584 * Renames a family in \a this mesh.
585 * \param [in] oldName - a current name of the family to rename.
586 * \param [in] newName - a new family name.
587 * \throw If no family named \a oldName exists in \a this mesh.
588 * \throw If a family named \a newName already exists.
590 void MEDFileMesh::changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
592 std::string oname(oldName);
593 std::map<std::string, int >::iterator it=_families.find(oname);
594 std::vector<std::string> fams=getFamiliesNames();
595 if(it==_families.end())
597 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
598 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
599 throw INTERP_KERNEL::Exception(oss.str().c_str());
601 std::string nname(newName);
602 std::map<std::string, int >::iterator it2=_families.find(nname);
603 if(it2!=_families.end())
605 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
606 throw INTERP_KERNEL::Exception(oss.str().c_str());
608 int cpy=(*it).second;
610 _families[newName]=cpy;
611 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
613 std::vector<std::string>& v=(*it3).second;
614 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
621 * Checks if \a this and another mesh contains the same families.
622 * \param [in] other - the mesh to compare with \a this one.
623 * \param [in,out] what - an unused parameter.
624 * \return bool - \c true if number of families and their ids are the same in the two
625 * meshes. Families with the id == \c 0 are not considered.
627 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
629 if(_families==other->_families)
631 std::map<std::string,int> fam0;
632 std::map<std::string,int> fam1;
633 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
635 fam0[(*it).first]=(*it).second;
636 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
638 fam1[(*it).first]=(*it).second;
643 * Checks if \a this and another mesh contains the same groups.
644 * \param [in] other - the mesh to compare with \a this one.
645 * \param [in,out] what - a string describing a difference of groups of the two meshes
646 * in case if this method returns \c false.
647 * \return bool - \c true if number of groups and families constituting them are the
648 * same in the two meshes.
650 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
652 if(_groups==other->_groups)
655 std::size_t sz=_groups.size();
656 if(sz!=other->_groups.size())
658 what="Groups differ because not same number !\n";
663 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
664 for(std::size_t i=0;i<sz && ret;i++,it1++)
666 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
667 if(it2!=other->_groups.end())
669 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
670 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
676 what="A group in first mesh exists not in other !\n";
682 std::ostringstream oss; oss << "Groups description differs :\n";
683 oss << "First group description :\n";
684 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
686 oss << " Group \"" << (*it).first << "\" on following families :\n";
687 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
688 oss << " \"" << *it2 << "\n";
690 oss << "Second group description :\n";
691 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
693 oss << " Group \"" << (*it).first << "\" on following families :\n";
694 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
695 oss << " \"" << *it2 << "\n";
703 * Checks if a group with a given name exists in \a this mesh.
704 * \param [in] groupName - the group name.
705 * \return bool - \c true the group \a groupName exists in \a this mesh.
707 bool MEDFileMesh::existsGroup(const char *groupName) const
709 std::string grpName(groupName);
710 return _groups.find(grpName)!=_groups.end();
714 * Checks if a family with a given id exists in \a this mesh.
715 * \param [in] famId - the family id.
716 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
718 bool MEDFileMesh::existsFamily(int famId) const
720 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
721 if((*it2).second==famId)
727 * Checks if a family with a given name exists in \a this mesh.
728 * \param [in] familyName - the family name.
729 * \return bool - \c true the family \a familyName exists in \a this mesh.
731 bool MEDFileMesh::existsFamily(const char *familyName) const
733 std::string fname(familyName);
734 return _families.find(fname)!=_families.end();
738 * Sets an id of a family.
739 * \param [in] familyName - the family name.
740 * \param [in] id - a new id of the family.
742 void MEDFileMesh::setFamilyId(const char *familyName, int id)
744 std::string fname(familyName);
748 void MEDFileMesh::setFamilyIdUnique(const char *familyName, int id) throw(INTERP_KERNEL::Exception)
750 std::string fname(familyName);
751 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
754 if((*it).first!=familyName)
756 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
757 throw INTERP_KERNEL::Exception(oss.str().c_str());
764 * Adds a family to \a this mesh.
765 * \param [in] familyName - a name of the family.
766 * \param [in] famId - an id of the family.
767 * \throw If a family with the same name or id already exists in \a this mesh.
769 void MEDFileMesh::addFamily(const char *familyName, int famId) throw(INTERP_KERNEL::Exception)
771 std::string fname(familyName);
772 std::map<std::string,int>::const_iterator it=_families.find(fname);
773 if(it==_families.end())
775 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
776 if((*it2).second==famId)
778 std::ostringstream oss;
779 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
780 throw INTERP_KERNEL::Exception(oss.str().c_str());
782 _families[fname]=famId;
786 if((*it).second!=famId)
788 std::ostringstream oss;
789 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
790 throw INTERP_KERNEL::Exception(oss.str().c_str());
796 * Creates a group including all mesh entities of given dimension.
797 * \warning This method does \b not guarantee that the created group includes mesh
798 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
799 * present in family fields of different dimensions. To assure this, call
800 * ensureDifferentFamIdsPerLevel() \b before calling this method.
801 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
803 * \param [in] groupName - a name of the new group.
804 * \throw If a group named \a groupName already exists.
805 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
806 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
808 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName) throw(INTERP_KERNEL::Exception)
810 std::string grpName(groupName);
811 std::vector<int> levs=getNonEmptyLevelsExt();
812 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
814 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
815 oss << "Available relative ext levels are : ";
816 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
817 throw INTERP_KERNEL::Exception(oss.str().c_str());
819 if(existsGroup(groupName))
821 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
822 oss << "Already existing groups are : ";
823 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
824 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
825 throw INTERP_KERNEL::Exception(oss.str().c_str());
827 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
829 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
830 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
831 std::vector<std::string> familiesOnWholeGroup;
832 for(const int *it=famIds->begin();it!=famIds->end();it++)
835 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
837 _groups[grpName]=familiesOnWholeGroup;
841 * Ensures that given family ids do not present in family fields of dimensions different
842 * than given ones. If a family id is present in the family fields of dimensions different
843 * than the given ones, a new family is created and the whole data is updated accordingly.
844 * \param [in] famIds - a sequence of family ids to check.
845 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
846 * famIds should exclusively belong.
847 * \return bool - \c true if no modification is done in \a this mesh by this method.
849 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
851 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
852 std::vector<int> levs=getNonEmptyLevelsExt();
853 std::set<int> levs2(levs.begin(),levs.end());
854 std::vector<int> levsToTest;
855 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
856 std::set<int> famIds2(famIds.begin(),famIds.end());
859 if(!_families.empty())
860 maxFamId=getMaxFamilyId()+1;
861 std::vector<std::string> allFams=getFamiliesNames();
862 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
864 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
867 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
868 std::vector<int> tmp;
869 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
870 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
873 std::string famName=getFamilyNameGivenId(*it2);
874 std::ostringstream oss; oss << "Family_" << maxFamId;
875 std::string zeName=CreateNameNotIn(oss.str(),allFams);
876 addFamilyOnAllGroupsHaving(famName.c_str(),zeName.c_str());
877 _families[zeName]=maxFamId;
878 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
887 * Adds a family to a given group in \a this mesh. If the group with a given name does
888 * not exist, it is created.
889 * \param [in] grpName - the name of the group to add the family in.
890 * \param [in] famName - the name of the family to add to the group named \a grpName.
891 * \throw If \a grpName or \a famName is an empty string.
892 * \throw If no family named \a famName is present in \a this mesh.
894 void MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName) throw(INTERP_KERNEL::Exception)
896 std::string grpn(grpName);
897 std::string famn(famName);
898 if(grpn.empty() || famn.empty())
899 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
900 std::vector<std::string> fams=getFamiliesNames();
901 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
903 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
904 oss << "Create this family or choose an existing one ! Existing fams are : ";
905 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
906 throw INTERP_KERNEL::Exception(oss.str().c_str());
908 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
909 if(it==_groups.end())
911 _groups[grpn].push_back(famn);
915 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
916 if(it2==(*it).second.end())
917 (*it).second.push_back(famn);
922 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
923 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
924 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
926 void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *otherFamName) throw(INTERP_KERNEL::Exception)
928 std::string famNameCpp(famName);
929 std::string otherCpp(otherFamName);
930 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
932 std::vector<std::string>& v=(*it).second;
933 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
935 v.push_back(otherCpp);
940 void MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
942 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
945 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)
947 std::string fam(familyNameToChange);
948 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
950 std::vector<std::string>& fams((*it).second);
951 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
955 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
961 * Returns a name of the family having a given id or, if no such a family exists, creates
962 * a new uniquely named family and returns its name.
963 * \param [in] id - the id of the family whose name is required.
964 * \param [out] created - returns \c true if the new family has been created, \c false, else.
965 * \return std::string - the name of the existing or the created family.
966 * \throw If it is not possible to create a unique family name.
968 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception)
970 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
974 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
975 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
976 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
977 * already existing. In this case 'created' will be returned with a value set to true, and internal state
979 * This method will throws an exception if it is not possible to create a unique family name.
981 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created) throw(INTERP_KERNEL::Exception)
983 std::vector<std::string> famAlreadyExisting(families.size());
985 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
989 famAlreadyExisting[ii]=(*it).first;
998 std::ostringstream oss; oss << "Family_" << id;
999 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1005 * Sets names and ids of all families in \a this mesh.
1006 * \param [in] info - a map of a family name to a family id.
1008 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1014 * Sets names of all groups and families constituting them in \a this mesh.
1015 * \param [in] info - a map of a group name to a vector of names of families
1016 * constituting the group.
1018 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1024 * Returns an id of the family having a given name.
1025 * \param [in] name - the name of the family of interest.
1026 * \return int - the id of the family of interest.
1027 * \throw If no family with such a \a name exists.
1029 int MEDFileMesh::getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception)
1031 std::string oname(name);
1032 std::map<std::string, int>::const_iterator it=_families.find(oname);
1033 std::vector<std::string> fams=getFamiliesNames();
1034 if(it==_families.end())
1036 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1037 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1038 throw INTERP_KERNEL::Exception(oss.str().c_str());
1040 return (*it).second;
1044 * Returns ids of the families having given names.
1045 * \param [in] fams - a sequence of the names of families of interest.
1046 * \return std::vector<int> - a sequence of the ids of families of interest.
1047 * \throw If \a fams contains a name of an inexistent family.
1049 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
1051 std::vector<int> ret(fams.size());
1053 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1055 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1056 if(it2==_families.end())
1058 std::vector<std::string> fams2=getFamiliesNames();
1059 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1060 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1061 throw INTERP_KERNEL::Exception(oss.str().c_str());
1063 ret[i]=(*it2).second;
1069 * Returns a maximal id of families in \a this mesh.
1070 * \return int - the maximal family id.
1071 * \throw If there are no families in \a this mesh.
1073 int MEDFileMesh::getMaxFamilyId() const throw(INTERP_KERNEL::Exception)
1075 if(_families.empty())
1076 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMaxFamilyId : no families set !");
1077 int ret=-std::numeric_limits<int>::max();
1078 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1080 ret=std::max((*it).second,ret);
1086 * Returns a minimal id of families in \a this mesh.
1087 * \return int - the minimal family id.
1088 * \throw If there are no families in \a this mesh.
1090 int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception)
1092 if(_families.empty())
1093 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMinFamilyId : no families set !");
1094 int ret=std::numeric_limits<int>::max();
1095 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1097 ret=std::min((*it).second,ret);
1103 * Returns a maximal id of families in \a this mesh. Not only named families are
1104 * considered but all family fields as well.
1105 * \return int - the maximal family id.
1107 int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception)
1109 int m1=-std::numeric_limits<int>::max();
1110 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1111 m1=std::max((*it).second,m1);
1112 int m2=getMaxFamilyIdInArrays();
1113 return std::max(m1,m2);
1116 int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception)
1118 int m1=std::numeric_limits<int>::max();
1119 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1120 m1=std::min((*it).second,m1);
1121 int m2=getMinFamilyIdInArrays();
1122 return std::min(m1,m2);
1125 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception)
1127 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1129 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1130 v.insert((*it).second);
1131 ret->alloc((int)v.size(),1);
1132 std::copy(v.begin(),v.end(),ret->getPointer());
1137 * true is returned if no modification has been needed. false if family
1138 * renumbering has been needed.
1140 bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception)
1142 std::vector<int> levs=getNonEmptyLevelsExt();
1143 std::set<int> allFamIds;
1144 int maxId=getMaxFamilyId()+1;
1145 std::map<int,std::vector<int> > famIdsToRenum;
1146 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1148 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1151 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1153 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1155 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1157 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1160 if(famIdsToRenum.empty())
1162 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1163 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1165 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1166 int *famIdsToChange=fam->getPointer();
1167 std::map<int,int> ren;
1168 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1170 if(allIds->presenceOfValue(*it3))
1172 std::string famName=getFamilyNameGivenId(*it3);
1173 std::vector<std::string> grps=getGroupsOnFamily(famName.c_str());
1176 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1177 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1178 addFamilyOnGrp((*it4).c_str(),newFam.c_str());
1181 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1182 for(const int *id=ids->begin();id!=ids->end();id++)
1183 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1189 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1190 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1191 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1192 * This method will throw an exception if a same family id is detected in different level.
1193 * \warning This policy is the opposite of those in MED file documentation ...
1195 void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
1197 ensureDifferentFamIdsPerLevel();
1198 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1199 std::vector<int> levs=getNonEmptyLevelsExt();
1200 std::set<int> levsS(levs.begin(),levs.end());
1201 std::set<std::string> famsFetched;
1202 std::map<std::string,int> families;
1203 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1206 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1210 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1211 std::map<int,int> ren;
1212 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1214 int nbOfTuples=fam->getNumberOfTuples();
1215 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1216 for(int *w=start;w!=start+nbOfTuples;w++)
1218 for(const int *it=tmp->begin();it!=tmp->end();it++)
1220 if(allIds->presenceOfValue(*it))
1222 std::string famName=getFamilyNameGivenId(*it);
1223 families[famName]=ren[*it];
1224 famsFetched.insert(famName);
1229 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1232 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1236 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1237 std::map<int,int> ren;
1238 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1240 int nbOfTuples=fam->getNumberOfTuples();
1241 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1242 for(int *w=start;w!=start+nbOfTuples;w++)
1244 for(const int *it=tmp->begin();it!=tmp->end();it++)
1246 if(allIds->presenceOfValue(*it))
1248 std::string famName=getFamilyNameGivenId(*it);
1249 families[famName]=ren[*it];
1250 famsFetched.insert(famName);
1255 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1257 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1260 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1261 fam->fillWithZero();
1262 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1263 if(allIds->presenceOfValue(*it3))
1265 std::string famName=getFamilyNameGivenId(*it3);
1266 families[famName]=0;
1267 famsFetched.insert(famName);
1272 std::vector<std::string> allFams=getFamiliesNames();
1273 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1274 std::set<std::string> unFetchedIds;
1275 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1276 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1277 families[*it4]=_families[*it4];
1282 * This method normalizes fam id with the following policy.
1283 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1284 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1285 * This method will throw an exception if a same family id is detected in different level.
1287 void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
1289 ensureDifferentFamIdsPerLevel();
1290 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1291 std::vector<int> levs=getNonEmptyLevelsExt();
1292 std::set<int> levsS(levs.begin(),levs.end());
1293 std::set<std::string> famsFetched;
1294 std::map<std::string,int> families;
1296 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1299 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1302 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1303 std::map<int,int> ren;
1304 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1306 int nbOfTuples=fam->getNumberOfTuples();
1307 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1308 for(int *w=start;w!=start+nbOfTuples;w++)
1310 for(const int *it=tmp->begin();it!=tmp->end();it++)
1312 if(allIds->presenceOfValue(*it))
1314 std::string famName=getFamilyNameGivenId(*it);
1315 families[famName]=ren[*it];
1316 famsFetched.insert(famName);
1322 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1324 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1327 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1328 std::map<int,int> ren;
1329 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1331 int nbOfTuples=fam->getNumberOfTuples();
1332 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1333 for(int *w=start;w!=start+nbOfTuples;w++)
1335 for(const int *it=tmp->begin();it!=tmp->end();it++)
1337 if(allIds->presenceOfValue(*it))
1339 std::string famName=getFamilyNameGivenId(*it);
1340 families[famName]=ren[*it];
1341 famsFetched.insert(famName);
1347 std::vector<std::string> allFams=getFamiliesNames();
1348 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1349 std::set<std::string> unFetchedIds;
1350 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1351 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1352 families[*it4]=_families[*it4];
1357 * Returns a name of the family by its id. If there are several families having the given
1358 * id, the name first in lexical order is returned.
1359 * \param [in] id - the id of the family whose name is required.
1360 * \return std::string - the name of the found family.
1361 * \throw If no family with the given \a id exists.
1363 std::string MEDFileMesh::getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception)
1365 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1366 if((*it).second==id)
1368 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1369 throw INTERP_KERNEL::Exception(oss.str().c_str());
1373 * Returns a string describing \a this mesh. This description includes the mesh name and
1374 * the mesh description string.
1375 * \return std::string - the mesh information string.
1377 std::string MEDFileMesh::simpleRepr() const
1379 std::ostringstream oss;
1380 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1381 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1382 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1387 * Returns ids of mesh entities contained in a given group of a given dimension.
1388 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1390 * \param [in] grp - the name of the group of interest.
1391 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1392 * returned instead of ids.
1393 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1394 * numbers, if available and required, of mesh entities of the group. The caller
1395 * is to delete this array using decrRef() as it is no more needed.
1396 * \throw If the name of a nonexistent group is specified.
1397 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1399 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1401 std::vector<std::string> tmp(1);
1403 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1409 * Returns ids of mesh entities contained in given groups of a given dimension.
1410 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1412 * \param [in] grps - the names of the groups of interest.
1413 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1414 * returned instead of ids.
1415 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1416 * numbers, if available and required, of mesh entities of the groups. The caller
1417 * is to delete this array using decrRef() as it is no more needed.
1418 * \throw If the name of a nonexistent group is present in \a grps.
1419 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1421 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1423 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1424 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1428 * Returns ids of mesh entities contained in a given family of a given dimension.
1429 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1431 * \param [in] fam - the name of the family of interest.
1432 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1433 * returned instead of ids.
1434 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1435 * numbers, if available and required, of mesh entities of the family. The caller
1436 * is to delete this array using decrRef() as it is no more needed.
1437 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1439 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1441 std::vector<std::string> tmp(1);
1443 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1449 * Returns ids of nodes contained in a given group.
1450 * \param [in] grp - the name of the group of interest.
1451 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1452 * returned instead of ids.
1453 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1454 * numbers, if available and required, of nodes of the group. The caller
1455 * is to delete this array using decrRef() as it is no more needed.
1456 * \throw If the name of a nonexistent group is specified.
1457 * \throw If the family field is missing for nodes.
1459 DataArrayInt *MEDFileMesh::getNodeGroupArr(const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1461 std::vector<std::string> tmp(1);
1463 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1469 * Returns ids of nodes contained in given groups.
1470 * \param [in] grps - the names of the groups of interest.
1471 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1472 * returned instead of ids.
1473 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1474 * numbers, if available and required, of nodes of the groups. The caller
1475 * is to delete this array using decrRef() as it is no more needed.
1476 * \throw If the name of a nonexistent group is present in \a grps.
1477 * \throw If the family field is missing for nodes.
1479 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1481 return getGroupsArr(1,grps,renum);
1485 * Returns ids of nodes contained in a given group.
1486 * \param [in] grp - the name of the group of interest.
1487 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1488 * returned instead of ids.
1489 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1490 * numbers, if available and required, of nodes of the group. The caller
1491 * is to delete this array using decrRef() as it is no more needed.
1492 * \throw If the name of a nonexistent group is specified.
1493 * \throw If the family field is missing for nodes.
1495 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1497 std::vector<std::string> tmp(1);
1499 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1505 * Returns ids of nodes contained in given families.
1506 * \param [in] fams - the names of the families of interest.
1507 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1508 * returned instead of ids.
1509 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1510 * numbers, if available and required, of nodes of the families. The caller
1511 * is to delete this array using decrRef() as it is no more needed.
1512 * \throw If the family field is missing for nodes.
1514 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
1516 return getFamiliesArr(1,fams,renum);
1520 * Adds groups of given dimension and creates corresponding families and family fields
1521 * given ids of mesh entities of each group.
1522 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1523 * \param [in] grps - a sequence of arrays of ids each describing a group.
1524 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1526 * \throw If names of some groups in \a grps are equal.
1527 * \throw If \a grps includes a group with an empty name.
1528 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1529 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1531 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum) throw(INTERP_KERNEL::Exception)
1535 std::set<std::string> grpsName;
1536 std::vector<std::string> grpsName2(grps.size());
1539 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1541 grpsName.insert((*it)->getName());
1542 grpsName2[i]=(*it)->getName();
1544 if(grpsName.size()!=grps.size())
1545 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1546 if(grpsName.find(std::string(""))!=grpsName.end())
1547 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1548 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1549 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1550 std::vector< std::vector<int> > fidsOfGroups;
1553 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1557 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1558 for(unsigned int ii=0;ii<grps.size();ii++)
1560 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1561 grps2[ii]->setName(grps[ii]->getName().c_str());
1563 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1564 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1567 if(!_families.empty())
1568 offset=getMaxFamilyId()+1;
1569 TranslateFamilyIds(offset,fam,fidsOfGroups);
1570 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1571 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1572 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1576 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1577 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1578 * For the moment, the two last input parameters are not taken into account.
1580 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1582 std::map<int,std::string> famInv;
1583 for(const int *it=famIds->begin();it!=famIds->end();it++)
1585 std::ostringstream oss;
1586 oss << "Family_" << (*it);
1587 _families[oss.str()]=(*it);
1588 famInv[*it]=oss.str();
1591 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1593 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1595 _groups[grpNames[i]].push_back(famInv[*it2]);
1600 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1602 famArr->applyLin(1,offset,0);
1603 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1604 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1608 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1609 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1610 * If this method fails to find such a name it will throw an exception.
1612 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid) throw(INTERP_KERNEL::Exception)
1615 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1618 std::size_t len=nameTry.length();
1619 for(std::size_t ii=1;ii<len;ii++)
1621 std::string tmp=nameTry.substr(ii,len-ii);
1622 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1628 for(std::size_t i=1;i<30;i++)
1630 std::string tmp1(nameTry.at(0),i);
1632 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1638 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1640 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1642 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1645 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt) throw(INTERP_KERNEL::Exception)
1647 std::size_t nbOfChunks=code.size()/3;
1648 if(code.size()%3!=0)
1649 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1651 for(std::size_t i=0;i<nbOfChunks;i++)
1660 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1661 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1662 * If _name is not empty and that 'm' has the same name nothing is done.
1663 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1665 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL::Exception)
1668 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1673 std::string name(m->getName());
1678 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1679 oss << name << "' ! Names must match !";
1680 throw INTERP_KERNEL::Exception(oss.str().c_str());
1684 if(_desc_name.empty())
1685 _desc_name=m->getDescription();
1688 std::string name(m->getDescription());
1691 if(_desc_name!=name)
1693 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1694 oss << name << "' ! Names must match !";
1695 throw INTERP_KERNEL::Exception(oss.str().c_str());
1701 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1703 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1704 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1706 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1707 oss << " - Groups lying on this family : ";
1708 std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
1709 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1710 oss << std::endl << std::endl;
1715 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1716 * file. The mesh to load is specified by its name and numbers of a time step and an
1718 * \param [in] fileName - the name of MED file to read.
1719 * \param [in] mName - the name of the mesh to read.
1720 * \param [in] dt - the number of a time step.
1721 * \param [in] it - the number of an iteration.
1722 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1723 * mesh using decrRef() as it is no more needed.
1724 * \throw If the file is not readable.
1725 * \throw If there is no mesh with given attributes in the file.
1726 * \throw If the mesh in the file is not an unstructured one.
1728 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
1730 MEDFileUtilities::CheckFileForRead(fileName);
1731 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1732 return new MEDFileUMesh(fid,mName,dt,it);
1736 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1737 * file. The first mesh in the file is loaded.
1738 * \param [in] fileName - the name of MED file to read.
1739 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1740 * mesh using decrRef() as it is no more needed.
1741 * \throw If the file is not readable.
1742 * \throw If there is no meshes in the file.
1743 * \throw If the mesh in the file is not an unstructured one.
1745 MEDFileUMesh *MEDFileUMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
1747 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1750 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1751 throw INTERP_KERNEL::Exception(oss.str().c_str());
1753 MEDFileUtilities::CheckFileForRead(fileName);
1754 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1756 ParaMEDMEM::MEDCouplingMeshType meshType;
1758 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
1759 return new MEDFileUMesh(fid,ms.front().c_str(),dt,it);
1763 * Returns an empty instance of MEDFileUMesh.
1764 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1765 * mesh using decrRef() as it is no more needed.
1767 MEDFileUMesh *MEDFileUMesh::New()
1769 return new MEDFileUMesh;
1772 std::size_t MEDFileUMesh::getHeapMemorySize() const
1774 std::size_t ret=MEDFileMesh::getHeapMemorySize();
1775 if((const DataArrayDouble*)_coords)
1776 ret+=_coords->getHeapMemorySize();
1777 if((const DataArrayInt *)_fam_coords)
1778 ret+=_fam_coords->getHeapMemorySize();
1779 if((const DataArrayInt *)_num_coords)
1780 ret+=_num_coords->getHeapMemorySize();
1781 if((const DataArrayInt *)_rev_num_coords)
1782 ret+=_rev_num_coords->getHeapMemorySize();
1783 if((const DataArrayAsciiChar *)_name_coords)
1784 ret+=_name_coords->getHeapMemorySize();
1785 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1786 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1787 if((const MEDFileUMeshSplitL1*) *it)
1788 ret+=(*it)->getHeapMemorySize();
1792 MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
1794 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1798 MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
1800 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1801 if((const DataArrayDouble*)_coords)
1802 ret->_coords=_coords->deepCpy();
1803 if((const DataArrayInt*)_fam_coords)
1804 ret->_fam_coords=_fam_coords->deepCpy();
1805 if((const DataArrayInt*)_num_coords)
1806 ret->_num_coords=_num_coords->deepCpy();
1807 if((const DataArrayInt*)_rev_num_coords)
1808 ret->_rev_num_coords=_rev_num_coords->deepCpy();
1809 if((const DataArrayAsciiChar*)_name_coords)
1810 ret->_name_coords=_name_coords->deepCpy();
1812 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
1814 if((const MEDFileUMeshSplitL1 *)(*it))
1815 ret->_ms[i]=(*it)->deepCpy();
1821 * Checks if \a this and another mesh are equal.
1822 * \param [in] other - the mesh to compare with.
1823 * \param [in] eps - a precision used to compare real values.
1824 * \param [in,out] what - the string returning description of unequal data.
1825 * \return bool - \c true if the meshes are equal, \c false, else.
1827 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
1829 if(!MEDFileMesh::isEqual(other,eps,what))
1831 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
1834 what="Mesh types differ ! This is unstructured and other is NOT !";
1837 clearNonDiscrAttributes();
1838 otherC->clearNonDiscrAttributes();
1839 const DataArrayDouble *coo1=_coords;
1840 const DataArrayDouble *coo2=otherC->_coords;
1841 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
1843 what="Mismatch of coordinates ! One is defined and not other !";
1848 bool ret=coo1->isEqual(*coo2,eps);
1851 what="Coords differ !";
1855 const DataArrayInt *famc1=_fam_coords;
1856 const DataArrayInt *famc2=otherC->_fam_coords;
1857 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
1859 what="Mismatch of families arr on nodes ! One is defined and not other !";
1864 bool ret=famc1->isEqual(*famc2);
1867 what="Families arr on node differ !";
1871 const DataArrayInt *numc1=_num_coords;
1872 const DataArrayInt *numc2=otherC->_num_coords;
1873 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
1875 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
1880 bool ret=numc1->isEqual(*numc2);
1883 what="Numbering arr on node differ !";
1887 const DataArrayAsciiChar *namec1=_name_coords;
1888 const DataArrayAsciiChar *namec2=otherC->_name_coords;
1889 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
1891 what="Mismatch of naming arr on nodes ! One is defined and not other !";
1896 bool ret=namec1->isEqual(*namec2);
1899 what="Names arr on node differ !";
1903 if(_ms.size()!=otherC->_ms.size())
1905 what="Number of levels differs !";
1908 std::size_t sz=_ms.size();
1909 for(std::size_t i=0;i<sz;i++)
1911 const MEDFileUMeshSplitL1 *s1=_ms[i];
1912 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
1913 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
1915 what="Mismatch of presence of sub levels !";
1920 bool ret=s1->isEqual(s2,eps,what);
1929 * Clears redundant attributes of incorporated data arrays.
1931 void MEDFileUMesh::clearNonDiscrAttributes() const
1933 MEDFileMesh::clearNonDiscrAttributes();
1934 const DataArrayDouble *coo1=_coords;
1936 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
1937 const DataArrayInt *famc1=_fam_coords;
1939 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
1940 const DataArrayInt *numc1=_num_coords;
1942 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
1943 const DataArrayAsciiChar *namc1=_name_coords;
1945 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
1946 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1948 const MEDFileUMeshSplitL1 *tmp=(*it);
1950 tmp->clearNonDiscrAttributes();
1954 MEDFileUMesh::MEDFileUMesh()
1958 MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
1961 loadUMeshFromFile(fid,mName,dt,it);
1963 catch(INTERP_KERNEL::Exception& e)
1968 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
1970 MEDFileUMeshL2 loaderl2;
1971 ParaMEDMEM::MEDCouplingMeshType meshType;
1974 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
1975 if(meshType!=UNSTRUCTURED)
1977 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
1978 throw INTERP_KERNEL::Exception(oss.str().c_str());
1980 loaderl2.loadAll(fid,mid,mName,dt,it);
1981 int lev=loaderl2.getNumberOfLevels();
1983 for(int i=0;i<lev;i++)
1985 if(!loaderl2.emptyLev(i))
1986 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
1990 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups);
1992 setName(loaderl2.getName());
1993 setDescription(loaderl2.getDescription());
1994 setUnivName(loaderl2.getUnivName());
1995 setIteration(loaderl2.getIteration());
1996 setOrder(loaderl2.getOrder());
1997 setTimeValue(loaderl2.getTime());
1998 setTimeUnit(loaderl2.getTimeUnit());
1999 _coords=loaderl2.getCoords();
2000 _fam_coords=loaderl2.getCoordsFamily();
2001 _num_coords=loaderl2.getCoordsNum();
2002 _name_coords=loaderl2.getCoordsName();
2006 MEDFileUMesh::~MEDFileUMesh()
2010 void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
2012 const DataArrayDouble *coo=_coords;
2013 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2014 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2015 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2016 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2017 int spaceDim=coo?coo->getNumberOfComponents():0;
2018 int mdim=getMeshDimension();
2019 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2020 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2021 for(int i=0;i<spaceDim;i++)
2023 std::string info=coo->getInfoOnComponent(i);
2025 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2026 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
2027 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
2029 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2030 MEDmeshUniversalNameWr(fid,maa);
2031 MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2032 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2033 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2034 (*it)->write(fid,maa,mdim);
2035 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
2039 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2040 * \return std::vector<int> - a sequence of the relative dimensions.
2042 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2044 std::vector<int> ret;
2046 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2047 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2054 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2055 * \return std::vector<int> - a sequence of the relative dimensions.
2057 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2059 std::vector<int> ret0=getNonEmptyLevels();
2060 if((const DataArrayDouble *) _coords)
2062 std::vector<int> ret(ret0.size()+1);
2064 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2071 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2072 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2073 * \param [in] grp - the name of the group of interest.
2074 * \return std::vector<int> - a sequence of the relative dimensions.
2076 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const throw(INTERP_KERNEL::Exception)
2078 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2079 return getFamsNonEmptyLevels(fams);
2083 * Returns all relative mesh levels (including nodes) where a given group is defined.
2084 * \param [in] grp - the name of the group of interest.
2085 * \return std::vector<int> - a sequence of the relative dimensions.
2087 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const throw(INTERP_KERNEL::Exception)
2089 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2090 return getFamsNonEmptyLevelsExt(fams);
2094 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2095 * To include nodes, call getFamNonEmptyLevelsExt() method.
2096 * \param [in] fam - the name of the family of interest.
2097 * \return std::vector<int> - a sequence of the relative dimensions.
2099 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const throw(INTERP_KERNEL::Exception)
2101 std::vector<std::string> fams(1,std::string(fam));
2102 return getFamsNonEmptyLevels(fams);
2106 * Returns all relative mesh levels (including nodes) where a given family is defined.
2107 * \param [in] fam - the name of the family of interest.
2108 * \return std::vector<int> - a sequence of the relative dimensions.
2110 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const throw(INTERP_KERNEL::Exception)
2112 std::vector<std::string> fams(1,std::string(fam));
2113 return getFamsNonEmptyLevelsExt(fams);
2117 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2118 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2119 * \param [in] grps - a sequence of names of the groups of interest.
2120 * \return std::vector<int> - a sequence of the relative dimensions.
2122 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2124 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2125 return getFamsNonEmptyLevels(fams);
2129 * Returns all relative mesh levels (including nodes) where given groups are defined.
2130 * \param [in] grps - a sequence of names of the groups of interest.
2131 * \return std::vector<int> - a sequence of the relative dimensions.
2133 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2135 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2136 return getFamsNonEmptyLevelsExt(fams);
2140 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2141 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2142 * \param [in] fams - the name of the family of interest.
2143 * \return std::vector<int> - a sequence of the relative dimensions.
2145 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2147 std::vector<int> ret;
2148 std::vector<int> levs=getNonEmptyLevels();
2149 std::vector<int> famIds=getFamiliesIds(fams);
2150 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2151 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2157 * Returns all relative mesh levels (including nodes) where given families are defined.
2158 * \param [in] fams - the names of the families of interest.
2159 * \return std::vector<int> - a sequence of the relative dimensions.
2161 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2163 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2164 const DataArrayInt *famCoords=_fam_coords;
2167 std::vector<int> famIds=getFamiliesIds(fams);
2168 if(famCoords->presenceOfValue(famIds))
2170 std::vector<int> ret(ret0.size()+1);
2172 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2180 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2181 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2182 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2185 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2187 std::vector<std::string> ret;
2188 std::vector<std::string> allGrps=getGroupsNames();
2189 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2191 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it).c_str());
2192 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2198 int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2200 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2201 if((const DataArrayInt *)_fam_coords)
2203 int val=_fam_coords->getMaxValue(tmp);
2204 ret=std::max(ret,val);
2206 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2208 if((const MEDFileUMeshSplitL1 *)(*it))
2210 const DataArrayInt *da=(*it)->getFamilyField();
2213 int val=da->getMaxValue(tmp);
2214 ret=std::max(ret,val);
2221 int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2223 int ret=std::numeric_limits<int>::max(),tmp=-1;
2224 if((const DataArrayInt *)_fam_coords)
2226 int val=_fam_coords->getMinValue(tmp);
2227 ret=std::min(ret,val);
2229 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2231 if((const MEDFileUMeshSplitL1 *)(*it))
2233 const DataArrayInt *da=(*it)->getFamilyField();
2236 int val=da->getMinValue(tmp);
2237 ret=std::min(ret,val);
2245 * Returns the dimension on cells in \a this mesh.
2246 * \return int - the mesh dimension.
2247 * \throw If there are no cells in this mesh.
2249 int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
2252 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2253 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2254 return (*it)->getMeshDimension()+lev;
2255 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2259 * Returns the space dimension of \a this mesh that is equal to number of components in
2260 * the node coordinates array.
2261 * \return int - the space dimension of \a this mesh.
2262 * \throw If the node coordinates array is not available.
2264 int MEDFileUMesh::getSpaceDimension() const throw(INTERP_KERNEL::Exception)
2266 const DataArrayDouble *coo=_coords;
2268 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2269 return coo->getNumberOfComponents();
2273 * Returns a string describing \a this mesh.
2274 * \return std::string - the mesh information string.
2276 std::string MEDFileUMesh::simpleRepr() const
2278 std::ostringstream oss;
2279 oss << MEDFileMesh::simpleRepr();
2280 const DataArrayDouble *coo=_coords;
2281 oss << "- The dimension of the space is ";
2282 static const char MSG1[]= "*** NO COORDS SET ***";
2283 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2285 oss << _coords->getNumberOfComponents() << std::endl;
2287 oss << MSG1 << std::endl;
2288 oss << "- Type of the mesh : UNSTRUCTURED\n";
2289 oss << "- Number of nodes : ";
2291 oss << _coords->getNumberOfTuples() << std::endl;
2293 oss << MSG1 << std::endl;
2294 std::size_t nbOfLev=_ms.size();
2295 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2296 for(std::size_t i=0;i<nbOfLev;i++)
2298 const MEDFileUMeshSplitL1 *lev=_ms[i];
2299 oss << " - Level #" << -((int) i) << " has dimension : ";
2302 oss << lev->getMeshDimension() << std::endl;
2303 lev->simpleRepr(oss);
2306 oss << MSG2 << std::endl;
2308 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2311 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2312 oss << "- Names of coordinates :" << std::endl;
2313 std::vector<std::string> vars=coo->getVarsOnComponent();
2314 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2315 oss << std::endl << "- Units of coordinates : " << std::endl;
2316 std::vector<std::string> units=coo->getUnitsOnComponent();
2317 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2319 oss << std::endl << std::endl;
2325 * Returns a full textual description of \a this mesh.
2326 * \return std::string - the string holding the mesh description.
2328 std::string MEDFileUMesh::advancedRepr() const
2330 return simpleRepr();
2334 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2335 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2336 * \return int - the number of entities.
2337 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2339 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2341 if(meshDimRelToMaxExt==1)
2343 if(!((const DataArrayDouble *)_coords))
2344 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2345 return _coords->getNumberOfTuples();
2347 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2351 * Returns the family field for mesh entities of a given dimension.
2352 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2353 * \return const DataArrayInt * - the family field. It is an array of ids of families
2354 * each mesh entity belongs to. It can be \c NULL.
2356 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2358 if(meshDimRelToMaxExt==1)
2360 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2361 return l1->getFamilyField();
2365 * Returns the optional numbers of mesh entities of a given dimension.
2366 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2367 * \return const DataArrayInt * - the array of the entity numbers.
2368 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2370 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2372 if(meshDimRelToMaxExt==1)
2374 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2375 return l1->getNumberField();
2378 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2380 if(meshDimRelToMaxExt==1)
2381 return _name_coords;
2382 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2383 return l1->getNameField();
2386 int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
2388 const DataArrayDouble *coo=_coords;
2390 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2391 return coo->getNumberOfTuples();
2395 * Returns the optional numbers of mesh entities of a given dimension transformed using
2396 * DataArrayInt::invertArrayN2O2O2N().
2397 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2398 * \return const DataArrayInt * - the array of the entity numbers transformed using
2399 * DataArrayInt::invertArrayN2O2O2N().
2400 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2402 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2404 if(meshDimRelToMaxExt==1)
2406 if(!((const DataArrayInt *)_num_coords))
2407 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2408 return _rev_num_coords;
2410 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2411 return l1->getRevNumberField();
2415 * Returns a pointer to the node coordinates array of \a this mesh \b without
2416 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2418 DataArrayDouble *MEDFileUMesh::getCoords() const
2420 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2421 if((DataArrayDouble *)tmp)
2429 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2430 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2432 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2433 * \param [in] grp - the name of the group whose mesh entities are included in the
2435 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2436 * according to the optional numbers of entities, if available.
2437 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2438 * delete this mesh using decrRef() as it is no more needed.
2439 * \throw If the name of a nonexistent group is specified.
2440 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2442 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
2444 synchronizeTinyInfoOnLeaves();
2445 std::vector<std::string> tmp(1);
2447 MEDCouplingUMesh *ret=getGroups(meshDimRelToMaxExt,tmp,renum);
2453 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2454 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2456 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2457 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2459 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2460 * according to the optional numbers of entities, if available.
2461 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2462 * delete this mesh using decrRef() as it is no more needed.
2463 * \throw If a name of a nonexistent group is present in \a grps.
2464 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2466 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
2468 synchronizeTinyInfoOnLeaves();
2469 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2470 return getFamilies(meshDimRelToMaxExt,fams2,renum);
2474 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2475 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2477 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2478 * \param [in] fam - the name of the family whose mesh entities are included in the
2480 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2481 * according to the optional numbers of entities, if available.
2482 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2483 * delete this mesh using decrRef() as it is no more needed.
2484 * \throw If a name of a nonexistent family is present in \a grps.
2485 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2487 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
2489 synchronizeTinyInfoOnLeaves();
2490 std::vector<std::string> tmp(1);
2492 MEDCouplingUMesh *ret=getFamilies(meshDimRelToMaxExt,tmp,renum);
2498 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2499 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2501 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2502 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2504 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2505 * according to the optional numbers of entities, if available.
2506 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2507 * delete this mesh using decrRef() as it is no more needed.
2508 * \throw If a name of a nonexistent family is present in \a fams.
2509 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2511 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2513 synchronizeTinyInfoOnLeaves();
2514 if(meshDimRelToMaxExt==1)
2516 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2517 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2518 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2522 std::vector<int> famIds=getFamiliesIds(fams);
2523 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2525 return l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2527 return l1->getFamilyPart(0,0,renum);
2531 * Returns ids of mesh entities contained in given families of a given dimension.
2532 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2534 * \param [in] fams - the names of the families of interest.
2535 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2536 * returned instead of ids.
2537 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2538 * numbers, if available and required, of mesh entities of the families. The caller
2539 * is to delete this array using decrRef() as it is no more needed.
2540 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2542 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2544 std::vector<int> famIds=getFamiliesIds(fams);
2545 if(meshDimRelToMaxExt==1)
2547 if((const DataArrayInt *)_fam_coords)
2549 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2551 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2553 da=_fam_coords->getIdsEqualList(0,0);
2555 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2560 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2562 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2564 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2566 return l1->getFamilyPartArr(0,0,renum);
2570 * Returns a MEDCouplingUMesh of a given relative dimension.
2571 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2572 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2573 * To build a valid MEDCouplingUMesh from the returned one in this case,
2574 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2575 * \param [in] meshDimRelToMax - the relative dimension of interest.
2576 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2577 * optional numbers of mesh entities.
2578 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2579 * delete using decrRef() as it is no more needed.
2580 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2581 * \sa getGenMeshAtLevel()
2583 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
2585 synchronizeTinyInfoOnLeaves();
2586 if(meshDimRelToMaxExt==1)
2590 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2591 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2592 umesh->setCoords(cc);
2593 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2594 umesh->setName(getName());
2598 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2599 return l1->getWholeMesh(renum);
2603 * Returns a MEDCouplingUMesh of a given relative dimension.
2604 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2605 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2606 * To build a valid MEDCouplingUMesh from the returned one in this case,
2607 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2608 * \param [in] meshDimRelToMax - the relative dimension of interest.
2609 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2610 * optional numbers of mesh entities.
2611 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2612 * delete using decrRef() as it is no more needed.
2613 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2614 * \sa getMeshAtLevel()
2616 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
2618 return getMeshAtLevel(meshDimRelToMax,renum);
2622 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2623 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2624 * optional numbers of mesh entities.
2625 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2626 * delete using decrRef() as it is no more needed.
2627 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2629 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2631 return getMeshAtLevel(0,renum);
2635 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2636 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2637 * optional numbers of mesh entities.
2638 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2639 * delete using decrRef() as it is no more needed.
2640 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2642 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2644 return getMeshAtLevel(-1,renum);
2648 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2649 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2650 * optional numbers of mesh entities.
2651 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2652 * delete using decrRef() as it is no more needed.
2653 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
2655 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2657 return getMeshAtLevel(-2,renum);
2661 * Returns a MEDCouplingUMesh of a relative dimension == -3.
2662 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2663 * optional numbers of mesh entities.
2664 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2665 * delete using decrRef() as it is no more needed.
2666 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
2668 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2670 return getMeshAtLevel(-3,renum);
2673 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2675 if(meshDimRelToMaxExt==1)
2676 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2677 if(meshDimRelToMaxExt>1)
2678 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2679 int tracucedRk=-meshDimRelToMaxExt;
2680 if(tracucedRk>=(int)_ms.size())
2681 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2682 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2683 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2684 return _ms[tracucedRk];
2687 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2689 if(meshDimRelToMaxExt==1)
2690 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2691 if(meshDimRelToMaxExt>1)
2692 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2693 int tracucedRk=-meshDimRelToMaxExt;
2694 if(tracucedRk>=(int)_ms.size())
2695 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2696 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2697 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2698 return _ms[tracucedRk];
2701 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2703 if(-meshDimRelToMax>=(int)_ms.size())
2704 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
2706 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2708 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
2710 int ref=(*it)->getMeshDimension();
2711 if(ref+i!=meshDim-meshDimRelToMax)
2712 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
2718 * Sets the node coordinates array of \a this mesh.
2719 * \param [in] coords - the new node coordinates array.
2720 * \throw If \a coords == \c NULL.
2723 void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
2726 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
2727 coords->checkAllocated();
2728 int nbOfTuples=coords->getNumberOfTuples();
2731 _fam_coords=DataArrayInt::New();
2732 _fam_coords->alloc(nbOfTuples,1);
2733 _fam_coords->fillWithZero();
2737 * Removes all groups of a given dimension in \a this mesh.
2738 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2739 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2741 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2743 if(meshDimRelToMaxExt==1)
2745 if((DataArrayInt *)_fam_coords)
2746 _fam_coords->fillWithZero();
2749 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2750 l1->eraseFamilyField();
2755 * Removes all families with ids not present in the family fields of \a this mesh.
2757 void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
2759 std::vector<int> levs=getNonEmptyLevelsExt();
2760 std::set<int> allFamsIds;
2761 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2763 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
2764 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
2766 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
2769 std::set<std::string> famNamesToKill;
2770 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2772 if(allFamsIds.find((*it).second)!=allFamsIds.end())
2773 famNamesToKill.insert((*it).first);
2775 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
2776 _families.erase(*it);
2777 std::vector<std::string> grpNamesToKill;
2778 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
2780 std::vector<std::string> tmp;
2781 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
2783 if(famNamesToKill.find(*it2)==famNamesToKill.end())
2784 tmp.push_back(*it2);
2789 tmp.push_back((*it).first);
2791 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
2795 void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception)
2797 std::vector<int> levs=getNonEmptyLevels();
2798 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
2799 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
2800 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
2801 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
2802 int nbNodes=m0->getNumberOfNodes();
2803 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
2804 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
2805 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
2806 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
2807 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
2808 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
2809 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
2810 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
2811 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
2812 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
2813 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
2814 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
2815 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
2816 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
2817 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
2818 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
2819 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
2820 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
2821 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
2822 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
2823 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
2824 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
2825 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
2826 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
2827 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
2828 m0->setCoords(tmp0->getCoords());
2829 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
2830 m1->setCoords(m0->getCoords());
2831 _coords=m0->getCoords(); _coords->incrRef();
2832 // duplication of cells in group 'grpNameM1' on level -1
2833 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
2834 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
2835 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
2836 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
2837 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
2839 newm1->setName(getName());
2840 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
2842 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
2843 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
2844 newFam->alloc(newm1->getNumberOfCells(),1);
2845 int idd=getMaxFamilyId()+1;
2846 int globStart=0,start=0,end,globEnd;
2847 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
2848 for(int i=0;i<nbOfChunks;i++)
2850 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
2851 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
2853 end=start+szOfCellGrpOfSameType->getIJ(i,0);
2854 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
2855 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
2860 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
2864 newm1->setCoords(getCoords());
2865 setMeshAtLevel(-1,newm1);
2866 setFamilyFieldArr(-1,newFam);
2867 std::string grpName2(grpNameM1); grpName2+="_dup";
2868 addFamily(grpName2.c_str(),idd);
2869 addFamilyOnGrp(grpName2.c_str(),grpName2.c_str());
2874 int newNbOfNodes=getCoords()->getNumberOfTuples();
2875 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
2876 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
2877 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
2880 nodesDuplicated=nodeIdsToDuplicate.retn();
2881 cellsModified=cellsToModifyConn0.retn();
2882 cellsNotModified=cellsToModifyConn1.retn();
2886 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
2887 * \param [out] newCode etrieves the distribution of types after the call if true is returned
2888 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
2890 * \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.
2891 * 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.
2893 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
2895 o2nRenumCell=0; oldCode.clear(); newCode.clear();
2896 std::vector<int> levs=getNonEmptyLevels();
2898 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
2899 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
2902 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
2904 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
2905 std::vector<int> code1=m->getDistributionOfTypes();
2906 end=PutInThirdComponentOfCodeOffset(code1,start);
2907 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
2908 bool hasChanged=m->unPolyze();
2909 DataArrayInt *fake=0;
2910 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
2911 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
2913 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
2916 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
2917 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
2919 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
2920 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
2921 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
2922 setMeshAtLevel(*it,m);
2923 std::vector<int> code2=m->getDistributionOfTypes();
2924 end=PutInThirdComponentOfCodeOffset(code2,start);
2925 newCode.insert(newCode.end(),code2.begin(),code2.end());
2927 if(o2nCellsPart2->isIdentity())
2931 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
2932 setFamilyFieldArr(*it,newFamField);
2936 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
2937 setRenumFieldArr(*it,newNumField);
2942 newCode.insert(newCode.end(),code1.begin(),code1.end());
2948 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
2949 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
2950 o2nRenumCell=o2nRenumCellRet.retn();
2955 struct MEDLoaderAccVisit1
2957 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
2958 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
2959 int _new_nb_of_nodes;
2963 * 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.
2964 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
2965 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
2966 * -1 values in returned array means that the corresponding old node is no more used.
2968 * \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
2969 * is modified in \a this.
2970 * \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
2973 DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
2975 const DataArrayDouble *coo=getCoords();
2977 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
2978 int nbOfNodes=coo->getNumberOfTuples();
2979 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
2980 std::vector<int> neLevs=getNonEmptyLevels();
2981 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
2983 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
2984 m->computeNodeIdsAlg(nodeIdsInUse);
2986 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
2987 if(nbrOfNodesInUse==nbOfNodes)
2989 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
2990 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
2991 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
2992 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
2993 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
2994 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
2995 if((const DataArrayInt *)_fam_coords)
2996 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
2997 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
2998 if((const DataArrayInt *)_num_coords)
2999 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3000 if((const DataArrayAsciiChar *)_name_coords)
3001 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3002 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3003 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3005 if((MEDFileUMeshSplitL1*)*it)
3006 (*it)->renumberNodesInConn(ret->begin());
3012 * Adds a group of nodes to \a this mesh.
3013 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3014 * The ids should be sorted and different each other (MED file norm).
3015 * \throw If the node coordinates array is not set.
3016 * \throw If \a ids == \c NULL.
3017 * \throw If \a ids->getName() == "".
3018 * \throw If \a ids does not respect the MED file norm.
3019 * \throw If a group with name \a ids->getName() already exists.
3021 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3023 const DataArrayDouble *coords=_coords;
3025 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3026 int nbOfNodes=coords->getNumberOfTuples();
3027 if(!((DataArrayInt *)_fam_coords))
3028 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3030 addGroupUnderground(ids,_fam_coords);
3033 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3035 std::vector<int> levs=getNonEmptyLevelsExt();
3036 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3038 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3039 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3041 if(meshDimRelToMaxExt==1)
3042 { addNodeGroup(ids); return ; }
3043 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3044 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3045 addGroupUnderground(ids,fam);
3049 * \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).
3050 * \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)
3052 void MEDFileUMesh::addGroupUnderground(const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3055 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3056 std::string grpName(ids->getName());
3058 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3059 ids->checkStrictlyMonotonic(true);
3060 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3061 std::vector<std::string> grpsNames=getGroupsNames();
3062 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3064 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3065 throw INTERP_KERNEL::Exception(oss.str().c_str());
3067 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3068 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3069 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3070 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3071 std::vector<int> familyIds;
3072 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3073 int maxVal=getTheMaxFamilyId()+1;
3074 std::map<std::string,int> families(_families);
3075 std::map<std::string, std::vector<std::string> > groups(_groups);
3076 std::vector<std::string> fams;
3077 bool created(false);
3078 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3080 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3081 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3082 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3083 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3086 bool isFamPresent=false;
3087 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3088 isFamPresent=(*itl)->presenceOfValue(*famId);
3090 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3093 familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ids2); std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,maxVal,created);
3094 fams.push_back(locFamName);
3095 if(existsFamily(*famId))
3097 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3098 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3101 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3105 familyIds.push_back(maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3106 familyIds.push_back(maxVal+1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3107 std::string n2(FindOrCreateAndGiveFamilyWithId(families,maxVal+1,created)); fams.push_back(n2);
3108 if(existsFamily(*famId))
3110 std::string n1(FindOrCreateAndGiveFamilyWithId(families,maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3111 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3116 for(std::size_t i=0;i<familyIds.size();i++)
3118 DataArrayInt *da=idsPerfamiliyIds[i];
3119 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3123 _groups[grpName]=fams;
3127 * Changes a name of a family specified by its id.
3128 * \param [in] id - the id of the family of interest.
3129 * \param [in] newFamName - the new family name.
3130 * \throw If no family with the given \a id exists.
3132 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
3134 std::string oldName=getFamilyNameGivenId(id);
3135 _families.erase(oldName);
3136 _families[newFamName]=id;
3140 * Removes a mesh of a given dimension.
3141 * \param [in] meshDimRelToMax - the relative dimension of interest.
3142 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3144 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
3146 std::vector<int> levSet=getNonEmptyLevels();
3147 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3148 if(it==levSet.end())
3149 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3150 int pos=(-meshDimRelToMax);
3155 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3156 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3157 * \param [in] m - the new mesh to set.
3158 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3159 * writing \a this mesh in a MED file.
3160 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3162 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3163 * another node coordinates array.
3164 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3165 * to the existing meshes of other levels of \a this mesh.
3167 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
3169 dealWithTinyInfo(m);
3170 std::vector<int> levSet=getNonEmptyLevels();
3171 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3173 if((DataArrayDouble *)_coords==0)
3175 DataArrayDouble *c=m->getCoords();
3180 if(m->getCoords()!=_coords)
3181 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3182 int sz=(-meshDimRelToMax)+1;
3183 if(sz>=(int)_ms.size())
3185 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3186 _ms[sz-1]=new MEDFileUMeshSplitL1(m,newOrOld);
3189 _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld);
3193 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3194 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3195 * The given meshes must share the same node coordinates array.
3196 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3197 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3198 * create in \a this mesh.
3199 * \throw If \a ms is empty.
3200 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3201 * to the existing meshes of other levels of \a this mesh.
3202 * \throw If the meshes in \a ms do not share the same node coordinates array.
3203 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3204 * of the given meshes.
3205 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3206 * \throw If names of some meshes in \a ms are equal.
3207 * \throw If \a ms includes a mesh with an empty name.
3209 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms) throw(INTERP_KERNEL::Exception)
3212 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3213 int sz=(-meshDimRelToMax)+1;
3214 if(sz>=(int)_ms.size())
3216 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3217 DataArrayDouble *coo=checkMultiMesh(ms);
3218 if((DataArrayDouble *)_coords==0)
3224 if((DataArrayDouble *)_coords!=coo)
3225 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3226 std::vector<DataArrayInt *> corr;
3227 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3228 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3229 setMeshAtLevel(meshDimRelToMax,m);
3230 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3231 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3235 * Creates groups at a given level in \a this mesh from a sequence of
3236 * meshes each representing a group.
3237 * The given meshes must share the same node coordinates array.
3238 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3239 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3240 * create in \a this mesh.
3241 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3243 * \throw If \a ms is empty.
3244 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3245 * to the existing meshes of other levels of \a this mesh.
3246 * \throw If the meshes in \a ms do not share the same node coordinates array.
3247 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3248 * of the given meshes.
3249 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3250 * \throw If names of some meshes in \a ms are equal.
3251 * \throw If \a ms includes a mesh with an empty name.
3253 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3256 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3257 int sz=(-meshDimRelToMax)+1;
3258 if(sz>=(int)_ms.size())
3260 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3261 DataArrayDouble *coo=checkMultiMesh(ms);
3262 if((DataArrayDouble *)_coords==0)
3268 if((DataArrayDouble *)_coords!=coo)
3269 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3270 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3271 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3273 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3275 DataArrayInt *arr=0;
3276 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3280 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3281 throw INTERP_KERNEL::Exception(oss.str().c_str());
3284 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3285 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3288 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const throw(INTERP_KERNEL::Exception)
3290 const DataArrayDouble *ret=ms[0]->getCoords();
3291 int mdim=ms[0]->getMeshDimension();
3292 for(unsigned int i=1;i<ms.size();i++)
3294 ms[i]->checkCoherency();
3295 if(ms[i]->getCoords()!=ret)
3296 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3297 if(ms[i]->getMeshDimension()!=mdim)
3298 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3300 return const_cast<DataArrayDouble *>(ret);
3304 * Sets the family field of a given relative dimension.
3305 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3306 * the family field is set.
3307 * \param [in] famArr - the array of the family field.
3308 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3309 * \throw If \a famArr has an invalid size.
3311 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3313 if(meshDimRelToMaxExt==1)
3320 DataArrayDouble *coo(_coords);
3322 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3323 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3328 if(meshDimRelToMaxExt>1)
3329 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3330 int traducedRk=-meshDimRelToMaxExt;
3331 if(traducedRk>=(int)_ms.size())
3332 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3333 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3334 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3335 return _ms[traducedRk]->setFamilyArr(famArr);
3339 * Sets the optional numbers of mesh entities of a given dimension.
3340 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3341 * \param [in] renumArr - the array of the numbers.
3342 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3343 * \throw If \a renumArr has an invalid size.
3345 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
3347 if(meshDimRelToMaxExt==1)
3355 DataArrayDouble *coo(_coords);
3357 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3358 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3359 renumArr->incrRef();
3360 _num_coords=renumArr;
3364 if(meshDimRelToMaxExt>1)
3365 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3366 int traducedRk=-meshDimRelToMaxExt;
3367 if(traducedRk>=(int)_ms.size())
3368 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3369 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3370 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3371 return _ms[traducedRk]->setRenumArr(renumArr);
3374 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
3376 if(meshDimRelToMaxExt==1)
3383 DataArrayDouble *coo(_coords);
3385 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3386 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3388 _name_coords=nameArr;
3391 if(meshDimRelToMaxExt>1)
3392 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3393 int traducedRk=-meshDimRelToMaxExt;
3394 if(traducedRk>=(int)_ms.size())
3395 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3396 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3397 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3398 return _ms[traducedRk]->setNameArr(nameArr);
3401 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3403 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3404 if((const MEDFileUMeshSplitL1 *)(*it))
3405 (*it)->synchronizeTinyInfo(*this);
3409 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3411 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
3413 DataArrayInt *arr=_fam_coords;
3415 arr->changeValue(oldId,newId);
3416 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3418 MEDFileUMeshSplitL1 *sp=(*it);
3421 sp->changeFamilyIdArr(oldId,newId);
3426 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3428 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3429 const DataArrayInt *da(_fam_coords);
3431 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3432 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3434 const MEDFileUMeshSplitL1 *elt(*it);
3437 da=elt->getFamilyField();
3439 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3445 void MEDFileUMesh::computeRevNum() const
3447 if((const DataArrayInt *)_num_coords)
3450 int maxValue=_num_coords->getMaxValue(pos);
3451 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3455 std::size_t MEDFileStructuredMesh::getHeapMemorySize() const
3457 std::size_t ret=MEDFileMesh::getHeapMemorySize();
3458 if((const DataArrayInt*)_fam_nodes)
3459 ret+=_fam_nodes->getHeapMemorySize();
3460 if((const DataArrayInt*)_num_nodes)
3461 ret+=_num_nodes->getHeapMemorySize();
3462 if((const DataArrayInt*)_fam_cells)
3463 ret+=_fam_cells->getHeapMemorySize();
3464 if((const DataArrayInt*)_num_cells)
3465 ret+=_num_cells->getHeapMemorySize();
3466 if((const DataArrayInt*)_rev_num_nodes)
3467 ret+=_rev_num_nodes->getHeapMemorySize();
3468 if((const DataArrayInt*)_rev_num_cells)
3469 ret+=_rev_num_cells->getHeapMemorySize();
3473 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3475 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3476 if((const DataArrayInt *)_fam_nodes)
3478 int val=_fam_nodes->getMaxValue(tmp);
3479 ret=std::max(ret,val);
3481 if((const DataArrayInt *)_fam_cells)
3483 int val=_fam_cells->getMaxValue(tmp);
3484 ret=std::max(ret,val);
3489 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3491 int ret=std::numeric_limits<int>::max(),tmp=-1;
3492 if((const DataArrayInt *)_fam_nodes)
3494 int val=_fam_nodes->getMinValue(tmp);
3495 ret=std::min(ret,val);
3497 if((const DataArrayInt *)_fam_cells)
3499 int val=_fam_cells->getMinValue(tmp);
3500 ret=std::min(ret,val);
3505 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3507 if(!MEDFileMesh::isEqual(other,eps,what))
3509 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
3512 what="Mesh types differ ! This is structured and other is NOT !";
3515 const DataArrayInt *famc1=_fam_nodes;
3516 const DataArrayInt *famc2=otherC->_fam_nodes;
3517 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3519 what="Mismatch of families arr on nodes ! One is defined and not other !";
3524 bool ret=famc1->isEqual(*famc2);
3527 what="Families arr on nodes differ !";
3532 famc2=otherC->_fam_cells;
3533 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3535 what="Mismatch of families arr on cells ! One is defined and not other !";
3540 bool ret=famc1->isEqual(*famc2);
3543 what="Families arr on cells differ !";
3548 famc2=otherC->_num_nodes;
3549 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3551 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
3556 bool ret=famc1->isEqual(*famc2);
3559 what="Numbering arr on nodes differ !";
3564 famc2=otherC->_num_cells;
3565 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3567 what="Mismatch of numbering arr on cells ! One is defined and not other !";
3572 bool ret=famc1->isEqual(*famc2);
3575 what="Numbering arr on cells differ !";
3579 const DataArrayAsciiChar *d1=_names_cells;
3580 const DataArrayAsciiChar *d2=otherC->_names_cells;
3581 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3583 what="Mismatch of naming arr on cells ! One is defined and not other !";
3588 bool ret=d1->isEqual(*d2);
3591 what="Naming arr on cells differ !";
3596 d2=otherC->_names_nodes;
3597 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3599 what="Mismatch of naming arr on nodes ! One is defined and not other !";
3604 bool ret=d1->isEqual(*d2);
3607 what="Naming arr on nodes differ !";
3614 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
3616 MEDFileMesh::clearNonDiscrAttributes();
3617 const DataArrayInt *tmp=_fam_nodes;
3619 (const_cast<DataArrayInt *>(tmp))->setName("");
3622 (const_cast<DataArrayInt *>(tmp))->setName("");
3625 (const_cast<DataArrayInt *>(tmp))->setName("");
3628 (const_cast<DataArrayInt *>(tmp))->setName("");
3632 * Returns ids of mesh entities contained in given families of a given dimension.
3633 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3635 * \param [in] fams - the names of the families of interest.
3636 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3637 * returned instead of ids.
3638 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3639 * numbers, if available and required, of mesh entities of the families. The caller
3640 * is to delete this array using decrRef() as it is no more needed.
3641 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3643 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
3645 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3646 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
3647 std::vector<int> famIds=getFamiliesIds(fams);
3648 if(meshDimRelToMaxExt==1)
3650 if((const DataArrayInt *)_fam_nodes)
3652 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3654 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3656 da=_fam_nodes->getIdsEqualList(0,0);
3658 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
3663 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
3667 if((const DataArrayInt *)_fam_cells)
3669 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3671 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3673 da=_fam_cells->getIdsEqualList(0,0);
3675 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
3680 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
3685 * Sets the family field of a given relative dimension.
3686 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3687 * the family field is set.
3688 * \param [in] famArr - the array of the family field.
3689 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3690 * \throw If \a famArr has an invalid size.
3691 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
3693 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3695 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3696 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
3697 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
3699 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
3700 if(meshDimRelToMaxExt==0)
3702 int nbCells=mesh->getNumberOfCells();
3703 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
3708 int nbNodes=mesh->getNumberOfNodes();
3709 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
3717 * Sets the optional numbers of mesh entities of a given dimension.
3718 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3719 * \param [in] renumArr - the array of the numbers.
3720 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3721 * \throw If \a renumArr has an invalid size.
3722 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
3724 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
3726 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3727 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
3728 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
3730 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
3731 if(meshDimRelToMaxExt==0)
3733 int nbCells=mesh->getNumberOfCells();
3734 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
3735 _num_cells=renumArr;
3739 int nbNodes=mesh->getNumberOfNodes();
3740 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
3741 _num_nodes=renumArr;
3744 renumArr->incrRef();
3747 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
3749 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3750 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
3751 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
3753 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
3754 if(meshDimRelToMaxExt==0)
3756 int nbCells=mesh->getNumberOfCells();
3757 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
3758 _names_cells=nameArr;
3762 int nbNodes=mesh->getNumberOfNodes();
3763 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
3764 _names_nodes=nameArr;
3771 * Returns the family field for mesh entities of a given dimension.
3772 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3773 * \return const DataArrayInt * - the family field. It is an array of ids of families
3774 * each mesh entity belongs to. It can be \c NULL.
3775 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
3777 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3779 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3780 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
3781 if(meshDimRelToMaxExt==0)
3788 * Returns the optional numbers of mesh entities of a given dimension.
3789 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3790 * \return const DataArrayInt * - the array of the entity numbers.
3791 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3792 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
3794 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3796 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3797 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
3798 if(meshDimRelToMaxExt==0)
3805 * Returns the optional numbers of mesh entities of a given dimension transformed using
3806 * DataArrayInt::invertArrayN2O2O2N().
3807 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3808 * \return const DataArrayInt * - the array of the entity numbers transformed using
3809 * DataArrayInt::invertArrayN2O2O2N().
3810 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
3811 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3813 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3815 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3816 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
3817 if(meshDimRelToMaxExt==0)
3819 if((const DataArrayInt *)_num_cells)
3822 int maxValue=_num_cells->getMaxValue(pos);
3823 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
3824 return _rev_num_cells;
3827 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
3831 if((const DataArrayInt *)_num_nodes)
3834 int maxValue=_num_nodes->getMaxValue(pos);
3835 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
3836 return _rev_num_nodes;
3839 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
3843 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3845 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3846 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
3847 if(meshDimRelToMaxExt==0)
3848 return _names_cells;
3850 return _names_nodes;
3854 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
3855 * \return std::vector<int> - a sequence of the relative dimensions: [0].
3857 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
3859 std::vector<int> ret(1);
3864 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
3865 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
3867 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
3869 std::vector<int> ret(2);
3875 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
3877 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
3879 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
3883 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
3885 DataArrayInt *arr=_fam_nodes;
3887 arr->changeValue(oldId,newId);
3890 arr->changeValue(oldId,newId);
3893 void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
3895 if((const DataArrayInt*)_fam_nodes)
3896 _fam_nodes=_fam_nodes->deepCpy();
3897 if((const DataArrayInt*)_num_nodes)
3898 _num_nodes=_num_nodes->deepCpy();
3899 if((const DataArrayInt*)_fam_cells)
3900 _fam_cells=_fam_cells->deepCpy();
3901 if((const DataArrayInt*)_num_cells)
3902 _num_cells=_num_cells->deepCpy();
3903 if((const DataArrayInt*)_rev_num_nodes)
3904 _rev_num_nodes=_rev_num_nodes->deepCpy();
3905 if((const DataArrayInt*)_rev_num_cells)
3906 _rev_num_cells=_rev_num_cells->deepCpy();
3910 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
3912 * \return a pointer to cartesian mesh that need to be managed by the caller.
3913 * \warning the returned pointer has to be managed by the caller.
3917 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
3918 * \param [in] meshDimRelToMax - it must be \c 0.
3919 * \param [in] renum - it must be \c false.
3920 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
3921 * delete using decrRef() as it is no more needed.
3923 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
3926 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
3927 if(meshDimRelToMax!=0)
3928 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
3929 const MEDCouplingStructuredMesh *m=getStructuredMesh();
3932 return const_cast<MEDCouplingStructuredMesh *>(m);
3936 * Returns number of mesh entities of a given relative dimension in \a this mesh.
3937 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3938 * \return int - the number of entities.
3939 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
3941 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
3943 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
3944 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
3945 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
3947 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
3948 if(meshDimRelToMaxExt==0)
3949 return cmesh->getNumberOfCells();
3951 return cmesh->getNumberOfNodes();
3954 int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
3956 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
3958 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
3959 return cmesh->getNumberOfNodes();
3962 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
3964 med_geometry_type geoTypeReq=MED_NONE;
3968 geoTypeReq=MED_HEXA8;
3971 geoTypeReq=MED_QUAD4;
3974 geoTypeReq=MED_SEG2;
3977 geoTypeReq=MED_POINT1;
3980 throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
3985 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
3987 setName(strm->getName());
3988 setDescription(strm->getDescription());
3989 setUnivName(strm->getUnivName());
3990 setIteration(strm->getIteration());
3991 setOrder(strm->getOrder());
3992 setTimeValue(strm->getTime());
3993 setTimeUnit(strm->getTimeUnit());
3994 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups);
3995 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
3996 int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
3999 _fam_nodes=DataArrayInt::New();
4000 _fam_nodes->alloc(nbOfElt,1);
4001 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4003 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4006 _num_nodes=DataArrayInt::New();
4007 _num_nodes->alloc(nbOfElt,1);
4008 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4010 int meshDim=getStructuredMesh()->getMeshDimension();
4011 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4012 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4015 _fam_cells=DataArrayInt::New();
4016 _fam_cells->alloc(nbOfElt,1);
4017 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
4019 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4022 _num_cells=DataArrayInt::New();
4023 _num_cells->alloc(nbOfElt,1);
4024 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
4026 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4029 _names_cells=DataArrayAsciiChar::New();
4030 _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4031 MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
4032 _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4034 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4037 _names_nodes=DataArrayAsciiChar::New();
4038 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4039 MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4040 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4044 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
4046 int meshDim=getStructuredMesh()->getMeshDimension();
4047 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4049 if((const DataArrayInt *)_fam_cells)
4050 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4051 if((const DataArrayInt *)_fam_nodes)
4052 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4053 if((const DataArrayInt *)_num_cells)
4054 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4055 if((const DataArrayInt *)_num_nodes)
4056 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4057 if((const DataArrayAsciiChar *)_names_cells)
4059 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4061 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4062 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4063 throw INTERP_KERNEL::Exception(oss.str().c_str());
4065 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4067 if((const DataArrayAsciiChar *)_names_nodes)
4069 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4071 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4072 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4073 throw INTERP_KERNEL::Exception(oss.str().c_str());
4075 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4078 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
4082 * Returns an empty instance of MEDFileCMesh.
4083 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4084 * mesh using decrRef() as it is no more needed.
4086 MEDFileCMesh *MEDFileCMesh::New()
4088 return new MEDFileCMesh;
4092 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4093 * file. The first mesh in the file is loaded.
4094 * \param [in] fileName - the name of MED file to read.
4095 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4096 * mesh using decrRef() as it is no more needed.
4097 * \throw If the file is not readable.
4098 * \throw If there is no meshes in the file.
4099 * \throw If the mesh in the file is not a Cartesian one.
4101 MEDFileCMesh *MEDFileCMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
4103 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4106 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4107 throw INTERP_KERNEL::Exception(oss.str().c_str());
4109 MEDFileUtilities::CheckFileForRead(fileName);
4110 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4112 ParaMEDMEM::MEDCouplingMeshType meshType;
4114 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4115 return new MEDFileCMesh(fid,ms.front().c_str(),dt,it);
4119 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4120 * file. The mesh to load is specified by its name and numbers of a time step and an
4122 * \param [in] fileName - the name of MED file to read.
4123 * \param [in] mName - the name of the mesh to read.
4124 * \param [in] dt - the number of a time step.
4125 * \param [in] it - the number of an iteration.
4126 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4127 * mesh using decrRef() as it is no more needed.
4128 * \throw If the file is not readable.
4129 * \throw If there is no mesh with given attributes in the file.
4130 * \throw If the mesh in the file is not a Cartesian one.
4132 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
4134 MEDFileUtilities::CheckFileForRead(fileName);
4135 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4136 return new MEDFileCMesh(fid,mName,dt,it);
4139 std::size_t MEDFileCMesh::getHeapMemorySize() const
4141 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4142 if((const MEDCouplingCMesh *)_cmesh)
4143 ret+=_cmesh->getHeapMemorySize();
4148 * Returns the dimension on cells in \a this mesh.
4149 * \return int - the mesh dimension.
4150 * \throw If there are no cells in this mesh.
4152 int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4154 if(!((const MEDCouplingCMesh*)_cmesh))
4155 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4156 return _cmesh->getMeshDimension();
4160 * Returns a string describing \a this mesh.
4161 * \return std::string - the mesh information string.
4163 std::string MEDFileCMesh::simpleRepr() const
4165 return MEDFileStructuredMesh::simpleRepr();
4169 * Returns a full textual description of \a this mesh.
4170 * \return std::string - the string holding the mesh description.
4172 std::string MEDFileCMesh::advancedRepr() const
4174 return simpleRepr();
4177 MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4179 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4183 MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4185 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4186 if((const MEDCouplingCMesh*)_cmesh)
4187 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
4188 ret->deepCpyAttributes();
4193 * Checks if \a this and another mesh are equal.
4194 * \param [in] other - the mesh to compare with.
4195 * \param [in] eps - a precision used to compare real values.
4196 * \param [in,out] what - the string returning description of unequal data.
4197 * \return bool - \c true if the meshes are equal, \c false, else.
4199 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4201 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4203 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
4206 what="Mesh types differ ! This is cartesian and other is NOT !";
4209 clearNonDiscrAttributes();
4210 otherC->clearNonDiscrAttributes();
4211 const MEDCouplingCMesh *coo1=_cmesh;
4212 const MEDCouplingCMesh *coo2=otherC->_cmesh;
4213 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4215 what="Mismatch of cartesian meshes ! One is defined and not other !";
4220 bool ret=coo1->isEqual(coo2,eps);
4223 what="cartesian meshes differ !";
4231 * Clears redundant attributes of incorporated data arrays.
4233 void MEDFileCMesh::clearNonDiscrAttributes() const
4235 MEDFileStructuredMesh::clearNonDiscrAttributes();
4236 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
4239 MEDFileCMesh::MEDFileCMesh()
4243 MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
4246 loadCMeshFromFile(fid,mName,dt,it);
4248 catch(INTERP_KERNEL::Exception& e)
4253 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
4255 ParaMEDMEM::MEDCouplingMeshType meshType;
4258 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4259 if(meshType!=CARTESIAN)
4261 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
4262 throw INTERP_KERNEL::Exception(oss.str().c_str());
4264 MEDFileCMeshL2 loaderl2;
4265 loaderl2.loadAll(fid,mid,mName,dt,it);
4266 MEDCouplingCMesh *mesh=loaderl2.getMesh();
4269 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it);
4273 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
4274 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
4276 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
4278 synchronizeTinyInfoOnLeaves();
4282 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
4284 synchronizeTinyInfoOnLeaves();
4289 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
4290 * \param [in] m - the new MEDCouplingCMesh to refer to.
4291 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4294 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
4296 dealWithTinyInfo(m);
4302 void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4304 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4305 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4306 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4307 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4308 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4309 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4310 int spaceDim=_cmesh->getSpaceDimension();
4311 int meshDim=_cmesh->getMeshDimension();
4312 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4313 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4314 for(int i=0;i<spaceDim;i++)
4316 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
4318 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4319 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
4320 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
4322 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4323 MEDmeshUniversalNameWr(fid,maa);
4324 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
4325 for(int i=0;i<spaceDim;i++)
4327 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
4328 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
4331 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4334 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
4336 const MEDCouplingCMesh *cmesh=_cmesh;
4339 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
4340 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
4341 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
4342 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
4345 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
4347 return new MEDFileCurveLinearMesh;
4350 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName) throw(INTERP_KERNEL::Exception)
4352 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4355 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4356 throw INTERP_KERNEL::Exception(oss.str().c_str());
4358 MEDFileUtilities::CheckFileForRead(fileName);
4359 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4361 ParaMEDMEM::MEDCouplingMeshType meshType;
4363 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4364 return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it);
4367 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
4369 MEDFileUtilities::CheckFileForRead(fileName);
4370 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4371 return new MEDFileCurveLinearMesh(fid,mName,dt,it);
4374 std::size_t MEDFileCurveLinearMesh::getHeapMemorySize() const
4376 std::size_t ret=MEDFileStructuredMesh::getHeapMemorySize();
4377 if((const MEDCouplingCurveLinearMesh *)_clmesh)
4378 ret+=_clmesh->getHeapMemorySize();
4382 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4384 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4388 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4390 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4391 if((const MEDCouplingCurveLinearMesh*)_clmesh)
4392 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
4393 ret->deepCpyAttributes();
4397 int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4399 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
4400 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4401 return _clmesh->getMeshDimension();
4404 std::string MEDFileCurveLinearMesh::simpleRepr() const
4406 return MEDFileStructuredMesh::simpleRepr();
4409 std::string MEDFileCurveLinearMesh::advancedRepr() const
4411 return simpleRepr();
4414 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4416 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4418 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
4421 what="Mesh types differ ! This is curve linear and other is NOT !";
4424 clearNonDiscrAttributes();
4425 otherC->clearNonDiscrAttributes();
4426 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
4427 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
4428 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4430 what="Mismatch of curve linear meshes ! One is defined and not other !";
4435 bool ret=coo1->isEqual(coo2,eps);
4438 what="curve linear meshes differ !";
4445 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
4447 MEDFileStructuredMesh::clearNonDiscrAttributes();
4448 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
4451 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
4453 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
4456 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
4457 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
4458 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
4459 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
4462 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
4464 synchronizeTinyInfoOnLeaves();
4468 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
4470 dealWithTinyInfo(m);
4476 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
4478 synchronizeTinyInfoOnLeaves();
4482 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
4486 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
4489 loadCLMeshFromFile(fid,mName,dt,it);
4491 catch(INTERP_KERNEL::Exception& e)
4496 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4498 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4499 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4500 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4501 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4502 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4503 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4504 int spaceDim=_clmesh->getSpaceDimension();
4505 int meshDim=_clmesh->getMeshDimension();
4506 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4507 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4508 const DataArrayDouble *coords=_clmesh->getCoords();
4510 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
4511 for(int i=0;i<spaceDim;i++)
4513 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
4515 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4516 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
4517 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
4519 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4520 MEDmeshUniversalNameWr(fid,maa);
4521 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
4522 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
4523 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
4525 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
4527 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4530 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it) throw(INTERP_KERNEL::Exception)
4532 ParaMEDMEM::MEDCouplingMeshType meshType;
4535 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4536 if(meshType!=CURVE_LINEAR)
4538 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
4539 throw INTERP_KERNEL::Exception(oss.str().c_str());
4541 MEDFileCLMeshL2 loaderl2;
4542 loaderl2.loadAll(fid,mid,mName,dt,it);
4543 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
4546 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it);
4549 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
4551 return new MEDFileMeshMultiTS;
4554 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
4556 return new MEDFileMeshMultiTS(fileName);
4559 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
4561 return new MEDFileMeshMultiTS(fileName,mName);
4564 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
4566 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
4567 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
4569 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
4570 if((const MEDFileMesh *)*it)
4571 meshOneTs[i]=(*it)->deepCpy();
4572 ret->_mesh_one_ts=meshOneTs;
4576 std::size_t MEDFileMeshMultiTS::getHeapMemorySize() const
4578 std::size_t ret=_mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
4579 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
4580 ret+=(*it)->getHeapMemorySize();
4584 const char *MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
4586 if(_mesh_one_ts.empty())
4587 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
4588 return _mesh_one_ts[0]->getName();
4591 void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::Exception)
4593 std::string oldName(getName());
4594 std::vector< std::pair<std::string,std::string> > v(1);
4595 v[0].first=oldName; v[0].second=newMeshName;
4599 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
4602 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
4604 MEDFileMesh *cur(*it);
4606 ret=cur->changeNames(modifTab) || ret;
4611 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception)
4613 if(_mesh_one_ts.empty())
4614 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
4615 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
4618 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception)
4621 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
4622 _mesh_one_ts.resize(1);
4623 mesh1TimeStep->incrRef();
4624 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
4625 _mesh_one_ts[0]=mesh1TimeStep;
4628 void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
4630 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
4632 (*it)->copyOptionsFrom(*this);
4637 void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
4639 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
4640 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
4641 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
4642 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
4646 void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
4647 {//for the moment to be improved
4648 _mesh_one_ts.resize(1);
4649 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
4652 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
4656 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception)
4659 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4662 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4663 throw INTERP_KERNEL::Exception(oss.str().c_str());
4665 MEDFileUtilities::CheckFileForRead(fileName);
4666 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4668 ParaMEDMEM::MEDCouplingMeshType meshType;
4670 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4671 loadFromFile(fileName,ms.front().c_str());
4673 catch(INTERP_KERNEL::Exception& e)
4678 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
4681 loadFromFile(fileName,mName);
4683 catch(INTERP_KERNEL::Exception& e)
4688 MEDFileMeshes *MEDFileMeshes::New()
4690 return new MEDFileMeshes;
4693 MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception)
4695 return new MEDFileMeshes(fileName);
4698 void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
4701 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
4703 (*it)->copyOptionsFrom(*this);
4708 void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
4710 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
4711 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
4712 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
4713 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
4718 int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception)
4720 return _meshes.size();
4723 MEDFileMeshesIterator *MEDFileMeshes::iterator() throw(INTERP_KERNEL::Exception)
4725 return new MEDFileMeshesIterator(this);
4728 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception)
4730 if(i<0 || i>=(int)_meshes.size())
4732 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
4733 throw INTERP_KERNEL::Exception(oss.str().c_str());
4735 return _meshes[i]->getOneTimeStep();
4738 MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTERP_KERNEL::Exception)
4740 std::vector<std::string> ms=getMeshesNames();
4741 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
4744 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
4745 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
4746 throw INTERP_KERNEL::Exception(oss.str().c_str());
4748 return getMeshAtPos((int)std::distance(ms.begin(),it));
4751 std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERNEL::Exception)
4753 std::vector<std::string> ret(_meshes.size());
4755 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
4757 const MEDFileMeshMultiTS *f=(*it);
4760 ret[i]=f->getName();
4764 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
4765 throw INTERP_KERNEL::Exception(oss.str().c_str());
4771 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
4774 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
4776 MEDFileMeshMultiTS *cur(*it);
4778 ret=cur->changeNames(modifTab) || ret;
4783 void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception)
4785 _meshes.resize(newSize);
4788 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
4791 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
4792 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
4793 elt->setOneTimeStep(mesh);
4794 _meshes.push_back(elt);
4797 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
4800 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
4801 if(i>=(int)_meshes.size())
4802 _meshes.resize(i+1);
4803 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
4804 elt->setOneTimeStep(mesh);
4808 void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
4810 if(i<0 || i>=(int)_meshes.size())
4812 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
4813 throw INTERP_KERNEL::Exception(oss.str().c_str());
4815 _meshes.erase(_meshes.begin()+i);
4818 void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception)
4820 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4822 _meshes.resize(ms.size());
4823 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4824 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str());
4827 MEDFileMeshes::MEDFileMeshes()
4831 MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception)
4834 loadFromFile(fileName);
4836 catch(INTERP_KERNEL::Exception& e)
4840 MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
4842 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
4844 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
4845 if((const MEDFileMeshMultiTS *)*it)
4846 meshes[i]=(*it)->deepCpy();
4847 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
4848 ret->_meshes=meshes;
4852 std::size_t MEDFileMeshes::getHeapMemorySize() const
4854 std::size_t ret=_meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
4855 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
4856 if((const MEDFileMeshMultiTS*)*it)
4857 ret+=(*it)->getHeapMemorySize();
4861 std::string MEDFileMeshes::simpleRepr() const
4863 std::ostringstream oss;
4864 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
4865 simpleReprWithoutHeader(oss);
4869 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
4871 int nbOfMeshes=getNumberOfMeshes();
4872 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
4873 std::vector<std::string> mns=getMeshesNames();
4874 for(int i=0;i<nbOfMeshes;i++)
4875 oss << " - #" << i << " \"" << mns[i] << "\"\n";
4878 void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception)
4880 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
4882 std::set<std::string> s;
4883 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
4885 const MEDFileMeshMultiTS *elt=(*it);
4888 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
4889 throw INTERP_KERNEL::Exception(oss.str().c_str());
4891 std::size_t sz=s.size();
4892 s.insert(std::string((*it)->getName()));
4895 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
4896 throw INTERP_KERNEL::Exception(oss.str().c_str());
4901 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
4906 _nb_iter=ms->getNumberOfMeshes();
4910 MEDFileMeshesIterator::~MEDFileMeshesIterator()
4914 MEDFileMesh *MEDFileMeshesIterator::nextt()
4916 if(_iter_id<_nb_iter)
4918 MEDFileMeshes *ms(_ms);
4920 return ms->getMeshAtPos(_iter_id++);