1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDFileMesh.hxx"
22 #include "MEDFileUtilities.hxx"
23 #include "MEDFileFieldOverView.hxx"
24 #include "MEDFileField.hxx"
25 #include "MEDLoader.hxx"
26 #include "MEDLoaderBase.hxx"
28 #include "MEDCouplingUMesh.hxx"
30 #include "InterpKernelAutoPtr.hxx"
35 using namespace ParaMEDMEM;
37 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
39 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
43 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
45 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
46 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
48 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
49 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
50 ret+=(*it2).capacity();
52 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
53 ret+=(*it).first.capacity()+sizeof(int);
57 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildren() const
59 return std::vector<const BigMemoryObject *>();
63 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
64 * file. The first mesh in the file is loaded.
65 * \param [in] fileName - the name of MED file to read.
66 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
67 * mesh using decrRef() as it is no more needed.
68 * \throw If the file is not readable.
69 * \throw If there is no meshes in the file.
70 * \throw If the mesh in the file is of a not supported type.
72 MEDFileMesh *MEDFileMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
74 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
77 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
78 throw INTERP_KERNEL::Exception(oss.str().c_str());
80 MEDFileUtilities::CheckFileForRead(fileName);
81 ParaMEDMEM::MEDCouplingMeshType meshType;
82 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
85 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
90 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
91 ret->loadUMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
92 return (MEDFileUMesh *)ret.retn();
96 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
97 ret->loadCMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
98 return (MEDFileCMesh *)ret.retn();
102 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
103 ret->loadCLMeshFromFile(fid,ms.front().c_str(),dt,it,mrs);
104 return (MEDFileCurveLinearMesh *)ret.retn();
108 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
109 throw INTERP_KERNEL::Exception(oss.str().c_str());
115 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
116 * file. The mesh to load is specified by its name and numbers of a time step and an
118 * \param [in] fileName - the name of MED file to read.
119 * \param [in] mName - the name of the mesh to read.
120 * \param [in] dt - the number of a time step.
121 * \param [in] it - the number of an iteration.
122 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
123 * mesh using decrRef() as it is no more needed.
124 * \throw If the file is not readable.
125 * \throw If there is no mesh with given attributes in the file.
126 * \throw If the mesh in the file is of a not supported type.
128 MEDFileMesh *MEDFileMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
130 MEDFileUtilities::CheckFileForRead(fileName);
131 ParaMEDMEM::MEDCouplingMeshType meshType;
132 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
135 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
140 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
141 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
142 return (MEDFileUMesh *)ret.retn();
146 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
147 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
148 return (MEDFileCMesh *)ret.retn();
152 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
153 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
154 return (MEDFileCurveLinearMesh *)ret.retn();
158 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
159 throw INTERP_KERNEL::Exception(oss.str().c_str());
165 * Writes \a this mesh into an open MED file specified by its descriptor.
166 * \param [in] fid - the MED file descriptor.
167 * \throw If the mesh name is not set.
168 * \throw If the file is open for reading only.
169 * \throw If the writing mode == 1 and the same data is present in an existing file.
171 void MEDFileMesh::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
174 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
176 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
181 * Writes \a this mesh into a MED file specified by its name.
182 * \param [in] fileName - the MED file name.
183 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
184 * - 2 - erase; an existing file is removed.
185 * - 1 - append; same data should not be present in an existing file.
186 * - 0 - overwrite; same data present in an existing file is overwritten.
187 * \throw If the mesh name is not set.
188 * \throw If \a mode == 1 and the same data is present in an existing file.
190 void MEDFileMesh::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
192 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
193 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
194 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
195 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
200 * Checks if \a this and another mesh are equal.
201 * \param [in] other - the mesh to compare with.
202 * \param [in] eps - a precision used to compare real values.
203 * \param [in,out] what - the string returning description of unequal data.
204 * \return bool - \c true if the meshes are equal, \c false, else.
206 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
208 if(_order!=other->_order)
210 what="Orders differ !";
213 if(_iteration!=other->_iteration)
215 what="Iterations differ !";
218 if(fabs(_time-other->_time)>eps)
220 what="Time values differ !";
223 if(_dt_unit!=other->_dt_unit)
225 what="Time units differ !";
228 if(_name!=other->_name)
230 what="Names differ !";
233 //univ_name has been ignored -> not a bug because it is a mutable attribute
234 if(_desc_name!=other->_desc_name)
236 what="Description names differ !";
239 if(!areGrpsEqual(other,what))
241 if(!areFamsEqual(other,what))
247 * Clears redundant attributes of incorporated data arrays.
249 void MEDFileMesh::clearNonDiscrAttributes() const
254 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
256 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
258 if((*it).first==_name)
268 * Copies data on groups and families from another mesh.
269 * \param [in] other - the mesh to copy the data from.
271 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
273 _groups=other._groups;
274 _families=other._families;
278 * Returns names of families constituting a group.
279 * \param [in] name - the name of the group of interest.
280 * \return std::vector<std::string> - a sequence of names of the families.
281 * \throw If the name of a nonexistent group is specified.
283 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
285 std::string oname(name);
286 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
287 if(it==_groups.end())
289 std::vector<std::string> grps=getGroupsNames();
290 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
291 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
292 throw INTERP_KERNEL::Exception(oss.str().c_str());
298 * Returns names of families constituting some groups.
299 * \param [in] grps - a sequence of names of groups of interest.
300 * \return std::vector<std::string> - a sequence of names of the families.
301 * \throw If a name of a nonexistent group is present in \a grps.
303 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
305 std::set<std::string> fams;
306 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
308 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
309 if(it2==_groups.end())
311 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
312 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
313 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
314 throw INTERP_KERNEL::Exception(oss.str().c_str());
316 fams.insert((*it2).second.begin(),(*it2).second.end());
318 std::vector<std::string> fams2(fams.begin(),fams.end());
323 * Returns ids of families constituting a group.
324 * \param [in] name - the name of the group of interest.
325 * \return std::vector<int> - sequence of ids of the families.
326 * \throw If the name of a nonexistent group is specified.
328 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const char *name) const throw(INTERP_KERNEL::Exception)
330 std::string oname(name);
331 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
332 std::vector<std::string> grps=getGroupsNames();
333 if(it==_groups.end())
335 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
336 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
337 throw INTERP_KERNEL::Exception(oss.str().c_str());
339 return getFamiliesIds((*it).second);
343 * Sets names of families constituting a group. If data on families of this group is
344 * already present, it is overwritten. Every family in \a fams is checked, and if a
345 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
346 * \param [in] name - the name of the group of interest.
347 * \param [in] fams - a sequence of names of families constituting the group.
349 void MEDFileMesh::setFamiliesOnGroup(const char *name, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception)
351 std::string oname(name);
353 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
355 std::map<std::string,int>::iterator it2=_families.find(*it1);
356 if(it2==_families.end())
362 * Sets families constituting a group. The families are specified by their ids.
363 * If a family name is not found by its id, an exception is thrown.
364 * If several families have same id, the first one in lexical order is taken.
365 * \param [in] name - the name of the group of interest.
366 * \param [in] famIds - a sequence of ids of families constituting the group.
367 * \throw If a family name is not found by its id.
369 void MEDFileMesh::setFamiliesIdsOnGroup(const char *name, const std::vector<int>& famIds) throw(INTERP_KERNEL::Exception)
371 std::string oname(name);
372 std::vector<std::string> fams(famIds.size());
374 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
376 std::string name2=getFamilyNameGivenId(*it1);
383 * Returns names of groups including a given family.
384 * \param [in] name - the name of the family of interest.
385 * \return std::vector<std::string> - a sequence of names of groups including the family.
387 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const char *name) const throw(INTERP_KERNEL::Exception)
389 std::vector<std::string> ret;
390 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
392 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
395 ret.push_back((*it1).first);
403 * Adds an existing family to groups.
404 * \param [in] famName - a name of family to add to \a grps.
405 * \param [in] grps - a sequence of group names to add the family in.
406 * \throw If a family named \a famName not yet exists.
408 void MEDFileMesh::setGroupsOnFamily(const char *famName, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception)
410 std::string fName(famName);
411 const std::map<std::string,int>::const_iterator it=_families.find(fName);
412 if(it==_families.end())
414 std::vector<std::string> fams=getFamiliesNames();
415 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
416 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
417 throw INTERP_KERNEL::Exception(oss.str().c_str());
419 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
421 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
422 if(it2!=_groups.end())
423 (*it2).second.push_back(fName);
426 std::vector<std::string> grps2(1,fName);
433 * Returns names of all groups of \a this mesh.
434 * \return std::vector<std::string> - a sequence of group names.
436 std::vector<std::string> MEDFileMesh::getGroupsNames() const
438 std::vector<std::string> ret(_groups.size());
440 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
446 * Returns names of all families of \a this mesh.
447 * \return std::vector<std::string> - a sequence of family names.
449 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
451 std::vector<std::string> ret(_families.size());
453 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
459 * Changes a name of every family, included in one group only, to be same as the group name.
460 * \throw If there are families with equal names in \a this mesh.
462 void MEDFileMesh::assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception)
464 std::map<std::string, std::vector<std::string> > groups(_groups);
465 std::map<std::string,int> newFams;
466 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
468 std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
469 if(grps.size()==1 && groups[grps[0]].size()==1)
471 if(newFams.find(grps[0])!=newFams.end())
473 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
474 throw INTERP_KERNEL::Exception(oss.str().c_str());
476 newFams[grps[0]]=(*it).second;
477 std::vector<std::string>& grps2=groups[grps[0]];
478 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
483 if(newFams.find((*it).first)!=newFams.end())
485 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
486 throw INTERP_KERNEL::Exception(oss.str().c_str());
488 newFams[(*it).first]=(*it).second;
496 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
498 * \return the removed groups.
500 std::vector<std::string> MEDFileMesh::removeEmptyGroups() throw(INTERP_KERNEL::Exception)
502 std::vector<std::string> ret;
503 std::map<std::string, std::vector<std::string> > newGrps;
504 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
506 if((*it).second.empty())
507 ret.push_back((*it).first);
509 newGrps[(*it).first]=(*it).second;
517 * Removes a group from \a this mesh.
518 * \param [in] name - the name of the group to remove.
519 * \throw If no group with such a \a name exists.
521 void MEDFileMesh::removeGroup(const char *name) throw(INTERP_KERNEL::Exception)
523 std::string oname(name);
524 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
525 std::vector<std::string> grps=getGroupsNames();
526 if(it==_groups.end())
528 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
529 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
530 throw INTERP_KERNEL::Exception(oss.str().c_str());
536 * Removes a family from \a this mesh.
537 * \param [in] name - the name of the family to remove.
538 * \throw If no family with such a \a name exists.
540 void MEDFileMesh::removeFamily(const char *name) throw(INTERP_KERNEL::Exception)
542 std::string oname(name);
543 std::map<std::string, int >::iterator it=_families.find(oname);
544 std::vector<std::string> fams=getFamiliesNames();
545 if(it==_families.end())
547 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
548 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
549 throw INTERP_KERNEL::Exception(oss.str().c_str());
552 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
554 std::vector<std::string>& v=(*it3).second;
555 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
562 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
563 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
564 * family field whatever its level. This method also suppresses the orphan families.
566 * \return - The list of removed groups names.
568 * \sa MEDFileMesh::removeOrphanFamilies.
570 std::vector<std::string> MEDFileMesh::removeOrphanGroups() throw(INTERP_KERNEL::Exception)
572 removeOrphanFamilies();
573 return removeEmptyGroups();
577 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
578 * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified.
580 * \return - The list of removed families names.
581 * \sa MEDFileMesh::removeOrphanGroups.
583 std::vector<std::string> MEDFileMesh::removeOrphanFamilies() throw(INTERP_KERNEL::Exception)
585 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
586 std::vector<std::string> ret;
587 if(!((DataArrayInt*)allFamIdsInUse))
589 ret=getFamiliesNames();
590 _families.clear(); _groups.clear();
593 std::map<std::string,int> famMap;
594 std::map<std::string, std::vector<std::string> > grps(_groups);
595 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
597 if(allFamIdsInUse->presenceOfValue((*it).second))
598 famMap[(*it).first]=(*it).second;
601 ret.push_back((*it).first);
602 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first.c_str());
603 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
605 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
606 std::vector<std::string>& famv=(*it3).second;
607 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
613 { _families=famMap; _groups=grps; }
618 * Renames a group in \a this mesh.
619 * \param [in] oldName - a current name of the group to rename.
620 * \param [in] newName - a new group name.
621 * \throw If no group named \a oldName exists in \a this mesh.
622 * \throw If a group named \a newName already exists.
624 void MEDFileMesh::changeGroupName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
626 std::string oname(oldName);
627 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
628 std::vector<std::string> grps=getGroupsNames();
629 if(it==_groups.end())
631 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
632 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
633 throw INTERP_KERNEL::Exception(oss.str().c_str());
635 std::string nname(newName);
636 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
637 if(it2!=_groups.end())
639 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
640 throw INTERP_KERNEL::Exception(oss.str().c_str());
642 std::vector<std::string> cpy=(*it).second;
644 _groups[newName]=cpy;
648 * Changes an id of a family in \a this mesh.
649 * This method calls changeFamilyIdArr().
650 * \param [in] oldId - a current id of the family.
651 * \param [in] newId - a new family id.
653 void MEDFileMesh::changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception)
655 changeFamilyIdArr(oldId,newId);
656 std::map<std::string,int> fam2;
657 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
659 if((*it).second==oldId)
660 fam2[(*it).first]=newId;
662 fam2[(*it).first]=(*it).second;
668 * Renames a family in \a this mesh.
669 * \param [in] oldName - a current name of the family to rename.
670 * \param [in] newName - a new family name.
671 * \throw If no family named \a oldName exists in \a this mesh.
672 * \throw If a family named \a newName already exists.
674 void MEDFileMesh::changeFamilyName(const char *oldName, const char *newName) throw(INTERP_KERNEL::Exception)
676 std::string oname(oldName);
677 std::map<std::string, int >::iterator it=_families.find(oname);
678 std::vector<std::string> fams=getFamiliesNames();
679 if(it==_families.end())
681 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
682 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
683 throw INTERP_KERNEL::Exception(oss.str().c_str());
685 std::string nname(newName);
686 std::map<std::string, int >::iterator it2=_families.find(nname);
687 if(it2!=_families.end())
689 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
690 throw INTERP_KERNEL::Exception(oss.str().c_str());
692 int cpy=(*it).second;
694 _families[newName]=cpy;
695 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
697 std::vector<std::string>& v=(*it3).second;
698 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
705 * Checks if \a this and another mesh contains the same families.
706 * \param [in] other - the mesh to compare with \a this one.
707 * \param [in,out] what - an unused parameter.
708 * \return bool - \c true if number of families and their ids are the same in the two
709 * meshes. Families with the id == \c 0 are not considered.
711 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
713 if(_families==other->_families)
715 std::map<std::string,int> fam0;
716 std::map<std::string,int> fam1;
717 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
719 fam0[(*it).first]=(*it).second;
720 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
722 fam1[(*it).first]=(*it).second;
727 * Checks if \a this and another mesh contains the same groups.
728 * \param [in] other - the mesh to compare with \a this one.
729 * \param [in,out] what - a string describing a difference of groups of the two meshes
730 * in case if this method returns \c false.
731 * \return bool - \c true if number of groups and families constituting them are the
732 * same in the two meshes.
734 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
736 if(_groups==other->_groups)
739 std::size_t sz=_groups.size();
740 if(sz!=other->_groups.size())
742 what="Groups differ because not same number !\n";
747 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
748 for(std::size_t i=0;i<sz && ret;i++,it1++)
750 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
751 if(it2!=other->_groups.end())
753 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
754 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
760 what="A group in first mesh exists not in other !\n";
766 std::ostringstream oss; oss << "Groups description differs :\n";
767 oss << "First group description :\n";
768 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
770 oss << " Group \"" << (*it).first << "\" on following families :\n";
771 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
772 oss << " \"" << *it2 << "\n";
774 oss << "Second group description :\n";
775 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
777 oss << " Group \"" << (*it).first << "\" on following families :\n";
778 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
779 oss << " \"" << *it2 << "\n";
787 * Checks if a group with a given name exists in \a this mesh.
788 * \param [in] groupName - the group name.
789 * \return bool - \c true the group \a groupName exists in \a this mesh.
791 bool MEDFileMesh::existsGroup(const char *groupName) const
793 std::string grpName(groupName);
794 return _groups.find(grpName)!=_groups.end();
798 * Checks if a family with a given id exists in \a this mesh.
799 * \param [in] famId - the family id.
800 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
802 bool MEDFileMesh::existsFamily(int famId) const
804 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
805 if((*it2).second==famId)
811 * Checks if a family with a given name exists in \a this mesh.
812 * \param [in] familyName - the family name.
813 * \return bool - \c true the family \a familyName exists in \a this mesh.
815 bool MEDFileMesh::existsFamily(const char *familyName) const
817 std::string fname(familyName);
818 return _families.find(fname)!=_families.end();
822 * Sets an id of a family.
823 * \param [in] familyName - the family name.
824 * \param [in] id - a new id of the family.
826 void MEDFileMesh::setFamilyId(const char *familyName, int id)
828 std::string fname(familyName);
832 void MEDFileMesh::setFamilyIdUnique(const char *familyName, int id) throw(INTERP_KERNEL::Exception)
834 std::string fname(familyName);
835 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
838 if((*it).first!=familyName)
840 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
841 throw INTERP_KERNEL::Exception(oss.str().c_str());
848 * Adds a family to \a this mesh.
849 * \param [in] familyName - a name of the family.
850 * \param [in] famId - an id of the family.
851 * \throw If a family with the same name or id already exists in \a this mesh.
853 void MEDFileMesh::addFamily(const char *familyName, int famId) throw(INTERP_KERNEL::Exception)
855 std::string fname(familyName);
856 std::map<std::string,int>::const_iterator it=_families.find(fname);
857 if(it==_families.end())
859 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
860 if((*it2).second==famId)
862 std::ostringstream oss;
863 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
864 throw INTERP_KERNEL::Exception(oss.str().c_str());
866 _families[fname]=famId;
870 if((*it).second!=famId)
872 std::ostringstream oss;
873 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
874 throw INTERP_KERNEL::Exception(oss.str().c_str());
880 * Creates a group including all mesh entities of given dimension.
881 * \warning This method does \b not guarantee that the created group includes mesh
882 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
883 * present in family fields of different dimensions. To assure this, call
884 * ensureDifferentFamIdsPerLevel() \b before calling this method.
885 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
887 * \param [in] groupName - a name of the new group.
888 * \throw If a group named \a groupName already exists.
889 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
890 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
892 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const char *groupName) throw(INTERP_KERNEL::Exception)
894 std::string grpName(groupName);
895 std::vector<int> levs=getNonEmptyLevelsExt();
896 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
898 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
899 oss << "Available relative ext levels are : ";
900 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
901 throw INTERP_KERNEL::Exception(oss.str().c_str());
903 if(existsGroup(groupName))
905 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
906 oss << "Already existing groups are : ";
907 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
908 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
909 throw INTERP_KERNEL::Exception(oss.str().c_str());
911 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
913 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
914 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
915 std::vector<std::string> familiesOnWholeGroup;
916 for(const int *it=famIds->begin();it!=famIds->end();it++)
919 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
921 _groups[grpName]=familiesOnWholeGroup;
925 * Ensures that given family ids do not present in family fields of dimensions different
926 * than given ones. If a family id is present in the family fields of dimensions different
927 * than the given ones, a new family is created and the whole data is updated accordingly.
928 * \param [in] famIds - a sequence of family ids to check.
929 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
930 * famIds should exclusively belong.
931 * \return bool - \c true if no modification is done in \a this mesh by this method.
933 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
935 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
936 std::vector<int> levs=getNonEmptyLevelsExt();
937 std::set<int> levs2(levs.begin(),levs.end());
938 std::vector<int> levsToTest;
939 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
940 std::set<int> famIds2(famIds.begin(),famIds.end());
943 if(!_families.empty())
944 maxFamId=getMaxFamilyId()+1;
945 std::vector<std::string> allFams=getFamiliesNames();
946 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
948 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
951 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
952 std::vector<int> tmp;
953 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
954 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
957 std::string famName=getFamilyNameGivenId(*it2);
958 std::ostringstream oss; oss << "Family_" << maxFamId;
959 std::string zeName=CreateNameNotIn(oss.str(),allFams);
960 addFamilyOnAllGroupsHaving(famName.c_str(),zeName.c_str());
961 _families[zeName]=maxFamId;
962 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
971 * Adds a family to a given group in \a this mesh. If the group with a given name does
972 * not exist, it is created.
973 * \param [in] grpName - the name of the group to add the family in.
974 * \param [in] famName - the name of the family to add to the group named \a grpName.
975 * \throw If \a grpName or \a famName is an empty string.
976 * \throw If no family named \a famName is present in \a this mesh.
978 void MEDFileMesh::addFamilyOnGrp(const char *grpName, const char *famName) throw(INTERP_KERNEL::Exception)
980 std::string grpn(grpName);
981 std::string famn(famName);
982 if(grpn.empty() || famn.empty())
983 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
984 std::vector<std::string> fams=getFamiliesNames();
985 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
987 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
988 oss << "Create this family or choose an existing one ! Existing fams are : ";
989 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
990 throw INTERP_KERNEL::Exception(oss.str().c_str());
992 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
993 if(it==_groups.end())
995 _groups[grpn].push_back(famn);
999 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1000 if(it2==(*it).second.end())
1001 (*it).second.push_back(famn);
1006 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1007 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1008 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1010 void MEDFileMesh::addFamilyOnAllGroupsHaving(const char *famName, const char *otherFamName) throw(INTERP_KERNEL::Exception)
1012 std::string famNameCpp(famName);
1013 std::string otherCpp(otherFamName);
1014 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1016 std::vector<std::string>& v=(*it).second;
1017 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1019 v.push_back(otherCpp);
1024 void MEDFileMesh::changeAllGroupsContainingFamily(const char *familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception)
1026 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1029 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)
1031 std::string fam(familyNameToChange);
1032 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1034 std::vector<std::string>& fams((*it).second);
1035 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1039 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1045 * Returns a name of the family having a given id or, if no such a family exists, creates
1046 * a new uniquely named family and returns its name.
1047 * \param [in] id - the id of the family whose name is required.
1048 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1049 * \return std::string - the name of the existing or the created family.
1050 * \throw If it is not possible to create a unique family name.
1052 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception)
1054 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1058 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1059 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1060 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1061 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1063 * This method will throws an exception if it is not possible to create a unique family name.
1065 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created) throw(INTERP_KERNEL::Exception)
1067 std::vector<std::string> famAlreadyExisting(families.size());
1069 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1071 if((*it).second!=id)
1073 famAlreadyExisting[ii]=(*it).first;
1082 std::ostringstream oss; oss << "Family_" << id;
1083 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1089 * Sets names and ids of all families in \a this mesh.
1090 * \param [in] info - a map of a family name to a family id.
1092 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1098 * Sets names of all groups and families constituting them in \a this mesh.
1099 * \param [in] info - a map of a group name to a vector of names of families
1100 * constituting the group.
1102 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1108 * Returns an id of the family having a given name.
1109 * \param [in] name - the name of the family of interest.
1110 * \return int - the id of the family of interest.
1111 * \throw If no family with such a \a name exists.
1113 int MEDFileMesh::getFamilyId(const char *name) const throw(INTERP_KERNEL::Exception)
1115 std::string oname(name);
1116 std::map<std::string, int>::const_iterator it=_families.find(oname);
1117 std::vector<std::string> fams=getFamiliesNames();
1118 if(it==_families.end())
1120 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1121 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1122 throw INTERP_KERNEL::Exception(oss.str().c_str());
1124 return (*it).second;
1128 * Returns ids of the families having given names.
1129 * \param [in] fams - a sequence of the names of families of interest.
1130 * \return std::vector<int> - a sequence of the ids of families of interest.
1131 * \throw If \a fams contains a name of an inexistent family.
1133 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
1135 std::vector<int> ret(fams.size());
1137 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1139 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1140 if(it2==_families.end())
1142 std::vector<std::string> fams2=getFamiliesNames();
1143 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1144 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1145 throw INTERP_KERNEL::Exception(oss.str().c_str());
1147 ret[i]=(*it2).second;
1153 * Returns a maximal abs(id) of families in \a this mesh.
1154 * \return int - the maximal norm of family id.
1155 * \throw If there are no families in \a this mesh.
1157 int MEDFileMesh::getMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
1159 if(_families.empty())
1160 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1161 int ret=-std::numeric_limits<int>::max();
1162 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1164 ret=std::max(std::abs((*it).second),ret);
1170 * Returns a maximal id of families in \a this mesh.
1171 * \return int - the maximal family id.
1172 * \throw If there are no families in \a this mesh.
1174 int MEDFileMesh::getMaxFamilyId() const throw(INTERP_KERNEL::Exception)
1176 if(_families.empty())
1177 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1178 int ret=-std::numeric_limits<int>::max();
1179 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1181 ret=std::max((*it).second,ret);
1187 * Returns a minimal id of families in \a this mesh.
1188 * \return int - the minimal family id.
1189 * \throw If there are no families in \a this mesh.
1191 int MEDFileMesh::getMinFamilyId() const throw(INTERP_KERNEL::Exception)
1193 if(_families.empty())
1194 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1195 int ret=std::numeric_limits<int>::max();
1196 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1198 ret=std::min((*it).second,ret);
1204 * Returns a maximal id of families in \a this mesh. Not only named families are
1205 * considered but all family fields as well.
1206 * \return int - the maximal family id.
1208 int MEDFileMesh::getTheMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception)
1210 int m1=-std::numeric_limits<int>::max();
1211 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1212 m1=std::max(std::abs((*it).second),m1);
1213 int m2=getMaxAbsFamilyIdInArrays();
1214 return std::max(m1,m2);
1218 * Returns a maximal id of families in \a this mesh. Not only named families are
1219 * considered but all family fields as well.
1220 * \return int - the maximal family id.
1222 int MEDFileMesh::getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception)
1224 int m1=-std::numeric_limits<int>::max();
1225 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1226 m1=std::max((*it).second,m1);
1227 int m2=getMaxFamilyIdInArrays();
1228 return std::max(m1,m2);
1232 * Returns a minimal id of families in \a this mesh. Not only named families are
1233 * considered but all family fields as well.
1234 * \return int - the minimal family id.
1236 int MEDFileMesh::getTheMinFamilyId() const throw(INTERP_KERNEL::Exception)
1238 int m1=std::numeric_limits<int>::max();
1239 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1240 m1=std::min((*it).second,m1);
1241 int m2=getMinFamilyIdInArrays();
1242 return std::min(m1,m2);
1246 * This method only considers the maps. The contain of family array is ignored here.
1248 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1250 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception)
1252 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1254 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1255 v.insert((*it).second);
1256 ret->alloc((int)v.size(),1);
1257 std::copy(v.begin(),v.end(),ret->getPointer());
1262 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1264 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1266 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const throw(INTERP_KERNEL::Exception)
1268 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1269 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1270 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1272 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1273 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1274 if((DataArrayInt *) ret)
1275 ret=dv->buildUnion(ret);
1283 * true is returned if no modification has been needed. false if family
1284 * renumbering has been needed.
1286 bool MEDFileMesh::ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception)
1288 std::vector<int> levs=getNonEmptyLevelsExt();
1289 std::set<int> allFamIds;
1290 int maxId=getMaxFamilyId()+1;
1291 std::map<int,std::vector<int> > famIdsToRenum;
1292 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1294 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1297 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1299 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1301 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1303 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1306 if(famIdsToRenum.empty())
1308 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1309 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1311 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1312 int *famIdsToChange=fam->getPointer();
1313 std::map<int,int> ren;
1314 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1316 if(allIds->presenceOfValue(*it3))
1318 std::string famName=getFamilyNameGivenId(*it3);
1319 std::vector<std::string> grps=getGroupsOnFamily(famName.c_str());
1322 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1323 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1324 addFamilyOnGrp((*it4).c_str(),newFam.c_str());
1327 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1328 for(const int *id=ids->begin();id!=ids->end();id++)
1329 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1335 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1336 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1337 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1338 * This method will throw an exception if a same family id is detected in different level.
1339 * \warning This policy is the opposite of those in MED file documentation ...
1341 void MEDFileMesh::normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception)
1343 ensureDifferentFamIdsPerLevel();
1344 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1345 std::vector<int> levs=getNonEmptyLevelsExt();
1346 std::set<int> levsS(levs.begin(),levs.end());
1347 std::set<std::string> famsFetched;
1348 std::map<std::string,int> families;
1349 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1352 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1356 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1357 std::map<int,int> ren;
1358 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1360 int nbOfTuples=fam->getNumberOfTuples();
1361 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1362 for(int *w=start;w!=start+nbOfTuples;w++)
1364 for(const int *it=tmp->begin();it!=tmp->end();it++)
1366 if(allIds->presenceOfValue(*it))
1368 std::string famName=getFamilyNameGivenId(*it);
1369 families[famName]=ren[*it];
1370 famsFetched.insert(famName);
1375 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1378 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1382 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1383 std::map<int,int> ren;
1384 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1386 int nbOfTuples=fam->getNumberOfTuples();
1387 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1388 for(int *w=start;w!=start+nbOfTuples;w++)
1390 for(const int *it=tmp->begin();it!=tmp->end();it++)
1392 if(allIds->presenceOfValue(*it))
1394 std::string famName=getFamilyNameGivenId(*it);
1395 families[famName]=ren[*it];
1396 famsFetched.insert(famName);
1401 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1403 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1406 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1407 fam->fillWithZero();
1408 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1409 if(allIds->presenceOfValue(*it3))
1411 std::string famName=getFamilyNameGivenId(*it3);
1412 families[famName]=0;
1413 famsFetched.insert(famName);
1418 std::vector<std::string> allFams=getFamiliesNames();
1419 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1420 std::set<std::string> unFetchedIds;
1421 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1422 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1423 families[*it4]=_families[*it4];
1428 * This method normalizes fam id with the following policy.
1429 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1430 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1431 * This method will throw an exception if a same family id is detected in different level.
1433 void MEDFileMesh::normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception)
1435 ensureDifferentFamIdsPerLevel();
1436 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1437 std::vector<int> levs=getNonEmptyLevelsExt();
1438 std::set<int> levsS(levs.begin(),levs.end());
1439 std::set<std::string> famsFetched;
1440 std::map<std::string,int> families;
1442 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1445 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1448 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1449 std::map<int,int> ren;
1450 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1452 int nbOfTuples=fam->getNumberOfTuples();
1453 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1454 for(int *w=start;w!=start+nbOfTuples;w++)
1456 for(const int *it=tmp->begin();it!=tmp->end();it++)
1458 if(allIds->presenceOfValue(*it))
1460 std::string famName=getFamilyNameGivenId(*it);
1461 families[famName]=ren[*it];
1462 famsFetched.insert(famName);
1468 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1470 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1473 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1474 std::map<int,int> ren;
1475 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1477 int nbOfTuples=fam->getNumberOfTuples();
1478 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1479 for(int *w=start;w!=start+nbOfTuples;w++)
1481 for(const int *it=tmp->begin();it!=tmp->end();it++)
1483 if(allIds->presenceOfValue(*it))
1485 std::string famName=getFamilyNameGivenId(*it);
1486 families[famName]=ren[*it];
1487 famsFetched.insert(famName);
1493 std::vector<std::string> allFams=getFamiliesNames();
1494 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1495 std::set<std::string> unFetchedIds;
1496 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1497 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1498 families[*it4]=_families[*it4];
1503 * Returns a name of the family by its id. If there are several families having the given
1504 * id, the name first in lexical order is returned.
1505 * \param [in] id - the id of the family whose name is required.
1506 * \return std::string - the name of the found family.
1507 * \throw If no family with the given \a id exists.
1509 std::string MEDFileMesh::getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception)
1511 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1512 if((*it).second==id)
1514 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1515 throw INTERP_KERNEL::Exception(oss.str().c_str());
1519 * Returns a string describing \a this mesh. This description includes the mesh name and
1520 * the mesh description string.
1521 * \return std::string - the mesh information string.
1523 std::string MEDFileMesh::simpleRepr() const
1525 std::ostringstream oss;
1526 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1527 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1528 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1533 * Returns ids of mesh entities contained in a given group of a given dimension.
1534 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1536 * \param [in] grp - the name of the group of interest.
1537 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1538 * returned instead of ids.
1539 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1540 * numbers, if available and required, of mesh entities of the group. The caller
1541 * is to delete this array using decrRef() as it is no more needed.
1542 * \throw If the name of a nonexistent group is specified.
1543 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1545 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1547 std::vector<std::string> tmp(1);
1549 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1555 * Returns ids of mesh entities contained in given groups of a given dimension.
1556 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1558 * \param [in] grps - the names of the groups of interest.
1559 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1560 * returned instead of ids.
1561 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1562 * numbers, if available and required, of mesh entities of the groups. The caller
1563 * is to delete this array using decrRef() as it is no more needed.
1564 * \throw If the name of a nonexistent group is present in \a grps.
1565 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1567 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1569 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1570 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1574 * Returns ids of mesh entities contained in a given family of a given dimension.
1575 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1577 * \param [in] fam - the name of the family of interest.
1578 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1579 * returned instead of ids.
1580 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1581 * numbers, if available and required, of mesh entities of the family. The caller
1582 * is to delete this array using decrRef() as it is no more needed.
1583 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1585 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1587 std::vector<std::string> tmp(1);
1589 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1595 * Returns ids of nodes contained in a given group.
1596 * \param [in] grp - the name of the group of interest.
1597 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1598 * returned instead of ids.
1599 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1600 * numbers, if available and required, of nodes of the group. The caller
1601 * is to delete this array using decrRef() as it is no more needed.
1602 * \throw If the name of a nonexistent group is specified.
1603 * \throw If the family field is missing for nodes.
1605 DataArrayInt *MEDFileMesh::getNodeGroupArr(const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
1607 std::vector<std::string> tmp(1);
1609 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1615 * Returns ids of nodes contained in given groups.
1616 * \param [in] grps - the names of the groups of interest.
1617 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1618 * returned instead of ids.
1619 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1620 * numbers, if available and required, of nodes of the groups. The caller
1621 * is to delete this array using decrRef() as it is no more needed.
1622 * \throw If the name of a nonexistent group is present in \a grps.
1623 * \throw If the family field is missing for nodes.
1625 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
1627 return getGroupsArr(1,grps,renum);
1631 * Returns ids of nodes contained in a given group.
1632 * \param [in] grp - the name of the group of interest.
1633 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1634 * returned instead of ids.
1635 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1636 * numbers, if available and required, of nodes of the group. The caller
1637 * is to delete this array using decrRef() as it is no more needed.
1638 * \throw If the name of a nonexistent group is specified.
1639 * \throw If the family field is missing for nodes.
1641 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
1643 std::vector<std::string> tmp(1);
1645 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1651 * Returns ids of nodes contained in given families.
1652 * \param [in] fams - the names of the families of interest.
1653 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1654 * returned instead of ids.
1655 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1656 * numbers, if available and required, of nodes of the families. The caller
1657 * is to delete this array using decrRef() as it is no more needed.
1658 * \throw If the family field is missing for nodes.
1660 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
1662 return getFamiliesArr(1,fams,renum);
1666 * Adds groups of given dimension and creates corresponding families and family fields
1667 * given ids of mesh entities of each group.
1668 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1669 * \param [in] grps - a sequence of arrays of ids each describing a group.
1670 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1672 * \throw If names of some groups in \a grps are equal.
1673 * \throw If \a grps includes a group with an empty name.
1674 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1675 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1677 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum) throw(INTERP_KERNEL::Exception)
1681 std::set<std::string> grpsName;
1682 std::vector<std::string> grpsName2(grps.size());
1685 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1687 grpsName.insert((*it)->getName());
1688 grpsName2[i]=(*it)->getName();
1690 if(grpsName.size()!=grps.size())
1691 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1692 if(grpsName.find(std::string(""))!=grpsName.end())
1693 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1694 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1695 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1696 std::vector< std::vector<int> > fidsOfGroups;
1699 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1703 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1704 for(unsigned int ii=0;ii<grps.size();ii++)
1706 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1707 grps2[ii]->setName(grps[ii]->getName().c_str());
1709 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1710 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1713 if(!_families.empty())
1714 offset=getMaxAbsFamilyId()+1;
1715 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1716 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1717 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1718 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1722 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1723 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1724 * For the moment, the two last input parameters are not taken into account.
1726 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1728 std::map<int,std::string> famInv;
1729 for(const int *it=famIds->begin();it!=famIds->end();it++)
1731 std::ostringstream oss;
1732 oss << "Family_" << (*it);
1733 _families[oss.str()]=(*it);
1734 famInv[*it]=oss.str();
1737 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1739 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1741 _groups[grpNames[i]].push_back(famInv[*it2]);
1746 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
1748 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1749 return mLev->getDistributionOfTypes();
1752 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1754 famArr->applyLin(offset>0?1:-1,offset,0);
1755 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1758 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1759 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1764 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1765 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1766 * If this method fails to find such a name it will throw an exception.
1768 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid) throw(INTERP_KERNEL::Exception)
1771 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1774 std::size_t len=nameTry.length();
1775 for(std::size_t ii=1;ii<len;ii++)
1777 std::string tmp=nameTry.substr(ii,len-ii);
1778 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1784 for(std::size_t i=1;i<30;i++)
1786 std::string tmp1(nameTry.at(0),i);
1788 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1794 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1796 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1798 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1801 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt) throw(INTERP_KERNEL::Exception)
1803 std::size_t nbOfChunks=code.size()/3;
1804 if(code.size()%3!=0)
1805 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1807 for(std::size_t i=0;i<nbOfChunks;i++)
1816 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1817 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1818 * If _name is not empty and that 'm' has the same name nothing is done.
1819 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1821 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) throw(INTERP_KERNEL::Exception)
1824 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1829 std::string name(m->getName());
1834 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1835 oss << name << "' ! Names must match !";
1836 throw INTERP_KERNEL::Exception(oss.str().c_str());
1840 if(_desc_name.empty())
1841 _desc_name=m->getDescription();
1844 std::string name(m->getDescription());
1847 if(_desc_name!=name)
1849 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1850 oss << name << "' ! Names must match !";
1851 throw INTERP_KERNEL::Exception(oss.str().c_str());
1857 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1859 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1860 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1862 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1863 oss << " - Groups lying on this family : ";
1864 std::vector<std::string> grps=getGroupsOnFamily((*it).first.c_str());
1865 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1866 oss << std::endl << std::endl;
1871 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1872 * file. The mesh to load is specified by its name and numbers of a time step and an
1874 * \param [in] fileName - the name of MED file to read.
1875 * \param [in] mName - the name of the mesh to read.
1876 * \param [in] dt - the number of a time step.
1877 * \param [in] it - the number of an iteration.
1878 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1879 * mesh using decrRef() as it is no more needed.
1880 * \throw If the file is not readable.
1881 * \throw If there is no mesh with given attributes in the file.
1882 * \throw If the mesh in the file is not an unstructured one.
1884 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
1886 MEDFileUtilities::CheckFileForRead(fileName);
1887 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1888 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1892 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1893 * file. The first mesh in the file is loaded.
1894 * \param [in] fileName - the name of MED file to read.
1895 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1896 * mesh using decrRef() as it is no more needed.
1897 * \throw If the file is not readable.
1898 * \throw If there is no meshes in the file.
1899 * \throw If the mesh in the file is not an unstructured one.
1901 MEDFileUMesh *MEDFileUMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
1903 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1906 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1907 throw INTERP_KERNEL::Exception(oss.str().c_str());
1909 MEDFileUtilities::CheckFileForRead(fileName);
1910 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
1912 ParaMEDMEM::MEDCouplingMeshType meshType;
1914 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
1915 return new MEDFileUMesh(fid,ms.front().c_str(),dt,it,mrs);
1919 * Returns an empty instance of MEDFileUMesh.
1920 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1921 * mesh using decrRef() as it is no more needed.
1923 MEDFileUMesh *MEDFileUMesh::New()
1925 return new MEDFileUMesh;
1928 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
1930 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
1931 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1935 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildren() const
1937 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
1938 if((const DataArrayDouble*)_coords)
1939 ret.push_back((const DataArrayDouble*)_coords);
1940 if((const DataArrayInt *)_fam_coords)
1941 ret.push_back((const DataArrayInt *)_fam_coords);
1942 if((const DataArrayInt *)_num_coords)
1943 ret.push_back((const DataArrayInt *)_num_coords);
1944 if((const DataArrayInt *)_rev_num_coords)
1945 ret.push_back((const DataArrayInt *)_rev_num_coords);
1946 if((const DataArrayAsciiChar *)_name_coords)
1947 ret.push_back((const DataArrayAsciiChar *)_name_coords);
1948 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1949 if((const MEDFileUMeshSplitL1*) *it)
1950 ret.push_back((const MEDFileUMeshSplitL1*) *it);
1954 MEDFileMesh *MEDFileUMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
1956 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1960 MEDFileMesh *MEDFileUMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
1962 return new MEDFileUMesh;
1965 MEDFileMesh *MEDFileUMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
1967 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1968 if((const DataArrayDouble*)_coords)
1969 ret->_coords=_coords->deepCpy();
1970 if((const DataArrayInt*)_fam_coords)
1971 ret->_fam_coords=_fam_coords->deepCpy();
1972 if((const DataArrayInt*)_num_coords)
1973 ret->_num_coords=_num_coords->deepCpy();
1974 if((const DataArrayInt*)_rev_num_coords)
1975 ret->_rev_num_coords=_rev_num_coords->deepCpy();
1976 if((const DataArrayAsciiChar*)_name_coords)
1977 ret->_name_coords=_name_coords->deepCpy();
1979 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
1981 if((const MEDFileUMeshSplitL1 *)(*it))
1982 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
1988 * Checks if \a this and another mesh are equal.
1989 * \param [in] other - the mesh to compare with.
1990 * \param [in] eps - a precision used to compare real values.
1991 * \param [in,out] what - the string returning description of unequal data.
1992 * \return bool - \c true if the meshes are equal, \c false, else.
1994 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
1996 if(!MEDFileMesh::isEqual(other,eps,what))
1998 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2001 what="Mesh types differ ! This is unstructured and other is NOT !";
2004 clearNonDiscrAttributes();
2005 otherC->clearNonDiscrAttributes();
2006 const DataArrayDouble *coo1=_coords;
2007 const DataArrayDouble *coo2=otherC->_coords;
2008 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2010 what="Mismatch of coordinates ! One is defined and not other !";
2015 bool ret=coo1->isEqual(*coo2,eps);
2018 what="Coords differ !";
2022 const DataArrayInt *famc1=_fam_coords;
2023 const DataArrayInt *famc2=otherC->_fam_coords;
2024 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2026 what="Mismatch of families arr on nodes ! One is defined and not other !";
2031 bool ret=famc1->isEqual(*famc2);
2034 what="Families arr on node differ !";
2038 const DataArrayInt *numc1=_num_coords;
2039 const DataArrayInt *numc2=otherC->_num_coords;
2040 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2042 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2047 bool ret=numc1->isEqual(*numc2);
2050 what="Numbering arr on node differ !";
2054 const DataArrayAsciiChar *namec1=_name_coords;
2055 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2056 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2058 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2063 bool ret=namec1->isEqual(*namec2);
2066 what="Names arr on node differ !";
2070 if(_ms.size()!=otherC->_ms.size())
2072 what="Number of levels differs !";
2075 std::size_t sz=_ms.size();
2076 for(std::size_t i=0;i<sz;i++)
2078 const MEDFileUMeshSplitL1 *s1=_ms[i];
2079 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2080 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2082 what="Mismatch of presence of sub levels !";
2087 bool ret=s1->isEqual(s2,eps,what);
2096 * Clears redundant attributes of incorporated data arrays.
2098 void MEDFileUMesh::clearNonDiscrAttributes() const
2100 MEDFileMesh::clearNonDiscrAttributes();
2101 const DataArrayDouble *coo1=_coords;
2103 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2104 const DataArrayInt *famc1=_fam_coords;
2106 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2107 const DataArrayInt *numc1=_num_coords;
2109 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2110 const DataArrayAsciiChar *namc1=_name_coords;
2112 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2113 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2115 const MEDFileUMeshSplitL1 *tmp=(*it);
2117 tmp->clearNonDiscrAttributes();
2121 MEDFileUMesh::MEDFileUMesh()
2125 MEDFileUMesh::MEDFileUMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
2128 loadUMeshFromFile(fid,mName,dt,it,mrs);
2130 catch(INTERP_KERNEL::Exception& e)
2135 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
2137 MEDFileUMeshL2 loaderl2;
2138 ParaMEDMEM::MEDCouplingMeshType meshType;
2141 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
2142 if(meshType!=UNSTRUCTURED)
2144 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2145 throw INTERP_KERNEL::Exception(oss.str().c_str());
2147 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2148 int lev=loaderl2.getNumberOfLevels();
2150 for(int i=0;i<lev;i++)
2152 if(!loaderl2.emptyLev(i))
2153 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2157 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2159 setName(loaderl2.getName());
2160 setDescription(loaderl2.getDescription());
2161 setUnivName(loaderl2.getUnivName());
2162 setIteration(loaderl2.getIteration());
2163 setOrder(loaderl2.getOrder());
2164 setTimeValue(loaderl2.getTime());
2165 setTimeUnit(loaderl2.getTimeUnit());
2166 _coords=loaderl2.getCoords();
2167 if(!mrs || mrs->isNodeFamilyFieldReading())
2168 _fam_coords=loaderl2.getCoordsFamily();
2169 if(!mrs || mrs->isNodeNumFieldReading())
2170 _num_coords=loaderl2.getCoordsNum();
2171 if(!mrs || mrs->isNodeNameFieldReading())
2172 _name_coords=loaderl2.getCoordsName();
2176 MEDFileUMesh::~MEDFileUMesh()
2180 void MEDFileUMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
2182 const DataArrayDouble *coo=_coords;
2183 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2184 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2185 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2186 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2187 int spaceDim=coo?coo->getNumberOfComponents():0;
2188 int mdim=getMeshDimension();
2189 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2190 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2191 for(int i=0;i<spaceDim;i++)
2193 std::string info=coo->getInfoOnComponent(i);
2195 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2196 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
2197 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
2199 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2200 MEDmeshUniversalNameWr(fid,maa);
2201 MEDFileUMeshL2::WriteCoords(fid,maa,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2202 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2203 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2204 (*it)->write(fid,maa,mdim);
2205 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
2209 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2210 * \return std::vector<int> - a sequence of the relative dimensions.
2212 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2214 std::vector<int> ret;
2216 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2217 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2224 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2225 * \return std::vector<int> - a sequence of the relative dimensions.
2227 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2229 std::vector<int> ret0=getNonEmptyLevels();
2230 if((const DataArrayDouble *) _coords)
2232 std::vector<int> ret(ret0.size()+1);
2234 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2240 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2242 std::vector<int> ret;
2243 const DataArrayInt *famCoo(_fam_coords);
2247 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2249 const MEDFileUMeshSplitL1 *cur(*it);
2251 if(cur->getFamilyField())
2257 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2259 std::vector<int> ret;
2260 const DataArrayInt *numCoo(_num_coords);
2264 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2266 const MEDFileUMeshSplitL1 *cur(*it);
2268 if(cur->getNumberField())
2274 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2276 std::vector<int> ret;
2277 const DataArrayAsciiChar *nameCoo(_name_coords);
2281 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2283 const MEDFileUMeshSplitL1 *cur(*it);
2285 if(cur->getNameField())
2292 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2293 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2294 * \param [in] grp - the name of the group of interest.
2295 * \return std::vector<int> - a sequence of the relative dimensions.
2297 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const char *grp) const throw(INTERP_KERNEL::Exception)
2299 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2300 return getFamsNonEmptyLevels(fams);
2304 * Returns all relative mesh levels (including nodes) where a given group is defined.
2305 * \param [in] grp - the name of the group of interest.
2306 * \return std::vector<int> - a sequence of the relative dimensions.
2308 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const char *grp) const throw(INTERP_KERNEL::Exception)
2310 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2311 return getFamsNonEmptyLevelsExt(fams);
2315 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2316 * To include nodes, call getFamNonEmptyLevelsExt() method.
2317 * \param [in] fam - the name of the family of interest.
2318 * \return std::vector<int> - a sequence of the relative dimensions.
2320 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const char *fam) const throw(INTERP_KERNEL::Exception)
2322 std::vector<std::string> fams(1,std::string(fam));
2323 return getFamsNonEmptyLevels(fams);
2327 * Returns all relative mesh levels (including nodes) where a given family is defined.
2328 * \param [in] fam - the name of the family of interest.
2329 * \return std::vector<int> - a sequence of the relative dimensions.
2331 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const char *fam) const throw(INTERP_KERNEL::Exception)
2333 std::vector<std::string> fams(1,std::string(fam));
2334 return getFamsNonEmptyLevelsExt(fams);
2338 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2339 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2340 * \param [in] grps - a sequence of names of the groups of interest.
2341 * \return std::vector<int> - a sequence of the relative dimensions.
2343 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2345 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2346 return getFamsNonEmptyLevels(fams);
2350 * Returns all relative mesh levels (including nodes) where given groups are defined.
2351 * \param [in] grps - a sequence of names of the groups of interest.
2352 * \return std::vector<int> - a sequence of the relative dimensions.
2354 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception)
2356 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2357 return getFamsNonEmptyLevelsExt(fams);
2361 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2362 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2363 * \param [in] fams - the name of the family of interest.
2364 * \return std::vector<int> - a sequence of the relative dimensions.
2366 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2368 std::vector<int> ret;
2369 std::vector<int> levs=getNonEmptyLevels();
2370 std::vector<int> famIds=getFamiliesIds(fams);
2371 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2372 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2378 * Returns all relative mesh levels (including nodes) where given families are defined.
2379 * \param [in] fams - the names of the families of interest.
2380 * \return std::vector<int> - a sequence of the relative dimensions.
2382 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception)
2384 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2385 const DataArrayInt *famCoords=_fam_coords;
2388 std::vector<int> famIds=getFamiliesIds(fams);
2389 if(famCoords->presenceOfValue(famIds))
2391 std::vector<int> ret(ret0.size()+1);
2393 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2401 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2402 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2403 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2406 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2408 std::vector<std::string> ret;
2409 std::vector<std::string> allGrps=getGroupsNames();
2410 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2412 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it).c_str());
2413 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2419 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2421 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2422 if((const DataArrayInt *)_fam_coords)
2424 int val=_fam_coords->getMaxValue(tmp);
2425 ret=std::max(ret,std::abs(val));
2427 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2429 if((const MEDFileUMeshSplitL1 *)(*it))
2431 const DataArrayInt *da=(*it)->getFamilyField();
2434 int val=da->getMaxValue(tmp);
2435 ret=std::max(ret,std::abs(val));
2442 int MEDFileUMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2444 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2445 if((const DataArrayInt *)_fam_coords)
2447 int val=_fam_coords->getMaxValue(tmp);
2448 ret=std::max(ret,val);
2450 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2452 if((const MEDFileUMeshSplitL1 *)(*it))
2454 const DataArrayInt *da=(*it)->getFamilyField();
2457 int val=da->getMaxValue(tmp);
2458 ret=std::max(ret,val);
2465 int MEDFileUMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
2467 int ret=std::numeric_limits<int>::max(),tmp=-1;
2468 if((const DataArrayInt *)_fam_coords)
2470 int val=_fam_coords->getMinValue(tmp);
2471 ret=std::min(ret,val);
2473 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2475 if((const MEDFileUMeshSplitL1 *)(*it))
2477 const DataArrayInt *da=(*it)->getFamilyField();
2480 int val=da->getMinValue(tmp);
2481 ret=std::min(ret,val);
2489 * Returns the dimension on cells in \a this mesh.
2490 * \return int - the mesh dimension.
2491 * \throw If there are no cells in this mesh.
2493 int MEDFileUMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
2496 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2497 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2498 return (*it)->getMeshDimension()+lev;
2499 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2503 * Returns the space dimension of \a this mesh that is equal to number of components in
2504 * the node coordinates array.
2505 * \return int - the space dimension of \a this mesh.
2506 * \throw If the node coordinates array is not available.
2508 int MEDFileUMesh::getSpaceDimension() const throw(INTERP_KERNEL::Exception)
2510 const DataArrayDouble *coo=_coords;
2512 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2513 return coo->getNumberOfComponents();
2517 * Returns a string describing \a this mesh.
2518 * \return std::string - the mesh information string.
2520 std::string MEDFileUMesh::simpleRepr() const
2522 std::ostringstream oss;
2523 oss << MEDFileMesh::simpleRepr();
2524 const DataArrayDouble *coo=_coords;
2525 oss << "- The dimension of the space is ";
2526 static const char MSG1[]= "*** NO COORDS SET ***";
2527 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2529 oss << _coords->getNumberOfComponents() << std::endl;
2531 oss << MSG1 << std::endl;
2532 oss << "- Type of the mesh : UNSTRUCTURED\n";
2533 oss << "- Number of nodes : ";
2535 oss << _coords->getNumberOfTuples() << std::endl;
2537 oss << MSG1 << std::endl;
2538 std::size_t nbOfLev=_ms.size();
2539 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2540 for(std::size_t i=0;i<nbOfLev;i++)
2542 const MEDFileUMeshSplitL1 *lev=_ms[i];
2543 oss << " - Level #" << -((int) i) << " has dimension : ";
2546 oss << lev->getMeshDimension() << std::endl;
2547 lev->simpleRepr(oss);
2550 oss << MSG2 << std::endl;
2552 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2555 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2556 oss << "- Names of coordinates :" << std::endl;
2557 std::vector<std::string> vars=coo->getVarsOnComponent();
2558 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2559 oss << std::endl << "- Units of coordinates : " << std::endl;
2560 std::vector<std::string> units=coo->getUnitsOnComponent();
2561 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2563 oss << std::endl << std::endl;
2569 * Returns a full textual description of \a this mesh.
2570 * \return std::string - the string holding the mesh description.
2572 std::string MEDFileUMesh::advancedRepr() const
2574 return simpleRepr();
2578 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2579 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2580 * \return int - the number of entities.
2581 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2583 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2585 if(meshDimRelToMaxExt==1)
2587 if(!((const DataArrayDouble *)_coords))
2588 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2589 return _coords->getNumberOfTuples();
2591 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2595 * Returns the family field for mesh entities of a given dimension.
2596 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2597 * \return const DataArrayInt * - the family field. It is an array of ids of families
2598 * each mesh entity belongs to. It can be \c NULL.
2600 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2602 if(meshDimRelToMaxExt==1)
2604 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2605 return l1->getFamilyField();
2609 * Returns the optional numbers of mesh entities of a given dimension.
2610 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2611 * \return const DataArrayInt * - the array of the entity numbers.
2612 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2614 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2616 if(meshDimRelToMaxExt==1)
2618 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2619 return l1->getNumberField();
2622 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2624 if(meshDimRelToMaxExt==1)
2625 return _name_coords;
2626 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2627 return l1->getNameField();
2630 int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
2632 const DataArrayDouble *coo=_coords;
2634 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2635 return coo->getNumberOfTuples();
2638 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
2640 std::size_t sz(st.getNumberOfItems());
2641 int mdim(getMeshDimension());
2642 for(std::size_t i=0;i<sz;i++)
2644 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2645 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2646 if(st[i].getPflName().empty())
2647 m->computeNodeIdsAlg(nodesFetched);
2650 const DataArrayInt *arr(globs->getProfile(st[i].getPflName().c_str()));
2651 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2652 m2->computeNodeIdsAlg(nodesFetched);
2658 * Returns the optional numbers of mesh entities of a given dimension transformed using
2659 * DataArrayInt::invertArrayN2O2O2N().
2660 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2661 * \return const DataArrayInt * - the array of the entity numbers transformed using
2662 * DataArrayInt::invertArrayN2O2O2N().
2663 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2665 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2667 if(meshDimRelToMaxExt==1)
2669 if(!((const DataArrayInt *)_num_coords))
2670 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2671 return _rev_num_coords;
2673 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2674 return l1->getRevNumberField();
2678 * Returns a pointer to the node coordinates array of \a this mesh \b without
2679 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2681 DataArrayDouble *MEDFileUMesh::getCoords() const
2683 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2684 if((DataArrayDouble *)tmp)
2692 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2693 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2695 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2696 * \param [in] grp - the name of the group whose mesh entities are included in the
2698 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2699 * according to the optional numbers of entities, if available.
2700 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2701 * delete this mesh using decrRef() as it is no more needed.
2702 * \throw If the name of a nonexistent group is specified.
2703 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2705 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const char *grp, bool renum) const throw(INTERP_KERNEL::Exception)
2707 synchronizeTinyInfoOnLeaves();
2708 std::vector<std::string> tmp(1);
2710 return getGroups(meshDimRelToMaxExt,tmp,renum);
2714 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2715 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2717 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2718 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2720 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2721 * according to the optional numbers of entities, if available.
2722 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2723 * delete this mesh using decrRef() as it is no more needed.
2724 * \throw If a name of a nonexistent group is present in \a grps.
2725 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2727 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const throw(INTERP_KERNEL::Exception)
2729 synchronizeTinyInfoOnLeaves();
2730 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2731 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2732 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2733 zeRet->setName(grps[0].c_str());
2734 return zeRet.retn();
2738 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2739 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2741 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2742 * \param [in] fam - the name of the family whose mesh entities are included in the
2744 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2745 * according to the optional numbers of entities, if available.
2746 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2747 * delete this mesh using decrRef() as it is no more needed.
2748 * \throw If a name of a nonexistent family is present in \a grps.
2749 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2751 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const char *fam, bool renum) const throw(INTERP_KERNEL::Exception)
2753 synchronizeTinyInfoOnLeaves();
2754 std::vector<std::string> tmp(1);
2756 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2760 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2761 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2763 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2764 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2766 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2767 * according to the optional numbers of entities, if available.
2768 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2769 * delete this mesh using decrRef() as it is no more needed.
2770 * \throw If a name of a nonexistent family is present in \a fams.
2771 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2773 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2775 synchronizeTinyInfoOnLeaves();
2776 if(meshDimRelToMaxExt==1)
2778 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2779 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2780 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2784 std::vector<int> famIds=getFamiliesIds(fams);
2785 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2786 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2788 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2790 zeRet=l1->getFamilyPart(0,0,renum);
2791 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2792 zeRet->setName(fams[0].c_str());
2793 return zeRet.retn();
2797 * Returns ids of mesh entities contained in given families of a given dimension.
2798 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2800 * \param [in] fams - the names of the families of interest.
2801 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2802 * returned instead of ids.
2803 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2804 * numbers, if available and required, of mesh entities of the families. The caller
2805 * is to delete this array using decrRef() as it is no more needed.
2806 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2808 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
2810 std::vector<int> famIds=getFamiliesIds(fams);
2811 if(meshDimRelToMaxExt==1)
2813 if((const DataArrayInt *)_fam_coords)
2815 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2817 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2819 da=_fam_coords->getIdsEqualList(0,0);
2821 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2826 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2828 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2830 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2832 return l1->getFamilyPartArr(0,0,renum);
2836 * Returns a MEDCouplingUMesh of a given relative dimension.
2837 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2838 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2839 * To build a valid MEDCouplingUMesh from the returned one in this case,
2840 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2841 * \param [in] meshDimRelToMax - the relative dimension of interest.
2842 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2843 * optional numbers of mesh entities.
2844 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2845 * delete using decrRef() as it is no more needed.
2846 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2847 * \sa getGenMeshAtLevel()
2849 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const throw(INTERP_KERNEL::Exception)
2851 synchronizeTinyInfoOnLeaves();
2852 if(meshDimRelToMaxExt==1)
2856 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2857 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2858 umesh->setCoords(cc);
2859 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2860 umesh->setName(getName().c_str());
2864 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2865 return l1->getWholeMesh(renum);
2869 * Returns a MEDCouplingUMesh of a given relative dimension.
2870 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2871 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2872 * To build a valid MEDCouplingUMesh from the returned one in this case,
2873 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2874 * \param [in] meshDimRelToMax - the relative dimension of interest.
2875 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2876 * optional numbers of mesh entities.
2877 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2878 * delete using decrRef() as it is no more needed.
2879 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2880 * \sa getMeshAtLevel()
2882 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
2884 return getMeshAtLevel(meshDimRelToMax,renum);
2887 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2889 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
2890 return l1->getDistributionOfTypes();
2894 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2895 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2896 * optional numbers of mesh entities.
2897 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2898 * delete using decrRef() as it is no more needed.
2899 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2901 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2903 return getMeshAtLevel(0,renum);
2907 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2908 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2909 * optional numbers of mesh entities.
2910 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2911 * delete using decrRef() as it is no more needed.
2912 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2914 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2916 return getMeshAtLevel(-1,renum);
2920 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2921 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2922 * optional numbers of mesh entities.
2923 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2924 * delete using decrRef() as it is no more needed.
2925 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
2927 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2929 return getMeshAtLevel(-2,renum);
2933 * Returns a MEDCouplingUMesh of a relative dimension == -3.
2934 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2935 * optional numbers of mesh entities.
2936 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2937 * delete using decrRef() as it is no more needed.
2938 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
2940 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const throw(INTERP_KERNEL::Exception)
2942 return getMeshAtLevel(-3,renum);
2946 * This method returns a vector of mesh parts containing each exactly one geometric type.
2947 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
2948 * This method is only for memory aware users.
2949 * The returned pointers are **NOT** new object pointer. No need to mange them.
2951 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
2953 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
2954 return sp->getDirectUndergroundSingleGeoTypeMeshes();
2958 * This method returns the part of \a this having the geometric type \a gt.
2959 * If such part is not existing an exception will be thrown.
2960 * The returned pointer is **NOT** new object pointer. No need to mange it.
2962 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception)
2964 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
2965 int lev=(int)cm.getDimension()-getMeshDimension();
2966 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
2967 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
2970 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
2972 if(meshDimRelToMaxExt==1)
2973 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2974 if(meshDimRelToMaxExt>1)
2975 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2976 int tracucedRk=-meshDimRelToMaxExt;
2977 if(tracucedRk>=(int)_ms.size())
2978 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2979 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2980 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2981 return _ms[tracucedRk];
2984 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
2986 if(meshDimRelToMaxExt==1)
2987 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
2988 if(meshDimRelToMaxExt>1)
2989 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
2990 int tracucedRk=-meshDimRelToMaxExt;
2991 if(tracucedRk>=(int)_ms.size())
2992 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
2993 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
2994 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
2995 return _ms[tracucedRk];
2998 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const throw(INTERP_KERNEL::Exception)
3000 if(-meshDimRelToMax>=(int)_ms.size())
3001 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3003 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3005 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3007 int ref=(*it)->getMeshDimension();
3008 if(ref+i!=meshDim-meshDimRelToMax)
3009 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3015 * Sets the node coordinates array of \a this mesh.
3016 * \param [in] coords - the new node coordinates array.
3017 * \throw If \a coords == \c NULL.
3019 void MEDFileUMesh::setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception)
3022 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3023 coords->checkAllocated();
3024 int nbOfTuples=coords->getNumberOfTuples();
3027 _fam_coords=DataArrayInt::New();
3028 _fam_coords->alloc(nbOfTuples,1);
3029 _fam_coords->fillWithZero();
3030 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3031 if((MEDFileUMeshSplitL1 *)(*it))
3032 (*it)->setCoords(coords);
3036 * Removes all groups of a given dimension in \a this mesh.
3037 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3038 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3040 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception)
3042 if(meshDimRelToMaxExt==1)
3044 if((DataArrayInt *)_fam_coords)
3045 _fam_coords->fillWithZero();
3048 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3049 l1->eraseFamilyField();
3054 * Removes all families with ids not present in the family fields of \a this mesh.
3056 void MEDFileUMesh::optimizeFamilies() throw(INTERP_KERNEL::Exception)
3058 std::vector<int> levs=getNonEmptyLevelsExt();
3059 std::set<int> allFamsIds;
3060 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3062 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3063 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3065 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3068 std::set<std::string> famNamesToKill;
3069 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3071 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3072 famNamesToKill.insert((*it).first);
3074 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3075 _families.erase(*it);
3076 std::vector<std::string> grpNamesToKill;
3077 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3079 std::vector<std::string> tmp;
3080 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3082 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3083 tmp.push_back(*it2);
3088 tmp.push_back((*it).first);
3090 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3094 void MEDFileUMesh::duplicateNodesOnM1Group(const char *grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) throw(INTERP_KERNEL::Exception)
3096 std::vector<int> levs=getNonEmptyLevels();
3097 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3098 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3099 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3100 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3101 int nbNodes=m0->getNumberOfNodes();
3102 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3103 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3104 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3105 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3106 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3107 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3108 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3109 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3110 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3111 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3112 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3113 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3114 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3115 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3116 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3117 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3118 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3119 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3120 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3121 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3122 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3123 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3124 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3125 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3126 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3127 m0->setCoords(tmp0->getCoords());
3128 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3129 m1->setCoords(m0->getCoords());
3130 _coords=m0->getCoords(); _coords->incrRef();
3131 // duplication of cells in group 'grpNameM1' on level -1
3132 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3133 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3134 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3135 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3136 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3138 newm1->setName(getName().c_str());
3139 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3141 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3142 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3143 newFam->alloc(newm1->getNumberOfCells(),1);
3144 int idd=getMaxFamilyId()+1;
3145 int globStart=0,start=0,end,globEnd;
3146 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3147 for(int i=0;i<nbOfChunks;i++)
3149 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3150 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3152 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3153 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3154 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3159 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3163 newm1->setCoords(getCoords());
3164 setMeshAtLevel(-1,newm1);
3165 setFamilyFieldArr(-1,newFam);
3166 std::string grpName2(grpNameM1); grpName2+="_dup";
3167 addFamily(grpName2.c_str(),idd);
3168 addFamilyOnGrp(grpName2.c_str(),grpName2.c_str());
3173 int newNbOfNodes=getCoords()->getNumberOfTuples();
3174 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3175 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3176 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3179 nodesDuplicated=nodeIdsToDuplicate.retn();
3180 cellsModified=cellsToModifyConn0.retn();
3181 cellsNotModified=cellsToModifyConn1.retn();
3185 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3186 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3187 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3189 * \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.
3190 * 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.
3192 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
3194 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3195 std::vector<int> levs=getNonEmptyLevels();
3197 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3198 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3201 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3203 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3204 std::vector<int> code1=m->getDistributionOfTypes();
3205 end=PutInThirdComponentOfCodeOffset(code1,start);
3206 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3207 bool hasChanged=m->unPolyze();
3208 DataArrayInt *fake=0;
3209 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3210 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3212 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3215 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3216 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3218 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3219 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3220 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3221 setMeshAtLevel(*it,m);
3222 std::vector<int> code2=m->getDistributionOfTypes();
3223 end=PutInThirdComponentOfCodeOffset(code2,start);
3224 newCode.insert(newCode.end(),code2.begin(),code2.end());
3226 if(o2nCellsPart2->isIdentity())
3230 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3231 setFamilyFieldArr(*it,newFamField);
3235 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3236 setRenumFieldArr(*it,newNumField);
3241 newCode.insert(newCode.end(),code1.begin(),code1.end());
3247 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3248 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3249 o2nRenumCell=o2nRenumCellRet.retn();
3254 struct MEDLoaderAccVisit1
3256 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3257 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3258 int _new_nb_of_nodes;
3262 * 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.
3263 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3264 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3265 * -1 values in returned array means that the corresponding old node is no more used.
3267 * \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
3268 * is modified in \a this.
3269 * \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
3272 DataArrayInt *MEDFileUMesh::zipCoords() throw(INTERP_KERNEL::Exception)
3274 const DataArrayDouble *coo=getCoords();
3276 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3277 int nbOfNodes=coo->getNumberOfTuples();
3278 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3279 std::vector<int> neLevs=getNonEmptyLevels();
3280 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3282 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3283 m->computeNodeIdsAlg(nodeIdsInUse);
3285 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3286 if(nbrOfNodesInUse==nbOfNodes)
3288 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3289 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3290 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3291 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3292 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3293 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3294 if((const DataArrayInt *)_fam_coords)
3295 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3296 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3297 if((const DataArrayInt *)_num_coords)
3298 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3299 if((const DataArrayAsciiChar *)_name_coords)
3300 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3301 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3302 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3304 if((MEDFileUMeshSplitL1*)*it)
3305 (*it)->renumberNodesInConn(ret->begin());
3311 * Adds a group of nodes to \a this mesh.
3312 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3313 * The ids should be sorted and different each other (MED file norm).
3314 * \throw If the node coordinates array is not set.
3315 * \throw If \a ids == \c NULL.
3316 * \throw If \a ids->getName() == "".
3317 * \throw If \a ids does not respect the MED file norm.
3318 * \throw If a group with name \a ids->getName() already exists.
3320 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3322 const DataArrayDouble *coords=_coords;
3324 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3325 int nbOfNodes=coords->getNumberOfTuples();
3326 if(!((DataArrayInt *)_fam_coords))
3327 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3329 addGroupUnderground(true,ids,_fam_coords);
3333 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3334 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3335 * The ids should be sorted and different each other (MED file norm).
3336 * \throw If the node coordinates array is not set.
3337 * \throw If \a ids == \c NULL.
3338 * \throw If \a ids->getName() == "".
3339 * \throw If \a ids does not respect the MED file norm.
3340 * \throw If a group with name \a ids->getName() already exists.
3342 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception)
3344 std::vector<int> levs=getNonEmptyLevelsExt();
3345 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3347 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3348 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3350 if(meshDimRelToMaxExt==1)
3351 { addNodeGroup(ids); return ; }
3352 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3353 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3354 addGroupUnderground(false,ids,fam);
3358 * \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).
3359 * \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)
3361 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3364 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3365 std::string grpName(ids->getName());
3367 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3368 ids->checkStrictlyMonotonic(true);
3369 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3370 std::vector<std::string> grpsNames=getGroupsNames();
3371 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3373 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3374 throw INTERP_KERNEL::Exception(oss.str().c_str());
3376 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3377 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3378 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3379 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3380 std::vector<int> familyIds;
3381 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3382 int maxVal=getTheMaxAbsFamilyId()+1;
3383 std::map<std::string,int> families(_families);
3384 std::map<std::string, std::vector<std::string> > groups(_groups);
3385 std::vector<std::string> fams;
3386 bool created(false);
3387 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3389 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3390 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3391 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3392 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3395 bool isFamPresent=false;
3396 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3397 isFamPresent=(*itl)->presenceOfValue(*famId);
3399 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3402 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3403 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3404 fams.push_back(locFamName);
3405 if(existsFamily(*famId))
3407 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3408 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3411 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3415 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3416 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3417 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3418 if(existsFamily(*famId))
3420 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3421 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId).c_str(),v);
3426 for(std::size_t i=0;i<familyIds.size();i++)
3428 DataArrayInt *da=idsPerfamiliyIds[i];
3429 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3433 _groups[grpName]=fams;
3437 * Changes a name of a family specified by its id.
3438 * \param [in] id - the id of the family of interest.
3439 * \param [in] newFamName - the new family name.
3440 * \throw If no family with the given \a id exists.
3442 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception)
3444 std::string oldName=getFamilyNameGivenId(id);
3445 _families.erase(oldName);
3446 _families[newFamName]=id;
3450 * Removes a mesh of a given dimension.
3451 * \param [in] meshDimRelToMax - the relative dimension of interest.
3452 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3454 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception)
3456 std::vector<int> levSet=getNonEmptyLevels();
3457 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3458 if(it==levSet.end())
3459 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3460 int pos=(-meshDimRelToMax);
3465 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3466 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3467 * \param [in] m - the new mesh to set.
3468 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3469 * writing \a this mesh in a MED file.
3470 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3472 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3473 * another node coordinates array.
3474 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3475 * to the existing meshes of other levels of \a this mesh.
3477 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) throw(INTERP_KERNEL::Exception)
3479 dealWithTinyInfo(m);
3480 std::vector<int> levSet=getNonEmptyLevels();
3481 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3483 if((DataArrayDouble *)_coords==0)
3485 DataArrayDouble *c=m->getCoords();
3490 if(m->getCoords()!=_coords)
3491 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3492 int sz=(-meshDimRelToMax)+1;
3493 if(sz>=(int)_ms.size())
3495 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3496 _ms[sz-1]=new MEDFileUMeshSplitL1(m,newOrOld);
3499 _ms[-meshDimRelToMax]=new MEDFileUMeshSplitL1(m,newOrOld);
3503 * This method allows to set at once the content of different levels in \a this.
3504 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3506 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3507 * \param [in] renum - the parameter (set to false by default) that tells the beheviour if there is a mesh on \a ms that is not geo type sorted.
3508 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3510 * \throw If \a there is a null pointer in \a ms.
3511 * \sa MEDFileUMesh::setMeshAtLevel
3513 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3517 const MEDCouplingUMesh *mRef=ms[0];
3519 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3520 std::string name(mRef->getName());
3521 const DataArrayDouble *coo(mRef->getCoords());
3524 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3526 const MEDCouplingUMesh *cur(*it);
3528 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3529 if(coo!=cur->getCoords())
3530 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3531 int mdim=cur->getMeshDimension();
3532 zeDim=std::max(zeDim,mdim);
3533 if(s.find(mdim)!=s.end())
3534 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3536 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3538 int mdim=(*it)->getMeshDimension();
3539 setName((*it)->getName().c_str());
3540 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3542 setName(name.c_str());
3546 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3547 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3548 * The given meshes must share the same node coordinates array.
3549 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3550 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3551 * create in \a this mesh.
3552 * \throw If \a ms is empty.
3553 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3554 * to the existing meshes of other levels of \a this mesh.
3555 * \throw If the meshes in \a ms do not share the same node coordinates array.
3556 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3557 * of the given meshes.
3558 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3559 * \throw If names of some meshes in \a ms are equal.
3560 * \throw If \a ms includes a mesh with an empty name.
3562 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3565 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3566 int sz=(-meshDimRelToMax)+1;
3567 if(sz>=(int)_ms.size())
3569 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3570 DataArrayDouble *coo=checkMultiMesh(ms);
3571 if((DataArrayDouble *)_coords==0)
3577 if((DataArrayDouble *)_coords!=coo)
3578 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3579 std::vector<DataArrayInt *> corr;
3580 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3581 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3582 setMeshAtLevel(meshDimRelToMax,m,renum);
3583 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3584 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3588 * Creates groups at a given level in \a this mesh from a sequence of
3589 * meshes each representing a group.
3590 * The given meshes must share the same node coordinates array.
3591 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3592 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3593 * create in \a this mesh.
3594 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3596 * \throw If \a ms is empty.
3597 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3598 * to the existing meshes of other levels of \a this mesh.
3599 * \throw If the meshes in \a ms do not share the same node coordinates array.
3600 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3601 * of the given meshes.
3602 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3603 * \throw If names of some meshes in \a ms are equal.
3604 * \throw If \a ms includes a mesh with an empty name.
3606 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) throw(INTERP_KERNEL::Exception)
3609 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3610 int sz=(-meshDimRelToMax)+1;
3611 if(sz>=(int)_ms.size())
3613 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3614 DataArrayDouble *coo=checkMultiMesh(ms);
3615 if((DataArrayDouble *)_coords==0)
3621 if((DataArrayDouble *)_coords!=coo)
3622 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3623 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3624 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3626 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3628 DataArrayInt *arr=0;
3629 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3633 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3634 throw INTERP_KERNEL::Exception(oss.str().c_str());
3637 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3638 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3641 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const throw(INTERP_KERNEL::Exception)
3643 const DataArrayDouble *ret=ms[0]->getCoords();
3644 int mdim=ms[0]->getMeshDimension();
3645 for(unsigned int i=1;i<ms.size();i++)
3647 ms[i]->checkCoherency();
3648 if(ms[i]->getCoords()!=ret)
3649 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3650 if(ms[i]->getMeshDimension()!=mdim)
3651 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3653 return const_cast<DataArrayDouble *>(ret);
3657 * Sets the family field of a given relative dimension.
3658 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3659 * the family field is set.
3660 * \param [in] famArr - the array of the family field.
3661 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3662 * \throw If \a famArr has an invalid size.
3664 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
3666 if(meshDimRelToMaxExt==1)
3673 DataArrayDouble *coo(_coords);
3675 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3676 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3681 if(meshDimRelToMaxExt>1)
3682 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3683 int traducedRk=-meshDimRelToMaxExt;
3684 if(traducedRk>=(int)_ms.size())
3685 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3686 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3687 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3688 return _ms[traducedRk]->setFamilyArr(famArr);
3692 * Sets the optional numbers of mesh entities of a given dimension.
3693 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3694 * \param [in] renumArr - the array of the numbers.
3695 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3696 * \throw If \a renumArr has an invalid size.
3698 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
3700 if(meshDimRelToMaxExt==1)
3708 DataArrayDouble *coo(_coords);
3710 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3711 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3712 renumArr->incrRef();
3713 _num_coords=renumArr;
3717 if(meshDimRelToMaxExt>1)
3718 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3719 int traducedRk=-meshDimRelToMaxExt;
3720 if(traducedRk>=(int)_ms.size())
3721 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3722 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3723 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3724 return _ms[traducedRk]->setRenumArr(renumArr);
3728 * Sets the optional names of mesh entities of a given dimension.
3729 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3730 * \param [in] nameArr - the array of the names.
3731 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3732 * \throw If \a nameArr has an invalid size.
3734 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
3736 if(meshDimRelToMaxExt==1)
3743 DataArrayDouble *coo(_coords);
3745 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3746 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3748 _name_coords=nameArr;
3751 if(meshDimRelToMaxExt>1)
3752 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3753 int traducedRk=-meshDimRelToMaxExt;
3754 if(traducedRk>=(int)_ms.size())
3755 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3756 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3757 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3758 return _ms[traducedRk]->setNameArr(nameArr);
3761 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3763 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3764 if((const MEDFileUMeshSplitL1 *)(*it))
3765 (*it)->synchronizeTinyInfo(*this);
3769 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3771 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
3773 DataArrayInt *arr=_fam_coords;
3775 arr->changeValue(oldId,newId);
3776 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3778 MEDFileUMeshSplitL1 *sp=(*it);
3781 sp->changeFamilyIdArr(oldId,newId);
3786 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3788 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3789 const DataArrayInt *da(_fam_coords);
3791 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3792 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3794 const MEDFileUMeshSplitL1 *elt(*it);
3797 da=elt->getFamilyField();
3799 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3805 void MEDFileUMesh::computeRevNum() const
3807 if((const DataArrayInt *)_num_coords)
3810 int maxValue=_num_coords->getMaxValue(pos);
3811 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3815 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
3817 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
3820 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildren() const
3822 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
3823 if((const DataArrayInt *)_fam_nodes)
3824 ret.push_back((const DataArrayInt *)_fam_nodes);
3825 if((const DataArrayInt *)_num_nodes)
3826 ret.push_back((const DataArrayInt *)_num_nodes);
3827 if((const DataArrayInt *)_fam_cells)
3828 ret.push_back((const DataArrayInt *)_fam_cells);
3829 if((const DataArrayInt *)_num_cells)
3830 ret.push_back((const DataArrayInt *)_num_nodes);
3831 if((const DataArrayInt *)_rev_num_nodes)
3832 ret.push_back((const DataArrayInt *)_rev_num_nodes);
3833 if((const DataArrayInt *)_rev_num_cells)
3834 ret.push_back((const DataArrayInt *)_rev_num_cells);
3838 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3840 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3841 if((const DataArrayInt *)_fam_nodes)
3843 int val=_fam_nodes->getMaxValue(tmp);
3844 ret=std::max(ret,std::abs(val));
3846 if((const DataArrayInt *)_fam_cells)
3848 int val=_fam_cells->getMaxValue(tmp);
3849 ret=std::max(ret,std::abs(val));
3854 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3856 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3857 if((const DataArrayInt *)_fam_nodes)
3859 int val=_fam_nodes->getMaxValue(tmp);
3860 ret=std::max(ret,val);
3862 if((const DataArrayInt *)_fam_cells)
3864 int val=_fam_cells->getMaxValue(tmp);
3865 ret=std::max(ret,val);
3870 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception)
3872 int ret=std::numeric_limits<int>::max(),tmp=-1;
3873 if((const DataArrayInt *)_fam_nodes)
3875 int val=_fam_nodes->getMinValue(tmp);
3876 ret=std::min(ret,val);
3878 if((const DataArrayInt *)_fam_cells)
3880 int val=_fam_cells->getMinValue(tmp);
3881 ret=std::min(ret,val);
3886 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
3888 if(!MEDFileMesh::isEqual(other,eps,what))
3890 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
3893 what="Mesh types differ ! This is structured and other is NOT !";
3896 const DataArrayInt *famc1=_fam_nodes;
3897 const DataArrayInt *famc2=otherC->_fam_nodes;
3898 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3900 what="Mismatch of families arr on nodes ! One is defined and not other !";
3905 bool ret=famc1->isEqual(*famc2);
3908 what="Families arr on nodes differ !";
3913 famc2=otherC->_fam_cells;
3914 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3916 what="Mismatch of families arr on cells ! One is defined and not other !";
3921 bool ret=famc1->isEqual(*famc2);
3924 what="Families arr on cells differ !";
3929 famc2=otherC->_num_nodes;
3930 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3932 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
3937 bool ret=famc1->isEqual(*famc2);
3940 what="Numbering arr on nodes differ !";
3945 famc2=otherC->_num_cells;
3946 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
3948 what="Mismatch of numbering arr on cells ! One is defined and not other !";
3953 bool ret=famc1->isEqual(*famc2);
3956 what="Numbering arr on cells differ !";
3960 const DataArrayAsciiChar *d1=_names_cells;
3961 const DataArrayAsciiChar *d2=otherC->_names_cells;
3962 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3964 what="Mismatch of naming arr on cells ! One is defined and not other !";
3969 bool ret=d1->isEqual(*d2);
3972 what="Naming arr on cells differ !";
3977 d2=otherC->_names_nodes;
3978 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
3980 what="Mismatch of naming arr on nodes ! One is defined and not other !";
3985 bool ret=d1->isEqual(*d2);
3988 what="Naming arr on nodes differ !";
3995 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
3997 MEDFileMesh::clearNonDiscrAttributes();
3998 const DataArrayInt *tmp=_fam_nodes;
4000 (const_cast<DataArrayInt *>(tmp))->setName("");
4003 (const_cast<DataArrayInt *>(tmp))->setName("");
4006 (const_cast<DataArrayInt *>(tmp))->setName("");
4009 (const_cast<DataArrayInt *>(tmp))->setName("");
4013 * Returns ids of mesh entities contained in given families of a given dimension.
4014 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4016 * \param [in] fams - the names of the families of interest.
4017 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4018 * returned instead of ids.
4019 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4020 * numbers, if available and required, of mesh entities of the families. The caller
4021 * is to delete this array using decrRef() as it is no more needed.
4022 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4024 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const throw(INTERP_KERNEL::Exception)
4026 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4027 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
4028 std::vector<int> famIds=getFamiliesIds(fams);
4029 if(meshDimRelToMaxExt==1)
4031 if((const DataArrayInt *)_fam_nodes)
4033 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4035 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4037 da=_fam_nodes->getIdsEqualList(0,0);
4039 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4044 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4048 if((const DataArrayInt *)_fam_cells)
4050 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4052 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4054 da=_fam_cells->getIdsEqualList(0,0);
4056 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4061 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4066 * Sets the family field of a given relative dimension.
4067 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4068 * the family field is set.
4069 * \param [in] famArr - the array of the family field.
4070 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4071 * \throw If \a famArr has an invalid size.
4072 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4074 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception)
4076 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4077 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4078 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4080 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4081 if(meshDimRelToMaxExt==0)
4083 int nbCells=mesh->getNumberOfCells();
4084 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4089 int nbNodes=mesh->getNumberOfNodes();
4090 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4098 * Sets the optional numbers of mesh entities of a given dimension.
4099 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4100 * \param [in] renumArr - the array of the numbers.
4101 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4102 * \throw If \a renumArr has an invalid size.
4103 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4105 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception)
4107 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4108 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4109 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4111 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4112 if(meshDimRelToMaxExt==0)
4114 int nbCells=mesh->getNumberOfCells();
4115 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4116 _num_cells=renumArr;
4120 int nbNodes=mesh->getNumberOfNodes();
4121 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4122 _num_nodes=renumArr;
4125 renumArr->incrRef();
4129 * Sets the optional names of mesh entities of a given dimension.
4130 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4131 * \param [in] nameArr - the array of the names.
4132 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4133 * \throw If \a nameArr has an invalid size.
4135 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception)
4137 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4138 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
4139 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4141 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4142 if(meshDimRelToMaxExt==0)
4144 int nbCells=mesh->getNumberOfCells();
4145 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4146 _names_cells=nameArr;
4150 int nbNodes=mesh->getNumberOfNodes();
4151 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4152 _names_nodes=nameArr;
4159 * Returns the family field for mesh entities of a given dimension.
4160 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4161 * \return const DataArrayInt * - the family field. It is an array of ids of families
4162 * each mesh entity belongs to. It can be \c NULL.
4163 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4165 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4167 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4168 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
4169 if(meshDimRelToMaxExt==0)
4176 * Returns the optional numbers of mesh entities of a given dimension.
4177 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4178 * \return const DataArrayInt * - the array of the entity numbers.
4179 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4180 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4182 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4184 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4185 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
4186 if(meshDimRelToMaxExt==0)
4193 * Returns the optional numbers of mesh entities of a given dimension transformed using
4194 * DataArrayInt::invertArrayN2O2O2N().
4195 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4196 * \return const DataArrayInt * - the array of the entity numbers transformed using
4197 * DataArrayInt::invertArrayN2O2O2N().
4198 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4199 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4201 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4203 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4204 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4205 if(meshDimRelToMaxExt==0)
4207 if((const DataArrayInt *)_num_cells)
4210 int maxValue=_num_cells->getMaxValue(pos);
4211 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4212 return _rev_num_cells;
4215 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4219 if((const DataArrayInt *)_num_nodes)
4222 int maxValue=_num_nodes->getMaxValue(pos);
4223 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4224 return _rev_num_nodes;
4227 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4231 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4233 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4234 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
4235 if(meshDimRelToMaxExt==0)
4236 return _names_cells;
4238 return _names_nodes;
4242 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4243 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4245 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4247 std::vector<int> ret(1);
4252 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4253 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4255 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4257 std::vector<int> ret(2);
4263 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4265 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4267 std::vector<int> ret;
4268 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells);
4277 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4279 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4281 std::vector<int> ret;
4282 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells);
4291 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4293 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4295 std::vector<int> ret;
4296 const DataArrayAsciiChar *namesCells(_names_cells);
4303 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4305 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception)
4307 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4311 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) throw(INTERP_KERNEL::Exception)
4313 DataArrayInt *arr=_fam_nodes;
4315 arr->changeValue(oldId,newId);
4318 arr->changeValue(oldId,newId);
4321 void MEDFileStructuredMesh::deepCpyAttributes() throw(INTERP_KERNEL::Exception)
4323 if((const DataArrayInt*)_fam_nodes)
4324 _fam_nodes=_fam_nodes->deepCpy();
4325 if((const DataArrayInt*)_num_nodes)
4326 _num_nodes=_num_nodes->deepCpy();
4327 if((const DataArrayInt*)_fam_cells)
4328 _fam_cells=_fam_cells->deepCpy();
4329 if((const DataArrayInt*)_num_cells)
4330 _num_cells=_num_cells->deepCpy();
4331 if((const DataArrayInt*)_rev_num_nodes)
4332 _rev_num_nodes=_rev_num_nodes->deepCpy();
4333 if((const DataArrayInt*)_rev_num_cells)
4334 _rev_num_cells=_rev_num_cells->deepCpy();
4338 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4340 * \return a pointer to cartesian mesh that need to be managed by the caller.
4341 * \warning the returned pointer has to be managed by the caller.
4345 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4346 * \param [in] meshDimRelToMax - it must be \c 0.
4347 * \param [in] renum - it must be \c false.
4348 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4349 * delete using decrRef() as it is no more needed.
4351 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const throw(INTERP_KERNEL::Exception)
4354 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4355 if(meshDimRelToMax!=0)
4356 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4357 const MEDCouplingStructuredMesh *m=getStructuredMesh();
4360 return const_cast<MEDCouplingStructuredMesh *>(m);
4364 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4365 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4366 * \return int - the number of entities.
4367 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4369 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
4371 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4372 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
4373 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4375 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4376 if(meshDimRelToMaxExt==0)
4377 return cmesh->getNumberOfCells();
4379 return cmesh->getNumberOfNodes();
4382 int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
4384 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4386 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4387 return cmesh->getNumberOfNodes();
4390 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
4392 if(st.getNumberOfItems()!=1)
4393 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !");
4394 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4395 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4396 if(getNumberOfNodes()!=(int)nodesFetched.size())
4397 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4398 if(st[0].getPflName().empty())
4400 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4403 const DataArrayInt *arr(globs->getProfile(st[0].getPflName().c_str()));
4404 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4405 int sz(nodesFetched.size());
4406 for(const int *work=arr->begin();work!=arr->end();work++)
4408 std::vector<int> conn;
4409 cmesh->getNodeIdsOfCell(*work,conn);
4410 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4411 if(*it>=0 && *it<sz)
4412 nodesFetched[*it]=true;
4414 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4418 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
4420 med_geometry_type geoTypeReq=MED_NONE;
4424 geoTypeReq=MED_HEXA8;
4427 geoTypeReq=MED_QUAD4;
4430 geoTypeReq=MED_SEG2;
4433 geoTypeReq=MED_POINT1;
4436 throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
4441 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4443 setName(strm->getName());
4444 setDescription(strm->getDescription());
4445 setUnivName(strm->getUnivName());
4446 setIteration(strm->getIteration());
4447 setOrder(strm->getOrder());
4448 setTimeValue(strm->getTime());
4449 setTimeUnit(strm->getTimeUnit());
4450 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4451 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4452 int nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4455 if(!mrs || mrs->isNodeFamilyFieldReading())
4457 _fam_nodes=DataArrayInt::New();
4458 _fam_nodes->alloc(nbOfElt,1);
4459 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4462 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4465 if(!mrs || mrs->isNodeNumFieldReading())
4467 _num_nodes=DataArrayInt::New();
4468 _num_nodes->alloc(nbOfElt,1);
4469 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4472 int meshDim=getStructuredMesh()->getMeshDimension();
4473 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4474 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4477 if(!mrs || mrs->isCellFamilyFieldReading())
4479 _fam_cells=DataArrayInt::New();
4480 _fam_cells->alloc(nbOfElt,1);
4481 MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
4484 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4487 if(!mrs || mrs->isCellNumFieldReading())
4489 _num_cells=DataArrayInt::New();
4490 _num_cells->alloc(nbOfElt,1);
4491 MEDmeshEntityNumberRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
4494 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4497 if(!mrs || mrs->isCellNameFieldReading())
4499 _names_cells=DataArrayAsciiChar::New();
4500 _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4501 MEDmeshEntityNameRd(fid,mName,dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
4502 _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4505 nbOfElt=MEDmeshnEntity(fid,mName,dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4508 if(!mrs || mrs->isNodeNameFieldReading())
4510 _names_nodes=DataArrayAsciiChar::New();
4511 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4512 MEDmeshEntityNameRd(fid,mName,dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4513 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4518 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const char *maa) const throw(INTERP_KERNEL::Exception)
4520 int meshDim=getStructuredMesh()->getMeshDimension();
4521 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4523 if((const DataArrayInt *)_fam_cells)
4524 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4525 if((const DataArrayInt *)_fam_nodes)
4526 MEDmeshEntityFamilyNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4527 if((const DataArrayInt *)_num_cells)
4528 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4529 if((const DataArrayInt *)_num_nodes)
4530 MEDmeshEntityNumberWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4531 if((const DataArrayAsciiChar *)_names_cells)
4533 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4535 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4536 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4537 throw INTERP_KERNEL::Exception(oss.str().c_str());
4539 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4541 if((const DataArrayAsciiChar *)_names_nodes)
4543 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4545 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4546 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4547 throw INTERP_KERNEL::Exception(oss.str().c_str());
4549 MEDmeshEntityNameWr(fid,maa,_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4552 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa,_families,_groups,_too_long_str);
4556 * Returns an empty instance of MEDFileCMesh.
4557 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4558 * mesh using decrRef() as it is no more needed.
4560 MEDFileCMesh *MEDFileCMesh::New()
4562 return new MEDFileCMesh;
4566 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4567 * file. The first mesh in the file is loaded.
4568 * \param [in] fileName - the name of MED file to read.
4569 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4570 * mesh using decrRef() as it is no more needed.
4571 * \throw If the file is not readable.
4572 * \throw If there is no meshes in the file.
4573 * \throw If the mesh in the file is not a Cartesian one.
4575 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4577 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4580 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4581 throw INTERP_KERNEL::Exception(oss.str().c_str());
4583 MEDFileUtilities::CheckFileForRead(fileName);
4584 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4586 ParaMEDMEM::MEDCouplingMeshType meshType;
4588 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4589 return new MEDFileCMesh(fid,ms.front().c_str(),dt,it,mrs);
4593 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4594 * file. The mesh to load is specified by its name and numbers of a time step and an
4596 * \param [in] fileName - the name of MED file to read.
4597 * \param [in] mName - the name of the mesh to read.
4598 * \param [in] dt - the number of a time step.
4599 * \param [in] it - the number of an iteration.
4600 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4601 * mesh using decrRef() as it is no more needed.
4602 * \throw If the file is not readable.
4603 * \throw If there is no mesh with given attributes in the file.
4604 * \throw If the mesh in the file is not a Cartesian one.
4606 MEDFileCMesh *MEDFileCMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4608 MEDFileUtilities::CheckFileForRead(fileName);
4609 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4610 return new MEDFileCMesh(fid,mName,dt,it,mrs);
4613 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
4615 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
4618 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildren() const
4620 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
4621 if((const MEDCouplingCMesh *)_cmesh)
4622 ret.push_back((const MEDCouplingCMesh *)_cmesh);
4627 * Returns the dimension on cells in \a this mesh.
4628 * \return int - the mesh dimension.
4629 * \throw If there are no cells in this mesh.
4631 int MEDFileCMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4633 if(!((const MEDCouplingCMesh*)_cmesh))
4634 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4635 return _cmesh->getMeshDimension();
4639 * Returns a string describing \a this mesh.
4640 * \return std::string - the mesh information string.
4642 std::string MEDFileCMesh::simpleRepr() const
4644 return MEDFileStructuredMesh::simpleRepr();
4648 * Returns a full textual description of \a this mesh.
4649 * \return std::string - the string holding the mesh description.
4651 std::string MEDFileCMesh::advancedRepr() const
4653 return simpleRepr();
4656 MEDFileMesh *MEDFileCMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4658 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4662 MEDFileMesh *MEDFileCMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4664 return new MEDFileCMesh;
4667 MEDFileMesh *MEDFileCMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4669 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4670 if((const MEDCouplingCMesh*)_cmesh)
4671 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
4672 ret->deepCpyAttributes();
4677 * Checks if \a this and another mesh are equal.
4678 * \param [in] other - the mesh to compare with.
4679 * \param [in] eps - a precision used to compare real values.
4680 * \param [in,out] what - the string returning description of unequal data.
4681 * \return bool - \c true if the meshes are equal, \c false, else.
4683 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4685 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4687 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
4690 what="Mesh types differ ! This is cartesian and other is NOT !";
4693 clearNonDiscrAttributes();
4694 otherC->clearNonDiscrAttributes();
4695 const MEDCouplingCMesh *coo1=_cmesh;
4696 const MEDCouplingCMesh *coo2=otherC->_cmesh;
4697 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4699 what="Mismatch of cartesian meshes ! One is defined and not other !";
4704 bool ret=coo1->isEqual(coo2,eps);
4707 what="cartesian meshes differ !";
4715 * Clears redundant attributes of incorporated data arrays.
4717 void MEDFileCMesh::clearNonDiscrAttributes() const
4719 MEDFileStructuredMesh::clearNonDiscrAttributes();
4720 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
4723 MEDFileCMesh::MEDFileCMesh()
4727 MEDFileCMesh::MEDFileCMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4730 loadCMeshFromFile(fid,mName,dt,it,mrs);
4732 catch(INTERP_KERNEL::Exception& e)
4737 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4739 ParaMEDMEM::MEDCouplingMeshType meshType;
4742 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4743 if(meshType!=CARTESIAN)
4745 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
4746 throw INTERP_KERNEL::Exception(oss.str().c_str());
4748 MEDFileCMeshL2 loaderl2;
4749 loaderl2.loadAll(fid,mid,mName,dt,it);
4750 MEDCouplingCMesh *mesh=loaderl2.getMesh();
4753 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
4757 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
4758 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
4760 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
4762 synchronizeTinyInfoOnLeaves();
4766 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
4768 synchronizeTinyInfoOnLeaves();
4773 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
4774 * \param [in] m - the new MEDCouplingCMesh to refer to.
4775 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4778 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception)
4780 dealWithTinyInfo(m);
4786 void MEDFileCMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4788 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4789 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4790 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4791 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4792 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4793 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4794 int spaceDim=_cmesh->getSpaceDimension();
4795 int meshDim=_cmesh->getMeshDimension();
4796 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4797 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4798 for(int i=0;i<spaceDim;i++)
4800 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
4802 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4803 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
4804 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
4806 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4807 MEDmeshUniversalNameWr(fid,maa);
4808 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
4809 for(int i=0;i<spaceDim;i++)
4811 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
4812 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
4815 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
4818 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
4820 const MEDCouplingCMesh *cmesh=_cmesh;
4823 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name.c_str());
4824 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name.c_str());
4825 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
4826 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit.c_str());
4829 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
4831 return new MEDFileCurveLinearMesh;
4834 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4836 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4839 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4840 throw INTERP_KERNEL::Exception(oss.str().c_str());
4842 MEDFileUtilities::CheckFileForRead(fileName);
4843 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4845 ParaMEDMEM::MEDCouplingMeshType meshType;
4847 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
4848 return new MEDFileCurveLinearMesh(fid,ms.front().c_str(),dt,it,mrs);
4851 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const char *fileName, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4853 MEDFileUtilities::CheckFileForRead(fileName);
4854 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
4855 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
4858 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
4860 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
4863 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildren() const
4865 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
4866 if((const MEDCouplingCurveLinearMesh *)_clmesh)
4867 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
4871 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const throw(INTERP_KERNEL::Exception)
4873 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4877 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const throw(INTERP_KERNEL::Exception)
4879 return new MEDFileCurveLinearMesh;
4882 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const throw(INTERP_KERNEL::Exception)
4884 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
4885 if((const MEDCouplingCurveLinearMesh*)_clmesh)
4886 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
4887 ret->deepCpyAttributes();
4891 int MEDFileCurveLinearMesh::getMeshDimension() const throw(INTERP_KERNEL::Exception)
4893 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
4894 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4895 return _clmesh->getMeshDimension();
4898 std::string MEDFileCurveLinearMesh::simpleRepr() const
4900 return MEDFileStructuredMesh::simpleRepr();
4903 std::string MEDFileCurveLinearMesh::advancedRepr() const
4905 return simpleRepr();
4908 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4910 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4912 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
4915 what="Mesh types differ ! This is curve linear and other is NOT !";
4918 clearNonDiscrAttributes();
4919 otherC->clearNonDiscrAttributes();
4920 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
4921 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
4922 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4924 what="Mismatch of curve linear meshes ! One is defined and not other !";
4929 bool ret=coo1->isEqual(coo2,eps);
4932 what="curve linear meshes differ !";
4939 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
4941 MEDFileStructuredMesh::clearNonDiscrAttributes();
4942 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
4945 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
4947 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
4950 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name.c_str());
4951 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name.c_str());
4952 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
4953 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit.c_str());
4956 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
4958 synchronizeTinyInfoOnLeaves();
4962 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception)
4964 dealWithTinyInfo(m);
4970 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
4972 synchronizeTinyInfoOnLeaves();
4976 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
4980 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
4983 loadCLMeshFromFile(fid,mName,dt,it,mrs);
4985 catch(INTERP_KERNEL::Exception& e)
4990 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception)
4992 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4993 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4994 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4995 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4996 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4997 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4998 int spaceDim=_clmesh->getSpaceDimension();
4999 int meshDim=_clmesh->getMeshDimension();
5000 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5001 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5002 const DataArrayDouble *coords=_clmesh->getCoords();
5004 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
5005 for(int i=0;i<spaceDim;i++)
5007 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
5009 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5010 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
5011 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
5013 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5014 MEDmeshUniversalNameWr(fid,maa);
5015 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5016 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5017 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5019 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5021 MEDFileStructuredMesh::writeStructuredLL(fid,maa);
5024 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const char *mName, int dt, int it, MEDFileMeshReadSelector *mrs) throw(INTERP_KERNEL::Exception)
5026 ParaMEDMEM::MEDCouplingMeshType meshType;
5029 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5030 if(meshType!=CURVE_LINEAR)
5032 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5033 throw INTERP_KERNEL::Exception(oss.str().c_str());
5035 MEDFileCLMeshL2 loaderl2;
5036 loaderl2.loadAll(fid,mid,mName,dt,it);
5037 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5040 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5043 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5045 return new MEDFileMeshMultiTS;
5048 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
5050 return new MEDFileMeshMultiTS(fileName);
5053 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5055 return new MEDFileMeshMultiTS(fileName,mName);
5058 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const throw(INTERP_KERNEL::Exception)
5060 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5061 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5063 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5064 if((const MEDFileMesh *)*it)
5065 meshOneTs[i]=(*it)->deepCpy();
5066 ret->_mesh_one_ts=meshOneTs;
5070 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
5072 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5075 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildren() const
5077 std::vector<const BigMemoryObject *> ret;
5078 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5080 const MEDFileMesh *cur(*it);
5087 std::string MEDFileMeshMultiTS::getName() const throw(INTERP_KERNEL::Exception)
5089 if(_mesh_one_ts.empty())
5090 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5091 return _mesh_one_ts[0]->getName();
5094 void MEDFileMeshMultiTS::setName(const char *newMeshName) throw(INTERP_KERNEL::Exception)
5096 std::string oldName(getName());
5097 std::vector< std::pair<std::string,std::string> > v(1);
5098 v[0].first=oldName; v[0].second=newMeshName;
5102 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
5105 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5107 MEDFileMesh *cur(*it);
5109 ret=cur->changeNames(modifTab) || ret;
5114 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const throw(INTERP_KERNEL::Exception)
5116 if(_mesh_one_ts.empty())
5117 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5118 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5121 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception)
5124 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5125 _mesh_one_ts.resize(1);
5126 mesh1TimeStep->incrRef();
5127 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5128 _mesh_one_ts[0]=mesh1TimeStep;
5131 void MEDFileMeshMultiTS::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5133 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5135 (*it)->copyOptionsFrom(*this);
5140 void MEDFileMeshMultiTS::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5142 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5143 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5144 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5145 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5149 void MEDFileMeshMultiTS::loadFromFile(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5150 {//for the moment to be improved
5151 _mesh_one_ts.resize(1);
5152 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5155 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5159 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName) throw(INTERP_KERNEL::Exception)
5162 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5165 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5166 throw INTERP_KERNEL::Exception(oss.str().c_str());
5168 MEDFileUtilities::CheckFileForRead(fileName);
5169 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
5171 ParaMEDMEM::MEDCouplingMeshType meshType;
5173 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front().c_str(),meshType,dt,it,dummy2);
5174 loadFromFile(fileName,ms.front().c_str());
5176 catch(INTERP_KERNEL::Exception& e)
5181 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const char *fileName, const char *mName) throw(INTERP_KERNEL::Exception)
5184 loadFromFile(fileName,mName);
5186 catch(INTERP_KERNEL::Exception& e)
5191 MEDFileMeshes *MEDFileMeshes::New()
5193 return new MEDFileMeshes;
5196 MEDFileMeshes *MEDFileMeshes::New(const char *fileName) throw(INTERP_KERNEL::Exception)
5198 return new MEDFileMeshes(fileName);
5201 void MEDFileMeshes::write(med_idt fid) const throw(INTERP_KERNEL::Exception)
5204 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5206 (*it)->copyOptionsFrom(*this);
5211 void MEDFileMeshes::write(const char *fileName, int mode) const throw(INTERP_KERNEL::Exception)
5213 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5214 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,medmod);
5215 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5216 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str().c_str());
5221 int MEDFileMeshes::getNumberOfMeshes() const throw(INTERP_KERNEL::Exception)
5223 return _meshes.size();
5226 MEDFileMeshesIterator *MEDFileMeshes::iterator() throw(INTERP_KERNEL::Exception)
5228 return new MEDFileMeshesIterator(this);
5231 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception)
5233 if(i<0 || i>=(int)_meshes.size())
5235 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5236 throw INTERP_KERNEL::Exception(oss.str().c_str());
5238 return _meshes[i]->getOneTimeStep();
5241 MEDFileMesh *MEDFileMeshes::getMeshWithName(const char *mname) const throw(INTERP_KERNEL::Exception)
5243 std::vector<std::string> ms=getMeshesNames();
5244 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5247 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5248 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5249 throw INTERP_KERNEL::Exception(oss.str().c_str());
5251 return getMeshAtPos((int)std::distance(ms.begin(),it));
5254 std::vector<std::string> MEDFileMeshes::getMeshesNames() const throw(INTERP_KERNEL::Exception)
5256 std::vector<std::string> ret(_meshes.size());
5258 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5260 const MEDFileMeshMultiTS *f=(*it);
5263 ret[i]=f->getName();
5267 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5268 throw INTERP_KERNEL::Exception(oss.str().c_str());
5274 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception)
5277 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5279 MEDFileMeshMultiTS *cur(*it);
5281 ret=cur->changeNames(modifTab) || ret;
5286 void MEDFileMeshes::resize(int newSize) throw(INTERP_KERNEL::Exception)
5288 _meshes.resize(newSize);
5291 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5294 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5295 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5296 elt->setOneTimeStep(mesh);
5297 _meshes.push_back(elt);
5300 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception)
5303 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5304 if(i>=(int)_meshes.size())
5305 _meshes.resize(i+1);
5306 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5307 elt->setOneTimeStep(mesh);
5311 void MEDFileMeshes::destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception)
5313 if(i<0 || i>=(int)_meshes.size())
5315 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5316 throw INTERP_KERNEL::Exception(oss.str().c_str());
5318 _meshes.erase(_meshes.begin()+i);
5321 void MEDFileMeshes::loadFromFile(const char *fileName) throw(INTERP_KERNEL::Exception)
5323 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5325 _meshes.resize(ms.size());
5326 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5327 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it).c_str());
5330 MEDFileMeshes::MEDFileMeshes()
5334 MEDFileMeshes::MEDFileMeshes(const char *fileName) throw(INTERP_KERNEL::Exception)
5337 loadFromFile(fileName);
5339 catch(INTERP_KERNEL::Exception& /*e*/)
5343 MEDFileMeshes *MEDFileMeshes::deepCpy() const throw(INTERP_KERNEL::Exception)
5345 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5347 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5348 if((const MEDFileMeshMultiTS *)*it)
5349 meshes[i]=(*it)->deepCpy();
5350 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5351 ret->_meshes=meshes;
5355 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
5357 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5360 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildren() const
5362 std::vector<const BigMemoryObject *> ret;
5363 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5365 const MEDFileMeshMultiTS *cur(*it);
5372 std::string MEDFileMeshes::simpleRepr() const
5374 std::ostringstream oss;
5375 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5376 simpleReprWithoutHeader(oss);
5380 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5382 int nbOfMeshes=getNumberOfMeshes();
5383 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5384 std::vector<std::string> mns=getMeshesNames();
5385 for(int i=0;i<nbOfMeshes;i++)
5386 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5389 void MEDFileMeshes::checkCoherency() const throw(INTERP_KERNEL::Exception)
5391 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5393 std::set<std::string> s;
5394 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5396 const MEDFileMeshMultiTS *elt=(*it);
5399 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5400 throw INTERP_KERNEL::Exception(oss.str().c_str());
5402 std::size_t sz=s.size();
5403 s.insert(std::string((*it)->getName()));
5406 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5407 throw INTERP_KERNEL::Exception(oss.str().c_str());
5412 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5417 _nb_iter=ms->getNumberOfMeshes();
5421 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5425 MEDFileMesh *MEDFileMeshesIterator::nextt()
5427 if(_iter_id<_nb_iter)
5429 MEDFileMeshes *ms(_ms);
5431 return ms->getMeshAtPos(_iter_id++);