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 std::string& fileName, MEDFileMeshReadSelector *mrs)
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.c_str(),MED_ACC_RDONLY);
85 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
90 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
91 ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
92 return (MEDFileUMesh *)ret.retn();
96 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
97 ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
98 return (MEDFileCMesh *)ret.retn();
102 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
103 ret->loadCLMeshFromFile(fid,ms.front(),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 std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
130 MEDFileUtilities::CheckFileForRead(fileName);
131 ParaMEDMEM::MEDCouplingMeshType meshType;
132 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),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
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 std::string& fileName, int mode) const
192 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
193 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
194 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
195 MEDFileUtilities::CheckMEDCode(fid,fid,oss.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))
246 void MEDFileMesh::setName(const std::string& name)
252 * Clears redundant attributes of incorporated data arrays.
254 void MEDFileMesh::clearNonDiscrAttributes() const
259 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
261 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
263 if((*it).first==_name)
273 * Copies data on groups and families from another mesh.
274 * \param [in] other - the mesh to copy the data from.
276 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
278 _groups=other._groups;
279 _families=other._families;
284 * This method clear all the groups in the map.
285 * So this method does not operate at all on arrays.
286 * So this method can lead to orphan families.
288 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
290 void MEDFileMesh::clearGrpMap()
296 * This method clear all the families in the map.
297 * So this method does not operate at all on arrays.
298 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
300 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
302 void MEDFileMesh::clearFamMap()
308 * This method clear all the families and groups in the map.
309 * So this method does not operate at all on arrays.
310 * As all groups and families entry will be removed after
311 * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object.
313 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
315 void MEDFileMesh::clearFamGrpMaps()
322 * Returns names of families constituting a group.
323 * \param [in] name - the name of the group of interest.
324 * \return std::vector<std::string> - a sequence of names of the families.
325 * \throw If the name of a nonexistent group is specified.
327 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
329 std::string oname(name);
330 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
331 if(it==_groups.end())
333 std::vector<std::string> grps=getGroupsNames();
334 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
335 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
336 throw INTERP_KERNEL::Exception(oss.str().c_str());
342 * Returns names of families constituting some groups.
343 * \param [in] grps - a sequence of names of groups of interest.
344 * \return std::vector<std::string> - a sequence of names of the families.
345 * \throw If a name of a nonexistent group is present in \a grps.
347 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
349 std::set<std::string> fams;
350 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
352 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
353 if(it2==_groups.end())
355 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
356 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
357 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
358 throw INTERP_KERNEL::Exception(oss.str().c_str());
360 fams.insert((*it2).second.begin(),(*it2).second.end());
362 std::vector<std::string> fams2(fams.begin(),fams.end());
367 * Returns ids of families constituting a group.
368 * \param [in] name - the name of the group of interest.
369 * \return std::vector<int> - sequence of ids of the families.
370 * \throw If the name of a nonexistent group is specified.
372 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
374 std::string oname(name);
375 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
376 std::vector<std::string> grps=getGroupsNames();
377 if(it==_groups.end())
379 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
380 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
381 throw INTERP_KERNEL::Exception(oss.str().c_str());
383 return getFamiliesIds((*it).second);
387 * Sets names of families constituting a group. If data on families of this group is
388 * already present, it is overwritten. Every family in \a fams is checked, and if a
389 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
390 * \param [in] name - the name of the group of interest.
391 * \param [in] fams - a sequence of names of families constituting the group.
393 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
395 std::string oname(name);
397 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
399 std::map<std::string,int>::iterator it2=_families.find(*it1);
400 if(it2==_families.end())
406 * Sets families constituting a group. The families are specified by their ids.
407 * If a family name is not found by its id, an exception is thrown.
408 * If several families have same id, the first one in lexical order is taken.
409 * \param [in] name - the name of the group of interest.
410 * \param [in] famIds - a sequence of ids of families constituting the group.
411 * \throw If a family name is not found by its id.
413 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
415 std::string oname(name);
416 std::vector<std::string> fams(famIds.size());
418 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
420 std::string name2=getFamilyNameGivenId(*it1);
427 * Returns names of groups including a given family.
428 * \param [in] name - the name of the family of interest.
429 * \return std::vector<std::string> - a sequence of names of groups including the family.
431 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
433 std::vector<std::string> ret;
434 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
436 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
439 ret.push_back((*it1).first);
447 * Adds an existing family to groups.
448 * \param [in] famName - a name of family to add to \a grps.
449 * \param [in] grps - a sequence of group names to add the family in.
450 * \throw If a family named \a famName not yet exists.
452 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
454 std::string fName(famName);
455 const std::map<std::string,int>::const_iterator it=_families.find(fName);
456 if(it==_families.end())
458 std::vector<std::string> fams=getFamiliesNames();
459 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
460 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
461 throw INTERP_KERNEL::Exception(oss.str().c_str());
463 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
465 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
466 if(it2!=_groups.end())
467 (*it2).second.push_back(fName);
470 std::vector<std::string> grps2(1,fName);
477 * Returns names of all groups of \a this mesh.
478 * \return std::vector<std::string> - a sequence of group names.
480 std::vector<std::string> MEDFileMesh::getGroupsNames() const
482 std::vector<std::string> ret(_groups.size());
484 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
490 * Returns names of all families of \a this mesh.
491 * \return std::vector<std::string> - a sequence of family names.
493 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
495 std::vector<std::string> ret(_families.size());
497 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
503 * Changes a name of every family, included in one group only, to be same as the group name.
504 * \throw If there are families with equal names in \a this mesh.
506 void MEDFileMesh::assignFamilyNameWithGroupName()
508 std::map<std::string, std::vector<std::string> > groups(_groups);
509 std::map<std::string,int> newFams;
510 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
512 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
513 if(grps.size()==1 && groups[grps[0]].size()==1)
515 if(newFams.find(grps[0])!=newFams.end())
517 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
518 throw INTERP_KERNEL::Exception(oss.str().c_str());
520 newFams[grps[0]]=(*it).second;
521 std::vector<std::string>& grps2=groups[grps[0]];
522 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
527 if(newFams.find((*it).first)!=newFams.end())
529 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
530 throw INTERP_KERNEL::Exception(oss.str().c_str());
532 newFams[(*it).first]=(*it).second;
540 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
542 * \return the removed groups.
544 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
546 std::vector<std::string> ret;
547 std::map<std::string, std::vector<std::string> > newGrps;
548 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
550 if((*it).second.empty())
551 ret.push_back((*it).first);
553 newGrps[(*it).first]=(*it).second;
561 * Removes a group from \a this mesh.
562 * \param [in] name - the name of the group to remove.
563 * \throw If no group with such a \a name exists.
565 void MEDFileMesh::removeGroup(const std::string& name)
567 std::string oname(name);
568 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
569 std::vector<std::string> grps=getGroupsNames();
570 if(it==_groups.end())
572 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
573 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
574 throw INTERP_KERNEL::Exception(oss.str().c_str());
580 * Removes a family from \a this mesh.
581 * \param [in] name - the name of the family to remove.
582 * \throw If no family with such a \a name exists.
584 void MEDFileMesh::removeFamily(const std::string& name)
586 std::string oname(name);
587 std::map<std::string, int >::iterator it=_families.find(oname);
588 std::vector<std::string> fams=getFamiliesNames();
589 if(it==_families.end())
591 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
592 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
593 throw INTERP_KERNEL::Exception(oss.str().c_str());
596 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
598 std::vector<std::string>& v=(*it3).second;
599 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
606 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
607 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
608 * family field whatever its level. This method also suppresses the orphan families.
610 * \return - The list of removed groups names.
612 * \sa MEDFileMesh::removeOrphanFamilies.
614 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
616 removeOrphanFamilies();
617 return removeEmptyGroups();
621 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
622 * 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.
624 * \return - The list of removed families names.
625 * \sa MEDFileMesh::removeOrphanGroups.
627 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
629 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
630 std::vector<std::string> ret;
631 if(!((DataArrayInt*)allFamIdsInUse))
633 ret=getFamiliesNames();
634 _families.clear(); _groups.clear();
637 std::map<std::string,int> famMap;
638 std::map<std::string, std::vector<std::string> > grps(_groups);
639 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
641 if(allFamIdsInUse->presenceOfValue((*it).second))
642 famMap[(*it).first]=(*it).second;
645 ret.push_back((*it).first);
646 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
647 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
649 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
650 std::vector<std::string>& famv=(*it3).second;
651 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
657 { _families=famMap; _groups=grps; }
662 * Renames a group in \a this mesh.
663 * \param [in] oldName - a current name of the group to rename.
664 * \param [in] newName - a new group name.
665 * \throw If no group named \a oldName exists in \a this mesh.
666 * \throw If a group named \a newName already exists.
668 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
670 std::string oname(oldName);
671 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
672 std::vector<std::string> grps=getGroupsNames();
673 if(it==_groups.end())
675 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
676 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
677 throw INTERP_KERNEL::Exception(oss.str().c_str());
679 std::string nname(newName);
680 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
681 if(it2!=_groups.end())
683 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
684 throw INTERP_KERNEL::Exception(oss.str().c_str());
686 std::vector<std::string> cpy=(*it).second;
688 _groups[newName]=cpy;
692 * Changes an id of a family in \a this mesh.
693 * This method calls changeFamilyIdArr().
694 * \param [in] oldId - a current id of the family.
695 * \param [in] newId - a new family id.
697 void MEDFileMesh::changeFamilyId(int oldId, int newId)
699 changeFamilyIdArr(oldId,newId);
700 std::map<std::string,int> fam2;
701 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
703 if((*it).second==oldId)
704 fam2[(*it).first]=newId;
706 fam2[(*it).first]=(*it).second;
712 * Renames a family in \a this mesh.
713 * \param [in] oldName - a current name of the family to rename.
714 * \param [in] newName - a new family name.
715 * \throw If no family named \a oldName exists in \a this mesh.
716 * \throw If a family named \a newName already exists.
718 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
720 std::string oname(oldName);
721 std::map<std::string, int >::iterator it=_families.find(oname);
722 std::vector<std::string> fams=getFamiliesNames();
723 if(it==_families.end())
725 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
726 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
727 throw INTERP_KERNEL::Exception(oss.str().c_str());
729 std::string nname(newName);
730 std::map<std::string, int >::iterator it2=_families.find(nname);
731 if(it2!=_families.end())
733 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
734 throw INTERP_KERNEL::Exception(oss.str().c_str());
736 int cpy=(*it).second;
738 _families[newName]=cpy;
739 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
741 std::vector<std::string>& v=(*it3).second;
742 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
749 * Checks if \a this and another mesh contains the same families.
750 * \param [in] other - the mesh to compare with \a this one.
751 * \param [in,out] what - an unused parameter.
752 * \return bool - \c true if number of families and their ids are the same in the two
753 * meshes. Families with the id == \c 0 are not considered.
755 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
757 if(_families==other->_families)
759 std::map<std::string,int> fam0;
760 std::map<std::string,int> fam1;
761 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
763 fam0[(*it).first]=(*it).second;
764 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
766 fam1[(*it).first]=(*it).second;
771 * Checks if \a this and another mesh contains the same groups.
772 * \param [in] other - the mesh to compare with \a this one.
773 * \param [in,out] what - a string describing a difference of groups of the two meshes
774 * in case if this method returns \c false.
775 * \return bool - \c true if number of groups and families constituting them are the
776 * same in the two meshes.
778 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
780 if(_groups==other->_groups)
783 std::size_t sz=_groups.size();
784 if(sz!=other->_groups.size())
786 what="Groups differ because not same number !\n";
791 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
792 for(std::size_t i=0;i<sz && ret;i++,it1++)
794 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
795 if(it2!=other->_groups.end())
797 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
798 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
804 what="A group in first mesh exists not in other !\n";
810 std::ostringstream oss; oss << "Groups description differs :\n";
811 oss << "First group description :\n";
812 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
814 oss << " Group \"" << (*it).first << "\" on following families :\n";
815 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
816 oss << " \"" << *it2 << "\n";
818 oss << "Second group description :\n";
819 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
821 oss << " Group \"" << (*it).first << "\" on following families :\n";
822 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
823 oss << " \"" << *it2 << "\n";
831 * Checks if a group with a given name exists in \a this mesh.
832 * \param [in] groupName - the group name.
833 * \return bool - \c true the group \a groupName exists in \a this mesh.
835 bool MEDFileMesh::existsGroup(const std::string& groupName) const
837 std::string grpName(groupName);
838 return _groups.find(grpName)!=_groups.end();
842 * Checks if a family with a given id exists in \a this mesh.
843 * \param [in] famId - the family id.
844 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
846 bool MEDFileMesh::existsFamily(int famId) const
848 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
849 if((*it2).second==famId)
855 * Checks if a family with a given name exists in \a this mesh.
856 * \param [in] familyName - the family name.
857 * \return bool - \c true the family \a familyName exists in \a this mesh.
859 bool MEDFileMesh::existsFamily(const std::string& familyName) const
861 std::string fname(familyName);
862 return _families.find(fname)!=_families.end();
866 * Sets an id of a family.
867 * \param [in] familyName - the family name.
868 * \param [in] id - a new id of the family.
870 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
872 std::string fname(familyName);
876 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
878 std::string fname(familyName);
879 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
882 if((*it).first!=familyName)
884 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
885 throw INTERP_KERNEL::Exception(oss.str().c_str());
892 * Adds a family to \a this mesh.
893 * \param [in] familyName - a name of the family.
894 * \param [in] famId - an id of the family.
895 * \throw If a family with the same name or id already exists in \a this mesh.
897 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
899 std::string fname(familyName);
900 std::map<std::string,int>::const_iterator it=_families.find(fname);
901 if(it==_families.end())
903 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
904 if((*it2).second==famId)
906 std::ostringstream oss;
907 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
908 throw INTERP_KERNEL::Exception(oss.str().c_str());
910 _families[fname]=famId;
914 if((*it).second!=famId)
916 std::ostringstream oss;
917 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
918 throw INTERP_KERNEL::Exception(oss.str().c_str());
924 * Creates a group including all mesh entities of given dimension.
925 * \warning This method does \b not guarantee that the created group includes mesh
926 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
927 * present in family fields of different dimensions. To assure this, call
928 * ensureDifferentFamIdsPerLevel() \b before calling this method.
929 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
931 * \param [in] groupName - a name of the new group.
932 * \throw If a group named \a groupName already exists.
933 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
934 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
936 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
938 std::string grpName(groupName);
939 std::vector<int> levs=getNonEmptyLevelsExt();
940 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
942 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
943 oss << "Available relative ext levels are : ";
944 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
945 throw INTERP_KERNEL::Exception(oss.str().c_str());
947 if(existsGroup(groupName))
949 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
950 oss << "Already existing groups are : ";
951 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
952 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
953 throw INTERP_KERNEL::Exception(oss.str().c_str());
955 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
957 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
959 std::vector<std::string> familiesOnWholeGroup;
960 for(const int *it=famIds->begin();it!=famIds->end();it++)
963 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
965 _groups[grpName]=familiesOnWholeGroup;
969 * Ensures that given family ids do not present in family fields of dimensions different
970 * than given ones. If a family id is present in the family fields of dimensions different
971 * than the given ones, a new family is created and the whole data is updated accordingly.
972 * \param [in] famIds - a sequence of family ids to check.
973 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
974 * famIds should exclusively belong.
975 * \return bool - \c true if no modification is done in \a this mesh by this method.
977 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
979 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
980 std::vector<int> levs=getNonEmptyLevelsExt();
981 std::set<int> levs2(levs.begin(),levs.end());
982 std::vector<int> levsToTest;
983 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
984 std::set<int> famIds2(famIds.begin(),famIds.end());
987 if(!_families.empty())
988 maxFamId=getMaxFamilyId()+1;
989 std::vector<std::string> allFams=getFamiliesNames();
990 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
992 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
995 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
996 std::vector<int> tmp;
997 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
998 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1001 std::string famName=getFamilyNameGivenId(*it2);
1002 std::ostringstream oss; oss << "Family_" << maxFamId;
1003 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1004 addFamilyOnAllGroupsHaving(famName,zeName);
1005 _families[zeName]=maxFamId;
1006 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1015 * Adds a family to a given group in \a this mesh. If the group with a given name does
1016 * not exist, it is created.
1017 * \param [in] grpName - the name of the group to add the family in.
1018 * \param [in] famName - the name of the family to add to the group named \a grpName.
1019 * \throw If \a grpName or \a famName is an empty string.
1020 * \throw If no family named \a famName is present in \a this mesh.
1022 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1024 std::string grpn(grpName);
1025 std::string famn(famName);
1026 if(grpn.empty() || famn.empty())
1027 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1028 std::vector<std::string> fams=getFamiliesNames();
1029 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1031 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1032 oss << "Create this family or choose an existing one ! Existing fams are : ";
1033 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1034 throw INTERP_KERNEL::Exception(oss.str().c_str());
1036 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1037 if(it==_groups.end())
1039 _groups[grpn].push_back(famn);
1043 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1044 if(it2==(*it).second.end())
1045 (*it).second.push_back(famn);
1050 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1051 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1052 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1054 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1056 std::string famNameCpp(famName);
1057 std::string otherCpp(otherFamName);
1058 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1060 std::vector<std::string>& v=(*it).second;
1061 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1063 v.push_back(otherCpp);
1068 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1070 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1073 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1075 std::string fam(familyNameToChange);
1076 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1078 std::vector<std::string>& fams((*it).second);
1079 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1083 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1089 * Returns a name of the family having a given id or, if no such a family exists, creates
1090 * a new uniquely named family and returns its name.
1091 * \param [in] id - the id of the family whose name is required.
1092 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1093 * \return std::string - the name of the existing or the created family.
1094 * \throw If it is not possible to create a unique family name.
1096 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1098 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1102 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1103 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1104 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1105 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1107 * This method will throws an exception if it is not possible to create a unique family name.
1109 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1111 std::vector<std::string> famAlreadyExisting(families.size());
1113 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1115 if((*it).second!=id)
1117 famAlreadyExisting[ii]=(*it).first;
1126 std::ostringstream oss; oss << "Family_" << id;
1127 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1133 * Sets names and ids of all families in \a this mesh.
1134 * \param [in] info - a map of a family name to a family id.
1136 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1142 * Sets names of all groups and families constituting them in \a this mesh.
1143 * \param [in] info - a map of a group name to a vector of names of families
1144 * constituting the group.
1146 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1152 * Returns an id of the family having a given name.
1153 * \param [in] name - the name of the family of interest.
1154 * \return int - the id of the family of interest.
1155 * \throw If no family with such a \a name exists.
1157 int MEDFileMesh::getFamilyId(const std::string& name) const
1159 std::string oname(name);
1160 std::map<std::string, int>::const_iterator it=_families.find(oname);
1161 std::vector<std::string> fams=getFamiliesNames();
1162 if(it==_families.end())
1164 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1165 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1166 throw INTERP_KERNEL::Exception(oss.str().c_str());
1168 return (*it).second;
1172 * Returns ids of the families having given names.
1173 * \param [in] fams - a sequence of the names of families of interest.
1174 * \return std::vector<int> - a sequence of the ids of families of interest.
1175 * \throw If \a fams contains a name of an inexistent family.
1177 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1179 std::vector<int> ret(fams.size());
1181 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1183 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1184 if(it2==_families.end())
1186 std::vector<std::string> fams2=getFamiliesNames();
1187 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1188 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1189 throw INTERP_KERNEL::Exception(oss.str().c_str());
1191 ret[i]=(*it2).second;
1197 * Returns a maximal abs(id) of families in \a this mesh.
1198 * \return int - the maximal norm of family id.
1199 * \throw If there are no families in \a this mesh.
1201 int MEDFileMesh::getMaxAbsFamilyId() const
1203 if(_families.empty())
1204 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1205 int ret=-std::numeric_limits<int>::max();
1206 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1208 ret=std::max(std::abs((*it).second),ret);
1214 * Returns a maximal id of families in \a this mesh.
1215 * \return int - the maximal family id.
1216 * \throw If there are no families in \a this mesh.
1218 int MEDFileMesh::getMaxFamilyId() const
1220 if(_families.empty())
1221 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1222 int ret=-std::numeric_limits<int>::max();
1223 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1225 ret=std::max((*it).second,ret);
1231 * Returns a minimal id of families in \a this mesh.
1232 * \return int - the minimal family id.
1233 * \throw If there are no families in \a this mesh.
1235 int MEDFileMesh::getMinFamilyId() const
1237 if(_families.empty())
1238 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1239 int ret=std::numeric_limits<int>::max();
1240 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1242 ret=std::min((*it).second,ret);
1248 * Returns a maximal id of families in \a this mesh. Not only named families are
1249 * considered but all family fields as well.
1250 * \return int - the maximal family id.
1252 int MEDFileMesh::getTheMaxAbsFamilyId() const
1254 int m1=-std::numeric_limits<int>::max();
1255 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1256 m1=std::max(std::abs((*it).second),m1);
1257 int m2=getMaxAbsFamilyIdInArrays();
1258 return std::max(m1,m2);
1262 * Returns a maximal id of families in \a this mesh. Not only named families are
1263 * considered but all family fields as well.
1264 * \return int - the maximal family id.
1266 int MEDFileMesh::getTheMaxFamilyId() const
1268 int m1=-std::numeric_limits<int>::max();
1269 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1270 m1=std::max((*it).second,m1);
1271 int m2=getMaxFamilyIdInArrays();
1272 return std::max(m1,m2);
1276 * Returns a minimal id of families in \a this mesh. Not only named families are
1277 * considered but all family fields as well.
1278 * \return int - the minimal family id.
1280 int MEDFileMesh::getTheMinFamilyId() const
1282 int m1=std::numeric_limits<int>::max();
1283 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1284 m1=std::min((*it).second,m1);
1285 int m2=getMinFamilyIdInArrays();
1286 return std::min(m1,m2);
1290 * This method only considers the maps. The contain of family array is ignored here.
1292 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1294 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1296 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1298 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1299 v.insert((*it).second);
1300 ret->alloc((int)v.size(),1);
1301 std::copy(v.begin(),v.end(),ret->getPointer());
1306 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1308 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1310 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1312 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1313 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1314 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1316 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1317 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1318 if((DataArrayInt *) ret)
1319 ret=dv->buildUnion(ret);
1327 * true is returned if no modification has been needed. false if family
1328 * renumbering has been needed.
1330 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1332 std::vector<int> levs=getNonEmptyLevelsExt();
1333 std::set<int> allFamIds;
1334 int maxId=getMaxFamilyId()+1;
1335 std::map<int,std::vector<int> > famIdsToRenum;
1336 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1338 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1341 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1343 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1345 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1347 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1350 if(famIdsToRenum.empty())
1352 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1353 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1355 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1356 int *famIdsToChange=fam->getPointer();
1357 std::map<int,int> ren;
1358 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1360 if(allIds->presenceOfValue(*it3))
1362 std::string famName=getFamilyNameGivenId(*it3);
1363 std::vector<std::string> grps=getGroupsOnFamily(famName);
1366 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1367 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1368 addFamilyOnGrp((*it4),newFam);
1371 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1372 for(const int *id=ids->begin();id!=ids->end();id++)
1373 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1379 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1380 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1381 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1382 * This method will throw an exception if a same family id is detected in different level.
1383 * \warning This policy is the opposite of those in MED file documentation ...
1385 void MEDFileMesh::normalizeFamIdsTrio()
1387 ensureDifferentFamIdsPerLevel();
1388 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1389 std::vector<int> levs=getNonEmptyLevelsExt();
1390 std::set<int> levsS(levs.begin(),levs.end());
1391 std::set<std::string> famsFetched;
1392 std::map<std::string,int> families;
1393 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1396 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1400 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1401 std::map<int,int> ren;
1402 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1404 int nbOfTuples=fam->getNumberOfTuples();
1405 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1406 for(int *w=start;w!=start+nbOfTuples;w++)
1408 for(const int *it=tmp->begin();it!=tmp->end();it++)
1410 if(allIds->presenceOfValue(*it))
1412 std::string famName=getFamilyNameGivenId(*it);
1413 families[famName]=ren[*it];
1414 famsFetched.insert(famName);
1419 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1422 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1426 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1427 std::map<int,int> ren;
1428 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1430 int nbOfTuples=fam->getNumberOfTuples();
1431 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1432 for(int *w=start;w!=start+nbOfTuples;w++)
1434 for(const int *it=tmp->begin();it!=tmp->end();it++)
1436 if(allIds->presenceOfValue(*it))
1438 std::string famName=getFamilyNameGivenId(*it);
1439 families[famName]=ren[*it];
1440 famsFetched.insert(famName);
1445 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1447 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1450 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1451 fam->fillWithZero();
1452 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1453 if(allIds->presenceOfValue(*it3))
1455 std::string famName=getFamilyNameGivenId(*it3);
1456 families[famName]=0;
1457 famsFetched.insert(famName);
1462 std::vector<std::string> allFams=getFamiliesNames();
1463 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1464 std::set<std::string> unFetchedIds;
1465 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1466 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1467 families[*it4]=_families[*it4];
1472 * This method normalizes fam id with the following policy.
1473 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1474 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1475 * This method will throw an exception if a same family id is detected in different level.
1477 void MEDFileMesh::normalizeFamIdsMEDFile()
1479 ensureDifferentFamIdsPerLevel();
1480 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1481 std::vector<int> levs=getNonEmptyLevelsExt();
1482 std::set<int> levsS(levs.begin(),levs.end());
1483 std::set<std::string> famsFetched;
1484 std::map<std::string,int> families;
1486 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1489 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1492 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1493 std::map<int,int> ren;
1494 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1496 int nbOfTuples=fam->getNumberOfTuples();
1497 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1498 for(int *w=start;w!=start+nbOfTuples;w++)
1500 for(const int *it=tmp->begin();it!=tmp->end();it++)
1502 if(allIds->presenceOfValue(*it))
1504 std::string famName=getFamilyNameGivenId(*it);
1505 families[famName]=ren[*it];
1506 famsFetched.insert(famName);
1512 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1514 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1517 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1518 std::map<int,int> ren;
1519 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1521 int nbOfTuples=fam->getNumberOfTuples();
1522 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1523 for(int *w=start;w!=start+nbOfTuples;w++)
1525 for(const int *it=tmp->begin();it!=tmp->end();it++)
1527 if(allIds->presenceOfValue(*it))
1529 std::string famName=getFamilyNameGivenId(*it);
1530 families[famName]=ren[*it];
1531 famsFetched.insert(famName);
1537 std::vector<std::string> allFams=getFamiliesNames();
1538 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1539 std::set<std::string> unFetchedIds;
1540 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1541 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1542 families[*it4]=_families[*it4];
1547 * Returns a name of the family by its id. If there are several families having the given
1548 * id, the name first in lexical order is returned.
1549 * \param [in] id - the id of the family whose name is required.
1550 * \return std::string - the name of the found family.
1551 * \throw If no family with the given \a id exists.
1553 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1555 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1556 if((*it).second==id)
1558 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1559 throw INTERP_KERNEL::Exception(oss.str().c_str());
1563 * Returns a string describing \a this mesh. This description includes the mesh name and
1564 * the mesh description string.
1565 * \return std::string - the mesh information string.
1567 std::string MEDFileMesh::simpleRepr() const
1569 std::ostringstream oss;
1570 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1571 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1572 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1577 * Returns ids of mesh entities contained in a given group of a given dimension.
1578 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1580 * \param [in] grp - the name of the group of interest.
1581 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1582 * returned instead of ids.
1583 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1584 * numbers, if available and required, of mesh entities of the group. The caller
1585 * is to delete this array using decrRef() as it is no more needed.
1586 * \throw If the name of a nonexistent group is specified.
1587 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1589 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1591 std::vector<std::string> tmp(1);
1593 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1599 * Returns ids of mesh entities contained in given groups of a given dimension.
1600 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1602 * \param [in] grps - the names of the groups of interest.
1603 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1604 * returned instead of ids.
1605 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1606 * numbers, if available and required, of mesh entities of the groups. The caller
1607 * is to delete this array using decrRef() as it is no more needed.
1608 * \throw If the name of a nonexistent group is present in \a grps.
1609 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1611 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1613 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1614 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1618 * Returns ids of mesh entities contained in a given family of a given dimension.
1619 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1621 * \param [in] fam - the name of the family of interest.
1622 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1623 * returned instead of ids.
1624 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1625 * numbers, if available and required, of mesh entities of the family. The caller
1626 * is to delete this array using decrRef() as it is no more needed.
1627 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1629 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1631 std::vector<std::string> tmp(1);
1633 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1639 * Returns ids of nodes contained in a given group.
1640 * \param [in] grp - the name of the group of interest.
1641 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1642 * returned instead of ids.
1643 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1644 * numbers, if available and required, of nodes of the group. The caller
1645 * is to delete this array using decrRef() as it is no more needed.
1646 * \throw If the name of a nonexistent group is specified.
1647 * \throw If the family field is missing for nodes.
1649 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1651 std::vector<std::string> tmp(1);
1653 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1659 * Returns ids of nodes contained in given groups.
1660 * \param [in] grps - the names of the groups of interest.
1661 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1662 * returned instead of ids.
1663 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1664 * numbers, if available and required, of nodes of the groups. The caller
1665 * is to delete this array using decrRef() as it is no more needed.
1666 * \throw If the name of a nonexistent group is present in \a grps.
1667 * \throw If the family field is missing for nodes.
1669 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1671 return getGroupsArr(1,grps,renum);
1675 * Returns ids of nodes contained in a given group.
1676 * \param [in] grp - the name of the group of interest.
1677 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1678 * returned instead of ids.
1679 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1680 * numbers, if available and required, of nodes of the group. The caller
1681 * is to delete this array using decrRef() as it is no more needed.
1682 * \throw If the name of a nonexistent group is specified.
1683 * \throw If the family field is missing for nodes.
1685 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1687 std::vector<std::string> tmp(1);
1689 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1695 * Returns ids of nodes contained in given families.
1696 * \param [in] fams - the names of the families of interest.
1697 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1698 * returned instead of ids.
1699 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1700 * numbers, if available and required, of nodes of the families. The caller
1701 * is to delete this array using decrRef() as it is no more needed.
1702 * \throw If the family field is missing for nodes.
1704 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1706 return getFamiliesArr(1,fams,renum);
1710 * Adds groups of given dimension and creates corresponding families and family fields
1711 * given ids of mesh entities of each group.
1712 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1713 * \param [in] grps - a sequence of arrays of ids each describing a group.
1714 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1716 * \throw If names of some groups in \a grps are equal.
1717 * \throw If \a grps includes a group with an empty name.
1718 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1719 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1721 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1725 std::set<std::string> grpsName;
1726 std::vector<std::string> grpsName2(grps.size());
1729 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1731 grpsName.insert((*it)->getName());
1732 grpsName2[i]=(*it)->getName();
1734 if(grpsName.size()!=grps.size())
1735 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1736 if(grpsName.find(std::string(""))!=grpsName.end())
1737 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1738 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1739 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1740 std::vector< std::vector<int> > fidsOfGroups;
1743 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1747 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1748 for(unsigned int ii=0;ii<grps.size();ii++)
1750 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1751 grps2[ii]->setName(grps[ii]->getName());
1753 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1754 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1757 if(!_families.empty())
1758 offset=getMaxAbsFamilyId()+1;
1759 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1760 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1761 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1762 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1766 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1767 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1768 * For the moment, the two last input parameters are not taken into account.
1770 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1772 std::map<int,std::string> famInv;
1773 for(const int *it=famIds->begin();it!=famIds->end();it++)
1775 std::ostringstream oss;
1776 oss << "Family_" << (*it);
1777 _families[oss.str()]=(*it);
1778 famInv[*it]=oss.str();
1781 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1783 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1785 _groups[grpNames[i]].push_back(famInv[*it2]);
1790 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1792 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1793 return mLev->getDistributionOfTypes();
1796 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1798 famArr->applyLin(offset>0?1:-1,offset,0);
1799 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1802 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1803 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1808 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1809 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1810 * If this method fails to find such a name it will throw an exception.
1812 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
1815 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1818 std::size_t len=nameTry.length();
1819 for(std::size_t ii=1;ii<len;ii++)
1821 std::string tmp=nameTry.substr(ii,len-ii);
1822 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1828 for(std::size_t i=1;i<30;i++)
1830 std::string tmp1(nameTry.at(0),i);
1832 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1838 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1840 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1842 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1845 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
1847 std::size_t nbOfChunks=code.size()/3;
1848 if(code.size()%3!=0)
1849 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1851 for(std::size_t i=0;i<nbOfChunks;i++)
1860 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1861 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1862 * If _name is not empty and that 'm' has the same name nothing is done.
1863 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1865 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
1868 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1873 std::string name(m->getName());
1878 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1879 oss << name << "' ! Names must match !";
1880 throw INTERP_KERNEL::Exception(oss.str().c_str());
1884 if(_desc_name.empty())
1885 _desc_name=m->getDescription();
1888 std::string name(m->getDescription());
1891 if(_desc_name!=name)
1893 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1894 oss << name << "' ! Names must match !";
1895 throw INTERP_KERNEL::Exception(oss.str().c_str());
1901 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1903 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1904 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1906 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1907 oss << " - Groups lying on this family : ";
1908 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
1909 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1910 oss << std::endl << std::endl;
1915 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1916 * file. The mesh to load is specified by its name and numbers of a time step and an
1918 * \param [in] fileName - the name of MED file to read.
1919 * \param [in] mName - the name of the mesh to read.
1920 * \param [in] dt - the number of a time step.
1921 * \param [in] it - the number of an iteration.
1922 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1923 * mesh using decrRef() as it is no more needed.
1924 * \throw If the file is not readable.
1925 * \throw If there is no mesh with given attributes in the file.
1926 * \throw If the mesh in the file is not an unstructured one.
1928 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
1930 MEDFileUtilities::CheckFileForRead(fileName);
1931 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1932 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1936 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1937 * file. The first mesh in the file is loaded.
1938 * \param [in] fileName - the name of MED file to read.
1939 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1940 * mesh using decrRef() as it is no more needed.
1941 * \throw If the file is not readable.
1942 * \throw If there is no meshes in the file.
1943 * \throw If the mesh in the file is not an unstructured one.
1945 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
1947 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1950 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1951 throw INTERP_KERNEL::Exception(oss.str().c_str());
1953 MEDFileUtilities::CheckFileForRead(fileName);
1954 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1956 ParaMEDMEM::MEDCouplingMeshType meshType;
1958 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
1959 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
1963 * Returns an empty instance of MEDFileUMesh.
1964 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1965 * mesh using decrRef() as it is no more needed.
1967 MEDFileUMesh *MEDFileUMesh::New()
1969 return new MEDFileUMesh;
1972 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
1974 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
1975 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1979 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildren() const
1981 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
1982 if((const DataArrayDouble*)_coords)
1983 ret.push_back((const DataArrayDouble*)_coords);
1984 if((const DataArrayInt *)_fam_coords)
1985 ret.push_back((const DataArrayInt *)_fam_coords);
1986 if((const DataArrayInt *)_num_coords)
1987 ret.push_back((const DataArrayInt *)_num_coords);
1988 if((const DataArrayInt *)_rev_num_coords)
1989 ret.push_back((const DataArrayInt *)_rev_num_coords);
1990 if((const DataArrayAsciiChar *)_name_coords)
1991 ret.push_back((const DataArrayAsciiChar *)_name_coords);
1992 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1993 if((const MEDFileUMeshSplitL1*) *it)
1994 ret.push_back((const MEDFileUMeshSplitL1*) *it);
1998 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2000 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2004 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2006 return new MEDFileUMesh;
2009 MEDFileMesh *MEDFileUMesh::deepCpy() const
2011 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2012 if((const DataArrayDouble*)_coords)
2013 ret->_coords=_coords->deepCpy();
2014 if((const DataArrayInt*)_fam_coords)
2015 ret->_fam_coords=_fam_coords->deepCpy();
2016 if((const DataArrayInt*)_num_coords)
2017 ret->_num_coords=_num_coords->deepCpy();
2018 if((const DataArrayInt*)_rev_num_coords)
2019 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2020 if((const DataArrayAsciiChar*)_name_coords)
2021 ret->_name_coords=_name_coords->deepCpy();
2023 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2025 if((const MEDFileUMeshSplitL1 *)(*it))
2026 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2032 * Checks if \a this and another mesh are equal.
2033 * \param [in] other - the mesh to compare with.
2034 * \param [in] eps - a precision used to compare real values.
2035 * \param [in,out] what - the string returning description of unequal data.
2036 * \return bool - \c true if the meshes are equal, \c false, else.
2038 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2040 if(!MEDFileMesh::isEqual(other,eps,what))
2042 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2045 what="Mesh types differ ! This is unstructured and other is NOT !";
2048 clearNonDiscrAttributes();
2049 otherC->clearNonDiscrAttributes();
2050 const DataArrayDouble *coo1=_coords;
2051 const DataArrayDouble *coo2=otherC->_coords;
2052 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2054 what="Mismatch of coordinates ! One is defined and not other !";
2059 bool ret=coo1->isEqual(*coo2,eps);
2062 what="Coords differ !";
2066 const DataArrayInt *famc1=_fam_coords;
2067 const DataArrayInt *famc2=otherC->_fam_coords;
2068 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2070 what="Mismatch of families arr on nodes ! One is defined and not other !";
2075 bool ret=famc1->isEqual(*famc2);
2078 what="Families arr on node differ !";
2082 const DataArrayInt *numc1=_num_coords;
2083 const DataArrayInt *numc2=otherC->_num_coords;
2084 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2086 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2091 bool ret=numc1->isEqual(*numc2);
2094 what="Numbering arr on node differ !";
2098 const DataArrayAsciiChar *namec1=_name_coords;
2099 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2100 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2102 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2107 bool ret=namec1->isEqual(*namec2);
2110 what="Names arr on node differ !";
2114 if(_ms.size()!=otherC->_ms.size())
2116 what="Number of levels differs !";
2119 std::size_t sz=_ms.size();
2120 for(std::size_t i=0;i<sz;i++)
2122 const MEDFileUMeshSplitL1 *s1=_ms[i];
2123 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2124 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2126 what="Mismatch of presence of sub levels !";
2131 bool ret=s1->isEqual(s2,eps,what);
2140 * Clears redundant attributes of incorporated data arrays.
2142 void MEDFileUMesh::clearNonDiscrAttributes() const
2144 MEDFileMesh::clearNonDiscrAttributes();
2145 const DataArrayDouble *coo1=_coords;
2147 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2148 const DataArrayInt *famc1=_fam_coords;
2150 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2151 const DataArrayInt *numc1=_num_coords;
2153 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2154 const DataArrayAsciiChar *namc1=_name_coords;
2156 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2157 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2159 const MEDFileUMeshSplitL1 *tmp=(*it);
2161 tmp->clearNonDiscrAttributes();
2165 void MEDFileUMesh::setName(const std::string& name)
2167 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2168 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2169 (*it)->setName(name);
2170 MEDFileMesh::setName(name);
2173 MEDFileUMesh::MEDFileUMesh()
2177 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2180 loadUMeshFromFile(fid,mName,dt,it,mrs);
2182 catch(INTERP_KERNEL::Exception& e)
2187 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2189 MEDFileUMeshL2 loaderl2;
2190 ParaMEDMEM::MEDCouplingMeshType meshType;
2193 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
2194 if(meshType!=UNSTRUCTURED)
2196 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2197 throw INTERP_KERNEL::Exception(oss.str().c_str());
2199 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2200 int lev=loaderl2.getNumberOfLevels();
2202 for(int i=0;i<lev;i++)
2204 if(!loaderl2.emptyLev(i))
2205 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2209 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2211 setName(loaderl2.getName());
2212 setDescription(loaderl2.getDescription());
2213 setUnivName(loaderl2.getUnivName());
2214 setIteration(loaderl2.getIteration());
2215 setOrder(loaderl2.getOrder());
2216 setTimeValue(loaderl2.getTime());
2217 setTimeUnit(loaderl2.getTimeUnit());
2218 _coords=loaderl2.getCoords();
2219 if(!mrs || mrs->isNodeFamilyFieldReading())
2220 _fam_coords=loaderl2.getCoordsFamily();
2221 if(!mrs || mrs->isNodeNumFieldReading())
2222 _num_coords=loaderl2.getCoordsNum();
2223 if(!mrs || mrs->isNodeNameFieldReading())
2224 _name_coords=loaderl2.getCoordsName();
2228 MEDFileUMesh::~MEDFileUMesh()
2232 void MEDFileUMesh::writeLL(med_idt fid) const
2234 const DataArrayDouble *coo=_coords;
2235 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2236 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2237 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2238 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2239 int spaceDim=coo?coo->getNumberOfComponents():0;
2240 int mdim=getMeshDimension();
2241 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2242 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2243 for(int i=0;i<spaceDim;i++)
2245 std::string info=coo->getInfoOnComponent(i);
2247 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2248 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
2249 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
2251 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2252 MEDmeshUniversalNameWr(fid,maa);
2253 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2254 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2255 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2256 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2257 (*it)->write(fid,meshName,mdim);
2258 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2262 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2263 * \return std::vector<int> - a sequence of the relative dimensions.
2265 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2267 std::vector<int> ret;
2269 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2270 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2277 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2278 * \return std::vector<int> - a sequence of the relative dimensions.
2280 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2282 std::vector<int> ret0=getNonEmptyLevels();
2283 if((const DataArrayDouble *) _coords)
2285 std::vector<int> ret(ret0.size()+1);
2287 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2293 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2295 std::vector<int> ret;
2296 const DataArrayInt *famCoo(_fam_coords);
2300 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2302 const MEDFileUMeshSplitL1 *cur(*it);
2304 if(cur->getFamilyField())
2310 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2312 std::vector<int> ret;
2313 const DataArrayInt *numCoo(_num_coords);
2317 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2319 const MEDFileUMeshSplitL1 *cur(*it);
2321 if(cur->getNumberField())
2327 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2329 std::vector<int> ret;
2330 const DataArrayAsciiChar *nameCoo(_name_coords);
2334 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2336 const MEDFileUMeshSplitL1 *cur(*it);
2338 if(cur->getNameField())
2345 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2346 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2347 * \param [in] grp - the name of the group of interest.
2348 * \return std::vector<int> - a sequence of the relative dimensions.
2350 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2352 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2353 return getFamsNonEmptyLevels(fams);
2357 * Returns all relative mesh levels (including nodes) where a given group is defined.
2358 * \param [in] grp - the name of the group of interest.
2359 * \return std::vector<int> - a sequence of the relative dimensions.
2361 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2363 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2364 return getFamsNonEmptyLevelsExt(fams);
2368 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2369 * To include nodes, call getFamNonEmptyLevelsExt() method.
2370 * \param [in] fam - the name of the family of interest.
2371 * \return std::vector<int> - a sequence of the relative dimensions.
2373 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2375 std::vector<std::string> fams(1,std::string(fam));
2376 return getFamsNonEmptyLevels(fams);
2380 * Returns all relative mesh levels (including nodes) where a given family is defined.
2381 * \param [in] fam - the name of the family of interest.
2382 * \return std::vector<int> - a sequence of the relative dimensions.
2384 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2386 std::vector<std::string> fams(1,std::string(fam));
2387 return getFamsNonEmptyLevelsExt(fams);
2391 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2392 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2393 * \param [in] grps - a sequence of names of the groups of interest.
2394 * \return std::vector<int> - a sequence of the relative dimensions.
2396 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2398 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2399 return getFamsNonEmptyLevels(fams);
2403 * Returns all relative mesh levels (including nodes) where given groups are defined.
2404 * \param [in] grps - a sequence of names of the groups of interest.
2405 * \return std::vector<int> - a sequence of the relative dimensions.
2407 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2409 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2410 return getFamsNonEmptyLevelsExt(fams);
2414 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2415 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2416 * \param [in] fams - the name of the family of interest.
2417 * \return std::vector<int> - a sequence of the relative dimensions.
2419 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2421 std::vector<int> ret;
2422 std::vector<int> levs=getNonEmptyLevels();
2423 std::vector<int> famIds=getFamiliesIds(fams);
2424 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2425 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2431 * Returns all relative mesh levels (including nodes) where given families are defined.
2432 * \param [in] fams - the names of the families of interest.
2433 * \return std::vector<int> - a sequence of the relative dimensions.
2435 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2437 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2438 const DataArrayInt *famCoords=_fam_coords;
2441 std::vector<int> famIds=getFamiliesIds(fams);
2442 if(famCoords->presenceOfValue(famIds))
2444 std::vector<int> ret(ret0.size()+1);
2446 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2454 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2455 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2456 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2459 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2461 std::vector<std::string> ret;
2462 std::vector<std::string> allGrps=getGroupsNames();
2463 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2465 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2466 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2472 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2474 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2475 if((const DataArrayInt *)_fam_coords)
2477 int val=_fam_coords->getMaxValue(tmp);
2478 ret=std::max(ret,std::abs(val));
2480 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2482 if((const MEDFileUMeshSplitL1 *)(*it))
2484 const DataArrayInt *da=(*it)->getFamilyField();
2487 int val=da->getMaxValue(tmp);
2488 ret=std::max(ret,std::abs(val));
2495 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2497 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2498 if((const DataArrayInt *)_fam_coords)
2500 int val=_fam_coords->getMaxValue(tmp);
2501 ret=std::max(ret,val);
2503 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2505 if((const MEDFileUMeshSplitL1 *)(*it))
2507 const DataArrayInt *da=(*it)->getFamilyField();
2510 int val=da->getMaxValue(tmp);
2511 ret=std::max(ret,val);
2518 int MEDFileUMesh::getMinFamilyIdInArrays() const
2520 int ret=std::numeric_limits<int>::max(),tmp=-1;
2521 if((const DataArrayInt *)_fam_coords)
2523 int val=_fam_coords->getMinValue(tmp);
2524 ret=std::min(ret,val);
2526 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2528 if((const MEDFileUMeshSplitL1 *)(*it))
2530 const DataArrayInt *da=(*it)->getFamilyField();
2533 int val=da->getMinValue(tmp);
2534 ret=std::min(ret,val);
2542 * Returns the dimension on cells in \a this mesh.
2543 * \return int - the mesh dimension.
2544 * \throw If there are no cells in this mesh.
2546 int MEDFileUMesh::getMeshDimension() const
2549 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2550 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2551 return (*it)->getMeshDimension()+lev;
2552 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2556 * Returns the space dimension of \a this mesh that is equal to number of components in
2557 * the node coordinates array.
2558 * \return int - the space dimension of \a this mesh.
2559 * \throw If the node coordinates array is not available.
2561 int MEDFileUMesh::getSpaceDimension() const
2563 const DataArrayDouble *coo=_coords;
2565 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2566 return coo->getNumberOfComponents();
2570 * Returns a string describing \a this mesh.
2571 * \return std::string - the mesh information string.
2573 std::string MEDFileUMesh::simpleRepr() const
2575 std::ostringstream oss;
2576 oss << MEDFileMesh::simpleRepr();
2577 const DataArrayDouble *coo=_coords;
2578 oss << "- The dimension of the space is ";
2579 static const char MSG1[]= "*** NO COORDS SET ***";
2580 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2582 oss << _coords->getNumberOfComponents() << std::endl;
2584 oss << MSG1 << std::endl;
2585 oss << "- Type of the mesh : UNSTRUCTURED\n";
2586 oss << "- Number of nodes : ";
2588 oss << _coords->getNumberOfTuples() << std::endl;
2590 oss << MSG1 << std::endl;
2591 std::size_t nbOfLev=_ms.size();
2592 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2593 for(std::size_t i=0;i<nbOfLev;i++)
2595 const MEDFileUMeshSplitL1 *lev=_ms[i];
2596 oss << " - Level #" << -((int) i) << " has dimension : ";
2599 oss << lev->getMeshDimension() << std::endl;
2600 lev->simpleRepr(oss);
2603 oss << MSG2 << std::endl;
2605 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2608 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2609 oss << "- Names of coordinates :" << std::endl;
2610 std::vector<std::string> vars=coo->getVarsOnComponent();
2611 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2612 oss << std::endl << "- Units of coordinates : " << std::endl;
2613 std::vector<std::string> units=coo->getUnitsOnComponent();
2614 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2616 oss << std::endl << std::endl;
2622 * Returns a full textual description of \a this mesh.
2623 * \return std::string - the string holding the mesh description.
2625 std::string MEDFileUMesh::advancedRepr() const
2627 return simpleRepr();
2631 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2632 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2633 * \return int - the number of entities.
2634 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2636 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2638 if(meshDimRelToMaxExt==1)
2640 if(!((const DataArrayDouble *)_coords))
2641 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2642 return _coords->getNumberOfTuples();
2644 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2648 * Returns the family field for mesh entities of a given dimension.
2649 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2650 * \return const DataArrayInt * - the family field. It is an array of ids of families
2651 * each mesh entity belongs to. It can be \c NULL.
2653 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2655 if(meshDimRelToMaxExt==1)
2657 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2658 return l1->getFamilyField();
2662 * Returns the optional numbers of mesh entities of a given dimension.
2663 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2664 * \return const DataArrayInt * - the array of the entity numbers.
2665 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2667 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2669 if(meshDimRelToMaxExt==1)
2671 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2672 return l1->getNumberField();
2675 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2677 if(meshDimRelToMaxExt==1)
2678 return _name_coords;
2679 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2680 return l1->getNameField();
2683 int MEDFileUMesh::getNumberOfNodes() const
2685 const DataArrayDouble *coo=_coords;
2687 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2688 return coo->getNumberOfTuples();
2691 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2693 std::size_t sz(st.getNumberOfItems());
2694 for(std::size_t i=0;i<sz;i++)
2696 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2697 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2698 if(st[i].getPflName().empty())
2699 m->computeNodeIdsAlg(nodesFetched);
2702 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
2703 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2704 m2->computeNodeIdsAlg(nodesFetched);
2710 * Returns the optional numbers of mesh entities of a given dimension transformed using
2711 * DataArrayInt::invertArrayN2O2O2N().
2712 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2713 * \return const DataArrayInt * - the array of the entity numbers transformed using
2714 * DataArrayInt::invertArrayN2O2O2N().
2715 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2717 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
2719 if(meshDimRelToMaxExt==1)
2721 if(!((const DataArrayInt *)_num_coords))
2722 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2723 return _rev_num_coords;
2725 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2726 return l1->getRevNumberField();
2730 * Returns a pointer to the node coordinates array of \a this mesh \b without
2731 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2733 DataArrayDouble *MEDFileUMesh::getCoords() const
2735 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2736 if((DataArrayDouble *)tmp)
2744 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2745 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2747 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2748 * \param [in] grp - the name of the group whose mesh entities are included in the
2750 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2751 * according to the optional numbers of entities, if available.
2752 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2753 * delete this mesh using decrRef() as it is no more needed.
2754 * \throw If the name of a nonexistent group is specified.
2755 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2757 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2759 synchronizeTinyInfoOnLeaves();
2760 std::vector<std::string> tmp(1);
2762 return getGroups(meshDimRelToMaxExt,tmp,renum);
2766 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2767 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2769 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2770 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2772 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2773 * according to the optional numbers of entities, if available.
2774 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2775 * delete this mesh using decrRef() as it is no more needed.
2776 * \throw If a name of a nonexistent group is present in \a grps.
2777 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2779 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2781 synchronizeTinyInfoOnLeaves();
2782 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2783 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2784 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2785 zeRet->setName(grps[0]);
2786 return zeRet.retn();
2790 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2791 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2793 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2794 * \param [in] fam - the name of the family whose mesh entities are included in the
2796 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2797 * according to the optional numbers of entities, if available.
2798 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2799 * delete this mesh using decrRef() as it is no more needed.
2800 * \throw If a name of a nonexistent family is present in \a grps.
2801 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2803 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2805 synchronizeTinyInfoOnLeaves();
2806 std::vector<std::string> tmp(1);
2808 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2812 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2813 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2815 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2816 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2818 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2819 * according to the optional numbers of entities, if available.
2820 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2821 * delete this mesh using decrRef() as it is no more needed.
2822 * \throw If a name of a nonexistent family is present in \a fams.
2823 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2825 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2827 synchronizeTinyInfoOnLeaves();
2828 if(meshDimRelToMaxExt==1)
2830 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2831 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2832 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2836 std::vector<int> famIds=getFamiliesIds(fams);
2837 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2838 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2840 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2842 zeRet=l1->getFamilyPart(0,0,renum);
2843 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2844 zeRet->setName(fams[0]);
2845 return zeRet.retn();
2849 * Returns ids of mesh entities contained in given families of a given dimension.
2850 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2852 * \param [in] fams - the names of the families of interest.
2853 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2854 * returned instead of ids.
2855 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2856 * numbers, if available and required, of mesh entities of the families. The caller
2857 * is to delete this array using decrRef() as it is no more needed.
2858 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2860 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2862 std::vector<int> famIds=getFamiliesIds(fams);
2863 if(meshDimRelToMaxExt==1)
2865 if((const DataArrayInt *)_fam_coords)
2867 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2869 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2871 da=_fam_coords->getIdsEqualList(0,0);
2873 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2878 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2880 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2882 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2884 return l1->getFamilyPartArr(0,0,renum);
2888 * Returns a MEDCouplingUMesh of a given relative dimension.
2889 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2890 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2891 * To build a valid MEDCouplingUMesh from the returned one in this case,
2892 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2893 * \param [in] meshDimRelToMax - the relative dimension of interest.
2894 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2895 * optional numbers of mesh entities.
2896 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2897 * delete using decrRef() as it is no more needed.
2898 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2899 * \sa getGenMeshAtLevel()
2901 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
2903 synchronizeTinyInfoOnLeaves();
2904 if(meshDimRelToMaxExt==1)
2908 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2909 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2910 umesh->setCoords(cc);
2911 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2912 umesh->setName(getName());
2916 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2917 return l1->getWholeMesh(renum);
2921 * Returns a MEDCouplingUMesh of a given relative dimension.
2922 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2923 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2924 * To build a valid MEDCouplingUMesh from the returned one in this case,
2925 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2926 * \param [in] meshDimRelToMax - the relative dimension of interest.
2927 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2928 * optional numbers of mesh entities.
2929 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2930 * delete using decrRef() as it is no more needed.
2931 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2932 * \sa getMeshAtLevel()
2934 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
2936 return getMeshAtLevel(meshDimRelToMax,renum);
2939 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
2941 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
2942 return l1->getDistributionOfTypes();
2946 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2947 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2948 * optional numbers of mesh entities.
2949 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2950 * delete using decrRef() as it is no more needed.
2951 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2953 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
2955 return getMeshAtLevel(0,renum);
2959 * Returns a MEDCouplingUMesh of a relative dimension == -1.
2960 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2961 * optional numbers of mesh entities.
2962 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2963 * delete using decrRef() as it is no more needed.
2964 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
2966 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
2968 return getMeshAtLevel(-1,renum);
2972 * Returns a MEDCouplingUMesh of a relative dimension == -2.
2973 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2974 * optional numbers of mesh entities.
2975 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2976 * delete using decrRef() as it is no more needed.
2977 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
2979 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
2981 return getMeshAtLevel(-2,renum);
2985 * Returns a MEDCouplingUMesh of a relative dimension == -3.
2986 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2987 * optional numbers of mesh entities.
2988 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2989 * delete using decrRef() as it is no more needed.
2990 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
2992 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
2994 return getMeshAtLevel(-3,renum);
2998 * This method is for advanced users. There is two storing strategy of mesh in \a this.
2999 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3000 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3001 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3003 void MEDFileUMesh::forceComputationOfParts() const
3005 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3007 const MEDFileUMeshSplitL1 *elt(*it);
3009 elt->forceComputationOfParts();
3014 * This method returns a vector of mesh parts containing each exactly one geometric type.
3015 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3016 * This method is only for memory aware users.
3017 * The returned pointers are **NOT** new object pointer. No need to mange them.
3019 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3021 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3022 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3026 * This method returns the part of \a this having the geometric type \a gt.
3027 * If such part is not existing an exception will be thrown.
3028 * The returned pointer is **NOT** new object pointer. No need to mange it.
3030 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3032 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3033 int lev=(int)cm.getDimension()-getMeshDimension();
3034 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3035 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3039 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3040 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3042 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3044 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3045 return sp->getGeoTypes();
3049 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3050 * \param [in] gt - the geometric type for which the family field is asked.
3051 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3052 * delete using decrRef() as it is no more needed.
3053 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3055 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3057 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3058 int lev=(int)cm.getDimension()-getMeshDimension();
3059 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3060 return sp->extractFamilyFieldOnGeoType(gt);
3064 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3065 * \param [in] gt - the geometric type for which the number field is asked.
3066 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3067 * delete using decrRef() as it is no more needed.
3068 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3070 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3072 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3073 int lev=(int)cm.getDimension()-getMeshDimension();
3074 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3075 return sp->extractNumberFieldOnGeoType(gt);
3078 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3080 if(meshDimRelToMaxExt==1)
3081 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3082 if(meshDimRelToMaxExt>1)
3083 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3084 int tracucedRk=-meshDimRelToMaxExt;
3085 if(tracucedRk>=(int)_ms.size())
3086 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3087 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3088 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3089 return _ms[tracucedRk];
3092 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3094 if(meshDimRelToMaxExt==1)
3095 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3096 if(meshDimRelToMaxExt>1)
3097 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3098 int tracucedRk=-meshDimRelToMaxExt;
3099 if(tracucedRk>=(int)_ms.size())
3100 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3101 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3102 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3103 return _ms[tracucedRk];
3106 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3108 if(-meshDimRelToMax>=(int)_ms.size())
3109 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3111 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3113 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3115 int ref=(*it)->getMeshDimension();
3116 if(ref+i!=meshDim-meshDimRelToMax)
3117 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3123 * Sets the node coordinates array of \a this mesh.
3124 * \param [in] coords - the new node coordinates array.
3125 * \throw If \a coords == \c NULL.
3127 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3130 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3131 coords->checkAllocated();
3132 int nbOfTuples=coords->getNumberOfTuples();
3135 _fam_coords=DataArrayInt::New();
3136 _fam_coords->alloc(nbOfTuples,1);
3137 _fam_coords->fillWithZero();
3138 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3139 if((MEDFileUMeshSplitL1 *)(*it))
3140 (*it)->setCoords(coords);
3144 * Removes all groups of a given dimension in \a this mesh.
3145 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3146 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3148 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3150 if(meshDimRelToMaxExt==1)
3152 if((DataArrayInt *)_fam_coords)
3153 _fam_coords->fillWithZero();
3156 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3157 l1->eraseFamilyField();
3162 * Removes all families with ids not present in the family fields of \a this mesh.
3164 void MEDFileUMesh::optimizeFamilies()
3166 std::vector<int> levs=getNonEmptyLevelsExt();
3167 std::set<int> allFamsIds;
3168 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3170 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3171 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3173 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3176 std::set<std::string> famNamesToKill;
3177 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3179 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3180 famNamesToKill.insert((*it).first);
3182 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3183 _families.erase(*it);
3184 std::vector<std::string> grpNamesToKill;
3185 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3187 std::vector<std::string> tmp;
3188 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3190 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3191 tmp.push_back(*it2);
3196 tmp.push_back((*it).first);
3198 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3202 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3204 std::vector<int> levs=getNonEmptyLevels();
3205 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3206 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3207 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3208 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3209 int nbNodes=m0->getNumberOfNodes();
3210 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3211 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3212 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3213 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3214 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3215 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3216 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3217 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3218 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3219 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3220 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3221 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3222 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3223 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3224 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3225 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3226 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3227 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3228 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3229 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3230 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3231 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3232 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3233 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3234 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3235 m0->setCoords(tmp0->getCoords());
3236 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3237 m1->setCoords(m0->getCoords());
3238 _coords=m0->getCoords(); _coords->incrRef();
3239 // duplication of cells in group 'grpNameM1' on level -1
3240 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3241 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3242 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3243 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3244 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3246 newm1->setName(getName());
3247 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3249 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3250 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3251 newFam->alloc(newm1->getNumberOfCells(),1);
3252 int idd=getMaxFamilyId()+1;
3253 int globStart=0,start=0,end,globEnd;
3254 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3255 for(int i=0;i<nbOfChunks;i++)
3257 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3258 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3260 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3261 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3262 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3267 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3271 newm1->setCoords(getCoords());
3272 setMeshAtLevel(-1,newm1);
3273 setFamilyFieldArr(-1,newFam);
3274 std::string grpName2(grpNameM1); grpName2+="_dup";
3275 addFamily(grpName2,idd);
3276 addFamilyOnGrp(grpName2,grpName2);
3281 int newNbOfNodes=getCoords()->getNumberOfTuples();
3282 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3283 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3284 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3287 nodesDuplicated=nodeIdsToDuplicate.retn();
3288 cellsModified=cellsToModifyConn0.retn();
3289 cellsNotModified=cellsToModifyConn1.retn();
3293 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3294 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3295 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3297 * \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.
3298 * 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.
3300 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3302 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3303 std::vector<int> levs=getNonEmptyLevels();
3305 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3306 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3309 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3311 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3312 std::vector<int> code1=m->getDistributionOfTypes();
3313 end=PutInThirdComponentOfCodeOffset(code1,start);
3314 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3315 bool hasChanged=m->unPolyze();
3316 DataArrayInt *fake=0;
3317 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3318 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3320 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3323 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3324 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3326 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3327 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3328 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3329 setMeshAtLevel(*it,m);
3330 std::vector<int> code2=m->getDistributionOfTypes();
3331 end=PutInThirdComponentOfCodeOffset(code2,start);
3332 newCode.insert(newCode.end(),code2.begin(),code2.end());
3334 if(o2nCellsPart2->isIdentity())
3338 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3339 setFamilyFieldArr(*it,newFamField);
3343 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3344 setRenumFieldArr(*it,newNumField);
3349 newCode.insert(newCode.end(),code1.begin(),code1.end());
3355 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3356 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3357 o2nRenumCell=o2nRenumCellRet.retn();
3362 struct MEDLoaderAccVisit1
3364 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3365 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3366 int _new_nb_of_nodes;
3370 * 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.
3371 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3372 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3373 * -1 values in returned array means that the corresponding old node is no more used.
3375 * \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
3376 * is modified in \a this.
3377 * \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
3380 DataArrayInt *MEDFileUMesh::zipCoords()
3382 const DataArrayDouble *coo=getCoords();
3384 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3385 int nbOfNodes=coo->getNumberOfTuples();
3386 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3387 std::vector<int> neLevs=getNonEmptyLevels();
3388 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3390 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3391 m->computeNodeIdsAlg(nodeIdsInUse);
3393 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3394 if(nbrOfNodesInUse==nbOfNodes)
3396 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3397 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3398 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3399 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3400 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3401 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3402 if((const DataArrayInt *)_fam_coords)
3403 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3404 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3405 if((const DataArrayInt *)_num_coords)
3406 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3407 if((const DataArrayAsciiChar *)_name_coords)
3408 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3409 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3410 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3412 if((MEDFileUMeshSplitL1*)*it)
3413 (*it)->renumberNodesInConn(ret->begin());
3419 * Adds a group of nodes to \a this mesh.
3420 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3421 * The ids should be sorted and different each other (MED file norm).
3422 * \throw If the node coordinates array is not set.
3423 * \throw If \a ids == \c NULL.
3424 * \throw If \a ids->getName() == "".
3425 * \throw If \a ids does not respect the MED file norm.
3426 * \throw If a group with name \a ids->getName() already exists.
3428 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
3430 const DataArrayDouble *coords=_coords;
3432 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3433 int nbOfNodes=coords->getNumberOfTuples();
3434 if(!((DataArrayInt *)_fam_coords))
3435 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3437 addGroupUnderground(true,ids,_fam_coords);
3441 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3442 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3443 * The ids should be sorted and different each other (MED file norm).
3444 * \throw If the node coordinates array is not set.
3445 * \throw If \a ids == \c NULL.
3446 * \throw If \a ids->getName() == "".
3447 * \throw If \a ids does not respect the MED file norm.
3448 * \throw If a group with name \a ids->getName() already exists.
3450 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
3452 std::vector<int> levs=getNonEmptyLevelsExt();
3453 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3455 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3456 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3458 if(meshDimRelToMaxExt==1)
3459 { addNodeGroup(ids); return ; }
3460 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3461 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3462 addGroupUnderground(false,ids,fam);
3466 * \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).
3467 * \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)
3469 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
3472 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3473 std::string grpName(ids->getName());
3475 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3476 ids->checkStrictlyMonotonic(true);
3477 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3478 std::vector<std::string> grpsNames=getGroupsNames();
3479 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3481 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3482 throw INTERP_KERNEL::Exception(oss.str().c_str());
3484 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3485 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3486 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3487 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3488 std::vector<int> familyIds;
3489 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3490 int maxVal=getTheMaxAbsFamilyId()+1;
3491 std::map<std::string,int> families(_families);
3492 std::map<std::string, std::vector<std::string> > groups(_groups);
3493 std::vector<std::string> fams;
3494 bool created(false);
3495 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3497 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3498 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3499 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3500 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3503 bool isFamPresent=false;
3504 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3505 isFamPresent=(*itl)->presenceOfValue(*famId);
3507 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3510 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3511 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3512 fams.push_back(locFamName);
3513 if(existsFamily(*famId))
3515 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3516 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3519 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3523 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3524 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3525 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3526 if(existsFamily(*famId))
3528 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3529 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3534 for(std::size_t i=0;i<familyIds.size();i++)
3536 DataArrayInt *da=idsPerfamiliyIds[i];
3537 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3541 _groups[grpName]=fams;
3545 * Changes a name of a family specified by its id.
3546 * \param [in] id - the id of the family of interest.
3547 * \param [in] newFamName - the new family name.
3548 * \throw If no family with the given \a id exists.
3550 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
3552 std::string oldName=getFamilyNameGivenId(id);
3553 _families.erase(oldName);
3554 _families[newFamName]=id;
3558 * Removes a mesh of a given dimension.
3559 * \param [in] meshDimRelToMax - the relative dimension of interest.
3560 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3562 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
3564 std::vector<int> levSet=getNonEmptyLevels();
3565 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3566 if(it==levSet.end())
3567 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3568 int pos=(-meshDimRelToMax);
3573 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
3574 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3575 * \param [in] m - the new mesh to set.
3576 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3578 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3579 * another node coordinates array.
3580 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3581 * to the existing meshes of other levels of \a this mesh.
3583 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
3585 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
3586 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3590 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3591 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3592 * \param [in] m - the new mesh to set.
3593 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3594 * writing \a this mesh in a MED file.
3595 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3597 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3598 * another node coordinates array.
3599 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3600 * to the existing meshes of other levels of \a this mesh.
3602 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
3604 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
3605 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3608 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
3610 dealWithTinyInfo(m);
3611 std::vector<int> levSet=getNonEmptyLevels();
3612 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3614 if((DataArrayDouble *)_coords==0)
3616 DataArrayDouble *c=m->getCoords();
3621 if(m->getCoords()!=_coords)
3622 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3623 int sz=(-meshDimRelToMax)+1;
3624 if(sz>=(int)_ms.size())
3626 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3630 return _ms[-meshDimRelToMax];
3634 * This method allows to set at once the content of different levels in \a this.
3635 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3637 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3638 * \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.
3639 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3641 * \throw If \a there is a null pointer in \a ms.
3642 * \sa MEDFileUMesh::setMeshAtLevel
3644 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3648 const MEDCouplingUMesh *mRef=ms[0];
3650 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3651 std::string name(mRef->getName());
3652 const DataArrayDouble *coo(mRef->getCoords());
3655 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3657 const MEDCouplingUMesh *cur(*it);
3659 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3660 if(coo!=cur->getCoords())
3661 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3662 int mdim=cur->getMeshDimension();
3663 zeDim=std::max(zeDim,mdim);
3664 if(s.find(mdim)!=s.end())
3665 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3667 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3669 int mdim=(*it)->getMeshDimension();
3670 setName((*it)->getName());
3671 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3677 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3678 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3679 * The given meshes must share the same node coordinates array.
3680 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3681 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3682 * create in \a this mesh.
3683 * \throw If \a ms is empty.
3684 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3685 * to the existing meshes of other levels of \a this mesh.
3686 * \throw If the meshes in \a ms do not share the same node coordinates array.
3687 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3688 * of the given meshes.
3689 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3690 * \throw If names of some meshes in \a ms are equal.
3691 * \throw If \a ms includes a mesh with an empty name.
3693 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3696 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3697 int sz=(-meshDimRelToMax)+1;
3698 if(sz>=(int)_ms.size())
3700 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3701 DataArrayDouble *coo=checkMultiMesh(ms);
3702 if((DataArrayDouble *)_coords==0)
3708 if((DataArrayDouble *)_coords!=coo)
3709 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3710 std::vector<DataArrayInt *> corr;
3711 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3712 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3713 setMeshAtLevel(meshDimRelToMax,m,renum);
3714 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3715 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3719 * Creates groups at a given level in \a this mesh from a sequence of
3720 * meshes each representing a group.
3721 * The given meshes must share the same node coordinates array.
3722 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3723 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3724 * create in \a this mesh.
3725 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3727 * \throw If \a ms is empty.
3728 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3729 * to the existing meshes of other levels of \a this mesh.
3730 * \throw If the meshes in \a ms do not share the same node coordinates array.
3731 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3732 * of the given meshes.
3733 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3734 * \throw If names of some meshes in \a ms are equal.
3735 * \throw If \a ms includes a mesh with an empty name.
3737 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3740 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3741 int sz=(-meshDimRelToMax)+1;
3742 if(sz>=(int)_ms.size())
3744 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3745 DataArrayDouble *coo=checkMultiMesh(ms);
3746 if((DataArrayDouble *)_coords==0)
3752 if((DataArrayDouble *)_coords!=coo)
3753 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3754 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3755 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3757 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3759 DataArrayInt *arr=0;
3760 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3764 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3765 throw INTERP_KERNEL::Exception(oss.str().c_str());
3768 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3769 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3772 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
3774 const DataArrayDouble *ret=ms[0]->getCoords();
3775 int mdim=ms[0]->getMeshDimension();
3776 for(unsigned int i=1;i<ms.size();i++)
3778 ms[i]->checkCoherency();
3779 if(ms[i]->getCoords()!=ret)
3780 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3781 if(ms[i]->getMeshDimension()!=mdim)
3782 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3784 return const_cast<DataArrayDouble *>(ret);
3788 * Sets the family field of a given relative dimension.
3789 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3790 * the family field is set.
3791 * \param [in] famArr - the array of the family field.
3792 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3793 * \throw If \a famArr has an invalid size.
3795 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
3797 if(meshDimRelToMaxExt==1)
3804 DataArrayDouble *coo(_coords);
3806 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3807 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3812 if(meshDimRelToMaxExt>1)
3813 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3814 int traducedRk=-meshDimRelToMaxExt;
3815 if(traducedRk>=(int)_ms.size())
3816 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3817 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3818 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3819 return _ms[traducedRk]->setFamilyArr(famArr);
3823 * Sets the optional numbers of mesh entities of a given dimension.
3824 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3825 * \param [in] renumArr - the array of the numbers.
3826 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3827 * \throw If \a renumArr has an invalid size.
3829 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
3831 if(meshDimRelToMaxExt==1)
3839 DataArrayDouble *coo(_coords);
3841 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3842 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3843 renumArr->incrRef();
3844 _num_coords=renumArr;
3848 if(meshDimRelToMaxExt>1)
3849 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3850 int traducedRk=-meshDimRelToMaxExt;
3851 if(traducedRk>=(int)_ms.size())
3852 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3853 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3854 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3855 return _ms[traducedRk]->setRenumArr(renumArr);
3859 * Sets the optional names of mesh entities of a given dimension.
3860 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3861 * \param [in] nameArr - the array of the names.
3862 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3863 * \throw If \a nameArr has an invalid size.
3865 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
3867 if(meshDimRelToMaxExt==1)
3874 DataArrayDouble *coo(_coords);
3876 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3877 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3879 _name_coords=nameArr;
3882 if(meshDimRelToMaxExt>1)
3883 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3884 int traducedRk=-meshDimRelToMaxExt;
3885 if(traducedRk>=(int)_ms.size())
3886 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3887 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3888 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3889 return _ms[traducedRk]->setNameArr(nameArr);
3892 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3894 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3895 if((const MEDFileUMeshSplitL1 *)(*it))
3896 (*it)->synchronizeTinyInfo(*this);
3900 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3902 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
3904 DataArrayInt *arr=_fam_coords;
3906 arr->changeValue(oldId,newId);
3907 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3909 MEDFileUMeshSplitL1 *sp=(*it);
3912 sp->changeFamilyIdArr(oldId,newId);
3917 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3919 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3920 const DataArrayInt *da(_fam_coords);
3922 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3923 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3925 const MEDFileUMeshSplitL1 *elt(*it);
3928 da=elt->getFamilyField();
3930 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3936 void MEDFileUMesh::computeRevNum() const
3938 if((const DataArrayInt *)_num_coords)
3941 int maxValue=_num_coords->getMaxValue(pos);
3942 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3946 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
3948 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
3951 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildren() const
3953 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
3954 if((const DataArrayInt *)_fam_nodes)
3955 ret.push_back((const DataArrayInt *)_fam_nodes);
3956 if((const DataArrayInt *)_num_nodes)
3957 ret.push_back((const DataArrayInt *)_num_nodes);
3958 if((const DataArrayInt *)_fam_cells)
3959 ret.push_back((const DataArrayInt *)_fam_cells);
3960 if((const DataArrayInt *)_num_cells)
3961 ret.push_back((const DataArrayInt *)_num_nodes);
3962 if((const DataArrayInt *)_rev_num_nodes)
3963 ret.push_back((const DataArrayInt *)_rev_num_nodes);
3964 if((const DataArrayInt *)_rev_num_cells)
3965 ret.push_back((const DataArrayInt *)_rev_num_cells);
3969 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
3971 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3972 if((const DataArrayInt *)_fam_nodes)
3974 int val=_fam_nodes->getMaxValue(tmp);
3975 ret=std::max(ret,std::abs(val));
3977 if((const DataArrayInt *)_fam_cells)
3979 int val=_fam_cells->getMaxValue(tmp);
3980 ret=std::max(ret,std::abs(val));
3985 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
3987 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3988 if((const DataArrayInt *)_fam_nodes)
3990 int val=_fam_nodes->getMaxValue(tmp);
3991 ret=std::max(ret,val);
3993 if((const DataArrayInt *)_fam_cells)
3995 int val=_fam_cells->getMaxValue(tmp);
3996 ret=std::max(ret,val);
4001 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4003 int ret=std::numeric_limits<int>::max(),tmp=-1;
4004 if((const DataArrayInt *)_fam_nodes)
4006 int val=_fam_nodes->getMinValue(tmp);
4007 ret=std::min(ret,val);
4009 if((const DataArrayInt *)_fam_cells)
4011 int val=_fam_cells->getMinValue(tmp);
4012 ret=std::min(ret,val);
4017 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4019 if(!MEDFileMesh::isEqual(other,eps,what))
4021 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4024 what="Mesh types differ ! This is structured and other is NOT !";
4027 const DataArrayInt *famc1=_fam_nodes;
4028 const DataArrayInt *famc2=otherC->_fam_nodes;
4029 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4031 what="Mismatch of families arr on nodes ! One is defined and not other !";
4036 bool ret=famc1->isEqual(*famc2);
4039 what="Families arr on nodes differ !";
4044 famc2=otherC->_fam_cells;
4045 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4047 what="Mismatch of families arr on cells ! One is defined and not other !";
4052 bool ret=famc1->isEqual(*famc2);
4055 what="Families arr on cells differ !";
4060 famc2=otherC->_num_nodes;
4061 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4063 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4068 bool ret=famc1->isEqual(*famc2);
4071 what="Numbering arr on nodes differ !";
4076 famc2=otherC->_num_cells;
4077 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4079 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4084 bool ret=famc1->isEqual(*famc2);
4087 what="Numbering arr on cells differ !";
4091 const DataArrayAsciiChar *d1=_names_cells;
4092 const DataArrayAsciiChar *d2=otherC->_names_cells;
4093 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4095 what="Mismatch of naming arr on cells ! One is defined and not other !";
4100 bool ret=d1->isEqual(*d2);
4103 what="Naming arr on cells differ !";
4108 d2=otherC->_names_nodes;
4109 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4111 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4116 bool ret=d1->isEqual(*d2);
4119 what="Naming arr on nodes differ !";
4126 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4128 MEDFileMesh::clearNonDiscrAttributes();
4129 const DataArrayInt *tmp=_fam_nodes;
4131 (const_cast<DataArrayInt *>(tmp))->setName("");
4134 (const_cast<DataArrayInt *>(tmp))->setName("");
4137 (const_cast<DataArrayInt *>(tmp))->setName("");
4140 (const_cast<DataArrayInt *>(tmp))->setName("");
4144 * Returns ids of mesh entities contained in given families of a given dimension.
4145 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4147 * \param [in] fams - the names of the families of interest.
4148 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4149 * returned instead of ids.
4150 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4151 * numbers, if available and required, of mesh entities of the families. The caller
4152 * is to delete this array using decrRef() as it is no more needed.
4153 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4155 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4157 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4158 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
4159 std::vector<int> famIds=getFamiliesIds(fams);
4160 if(meshDimRelToMaxExt==1)
4162 if((const DataArrayInt *)_fam_nodes)
4164 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4166 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4168 da=_fam_nodes->getIdsEqualList(0,0);
4170 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4175 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4179 if((const DataArrayInt *)_fam_cells)
4181 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4183 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4185 da=_fam_cells->getIdsEqualList(0,0);
4187 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4192 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4197 * Sets the family field of a given relative dimension.
4198 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4199 * the family field is set.
4200 * \param [in] famArr - the array of the family field.
4201 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4202 * \throw If \a famArr has an invalid size.
4203 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4205 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4207 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4208 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4209 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4211 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4212 if(meshDimRelToMaxExt==0)
4214 int nbCells=mesh->getNumberOfCells();
4215 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4220 int nbNodes=mesh->getNumberOfNodes();
4221 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4229 * Sets the optional numbers of mesh entities of a given dimension.
4230 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4231 * \param [in] renumArr - the array of the numbers.
4232 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4233 * \throw If \a renumArr has an invalid size.
4234 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4236 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4238 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4239 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4240 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4242 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4243 if(meshDimRelToMaxExt==0)
4245 int nbCells=mesh->getNumberOfCells();
4246 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4247 _num_cells=renumArr;
4251 int nbNodes=mesh->getNumberOfNodes();
4252 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4253 _num_nodes=renumArr;
4256 renumArr->incrRef();
4260 * Sets the optional names of mesh entities of a given dimension.
4261 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4262 * \param [in] nameArr - the array of the names.
4263 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4264 * \throw If \a nameArr has an invalid size.
4266 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4268 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4269 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
4270 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4272 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4273 if(meshDimRelToMaxExt==0)
4275 int nbCells=mesh->getNumberOfCells();
4276 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4277 _names_cells=nameArr;
4281 int nbNodes=mesh->getNumberOfNodes();
4282 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4283 _names_nodes=nameArr;
4290 * Returns the family field for mesh entities of a given dimension.
4291 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4292 * \return const DataArrayInt * - the family field. It is an array of ids of families
4293 * each mesh entity belongs to. It can be \c NULL.
4294 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4296 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
4298 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4299 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
4300 if(meshDimRelToMaxExt==0)
4307 * Returns the optional numbers of mesh entities of a given dimension.
4308 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4309 * \return const DataArrayInt * - the array of the entity numbers.
4310 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4311 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4313 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
4315 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4316 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
4317 if(meshDimRelToMaxExt==0)
4324 * Returns the optional numbers of mesh entities of a given dimension transformed using
4325 * DataArrayInt::invertArrayN2O2O2N().
4326 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4327 * \return const DataArrayInt * - the array of the entity numbers transformed using
4328 * DataArrayInt::invertArrayN2O2O2N().
4329 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4330 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4332 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
4334 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4335 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4336 if(meshDimRelToMaxExt==0)
4338 if((const DataArrayInt *)_num_cells)
4341 int maxValue=_num_cells->getMaxValue(pos);
4342 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4343 return _rev_num_cells;
4346 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4350 if((const DataArrayInt *)_num_nodes)
4353 int maxValue=_num_nodes->getMaxValue(pos);
4354 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4355 return _rev_num_nodes;
4358 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4362 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
4364 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4365 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
4366 if(meshDimRelToMaxExt==0)
4367 return _names_cells;
4369 return _names_nodes;
4373 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4374 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4376 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4378 std::vector<int> ret(1);
4383 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4384 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4386 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4388 std::vector<int> ret(2);
4394 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4396 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4398 std::vector<int> ret;
4399 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells);
4408 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4410 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4412 std::vector<int> ret;
4413 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells);
4422 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4424 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4426 std::vector<int> ret;
4427 const DataArrayAsciiChar *namesCells(_names_cells);
4434 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4436 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4438 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4442 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
4444 DataArrayInt *arr=_fam_nodes;
4446 arr->changeValue(oldId,newId);
4449 arr->changeValue(oldId,newId);
4452 void MEDFileStructuredMesh::deepCpyAttributes()
4454 if((const DataArrayInt*)_fam_nodes)
4455 _fam_nodes=_fam_nodes->deepCpy();
4456 if((const DataArrayInt*)_num_nodes)
4457 _num_nodes=_num_nodes->deepCpy();
4458 if((const DataArrayInt*)_fam_cells)
4459 _fam_cells=_fam_cells->deepCpy();
4460 if((const DataArrayInt*)_num_cells)
4461 _num_cells=_num_cells->deepCpy();
4462 if((const DataArrayInt*)_rev_num_nodes)
4463 _rev_num_nodes=_rev_num_nodes->deepCpy();
4464 if((const DataArrayInt*)_rev_num_cells)
4465 _rev_num_cells=_rev_num_cells->deepCpy();
4469 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4471 * \return a pointer to cartesian mesh that need to be managed by the caller.
4472 * \warning the returned pointer has to be managed by the caller.
4476 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4477 * \param [in] meshDimRelToMax - it must be \c 0.
4478 * \param [in] renum - it must be \c false.
4479 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4480 * delete using decrRef() as it is no more needed.
4482 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
4485 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4486 if(meshDimRelToMax!=0)
4487 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4488 const MEDCouplingStructuredMesh *m=getStructuredMesh();
4491 return const_cast<MEDCouplingStructuredMesh *>(m);
4495 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4496 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4497 * \return int - the number of entities.
4498 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4500 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
4502 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4503 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
4504 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4506 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4507 if(meshDimRelToMaxExt==0)
4508 return cmesh->getNumberOfCells();
4510 return cmesh->getNumberOfNodes();
4513 int MEDFileStructuredMesh::getNumberOfNodes() const
4515 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4517 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4518 return cmesh->getNumberOfNodes();
4521 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
4523 if(meshDimRelToMax!=0)
4524 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory !");
4525 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
4526 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
4530 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
4532 if(st.getNumberOfItems()!=1)
4533 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 !");
4534 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4535 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4536 if(getNumberOfNodes()!=(int)nodesFetched.size())
4537 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4538 if(st[0].getPflName().empty())
4540 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4543 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
4544 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4545 int sz(nodesFetched.size());
4546 for(const int *work=arr->begin();work!=arr->end();work++)
4548 std::vector<int> conn;
4549 cmesh->getNodeIdsOfCell(*work,conn);
4550 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4551 if(*it>=0 && *it<sz)
4552 nodesFetched[*it]=true;
4554 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4558 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
4560 med_geometry_type geoTypeReq=MED_NONE;
4564 geoTypeReq=MED_HEXA8;
4567 geoTypeReq=MED_QUAD4;
4570 geoTypeReq=MED_SEG2;
4573 geoTypeReq=MED_POINT1;
4576 throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
4581 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4583 setName(strm->getName());
4584 setDescription(strm->getDescription());
4585 setUnivName(strm->getUnivName());
4586 setIteration(strm->getIteration());
4587 setOrder(strm->getOrder());
4588 setTimeValue(strm->getTime());
4589 setTimeUnit(strm->getTimeUnit());
4590 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4591 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4592 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4595 if(!mrs || mrs->isNodeFamilyFieldReading())
4597 _fam_nodes=DataArrayInt::New();
4598 _fam_nodes->alloc(nbOfElt,1);
4599 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4602 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4605 if(!mrs || mrs->isNodeNumFieldReading())
4607 _num_nodes=DataArrayInt::New();
4608 _num_nodes->alloc(nbOfElt,1);
4609 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4612 int meshDim=getStructuredMesh()->getMeshDimension();
4613 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4614 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4617 if(!mrs || mrs->isCellFamilyFieldReading())
4619 _fam_cells=DataArrayInt::New();
4620 _fam_cells->alloc(nbOfElt,1);
4621 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
4624 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4627 if(!mrs || mrs->isCellNumFieldReading())
4629 _num_cells=DataArrayInt::New();
4630 _num_cells->alloc(nbOfElt,1);
4631 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
4634 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4637 if(!mrs || mrs->isCellNameFieldReading())
4639 _names_cells=DataArrayAsciiChar::New();
4640 _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4641 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
4642 _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4645 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4648 if(!mrs || mrs->isNodeNameFieldReading())
4650 _names_nodes=DataArrayAsciiChar::New();
4651 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4652 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4653 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4658 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
4660 int meshDim=getStructuredMesh()->getMeshDimension();
4661 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4663 if((const DataArrayInt *)_fam_cells)
4664 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4665 if((const DataArrayInt *)_fam_nodes)
4666 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4667 if((const DataArrayInt *)_num_cells)
4668 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4669 if((const DataArrayInt *)_num_nodes)
4670 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4671 if((const DataArrayAsciiChar *)_names_cells)
4673 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4675 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4676 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4677 throw INTERP_KERNEL::Exception(oss.str().c_str());
4679 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4681 if((const DataArrayAsciiChar *)_names_nodes)
4683 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4685 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4686 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4687 throw INTERP_KERNEL::Exception(oss.str().c_str());
4689 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4692 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
4696 * Returns an empty instance of MEDFileCMesh.
4697 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4698 * mesh using decrRef() as it is no more needed.
4700 MEDFileCMesh *MEDFileCMesh::New()
4702 return new MEDFileCMesh;
4706 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4707 * file. The first mesh in the file is loaded.
4708 * \param [in] fileName - the name of MED file to read.
4709 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4710 * mesh using decrRef() as it is no more needed.
4711 * \throw If the file is not readable.
4712 * \throw If there is no meshes in the file.
4713 * \throw If the mesh in the file is not a Cartesian one.
4715 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
4717 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4720 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4721 throw INTERP_KERNEL::Exception(oss.str().c_str());
4723 MEDFileUtilities::CheckFileForRead(fileName);
4724 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4726 ParaMEDMEM::MEDCouplingMeshType meshType;
4728 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
4729 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
4733 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4734 * file. The mesh to load is specified by its name and numbers of a time step and an
4736 * \param [in] fileName - the name of MED file to read.
4737 * \param [in] mName - the name of the mesh to read.
4738 * \param [in] dt - the number of a time step.
4739 * \param [in] it - the number of an iteration.
4740 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4741 * mesh using decrRef() as it is no more needed.
4742 * \throw If the file is not readable.
4743 * \throw If there is no mesh with given attributes in the file.
4744 * \throw If the mesh in the file is not a Cartesian one.
4746 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4748 MEDFileUtilities::CheckFileForRead(fileName);
4749 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4750 return new MEDFileCMesh(fid,mName,dt,it,mrs);
4753 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
4755 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
4758 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildren() const
4760 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
4761 if((const MEDCouplingCMesh *)_cmesh)
4762 ret.push_back((const MEDCouplingCMesh *)_cmesh);
4767 * Returns the dimension on cells in \a this mesh.
4768 * \return int - the mesh dimension.
4769 * \throw If there are no cells in this mesh.
4771 int MEDFileCMesh::getMeshDimension() const
4773 if(!((const MEDCouplingCMesh*)_cmesh))
4774 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4775 return _cmesh->getMeshDimension();
4779 * Returns the dimension on nodes in \a this mesh.
4780 * \return int - the space dimension.
4781 * \throw If there are no cells in this mesh.
4783 int MEDFileCMesh::getSpaceDimension() const
4785 if(!((const MEDCouplingCMesh*)_cmesh))
4786 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
4787 return _cmesh->getSpaceDimension();
4791 * Returns a string describing \a this mesh.
4792 * \return std::string - the mesh information string.
4794 std::string MEDFileCMesh::simpleRepr() const
4796 return MEDFileStructuredMesh::simpleRepr();
4800 * Returns a full textual description of \a this mesh.
4801 * \return std::string - the string holding the mesh description.
4803 std::string MEDFileCMesh::advancedRepr() const
4805 return simpleRepr();
4808 MEDFileMesh *MEDFileCMesh::shallowCpy() const
4810 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4814 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
4816 return new MEDFileCMesh;
4819 MEDFileMesh *MEDFileCMesh::deepCpy() const
4821 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4822 if((const MEDCouplingCMesh*)_cmesh)
4823 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
4824 ret->deepCpyAttributes();
4829 * Checks if \a this and another mesh are equal.
4830 * \param [in] other - the mesh to compare with.
4831 * \param [in] eps - a precision used to compare real values.
4832 * \param [in,out] what - the string returning description of unequal data.
4833 * \return bool - \c true if the meshes are equal, \c false, else.
4835 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4837 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4839 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
4842 what="Mesh types differ ! This is cartesian and other is NOT !";
4845 clearNonDiscrAttributes();
4846 otherC->clearNonDiscrAttributes();
4847 const MEDCouplingCMesh *coo1=_cmesh;
4848 const MEDCouplingCMesh *coo2=otherC->_cmesh;
4849 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4851 what="Mismatch of cartesian meshes ! One is defined and not other !";
4856 bool ret=coo1->isEqual(coo2,eps);
4859 what="cartesian meshes differ !";
4867 * Clears redundant attributes of incorporated data arrays.
4869 void MEDFileCMesh::clearNonDiscrAttributes() const
4871 MEDFileStructuredMesh::clearNonDiscrAttributes();
4872 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
4875 MEDFileCMesh::MEDFileCMesh()
4879 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4882 loadCMeshFromFile(fid,mName,dt,it,mrs);
4884 catch(INTERP_KERNEL::Exception& e)
4889 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4891 ParaMEDMEM::MEDCouplingMeshType meshType;
4894 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4895 if(meshType!=CARTESIAN)
4897 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
4898 throw INTERP_KERNEL::Exception(oss.str().c_str());
4900 MEDFileCMeshL2 loaderl2;
4901 loaderl2.loadAll(fid,mid,mName,dt,it);
4902 MEDCouplingCMesh *mesh=loaderl2.getMesh();
4905 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
4909 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
4910 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
4912 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
4914 synchronizeTinyInfoOnLeaves();
4918 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
4920 synchronizeTinyInfoOnLeaves();
4925 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
4926 * \param [in] m - the new MEDCouplingCMesh to refer to.
4927 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4930 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
4932 dealWithTinyInfo(m);
4938 void MEDFileCMesh::writeLL(med_idt fid) const
4940 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4941 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4942 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4943 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4944 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4945 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4946 int spaceDim(_cmesh->getSpaceDimension());
4947 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4948 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4949 for(int i=0;i<spaceDim;i++)
4951 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
4953 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4954 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
4955 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
4957 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4958 MEDmeshUniversalNameWr(fid,maa);
4959 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
4960 for(int i=0;i<spaceDim;i++)
4962 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
4963 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
4966 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
4967 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
4970 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
4972 const MEDCouplingCMesh *cmesh=_cmesh;
4975 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
4976 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
4977 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
4978 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
4981 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
4983 return new MEDFileCurveLinearMesh;
4986 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
4988 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4991 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4992 throw INTERP_KERNEL::Exception(oss.str().c_str());
4994 MEDFileUtilities::CheckFileForRead(fileName);
4995 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4997 ParaMEDMEM::MEDCouplingMeshType meshType;
4999 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5000 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
5003 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5005 MEDFileUtilities::CheckFileForRead(fileName);
5006 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5007 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
5010 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
5012 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5015 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildren() const
5017 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
5018 if((const MEDCouplingCurveLinearMesh *)_clmesh)
5019 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
5023 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
5025 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5029 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
5031 return new MEDFileCurveLinearMesh;
5034 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
5036 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5037 if((const MEDCouplingCurveLinearMesh*)_clmesh)
5038 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
5039 ret->deepCpyAttributes();
5043 int MEDFileCurveLinearMesh::getMeshDimension() const
5045 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
5046 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5047 return _clmesh->getMeshDimension();
5050 std::string MEDFileCurveLinearMesh::simpleRepr() const
5052 return MEDFileStructuredMesh::simpleRepr();
5055 std::string MEDFileCurveLinearMesh::advancedRepr() const
5057 return simpleRepr();
5060 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5062 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5064 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
5067 what="Mesh types differ ! This is curve linear and other is NOT !";
5070 clearNonDiscrAttributes();
5071 otherC->clearNonDiscrAttributes();
5072 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
5073 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
5074 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5076 what="Mismatch of curve linear meshes ! One is defined and not other !";
5081 bool ret=coo1->isEqual(coo2,eps);
5084 what="curve linear meshes differ !";
5091 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
5093 MEDFileStructuredMesh::clearNonDiscrAttributes();
5094 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
5097 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
5099 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
5102 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
5103 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
5104 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
5105 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
5108 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
5110 synchronizeTinyInfoOnLeaves();
5114 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
5116 dealWithTinyInfo(m);
5122 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
5124 synchronizeTinyInfoOnLeaves();
5128 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
5132 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5135 loadCLMeshFromFile(fid,mName,dt,it,mrs);
5137 catch(INTERP_KERNEL::Exception& e)
5142 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
5144 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5145 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5146 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5147 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5148 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5149 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5150 int spaceDim=_clmesh->getSpaceDimension();
5151 int meshDim=_clmesh->getMeshDimension();
5152 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5153 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5154 const DataArrayDouble *coords=_clmesh->getCoords();
5156 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
5157 for(int i=0;i<spaceDim;i++)
5159 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
5161 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5162 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
5163 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
5165 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5166 MEDmeshUniversalNameWr(fid,maa);
5167 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5168 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5169 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5171 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5173 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5174 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5177 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5179 ParaMEDMEM::MEDCouplingMeshType meshType;
5182 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5183 if(meshType!=CURVE_LINEAR)
5185 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5186 throw INTERP_KERNEL::Exception(oss.str().c_str());
5188 MEDFileCLMeshL2 loaderl2;
5189 loaderl2.loadAll(fid,mid,mName,dt,it);
5190 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5193 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5196 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5198 return new MEDFileMeshMultiTS;
5201 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
5203 return new MEDFileMeshMultiTS(fileName);
5206 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
5208 return new MEDFileMeshMultiTS(fileName,mName);
5211 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
5213 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5214 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5216 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5217 if((const MEDFileMesh *)*it)
5218 meshOneTs[i]=(*it)->deepCpy();
5219 ret->_mesh_one_ts=meshOneTs;
5223 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
5225 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5228 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildren() const
5230 std::vector<const BigMemoryObject *> ret;
5231 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5233 const MEDFileMesh *cur(*it);
5240 std::string MEDFileMeshMultiTS::getName() const
5242 if(_mesh_one_ts.empty())
5243 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5244 return _mesh_one_ts[0]->getName();
5247 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
5249 std::string oldName(getName());
5250 std::vector< std::pair<std::string,std::string> > v(1);
5251 v[0].first=oldName; v[0].second=newMeshName;
5255 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5258 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5260 MEDFileMesh *cur(*it);
5262 ret=cur->changeNames(modifTab) || ret;
5267 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
5269 if(_mesh_one_ts.empty())
5270 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5271 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5274 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
5277 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5278 _mesh_one_ts.resize(1);
5279 mesh1TimeStep->incrRef();
5280 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5281 _mesh_one_ts[0]=mesh1TimeStep;
5284 void MEDFileMeshMultiTS::write(med_idt fid) const
5286 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5288 (*it)->copyOptionsFrom(*this);
5293 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
5295 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5296 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5297 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5298 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5302 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
5303 {//for the moment to be improved
5304 _mesh_one_ts.resize(1);
5305 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5308 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5312 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
5315 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5318 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5319 throw INTERP_KERNEL::Exception(oss.str().c_str());
5321 MEDFileUtilities::CheckFileForRead(fileName);
5322 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5324 ParaMEDMEM::MEDCouplingMeshType meshType;
5326 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5327 loadFromFile(fileName,ms.front());
5329 catch(INTERP_KERNEL::Exception& e)
5334 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
5337 loadFromFile(fileName,mName);
5339 catch(INTERP_KERNEL::Exception& e)
5344 MEDFileMeshes *MEDFileMeshes::New()
5346 return new MEDFileMeshes;
5349 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
5351 return new MEDFileMeshes(fileName);
5354 void MEDFileMeshes::write(med_idt fid) const
5357 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5359 (*it)->copyOptionsFrom(*this);
5364 void MEDFileMeshes::write(const std::string& fileName, int mode) const
5366 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5367 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5368 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5369 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5374 int MEDFileMeshes::getNumberOfMeshes() const
5376 return _meshes.size();
5379 MEDFileMeshesIterator *MEDFileMeshes::iterator()
5381 return new MEDFileMeshesIterator(this);
5384 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
5386 if(i<0 || i>=(int)_meshes.size())
5388 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5389 throw INTERP_KERNEL::Exception(oss.str().c_str());
5391 return _meshes[i]->getOneTimeStep();
5394 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
5396 std::vector<std::string> ms=getMeshesNames();
5397 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5400 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5401 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5402 throw INTERP_KERNEL::Exception(oss.str().c_str());
5404 return getMeshAtPos((int)std::distance(ms.begin(),it));
5407 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
5409 std::vector<std::string> ret(_meshes.size());
5411 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5413 const MEDFileMeshMultiTS *f=(*it);
5416 ret[i]=f->getName();
5420 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5421 throw INTERP_KERNEL::Exception(oss.str().c_str());
5427 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5430 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5432 MEDFileMeshMultiTS *cur(*it);
5434 ret=cur->changeNames(modifTab) || ret;
5439 void MEDFileMeshes::resize(int newSize)
5441 _meshes.resize(newSize);
5444 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
5447 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5448 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5449 elt->setOneTimeStep(mesh);
5450 _meshes.push_back(elt);
5453 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
5456 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5457 if(i>=(int)_meshes.size())
5458 _meshes.resize(i+1);
5459 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5460 elt->setOneTimeStep(mesh);
5464 void MEDFileMeshes::destroyMeshAtPos(int i)
5466 if(i<0 || i>=(int)_meshes.size())
5468 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5469 throw INTERP_KERNEL::Exception(oss.str().c_str());
5471 _meshes.erase(_meshes.begin()+i);
5474 void MEDFileMeshes::loadFromFile(const std::string& fileName)
5476 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5478 _meshes.resize(ms.size());
5479 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5480 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
5483 MEDFileMeshes::MEDFileMeshes()
5487 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
5490 loadFromFile(fileName);
5492 catch(INTERP_KERNEL::Exception& /*e*/)
5496 MEDFileMeshes *MEDFileMeshes::deepCpy() const
5498 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5500 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5501 if((const MEDFileMeshMultiTS *)*it)
5502 meshes[i]=(*it)->deepCpy();
5503 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5504 ret->_meshes=meshes;
5508 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
5510 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5513 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildren() const
5515 std::vector<const BigMemoryObject *> ret;
5516 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5518 const MEDFileMeshMultiTS *cur(*it);
5525 std::string MEDFileMeshes::simpleRepr() const
5527 std::ostringstream oss;
5528 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5529 simpleReprWithoutHeader(oss);
5533 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5535 int nbOfMeshes=getNumberOfMeshes();
5536 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5537 std::vector<std::string> mns=getMeshesNames();
5538 for(int i=0;i<nbOfMeshes;i++)
5539 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5542 void MEDFileMeshes::checkCoherency() const
5544 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5546 std::set<std::string> s;
5547 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5549 const MEDFileMeshMultiTS *elt=(*it);
5552 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5553 throw INTERP_KERNEL::Exception(oss.str().c_str());
5555 std::size_t sz=s.size();
5556 s.insert(std::string((*it)->getName()));
5559 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5560 throw INTERP_KERNEL::Exception(oss.str().c_str());
5565 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5570 _nb_iter=ms->getNumberOfMeshes();
5574 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5578 MEDFileMesh *MEDFileMeshesIterator::nextt()
5580 if(_iter_id<_nb_iter)
5582 MEDFileMeshes *ms(_ms);
5584 return ms->getMeshAtPos(_iter_id++);