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))
247 * Clears redundant attributes of incorporated data arrays.
249 void MEDFileMesh::clearNonDiscrAttributes() const
254 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
256 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
258 if((*it).first==_name)
268 * Copies data on groups and families from another mesh.
269 * \param [in] other - the mesh to copy the data from.
271 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
273 _groups=other._groups;
274 _families=other._families;
279 * This method clear all the groups in the map.
280 * So this method does not operate at all on arrays.
281 * So this method can lead to orphan families.
283 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
285 void MEDFileMesh::clearGrpMap()
291 * This method clear all the families in the map.
292 * So this method does not operate at all on arrays.
293 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
295 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
297 void MEDFileMesh::clearFamMap()
303 * This method clear all the families and groups in the map.
304 * So this method does not operate at all on arrays.
305 * As all groups and families entry will be removed after
306 * 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.
308 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
310 void MEDFileMesh::clearFamGrpMaps()
317 * Returns names of families constituting a group.
318 * \param [in] name - the name of the group of interest.
319 * \return std::vector<std::string> - a sequence of names of the families.
320 * \throw If the name of a nonexistent group is specified.
322 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
324 std::string oname(name);
325 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
326 if(it==_groups.end())
328 std::vector<std::string> grps=getGroupsNames();
329 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
330 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
331 throw INTERP_KERNEL::Exception(oss.str().c_str());
337 * Returns names of families constituting some groups.
338 * \param [in] grps - a sequence of names of groups of interest.
339 * \return std::vector<std::string> - a sequence of names of the families.
340 * \throw If a name of a nonexistent group is present in \a grps.
342 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
344 std::set<std::string> fams;
345 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
347 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
348 if(it2==_groups.end())
350 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
351 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
352 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
353 throw INTERP_KERNEL::Exception(oss.str().c_str());
355 fams.insert((*it2).second.begin(),(*it2).second.end());
357 std::vector<std::string> fams2(fams.begin(),fams.end());
362 * Returns ids of families constituting a group.
363 * \param [in] name - the name of the group of interest.
364 * \return std::vector<int> - sequence of ids of the families.
365 * \throw If the name of a nonexistent group is specified.
367 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
369 std::string oname(name);
370 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
371 std::vector<std::string> grps=getGroupsNames();
372 if(it==_groups.end())
374 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
375 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
376 throw INTERP_KERNEL::Exception(oss.str().c_str());
378 return getFamiliesIds((*it).second);
382 * Sets names of families constituting a group. If data on families of this group is
383 * already present, it is overwritten. Every family in \a fams is checked, and if a
384 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
385 * \param [in] name - the name of the group of interest.
386 * \param [in] fams - a sequence of names of families constituting the group.
388 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
390 std::string oname(name);
392 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
394 std::map<std::string,int>::iterator it2=_families.find(*it1);
395 if(it2==_families.end())
401 * Sets families constituting a group. The families are specified by their ids.
402 * If a family name is not found by its id, an exception is thrown.
403 * If several families have same id, the first one in lexical order is taken.
404 * \param [in] name - the name of the group of interest.
405 * \param [in] famIds - a sequence of ids of families constituting the group.
406 * \throw If a family name is not found by its id.
408 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
410 std::string oname(name);
411 std::vector<std::string> fams(famIds.size());
413 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
415 std::string name2=getFamilyNameGivenId(*it1);
422 * Returns names of groups including a given family.
423 * \param [in] name - the name of the family of interest.
424 * \return std::vector<std::string> - a sequence of names of groups including the family.
426 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
428 std::vector<std::string> ret;
429 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
431 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
434 ret.push_back((*it1).first);
442 * Adds an existing family to groups.
443 * \param [in] famName - a name of family to add to \a grps.
444 * \param [in] grps - a sequence of group names to add the family in.
445 * \throw If a family named \a famName not yet exists.
447 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
449 std::string fName(famName);
450 const std::map<std::string,int>::const_iterator it=_families.find(fName);
451 if(it==_families.end())
453 std::vector<std::string> fams=getFamiliesNames();
454 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
455 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
456 throw INTERP_KERNEL::Exception(oss.str().c_str());
458 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
460 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
461 if(it2!=_groups.end())
462 (*it2).second.push_back(fName);
465 std::vector<std::string> grps2(1,fName);
472 * Returns names of all groups of \a this mesh.
473 * \return std::vector<std::string> - a sequence of group names.
475 std::vector<std::string> MEDFileMesh::getGroupsNames() const
477 std::vector<std::string> ret(_groups.size());
479 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
485 * Returns names of all families of \a this mesh.
486 * \return std::vector<std::string> - a sequence of family names.
488 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
490 std::vector<std::string> ret(_families.size());
492 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
498 * Changes a name of every family, included in one group only, to be same as the group name.
499 * \throw If there are families with equal names in \a this mesh.
501 void MEDFileMesh::assignFamilyNameWithGroupName()
503 std::map<std::string, std::vector<std::string> > groups(_groups);
504 std::map<std::string,int> newFams;
505 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
507 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
508 if(grps.size()==1 && groups[grps[0]].size()==1)
510 if(newFams.find(grps[0])!=newFams.end())
512 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
513 throw INTERP_KERNEL::Exception(oss.str().c_str());
515 newFams[grps[0]]=(*it).second;
516 std::vector<std::string>& grps2=groups[grps[0]];
517 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
522 if(newFams.find((*it).first)!=newFams.end())
524 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
525 throw INTERP_KERNEL::Exception(oss.str().c_str());
527 newFams[(*it).first]=(*it).second;
535 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
537 * \return the removed groups.
539 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
541 std::vector<std::string> ret;
542 std::map<std::string, std::vector<std::string> > newGrps;
543 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
545 if((*it).second.empty())
546 ret.push_back((*it).first);
548 newGrps[(*it).first]=(*it).second;
556 * Removes a group from \a this mesh.
557 * \param [in] name - the name of the group to remove.
558 * \throw If no group with such a \a name exists.
560 void MEDFileMesh::removeGroup(const std::string& name)
562 std::string oname(name);
563 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
564 std::vector<std::string> grps=getGroupsNames();
565 if(it==_groups.end())
567 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
568 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
569 throw INTERP_KERNEL::Exception(oss.str().c_str());
575 * Removes a family from \a this mesh.
576 * \param [in] name - the name of the family to remove.
577 * \throw If no family with such a \a name exists.
579 void MEDFileMesh::removeFamily(const std::string& name)
581 std::string oname(name);
582 std::map<std::string, int >::iterator it=_families.find(oname);
583 std::vector<std::string> fams=getFamiliesNames();
584 if(it==_families.end())
586 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
587 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
588 throw INTERP_KERNEL::Exception(oss.str().c_str());
591 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
593 std::vector<std::string>& v=(*it3).second;
594 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
601 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
602 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
603 * family field whatever its level. This method also suppresses the orphan families.
605 * \return - The list of removed groups names.
607 * \sa MEDFileMesh::removeOrphanFamilies.
609 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
611 removeOrphanFamilies();
612 return removeEmptyGroups();
616 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
617 * 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.
619 * \return - The list of removed families names.
620 * \sa MEDFileMesh::removeOrphanGroups.
622 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
624 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
625 std::vector<std::string> ret;
626 if(!((DataArrayInt*)allFamIdsInUse))
628 ret=getFamiliesNames();
629 _families.clear(); _groups.clear();
632 std::map<std::string,int> famMap;
633 std::map<std::string, std::vector<std::string> > grps(_groups);
634 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
636 if(allFamIdsInUse->presenceOfValue((*it).second))
637 famMap[(*it).first]=(*it).second;
640 ret.push_back((*it).first);
641 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
642 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
644 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
645 std::vector<std::string>& famv=(*it3).second;
646 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
652 { _families=famMap; _groups=grps; }
657 * Renames a group in \a this mesh.
658 * \param [in] oldName - a current name of the group to rename.
659 * \param [in] newName - a new group name.
660 * \throw If no group named \a oldName exists in \a this mesh.
661 * \throw If a group named \a newName already exists.
663 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
665 std::string oname(oldName);
666 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
667 std::vector<std::string> grps=getGroupsNames();
668 if(it==_groups.end())
670 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
671 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
672 throw INTERP_KERNEL::Exception(oss.str().c_str());
674 std::string nname(newName);
675 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
676 if(it2!=_groups.end())
678 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
679 throw INTERP_KERNEL::Exception(oss.str().c_str());
681 std::vector<std::string> cpy=(*it).second;
683 _groups[newName]=cpy;
687 * Changes an id of a family in \a this mesh.
688 * This method calls changeFamilyIdArr().
689 * \param [in] oldId - a current id of the family.
690 * \param [in] newId - a new family id.
692 void MEDFileMesh::changeFamilyId(int oldId, int newId)
694 changeFamilyIdArr(oldId,newId);
695 std::map<std::string,int> fam2;
696 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
698 if((*it).second==oldId)
699 fam2[(*it).first]=newId;
701 fam2[(*it).first]=(*it).second;
707 * Renames a family in \a this mesh.
708 * \param [in] oldName - a current name of the family to rename.
709 * \param [in] newName - a new family name.
710 * \throw If no family named \a oldName exists in \a this mesh.
711 * \throw If a family named \a newName already exists.
713 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
715 std::string oname(oldName);
716 std::map<std::string, int >::iterator it=_families.find(oname);
717 std::vector<std::string> fams=getFamiliesNames();
718 if(it==_families.end())
720 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
721 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
722 throw INTERP_KERNEL::Exception(oss.str().c_str());
724 std::string nname(newName);
725 std::map<std::string, int >::iterator it2=_families.find(nname);
726 if(it2!=_families.end())
728 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
729 throw INTERP_KERNEL::Exception(oss.str().c_str());
731 int cpy=(*it).second;
733 _families[newName]=cpy;
734 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
736 std::vector<std::string>& v=(*it3).second;
737 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
744 * Checks if \a this and another mesh contains the same families.
745 * \param [in] other - the mesh to compare with \a this one.
746 * \param [in,out] what - an unused parameter.
747 * \return bool - \c true if number of families and their ids are the same in the two
748 * meshes. Families with the id == \c 0 are not considered.
750 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
752 if(_families==other->_families)
754 std::map<std::string,int> fam0;
755 std::map<std::string,int> fam1;
756 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
758 fam0[(*it).first]=(*it).second;
759 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
761 fam1[(*it).first]=(*it).second;
766 * Checks if \a this and another mesh contains the same groups.
767 * \param [in] other - the mesh to compare with \a this one.
768 * \param [in,out] what - a string describing a difference of groups of the two meshes
769 * in case if this method returns \c false.
770 * \return bool - \c true if number of groups and families constituting them are the
771 * same in the two meshes.
773 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
775 if(_groups==other->_groups)
778 std::size_t sz=_groups.size();
779 if(sz!=other->_groups.size())
781 what="Groups differ because not same number !\n";
786 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
787 for(std::size_t i=0;i<sz && ret;i++,it1++)
789 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
790 if(it2!=other->_groups.end())
792 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
793 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
799 what="A group in first mesh exists not in other !\n";
805 std::ostringstream oss; oss << "Groups description differs :\n";
806 oss << "First group description :\n";
807 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
809 oss << " Group \"" << (*it).first << "\" on following families :\n";
810 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
811 oss << " \"" << *it2 << "\n";
813 oss << "Second group description :\n";
814 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
816 oss << " Group \"" << (*it).first << "\" on following families :\n";
817 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
818 oss << " \"" << *it2 << "\n";
826 * Checks if a group with a given name exists in \a this mesh.
827 * \param [in] groupName - the group name.
828 * \return bool - \c true the group \a groupName exists in \a this mesh.
830 bool MEDFileMesh::existsGroup(const std::string& groupName) const
832 std::string grpName(groupName);
833 return _groups.find(grpName)!=_groups.end();
837 * Checks if a family with a given id exists in \a this mesh.
838 * \param [in] famId - the family id.
839 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
841 bool MEDFileMesh::existsFamily(int famId) const
843 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
844 if((*it2).second==famId)
850 * Checks if a family with a given name exists in \a this mesh.
851 * \param [in] familyName - the family name.
852 * \return bool - \c true the family \a familyName exists in \a this mesh.
854 bool MEDFileMesh::existsFamily(const std::string& familyName) const
856 std::string fname(familyName);
857 return _families.find(fname)!=_families.end();
861 * Sets an id of a family.
862 * \param [in] familyName - the family name.
863 * \param [in] id - a new id of the family.
865 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
867 std::string fname(familyName);
871 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
873 std::string fname(familyName);
874 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
877 if((*it).first!=familyName)
879 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
880 throw INTERP_KERNEL::Exception(oss.str().c_str());
887 * Adds a family to \a this mesh.
888 * \param [in] familyName - a name of the family.
889 * \param [in] famId - an id of the family.
890 * \throw If a family with the same name or id already exists in \a this mesh.
892 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
894 std::string fname(familyName);
895 std::map<std::string,int>::const_iterator it=_families.find(fname);
896 if(it==_families.end())
898 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
899 if((*it2).second==famId)
901 std::ostringstream oss;
902 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
903 throw INTERP_KERNEL::Exception(oss.str().c_str());
905 _families[fname]=famId;
909 if((*it).second!=famId)
911 std::ostringstream oss;
912 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
913 throw INTERP_KERNEL::Exception(oss.str().c_str());
919 * Creates a group including all mesh entities of given dimension.
920 * \warning This method does \b not guarantee that the created group includes mesh
921 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
922 * present in family fields of different dimensions. To assure this, call
923 * ensureDifferentFamIdsPerLevel() \b before calling this method.
924 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
926 * \param [in] groupName - a name of the new group.
927 * \throw If a group named \a groupName already exists.
928 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
929 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
931 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
933 std::string grpName(groupName);
934 std::vector<int> levs=getNonEmptyLevelsExt();
935 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
937 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
938 oss << "Available relative ext levels are : ";
939 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
940 throw INTERP_KERNEL::Exception(oss.str().c_str());
942 if(existsGroup(groupName))
944 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
945 oss << "Already existing groups are : ";
946 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
947 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
948 throw INTERP_KERNEL::Exception(oss.str().c_str());
950 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
952 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
953 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
954 std::vector<std::string> familiesOnWholeGroup;
955 for(const int *it=famIds->begin();it!=famIds->end();it++)
958 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
960 _groups[grpName]=familiesOnWholeGroup;
964 * Ensures that given family ids do not present in family fields of dimensions different
965 * than given ones. If a family id is present in the family fields of dimensions different
966 * than the given ones, a new family is created and the whole data is updated accordingly.
967 * \param [in] famIds - a sequence of family ids to check.
968 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
969 * famIds should exclusively belong.
970 * \return bool - \c true if no modification is done in \a this mesh by this method.
972 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
974 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
975 std::vector<int> levs=getNonEmptyLevelsExt();
976 std::set<int> levs2(levs.begin(),levs.end());
977 std::vector<int> levsToTest;
978 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
979 std::set<int> famIds2(famIds.begin(),famIds.end());
982 if(!_families.empty())
983 maxFamId=getMaxFamilyId()+1;
984 std::vector<std::string> allFams=getFamiliesNames();
985 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
987 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
990 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
991 std::vector<int> tmp;
992 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
993 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
996 std::string famName=getFamilyNameGivenId(*it2);
997 std::ostringstream oss; oss << "Family_" << maxFamId;
998 std::string zeName=CreateNameNotIn(oss.str(),allFams);
999 addFamilyOnAllGroupsHaving(famName,zeName);
1000 _families[zeName]=maxFamId;
1001 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1010 * Adds a family to a given group in \a this mesh. If the group with a given name does
1011 * not exist, it is created.
1012 * \param [in] grpName - the name of the group to add the family in.
1013 * \param [in] famName - the name of the family to add to the group named \a grpName.
1014 * \throw If \a grpName or \a famName is an empty string.
1015 * \throw If no family named \a famName is present in \a this mesh.
1017 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1019 std::string grpn(grpName);
1020 std::string famn(famName);
1021 if(grpn.empty() || famn.empty())
1022 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1023 std::vector<std::string> fams=getFamiliesNames();
1024 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1026 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1027 oss << "Create this family or choose an existing one ! Existing fams are : ";
1028 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1029 throw INTERP_KERNEL::Exception(oss.str().c_str());
1031 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1032 if(it==_groups.end())
1034 _groups[grpn].push_back(famn);
1038 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1039 if(it2==(*it).second.end())
1040 (*it).second.push_back(famn);
1045 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1046 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1047 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1049 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1051 std::string famNameCpp(famName);
1052 std::string otherCpp(otherFamName);
1053 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1055 std::vector<std::string>& v=(*it).second;
1056 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1058 v.push_back(otherCpp);
1063 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1065 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1068 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1070 std::string fam(familyNameToChange);
1071 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1073 std::vector<std::string>& fams((*it).second);
1074 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1078 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1084 * Returns a name of the family having a given id or, if no such a family exists, creates
1085 * a new uniquely named family and returns its name.
1086 * \param [in] id - the id of the family whose name is required.
1087 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1088 * \return std::string - the name of the existing or the created family.
1089 * \throw If it is not possible to create a unique family name.
1091 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1093 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1097 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1098 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1099 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1100 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1102 * This method will throws an exception if it is not possible to create a unique family name.
1104 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1106 std::vector<std::string> famAlreadyExisting(families.size());
1108 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1110 if((*it).second!=id)
1112 famAlreadyExisting[ii]=(*it).first;
1121 std::ostringstream oss; oss << "Family_" << id;
1122 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1128 * Sets names and ids of all families in \a this mesh.
1129 * \param [in] info - a map of a family name to a family id.
1131 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1137 * Sets names of all groups and families constituting them in \a this mesh.
1138 * \param [in] info - a map of a group name to a vector of names of families
1139 * constituting the group.
1141 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1147 * Returns an id of the family having a given name.
1148 * \param [in] name - the name of the family of interest.
1149 * \return int - the id of the family of interest.
1150 * \throw If no family with such a \a name exists.
1152 int MEDFileMesh::getFamilyId(const std::string& name) const
1154 std::string oname(name);
1155 std::map<std::string, int>::const_iterator it=_families.find(oname);
1156 std::vector<std::string> fams=getFamiliesNames();
1157 if(it==_families.end())
1159 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1160 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1161 throw INTERP_KERNEL::Exception(oss.str().c_str());
1163 return (*it).second;
1167 * Returns ids of the families having given names.
1168 * \param [in] fams - a sequence of the names of families of interest.
1169 * \return std::vector<int> - a sequence of the ids of families of interest.
1170 * \throw If \a fams contains a name of an inexistent family.
1172 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1174 std::vector<int> ret(fams.size());
1176 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1178 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1179 if(it2==_families.end())
1181 std::vector<std::string> fams2=getFamiliesNames();
1182 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1183 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1184 throw INTERP_KERNEL::Exception(oss.str().c_str());
1186 ret[i]=(*it2).second;
1192 * Returns a maximal abs(id) of families in \a this mesh.
1193 * \return int - the maximal norm of family id.
1194 * \throw If there are no families in \a this mesh.
1196 int MEDFileMesh::getMaxAbsFamilyId() const
1198 if(_families.empty())
1199 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1200 int ret=-std::numeric_limits<int>::max();
1201 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1203 ret=std::max(std::abs((*it).second),ret);
1209 * Returns a maximal id of families in \a this mesh.
1210 * \return int - the maximal family id.
1211 * \throw If there are no families in \a this mesh.
1213 int MEDFileMesh::getMaxFamilyId() const
1215 if(_families.empty())
1216 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1217 int ret=-std::numeric_limits<int>::max();
1218 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1220 ret=std::max((*it).second,ret);
1226 * Returns a minimal id of families in \a this mesh.
1227 * \return int - the minimal family id.
1228 * \throw If there are no families in \a this mesh.
1230 int MEDFileMesh::getMinFamilyId() const
1232 if(_families.empty())
1233 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1234 int ret=std::numeric_limits<int>::max();
1235 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1237 ret=std::min((*it).second,ret);
1243 * Returns a maximal id of families in \a this mesh. Not only named families are
1244 * considered but all family fields as well.
1245 * \return int - the maximal family id.
1247 int MEDFileMesh::getTheMaxAbsFamilyId() const
1249 int m1=-std::numeric_limits<int>::max();
1250 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1251 m1=std::max(std::abs((*it).second),m1);
1252 int m2=getMaxAbsFamilyIdInArrays();
1253 return std::max(m1,m2);
1257 * Returns a maximal id of families in \a this mesh. Not only named families are
1258 * considered but all family fields as well.
1259 * \return int - the maximal family id.
1261 int MEDFileMesh::getTheMaxFamilyId() const
1263 int m1=-std::numeric_limits<int>::max();
1264 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1265 m1=std::max((*it).second,m1);
1266 int m2=getMaxFamilyIdInArrays();
1267 return std::max(m1,m2);
1271 * Returns a minimal id of families in \a this mesh. Not only named families are
1272 * considered but all family fields as well.
1273 * \return int - the minimal family id.
1275 int MEDFileMesh::getTheMinFamilyId() const
1277 int m1=std::numeric_limits<int>::max();
1278 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1279 m1=std::min((*it).second,m1);
1280 int m2=getMinFamilyIdInArrays();
1281 return std::min(m1,m2);
1285 * This method only considers the maps. The contain of family array is ignored here.
1287 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1289 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1291 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1293 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1294 v.insert((*it).second);
1295 ret->alloc((int)v.size(),1);
1296 std::copy(v.begin(),v.end(),ret->getPointer());
1301 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1303 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1305 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1307 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1308 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1309 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1311 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1312 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1313 if((DataArrayInt *) ret)
1314 ret=dv->buildUnion(ret);
1322 * true is returned if no modification has been needed. false if family
1323 * renumbering has been needed.
1325 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1327 std::vector<int> levs=getNonEmptyLevelsExt();
1328 std::set<int> allFamIds;
1329 int maxId=getMaxFamilyId()+1;
1330 std::map<int,std::vector<int> > famIdsToRenum;
1331 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1333 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1336 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1338 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1340 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1342 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1345 if(famIdsToRenum.empty())
1347 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1348 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1350 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1351 int *famIdsToChange=fam->getPointer();
1352 std::map<int,int> ren;
1353 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1355 if(allIds->presenceOfValue(*it3))
1357 std::string famName=getFamilyNameGivenId(*it3);
1358 std::vector<std::string> grps=getGroupsOnFamily(famName);
1361 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1362 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1363 addFamilyOnGrp((*it4),newFam);
1366 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1367 for(const int *id=ids->begin();id!=ids->end();id++)
1368 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1374 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1375 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1376 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1377 * This method will throw an exception if a same family id is detected in different level.
1378 * \warning This policy is the opposite of those in MED file documentation ...
1380 void MEDFileMesh::normalizeFamIdsTrio()
1382 ensureDifferentFamIdsPerLevel();
1383 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1384 std::vector<int> levs=getNonEmptyLevelsExt();
1385 std::set<int> levsS(levs.begin(),levs.end());
1386 std::set<std::string> famsFetched;
1387 std::map<std::string,int> families;
1388 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1391 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1395 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1396 std::map<int,int> ren;
1397 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1399 int nbOfTuples=fam->getNumberOfTuples();
1400 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1401 for(int *w=start;w!=start+nbOfTuples;w++)
1403 for(const int *it=tmp->begin();it!=tmp->end();it++)
1405 if(allIds->presenceOfValue(*it))
1407 std::string famName=getFamilyNameGivenId(*it);
1408 families[famName]=ren[*it];
1409 famsFetched.insert(famName);
1414 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1417 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1421 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1422 std::map<int,int> ren;
1423 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1425 int nbOfTuples=fam->getNumberOfTuples();
1426 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1427 for(int *w=start;w!=start+nbOfTuples;w++)
1429 for(const int *it=tmp->begin();it!=tmp->end();it++)
1431 if(allIds->presenceOfValue(*it))
1433 std::string famName=getFamilyNameGivenId(*it);
1434 families[famName]=ren[*it];
1435 famsFetched.insert(famName);
1440 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1442 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1445 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1446 fam->fillWithZero();
1447 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1448 if(allIds->presenceOfValue(*it3))
1450 std::string famName=getFamilyNameGivenId(*it3);
1451 families[famName]=0;
1452 famsFetched.insert(famName);
1457 std::vector<std::string> allFams=getFamiliesNames();
1458 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1459 std::set<std::string> unFetchedIds;
1460 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1461 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1462 families[*it4]=_families[*it4];
1467 * This method normalizes fam id with the following policy.
1468 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1469 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1470 * This method will throw an exception if a same family id is detected in different level.
1472 void MEDFileMesh::normalizeFamIdsMEDFile()
1474 ensureDifferentFamIdsPerLevel();
1475 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1476 std::vector<int> levs=getNonEmptyLevelsExt();
1477 std::set<int> levsS(levs.begin(),levs.end());
1478 std::set<std::string> famsFetched;
1479 std::map<std::string,int> families;
1481 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1484 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1487 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1488 std::map<int,int> ren;
1489 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1491 int nbOfTuples=fam->getNumberOfTuples();
1492 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1493 for(int *w=start;w!=start+nbOfTuples;w++)
1495 for(const int *it=tmp->begin();it!=tmp->end();it++)
1497 if(allIds->presenceOfValue(*it))
1499 std::string famName=getFamilyNameGivenId(*it);
1500 families[famName]=ren[*it];
1501 famsFetched.insert(famName);
1507 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1509 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1512 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1513 std::map<int,int> ren;
1514 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1516 int nbOfTuples=fam->getNumberOfTuples();
1517 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1518 for(int *w=start;w!=start+nbOfTuples;w++)
1520 for(const int *it=tmp->begin();it!=tmp->end();it++)
1522 if(allIds->presenceOfValue(*it))
1524 std::string famName=getFamilyNameGivenId(*it);
1525 families[famName]=ren[*it];
1526 famsFetched.insert(famName);
1532 std::vector<std::string> allFams=getFamiliesNames();
1533 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1534 std::set<std::string> unFetchedIds;
1535 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1536 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1537 families[*it4]=_families[*it4];
1542 * Returns a name of the family by its id. If there are several families having the given
1543 * id, the name first in lexical order is returned.
1544 * \param [in] id - the id of the family whose name is required.
1545 * \return std::string - the name of the found family.
1546 * \throw If no family with the given \a id exists.
1548 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1550 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1551 if((*it).second==id)
1553 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1554 throw INTERP_KERNEL::Exception(oss.str().c_str());
1558 * Returns a string describing \a this mesh. This description includes the mesh name and
1559 * the mesh description string.
1560 * \return std::string - the mesh information string.
1562 std::string MEDFileMesh::simpleRepr() const
1564 std::ostringstream oss;
1565 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1566 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1567 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1572 * Returns ids of mesh entities contained in a given group of a given dimension.
1573 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1575 * \param [in] grp - the name of the group of interest.
1576 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1577 * returned instead of ids.
1578 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1579 * numbers, if available and required, of mesh entities of the group. The caller
1580 * is to delete this array using decrRef() as it is no more needed.
1581 * \throw If the name of a nonexistent group is specified.
1582 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1584 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1586 std::vector<std::string> tmp(1);
1588 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1594 * Returns ids of mesh entities contained in given groups of a given dimension.
1595 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1597 * \param [in] grps - the names of the groups of interest.
1598 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1599 * returned instead of ids.
1600 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1601 * numbers, if available and required, of mesh entities of the groups. The caller
1602 * is to delete this array using decrRef() as it is no more needed.
1603 * \throw If the name of a nonexistent group is present in \a grps.
1604 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1606 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1608 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1609 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1613 * Returns ids of mesh entities contained in a given family of a given dimension.
1614 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1616 * \param [in] fam - the name of the family of interest.
1617 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1618 * returned instead of ids.
1619 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1620 * numbers, if available and required, of mesh entities of the family. The caller
1621 * is to delete this array using decrRef() as it is no more needed.
1622 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1624 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1626 std::vector<std::string> tmp(1);
1628 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1634 * Returns ids of nodes contained in a given group.
1635 * \param [in] grp - the name of the group of interest.
1636 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1637 * returned instead of ids.
1638 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1639 * numbers, if available and required, of nodes of the group. The caller
1640 * is to delete this array using decrRef() as it is no more needed.
1641 * \throw If the name of a nonexistent group is specified.
1642 * \throw If the family field is missing for nodes.
1644 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1646 std::vector<std::string> tmp(1);
1648 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1654 * Returns ids of nodes contained in given groups.
1655 * \param [in] grps - the names of the groups of interest.
1656 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1657 * returned instead of ids.
1658 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1659 * numbers, if available and required, of nodes of the groups. The caller
1660 * is to delete this array using decrRef() as it is no more needed.
1661 * \throw If the name of a nonexistent group is present in \a grps.
1662 * \throw If the family field is missing for nodes.
1664 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1666 return getGroupsArr(1,grps,renum);
1670 * Returns ids of nodes contained in a given group.
1671 * \param [in] grp - the name of the group of interest.
1672 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1673 * returned instead of ids.
1674 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1675 * numbers, if available and required, of nodes of the group. The caller
1676 * is to delete this array using decrRef() as it is no more needed.
1677 * \throw If the name of a nonexistent group is specified.
1678 * \throw If the family field is missing for nodes.
1680 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1682 std::vector<std::string> tmp(1);
1684 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1690 * Returns ids of nodes contained in given families.
1691 * \param [in] fams - the names of the families of interest.
1692 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1693 * returned instead of ids.
1694 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1695 * numbers, if available and required, of nodes of the families. The caller
1696 * is to delete this array using decrRef() as it is no more needed.
1697 * \throw If the family field is missing for nodes.
1699 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1701 return getFamiliesArr(1,fams,renum);
1705 * Adds groups of given dimension and creates corresponding families and family fields
1706 * given ids of mesh entities of each group.
1707 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1708 * \param [in] grps - a sequence of arrays of ids each describing a group.
1709 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1711 * \throw If names of some groups in \a grps are equal.
1712 * \throw If \a grps includes a group with an empty name.
1713 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1714 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1716 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1720 std::set<std::string> grpsName;
1721 std::vector<std::string> grpsName2(grps.size());
1724 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1726 grpsName.insert((*it)->getName());
1727 grpsName2[i]=(*it)->getName();
1729 if(grpsName.size()!=grps.size())
1730 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1731 if(grpsName.find(std::string(""))!=grpsName.end())
1732 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1733 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1734 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1735 std::vector< std::vector<int> > fidsOfGroups;
1738 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1742 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1743 for(unsigned int ii=0;ii<grps.size();ii++)
1745 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1746 grps2[ii]->setName(grps[ii]->getName());
1748 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1749 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1752 if(!_families.empty())
1753 offset=getMaxAbsFamilyId()+1;
1754 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1755 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1756 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1757 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1761 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1762 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1763 * For the moment, the two last input parameters are not taken into account.
1765 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1767 std::map<int,std::string> famInv;
1768 for(const int *it=famIds->begin();it!=famIds->end();it++)
1770 std::ostringstream oss;
1771 oss << "Family_" << (*it);
1772 _families[oss.str()]=(*it);
1773 famInv[*it]=oss.str();
1776 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1778 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1780 _groups[grpNames[i]].push_back(famInv[*it2]);
1785 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1787 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1788 return mLev->getDistributionOfTypes();
1791 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1793 famArr->applyLin(offset>0?1:-1,offset,0);
1794 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1797 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1798 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1803 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1804 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1805 * If this method fails to find such a name it will throw an exception.
1807 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
1810 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
1813 std::size_t len=nameTry.length();
1814 for(std::size_t ii=1;ii<len;ii++)
1816 std::string tmp=nameTry.substr(ii,len-ii);
1817 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
1823 for(std::size_t i=1;i<30;i++)
1825 std::string tmp1(nameTry.at(0),i);
1827 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
1833 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
1835 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
1837 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
1840 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
1842 std::size_t nbOfChunks=code.size()/3;
1843 if(code.size()%3!=0)
1844 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
1846 for(std::size_t i=0;i<nbOfChunks;i++)
1855 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
1856 * If _name attribute is empty the name of 'm' if taken as _name attribute.
1857 * If _name is not empty and that 'm' has the same name nothing is done.
1858 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
1860 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
1863 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
1868 std::string name(m->getName());
1873 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
1874 oss << name << "' ! Names must match !";
1875 throw INTERP_KERNEL::Exception(oss.str().c_str());
1879 if(_desc_name.empty())
1880 _desc_name=m->getDescription();
1883 std::string name(m->getDescription());
1886 if(_desc_name!=name)
1888 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
1889 oss << name << "' ! Names must match !";
1890 throw INTERP_KERNEL::Exception(oss.str().c_str());
1896 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
1898 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
1899 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1901 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
1902 oss << " - Groups lying on this family : ";
1903 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
1904 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
1905 oss << std::endl << std::endl;
1910 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1911 * file. The mesh to load is specified by its name and numbers of a time step and an
1913 * \param [in] fileName - the name of MED file to read.
1914 * \param [in] mName - the name of the mesh to read.
1915 * \param [in] dt - the number of a time step.
1916 * \param [in] it - the number of an iteration.
1917 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1918 * mesh using decrRef() as it is no more needed.
1919 * \throw If the file is not readable.
1920 * \throw If there is no mesh with given attributes in the file.
1921 * \throw If the mesh in the file is not an unstructured one.
1923 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
1925 MEDFileUtilities::CheckFileForRead(fileName);
1926 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1927 return new MEDFileUMesh(fid,mName,dt,it,mrs);
1931 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
1932 * file. The first mesh in the file is loaded.
1933 * \param [in] fileName - the name of MED file to read.
1934 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1935 * mesh using decrRef() as it is no more needed.
1936 * \throw If the file is not readable.
1937 * \throw If there is no meshes in the file.
1938 * \throw If the mesh in the file is not an unstructured one.
1940 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
1942 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
1945 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
1946 throw INTERP_KERNEL::Exception(oss.str().c_str());
1948 MEDFileUtilities::CheckFileForRead(fileName);
1949 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
1951 ParaMEDMEM::MEDCouplingMeshType meshType;
1953 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
1954 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
1958 * Returns an empty instance of MEDFileUMesh.
1959 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
1960 * mesh using decrRef() as it is no more needed.
1962 MEDFileUMesh *MEDFileUMesh::New()
1964 return new MEDFileUMesh;
1967 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
1969 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
1970 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
1974 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildren() const
1976 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
1977 if((const DataArrayDouble*)_coords)
1978 ret.push_back((const DataArrayDouble*)_coords);
1979 if((const DataArrayInt *)_fam_coords)
1980 ret.push_back((const DataArrayInt *)_fam_coords);
1981 if((const DataArrayInt *)_num_coords)
1982 ret.push_back((const DataArrayInt *)_num_coords);
1983 if((const DataArrayInt *)_rev_num_coords)
1984 ret.push_back((const DataArrayInt *)_rev_num_coords);
1985 if((const DataArrayAsciiChar *)_name_coords)
1986 ret.push_back((const DataArrayAsciiChar *)_name_coords);
1987 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
1988 if((const MEDFileUMeshSplitL1*) *it)
1989 ret.push_back((const MEDFileUMeshSplitL1*) *it);
1993 MEDFileMesh *MEDFileUMesh::shallowCpy() const
1995 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
1999 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2001 return new MEDFileUMesh;
2004 MEDFileMesh *MEDFileUMesh::deepCpy() const
2006 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2007 if((const DataArrayDouble*)_coords)
2008 ret->_coords=_coords->deepCpy();
2009 if((const DataArrayInt*)_fam_coords)
2010 ret->_fam_coords=_fam_coords->deepCpy();
2011 if((const DataArrayInt*)_num_coords)
2012 ret->_num_coords=_num_coords->deepCpy();
2013 if((const DataArrayInt*)_rev_num_coords)
2014 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2015 if((const DataArrayAsciiChar*)_name_coords)
2016 ret->_name_coords=_name_coords->deepCpy();
2018 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2020 if((const MEDFileUMeshSplitL1 *)(*it))
2021 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2027 * Checks if \a this and another mesh are equal.
2028 * \param [in] other - the mesh to compare with.
2029 * \param [in] eps - a precision used to compare real values.
2030 * \param [in,out] what - the string returning description of unequal data.
2031 * \return bool - \c true if the meshes are equal, \c false, else.
2033 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2035 if(!MEDFileMesh::isEqual(other,eps,what))
2037 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2040 what="Mesh types differ ! This is unstructured and other is NOT !";
2043 clearNonDiscrAttributes();
2044 otherC->clearNonDiscrAttributes();
2045 const DataArrayDouble *coo1=_coords;
2046 const DataArrayDouble *coo2=otherC->_coords;
2047 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2049 what="Mismatch of coordinates ! One is defined and not other !";
2054 bool ret=coo1->isEqual(*coo2,eps);
2057 what="Coords differ !";
2061 const DataArrayInt *famc1=_fam_coords;
2062 const DataArrayInt *famc2=otherC->_fam_coords;
2063 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2065 what="Mismatch of families arr on nodes ! One is defined and not other !";
2070 bool ret=famc1->isEqual(*famc2);
2073 what="Families arr on node differ !";
2077 const DataArrayInt *numc1=_num_coords;
2078 const DataArrayInt *numc2=otherC->_num_coords;
2079 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2081 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2086 bool ret=numc1->isEqual(*numc2);
2089 what="Numbering arr on node differ !";
2093 const DataArrayAsciiChar *namec1=_name_coords;
2094 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2095 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2097 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2102 bool ret=namec1->isEqual(*namec2);
2105 what="Names arr on node differ !";
2109 if(_ms.size()!=otherC->_ms.size())
2111 what="Number of levels differs !";
2114 std::size_t sz=_ms.size();
2115 for(std::size_t i=0;i<sz;i++)
2117 const MEDFileUMeshSplitL1 *s1=_ms[i];
2118 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2119 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2121 what="Mismatch of presence of sub levels !";
2126 bool ret=s1->isEqual(s2,eps,what);
2135 * Clears redundant attributes of incorporated data arrays.
2137 void MEDFileUMesh::clearNonDiscrAttributes() const
2139 MEDFileMesh::clearNonDiscrAttributes();
2140 const DataArrayDouble *coo1=_coords;
2142 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2143 const DataArrayInt *famc1=_fam_coords;
2145 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2146 const DataArrayInt *numc1=_num_coords;
2148 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2149 const DataArrayAsciiChar *namc1=_name_coords;
2151 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2152 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2154 const MEDFileUMeshSplitL1 *tmp=(*it);
2156 tmp->clearNonDiscrAttributes();
2160 MEDFileUMesh::MEDFileUMesh()
2164 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2167 loadUMeshFromFile(fid,mName,dt,it,mrs);
2169 catch(INTERP_KERNEL::Exception& e)
2174 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2176 MEDFileUMeshL2 loaderl2;
2177 ParaMEDMEM::MEDCouplingMeshType meshType;
2180 int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
2181 if(meshType!=UNSTRUCTURED)
2183 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2184 throw INTERP_KERNEL::Exception(oss.str().c_str());
2186 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2187 int lev=loaderl2.getNumberOfLevels();
2189 for(int i=0;i<lev;i++)
2191 if(!loaderl2.emptyLev(i))
2192 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2196 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2198 setName(loaderl2.getName());
2199 setDescription(loaderl2.getDescription());
2200 setUnivName(loaderl2.getUnivName());
2201 setIteration(loaderl2.getIteration());
2202 setOrder(loaderl2.getOrder());
2203 setTimeValue(loaderl2.getTime());
2204 setTimeUnit(loaderl2.getTimeUnit());
2205 _coords=loaderl2.getCoords();
2206 if(!mrs || mrs->isNodeFamilyFieldReading())
2207 _fam_coords=loaderl2.getCoordsFamily();
2208 if(!mrs || mrs->isNodeNumFieldReading())
2209 _num_coords=loaderl2.getCoordsNum();
2210 if(!mrs || mrs->isNodeNameFieldReading())
2211 _name_coords=loaderl2.getCoordsName();
2215 MEDFileUMesh::~MEDFileUMesh()
2219 void MEDFileUMesh::writeLL(med_idt fid) const
2221 const DataArrayDouble *coo=_coords;
2222 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2223 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2224 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2225 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2226 int spaceDim=coo?coo->getNumberOfComponents():0;
2227 int mdim=getMeshDimension();
2228 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2229 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2230 for(int i=0;i<spaceDim;i++)
2232 std::string info=coo->getInfoOnComponent(i);
2234 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2235 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
2236 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
2238 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2239 MEDmeshUniversalNameWr(fid,maa);
2240 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2241 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2242 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2243 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2244 (*it)->write(fid,meshName,mdim);
2245 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2249 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2250 * \return std::vector<int> - a sequence of the relative dimensions.
2252 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2254 std::vector<int> ret;
2256 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2257 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2264 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2265 * \return std::vector<int> - a sequence of the relative dimensions.
2267 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2269 std::vector<int> ret0=getNonEmptyLevels();
2270 if((const DataArrayDouble *) _coords)
2272 std::vector<int> ret(ret0.size()+1);
2274 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2280 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2282 std::vector<int> ret;
2283 const DataArrayInt *famCoo(_fam_coords);
2287 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2289 const MEDFileUMeshSplitL1 *cur(*it);
2291 if(cur->getFamilyField())
2297 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2299 std::vector<int> ret;
2300 const DataArrayInt *numCoo(_num_coords);
2304 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2306 const MEDFileUMeshSplitL1 *cur(*it);
2308 if(cur->getNumberField())
2314 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2316 std::vector<int> ret;
2317 const DataArrayAsciiChar *nameCoo(_name_coords);
2321 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2323 const MEDFileUMeshSplitL1 *cur(*it);
2325 if(cur->getNameField())
2332 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2333 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2334 * \param [in] grp - the name of the group of interest.
2335 * \return std::vector<int> - a sequence of the relative dimensions.
2337 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2339 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2340 return getFamsNonEmptyLevels(fams);
2344 * Returns all relative mesh levels (including nodes) where a given group is defined.
2345 * \param [in] grp - the name of the group of interest.
2346 * \return std::vector<int> - a sequence of the relative dimensions.
2348 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2350 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2351 return getFamsNonEmptyLevelsExt(fams);
2355 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2356 * To include nodes, call getFamNonEmptyLevelsExt() method.
2357 * \param [in] fam - the name of the family of interest.
2358 * \return std::vector<int> - a sequence of the relative dimensions.
2360 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2362 std::vector<std::string> fams(1,std::string(fam));
2363 return getFamsNonEmptyLevels(fams);
2367 * Returns all relative mesh levels (including nodes) where a given family is defined.
2368 * \param [in] fam - the name of the family of interest.
2369 * \return std::vector<int> - a sequence of the relative dimensions.
2371 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2373 std::vector<std::string> fams(1,std::string(fam));
2374 return getFamsNonEmptyLevelsExt(fams);
2378 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2379 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2380 * \param [in] grps - a sequence of names of the groups of interest.
2381 * \return std::vector<int> - a sequence of the relative dimensions.
2383 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2385 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2386 return getFamsNonEmptyLevels(fams);
2390 * Returns all relative mesh levels (including nodes) where given groups are defined.
2391 * \param [in] grps - a sequence of names of the groups of interest.
2392 * \return std::vector<int> - a sequence of the relative dimensions.
2394 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2396 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2397 return getFamsNonEmptyLevelsExt(fams);
2401 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2402 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2403 * \param [in] fams - the name of the family of interest.
2404 * \return std::vector<int> - a sequence of the relative dimensions.
2406 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2408 std::vector<int> ret;
2409 std::vector<int> levs=getNonEmptyLevels();
2410 std::vector<int> famIds=getFamiliesIds(fams);
2411 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2412 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2418 * Returns all relative mesh levels (including nodes) where given families are defined.
2419 * \param [in] fams - the names of the families of interest.
2420 * \return std::vector<int> - a sequence of the relative dimensions.
2422 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2424 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2425 const DataArrayInt *famCoords=_fam_coords;
2428 std::vector<int> famIds=getFamiliesIds(fams);
2429 if(famCoords->presenceOfValue(famIds))
2431 std::vector<int> ret(ret0.size()+1);
2433 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2441 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2442 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2443 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2446 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2448 std::vector<std::string> ret;
2449 std::vector<std::string> allGrps=getGroupsNames();
2450 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2452 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2453 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2459 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2461 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2462 if((const DataArrayInt *)_fam_coords)
2464 int val=_fam_coords->getMaxValue(tmp);
2465 ret=std::max(ret,std::abs(val));
2467 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2469 if((const MEDFileUMeshSplitL1 *)(*it))
2471 const DataArrayInt *da=(*it)->getFamilyField();
2474 int val=da->getMaxValue(tmp);
2475 ret=std::max(ret,std::abs(val));
2482 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2484 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2485 if((const DataArrayInt *)_fam_coords)
2487 int val=_fam_coords->getMaxValue(tmp);
2488 ret=std::max(ret,val);
2490 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2492 if((const MEDFileUMeshSplitL1 *)(*it))
2494 const DataArrayInt *da=(*it)->getFamilyField();
2497 int val=da->getMaxValue(tmp);
2498 ret=std::max(ret,val);
2505 int MEDFileUMesh::getMinFamilyIdInArrays() const
2507 int ret=std::numeric_limits<int>::max(),tmp=-1;
2508 if((const DataArrayInt *)_fam_coords)
2510 int val=_fam_coords->getMinValue(tmp);
2511 ret=std::min(ret,val);
2513 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2515 if((const MEDFileUMeshSplitL1 *)(*it))
2517 const DataArrayInt *da=(*it)->getFamilyField();
2520 int val=da->getMinValue(tmp);
2521 ret=std::min(ret,val);
2529 * Returns the dimension on cells in \a this mesh.
2530 * \return int - the mesh dimension.
2531 * \throw If there are no cells in this mesh.
2533 int MEDFileUMesh::getMeshDimension() const
2536 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2537 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2538 return (*it)->getMeshDimension()+lev;
2539 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2543 * Returns the space dimension of \a this mesh that is equal to number of components in
2544 * the node coordinates array.
2545 * \return int - the space dimension of \a this mesh.
2546 * \throw If the node coordinates array is not available.
2548 int MEDFileUMesh::getSpaceDimension() const
2550 const DataArrayDouble *coo=_coords;
2552 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2553 return coo->getNumberOfComponents();
2557 * Returns a string describing \a this mesh.
2558 * \return std::string - the mesh information string.
2560 std::string MEDFileUMesh::simpleRepr() const
2562 std::ostringstream oss;
2563 oss << MEDFileMesh::simpleRepr();
2564 const DataArrayDouble *coo=_coords;
2565 oss << "- The dimension of the space is ";
2566 static const char MSG1[]= "*** NO COORDS SET ***";
2567 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2569 oss << _coords->getNumberOfComponents() << std::endl;
2571 oss << MSG1 << std::endl;
2572 oss << "- Type of the mesh : UNSTRUCTURED\n";
2573 oss << "- Number of nodes : ";
2575 oss << _coords->getNumberOfTuples() << std::endl;
2577 oss << MSG1 << std::endl;
2578 std::size_t nbOfLev=_ms.size();
2579 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2580 for(std::size_t i=0;i<nbOfLev;i++)
2582 const MEDFileUMeshSplitL1 *lev=_ms[i];
2583 oss << " - Level #" << -((int) i) << " has dimension : ";
2586 oss << lev->getMeshDimension() << std::endl;
2587 lev->simpleRepr(oss);
2590 oss << MSG2 << std::endl;
2592 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2595 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2596 oss << "- Names of coordinates :" << std::endl;
2597 std::vector<std::string> vars=coo->getVarsOnComponent();
2598 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2599 oss << std::endl << "- Units of coordinates : " << std::endl;
2600 std::vector<std::string> units=coo->getUnitsOnComponent();
2601 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2603 oss << std::endl << std::endl;
2609 * Returns a full textual description of \a this mesh.
2610 * \return std::string - the string holding the mesh description.
2612 std::string MEDFileUMesh::advancedRepr() const
2614 return simpleRepr();
2618 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2619 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2620 * \return int - the number of entities.
2621 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2623 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2625 if(meshDimRelToMaxExt==1)
2627 if(!((const DataArrayDouble *)_coords))
2628 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2629 return _coords->getNumberOfTuples();
2631 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2635 * Returns the family field for mesh entities of a given dimension.
2636 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2637 * \return const DataArrayInt * - the family field. It is an array of ids of families
2638 * each mesh entity belongs to. It can be \c NULL.
2640 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2642 if(meshDimRelToMaxExt==1)
2644 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2645 return l1->getFamilyField();
2649 * Returns the optional numbers of mesh entities of a given dimension.
2650 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2651 * \return const DataArrayInt * - the array of the entity numbers.
2652 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2654 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2656 if(meshDimRelToMaxExt==1)
2658 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2659 return l1->getNumberField();
2662 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2664 if(meshDimRelToMaxExt==1)
2665 return _name_coords;
2666 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2667 return l1->getNameField();
2670 int MEDFileUMesh::getNumberOfNodes() const
2672 const DataArrayDouble *coo=_coords;
2674 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2675 return coo->getNumberOfTuples();
2678 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2680 std::size_t sz(st.getNumberOfItems());
2681 for(std::size_t i=0;i<sz;i++)
2683 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2684 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
2685 if(st[i].getPflName().empty())
2686 m->computeNodeIdsAlg(nodesFetched);
2689 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
2690 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
2691 m2->computeNodeIdsAlg(nodesFetched);
2697 * Returns the optional numbers of mesh entities of a given dimension transformed using
2698 * DataArrayInt::invertArrayN2O2O2N().
2699 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2700 * \return const DataArrayInt * - the array of the entity numbers transformed using
2701 * DataArrayInt::invertArrayN2O2O2N().
2702 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2704 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
2706 if(meshDimRelToMaxExt==1)
2708 if(!((const DataArrayInt *)_num_coords))
2709 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
2710 return _rev_num_coords;
2712 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2713 return l1->getRevNumberField();
2717 * Returns a pointer to the node coordinates array of \a this mesh \b without
2718 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
2720 DataArrayDouble *MEDFileUMesh::getCoords() const
2722 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
2723 if((DataArrayDouble *)tmp)
2731 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2732 * group of \a this mesh. Only mesh entities of a given dimension are included in the
2734 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2735 * \param [in] grp - the name of the group whose mesh entities are included in the
2737 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2738 * according to the optional numbers of entities, if available.
2739 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2740 * delete this mesh using decrRef() as it is no more needed.
2741 * \throw If the name of a nonexistent group is specified.
2742 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2744 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
2746 synchronizeTinyInfoOnLeaves();
2747 std::vector<std::string> tmp(1);
2749 return getGroups(meshDimRelToMaxExt,tmp,renum);
2753 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2754 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
2756 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2757 * \param [in] grps - a sequence of group names whose mesh entities are included in the
2759 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2760 * according to the optional numbers of entities, if available.
2761 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2762 * delete this mesh using decrRef() as it is no more needed.
2763 * \throw If a name of a nonexistent group is present in \a grps.
2764 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2766 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
2768 synchronizeTinyInfoOnLeaves();
2769 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
2770 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
2771 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
2772 zeRet->setName(grps[0]);
2773 return zeRet.retn();
2777 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
2778 * family of \a this mesh. Only mesh entities of a given dimension are included in the
2780 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2781 * \param [in] fam - the name of the family whose mesh entities are included in the
2783 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2784 * according to the optional numbers of entities, if available.
2785 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2786 * delete this mesh using decrRef() as it is no more needed.
2787 * \throw If a name of a nonexistent family is present in \a grps.
2788 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2790 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
2792 synchronizeTinyInfoOnLeaves();
2793 std::vector<std::string> tmp(1);
2795 return getFamilies(meshDimRelToMaxExt,tmp,renum);
2799 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
2800 * families of \a this mesh. Only mesh entities of a given dimension are included in the
2802 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
2803 * \param [in] fams - a sequence of family names whose mesh entities are included in the
2805 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
2806 * according to the optional numbers of entities, if available.
2807 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
2808 * delete this mesh using decrRef() as it is no more needed.
2809 * \throw If a name of a nonexistent family is present in \a fams.
2810 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2812 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2814 synchronizeTinyInfoOnLeaves();
2815 if(meshDimRelToMaxExt==1)
2817 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
2818 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
2819 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
2823 std::vector<int> famIds=getFamiliesIds(fams);
2824 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2825 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
2827 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
2829 zeRet=l1->getFamilyPart(0,0,renum);
2830 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
2831 zeRet->setName(fams[0]);
2832 return zeRet.retn();
2836 * Returns ids of mesh entities contained in given families of a given dimension.
2837 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
2839 * \param [in] fams - the names of the families of interest.
2840 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
2841 * returned instead of ids.
2842 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
2843 * numbers, if available and required, of mesh entities of the families. The caller
2844 * is to delete this array using decrRef() as it is no more needed.
2845 * \throw If the family field is missing for \a meshDimRelToMaxExt.
2847 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
2849 std::vector<int> famIds=getFamiliesIds(fams);
2850 if(meshDimRelToMaxExt==1)
2852 if((const DataArrayInt *)_fam_coords)
2854 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
2856 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
2858 da=_fam_coords->getIdsEqualList(0,0);
2860 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
2865 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
2867 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2869 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
2871 return l1->getFamilyPartArr(0,0,renum);
2875 * Returns a MEDCouplingUMesh of a given relative dimension.
2876 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2877 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2878 * To build a valid MEDCouplingUMesh from the returned one in this case,
2879 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2880 * \param [in] meshDimRelToMax - the relative dimension of interest.
2881 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2882 * optional numbers of mesh entities.
2883 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2884 * delete using decrRef() as it is no more needed.
2885 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2886 * \sa getGenMeshAtLevel()
2888 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
2890 synchronizeTinyInfoOnLeaves();
2891 if(meshDimRelToMaxExt==1)
2895 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
2896 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
2897 umesh->setCoords(cc);
2898 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
2899 umesh->setName(getName());
2903 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2904 return l1->getWholeMesh(renum);
2908 * Returns a MEDCouplingUMesh of a given relative dimension.
2909 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
2910 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
2911 * To build a valid MEDCouplingUMesh from the returned one in this case,
2912 * call MEDCouplingUMesh::Build0DMeshFromCoords().
2913 * \param [in] meshDimRelToMax - the relative dimension of interest.
2914 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2915 * optional numbers of mesh entities.
2916 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
2917 * delete using decrRef() as it is no more needed.
2918 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
2919 * \sa getMeshAtLevel()
2921 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
2923 return getMeshAtLevel(meshDimRelToMax,renum);
2926 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
2928 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
2929 return l1->getDistributionOfTypes();
2933 * Returns a MEDCouplingUMesh of a relative dimension == 0.
2934 * \param [in] renum - if \c true, the returned mesh is permuted according to the
2935 * optional numbers of mesh entities.
2936 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
2937 * delete using decrRef() as it is no more needed.
2938 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
2940 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
2942 return getMeshAtLevel(0,renum);
2946 * Returns a MEDCouplingUMesh of a relative dimension == -1.
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 == -1 in \a this mesh.
2953 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
2955 return getMeshAtLevel(-1,renum);
2959 * Returns a MEDCouplingUMesh of a relative dimension == -2.
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 == -2 in \a this mesh.
2966 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
2968 return getMeshAtLevel(-2,renum);
2972 * Returns a MEDCouplingUMesh of a relative dimension == -3.
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 == -3 in \a this mesh.
2979 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
2981 return getMeshAtLevel(-3,renum);
2985 * This method is for advanced users. There is two storing strategy of mesh in \a this.
2986 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
2987 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
2988 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
2990 void MEDFileUMesh::forceComputationOfParts() const
2992 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2994 const MEDFileUMeshSplitL1 *elt(*it);
2996 elt->forceComputationOfParts();
3001 * This method returns a vector of mesh parts containing each exactly one geometric type.
3002 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3003 * This method is only for memory aware users.
3004 * The returned pointers are **NOT** new object pointer. No need to mange them.
3006 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3008 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3009 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3013 * This method returns the part of \a this having the geometric type \a gt.
3014 * If such part is not existing an exception will be thrown.
3015 * The returned pointer is **NOT** new object pointer. No need to mange it.
3017 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3019 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3020 int lev=(int)cm.getDimension()-getMeshDimension();
3021 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3022 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3026 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3027 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3029 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3031 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3032 return sp->getGeoTypes();
3036 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3037 * \param [in] gt - the geometric type for which the family field is asked.
3038 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3039 * delete using decrRef() as it is no more needed.
3040 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3042 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3044 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3045 int lev=(int)cm.getDimension()-getMeshDimension();
3046 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3047 return sp->extractFamilyFieldOnGeoType(gt);
3051 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3052 * \param [in] gt - the geometric type for which the number field is asked.
3053 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3054 * delete using decrRef() as it is no more needed.
3055 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3057 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3059 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3060 int lev=(int)cm.getDimension()-getMeshDimension();
3061 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3062 return sp->extractNumberFieldOnGeoType(gt);
3065 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3067 if(meshDimRelToMaxExt==1)
3068 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3069 if(meshDimRelToMaxExt>1)
3070 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3071 int tracucedRk=-meshDimRelToMaxExt;
3072 if(tracucedRk>=(int)_ms.size())
3073 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3074 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3075 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3076 return _ms[tracucedRk];
3079 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3081 if(meshDimRelToMaxExt==1)
3082 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3083 if(meshDimRelToMaxExt>1)
3084 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3085 int tracucedRk=-meshDimRelToMaxExt;
3086 if(tracucedRk>=(int)_ms.size())
3087 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3088 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3089 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3090 return _ms[tracucedRk];
3093 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3095 if(-meshDimRelToMax>=(int)_ms.size())
3096 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3098 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3100 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3102 int ref=(*it)->getMeshDimension();
3103 if(ref+i!=meshDim-meshDimRelToMax)
3104 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3110 * Sets the node coordinates array of \a this mesh.
3111 * \param [in] coords - the new node coordinates array.
3112 * \throw If \a coords == \c NULL.
3114 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3117 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3118 coords->checkAllocated();
3119 int nbOfTuples=coords->getNumberOfTuples();
3122 _fam_coords=DataArrayInt::New();
3123 _fam_coords->alloc(nbOfTuples,1);
3124 _fam_coords->fillWithZero();
3125 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3126 if((MEDFileUMeshSplitL1 *)(*it))
3127 (*it)->setCoords(coords);
3131 * Removes all groups of a given dimension in \a this mesh.
3132 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3133 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3135 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3137 if(meshDimRelToMaxExt==1)
3139 if((DataArrayInt *)_fam_coords)
3140 _fam_coords->fillWithZero();
3143 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3144 l1->eraseFamilyField();
3149 * Removes all families with ids not present in the family fields of \a this mesh.
3151 void MEDFileUMesh::optimizeFamilies()
3153 std::vector<int> levs=getNonEmptyLevelsExt();
3154 std::set<int> allFamsIds;
3155 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3157 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3158 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3160 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3163 std::set<std::string> famNamesToKill;
3164 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3166 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3167 famNamesToKill.insert((*it).first);
3169 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3170 _families.erase(*it);
3171 std::vector<std::string> grpNamesToKill;
3172 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3174 std::vector<std::string> tmp;
3175 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3177 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3178 tmp.push_back(*it2);
3183 tmp.push_back((*it).first);
3185 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3189 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3191 std::vector<int> levs=getNonEmptyLevels();
3192 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3193 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3194 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3195 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3196 int nbNodes=m0->getNumberOfNodes();
3197 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3198 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3199 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3200 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3201 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3202 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3203 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3204 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3205 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3206 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3207 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3208 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3209 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3210 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3211 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3212 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3213 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3214 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3215 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3216 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3217 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3218 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3219 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3220 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3221 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3222 m0->setCoords(tmp0->getCoords());
3223 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3224 m1->setCoords(m0->getCoords());
3225 _coords=m0->getCoords(); _coords->incrRef();
3226 // duplication of cells in group 'grpNameM1' on level -1
3227 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3228 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3229 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3230 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3231 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3233 newm1->setName(getName());
3234 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3236 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3237 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3238 newFam->alloc(newm1->getNumberOfCells(),1);
3239 int idd=getMaxFamilyId()+1;
3240 int globStart=0,start=0,end,globEnd;
3241 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3242 for(int i=0;i<nbOfChunks;i++)
3244 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3245 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3247 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3248 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3249 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3254 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3258 newm1->setCoords(getCoords());
3259 setMeshAtLevel(-1,newm1);
3260 setFamilyFieldArr(-1,newFam);
3261 std::string grpName2(grpNameM1); grpName2+="_dup";
3262 addFamily(grpName2,idd);
3263 addFamilyOnGrp(grpName2,grpName2);
3268 int newNbOfNodes=getCoords()->getNumberOfTuples();
3269 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3270 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3271 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3274 nodesDuplicated=nodeIdsToDuplicate.retn();
3275 cellsModified=cellsToModifyConn0.retn();
3276 cellsNotModified=cellsToModifyConn1.retn();
3280 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3281 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3282 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3284 * \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.
3285 * 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.
3287 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3289 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3290 std::vector<int> levs=getNonEmptyLevels();
3292 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3293 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3296 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3298 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3299 std::vector<int> code1=m->getDistributionOfTypes();
3300 end=PutInThirdComponentOfCodeOffset(code1,start);
3301 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3302 bool hasChanged=m->unPolyze();
3303 DataArrayInt *fake=0;
3304 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3305 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3307 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3310 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3311 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3313 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3314 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3315 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3316 setMeshAtLevel(*it,m);
3317 std::vector<int> code2=m->getDistributionOfTypes();
3318 end=PutInThirdComponentOfCodeOffset(code2,start);
3319 newCode.insert(newCode.end(),code2.begin(),code2.end());
3321 if(o2nCellsPart2->isIdentity())
3325 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3326 setFamilyFieldArr(*it,newFamField);
3330 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3331 setRenumFieldArr(*it,newNumField);
3336 newCode.insert(newCode.end(),code1.begin(),code1.end());
3342 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3343 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3344 o2nRenumCell=o2nRenumCellRet.retn();
3349 struct MEDLoaderAccVisit1
3351 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3352 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3353 int _new_nb_of_nodes;
3357 * 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.
3358 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3359 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3360 * -1 values in returned array means that the corresponding old node is no more used.
3362 * \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
3363 * is modified in \a this.
3364 * \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
3367 DataArrayInt *MEDFileUMesh::zipCoords()
3369 const DataArrayDouble *coo=getCoords();
3371 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3372 int nbOfNodes=coo->getNumberOfTuples();
3373 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3374 std::vector<int> neLevs=getNonEmptyLevels();
3375 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3377 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*lev);
3378 m->computeNodeIdsAlg(nodeIdsInUse);
3380 int nbrOfNodesInUse=(int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true);
3381 if(nbrOfNodesInUse==nbOfNodes)
3383 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodes,1);
3384 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3385 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2OBis(nbrOfNodesInUse);
3386 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->selectByTupleIdSafe(ret2->begin(),ret2->end());
3387 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3388 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3389 if((const DataArrayInt *)_fam_coords)
3390 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3391 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3392 if((const DataArrayInt *)_num_coords)
3393 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3394 if((const DataArrayAsciiChar *)_name_coords)
3395 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3396 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3397 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3399 if((MEDFileUMeshSplitL1*)*it)
3400 (*it)->renumberNodesInConn(ret->begin());
3406 * Adds a group of nodes to \a this mesh.
3407 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3408 * The ids should be sorted and different each other (MED file norm).
3409 * \throw If the node coordinates array is not set.
3410 * \throw If \a ids == \c NULL.
3411 * \throw If \a ids->getName() == "".
3412 * \throw If \a ids does not respect the MED file norm.
3413 * \throw If a group with name \a ids->getName() already exists.
3415 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
3417 const DataArrayDouble *coords=_coords;
3419 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
3420 int nbOfNodes=coords->getNumberOfTuples();
3421 if(!((DataArrayInt *)_fam_coords))
3422 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
3424 addGroupUnderground(true,ids,_fam_coords);
3428 * Adds a group of nodes/cells/faces/edges to \a this mesh.
3429 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
3430 * The ids should be sorted and different each other (MED file norm).
3431 * \throw If the node coordinates array is not set.
3432 * \throw If \a ids == \c NULL.
3433 * \throw If \a ids->getName() == "".
3434 * \throw If \a ids does not respect the MED file norm.
3435 * \throw If a group with name \a ids->getName() already exists.
3437 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
3439 std::vector<int> levs=getNonEmptyLevelsExt();
3440 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
3442 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
3443 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
3445 if(meshDimRelToMaxExt==1)
3446 { addNodeGroup(ids); return ; }
3447 MEDFileUMeshSplitL1 *lev=getMeshAtLevSafe(meshDimRelToMaxExt);
3448 DataArrayInt *fam=lev->getOrCreateAndGetFamilyField();
3449 addGroupUnderground(false,ids,fam);
3453 * \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).
3454 * \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)
3456 void MEDFileUMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
3459 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
3460 std::string grpName(ids->getName());
3462 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
3463 ids->checkStrictlyMonotonic(true);
3464 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
3465 std::vector<std::string> grpsNames=getGroupsNames();
3466 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
3468 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
3469 throw INTERP_KERNEL::Exception(oss.str().c_str());
3471 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds=getAllNonNullFamilyIds();
3472 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
3473 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
3474 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
3475 std::vector<int> familyIds;
3476 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
3477 int maxVal=getTheMaxAbsFamilyId()+1;
3478 std::map<std::string,int> families(_families);
3479 std::map<std::string, std::vector<std::string> > groups(_groups);
3480 std::vector<std::string> fams;
3481 bool created(false);
3482 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
3484 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
3485 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
3486 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
3487 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
3490 bool isFamPresent=false;
3491 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
3492 isFamPresent=(*itl)->presenceOfValue(*famId);
3494 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
3497 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
3498 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
3499 fams.push_back(locFamName);
3500 if(existsFamily(*famId))
3502 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
3503 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3506 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
3510 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
3511 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
3512 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
3513 if(existsFamily(*famId))
3515 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
3516 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
3521 for(std::size_t i=0;i<familyIds.size();i++)
3523 DataArrayInt *da=idsPerfamiliyIds[i];
3524 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
3528 _groups[grpName]=fams;
3532 * Changes a name of a family specified by its id.
3533 * \param [in] id - the id of the family of interest.
3534 * \param [in] newFamName - the new family name.
3535 * \throw If no family with the given \a id exists.
3537 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
3539 std::string oldName=getFamilyNameGivenId(id);
3540 _families.erase(oldName);
3541 _families[newFamName]=id;
3545 * Removes a mesh of a given dimension.
3546 * \param [in] meshDimRelToMax - the relative dimension of interest.
3547 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
3549 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
3551 std::vector<int> levSet=getNonEmptyLevels();
3552 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
3553 if(it==levSet.end())
3554 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
3555 int pos=(-meshDimRelToMax);
3560 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
3561 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3562 * \param [in] m - the new mesh to set.
3563 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3565 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3566 * another node coordinates array.
3567 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3568 * to the existing meshes of other levels of \a this mesh.
3570 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
3572 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
3573 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3577 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
3578 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
3579 * \param [in] m - the new mesh to set.
3580 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
3581 * writing \a this mesh in a MED file.
3582 * \throw If the name or the description of \a this mesh and \a m are not empty and are
3584 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
3585 * another node coordinates array.
3586 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
3587 * to the existing meshes of other levels of \a this mesh.
3589 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
3591 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
3592 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
3595 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
3597 dealWithTinyInfo(m);
3598 std::vector<int> levSet=getNonEmptyLevels();
3599 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
3601 if((DataArrayDouble *)_coords==0)
3603 DataArrayDouble *c=m->getCoords();
3608 if(m->getCoords()!=_coords)
3609 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
3610 int sz=(-meshDimRelToMax)+1;
3611 if(sz>=(int)_ms.size())
3613 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
3617 return _ms[-meshDimRelToMax];
3621 * This method allows to set at once the content of different levels in \a this.
3622 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
3624 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
3625 * \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.
3626 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
3628 * \throw If \a there is a null pointer in \a ms.
3629 * \sa MEDFileUMesh::setMeshAtLevel
3631 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3635 const MEDCouplingUMesh *mRef=ms[0];
3637 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
3638 std::string name(mRef->getName());
3639 const DataArrayDouble *coo(mRef->getCoords());
3642 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3644 const MEDCouplingUMesh *cur(*it);
3646 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
3647 if(coo!=cur->getCoords())
3648 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
3649 int mdim=cur->getMeshDimension();
3650 zeDim=std::max(zeDim,mdim);
3651 if(s.find(mdim)!=s.end())
3652 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
3654 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3656 int mdim=(*it)->getMeshDimension();
3657 setName((*it)->getName());
3658 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
3664 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
3665 * meshes each representing a group, and creates corresponding groups in \a this mesh.
3666 * The given meshes must share the same node coordinates array.
3667 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
3668 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3669 * create in \a this mesh.
3670 * \throw If \a ms is empty.
3671 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3672 * to the existing meshes of other levels of \a this mesh.
3673 * \throw If the meshes in \a ms do not share the same node coordinates array.
3674 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3675 * of the given meshes.
3676 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3677 * \throw If names of some meshes in \a ms are equal.
3678 * \throw If \a ms includes a mesh with an empty name.
3680 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3683 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
3684 int sz=(-meshDimRelToMax)+1;
3685 if(sz>=(int)_ms.size())
3687 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3688 DataArrayDouble *coo=checkMultiMesh(ms);
3689 if((DataArrayDouble *)_coords==0)
3695 if((DataArrayDouble *)_coords!=coo)
3696 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
3697 std::vector<DataArrayInt *> corr;
3698 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
3699 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
3700 setMeshAtLevel(meshDimRelToMax,m,renum);
3701 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3702 setGroupsAtLevel(meshDimRelToMax,corr2,true);
3706 * Creates groups at a given level in \a this mesh from a sequence of
3707 * meshes each representing a group.
3708 * The given meshes must share the same node coordinates array.
3709 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
3710 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
3711 * create in \a this mesh.
3712 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
3714 * \throw If \a ms is empty.
3715 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
3716 * to the existing meshes of other levels of \a this mesh.
3717 * \throw If the meshes in \a ms do not share the same node coordinates array.
3718 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
3719 * of the given meshes.
3720 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
3721 * \throw If names of some meshes in \a ms are equal.
3722 * \throw If \a ms includes a mesh with an empty name.
3724 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
3727 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
3728 int sz=(-meshDimRelToMax)+1;
3729 if(sz>=(int)_ms.size())
3731 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
3732 DataArrayDouble *coo=checkMultiMesh(ms);
3733 if((DataArrayDouble *)_coords==0)
3739 if((DataArrayDouble *)_coords!=coo)
3740 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
3741 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
3742 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
3744 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
3746 DataArrayInt *arr=0;
3747 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
3751 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
3752 throw INTERP_KERNEL::Exception(oss.str().c_str());
3755 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
3756 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
3759 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
3761 const DataArrayDouble *ret=ms[0]->getCoords();
3762 int mdim=ms[0]->getMeshDimension();
3763 for(unsigned int i=1;i<ms.size();i++)
3765 ms[i]->checkCoherency();
3766 if(ms[i]->getCoords()!=ret)
3767 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
3768 if(ms[i]->getMeshDimension()!=mdim)
3769 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
3771 return const_cast<DataArrayDouble *>(ret);
3775 * Sets the family field of a given relative dimension.
3776 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
3777 * the family field is set.
3778 * \param [in] famArr - the array of the family field.
3779 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3780 * \throw If \a famArr has an invalid size.
3782 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
3784 if(meshDimRelToMaxExt==1)
3791 DataArrayDouble *coo(_coords);
3793 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
3794 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
3799 if(meshDimRelToMaxExt>1)
3800 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
3801 int traducedRk=-meshDimRelToMaxExt;
3802 if(traducedRk>=(int)_ms.size())
3803 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3804 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3805 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3806 return _ms[traducedRk]->setFamilyArr(famArr);
3810 * Sets the optional numbers of mesh entities of a given dimension.
3811 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3812 * \param [in] renumArr - the array of the numbers.
3813 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3814 * \throw If \a renumArr has an invalid size.
3816 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
3818 if(meshDimRelToMaxExt==1)
3826 DataArrayDouble *coo(_coords);
3828 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
3829 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
3830 renumArr->incrRef();
3831 _num_coords=renumArr;
3835 if(meshDimRelToMaxExt>1)
3836 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
3837 int traducedRk=-meshDimRelToMaxExt;
3838 if(traducedRk>=(int)_ms.size())
3839 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3840 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3841 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3842 return _ms[traducedRk]->setRenumArr(renumArr);
3846 * Sets the optional names of mesh entities of a given dimension.
3847 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3848 * \param [in] nameArr - the array of the names.
3849 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3850 * \throw If \a nameArr has an invalid size.
3852 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
3854 if(meshDimRelToMaxExt==1)
3861 DataArrayDouble *coo(_coords);
3863 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
3864 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
3866 _name_coords=nameArr;
3869 if(meshDimRelToMaxExt>1)
3870 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
3871 int traducedRk=-meshDimRelToMaxExt;
3872 if(traducedRk>=(int)_ms.size())
3873 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! To low !");
3874 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
3875 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3876 return _ms[traducedRk]->setNameArr(nameArr);
3879 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
3881 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3882 if((const MEDFileUMeshSplitL1 *)(*it))
3883 (*it)->synchronizeTinyInfo(*this);
3887 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
3889 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
3891 DataArrayInt *arr=_fam_coords;
3893 arr->changeValue(oldId,newId);
3894 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3896 MEDFileUMeshSplitL1 *sp=(*it);
3899 sp->changeFamilyIdArr(oldId,newId);
3904 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
3906 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
3907 const DataArrayInt *da(_fam_coords);
3909 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3910 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3912 const MEDFileUMeshSplitL1 *elt(*it);
3915 da=elt->getFamilyField();
3917 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
3923 void MEDFileUMesh::computeRevNum() const
3925 if((const DataArrayInt *)_num_coords)
3928 int maxValue=_num_coords->getMaxValue(pos);
3929 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
3933 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
3935 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
3938 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildren() const
3940 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildren());
3941 if((const DataArrayInt *)_fam_nodes)
3942 ret.push_back((const DataArrayInt *)_fam_nodes);
3943 if((const DataArrayInt *)_num_nodes)
3944 ret.push_back((const DataArrayInt *)_num_nodes);
3945 if((const DataArrayInt *)_fam_cells)
3946 ret.push_back((const DataArrayInt *)_fam_cells);
3947 if((const DataArrayInt *)_num_cells)
3948 ret.push_back((const DataArrayInt *)_num_nodes);
3949 if((const DataArrayInt *)_rev_num_nodes)
3950 ret.push_back((const DataArrayInt *)_rev_num_nodes);
3951 if((const DataArrayInt *)_rev_num_cells)
3952 ret.push_back((const DataArrayInt *)_rev_num_cells);
3956 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
3958 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3959 if((const DataArrayInt *)_fam_nodes)
3961 int val=_fam_nodes->getMaxValue(tmp);
3962 ret=std::max(ret,std::abs(val));
3964 if((const DataArrayInt *)_fam_cells)
3966 int val=_fam_cells->getMaxValue(tmp);
3967 ret=std::max(ret,std::abs(val));
3972 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
3974 int ret=-std::numeric_limits<int>::max(),tmp=-1;
3975 if((const DataArrayInt *)_fam_nodes)
3977 int val=_fam_nodes->getMaxValue(tmp);
3978 ret=std::max(ret,val);
3980 if((const DataArrayInt *)_fam_cells)
3982 int val=_fam_cells->getMaxValue(tmp);
3983 ret=std::max(ret,val);
3988 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
3990 int ret=std::numeric_limits<int>::max(),tmp=-1;
3991 if((const DataArrayInt *)_fam_nodes)
3993 int val=_fam_nodes->getMinValue(tmp);
3994 ret=std::min(ret,val);
3996 if((const DataArrayInt *)_fam_cells)
3998 int val=_fam_cells->getMinValue(tmp);
3999 ret=std::min(ret,val);
4004 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4006 if(!MEDFileMesh::isEqual(other,eps,what))
4008 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4011 what="Mesh types differ ! This is structured and other is NOT !";
4014 const DataArrayInt *famc1=_fam_nodes;
4015 const DataArrayInt *famc2=otherC->_fam_nodes;
4016 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4018 what="Mismatch of families arr on nodes ! One is defined and not other !";
4023 bool ret=famc1->isEqual(*famc2);
4026 what="Families arr on nodes differ !";
4031 famc2=otherC->_fam_cells;
4032 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4034 what="Mismatch of families arr on cells ! One is defined and not other !";
4039 bool ret=famc1->isEqual(*famc2);
4042 what="Families arr on cells differ !";
4047 famc2=otherC->_num_nodes;
4048 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4050 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4055 bool ret=famc1->isEqual(*famc2);
4058 what="Numbering arr on nodes differ !";
4063 famc2=otherC->_num_cells;
4064 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4066 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4071 bool ret=famc1->isEqual(*famc2);
4074 what="Numbering arr on cells differ !";
4078 const DataArrayAsciiChar *d1=_names_cells;
4079 const DataArrayAsciiChar *d2=otherC->_names_cells;
4080 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4082 what="Mismatch of naming arr on cells ! One is defined and not other !";
4087 bool ret=d1->isEqual(*d2);
4090 what="Naming arr on cells differ !";
4095 d2=otherC->_names_nodes;
4096 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4098 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4103 bool ret=d1->isEqual(*d2);
4106 what="Naming arr on nodes differ !";
4113 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4115 MEDFileMesh::clearNonDiscrAttributes();
4116 const DataArrayInt *tmp=_fam_nodes;
4118 (const_cast<DataArrayInt *>(tmp))->setName("");
4121 (const_cast<DataArrayInt *>(tmp))->setName("");
4124 (const_cast<DataArrayInt *>(tmp))->setName("");
4127 (const_cast<DataArrayInt *>(tmp))->setName("");
4131 * Returns ids of mesh entities contained in given families of a given dimension.
4132 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4134 * \param [in] fams - the names of the families of interest.
4135 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4136 * returned instead of ids.
4137 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4138 * numbers, if available and required, of mesh entities of the families. The caller
4139 * is to delete this array using decrRef() as it is no more needed.
4140 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4142 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4144 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4145 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : Only available for levels 0 or 1 !");
4146 std::vector<int> famIds=getFamiliesIds(fams);
4147 if(meshDimRelToMaxExt==1)
4149 if((const DataArrayInt *)_fam_nodes)
4151 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4153 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4155 da=_fam_nodes->getIdsEqualList(0,0);
4157 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4162 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4166 if((const DataArrayInt *)_fam_cells)
4168 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4170 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4172 da=_fam_cells->getIdsEqualList(0,0);
4174 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4179 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4184 * Sets the family field of a given relative dimension.
4185 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4186 * the family field is set.
4187 * \param [in] famArr - the array of the family field.
4188 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4189 * \throw If \a famArr has an invalid size.
4190 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4192 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4194 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4195 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4196 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4198 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4199 if(meshDimRelToMaxExt==0)
4201 int nbCells=mesh->getNumberOfCells();
4202 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4207 int nbNodes=mesh->getNumberOfNodes();
4208 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4216 * Sets the optional numbers of mesh entities of a given dimension.
4217 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4218 * \param [in] renumArr - the array of the numbers.
4219 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4220 * \throw If \a renumArr has an invalid size.
4221 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4223 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4225 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4226 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 !");
4227 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4229 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
4230 if(meshDimRelToMaxExt==0)
4232 int nbCells=mesh->getNumberOfCells();
4233 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
4234 _num_cells=renumArr;
4238 int nbNodes=mesh->getNumberOfNodes();
4239 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
4240 _num_nodes=renumArr;
4243 renumArr->incrRef();
4247 * Sets the optional names of mesh entities of a given dimension.
4248 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4249 * \param [in] nameArr - the array of the names.
4250 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4251 * \throw If \a nameArr has an invalid size.
4253 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4255 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4256 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 !");
4257 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
4259 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
4260 if(meshDimRelToMaxExt==0)
4262 int nbCells=mesh->getNumberOfCells();
4263 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
4264 _names_cells=nameArr;
4268 int nbNodes=mesh->getNumberOfNodes();
4269 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
4270 _names_nodes=nameArr;
4277 * Returns the family field for mesh entities of a given dimension.
4278 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4279 * \return const DataArrayInt * - the family field. It is an array of ids of families
4280 * each mesh entity belongs to. It can be \c NULL.
4281 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4283 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
4285 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4286 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 !");
4287 if(meshDimRelToMaxExt==0)
4294 * Returns the optional numbers of mesh entities of a given dimension.
4295 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4296 * \return const DataArrayInt * - the array of the entity numbers.
4297 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4298 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4300 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
4302 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4303 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 !");
4304 if(meshDimRelToMaxExt==0)
4311 * Returns the optional numbers of mesh entities of a given dimension transformed using
4312 * DataArrayInt::invertArrayN2O2O2N().
4313 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4314 * \return const DataArrayInt * - the array of the entity numbers transformed using
4315 * DataArrayInt::invertArrayN2O2O2N().
4316 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
4317 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4319 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
4321 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4322 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
4323 if(meshDimRelToMaxExt==0)
4325 if((const DataArrayInt *)_num_cells)
4328 int maxValue=_num_cells->getMaxValue(pos);
4329 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
4330 return _rev_num_cells;
4333 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
4337 if((const DataArrayInt *)_num_nodes)
4340 int maxValue=_num_nodes->getMaxValue(pos);
4341 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
4342 return _rev_num_nodes;
4345 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
4349 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
4351 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4352 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 !");
4353 if(meshDimRelToMaxExt==0)
4354 return _names_cells;
4356 return _names_nodes;
4360 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
4361 * \return std::vector<int> - a sequence of the relative dimensions: [0].
4363 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
4365 std::vector<int> ret(1);
4370 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
4371 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
4373 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
4375 std::vector<int> ret(2);
4381 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
4383 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
4385 std::vector<int> ret;
4386 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells);
4395 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
4397 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
4399 std::vector<int> ret;
4400 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells);
4409 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
4411 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
4413 std::vector<int> ret;
4414 const DataArrayAsciiChar *namesCells(_names_cells);
4421 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
4423 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
4425 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
4429 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
4431 DataArrayInt *arr=_fam_nodes;
4433 arr->changeValue(oldId,newId);
4436 arr->changeValue(oldId,newId);
4439 void MEDFileStructuredMesh::deepCpyAttributes()
4441 if((const DataArrayInt*)_fam_nodes)
4442 _fam_nodes=_fam_nodes->deepCpy();
4443 if((const DataArrayInt*)_num_nodes)
4444 _num_nodes=_num_nodes->deepCpy();
4445 if((const DataArrayInt*)_fam_cells)
4446 _fam_cells=_fam_cells->deepCpy();
4447 if((const DataArrayInt*)_num_cells)
4448 _num_cells=_num_cells->deepCpy();
4449 if((const DataArrayInt*)_rev_num_nodes)
4450 _rev_num_nodes=_rev_num_nodes->deepCpy();
4451 if((const DataArrayInt*)_rev_num_cells)
4452 _rev_num_cells=_rev_num_cells->deepCpy();
4456 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
4458 * \return a pointer to cartesian mesh that need to be managed by the caller.
4459 * \warning the returned pointer has to be managed by the caller.
4463 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
4464 * \param [in] meshDimRelToMax - it must be \c 0.
4465 * \param [in] renum - it must be \c false.
4466 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
4467 * delete using decrRef() as it is no more needed.
4469 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
4472 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
4473 if(meshDimRelToMax!=0)
4474 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
4475 const MEDCouplingStructuredMesh *m=getStructuredMesh();
4478 return const_cast<MEDCouplingStructuredMesh *>(m);
4482 * Returns number of mesh entities of a given relative dimension in \a this mesh.
4483 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
4484 * \return int - the number of entities.
4485 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
4487 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
4489 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
4490 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 !");
4491 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4493 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
4494 if(meshDimRelToMaxExt==0)
4495 return cmesh->getNumberOfCells();
4497 return cmesh->getNumberOfNodes();
4500 int MEDFileStructuredMesh::getNumberOfNodes() const
4502 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();
4504 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
4505 return cmesh->getNumberOfNodes();
4508 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
4510 if(st.getNumberOfItems()!=1)
4511 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 !");
4512 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
4513 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
4514 if(getNumberOfNodes()!=(int)nodesFetched.size())
4515 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
4516 if(st[0].getPflName().empty())
4518 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
4521 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
4522 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
4523 int sz(nodesFetched.size());
4524 for(const int *work=arr->begin();work!=arr->end();work++)
4526 std::vector<int> conn;
4527 cmesh->getNodeIdsOfCell(*work,conn);
4528 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
4529 if(*it>=0 && *it<sz)
4530 nodesFetched[*it]=true;
4532 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
4536 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
4538 med_geometry_type geoTypeReq=MED_NONE;
4542 geoTypeReq=MED_HEXA8;
4545 geoTypeReq=MED_QUAD4;
4548 geoTypeReq=MED_SEG2;
4551 geoTypeReq=MED_POINT1;
4554 throw INTERP_KERNEL::Exception("Invalid meshdim detected for structured mesh ! Must be in (1,2,3) !");
4559 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4561 setName(strm->getName());
4562 setDescription(strm->getDescription());
4563 setUnivName(strm->getUnivName());
4564 setIteration(strm->getIteration());
4565 setOrder(strm->getOrder());
4566 setTimeValue(strm->getTime());
4567 setTimeUnit(strm->getTimeUnit());
4568 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
4569 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
4570 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4573 if(!mrs || mrs->isNodeFamilyFieldReading())
4575 _fam_nodes=DataArrayInt::New();
4576 _fam_nodes->alloc(nbOfElt,1);
4577 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
4580 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4583 if(!mrs || mrs->isNodeNumFieldReading())
4585 _num_nodes=DataArrayInt::New();
4586 _num_nodes->alloc(nbOfElt,1);
4587 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
4590 int meshDim=getStructuredMesh()->getMeshDimension();
4591 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4592 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
4595 if(!mrs || mrs->isCellFamilyFieldReading())
4597 _fam_cells=DataArrayInt::New();
4598 _fam_cells->alloc(nbOfElt,1);
4599 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_fam_cells->getPointer());
4602 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
4605 if(!mrs || mrs->isCellNumFieldReading())
4607 _num_cells=DataArrayInt::New();
4608 _num_cells->alloc(nbOfElt,1);
4609 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_num_cells->getPointer());
4612 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
4615 if(!mrs || mrs->isCellNameFieldReading())
4617 _names_cells=DataArrayAsciiChar::New();
4618 _names_cells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4619 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,_names_cells->getPointer());
4620 _names_cells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4623 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
4626 if(!mrs || mrs->isNodeNameFieldReading())
4628 _names_nodes=DataArrayAsciiChar::New();
4629 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
4630 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
4631 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
4636 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
4638 int meshDim=getStructuredMesh()->getMeshDimension();
4639 med_geometry_type geoTypeReq=GetGeoTypeFromMeshDim(meshDim);
4641 if((const DataArrayInt *)_fam_cells)
4642 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
4643 if((const DataArrayInt *)_fam_nodes)
4644 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
4645 if((const DataArrayInt *)_num_cells)
4646 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
4647 if((const DataArrayInt *)_num_nodes)
4648 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
4649 if((const DataArrayAsciiChar *)_names_cells)
4651 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
4653 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
4654 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4655 throw INTERP_KERNEL::Exception(oss.str().c_str());
4657 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
4659 if((const DataArrayAsciiChar *)_names_nodes)
4661 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
4663 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
4664 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
4665 throw INTERP_KERNEL::Exception(oss.str().c_str());
4667 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
4670 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
4674 * Returns an empty instance of MEDFileCMesh.
4675 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4676 * mesh using decrRef() as it is no more needed.
4678 MEDFileCMesh *MEDFileCMesh::New()
4680 return new MEDFileCMesh;
4684 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4685 * file. The first mesh in the file is loaded.
4686 * \param [in] fileName - the name of MED file to read.
4687 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4688 * mesh using decrRef() as it is no more needed.
4689 * \throw If the file is not readable.
4690 * \throw If there is no meshes in the file.
4691 * \throw If the mesh in the file is not a Cartesian one.
4693 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
4695 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4698 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4699 throw INTERP_KERNEL::Exception(oss.str().c_str());
4701 MEDFileUtilities::CheckFileForRead(fileName);
4702 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4704 ParaMEDMEM::MEDCouplingMeshType meshType;
4706 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
4707 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
4711 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
4712 * file. The mesh to load is specified by its name and numbers of a time step and an
4714 * \param [in] fileName - the name of MED file to read.
4715 * \param [in] mName - the name of the mesh to read.
4716 * \param [in] dt - the number of a time step.
4717 * \param [in] it - the number of an iteration.
4718 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
4719 * mesh using decrRef() as it is no more needed.
4720 * \throw If the file is not readable.
4721 * \throw If there is no mesh with given attributes in the file.
4722 * \throw If the mesh in the file is not a Cartesian one.
4724 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4726 MEDFileUtilities::CheckFileForRead(fileName);
4727 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4728 return new MEDFileCMesh(fid,mName,dt,it,mrs);
4731 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
4733 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
4736 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildren() const
4738 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
4739 if((const MEDCouplingCMesh *)_cmesh)
4740 ret.push_back((const MEDCouplingCMesh *)_cmesh);
4745 * Returns the dimension on cells in \a this mesh.
4746 * \return int - the mesh dimension.
4747 * \throw If there are no cells in this mesh.
4749 int MEDFileCMesh::getMeshDimension() const
4751 if(!((const MEDCouplingCMesh*)_cmesh))
4752 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
4753 return _cmesh->getMeshDimension();
4757 * Returns the dimension on nodes in \a this mesh.
4758 * \return int - the space dimension.
4759 * \throw If there are no cells in this mesh.
4761 int MEDFileCMesh::getSpaceDimension() const
4763 if(!((const MEDCouplingCMesh*)_cmesh))
4764 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
4765 return _cmesh->getSpaceDimension();
4769 * Returns a string describing \a this mesh.
4770 * \return std::string - the mesh information string.
4772 std::string MEDFileCMesh::simpleRepr() const
4774 return MEDFileStructuredMesh::simpleRepr();
4778 * Returns a full textual description of \a this mesh.
4779 * \return std::string - the string holding the mesh description.
4781 std::string MEDFileCMesh::advancedRepr() const
4783 return simpleRepr();
4786 MEDFileMesh *MEDFileCMesh::shallowCpy() const
4788 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4792 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
4794 return new MEDFileCMesh;
4797 MEDFileMesh *MEDFileCMesh::deepCpy() const
4799 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
4800 if((const MEDCouplingCMesh*)_cmesh)
4801 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
4802 ret->deepCpyAttributes();
4807 * Checks if \a this and another mesh are equal.
4808 * \param [in] other - the mesh to compare with.
4809 * \param [in] eps - a precision used to compare real values.
4810 * \param [in,out] what - the string returning description of unequal data.
4811 * \return bool - \c true if the meshes are equal, \c false, else.
4813 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4815 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
4817 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
4820 what="Mesh types differ ! This is cartesian and other is NOT !";
4823 clearNonDiscrAttributes();
4824 otherC->clearNonDiscrAttributes();
4825 const MEDCouplingCMesh *coo1=_cmesh;
4826 const MEDCouplingCMesh *coo2=otherC->_cmesh;
4827 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
4829 what="Mismatch of cartesian meshes ! One is defined and not other !";
4834 bool ret=coo1->isEqual(coo2,eps);
4837 what="cartesian meshes differ !";
4845 * Clears redundant attributes of incorporated data arrays.
4847 void MEDFileCMesh::clearNonDiscrAttributes() const
4849 MEDFileStructuredMesh::clearNonDiscrAttributes();
4850 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
4853 MEDFileCMesh::MEDFileCMesh()
4857 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4860 loadCMeshFromFile(fid,mName,dt,it,mrs);
4862 catch(INTERP_KERNEL::Exception& e)
4867 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4869 ParaMEDMEM::MEDCouplingMeshType meshType;
4872 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
4873 if(meshType!=CARTESIAN)
4875 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
4876 throw INTERP_KERNEL::Exception(oss.str().c_str());
4878 MEDFileCMeshL2 loaderl2;
4879 loaderl2.loadAll(fid,mid,mName,dt,it);
4880 MEDCouplingCMesh *mesh=loaderl2.getMesh();
4883 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
4887 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
4888 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
4890 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
4892 synchronizeTinyInfoOnLeaves();
4896 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
4898 synchronizeTinyInfoOnLeaves();
4903 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
4904 * \param [in] m - the new MEDCouplingCMesh to refer to.
4905 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4908 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
4910 dealWithTinyInfo(m);
4916 void MEDFileCMesh::writeLL(med_idt fid) const
4918 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
4919 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
4920 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
4921 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
4922 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
4923 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
4924 int spaceDim(_cmesh->getSpaceDimension());
4925 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4926 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
4927 for(int i=0;i<spaceDim;i++)
4929 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
4931 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
4932 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
4933 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
4935 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
4936 MEDmeshUniversalNameWr(fid,maa);
4937 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
4938 for(int i=0;i<spaceDim;i++)
4940 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
4941 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
4944 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
4945 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
4948 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
4950 const MEDCouplingCMesh *cmesh=_cmesh;
4953 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
4954 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
4955 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
4956 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
4959 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
4961 return new MEDFileCurveLinearMesh;
4964 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
4966 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
4969 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
4970 throw INTERP_KERNEL::Exception(oss.str().c_str());
4972 MEDFileUtilities::CheckFileForRead(fileName);
4973 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4975 ParaMEDMEM::MEDCouplingMeshType meshType;
4977 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
4978 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
4981 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
4983 MEDFileUtilities::CheckFileForRead(fileName);
4984 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
4985 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
4988 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
4990 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
4993 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildren() const
4995 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildren());
4996 if((const MEDCouplingCurveLinearMesh *)_clmesh)
4997 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
5001 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
5003 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5007 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
5009 return new MEDFileCurveLinearMesh;
5012 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
5014 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
5015 if((const MEDCouplingCurveLinearMesh*)_clmesh)
5016 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
5017 ret->deepCpyAttributes();
5021 int MEDFileCurveLinearMesh::getMeshDimension() const
5023 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
5024 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5025 return _clmesh->getMeshDimension();
5028 std::string MEDFileCurveLinearMesh::simpleRepr() const
5030 return MEDFileStructuredMesh::simpleRepr();
5033 std::string MEDFileCurveLinearMesh::advancedRepr() const
5035 return simpleRepr();
5038 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5040 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5042 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
5045 what="Mesh types differ ! This is curve linear and other is NOT !";
5048 clearNonDiscrAttributes();
5049 otherC->clearNonDiscrAttributes();
5050 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
5051 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
5052 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5054 what="Mismatch of curve linear meshes ! One is defined and not other !";
5059 bool ret=coo1->isEqual(coo2,eps);
5062 what="curve linear meshes differ !";
5069 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
5071 MEDFileStructuredMesh::clearNonDiscrAttributes();
5072 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
5075 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
5077 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
5080 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
5081 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
5082 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
5083 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
5086 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
5088 synchronizeTinyInfoOnLeaves();
5092 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
5094 dealWithTinyInfo(m);
5100 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
5102 synchronizeTinyInfoOnLeaves();
5106 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
5110 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5113 loadCLMeshFromFile(fid,mName,dt,it,mrs);
5115 catch(INTERP_KERNEL::Exception& e)
5120 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
5122 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5123 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5124 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5125 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5126 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5127 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5128 int spaceDim=_clmesh->getSpaceDimension();
5129 int meshDim=_clmesh->getMeshDimension();
5130 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5131 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5132 const DataArrayDouble *coords=_clmesh->getCoords();
5134 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
5135 for(int i=0;i<spaceDim;i++)
5137 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
5139 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5140 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
5141 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
5143 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
5144 MEDmeshUniversalNameWr(fid,maa);
5145 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
5146 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
5147 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
5149 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
5151 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
5152 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
5155 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5157 ParaMEDMEM::MEDCouplingMeshType meshType;
5160 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5161 if(meshType!=CURVE_LINEAR)
5163 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
5164 throw INTERP_KERNEL::Exception(oss.str().c_str());
5166 MEDFileCLMeshL2 loaderl2;
5167 loaderl2.loadAll(fid,mid,mName,dt,it);
5168 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
5171 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5174 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
5176 return new MEDFileMeshMultiTS;
5179 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
5181 return new MEDFileMeshMultiTS(fileName);
5184 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
5186 return new MEDFileMeshMultiTS(fileName,mName);
5189 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
5191 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
5192 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
5194 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
5195 if((const MEDFileMesh *)*it)
5196 meshOneTs[i]=(*it)->deepCpy();
5197 ret->_mesh_one_ts=meshOneTs;
5201 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
5203 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
5206 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildren() const
5208 std::vector<const BigMemoryObject *> ret;
5209 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5211 const MEDFileMesh *cur(*it);
5218 std::string MEDFileMeshMultiTS::getName() const
5220 if(_mesh_one_ts.empty())
5221 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
5222 return _mesh_one_ts[0]->getName();
5225 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
5227 std::string oldName(getName());
5228 std::vector< std::pair<std::string,std::string> > v(1);
5229 v[0].first=oldName; v[0].second=newMeshName;
5233 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5236 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5238 MEDFileMesh *cur(*it);
5240 ret=cur->changeNames(modifTab) || ret;
5245 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
5247 if(_mesh_one_ts.empty())
5248 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
5249 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
5252 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
5255 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
5256 _mesh_one_ts.resize(1);
5257 mesh1TimeStep->incrRef();
5258 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
5259 _mesh_one_ts[0]=mesh1TimeStep;
5262 void MEDFileMeshMultiTS::write(med_idt fid) const
5264 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
5266 (*it)->copyOptionsFrom(*this);
5271 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
5273 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5274 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5275 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5276 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5280 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
5281 {//for the moment to be improved
5282 _mesh_one_ts.resize(1);
5283 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
5286 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
5290 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
5293 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5296 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5297 throw INTERP_KERNEL::Exception(oss.str().c_str());
5299 MEDFileUtilities::CheckFileForRead(fileName);
5300 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5302 ParaMEDMEM::MEDCouplingMeshType meshType;
5304 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5305 loadFromFile(fileName,ms.front());
5307 catch(INTERP_KERNEL::Exception& e)
5312 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
5315 loadFromFile(fileName,mName);
5317 catch(INTERP_KERNEL::Exception& e)
5322 MEDFileMeshes *MEDFileMeshes::New()
5324 return new MEDFileMeshes;
5327 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
5329 return new MEDFileMeshes(fileName);
5332 void MEDFileMeshes::write(med_idt fid) const
5335 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5337 (*it)->copyOptionsFrom(*this);
5342 void MEDFileMeshes::write(const std::string& fileName, int mode) const
5344 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
5345 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
5346 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
5347 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
5352 int MEDFileMeshes::getNumberOfMeshes() const
5354 return _meshes.size();
5357 MEDFileMeshesIterator *MEDFileMeshes::iterator()
5359 return new MEDFileMeshesIterator(this);
5362 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
5364 if(i<0 || i>=(int)_meshes.size())
5366 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
5367 throw INTERP_KERNEL::Exception(oss.str().c_str());
5369 return _meshes[i]->getOneTimeStep();
5372 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
5374 std::vector<std::string> ms=getMeshesNames();
5375 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
5378 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
5379 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
5380 throw INTERP_KERNEL::Exception(oss.str().c_str());
5382 return getMeshAtPos((int)std::distance(ms.begin(),it));
5385 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
5387 std::vector<std::string> ret(_meshes.size());
5389 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5391 const MEDFileMeshMultiTS *f=(*it);
5394 ret[i]=f->getName();
5398 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
5399 throw INTERP_KERNEL::Exception(oss.str().c_str());
5405 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
5408 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
5410 MEDFileMeshMultiTS *cur(*it);
5412 ret=cur->changeNames(modifTab) || ret;
5417 void MEDFileMeshes::resize(int newSize)
5419 _meshes.resize(newSize);
5422 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
5425 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
5426 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5427 elt->setOneTimeStep(mesh);
5428 _meshes.push_back(elt);
5431 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
5434 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
5435 if(i>=(int)_meshes.size())
5436 _meshes.resize(i+1);
5437 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
5438 elt->setOneTimeStep(mesh);
5442 void MEDFileMeshes::destroyMeshAtPos(int i)
5444 if(i<0 || i>=(int)_meshes.size())
5446 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
5447 throw INTERP_KERNEL::Exception(oss.str().c_str());
5449 _meshes.erase(_meshes.begin()+i);
5452 void MEDFileMeshes::loadFromFile(const std::string& fileName)
5454 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5456 _meshes.resize(ms.size());
5457 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
5458 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
5461 MEDFileMeshes::MEDFileMeshes()
5465 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
5468 loadFromFile(fileName);
5470 catch(INTERP_KERNEL::Exception& /*e*/)
5474 MEDFileMeshes *MEDFileMeshes::deepCpy() const
5476 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
5478 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5479 if((const MEDFileMeshMultiTS *)*it)
5480 meshes[i]=(*it)->deepCpy();
5481 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
5482 ret->_meshes=meshes;
5486 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
5488 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
5491 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildren() const
5493 std::vector<const BigMemoryObject *> ret;
5494 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
5496 const MEDFileMeshMultiTS *cur(*it);
5503 std::string MEDFileMeshes::simpleRepr() const
5505 std::ostringstream oss;
5506 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
5507 simpleReprWithoutHeader(oss);
5511 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
5513 int nbOfMeshes=getNumberOfMeshes();
5514 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
5515 std::vector<std::string> mns=getMeshesNames();
5516 for(int i=0;i<nbOfMeshes;i++)
5517 oss << " - #" << i << " \"" << mns[i] << "\"\n";
5520 void MEDFileMeshes::checkCoherency() const
5522 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
5524 std::set<std::string> s;
5525 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
5527 const MEDFileMeshMultiTS *elt=(*it);
5530 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
5531 throw INTERP_KERNEL::Exception(oss.str().c_str());
5533 std::size_t sz=s.size();
5534 s.insert(std::string((*it)->getName()));
5537 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
5538 throw INTERP_KERNEL::Exception(oss.str().c_str());
5543 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
5548 _nb_iter=ms->getNumberOfMeshes();
5552 MEDFileMeshesIterator::~MEDFileMeshesIterator()
5556 MEDFileMesh *MEDFileMeshesIterator::nextt()
5558 if(_iter_id<_nb_iter)
5560 MEDFileMeshes *ms(_ms);
5562 return ms->getMeshAtPos(_iter_id++);