1 // Copyright (C) 2007-2015 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, or (at your option) any later version.
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 extern med_geometry_type typmai3[34];
37 using namespace ParaMEDMEM;
39 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
41 MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
45 std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
47 std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity());
48 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
50 ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string);
51 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
52 ret+=(*it2).capacity();
54 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
55 ret+=(*it).first.capacity()+sizeof(int);
59 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
61 return std::vector<const BigMemoryObject *>();
65 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
66 * file. The first mesh in the file is loaded.
67 * \param [in] fileName - the name of MED file to read.
68 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
69 * mesh using decrRef() as it is no more needed.
70 * \throw If the file is not readable.
71 * \throw If there is no meshes in the file.
72 * \throw If the mesh in the file is of a not supported type.
74 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
76 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
79 std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
80 throw INTERP_KERNEL::Exception(oss.str().c_str());
82 MEDFileUtilities::CheckFileForRead(fileName);
83 ParaMEDMEM::MEDCouplingMeshType meshType;
84 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
87 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
92 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
93 ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
94 return (MEDFileUMesh *)ret.retn();
98 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
99 ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
100 return (MEDFileCMesh *)ret.retn();
104 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
105 ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
106 return (MEDFileCurveLinearMesh *)ret.retn();
110 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !";
111 throw INTERP_KERNEL::Exception(oss.str().c_str());
117 * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED
118 * file. The mesh to load is specified by its name and numbers of a time step and an
120 * \param [in] fileName - the name of MED file to read.
121 * \param [in] mName - the name of the mesh to read.
122 * \param [in] dt - the number of a time step.
123 * \param [in] it - the number of an iteration.
124 * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this
125 * mesh using decrRef() as it is no more needed.
126 * \throw If the file is not readable.
127 * \throw If there is no mesh with given attributes in the file.
128 * \throw If the mesh in the file is of a not supported type.
130 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
132 MEDFileUtilities::CheckFileForRead(fileName);
133 ParaMEDMEM::MEDCouplingMeshType meshType;
134 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
137 MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
142 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
143 ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
144 return (MEDFileUMesh *)ret.retn();
148 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
149 ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
150 return (MEDFileCMesh *)ret.retn();
154 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
155 ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
156 return (MEDFileCurveLinearMesh *)ret.retn();
160 std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !";
161 throw INTERP_KERNEL::Exception(oss.str().c_str());
167 * Writes \a this mesh into an open MED file specified by its descriptor.
168 * \param [in] fid - the MED file descriptor.
169 * \throw If the mesh name is not set.
170 * \throw If the file is open for reading only.
171 * \throw If the writing mode == 1 and the same data is present in an existing file.
173 void MEDFileMesh::write(med_idt fid) const
176 const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
178 throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
183 * Writes \a this mesh into a MED file specified by its name.
184 * \param [in] fileName - the MED file name.
185 * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
186 * - 2 - erase; an existing file is removed.
187 * - 1 - append; same data should not be present in an existing file.
188 * - 0 - overwrite; same data present in an existing file is overwritten.
189 * \throw If the mesh name is not set.
190 * \throw If \a mode == 1 and the same data is present in an existing file.
192 void MEDFileMesh::write(const std::string& fileName, int mode) const
194 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
195 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
196 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
197 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
202 * Checks if \a this and another mesh are equal.
203 * \param [in] other - the mesh to compare with.
204 * \param [in] eps - a precision used to compare real values.
205 * \param [in,out] what - the string returning description of unequal data.
206 * \return bool - \c true if the meshes are equal, \c false, else.
208 bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
210 if(_order!=other->_order)
212 what="Orders differ !";
215 if(_iteration!=other->_iteration)
217 what="Iterations differ !";
220 if(fabs(_time-other->_time)>eps)
222 what="Time values differ !";
225 if(_dt_unit!=other->_dt_unit)
227 what="Time units differ !";
230 if(_name!=other->_name)
232 what="Names differ !";
235 //univ_name has been ignored -> not a bug because it is a mutable attribute
236 if(_desc_name!=other->_desc_name)
238 what="Description names differ !";
241 if(!areGrpsEqual(other,what))
243 if(!areFamsEqual(other,what))
248 void MEDFileMesh::setName(const std::string& name)
254 * Clears redundant attributes of incorporated data arrays.
256 void MEDFileMesh::clearNonDiscrAttributes() const
261 bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
263 for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++)
265 if((*it).first==_name)
275 * Copies data on groups and families from another mesh.
276 * \param [in] other - the mesh to copy the data from.
278 void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other)
280 _groups=other._groups;
281 _families=other._families;
286 * This method clear all the groups in the map.
287 * So this method does not operate at all on arrays.
288 * So this method can lead to orphan families.
290 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
292 void MEDFileMesh::clearGrpMap()
298 * This method clear all the families in the map.
299 * So this method does not operate at all on arrays.
300 * WARNING ! if there are some groups lying on cleared families, those groups will be impacted !
302 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps
304 void MEDFileMesh::clearFamMap()
310 * This method clear all the families and groups in the map.
311 * So this method does not operate at all on arrays.
312 * As all groups and families entry will be removed after
313 * 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.
315 * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap
317 void MEDFileMesh::clearFamGrpMaps()
324 * Returns names of families constituting a group.
325 * \param [in] name - the name of the group of interest.
326 * \return std::vector<std::string> - a sequence of names of the families.
327 * \throw If the name of a nonexistent group is specified.
329 std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const
331 std::string oname(name);
332 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
333 if(it==_groups.end())
335 std::vector<std::string> grps=getGroupsNames();
336 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
337 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
338 throw INTERP_KERNEL::Exception(oss.str().c_str());
344 * Returns names of families constituting some groups.
345 * \param [in] grps - a sequence of names of groups of interest.
346 * \return std::vector<std::string> - a sequence of names of the families.
347 * \throw If a name of a nonexistent group is present in \a grps.
349 std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const
351 std::set<std::string> fams;
352 for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++)
354 std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it);
355 if(it2==_groups.end())
357 std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it;
358 std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
359 std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
360 throw INTERP_KERNEL::Exception(oss.str().c_str());
362 fams.insert((*it2).second.begin(),(*it2).second.end());
364 std::vector<std::string> fams2(fams.begin(),fams.end());
369 * Returns ids of families constituting a group.
370 * \param [in] name - the name of the group of interest.
371 * \return std::vector<int> - sequence of ids of the families.
372 * \throw If the name of a nonexistent group is specified.
374 std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
376 std::string oname(name);
377 std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
378 std::vector<std::string> grps=getGroupsNames();
379 if(it==_groups.end())
381 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
382 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
383 throw INTERP_KERNEL::Exception(oss.str().c_str());
385 return getFamiliesIds((*it).second);
389 * Sets names of families constituting a group. If data on families of this group is
390 * already present, it is overwritten. Every family in \a fams is checked, and if a
391 family is not yet in \a this mesh, the default group id \c 0 is assigned to it.
392 * \param [in] name - the name of the group of interest.
393 * \param [in] fams - a sequence of names of families constituting the group.
395 void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams)
397 std::string oname(name);
399 for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
401 std::map<std::string,int>::iterator it2=_families.find(*it1);
402 if(it2==_families.end())
408 * Sets families constituting a group. The families are specified by their ids.
409 * If a family name is not found by its id, an exception is thrown.
410 * If several families have same id, the first one in lexical order is taken.
411 * \param [in] name - the name of the group of interest.
412 * \param [in] famIds - a sequence of ids of families constituting the group.
413 * \throw If a family name is not found by its id.
415 void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
417 std::string oname(name);
418 std::vector<std::string> fams(famIds.size());
420 for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
422 std::string name2=getFamilyNameGivenId(*it1);
429 * Returns names of groups including a given family.
430 * \param [in] name - the name of the family of interest.
431 * \return std::vector<std::string> - a sequence of names of groups including the family.
433 std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const
435 std::vector<std::string> ret;
436 for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++)
438 for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++)
441 ret.push_back((*it1).first);
449 * Adds an existing family to groups.
450 * \param [in] famName - a name of family to add to \a grps.
451 * \param [in] grps - a sequence of group names to add the family in.
452 * \throw If a family named \a famName not yet exists.
454 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
456 std::string fName(famName);
457 const std::map<std::string,int>::const_iterator it=_families.find(fName);
458 if(it==_families.end())
460 std::vector<std::string> fams=getFamiliesNames();
461 std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :";
462 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
463 throw INTERP_KERNEL::Exception(oss.str().c_str());
465 for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++)
467 std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3);
468 if(it2!=_groups.end())
469 (*it2).second.push_back(fName);
472 std::vector<std::string> grps2(1,fName);
479 * Returns names of all groups of \a this mesh.
480 * \return std::vector<std::string> - a sequence of group names.
482 std::vector<std::string> MEDFileMesh::getGroupsNames() const
484 std::vector<std::string> ret(_groups.size());
486 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++)
492 * Returns names of all families of \a this mesh.
493 * \return std::vector<std::string> - a sequence of family names.
495 std::vector<std::string> MEDFileMesh::getFamiliesNames() const
497 std::vector<std::string> ret(_families.size());
499 for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
505 * Changes a name of every family, included in one group only, to be same as the group name.
506 * \throw If there are families with equal names in \a this mesh.
508 void MEDFileMesh::assignFamilyNameWithGroupName()
510 std::map<std::string, std::vector<std::string> > groups(_groups);
511 std::map<std::string,int> newFams;
512 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
514 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
515 if(grps.size()==1 && groups[grps[0]].size()==1)
517 if(newFams.find(grps[0])!=newFams.end())
519 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !";
520 throw INTERP_KERNEL::Exception(oss.str().c_str());
522 newFams[grps[0]]=(*it).second;
523 std::vector<std::string>& grps2=groups[grps[0]];
524 std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first));
529 if(newFams.find((*it).first)!=newFams.end())
531 std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !";
532 throw INTERP_KERNEL::Exception(oss.str().c_str());
534 newFams[(*it).first]=(*it).second;
542 * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched.
544 * \return the removed groups.
546 std::vector<std::string> MEDFileMesh::removeEmptyGroups()
548 std::vector<std::string> ret;
549 std::map<std::string, std::vector<std::string> > newGrps;
550 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
552 if((*it).second.empty())
553 ret.push_back((*it).first);
555 newGrps[(*it).first]=(*it).second;
563 * Removes a group from \a this mesh.
564 * \param [in] name - the name of the group to remove.
565 * \throw If no group with such a \a name exists.
567 void MEDFileMesh::removeGroup(const std::string& name)
569 std::string oname(name);
570 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
571 std::vector<std::string> grps=getGroupsNames();
572 if(it==_groups.end())
574 std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
575 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
576 throw INTERP_KERNEL::Exception(oss.str().c_str());
582 * Removes a family from \a this mesh.
583 * \param [in] name - the name of the family to remove.
584 * \throw If no family with such a \a name exists.
586 void MEDFileMesh::removeFamily(const std::string& name)
588 std::string oname(name);
589 std::map<std::string, int >::iterator it=_families.find(oname);
590 std::vector<std::string> fams=getFamiliesNames();
591 if(it==_families.end())
593 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
594 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
595 throw INTERP_KERNEL::Exception(oss.str().c_str());
598 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
600 std::vector<std::string>& v=(*it3).second;
601 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
608 * Removes all groups in \a this that are orphan. A group is orphan if this group lies on
609 * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in
610 * family field whatever its level. This method also suppresses the orphan families.
612 * \return - The list of removed groups names.
614 * \sa MEDFileMesh::removeOrphanFamilies.
616 std::vector<std::string> MEDFileMesh::removeOrphanGroups()
618 removeOrphanFamilies();
619 return removeEmptyGroups();
623 * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in
624 * 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.
626 * \return - The list of removed families names.
627 * \sa MEDFileMesh::removeOrphanGroups.
629 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
632 std::vector<std::string> ret;
633 if(!((DataArrayInt*)allFamIdsInUse))
635 ret=getFamiliesNames();
636 _families.clear(); _groups.clear();
639 std::map<std::string,int> famMap;
640 std::map<std::string, std::vector<std::string> > grps(_groups);
641 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
643 if(allFamIdsInUse->presenceOfValue((*it).second))
644 famMap[(*it).first]=(*it).second;
647 ret.push_back((*it).first);
648 std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first);
649 for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++)
651 std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy
652 std::vector<std::string>& famv=(*it3).second;
653 std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy
659 { _families=famMap; _groups=grps; }
664 * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever
665 * this family is orphan or not.
667 * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
669 void MEDFileMesh::removeFamiliesReferedByNoGroups()
671 std::map<std::string,int> fams;
672 std::set<std::string> sfams;
673 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
674 sfams.insert((*it).first);
675 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
676 for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
678 for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++)
679 if(*it!=DFT_FAM_NAME)
680 _families.erase(*it);
684 * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities
685 * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
686 * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
688 * \sa MEDFileMesh::removeOrphanFamilies
690 void MEDFileMesh::rearrangeFamilies()
692 checkOrphanFamilyZero();
693 removeFamiliesReferedByNoGroups();
695 std::vector<int> levels(getNonEmptyLevelsExt());
696 std::set<int> idsRefed;
697 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
698 idsRefed.insert((*it).second);
699 for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
701 const DataArrayInt *fams(0);
704 fams=getFamilyFieldAtLevel(*it);
706 catch(INTERP_KERNEL::Exception& e) { }
709 std::vector<bool> v(fams->getNumberOfTuples(),false);
710 for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
711 fams->switchOnTupleEqualTo(*pt,v);
712 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
713 if(!unfetchedIds->empty())
715 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
716 newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
717 setFamilyFieldArr(*it,newFams);
720 removeOrphanFamilies();
724 * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
726 void MEDFileMesh::checkOrphanFamilyZero() const
728 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
730 if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end())
732 std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !";
733 throw INTERP_KERNEL::Exception(oss.str().c_str());
739 * Renames a group in \a this mesh.
740 * \param [in] oldName - a current name of the group to rename.
741 * \param [in] newName - a new group name.
742 * \throw If no group named \a oldName exists in \a this mesh.
743 * \throw If a group named \a newName already exists.
745 void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName)
747 std::string oname(oldName);
748 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
749 std::vector<std::string> grps=getGroupsNames();
750 if(it==_groups.end())
752 std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :";
753 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
754 throw INTERP_KERNEL::Exception(oss.str().c_str());
756 std::string nname(newName);
757 std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname);
758 if(it2!=_groups.end())
760 std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !";
761 throw INTERP_KERNEL::Exception(oss.str().c_str());
763 std::vector<std::string> cpy=(*it).second;
765 _groups[newName]=cpy;
769 * Changes an id of a family in \a this mesh.
770 * This method calls changeFamilyIdArr().
771 * \param [in] oldId - a current id of the family.
772 * \param [in] newId - a new family id.
774 void MEDFileMesh::changeFamilyId(int oldId, int newId)
776 changeFamilyIdArr(oldId,newId);
777 std::map<std::string,int> fam2;
778 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
780 if((*it).second==oldId)
781 fam2[(*it).first]=newId;
783 fam2[(*it).first]=(*it).second;
789 * Renames a family in \a this mesh.
790 * \param [in] oldName - a current name of the family to rename.
791 * \param [in] newName - a new family name.
792 * \throw If no family named \a oldName exists in \a this mesh.
793 * \throw If a family named \a newName already exists.
795 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
797 std::string oname(oldName);
798 std::map<std::string, int >::iterator it=_families.find(oname);
799 std::vector<std::string> fams=getFamiliesNames();
800 if(it==_families.end())
802 std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :";
803 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
804 throw INTERP_KERNEL::Exception(oss.str().c_str());
806 std::string nname(newName);
807 std::map<std::string, int >::iterator it2=_families.find(nname);
808 if(it2!=_families.end())
810 std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
811 throw INTERP_KERNEL::Exception(oss.str().c_str());
813 int cpy=(*it).second;
815 _families[newName]=cpy;
816 for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
818 std::vector<std::string>& v=(*it3).second;
819 std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname);
826 * Checks if \a this and another mesh contains the same families.
827 * \param [in] other - the mesh to compare with \a this one.
828 * \param [in,out] what - an unused parameter.
829 * \return bool - \c true if number of families and their ids are the same in the two
830 * meshes. Families with the id == \c 0 are not considered.
832 bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const
834 if(_families==other->_families)
836 std::map<std::string,int> fam0;
837 std::map<std::string,int> fam1;
838 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
840 fam0[(*it).first]=(*it).second;
841 for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
843 fam1[(*it).first]=(*it).second;
848 * Checks if \a this and another mesh contains the same groups.
849 * \param [in] other - the mesh to compare with \a this one.
850 * \param [in,out] what - a string describing a difference of groups of the two meshes
851 * in case if this method returns \c false.
852 * \return bool - \c true if number of groups and families constituting them are the
853 * same in the two meshes.
855 bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const
857 if(_groups==other->_groups)
860 std::size_t sz=_groups.size();
861 if(sz!=other->_groups.size())
863 what="Groups differ because not same number !\n";
868 std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();
869 for(std::size_t i=0;i<sz && ret;i++,it1++)
871 std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first);
872 if(it2!=other->_groups.end())
874 std::set<std::string> s1((*it1).second.begin(),(*it1).second.end());
875 std::set<std::string> s2((*it2).second.begin(),(*it2).second.end());
881 what="A group in first mesh exists not in other !\n";
887 std::ostringstream oss; oss << "Groups description differs :\n";
888 oss << "First group description :\n";
889 for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++)
891 oss << " Group \"" << (*it).first << "\" on following families :\n";
892 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
893 oss << " \"" << *it2 << "\n";
895 oss << "Second group description :\n";
896 for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++)
898 oss << " Group \"" << (*it).first << "\" on following families :\n";
899 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
900 oss << " \"" << *it2 << "\n";
908 * Checks if a group with a given name exists in \a this mesh.
909 * \param [in] groupName - the group name.
910 * \return bool - \c true the group \a groupName exists in \a this mesh.
912 bool MEDFileMesh::existsGroup(const std::string& groupName) const
914 std::string grpName(groupName);
915 return _groups.find(grpName)!=_groups.end();
919 * Checks if a family with a given id exists in \a this mesh.
920 * \param [in] famId - the family id.
921 * \return bool - \c true the family with the id \a famId exists in \a this mesh.
923 bool MEDFileMesh::existsFamily(int famId) const
925 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
926 if((*it2).second==famId)
932 * Checks if a family with a given name exists in \a this mesh.
933 * \param [in] familyName - the family name.
934 * \return bool - \c true the family \a familyName exists in \a this mesh.
936 bool MEDFileMesh::existsFamily(const std::string& familyName) const
938 std::string fname(familyName);
939 return _families.find(fname)!=_families.end();
943 * Sets an id of a family.
944 * \param [in] familyName - the family name.
945 * \param [in] id - a new id of the family.
947 void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
949 std::string fname(familyName);
953 void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
955 std::string fname(familyName);
956 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
959 if((*it).first!=familyName)
961 std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !";
962 throw INTERP_KERNEL::Exception(oss.str().c_str());
969 * Adds a family to \a this mesh.
970 * \param [in] familyName - a name of the family.
971 * \param [in] famId - an id of the family.
972 * \throw If a family with the same name or id already exists in \a this mesh.
974 void MEDFileMesh::addFamily(const std::string& familyName, int famId)
976 std::string fname(familyName);
977 std::map<std::string,int>::const_iterator it=_families.find(fname);
978 if(it==_families.end())
980 for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
981 if((*it2).second==famId)
983 std::ostringstream oss;
984 oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !";
985 throw INTERP_KERNEL::Exception(oss.str().c_str());
987 _families[fname]=famId;
991 if((*it).second!=famId)
993 std::ostringstream oss;
994 oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !";
995 throw INTERP_KERNEL::Exception(oss.str().c_str());
1001 * Creates a group including all mesh entities of given dimension.
1002 * \warning This method does \b not guarantee that the created group includes mesh
1003 * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is
1004 * present in family fields of different dimensions. To assure this, call
1005 * ensureDifferentFamIdsPerLevel() \b before calling this method.
1006 * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to
1008 * \param [in] groupName - a name of the new group.
1009 * \throw If a group named \a groupName already exists.
1010 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh.
1011 * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh.
1013 void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName)
1015 std::string grpName(groupName);
1016 std::vector<int> levs=getNonEmptyLevelsExt();
1017 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
1019 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl;
1020 oss << "Available relative ext levels are : ";
1021 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1022 throw INTERP_KERNEL::Exception(oss.str().c_str());
1024 if(existsGroup(groupName))
1026 std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl;
1027 oss << "Already existing groups are : ";
1028 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," "));
1029 oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
1030 throw INTERP_KERNEL::Exception(oss.str().c_str());
1032 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
1034 throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
1035 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
1036 std::vector<std::string> familiesOnWholeGroup;
1037 for(const int *it=famIds->begin();it!=famIds->end();it++)
1040 familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
1042 _groups[grpName]=familiesOnWholeGroup;
1046 * Ensures that given family ids do not present in family fields of dimensions different
1047 * than given ones. If a family id is present in the family fields of dimensions different
1048 * than the given ones, a new family is created and the whole data is updated accordingly.
1049 * \param [in] famIds - a sequence of family ids to check.
1050 * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a
1051 * famIds should exclusively belong.
1052 * \return bool - \c true if no modification is done in \a this mesh by this method.
1054 bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
1056 std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
1057 std::vector<int> levs=getNonEmptyLevelsExt();
1058 std::set<int> levs2(levs.begin(),levs.end());
1059 std::vector<int> levsToTest;
1060 std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
1061 std::set<int> famIds2(famIds.begin(),famIds.end());
1064 if(!_families.empty())
1065 maxFamId=getMaxFamilyId()+1;
1066 std::vector<std::string> allFams=getFamiliesNames();
1067 for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
1069 const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
1072 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
1073 std::vector<int> tmp;
1074 std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
1075 for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
1078 std::string famName=getFamilyNameGivenId(*it2);
1079 std::ostringstream oss; oss << "Family_" << maxFamId;
1080 std::string zeName=CreateNameNotIn(oss.str(),allFams);
1081 addFamilyOnAllGroupsHaving(famName,zeName);
1082 _families[zeName]=maxFamId;
1083 (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
1092 * Adds a family to a given group in \a this mesh. If the group with a given name does
1093 * not exist, it is created.
1094 * \param [in] grpName - the name of the group to add the family in.
1095 * \param [in] famName - the name of the family to add to the group named \a grpName.
1096 * \throw If \a grpName or \a famName is an empty string.
1097 * \throw If no family named \a famName is present in \a this mesh.
1099 void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName)
1101 std::string grpn(grpName);
1102 std::string famn(famName);
1103 if(grpn.empty() || famn.empty())
1104 throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !");
1105 std::vector<std::string> fams=getFamiliesNames();
1106 if(std::find(fams.begin(),fams.end(),famn)==fams.end())
1108 std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl;
1109 oss << "Create this family or choose an existing one ! Existing fams are : ";
1110 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << ".";
1111 throw INTERP_KERNEL::Exception(oss.str().c_str());
1113 std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn);
1114 if(it==_groups.end())
1116 _groups[grpn].push_back(famn);
1120 std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn);
1121 if(it2==(*it).second.end())
1122 (*it).second.push_back(famn);
1127 * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'.
1128 * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families.
1129 * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method.
1131 void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName)
1133 std::string famNameCpp(famName);
1134 std::string otherCpp(otherFamName);
1135 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
1137 std::vector<std::string>& v=(*it).second;
1138 if(std::find(v.begin(),v.end(),famNameCpp)!=v.end())
1140 v.push_back(otherCpp);
1146 * \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).
1147 * \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)
1149 void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
1152 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
1153 std::string grpName(ids->getName());
1155 throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
1156 ids->checkStrictlyMonotonic(true);
1157 famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
1158 std::vector<std::string> grpsNames=getGroupsNames();
1159 if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
1161 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
1162 throw INTERP_KERNEL::Exception(oss.str().c_str());
1164 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
1165 allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
1166 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
1167 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
1168 std::vector<int> familyIds;
1169 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
1170 int maxVal=getTheMaxAbsFamilyId()+1;
1171 std::map<std::string,int> families(_families);
1172 std::map<std::string, std::vector<std::string> > groups(_groups);
1173 std::vector<std::string> fams;
1174 bool created(false);
1175 for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
1177 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
1178 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
1179 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
1180 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
1183 bool isFamPresent=false;
1184 for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
1185 isFamPresent=(*itl)->presenceOfValue(*famId);
1187 { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
1190 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2);
1191 std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created);
1192 fams.push_back(locFamName);
1193 if(existsFamily(*famId))
1195 std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName;
1196 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1199 } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal
1203 familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1
1204 familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1
1205 std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2);
1206 if(existsFamily(*famId))
1208 std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2;
1209 ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v);
1214 for(std::size_t i=0;i<familyIds.size();i++)
1216 DataArrayInt *da=idsPerfamiliyIds[i];
1217 famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
1221 _groups[grpName]=fams;
1224 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1226 ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames);
1229 void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
1231 std::string fam(familyNameToChange);
1232 for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++)
1234 std::vector<std::string>& fams((*it).second);
1235 std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam);
1239 fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end());
1245 * Returns a name of the family having a given id or, if no such a family exists, creates
1246 * a new uniquely named family and returns its name.
1247 * \param [in] id - the id of the family whose name is required.
1248 * \param [out] created - returns \c true if the new family has been created, \c false, else.
1249 * \return std::string - the name of the existing or the created family.
1250 * \throw If it is not possible to create a unique family name.
1252 std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
1254 return FindOrCreateAndGiveFamilyWithId(_families,id,created);
1258 * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId.
1259 * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false.
1260 * If there is no family whose family id is equal to 'id' a family is created with a name different from those
1261 * already existing. In this case 'created' will be returned with a value set to true, and internal state
1263 * This method will throws an exception if it is not possible to create a unique family name.
1265 std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
1267 std::vector<std::string> famAlreadyExisting(families.size());
1269 for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
1271 if((*it).second!=id)
1273 famAlreadyExisting[ii]=(*it).first;
1282 std::ostringstream oss; oss << "Family_" << id;
1283 std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting);
1289 * Sets names and ids of all families in \a this mesh.
1290 * \param [in] info - a map of a family name to a family id.
1292 void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
1298 * Sets names of all groups and families constituting them in \a this mesh.
1299 * \param [in] info - a map of a group name to a vector of names of families
1300 * constituting the group.
1302 void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info)
1308 * Returns an id of the family having a given name.
1309 * \param [in] name - the name of the family of interest.
1310 * \return int - the id of the family of interest.
1311 * \throw If no family with such a \a name exists.
1313 int MEDFileMesh::getFamilyId(const std::string& name) const
1315 std::string oname(name);
1316 std::map<std::string, int>::const_iterator it=_families.find(oname);
1317 std::vector<std::string> fams=getFamiliesNames();
1318 if(it==_families.end())
1320 std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
1321 std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
1322 throw INTERP_KERNEL::Exception(oss.str().c_str());
1324 return (*it).second;
1328 * Returns ids of the families having given names.
1329 * \param [in] fams - a sequence of the names of families of interest.
1330 * \return std::vector<int> - a sequence of the ids of families of interest.
1331 * \throw If \a fams contains a name of an inexistent family.
1333 std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
1335 std::vector<int> ret(fams.size());
1337 for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
1339 std::map<std::string, int>::const_iterator it2=_families.find(*it);
1340 if(it2==_families.end())
1342 std::vector<std::string> fams2=getFamiliesNames();
1343 std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :";
1344 std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," "));
1345 throw INTERP_KERNEL::Exception(oss.str().c_str());
1347 ret[i]=(*it2).second;
1353 * Returns a maximal abs(id) of families in \a this mesh.
1354 * \return int - the maximal norm of family id.
1355 * \throw If there are no families in \a this mesh.
1357 int MEDFileMesh::getMaxAbsFamilyId() const
1359 if(_families.empty())
1360 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1361 int ret=-std::numeric_limits<int>::max();
1362 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1364 ret=std::max(std::abs((*it).second),ret);
1370 * Returns a maximal id of families in \a this mesh.
1371 * \return int - the maximal family id.
1372 * \throw If there are no families in \a this mesh.
1374 int MEDFileMesh::getMaxFamilyId() const
1376 if(_families.empty())
1377 throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
1378 int ret=-std::numeric_limits<int>::max();
1379 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1381 ret=std::max((*it).second,ret);
1387 * Returns a minimal id of families in \a this mesh.
1388 * \return int - the minimal family id.
1389 * \throw If there are no families in \a this mesh.
1391 int MEDFileMesh::getMinFamilyId() const
1393 if(_families.empty())
1394 throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
1395 int ret=std::numeric_limits<int>::max();
1396 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1398 ret=std::min((*it).second,ret);
1404 * Returns a maximal id of families in \a this mesh. Not only named families are
1405 * considered but all family fields as well.
1406 * \return int - the maximal family id.
1408 int MEDFileMesh::getTheMaxAbsFamilyId() const
1410 int m1=-std::numeric_limits<int>::max();
1411 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1412 m1=std::max(std::abs((*it).second),m1);
1413 int m2=getMaxAbsFamilyIdInArrays();
1414 return std::max(m1,m2);
1418 * Returns a maximal id of families in \a this mesh. Not only named families are
1419 * considered but all family fields as well.
1420 * \return int - the maximal family id.
1422 int MEDFileMesh::getTheMaxFamilyId() const
1424 int m1=-std::numeric_limits<int>::max();
1425 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1426 m1=std::max((*it).second,m1);
1427 int m2=getMaxFamilyIdInArrays();
1428 return std::max(m1,m2);
1432 * Returns a minimal id of families in \a this mesh. Not only named families are
1433 * considered but all family fields as well.
1434 * \return int - the minimal family id.
1436 int MEDFileMesh::getTheMinFamilyId() const
1438 int m1=std::numeric_limits<int>::max();
1439 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1440 m1=std::min((*it).second,m1);
1441 int m2=getMinFamilyIdInArrays();
1442 return std::min(m1,m2);
1446 * This method only considers the maps. The contain of family array is ignored here.
1448 * \sa MEDFileMesh::computeAllFamilyIdsInUse
1450 DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
1452 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1454 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1455 v.insert((*it).second);
1456 ret->alloc((int)v.size(),1);
1457 std::copy(v.begin(),v.end(),ret->getPointer());
1462 * This method does not consider map of family name, family id. Only family field array on different levels is considered.
1464 * \sa MEDFileMesh::getAllFamiliesIdsReferenced
1466 DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
1468 std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
1469 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
1470 for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
1472 const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
1473 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
1474 if((DataArrayInt *) ret)
1475 ret=dv->buildUnion(ret);
1483 * true is returned if no modification has been needed. false if family
1484 * renumbering has been needed.
1486 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
1488 std::vector<int> levs=getNonEmptyLevelsExt();
1489 std::set<int> allFamIds;
1490 int maxId=getMaxFamilyId()+1;
1491 std::map<int,std::vector<int> > famIdsToRenum;
1492 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1494 const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
1497 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1499 std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
1501 famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
1503 std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
1506 if(famIdsToRenum.empty())
1508 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1509 for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
1511 DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
1512 int *famIdsToChange=fam->getPointer();
1513 std::map<int,int> ren;
1514 for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
1516 if(allIds->presenceOfValue(*it3))
1518 std::string famName=getFamilyNameGivenId(*it3);
1519 std::vector<std::string> grps=getGroupsOnFamily(famName);
1522 std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy);
1523 for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++)
1524 addFamilyOnGrp((*it4),newFam);
1527 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
1528 for(const int *id=ids->begin();id!=ids->end();id++)
1529 famIdsToChange[*id]=ren[famIdsToChange[*id]];
1535 * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH.
1536 * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0
1537 * This policy is those used by SMESH and Trio and that is the opposite of those in MED file.
1538 * This method will throw an exception if a same family id is detected in different level.
1539 * \warning This policy is the opposite of those in MED file documentation ...
1541 void MEDFileMesh::normalizeFamIdsTrio()
1543 ensureDifferentFamIdsPerLevel();
1544 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1545 std::vector<int> levs=getNonEmptyLevelsExt();
1546 std::set<int> levsS(levs.begin(),levs.end());
1547 std::set<std::string> famsFetched;
1548 std::map<std::string,int> families;
1549 if(std::find(levs.begin(),levs.end(),0)!=levs.end())
1552 const DataArrayInt *fam=getFamilyFieldAtLevel(0);
1556 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1557 std::map<int,int> ren;
1558 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1560 int nbOfTuples=fam->getNumberOfTuples();
1561 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1562 for(int *w=start;w!=start+nbOfTuples;w++)
1564 for(const int *it=tmp->begin();it!=tmp->end();it++)
1566 if(allIds->presenceOfValue(*it))
1568 std::string famName=getFamilyNameGivenId(*it);
1569 families[famName]=ren[*it];
1570 famsFetched.insert(famName);
1575 if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
1578 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
1582 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1583 std::map<int,int> ren;
1584 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1586 int nbOfTuples=fam->getNumberOfTuples();
1587 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1588 for(int *w=start;w!=start+nbOfTuples;w++)
1590 for(const int *it=tmp->begin();it!=tmp->end();it++)
1592 if(allIds->presenceOfValue(*it))
1594 std::string famName=getFamilyNameGivenId(*it);
1595 families[famName]=ren[*it];
1596 famsFetched.insert(famName);
1601 for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
1603 DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
1606 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1607 fam->fillWithZero();
1608 for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
1609 if(allIds->presenceOfValue(*it3))
1611 std::string famName=getFamilyNameGivenId(*it3);
1612 families[famName]=0;
1613 famsFetched.insert(famName);
1618 std::vector<std::string> allFams=getFamiliesNames();
1619 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1620 std::set<std::string> unFetchedIds;
1621 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1622 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1623 families[*it4]=_families[*it4];
1628 * This method normalizes fam id with the following policy.
1629 * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0
1630 * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio.
1631 * This method will throw an exception if a same family id is detected in different level.
1633 void MEDFileMesh::normalizeFamIdsMEDFile()
1635 ensureDifferentFamIdsPerLevel();
1636 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
1637 std::vector<int> levs=getNonEmptyLevelsExt();
1638 std::set<int> levsS(levs.begin(),levs.end());
1639 std::set<std::string> famsFetched;
1640 std::map<std::string,int> families;
1642 if(std::find(levs.begin(),levs.end(),1)!=levs.end())
1645 const DataArrayInt *fam=getFamilyFieldAtLevel(1);
1648 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1649 std::map<int,int> ren;
1650 for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
1652 int nbOfTuples=fam->getNumberOfTuples();
1653 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1654 for(int *w=start;w!=start+nbOfTuples;w++)
1656 for(const int *it=tmp->begin();it!=tmp->end();it++)
1658 if(allIds->presenceOfValue(*it))
1660 std::string famName=getFamilyNameGivenId(*it);
1661 families[famName]=ren[*it];
1662 famsFetched.insert(famName);
1668 for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
1670 const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
1673 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
1674 std::map<int,int> ren;
1675 for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
1677 int nbOfTuples=fam->getNumberOfTuples();
1678 int *start=const_cast<DataArrayInt *>(fam)->getPointer();
1679 for(int *w=start;w!=start+nbOfTuples;w++)
1681 for(const int *it=tmp->begin();it!=tmp->end();it++)
1683 if(allIds->presenceOfValue(*it))
1685 std::string famName=getFamilyNameGivenId(*it);
1686 families[famName]=ren[*it];
1687 famsFetched.insert(famName);
1693 std::vector<std::string> allFams=getFamiliesNames();
1694 std::set<std::string> allFamsS(allFams.begin(),allFams.end());
1695 std::set<std::string> unFetchedIds;
1696 std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end()));
1697 for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++)
1698 families[*it4]=_families[*it4];
1703 * Returns a name of the family by its id. If there are several families having the given
1704 * id, the name first in lexical order is returned.
1705 * \param [in] id - the id of the family whose name is required.
1706 * \return std::string - the name of the found family.
1707 * \throw If no family with the given \a id exists.
1709 std::string MEDFileMesh::getFamilyNameGivenId(int id) const
1711 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
1712 if((*it).second==id)
1714 std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
1715 throw INTERP_KERNEL::Exception(oss.str().c_str());
1719 * Returns a string describing \a this mesh. This description includes the mesh name and
1720 * the mesh description string.
1721 * \return std::string - the mesh information string.
1723 std::string MEDFileMesh::simpleRepr() const
1725 std::ostringstream oss;
1726 oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n";
1727 oss << "- Name of the mesh : <<" << getName() << ">>\n";
1728 oss << "- Description associated to the mesh : " << getDescription() << std::endl;
1733 * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
1734 * an empty one is created.
1736 DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
1738 DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
1741 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New());
1742 arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
1743 arr->fillWithZero();
1744 setFamilyFieldArr(meshDimRelToMaxExt,arr);
1745 return getFamilyFieldAtLevel(meshDimRelToMaxExt);
1749 * Returns ids of mesh entities contained in a given group of a given dimension.
1750 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1752 * \param [in] grp - the name of the group of interest.
1753 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1754 * returned instead of ids.
1755 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1756 * numbers, if available and required, of mesh entities of the group. The caller
1757 * is to delete this array using decrRef() as it is no more needed.
1758 * \throw If the name of a nonexistent group is specified.
1759 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1761 DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
1763 std::vector<std::string> tmp(1);
1765 DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
1771 * Returns ids of mesh entities contained in given groups of a given dimension.
1772 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1774 * \param [in] grps - the names of the groups of interest.
1775 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1776 * returned instead of ids.
1777 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1778 * numbers, if available and required, of mesh entities of the groups. The caller
1779 * is to delete this array using decrRef() as it is no more needed.
1780 * \throw If the name of a nonexistent group is present in \a grps.
1781 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1783 DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
1785 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
1786 return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
1790 * Returns ids of mesh entities contained in a given family of a given dimension.
1791 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
1793 * \param [in] fam - the name of the family of interest.
1794 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
1795 * returned instead of ids.
1796 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1797 * numbers, if available and required, of mesh entities of the family. The caller
1798 * is to delete this array using decrRef() as it is no more needed.
1799 * \throw If the family field is missing for \a meshDimRelToMaxExt.
1801 DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
1803 std::vector<std::string> tmp(1);
1805 DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
1811 * Returns ids of nodes contained in a given group.
1812 * \param [in] grp - the name of the group of interest.
1813 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1814 * returned instead of ids.
1815 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1816 * numbers, if available and required, of nodes of the group. The caller
1817 * is to delete this array using decrRef() as it is no more needed.
1818 * \throw If the name of a nonexistent group is specified.
1819 * \throw If the family field is missing for nodes.
1821 DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
1823 std::vector<std::string> tmp(1);
1825 DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
1831 * Returns ids of nodes contained in given groups.
1832 * \param [in] grps - the names of the groups of interest.
1833 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1834 * returned instead of ids.
1835 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1836 * numbers, if available and required, of nodes of the groups. The caller
1837 * is to delete this array using decrRef() as it is no more needed.
1838 * \throw If the name of a nonexistent group is present in \a grps.
1839 * \throw If the family field is missing for nodes.
1841 DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
1843 return getGroupsArr(1,grps,renum);
1847 * Returns ids of nodes contained in a given group.
1848 * \param [in] grp - the name of the group of interest.
1849 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1850 * returned instead of ids.
1851 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1852 * numbers, if available and required, of nodes of the group. The caller
1853 * is to delete this array using decrRef() as it is no more needed.
1854 * \throw If the name of a nonexistent group is specified.
1855 * \throw If the family field is missing for nodes.
1857 DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
1859 std::vector<std::string> tmp(1);
1861 DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
1867 * Returns ids of nodes contained in given families.
1868 * \param [in] fams - the names of the families of interest.
1869 * \param [in] renum - if \c true, the optional numbers of nodes, if available, are
1870 * returned instead of ids.
1871 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
1872 * numbers, if available and required, of nodes of the families. The caller
1873 * is to delete this array using decrRef() as it is no more needed.
1874 * \throw If the family field is missing for nodes.
1876 DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
1878 return getFamiliesArr(1,fams,renum);
1882 * Adds groups of given dimension and creates corresponding families and family fields
1883 * given ids of mesh entities of each group.
1884 * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities.
1885 * \param [in] grps - a sequence of arrays of ids each describing a group.
1886 * \param [in] renum - \c true means that \a grps contains not ids but optional numbers
1888 * \throw If names of some groups in \a grps are equal.
1889 * \throw If \a grps includes a group with an empty name.
1890 * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
1891 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
1893 void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
1897 std::set<std::string> grpsName;
1898 std::vector<std::string> grpsName2(grps.size());
1901 for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
1903 grpsName.insert((*it)->getName());
1904 grpsName2[i]=(*it)->getName();
1906 if(grpsName.size()!=grps.size())
1907 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
1908 if(grpsName.find(std::string(""))!=grpsName.end())
1909 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
1910 int sz=getSizeAtLevel(meshDimRelToMaxExt);
1911 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
1912 std::vector< std::vector<int> > fidsOfGroups;
1915 fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
1919 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
1920 for(unsigned int ii=0;ii<grps.size();ii++)
1922 grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
1923 grps2[ii]->setName(grps[ii]->getName());
1925 std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
1926 fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
1929 if(!_families.empty())
1930 offset=getMaxAbsFamilyId()+1;
1931 TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
1932 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
1933 appendFamilyEntries(ids,fidsOfGroups,grpsName2);
1934 setFamilyFieldArr(meshDimRelToMaxExt,fam);
1938 * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids
1939 * not in '_families'. Groups information are given in parameters in order to give to families representative names.
1940 * For the moment, the two last input parameters are not taken into account.
1942 void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
1944 std::map<int,std::string> famInv;
1945 for(const int *it=famIds->begin();it!=famIds->end();it++)
1947 std::ostringstream oss;
1948 oss << "Family_" << (*it);
1949 _families[oss.str()]=(*it);
1950 famInv[*it]=oss.str();
1953 for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
1955 for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
1957 _groups[grpNames[i]].push_back(famInv[*it2]);
1962 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const
1964 std::vector<int> levs(getNonEmptyLevels());
1965 std::vector<INTERP_KERNEL::NormalizedCellType> ret;
1966 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
1968 std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it));
1969 ret.insert(ret.end(),elts.begin(),elts.end());
1974 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
1976 MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
1977 return mLev->getDistributionOfTypes();
1980 void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
1982 famArr->applyLin(offset>0?1:-1,offset,0);
1983 for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
1986 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
1987 std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
1992 * Warning no check is done on 'nameTry' in parameter. It should be non empty.
1993 * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'.
1994 * If this method fails to find such a name it will throw an exception.
1996 std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid)
1999 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end())
2002 std::size_t len=nameTry.length();
2003 for(std::size_t ii=1;ii<len;ii++)
2005 std::string tmp=nameTry.substr(ii,len-ii);
2006 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end())
2012 for(std::size_t i=1;i<30;i++)
2014 std::string tmp1(nameTry.at(0),i);
2016 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end())
2022 for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++)
2024 if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end())
2026 throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
2029 int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
2031 std::size_t nbOfChunks=code.size()/3;
2032 if(code.size()%3!=0)
2033 throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
2035 for(std::size_t i=0;i<nbOfChunks;i++)
2044 * This method should be called by any set* method of subclasses to deal automatically with _name attribute.
2045 * If _name attribute is empty the name of 'm' if taken as _name attribute.
2046 * If _name is not empty and that 'm' has the same name nothing is done.
2047 * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown.
2049 void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
2052 throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !");
2057 std::string name(m->getName());
2062 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '";
2063 oss << name << "' ! Names must match !";
2064 throw INTERP_KERNEL::Exception(oss.str().c_str());
2068 if(_desc_name.empty())
2069 _desc_name=m->getDescription();
2072 std::string name(m->getDescription());
2075 if(_desc_name!=name)
2077 std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '";
2078 oss << name << "' ! Names must match !";
2079 throw INTERP_KERNEL::Exception(oss.str().c_str());
2085 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
2087 oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
2088 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
2090 oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
2091 oss << " - Groups lying on this family : ";
2092 std::vector<std::string> grps=getGroupsOnFamily((*it).first);
2093 std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
2094 oss << std::endl << std::endl;
2099 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2100 * file. The mesh to load is specified by its name and numbers of a time step and an
2102 * \param [in] fileName - the name of MED file to read.
2103 * \param [in] mName - the name of the mesh to read.
2104 * \param [in] dt - the number of a time step.
2105 * \param [in] it - the number of an iteration.
2106 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2107 * mesh using decrRef() as it is no more needed.
2108 * \throw If the file is not readable.
2109 * \throw If there is no mesh with given attributes in the file.
2110 * \throw If the mesh in the file is not an unstructured one.
2112 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2114 MEDFileUtilities::CheckFileForRead(fileName);
2115 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2116 return new MEDFileUMesh(fid,mName,dt,it,mrs);
2120 * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED
2121 * file. The first mesh in the file is loaded.
2122 * \param [in] fileName - the name of MED file to read.
2123 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2124 * mesh using decrRef() as it is no more needed.
2125 * \throw If the file is not readable.
2126 * \throw If there is no meshes in the file.
2127 * \throw If the mesh in the file is not an unstructured one.
2129 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
2131 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
2134 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
2135 throw INTERP_KERNEL::Exception(oss.str().c_str());
2137 MEDFileUtilities::CheckFileForRead(fileName);
2138 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
2140 ParaMEDMEM::MEDCouplingMeshType meshType;
2142 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
2143 return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
2147 * Returns an empty instance of MEDFileUMesh.
2148 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this
2149 * mesh using decrRef() as it is no more needed.
2151 MEDFileUMesh *MEDFileUMesh::New()
2153 return new MEDFileUMesh;
2157 * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
2158 * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
2159 * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh.
2160 * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce
2161 * at most the memory consumtion.
2163 * \param [in] fileName - the name of the file.
2164 * \param [in] mName - the name of the mesh to be read.
2165 * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most.
2166 * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
2167 * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
2168 * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
2169 * \param [in] mrs - the request for what to be loaded.
2170 * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
2172 MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2174 MEDFileUtilities::CheckFileForRead(fileName);
2175 MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
2176 return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
2180 * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
2181 * This method is \b NOT wrapped into python.
2183 MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2185 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
2186 ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
2190 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
2192 std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
2193 ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
2197 std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const
2199 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
2200 ret.push_back((const DataArrayDouble*)_coords);
2201 ret.push_back((const DataArrayInt *)_fam_coords);
2202 ret.push_back((const DataArrayInt *)_num_coords);
2203 ret.push_back((const DataArrayInt *)_rev_num_coords);
2204 ret.push_back((const DataArrayAsciiChar *)_name_coords);
2205 ret.push_back((const PartDefinition *)_part_coords);
2206 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2207 ret.push_back((const MEDFileUMeshSplitL1*) *it);
2211 MEDFileMesh *MEDFileUMesh::shallowCpy() const
2213 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2217 MEDFileMesh *MEDFileUMesh::createNewEmpty() const
2219 return new MEDFileUMesh;
2222 MEDFileMesh *MEDFileUMesh::deepCpy() const
2224 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
2225 if((const DataArrayDouble*)_coords)
2226 ret->_coords=_coords->deepCpy();
2227 if((const DataArrayInt*)_fam_coords)
2228 ret->_fam_coords=_fam_coords->deepCpy();
2229 if((const DataArrayInt*)_num_coords)
2230 ret->_num_coords=_num_coords->deepCpy();
2231 if((const DataArrayInt*)_rev_num_coords)
2232 ret->_rev_num_coords=_rev_num_coords->deepCpy();
2233 if((const DataArrayAsciiChar*)_name_coords)
2234 ret->_name_coords=_name_coords->deepCpy();
2236 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
2238 if((const MEDFileUMeshSplitL1 *)(*it))
2239 ret->_ms[i]=(*it)->deepCpy(ret->_coords);
2241 if((const PartDefinition*)_part_coords)
2242 ret->_part_coords=_part_coords->deepCpy();
2247 * Checks if \a this and another mesh are equal.
2248 * \param [in] other - the mesh to compare with.
2249 * \param [in] eps - a precision used to compare real values.
2250 * \param [in,out] what - the string returning description of unequal data.
2251 * \return bool - \c true if the meshes are equal, \c false, else.
2253 bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
2255 if(!MEDFileMesh::isEqual(other,eps,what))
2257 const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other);
2260 what="Mesh types differ ! This is unstructured and other is NOT !";
2263 clearNonDiscrAttributes();
2264 otherC->clearNonDiscrAttributes();
2265 const DataArrayDouble *coo1=_coords;
2266 const DataArrayDouble *coo2=otherC->_coords;
2267 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
2269 what="Mismatch of coordinates ! One is defined and not other !";
2274 bool ret=coo1->isEqual(*coo2,eps);
2277 what="Coords differ !";
2281 const DataArrayInt *famc1=_fam_coords;
2282 const DataArrayInt *famc2=otherC->_fam_coords;
2283 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
2285 what="Mismatch of families arr on nodes ! One is defined and not other !";
2290 bool ret=famc1->isEqual(*famc2);
2293 what="Families arr on node differ !";
2297 const DataArrayInt *numc1=_num_coords;
2298 const DataArrayInt *numc2=otherC->_num_coords;
2299 if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
2301 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
2306 bool ret=numc1->isEqual(*numc2);
2309 what="Numbering arr on node differ !";
2313 const DataArrayAsciiChar *namec1=_name_coords;
2314 const DataArrayAsciiChar *namec2=otherC->_name_coords;
2315 if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
2317 what="Mismatch of naming arr on nodes ! One is defined and not other !";
2322 bool ret=namec1->isEqual(*namec2);
2325 what="Names arr on node differ !";
2329 if(_ms.size()!=otherC->_ms.size())
2331 what="Number of levels differs !";
2334 std::size_t sz=_ms.size();
2335 for(std::size_t i=0;i<sz;i++)
2337 const MEDFileUMeshSplitL1 *s1=_ms[i];
2338 const MEDFileUMeshSplitL1 *s2=otherC->_ms[i];
2339 if((s1==0 && s2!=0) || (s1!=0 && s2==0))
2341 what="Mismatch of presence of sub levels !";
2346 bool ret=s1->isEqual(s2,eps,what);
2351 const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords);
2354 if((!pd0 && pd1) || (pd0 && !pd1))
2356 what=std::string("node part def is defined only for one among this or other !");
2359 return pd0->isEqual(pd1,what);
2363 * Clears redundant attributes of incorporated data arrays.
2365 void MEDFileUMesh::clearNonDiscrAttributes() const
2367 MEDFileMesh::clearNonDiscrAttributes();
2368 const DataArrayDouble *coo1=_coords;
2370 (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
2371 const DataArrayInt *famc1=_fam_coords;
2373 (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
2374 const DataArrayInt *numc1=_num_coords;
2376 (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
2377 const DataArrayAsciiChar *namc1=_name_coords;
2379 (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
2380 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2382 const MEDFileUMeshSplitL1 *tmp=(*it);
2384 tmp->clearNonDiscrAttributes();
2388 void MEDFileUMesh::setName(const std::string& name)
2390 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
2391 if((MEDFileUMeshSplitL1 *)(*it)!=0)
2392 (*it)->setName(name);
2393 MEDFileMesh::setName(name);
2396 MEDFileUMesh::MEDFileUMesh()
2400 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2403 loadUMeshFromFile(fid,mName,dt,it,mrs);
2405 catch(INTERP_KERNEL::Exception& e)
2411 * This method loads only a part of specified cells (given by range of cell ID per geometric type)
2412 * See MEDFileUMesh::LoadPartOf for detailed description.
2414 * \sa loadUMeshFromFile
2416 void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
2418 MEDFileUMeshL2 loaderl2;
2419 ParaMEDMEM::MEDCouplingMeshType meshType;
2422 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2423 if(meshType!=UNSTRUCTURED)
2425 std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2426 throw INTERP_KERNEL::Exception(oss.str().c_str());
2428 loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
2429 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2433 * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
2435 * \sa loadPartUMeshFromFile
2437 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
2439 MEDFileUMeshL2 loaderl2;
2440 ParaMEDMEM::MEDCouplingMeshType meshType;
2443 int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
2444 if(meshType!=UNSTRUCTURED)
2446 std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
2447 throw INTERP_KERNEL::Exception(oss.str().c_str());
2449 loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
2450 dispatchLoadedPart(fid,loaderl2,mName,mrs);
2454 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
2456 int lev=loaderl2.getNumberOfLevels();
2458 for(int i=0;i<lev;i++)
2460 if(!loaderl2.emptyLev(i))
2461 _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i);
2465 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
2467 setName(loaderl2.getName());
2468 setDescription(loaderl2.getDescription());
2469 setUnivName(loaderl2.getUnivName());
2470 setIteration(loaderl2.getIteration());
2471 setOrder(loaderl2.getOrder());
2472 setTimeValue(loaderl2.getTime());
2473 setTimeUnit(loaderl2.getTimeUnit());
2474 _coords=loaderl2.getCoords();
2475 if(!mrs || mrs->isNodeFamilyFieldReading())
2476 _fam_coords=loaderl2.getCoordsFamily();
2477 if(!mrs || mrs->isNodeNumFieldReading())
2478 _num_coords=loaderl2.getCoordsNum();
2479 if(!mrs || mrs->isNodeNameFieldReading())
2480 _name_coords=loaderl2.getCoordsName();
2481 _part_coords=loaderl2.getPartDefOfCoo();
2485 MEDFileUMesh::~MEDFileUMesh()
2489 void MEDFileUMesh::writeLL(med_idt fid) const
2491 const DataArrayDouble *coo=_coords;
2492 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
2493 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
2494 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
2495 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
2496 int spaceDim=coo?coo->getNumberOfComponents():0;
2499 mdim=getMeshDimension();
2500 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2501 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
2502 for(int i=0;i<spaceDim;i++)
2504 std::string info=coo->getInfoOnComponent(i);
2506 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
2507 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
2508 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
2510 MEDmeshCr(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
2511 MEDmeshUniversalNameWr(fid,maa);
2512 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
2513 MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
2514 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2515 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2516 (*it)->write(fid,meshName,mdim);
2517 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
2521 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
2522 * \return std::vector<int> - a sequence of the relative dimensions.
2524 std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
2526 std::vector<int> ret;
2528 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2529 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2536 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
2537 * \return std::vector<int> - a sequence of the relative dimensions.
2539 std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
2541 std::vector<int> ret0=getNonEmptyLevels();
2542 if((const DataArrayDouble *) _coords)
2544 std::vector<int> ret(ret0.size()+1);
2546 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2552 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
2554 std::vector<int> ret;
2555 const DataArrayInt *famCoo(_fam_coords);
2559 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2561 const MEDFileUMeshSplitL1 *cur(*it);
2563 if(cur->getFamilyField())
2569 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
2571 std::vector<int> ret;
2572 const DataArrayInt *numCoo(_num_coords);
2576 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2578 const MEDFileUMeshSplitL1 *cur(*it);
2580 if(cur->getNumberField())
2586 std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
2588 std::vector<int> ret;
2589 const DataArrayAsciiChar *nameCoo(_name_coords);
2593 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
2595 const MEDFileUMeshSplitL1 *cur(*it);
2597 if(cur->getNameField())
2604 * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
2605 * To include nodes, call getGrpNonEmptyLevelsExt() method.
2606 * \param [in] grp - the name of the group of interest.
2607 * \return std::vector<int> - a sequence of the relative dimensions.
2609 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
2611 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2612 return getFamsNonEmptyLevels(fams);
2616 * Returns all relative mesh levels (including nodes) where a given group is defined.
2617 * \param [in] grp - the name of the group of interest.
2618 * \return std::vector<int> - a sequence of the relative dimensions.
2620 std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
2622 std::vector<std::string> fams=getFamiliesOnGroup(grp);
2623 return getFamsNonEmptyLevelsExt(fams);
2627 * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
2628 * To include nodes, call getFamNonEmptyLevelsExt() method.
2629 * \param [in] fam - the name of the family of interest.
2630 * \return std::vector<int> - a sequence of the relative dimensions.
2632 std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
2634 std::vector<std::string> fams(1,std::string(fam));
2635 return getFamsNonEmptyLevels(fams);
2639 * Returns all relative mesh levels (including nodes) where a given family is defined.
2640 * \param [in] fam - the name of the family of interest.
2641 * \return std::vector<int> - a sequence of the relative dimensions.
2643 std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
2645 std::vector<std::string> fams(1,std::string(fam));
2646 return getFamsNonEmptyLevelsExt(fams);
2650 * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
2651 * To include nodes, call getGrpsNonEmptyLevelsExt() method.
2652 * \param [in] grps - a sequence of names of the groups of interest.
2653 * \return std::vector<int> - a sequence of the relative dimensions.
2655 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
2657 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2658 return getFamsNonEmptyLevels(fams);
2662 * Returns all relative mesh levels (including nodes) where given groups are defined.
2663 * \param [in] grps - a sequence of names of the groups of interest.
2664 * \return std::vector<int> - a sequence of the relative dimensions.
2666 std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
2668 std::vector<std::string> fams=getFamiliesOnGroups(grps);
2669 return getFamsNonEmptyLevelsExt(fams);
2673 * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
2674 * To include nodes, call getFamsNonEmptyLevelsExt() method.
2675 * \param [in] fams - the name of the family of interest.
2676 * \return std::vector<int> - a sequence of the relative dimensions.
2678 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
2680 std::vector<int> ret;
2681 std::vector<int> levs=getNonEmptyLevels();
2682 std::vector<int> famIds=getFamiliesIds(fams);
2683 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
2684 if(_ms[-(*it)]->presenceOfOneFams(famIds))
2690 * Returns all relative mesh levels (including nodes) where given families are defined.
2691 * \param [in] fams - the names of the families of interest.
2692 * \return std::vector<int> - a sequence of the relative dimensions.
2694 std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
2696 std::vector<int> ret0=getFamsNonEmptyLevels(fams);
2697 const DataArrayInt *famCoords=_fam_coords;
2700 std::vector<int> famIds=getFamiliesIds(fams);
2701 if(famCoords->presenceOfValue(famIds))
2703 std::vector<int> ret(ret0.size()+1);
2705 std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
2713 * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
2714 * \param [in] meshDimRelToMaxExt - a relative dimension of interest.
2715 * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
2718 std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
2720 std::vector<std::string> ret;
2721 std::vector<std::string> allGrps=getGroupsNames();
2722 for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
2724 std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
2725 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
2731 int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
2733 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2734 if((const DataArrayInt *)_fam_coords)
2736 int val=_fam_coords->getMaxValue(tmp);
2737 ret=std::max(ret,std::abs(val));
2739 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2741 if((const MEDFileUMeshSplitL1 *)(*it))
2743 const DataArrayInt *da=(*it)->getFamilyField();
2746 int val=da->getMaxValue(tmp);
2747 ret=std::max(ret,std::abs(val));
2754 int MEDFileUMesh::getMaxFamilyIdInArrays() const
2756 int ret=-std::numeric_limits<int>::max(),tmp=-1;
2757 if((const DataArrayInt *)_fam_coords)
2759 int val=_fam_coords->getMaxValue(tmp);
2760 ret=std::max(ret,val);
2762 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2764 if((const MEDFileUMeshSplitL1 *)(*it))
2766 const DataArrayInt *da=(*it)->getFamilyField();
2769 int val=da->getMaxValue(tmp);
2770 ret=std::max(ret,val);
2777 int MEDFileUMesh::getMinFamilyIdInArrays() const
2779 int ret=std::numeric_limits<int>::max(),tmp=-1;
2780 if((const DataArrayInt *)_fam_coords)
2782 int val=_fam_coords->getMinValue(tmp);
2783 ret=std::min(ret,val);
2785 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
2787 if((const MEDFileUMeshSplitL1 *)(*it))
2789 const DataArrayInt *da=(*it)->getFamilyField();
2792 int val=da->getMinValue(tmp);
2793 ret=std::min(ret,val);
2801 * Returns the dimension on cells in \a this mesh.
2802 * \return int - the mesh dimension.
2803 * \throw If there are no cells in this mesh.
2805 int MEDFileUMesh::getMeshDimension() const
2808 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
2809 if((const MEDFileUMeshSplitL1 *)(*it)!=0)
2810 return (*it)->getMeshDimension()+lev;
2811 throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
2815 * Returns the space dimension of \a this mesh that is equal to number of components in
2816 * the node coordinates array.
2817 * \return int - the space dimension of \a this mesh.
2818 * \throw If the node coordinates array is not available.
2820 int MEDFileUMesh::getSpaceDimension() const
2822 const DataArrayDouble *coo=_coords;
2824 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
2825 return coo->getNumberOfComponents();
2829 * Returns a string describing \a this mesh.
2830 * \return std::string - the mesh information string.
2832 std::string MEDFileUMesh::simpleRepr() const
2834 std::ostringstream oss;
2835 oss << MEDFileMesh::simpleRepr();
2836 const DataArrayDouble *coo=_coords;
2837 oss << "- The dimension of the space is ";
2838 static const char MSG1[]= "*** NO COORDS SET ***";
2839 static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***";
2841 oss << _coords->getNumberOfComponents() << std::endl;
2843 oss << MSG1 << std::endl;
2844 oss << "- Type of the mesh : UNSTRUCTURED\n";
2845 oss << "- Number of nodes : ";
2847 oss << _coords->getNumberOfTuples() << std::endl;
2849 oss << MSG1 << std::endl;
2850 std::size_t nbOfLev=_ms.size();
2851 oss << "- Number of levels allocated : " << nbOfLev << std::endl;
2852 for(std::size_t i=0;i<nbOfLev;i++)
2854 const MEDFileUMeshSplitL1 *lev=_ms[i];
2855 oss << " - Level #" << -((int) i) << " has dimension : ";
2858 oss << lev->getMeshDimension() << std::endl;
2859 lev->simpleRepr(oss);
2862 oss << MSG2 << std::endl;
2864 oss << "- Number of families : " << _families.size() << std::endl << std::endl;
2867 oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n";
2868 oss << "- Names of coordinates :" << std::endl;
2869 std::vector<std::string> vars=coo->getVarsOnComponent();
2870 std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," "));
2871 oss << std::endl << "- Units of coordinates : " << std::endl;
2872 std::vector<std::string> units=coo->getUnitsOnComponent();
2873 std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," "));
2875 oss << std::endl << std::endl;
2881 * Returns a full textual description of \a this mesh.
2882 * \return std::string - the string holding the mesh description.
2884 std::string MEDFileUMesh::advancedRepr() const
2886 return simpleRepr();
2890 * Returns number of mesh entities of a given relative dimension in \a this mesh.
2891 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
2892 * \return int - the number of entities.
2893 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
2895 int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
2897 if(meshDimRelToMaxExt==1)
2899 if(!((const DataArrayDouble *)_coords))
2900 throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !");
2901 return _coords->getNumberOfTuples();
2903 return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize();
2907 * Returns the family field for mesh entities of a given dimension.
2908 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2909 * \return const DataArrayInt * - the family field. It is an array of ids of families
2910 * each mesh entity belongs to. It can be \c NULL.
2912 const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
2914 if(meshDimRelToMaxExt==1)
2916 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2917 return l1->getFamilyField();
2920 DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
2922 if(meshDimRelToMaxExt==1)
2924 MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2925 return l1->getFamilyField();
2929 * Returns the optional numbers of mesh entities of a given dimension.
2930 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
2931 * \return const DataArrayInt * - the array of the entity numbers.
2932 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
2934 const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
2936 if(meshDimRelToMaxExt==1)
2938 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2939 return l1->getNumberField();
2942 const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
2944 if(meshDimRelToMaxExt==1)
2945 return _name_coords;
2946 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
2947 return l1->getNameField();
2951 * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file).
2953 * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested.
2954 * \param [in] gt - The input geometric type for which the part definition is requested.
2955 * \return the part definition owned by \a this. So no need to deallocate the returned instance.
2957 const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const
2959 if(meshDimRelToMaxExt==1)
2960 return _part_coords;
2961 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2962 return l1->getPartDef(gt);
2965 int MEDFileUMesh::getNumberOfNodes() const
2967 const DataArrayDouble *coo(_coords);
2969 throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !");
2970 return coo->getNumberOfTuples();
2973 int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
2975 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
2976 return l1->getNumberOfCells();
2979 bool MEDFileUMesh::hasImplicitPart() const
2984 int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
2986 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
2989 void MEDFileUMesh::releaseImplicitPartIfAny() const
2993 void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
2995 std::size_t sz(st.getNumberOfItems());
2996 for(std::size_t i=0;i<sz;i++)
2998 INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo());
2999 const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt));
3000 if(st[i].getPflName().empty())
3001 m->computeNodeIdsAlg(nodesFetched);
3004 const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
3005 MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
3006 m2->computeNodeIdsAlg(nodesFetched);
3012 * Returns the optional numbers of mesh entities of a given dimension transformed using
3013 * DataArrayInt::invertArrayN2O2O2N().
3014 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
3015 * \return const DataArrayInt * - the array of the entity numbers transformed using
3016 * DataArrayInt::invertArrayN2O2O2N().
3017 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3019 const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
3021 if(meshDimRelToMaxExt==1)
3023 if(!((const DataArrayInt *)_num_coords))
3024 throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
3025 return _rev_num_coords;
3027 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3028 return l1->getRevNumberField();
3032 * Returns a pointer to the node coordinates array of \a this mesh \b without
3033 * incrementing its reference counter, thus there is no need to decrRef() it by the caller.
3035 DataArrayDouble *MEDFileUMesh::getCoords() const
3037 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
3038 if((DataArrayDouble *)tmp)
3046 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3047 * group of \a this mesh. Only mesh entities of a given dimension are included in the
3049 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3050 * \param [in] grp - the name of the group whose mesh entities are included in the
3052 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3053 * according to the optional numbers of entities, if available.
3054 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3055 * delete this mesh using decrRef() as it is no more needed.
3056 * \throw If the name of a nonexistent group is specified.
3057 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3059 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
3061 synchronizeTinyInfoOnLeaves();
3062 std::vector<std::string> tmp(1);
3064 return getGroups(meshDimRelToMaxExt,tmp,renum);
3068 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3069 * groups of \a this mesh. Only mesh entities of a given dimension are included in the
3071 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3072 * \param [in] grps - a sequence of group names whose mesh entities are included in the
3074 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3075 * according to the optional numbers of entities, if available.
3076 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3077 * delete this mesh using decrRef() as it is no more needed.
3078 * \throw If a name of a nonexistent group is present in \a grps.
3079 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3081 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
3083 synchronizeTinyInfoOnLeaves();
3084 std::vector<std::string> fams2=getFamiliesOnGroups(grps);
3085 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
3086 if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
3087 zeRet->setName(grps[0]);
3088 return zeRet.retn();
3092 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given
3093 * family of \a this mesh. Only mesh entities of a given dimension are included in the
3095 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3096 * \param [in] fam - the name of the family whose mesh entities are included in the
3098 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3099 * according to the optional numbers of entities, if available.
3100 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3101 * delete this mesh using decrRef() as it is no more needed.
3102 * \throw If a name of a nonexistent family is present in \a grps.
3103 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3105 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
3107 synchronizeTinyInfoOnLeaves();
3108 std::vector<std::string> tmp(1);
3110 return getFamilies(meshDimRelToMaxExt,tmp,renum);
3114 * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given
3115 * families of \a this mesh. Only mesh entities of a given dimension are included in the
3117 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest.
3118 * \param [in] fams - a sequence of family names whose mesh entities are included in the
3120 * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted
3121 * according to the optional numbers of entities, if available.
3122 * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to
3123 * delete this mesh using decrRef() as it is no more needed.
3124 * \throw If a name of a nonexistent family is present in \a fams.
3125 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3127 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3129 synchronizeTinyInfoOnLeaves();
3130 if(meshDimRelToMaxExt==1)
3132 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
3133 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
3134 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
3138 std::vector<int> famIds=getFamiliesIds(fams);
3139 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3140 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
3142 zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
3144 zeRet=l1->getFamilyPart(0,0,renum);
3145 if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet))
3146 zeRet->setName(fams[0]);
3147 return zeRet.retn();
3151 * Returns ids of mesh entities contained in given families of a given dimension.
3152 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
3154 * \param [in] fams - the names of the families of interest.
3155 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
3156 * returned instead of ids.
3157 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
3158 * numbers, if available and required, of mesh entities of the families. The caller
3159 * is to delete this array using decrRef() as it is no more needed.
3160 * \throw If the family field is missing for \a meshDimRelToMaxExt.
3162 DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
3164 std::vector<int> famIds=getFamiliesIds(fams);
3165 if(meshDimRelToMaxExt==1)
3167 if((const DataArrayInt *)_fam_coords)
3169 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
3171 da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
3173 da=_fam_coords->getIdsEqualList(0,0);
3175 return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
3180 throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !");
3182 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3184 return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum);
3186 return l1->getFamilyPartArr(0,0,renum);
3190 * Returns a MEDCouplingUMesh of a given relative dimension.
3191 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3192 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3193 * To build a valid MEDCouplingUMesh from the returned one in this case,
3194 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3195 * \param [in] meshDimRelToMax - the relative dimension of interest.
3196 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3197 * optional numbers of mesh entities.
3198 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3199 * delete using decrRef() as it is no more needed.
3200 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3201 * \sa getGenMeshAtLevel()
3203 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
3205 synchronizeTinyInfoOnLeaves();
3206 if(meshDimRelToMaxExt==1)
3210 MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
3211 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
3212 umesh->setCoords(cc);
3213 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
3214 umesh->setName(getName());
3218 const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3219 return l1->getWholeMesh(renum);
3223 * Returns a MEDCouplingUMesh of a given relative dimension.
3224 * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
3225 * valid**. This is a feature, because MEDLoader does not create cells that do not exist!
3226 * To build a valid MEDCouplingUMesh from the returned one in this case,
3227 * call MEDCouplingUMesh::Build0DMeshFromCoords().
3228 * \param [in] meshDimRelToMax - the relative dimension of interest.
3229 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3230 * optional numbers of mesh entities.
3231 * \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
3232 * delete using decrRef() as it is no more needed.
3233 * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
3234 * \sa getMeshAtLevel()
3236 MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
3238 return getMeshAtLevel(meshDimRelToMax,renum);
3241 std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
3243 const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
3244 return l1->getDistributionOfTypes();
3248 * Returns a MEDCouplingUMesh of a relative dimension == 0.
3249 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3250 * optional numbers of mesh entities.
3251 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3252 * delete using decrRef() as it is no more needed.
3253 * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh.
3255 MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const
3257 return getMeshAtLevel(0,renum);
3261 * Returns a MEDCouplingUMesh of a relative dimension == -1.
3262 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3263 * optional numbers of mesh entities.
3264 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3265 * delete using decrRef() as it is no more needed.
3266 * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh.
3268 MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const
3270 return getMeshAtLevel(-1,renum);
3274 * Returns a MEDCouplingUMesh of a relative dimension == -2.
3275 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3276 * optional numbers of mesh entities.
3277 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3278 * delete using decrRef() as it is no more needed.
3279 * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh.
3281 MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const
3283 return getMeshAtLevel(-2,renum);
3287 * Returns a MEDCouplingUMesh of a relative dimension == -3.
3288 * \param [in] renum - if \c true, the returned mesh is permuted according to the
3289 * optional numbers of mesh entities.
3290 * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
3291 * delete using decrRef() as it is no more needed.
3292 * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh.
3294 MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
3296 return getMeshAtLevel(-3,renum);
3300 * This method is for advanced users. There is two storing strategy of mesh in \a this.
3301 * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
3302 * When assignement is done the first one is done, which is not optimal in write mode for MED file.
3303 * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
3305 void MEDFileUMesh::forceComputationOfParts() const
3307 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
3309 const MEDFileUMeshSplitL1 *elt(*it);
3311 elt->forceComputationOfParts();
3316 * This method returns a vector of mesh parts containing each exactly one geometric type.
3317 * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown).
3318 * This method is only for memory aware users.
3319 * The returned pointers are **NOT** new object pointer. No need to mange them.
3321 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
3323 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3324 return sp->getDirectUndergroundSingleGeoTypeMeshes();
3328 * This method returns the part of \a this having the geometric type \a gt.
3329 * If such part is not existing an exception will be thrown.
3330 * The returned pointer is **NOT** new object pointer. No need to mange it.
3332 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
3334 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3335 int lev=(int)cm.getDimension()-getMeshDimension();
3336 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3337 return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
3341 * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
3342 * \throw if the reqsuested \a meshDimRelToMax does not exist.
3344 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
3346 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
3347 return sp->getGeoTypes();
3351 * This method extracts from whole family field ids the part relative to the input parameter \a gt.
3352 * \param [in] gt - the geometric type for which the family field is asked.
3353 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3354 * delete using decrRef() as it is no more needed.
3355 * \sa MEDFileUMesh::extractNumberFieldOnGeoType
3357 DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3359 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3360 int lev=(int)cm.getDimension()-getMeshDimension();
3361 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3362 return sp->extractFamilyFieldOnGeoType(gt);
3366 * This method extracts from whole number field ids the part relative to the input parameter \a gt.
3367 * \param [in] gt - the geometric type for which the number field is asked.
3368 * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
3369 * delete using decrRef() as it is no more needed.
3370 * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
3372 DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3374 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3375 int lev=(int)cm.getDimension()-getMeshDimension();
3376 const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
3377 return sp->extractNumberFieldOnGeoType(gt);
3381 * This method returns for specified geometric type \a gt the relative level to \a this.
3382 * If the relative level is empty an exception will be thrown.
3384 int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
3386 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
3387 int ret((int)cm.getDimension()-getMeshDimension());
3388 getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level.
3392 const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const
3394 if(meshDimRelToMaxExt==1)
3395 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3396 if(meshDimRelToMaxExt>1)
3397 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3398 int tracucedRk=-meshDimRelToMaxExt;
3399 if(tracucedRk>=(int)_ms.size())
3400 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3401 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3402 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3403 return _ms[tracucedRk];
3406 MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt)
3408 if(meshDimRelToMaxExt==1)
3409 throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !");
3410 if(meshDimRelToMaxExt>1)
3411 throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !");
3412 int tracucedRk=-meshDimRelToMaxExt;
3413 if(tracucedRk>=(int)_ms.size())
3414 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
3415 if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0)
3416 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
3417 return _ms[tracucedRk];
3420 void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
3422 if(-meshDimRelToMax>=(int)_ms.size())
3423 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
3425 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
3427 if(((const MEDFileUMeshSplitL1*) (*it))!=0)
3429 int ref=(*it)->getMeshDimension();
3430 if(ref+i!=meshDim-meshDimRelToMax)
3431 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !");
3437 * Sets the node coordinates array of \a this mesh.
3438 * \param [in] coords - the new node coordinates array.
3439 * \throw If \a coords == \c NULL.
3441 void MEDFileUMesh::setCoords(DataArrayDouble *coords)
3444 throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
3445 coords->checkAllocated();
3446 int nbOfTuples=coords->getNumberOfTuples();
3449 _fam_coords=DataArrayInt::New();
3450 _fam_coords->alloc(nbOfTuples,1);
3451 _fam_coords->fillWithZero();
3452 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3453 if((MEDFileUMeshSplitL1 *)(*it))
3454 (*it)->setCoords(coords);
3458 * Removes all groups of a given dimension in \a this mesh.
3459 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
3460 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
3462 void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
3464 if(meshDimRelToMaxExt==1)
3466 if((DataArrayInt *)_fam_coords)
3467 _fam_coords->fillWithZero();
3470 MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
3471 l1->eraseFamilyField();
3476 * Removes all families with ids not present in the family fields of \a this mesh.
3478 void MEDFileUMesh::optimizeFamilies()
3480 std::vector<int> levs=getNonEmptyLevelsExt();
3481 std::set<int> allFamsIds;
3482 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
3484 const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
3485 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
3487 std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
3490 std::set<std::string> famNamesToKill;
3491 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
3493 if(allFamsIds.find((*it).second)!=allFamsIds.end())
3494 famNamesToKill.insert((*it).first);
3496 for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++)
3497 _families.erase(*it);
3498 std::vector<std::string> grpNamesToKill;
3499 for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++)
3501 std::vector<std::string> tmp;
3502 for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
3504 if(famNamesToKill.find(*it2)==famNamesToKill.end())
3505 tmp.push_back(*it2);
3510 tmp.push_back((*it).first);
3512 for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++)
3516 void MEDFileUMesh::duplicateNodesOnM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
3518 std::vector<int> levs=getNonEmptyLevels();
3519 if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
3520 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : This method works only for mesh definied on level 0 and -1 !");
3521 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
3522 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
3523 int nbNodes=m0->getNumberOfNodes();
3524 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
3525 DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
3526 m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
3527 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
3528 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
3529 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
3530 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
3531 // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
3532 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
3533 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
3534 descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
3535 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
3536 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
3537 DataArrayInt *cellsInM1ToRenumW4Tmp=0;
3538 m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
3539 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
3540 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
3541 cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
3542 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
3543 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
3544 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
3545 m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
3546 m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
3547 // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
3548 tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
3549 m0->setCoords(tmp0->getCoords());
3550 m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
3551 m1->setCoords(m0->getCoords());
3552 _coords=m0->getCoords(); _coords->incrRef();
3553 // duplication of cells in group 'grpNameM1' on level -1
3554 m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
3555 std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
3556 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
3557 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
3558 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
3560 newm1->setName(getName());
3561 const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
3563 throw INTERP_KERNEL::Exception("MEDFileUMesh::duplicateNodesOnM1Group : internal problem !");
3564 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
3565 newFam->alloc(newm1->getNumberOfCells(),1);
3566 int idd=getMaxFamilyId()+1;
3567 int globStart=0,start=0,end,globEnd;
3568 int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
3569 for(int i=0;i<nbOfChunks;i++)
3571 globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
3572 if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
3574 end=start+szOfCellGrpOfSameType->getIJ(i,0);
3575 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
3576 newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
3581 newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1);
3585 newm1->setCoords(getCoords());
3586 setMeshAtLevel(-1,newm1);
3587 setFamilyFieldArr(-1,newFam);
3588 std::string grpName2(grpNameM1); grpName2+="_dup";
3589 addFamily(grpName2,idd);
3590 addFamilyOnGrp(grpName2,grpName2);
3595 int newNbOfNodes=getCoords()->getNumberOfTuples();
3596 newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
3597 newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
3598 newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
3601 nodesDuplicated=nodeIdsToDuplicate.retn();
3602 cellsModified=cellsToModifyConn0.retn();
3603 cellsNotModified=cellsToModifyConn1.retn();
3607 * \param [out] oldCode retrieves the distribution of types before the call if true is returned
3608 * \param [out] newCode etrieves the distribution of types after the call if true is returned
3609 * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
3611 * \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.
3612 * 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.
3614 bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
3616 o2nRenumCell=0; oldCode.clear(); newCode.clear();
3617 std::vector<int> levs=getNonEmptyLevels();
3619 std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
3620 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
3623 for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
3625 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
3626 std::vector<int> code1=m->getDistributionOfTypes();
3627 end=PutInThirdComponentOfCodeOffset(code1,start);
3628 oldCode.insert(oldCode.end(),code1.begin(),code1.end());
3629 bool hasChanged=m->unPolyze();
3630 DataArrayInt *fake=0;
3631 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
3632 MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
3634 renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
3637 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
3638 m->renumberCells(o2nCellsPart2->getConstPointer(),false);
3640 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
3641 const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
3642 const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
3643 setMeshAtLevel(*it,m);
3644 std::vector<int> code2=m->getDistributionOfTypes();
3645 end=PutInThirdComponentOfCodeOffset(code2,start);
3646 newCode.insert(newCode.end(),code2.begin(),code2.end());
3648 if(o2nCellsPart2->isIdentity())
3652 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
3653 setFamilyFieldArr(*it,newFamField);
3657 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
3658 setRenumFieldArr(*it,newNumField);
3663 newCode.insert(newCode.end(),code1.begin(),code1.end());
3669 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
3670 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
3671 o2nRenumCell=o2nRenumCellRet.retn();
3676 struct MEDLoaderAccVisit1
3678 MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
3679 int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
3680 int _new_nb_of_nodes;
3684 * 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.
3685 * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
3686 * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
3687 * -1 values in returned array means that the corresponding old node is no more used.
3689 * \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
3690 * is modified in \a this.
3691 * \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
3694 DataArrayInt *MEDFileUMesh::zipCoords()
3696 const DataArrayDouble *coo(getCoords());
3698 throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
3699 int nbOfNodes(coo->getNumberOfTuples());
3700 std::vector<bool> nodeIdsInUse(nbOfNodes,false);
3701 std::vector<int> neLevs(getNonEmptyLevels());
3702 for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
3704 const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev));
3705 if(zeLev->isMeshStoredSplitByType())
3707 std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes());
3708 for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
3710 (*it)->computeNodeIdsAlg(nodeIdsInUse);
3714 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
3715 mesh->computeNodeIdsAlg(nodeIdsInUse);
3718 int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
3719 if(nbrOfNodesInUse==nbOfNodes)
3720 return 0;//no need to update _part_coords
3721 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
3722 std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
3723 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
3724 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3725 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
3726 MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
3727 if((const DataArrayInt *)_fam_coords)
3728 newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3729 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
3730 if((const DataArrayInt *)_num_coords)
3731 newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
3732 if((const DataArrayAsciiChar *)_name_coords)
3733 newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
3734 _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
3735 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
3737 if((MEDFileUMeshSplitL1*)*it)
3739 (*it)->renumberNodesInConn(ret->begin());
3740 (*it)->setCoords(_coords);
3743 // updates _part_coords
3744 const PartDefinition *pc(_part_coords);
3747 MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
3748 _part_coords=tmpPD->composeWith(pc);
3754 * This method performs an extrusion along a path defined by \a m1D.
3755 * \a this is expected to be a mesh with max mesh dimension equal to 2.
3756 * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1.
3757 * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this.
3758 * This method scans all levels in \a this
3759 * and put them in the returned mesh. All groups in \a this are also put in the returned mesh.
3761 * \param [in] m1D - the mesh defining the extrusion path.
3762 * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details)
3763 * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this.
3765 * \sa MEDCouplingUMesh::buildExtrudedMesh
3767 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
3769 if(getMeshDimension()!=2)
3770 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
3771 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3772 m1D->checkCoherency();
3773 if(m1D->getMeshDimension()!=1)
3774 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
3775 int nbRep(m1D->getNumberOfCells());
3776 std::vector<int> levs(getNonEmptyLevels());
3777 std::vector<std::string> grps(getGroupsNames());
3778 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
3779 DataArrayDouble *coords(0);
3780 std::size_t nbOfLevsOut(levs.size()+1);
3781 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
3782 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3784 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
3785 item=item->clone(false);
3786 item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
3787 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
3788 tmp->changeSpaceDimension(3+(*lev),0.);
3789 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
3790 zeList.push_back(elt);
3792 coords=elt->getCoords();
3795 throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
3796 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
3798 (*it)->setName(getName());
3799 (*it)->setCoords(coords);
3801 for(std::size_t ii=0;ii!=zeList.size();ii++)
3804 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
3807 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
3808 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
3809 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
3810 elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
3811 elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
3812 elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
3813 std::vector<const MEDCouplingUMesh *> elts(3);
3814 elts[0]=elt; elts[1]=elt1; elts[2]=elt2;
3815 elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts);
3816 elt->setName(getName());
3819 o2ns[ii]=elt->sortCellsInMEDFileFrmt();
3820 ret->setMeshAtLevel(lev,elt);
3822 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
3823 endLev=endLev->clone(false); endLev->setCoords(coords);
3824 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
3825 endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
3826 endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
3827 endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
3828 o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt();
3829 endLev->setName(getName());
3830 ret->setMeshAtLevel(levs.back()-1,endLev);
3832 for(std::size_t ii=0;ii!=zeList.size();ii++)
3835 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3836 std::vector< const DataArrayInt * > outGrps2;
3839 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3841 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
3842 if(!grpArr->empty())
3844 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
3845 int offset0(zeList[ii]->getNumberOfCells());
3846 int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
3847 grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
3848 std::ostringstream oss; oss << grpArr2->getName() << "_top";
3849 grpArr2->setName(oss.str());
3850 grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3851 grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3852 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3853 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3858 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3860 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
3861 if(!grpArr->empty())
3863 int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
3864 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
3865 std::vector< const DataArrayInt *> grpArrs2(nbRep);
3866 for(int iii=0;iii<nbRep;iii++)
3868 grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
3869 grpArrs2[iii]=grpArrs[iii];
3871 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
3872 grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
3873 std::ostringstream grpName; grpName << *grp << "_extruded";
3874 grpArrExt->setName(grpName.str());
3875 outGrps.push_back(grpArrExt);
3876 outGrps2.push_back(grpArrExt);
3879 ret->setGroupsAtLevel(lev,outGrps2);
3881 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
3882 std::vector< const DataArrayInt * > outGrps2;
3883 for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
3885 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
3886 if(grpArr1->empty())
3888 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
3889 std::ostringstream grpName; grpName << *grp << "_top";
3890 grpArr2->setName(grpName.str());
3891 grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
3892 outGrps.push_back(grpArr1); outGrps.push_back(grpArr2);
3893 outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2);
3895 ret->setGroupsAtLevel(levs.back()-1,outGrps2);
3900 * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy).
3901 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
3902 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
3904 * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple
3905 * corresponding quadratic cells. 1 is those creating the 'most' complex.
3906 * \param [in] eps - detection threshold for coordinates.
3907 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
3909 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear
3911 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
3913 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3914 int initialNbNodes(getNumberOfNodes());
3915 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
3916 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
3918 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
3920 DataArrayDouble *zeCoords(m0->getCoords());
3921 ret->setMeshAtLevel(0,m0);
3922 std::vector<int> levs(getNonEmptyLevels());
3923 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
3926 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
3927 ret->setFamilyFieldArr(0,famFieldCpy);
3929 famField=getFamilyFieldAtLevel(1);
3932 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
3933 fam->fillWithZero();
3934 fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
3935 ret->setFamilyFieldArr(1,fam);
3937 ret->copyFamGrpMapsFrom(*this);
3938 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
3939 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
3943 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
3944 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
3946 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
3948 MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
3950 bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
3951 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
3954 std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
3955 throw INTERP_KERNEL::Exception(oss.str().c_str());
3957 b->applyLin(1,initialNbNodes);
3958 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
3959 std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
3960 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
3961 m1->renumberNodesInConn(renum->begin());
3962 m1->setCoords(zeCoords);
3963 ret->setMeshAtLevel(*lev,m1);
3964 famField=getFamilyFieldAtLevel(*lev);
3967 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
3968 ret->setFamilyFieldArr(*lev,famFieldCpy);
3975 * This method converts all quadratic cells in \a this into linear cells.
3976 * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance.
3977 * Groups on nodes and families on nodes are copied directly to the returned instance without transformation.
3979 * \param [in] eps - detection threshold for coordinates.
3980 * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance.
3982 * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic
3984 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
3986 MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
3987 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
3988 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
3989 m0->convertQuadraticCellsToLinear();
3991 DataArrayDouble *zeCoords(m0->getCoords());
3992 ret->setMeshAtLevel(0,m0);
3993 std::vector<int> levs(getNonEmptyLevels());
3994 const DataArrayInt *famField(getFamilyFieldAtLevel(0));
3997 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
3998 ret->setFamilyFieldArr(0,famFieldCpy);
4000 famField=getFamilyFieldAtLevel(1);
4003 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
4004 ret->setFamilyFieldArr(1,fam);
4006 ret->copyFamGrpMapsFrom(*this);
4007 for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
4011 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
4012 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
4013 m1->convertQuadraticCellsToLinear();
4016 bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
4017 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
4020 std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
4021 throw INTERP_KERNEL::Exception(oss.str().c_str());
4023 m1->renumberNodesInConn(b->begin());
4024 m1->setCoords(zeCoords);
4025 ret->setMeshAtLevel(*lev,m1);
4026 famField=getFamilyFieldAtLevel(*lev);
4029 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
4030 ret->setFamilyFieldArr(*lev,famFieldCpy);
4036 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4038 clearNonDiscrAttributes();
4039 forceComputationOfParts();
4040 tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
4041 std::vector<int> layer0;
4042 layer0.push_back(_order); //0 i
4043 layer0.push_back(_iteration);//1 i
4044 layer0.push_back(getSpaceDimension());//2 i
4045 tinyDouble.push_back(_time);//0 d
4046 tinyStr.push_back(_name);//0 s
4047 tinyStr.push_back(_desc_name);//1 s
4048 for(int i=0;i<getSpaceDimension();i++)
4049 tinyStr.push_back(_coords->getInfoOnComponent(i));
4050 layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
4051 for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
4053 tinyStr.push_back((*it).first);
4054 layer0.push_back((*it).second);
4056 layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
4057 for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
4059 layer0.push_back((int)(*it0).second.size());
4060 tinyStr.push_back((*it0).first);
4061 for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
4062 tinyStr.push_back(*it1);
4064 // sizeof(layer0)==3+aa+1+bb layer#0
4065 bigArrayD=_coords;// 0 bd
4066 bigArraysI.push_back(_fam_coords);// 0 bi
4067 bigArraysI.push_back(_num_coords);// 1 bi
4068 const PartDefinition *pd(_part_coords);
4070 layer0.push_back(-1);
4073 std::vector<int> tmp0;
4074 pd->serialize(tmp0,bigArraysI);
4075 tinyInt.push_back(tmp0.size());
4076 tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
4079 std::vector<int> layer1;
4080 std::vector<int> levs(getNonEmptyLevels());
4081 layer1.push_back((int)levs.size());// 0 i <- key
4082 layer1.insert(layer1.end(),levs.begin(),levs.end());
4083 for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
4085 const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it));
4086 lev->serialize(layer1,bigArraysI);
4088 // put layers all together.
4089 tinyInt.push_back(layer0.size());
4090 tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
4091 tinyInt.push_back(layer1.size());
4092 tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
4095 void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
4096 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
4098 int sz0(tinyInt[0]);
4099 std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
4100 int sz1(tinyInt[sz0+1]);
4101 std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
4103 std::reverse(layer0.begin(),layer0.end());
4104 std::reverse(layer1.begin(),layer1.end());
4105 std::reverse(tinyDouble.begin(),tinyDouble.end());
4106 std::reverse(tinyStr.begin(),tinyStr.end());
4107 std::reverse(bigArraysI.begin(),bigArraysI.end());
4109 _order=layer0.back(); layer0.pop_back();
4110 _iteration=layer0.back(); layer0.pop_back();
4111 int spaceDim(layer0.back()); layer0.pop_back();
4112 _time=tinyDouble.back(); tinyDouble.pop_back();
4113 _name=tinyStr.back(); tinyStr.pop_back();
4114 _desc_name=tinyStr.back(); tinyStr.pop_back();
4115 _coords=bigArrayD; _coords->rearrange(spaceDim);
4116 for(int i=0;i<spaceDim;i++)
4118 _coords->setInfoOnComponent(i,tinyStr.back());
4121 int nbOfFams(layer0.back()); layer0.pop_back();
4123 for(int i=0;i<nbOfFams;i++)
4125 _families[tinyStr.back()]=layer0.back();
4126 tinyStr.pop_back(); layer0.pop_back();
4128 int nbGroups(layer0.back()); layer0.pop_back();
4130 for(int i=0;i<nbGroups;i++)
4132 std::string grpName(tinyStr.back()); tinyStr.pop_back();
4133 int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
4134 std::vector<std::string> fams(nbOfFamsOnGrp);
4135 for(int j=0;j<nbOfFamsOnGrp;j++)
4137 fams[j]=tinyStr.back(); tinyStr.pop_back();
4139 _groups[grpName]=fams;
4141 _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
4142 _num_coords=bigArraysI.back(); bigArraysI.pop_back();
4144 int isPd(layer0.back()); layer0.pop_back();
4147 std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
4148 layer0.erase(layer0.begin(),layer0.begin()+isPd);
4149 _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
4152 throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
4154 int nbLevs(layer1.back()); layer1.pop_back();
4155 std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
4157 int maxLev(-(*std::min_element(levs.begin(),levs.end())));
4158 _ms.resize(maxLev+1);
4159 for(int i=0;i<nbLevs;i++)
4163 _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
4168 * Adds a group of nodes to \a this mesh.
4169 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4170 * The ids should be sorted and different each other (MED file norm).
4172 * \warning this method can alter default "FAMILLE_ZERO" family.
4173 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4175 * \throw If the node coordinates array is not set.
4176 * \throw If \a ids == \c NULL.
4177 * \throw If \a ids->getName() == "".
4178 * \throw If \a ids does not respect the MED file norm.
4179 * \throw If a group with name \a ids->getName() already exists.
4181 void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
4183 const DataArrayDouble *coords(_coords);
4185 throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
4186 int nbOfNodes(coords->getNumberOfTuples());
4187 if(!((DataArrayInt *)_fam_coords))
4188 { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
4190 addGroupUnderground(true,ids,_fam_coords);
4194 * Adds a group of nodes/cells/faces/edges to \a this mesh.
4196 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
4197 * The ids should be sorted and different each other (MED file norm).
4199 * \warning this method can alter default "FAMILLE_ZERO" family.
4200 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
4202 * \throw If the node coordinates array is not set.
4203 * \throw If \a ids == \c NULL.
4204 * \throw If \a ids->getName() == "".
4205 * \throw If \a ids does not respect the MED file norm.
4206 * \throw If a group with name \a ids->getName() already exists.
4208 void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
4210 std::vector<int> levs(getNonEmptyLevelsExt());
4211 if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
4213 std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in ";
4214 std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str());
4216 if(meshDimRelToMaxExt==1)
4217 { addNodeGroup(ids); return ; }
4218 MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
4219 DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
4220 addGroupUnderground(false,ids,fam);
4224 * Changes a name of a family specified by its id.
4225 * \param [in] id - the id of the family of interest.
4226 * \param [in] newFamName - the new family name.
4227 * \throw If no family with the given \a id exists.
4229 void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
4231 std::string oldName=getFamilyNameGivenId(id);
4232 _families.erase(oldName);
4233 _families[newFamName]=id;
4237 * Removes a mesh of a given dimension.
4238 * \param [in] meshDimRelToMax - the relative dimension of interest.
4239 * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh.
4241 void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
4243 std::vector<int> levSet=getNonEmptyLevels();
4244 std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax);
4245 if(it==levSet.end())
4246 throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !");
4247 int pos=(-meshDimRelToMax);
4252 * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh.
4253 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4254 * \param [in] m - the new mesh to set.
4255 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4257 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4258 * another node coordinates array.
4259 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4260 * to the existing meshes of other levels of \a this mesh.
4262 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
4264 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
4265 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4269 * Sets a new MEDCouplingUMesh at a given level in \a this mesh.
4270 * \param [in] meshDimRelToMax - a relative level to set the mesh at.
4271 * \param [in] m - the new mesh to set.
4272 * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for
4273 * writing \a this mesh in a MED file.
4274 * \throw If the name or the description of \a this mesh and \a m are not empty and are
4276 * \throw If the node coordinates array is set \a this in mesh and \a m refers to
4277 * another node coordinates array.
4278 * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or
4279 * to the existing meshes of other levels of \a this mesh.
4281 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
4283 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
4284 checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
4287 MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
4289 dealWithTinyInfo(m);
4290 std::vector<int> levSet=getNonEmptyLevels();
4291 if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end())
4293 if((DataArrayDouble *)_coords==0)
4295 DataArrayDouble *c=m->getCoords();
4300 if(m->getCoords()!=_coords)
4301 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !");
4302 int sz=(-meshDimRelToMax)+1;
4303 if(sz>=(int)_ms.size())
4305 checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax);
4309 return _ms[-meshDimRelToMax];
4313 * This method allows to set at once the content of different levels in \a this.
4314 * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel.
4316 * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
4317 * \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.
4318 * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
4320 * \throw If \a there is a null pointer in \a ms.
4321 * \sa MEDFileUMesh::setMeshAtLevel
4323 void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4327 const MEDCouplingUMesh *mRef=ms[0];
4329 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !");
4330 std::string name(mRef->getName());
4331 const DataArrayDouble *coo(mRef->getCoords());
4334 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4336 const MEDCouplingUMesh *cur(*it);
4338 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !");
4339 if(coo!=cur->getCoords())
4340 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !");
4341 int mdim=cur->getMeshDimension();
4342 zeDim=std::max(zeDim,mdim);
4343 if(s.find(mdim)!=s.end())
4344 throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !");
4346 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
4348 int mdim=(*it)->getMeshDimension();
4349 setName((*it)->getName());
4350 setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum);
4356 * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of
4357 * meshes each representing a group, and creates corresponding groups in \a this mesh.
4358 * The given meshes must share the same node coordinates array.
4359 * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at.
4360 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4361 * create in \a this mesh.
4362 * \throw If \a ms is empty.
4363 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4364 * to the existing meshes of other levels of \a this mesh.
4365 * \throw If the meshes in \a ms do not share the same node coordinates array.
4366 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4367 * of the given meshes.
4368 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4369 * \throw If names of some meshes in \a ms are equal.
4370 * \throw If \a ms includes a mesh with an empty name.
4372 void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4375 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !");
4376 int sz=(-meshDimRelToMax)+1;
4377 if(sz>=(int)_ms.size())
4379 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4380 DataArrayDouble *coo=checkMultiMesh(ms);
4381 if((DataArrayDouble *)_coords==0)
4387 if((DataArrayDouble *)_coords!=coo)
4388 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
4389 std::vector<DataArrayInt *> corr;
4390 MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
4391 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
4392 setMeshAtLevel(meshDimRelToMax,m,renum);
4393 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4394 setGroupsAtLevel(meshDimRelToMax,corr2,true);
4398 * Creates groups at a given level in \a this mesh from a sequence of
4399 * meshes each representing a group.
4400 * The given meshes must share the same node coordinates array.
4401 * \param [in] meshDimRelToMax - the relative dimension to create the groups at.
4402 * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to
4403 * create in \a this mesh.
4404 * \param [in] renum - if \c true, then the optional numbers of entities are taken into
4406 * \throw If \a ms is empty.
4407 * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or
4408 * to the existing meshes of other levels of \a this mesh.
4409 * \throw If the meshes in \a ms do not share the same node coordinates array.
4410 * \throw If the node coordinates array of \a this mesh (if any) is not the same as that
4411 * of the given meshes.
4412 * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
4413 * \throw If names of some meshes in \a ms are equal.
4414 * \throw If \a ms includes a mesh with an empty name.
4416 void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum)
4419 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !");
4420 int sz=(-meshDimRelToMax)+1;
4421 if(sz>=(int)_ms.size())
4423 checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax);
4424 DataArrayDouble *coo=checkMultiMesh(ms);
4425 if((DataArrayDouble *)_coords==0)
4431 if((DataArrayDouble *)_coords!=coo)
4432 throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
4433 MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
4434 std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
4436 for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
4438 DataArrayInt *arr=0;
4439 bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
4443 std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !";
4444 throw INTERP_KERNEL::Exception(oss.str().c_str());
4447 std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
4448 setGroupsAtLevel(meshDimRelToMax,corr2,renum);
4451 DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const
4453 const DataArrayDouble *ret=ms[0]->getCoords();
4454 int mdim=ms[0]->getMeshDimension();
4455 for(unsigned int i=1;i<ms.size();i++)
4457 ms[i]->checkCoherency();
4458 if(ms[i]->getCoords()!=ret)
4459 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
4460 if(ms[i]->getMeshDimension()!=mdim)
4461 throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !");
4463 return const_cast<DataArrayDouble *>(ret);
4467 * Sets the family field of a given relative dimension.
4468 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4469 * the family field is set.
4470 * \param [in] famArr - the array of the family field.
4471 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4472 * \throw If \a famArr has an invalid size.
4474 void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4476 if(meshDimRelToMaxExt==1)
4483 DataArrayDouble *coo(_coords);
4485 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
4486 famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
4491 if(meshDimRelToMaxExt>1)
4492 throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !");
4493 int traducedRk=-meshDimRelToMaxExt;
4494 if(traducedRk>=(int)_ms.size())
4495 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4496 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4497 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4498 return _ms[traducedRk]->setFamilyArr(famArr);
4502 * Sets the optional numbers of mesh entities of a given dimension.
4503 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4504 * \param [in] renumArr - the array of the numbers.
4505 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4506 * \throw If \a renumArr has an invalid size.
4508 void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
4510 if(meshDimRelToMaxExt==1)
4518 DataArrayDouble *coo(_coords);
4520 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
4521 renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
4522 renumArr->incrRef();
4523 _num_coords=renumArr;
4527 if(meshDimRelToMaxExt>1)
4528 throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !");
4529 int traducedRk=-meshDimRelToMaxExt;
4530 if(traducedRk>=(int)_ms.size())
4531 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4532 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4533 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4534 return _ms[traducedRk]->setRenumArr(renumArr);
4538 * Sets the optional names of mesh entities of a given dimension.
4539 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
4540 * \param [in] nameArr - the array of the names.
4541 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4542 * \throw If \a nameArr has an invalid size.
4544 void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
4546 if(meshDimRelToMaxExt==1)
4553 DataArrayDouble *coo(_coords);
4555 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
4556 nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
4558 _name_coords=nameArr;
4561 if(meshDimRelToMaxExt>1)
4562 throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !");
4563 int traducedRk=-meshDimRelToMaxExt;
4564 if(traducedRk>=(int)_ms.size())
4565 throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !");
4566 if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0)
4567 throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !");
4568 return _ms[traducedRk]->setNameArr(nameArr);
4571 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
4573 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4574 if((const MEDFileUMeshSplitL1 *)(*it))
4575 (*it)->synchronizeTinyInfo(*this);
4579 * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
4581 void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
4583 DataArrayInt *arr=_fam_coords;
4585 arr->changeValue(oldId,newId);
4586 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
4588 MEDFileUMeshSplitL1 *sp=(*it);
4591 sp->changeFamilyIdArr(oldId,newId);
4596 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
4598 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
4599 const DataArrayInt *da(_fam_coords);
4601 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4602 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
4604 const MEDFileUMeshSplitL1 *elt(*it);
4607 da=elt->getFamilyField();
4609 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
4615 void MEDFileUMesh::computeRevNum() const
4617 if((const DataArrayInt *)_num_coords)
4620 int maxValue=_num_coords->getMaxValue(pos);
4621 _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
4625 std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
4627 return MEDFileMesh::getHeapMemorySizeWithoutChildren();
4630 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
4632 std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
4633 ret.push_back((const DataArrayInt *)_fam_nodes);
4634 ret.push_back((const DataArrayInt *)_num_nodes);
4635 ret.push_back((const DataArrayAsciiChar *)_names_nodes);
4636 ret.push_back((const DataArrayInt *)_fam_cells);
4637 ret.push_back((const DataArrayInt *)_num_cells);
4638 ret.push_back((const DataArrayAsciiChar *)_names_cells);
4639 ret.push_back((const DataArrayInt *)_fam_faces);
4640 ret.push_back((const DataArrayInt *)_num_faces);
4641 ret.push_back((const DataArrayInt *)_rev_num_nodes);
4642 ret.push_back((const DataArrayAsciiChar *)_names_faces);
4643 ret.push_back((const DataArrayInt *)_rev_num_cells);
4644 ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
4648 int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
4650 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4651 if((const DataArrayInt *)_fam_nodes)
4653 int val=_fam_nodes->getMaxValue(tmp);
4654 ret=std::max(ret,std::abs(val));
4656 if((const DataArrayInt *)_fam_cells)
4658 int val=_fam_cells->getMaxValue(tmp);
4659 ret=std::max(ret,std::abs(val));
4661 if((const DataArrayInt *)_fam_faces)
4663 int val=_fam_faces->getMaxValue(tmp);
4664 ret=std::max(ret,std::abs(val));
4669 int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
4671 int ret=-std::numeric_limits<int>::max(),tmp=-1;
4672 if((const DataArrayInt *)_fam_nodes)
4674 int val=_fam_nodes->getMaxValue(tmp);
4675 ret=std::max(ret,val);
4677 if((const DataArrayInt *)_fam_cells)
4679 int val=_fam_cells->getMaxValue(tmp);
4680 ret=std::max(ret,val);
4682 if((const DataArrayInt *)_fam_faces)
4684 int val=_fam_faces->getMaxValue(tmp);
4685 ret=std::max(ret,val);
4690 int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
4692 int ret=std::numeric_limits<int>::max(),tmp=-1;
4693 if((const DataArrayInt *)_fam_nodes)
4695 int val=_fam_nodes->getMinValue(tmp);
4696 ret=std::min(ret,val);
4698 if((const DataArrayInt *)_fam_cells)
4700 int val=_fam_cells->getMinValue(tmp);
4701 ret=std::min(ret,val);
4703 if((const DataArrayInt *)_fam_faces)
4705 int val=_fam_faces->getMinValue(tmp);
4706 ret=std::min(ret,val);
4711 bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
4713 if(!MEDFileMesh::isEqual(other,eps,what))
4715 const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other);
4718 what="Mesh types differ ! This is structured and other is NOT !";
4721 const DataArrayInt *famc1=_fam_nodes;
4722 const DataArrayInt *famc2=otherC->_fam_nodes;
4723 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4725 what="Mismatch of families arr on nodes ! One is defined and not other !";
4730 bool ret=famc1->isEqual(*famc2);
4733 what="Families arr on nodes differ !";
4738 famc2=otherC->_fam_cells;
4739 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4741 what="Mismatch of families arr on cells ! One is defined and not other !";
4746 bool ret=famc1->isEqual(*famc2);
4749 what="Families arr on cells differ !";
4754 famc2=otherC->_fam_faces;
4755 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4757 what="Mismatch of families arr on faces ! One is defined and not other !";
4762 bool ret=famc1->isEqual(*famc2);
4765 what="Families arr on faces differ !";
4770 famc2=otherC->_num_nodes;
4771 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4773 what="Mismatch of numbering arr on nodes ! One is defined and not other !";
4778 bool ret=famc1->isEqual(*famc2);
4781 what="Numbering arr on nodes differ !";
4786 famc2=otherC->_num_cells;
4787 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4789 what="Mismatch of numbering arr on cells ! One is defined and not other !";
4794 bool ret=famc1->isEqual(*famc2);
4797 what="Numbering arr on cells differ !";
4802 famc2=otherC->_num_faces;
4803 if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
4805 what="Mismatch of numbering arr on faces ! One is defined and not other !";
4810 bool ret=famc1->isEqual(*famc2);
4813 what="Numbering arr on faces differ !";
4817 const DataArrayAsciiChar *d1=_names_cells;
4818 const DataArrayAsciiChar *d2=otherC->_names_cells;
4819 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4821 what="Mismatch of naming arr on cells ! One is defined and not other !";
4826 bool ret=d1->isEqual(*d2);
4829 what="Naming arr on cells differ !";
4834 d2=otherC->_names_faces;
4835 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4837 what="Mismatch of naming arr on faces ! One is defined and not other !";
4842 bool ret=d1->isEqual(*d2);
4845 what="Naming arr on faces differ !";
4850 d2=otherC->_names_nodes;
4851 if((d1==0 && d2!=0) || (d1!=0 && d2==0))
4853 what="Mismatch of naming arr on nodes ! One is defined and not other !";
4858 bool ret=d1->isEqual(*d2);
4861 what="Naming arr on nodes differ !";
4868 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
4870 MEDFileMesh::clearNonDiscrAttributes();
4871 const DataArrayInt *tmp=_fam_nodes;
4873 (const_cast<DataArrayInt *>(tmp))->setName("");
4876 (const_cast<DataArrayInt *>(tmp))->setName("");
4879 (const_cast<DataArrayInt *>(tmp))->setName("");
4882 (const_cast<DataArrayInt *>(tmp))->setName("");
4885 (const_cast<DataArrayInt *>(tmp))->setName("");
4888 (const_cast<DataArrayInt *>(tmp))->setName("");
4892 * Returns ids of mesh entities contained in given families of a given dimension.
4893 * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids
4895 * \param [in] fams - the names of the families of interest.
4896 * \param [in] renum - if \c true, the optional numbers of entities, if available, are
4897 * returned instead of ids.
4898 * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
4899 * numbers, if available and required, of mesh entities of the families. The caller
4900 * is to delete this array using decrRef() as it is no more needed.
4901 * \throw If the family field is missing for \a meshDimRelToMaxExt.
4903 DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
4905 std::vector<int> famIds(getFamiliesIds(fams));
4906 switch(meshDimRelToMaxExt)
4910 if((const DataArrayInt *)_fam_nodes)
4912 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4914 da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4916 da=_fam_nodes->getIdsEqualList(0,0);
4918 return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
4923 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !");
4928 if((const DataArrayInt *)_fam_cells)
4930 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4932 da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4934 da=_fam_cells->getIdsEqualList(0,0);
4936 return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
4941 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !");
4946 if((const DataArrayInt *)_fam_faces)
4948 MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
4950 da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
4952 da=_fam_faces->getIdsEqualList(0,0);
4954 return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
4959 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !");
4963 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !");
4965 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !");
4969 * Sets the family field of a given relative dimension.
4970 * \param [in] meshDimRelToMaxExt - the relative dimension of entities for which
4971 * the family field is set.
4972 * \param [in] famArr - the array of the family field.
4973 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
4974 * \throw If \a famArr has an invalid size.
4975 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
4977 void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
4979 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
4981 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !");
4982 switch(meshDimRelToMaxExt)
4986 int nbCells=mesh->getNumberOfCells();
4987 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
4993 int nbNodes=mesh->getNumberOfNodes();
4994 famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5000 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5001 famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
5006 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !");
5013 * Sets the optional numbers of mesh entities of a given dimension.
5014 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5015 * \param [in] renumArr - the array of the numbers.
5016 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5017 * \throw If \a renumArr has an invalid size.
5018 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5020 void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
5022 const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
5024 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !");
5025 switch(meshDimRelToMaxExt)
5029 int nbCells=mesh->getNumberOfCells();
5030 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
5031 _num_cells=renumArr;
5036 int nbNodes=mesh->getNumberOfNodes();
5037 renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
5038 _num_nodes=renumArr;
5043 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5044 renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
5045 _num_faces=renumArr;
5049 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !");
5052 renumArr->incrRef();
5056 * Sets the optional names of mesh entities of a given dimension.
5057 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5058 * \param [in] nameArr - the array of the names.
5059 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5060 * \throw If \a nameArr has an invalid size.
5062 void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr)
5064 const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
5066 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !");
5067 switch(meshDimRelToMaxExt)
5071 int nbCells=mesh->getNumberOfCells();
5072 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
5073 _names_cells=nameArr;
5078 int nbNodes=mesh->getNumberOfNodes();
5079 nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
5080 _names_nodes=nameArr;
5085 int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
5086 nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
5087 _names_cells=nameArr;
5090 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5097 * Adds a group of nodes to \a this mesh.
5098 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5099 * The ids should be sorted and different each other (MED file norm).
5101 * \warning this method can alter default "FAMILLE_ZERO" family.
5102 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5104 * \throw If the node coordinates array is not set.
5105 * \throw If \a ids == \c NULL.
5106 * \throw If \a ids->getName() == "".
5107 * \throw If \a ids does not respect the MED file norm.
5108 * \throw If a group with name \a ids->getName() already exists.
5110 void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
5116 * Adds a group of nodes/cells/faces/edges to \a this mesh.
5118 * \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
5119 * The ids should be sorted and different each other (MED file norm).
5121 * \warning this method can alter default "FAMILLE_ZERO" family.
5122 * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session.
5124 * \throw If the node coordinates array is not set.
5125 * \throw If \a ids == \c NULL.
5126 * \throw If \a ids->getName() == "".
5127 * \throw If \a ids does not respect the MED file norm.
5128 * \throw If a group with name \a ids->getName() already exists.
5130 void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
5132 DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
5133 addGroupUnderground(false,ids,fam);
5138 * Returns the family field for mesh entities of a given dimension.
5139 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5140 * \return const DataArrayInt * - the family field. It is an array of ids of families
5141 * each mesh entity belongs to. It can be \c NULL.
5142 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5144 const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
5146 switch(meshDimRelToMaxExt)
5155 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5160 * Returns the family field for mesh entities of a given dimension.
5161 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5162 * \return const DataArrayInt * - the family field. It is an array of ids of families
5163 * each mesh entity belongs to. It can be \c NULL.
5164 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5166 DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
5168 switch(meshDimRelToMaxExt)
5177 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5182 * Returns the optional numbers of mesh entities of a given dimension.
5183 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5184 * \return const DataArrayInt * - the array of the entity numbers.
5185 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5186 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5188 const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
5190 switch(meshDimRelToMaxExt)
5199 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5204 * Returns the optional numbers of mesh entities of a given dimension transformed using
5205 * DataArrayInt::invertArrayN2O2O2N().
5206 * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
5207 * \return const DataArrayInt * - the array of the entity numbers transformed using
5208 * DataArrayInt::invertArrayN2O2O2N().
5209 * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
5210 * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
5212 const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
5214 if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
5215 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
5216 if(meshDimRelToMaxExt==0)
5218 if((const DataArrayInt *)_num_cells)
5221 int maxValue=_num_cells->getMaxValue(pos);
5222 _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
5223 return _rev_num_cells;
5226 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !");
5230 if((const DataArrayInt *)_num_nodes)
5233 int maxValue=_num_nodes->getMaxValue(pos);
5234 _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
5235 return _rev_num_nodes;
5238 throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !");
5242 const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const
5244 switch(meshDimRelToMaxExt)
5247 return _names_cells;
5249 return _names_nodes;
5251 return _names_faces;
5253 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
5258 * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
5259 * \return std::vector<int> - a sequence of the relative dimensions: [0].
5261 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const
5263 std::vector<int> ret(1);
5268 * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh.
5269 * \return std::vector<int> - a sequence of the relative dimensions: [1,0].
5271 std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
5273 std::vector<int> ret(2);
5279 * Returns the set of extensive levels (nodes included) where not NULL family arr are defined.
5281 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
5283 std::vector<int> ret;
5284 const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
5295 * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined.
5297 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
5299 std::vector<int> ret;
5300 const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
5311 * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined.
5313 std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
5315 std::vector<int> ret;
5316 const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces);
5327 * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
5329 bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
5331 oldCode.clear(); newCode.clear(); o2nRenumCell=0;
5335 void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
5337 DataArrayInt *arr=_fam_nodes;
5339 arr->changeValue(oldId,newId);
5342 arr->changeValue(oldId,newId);
5345 arr->changeValue(oldId,newId);
5348 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
5350 std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
5351 const DataArrayInt *da(_fam_nodes);
5353 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5356 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5359 { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
5363 void MEDFileStructuredMesh::deepCpyAttributes()
5365 if((const DataArrayInt*)_fam_nodes)
5366 _fam_nodes=_fam_nodes->deepCpy();
5367 if((const DataArrayInt*)_num_nodes)
5368 _num_nodes=_num_nodes->deepCpy();
5369 if((const DataArrayAsciiChar*)_names_nodes)
5370 _names_nodes=_names_nodes->deepCpy();
5371 if((const DataArrayInt*)_fam_cells)
5372 _fam_cells=_fam_cells->deepCpy();
5373 if((const DataArrayInt*)_num_cells)
5374 _num_cells=_num_cells->deepCpy();
5375 if((const DataArrayAsciiChar*)_names_cells)
5376 _names_cells=_names_cells->deepCpy();
5377 if((const DataArrayInt*)_fam_faces)
5378 _fam_faces=_fam_faces->deepCpy();
5379 if((const DataArrayInt*)_num_faces)
5380 _num_faces=_num_faces->deepCpy();
5381 if((const DataArrayAsciiChar*)_names_faces)
5382 _names_faces=_names_faces->deepCpy();
5383 if((const DataArrayInt*)_rev_num_nodes)
5384 _rev_num_nodes=_rev_num_nodes->deepCpy();
5385 if((const DataArrayInt*)_rev_num_cells)
5386 _rev_num_cells=_rev_num_cells->deepCpy();
5390 * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
5392 * \return a pointer to cartesian mesh that need to be managed by the caller.
5393 * \warning the returned pointer has to be managed by the caller.
5397 * Returns a pointer to MEDCouplingStructuredMesh held by \a this.
5398 * \param [in] meshDimRelToMax - it must be \c 0 or \c -1.
5399 * \param [in] renum - it must be \c false.
5400 * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
5401 * delete using decrRef() as it is no more needed.
5403 MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
5406 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
5407 const MEDCouplingStructuredMesh *m(getStructuredMesh());
5408 switch(meshDimRelToMax)
5414 return const_cast<MEDCouplingStructuredMesh *>(m);
5419 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
5420 buildMinusOneImplicitPartIfNeeded();
5421 MEDCouplingMesh *ret(_faces_if_necessary);
5427 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !");
5432 * Returns number of mesh entities of a given relative dimension in \a this mesh.
5433 * \param [in] meshDimRelToMaxExt - the relative dimension of interest.
5434 * \return int - the number of entities.
5435 * \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
5437 int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
5439 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5441 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !");
5442 switch(meshDimRelToMaxExt)
5445 return cmesh->getNumberOfCells();
5447 return cmesh->getNumberOfNodes();
5449 return cmesh->getNumberOfCellsOfSubLevelMesh();
5451 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !");
5455 int MEDFileStructuredMesh::getNumberOfNodes() const
5457 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5459 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5460 return cmesh->getNumberOfNodes();
5463 int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
5465 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5467 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !");
5468 switch(meshDimRelToMaxExt)
5471 return cmesh->getNumberOfCells();
5473 return cmesh->getNumberOfCellsOfSubLevelMesh();
5475 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !");
5479 bool MEDFileStructuredMesh::hasImplicitPart() const
5485 * \sa MEDFileStructuredMesh::getImplicitFaceMesh
5487 int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
5489 static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
5490 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5493 const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())));
5494 if(cm.getReverseExtrudedType()!=gt)
5495 throw INTERP_KERNEL::Exception(MSG);
5496 buildImplicitPart();
5497 return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh();
5501 if(gt!=zeFaceMesh->getCellModelEnum())
5502 throw INTERP_KERNEL::Exception(MSG);
5503 return zeFaceMesh->getNumberOfCells();
5507 void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const
5509 const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
5511 buildImplicitPart();
5514 void MEDFileStructuredMesh::buildImplicitPart() const
5516 const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh());
5518 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !");
5519 _faces_if_necessary=mcmesh->build1SGTSubLevelMesh();
5522 void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
5524 _faces_if_necessary=0;
5528 * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any.
5529 * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method.
5531 * \sa MEDFileStructuredMesh::buildImplicitPartIfAny
5533 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
5535 return _faces_if_necessary;
5538 std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const
5540 const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
5542 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !");
5543 switch(meshDimRelToMax)
5547 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0));
5552 int mdim(cmesh->getMeshDimension());
5554 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !");
5555 std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1));
5559 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !");
5563 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
5565 if(st.getNumberOfItems()!=1)
5566 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 !");
5567 if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
5568 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
5569 if(getNumberOfNodes()!=(int)nodesFetched.size())
5570 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
5571 if(st[0].getPflName().empty())
5573 std::fill(nodesFetched.begin(),nodesFetched.end(),true);
5576 const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
5577 const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
5578 int sz(nodesFetched.size());
5579 for(const int *work=arr->begin();work!=arr->end();work++)
5581 std::vector<int> conn;
5582 cmesh->getNodeIdsOfCell(*work,conn);
5583 for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
5584 if(*it>=0 && *it<sz)
5585 nodesFetched[*it]=true;
5587 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
5591 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
5593 INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim));
5597 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
5598 MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
5600 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5601 med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
5603 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5606 if(!mrs || mrs->isCellFamilyFieldReading())
5608 famCells=DataArrayInt::New();
5609 famCells->alloc(nbOfElt,1);
5610 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer());
5613 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5616 if(!mrs || mrs->isCellNumFieldReading())
5618 numCells=DataArrayInt::New();
5619 numCells->alloc(nbOfElt,1);
5620 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer());
5623 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
5626 if(!mrs || mrs->isCellNameFieldReading())
5628 namesCells=DataArrayAsciiChar::New();
5629 namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5630 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer());
5631 namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5636 void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5638 setName(strm->getName());
5639 setDescription(strm->getDescription());
5640 setUnivName(strm->getUnivName());
5641 setIteration(strm->getIteration());
5642 setOrder(strm->getOrder());
5643 setTimeValue(strm->getTime());
5644 setTimeUnit(strm->getTimeUnit());
5645 MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
5646 med_bool chgt=MED_FALSE,trsf=MED_FALSE;
5647 int nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
5650 if(!mrs || mrs->isNodeFamilyFieldReading())
5652 int nbNodes(getNumberOfNodes());
5654 throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
5655 _fam_nodes=DataArrayInt::New();
5656 _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
5657 if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378...
5658 _fam_nodes->fillWithZero();
5659 MEDmeshEntityFamilyNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer());
5662 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
5665 if(!mrs || mrs->isNodeNumFieldReading())
5667 _num_nodes=DataArrayInt::New();
5668 _num_nodes->alloc(nbOfElt,1);
5669 MEDmeshEntityNumberRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer());
5672 nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
5675 if(!mrs || mrs->isNodeNameFieldReading())
5677 _names_nodes=DataArrayAsciiChar::New();
5678 _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
5679 MEDmeshEntityNameRd(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer());
5680 _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end
5683 int meshDim(getStructuredMesh()->getMeshDimension());
5684 LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells);
5686 LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces);
5689 void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const
5691 int meshDim(getStructuredMesh()->getMeshDimension());
5692 med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
5694 if((const DataArrayInt *)_fam_cells)
5695 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer());
5696 if((const DataArrayInt *)_fam_faces)
5697 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer());
5698 if((const DataArrayInt *)_fam_nodes)
5699 MEDmeshEntityFamilyNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer());
5700 if((const DataArrayInt *)_num_cells)
5701 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer());
5702 if((const DataArrayInt *)_num_faces)
5703 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer());
5704 if((const DataArrayInt *)_num_nodes)
5705 MEDmeshEntityNumberWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer());
5706 if((const DataArrayAsciiChar *)_names_cells)
5708 if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
5710 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE;
5711 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5712 throw INTERP_KERNEL::Exception(oss.str().c_str());
5714 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer());
5716 if((const DataArrayAsciiChar *)_names_faces)
5718 if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE)
5720 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE;
5721 oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
5722 throw INTERP_KERNEL::Exception(oss.str().c_str());
5724 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer());
5726 if((const DataArrayAsciiChar *)_names_nodes)
5728 if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE)
5730 std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE;
5731 oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
5732 throw INTERP_KERNEL::Exception(oss.str().c_str());
5734 MEDmeshEntityNameWr(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer());
5737 MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
5741 * Returns an empty instance of MEDFileCMesh.
5742 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5743 * mesh using decrRef() as it is no more needed.
5745 MEDFileCMesh *MEDFileCMesh::New()
5747 return new MEDFileCMesh;
5751 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5752 * file. The first mesh in the file is loaded.
5753 * \param [in] fileName - the name of MED file to read.
5754 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5755 * mesh using decrRef() as it is no more needed.
5756 * \throw If the file is not readable.
5757 * \throw If there is no meshes in the file.
5758 * \throw If the mesh in the file is not a Cartesian one.
5760 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
5762 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
5765 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
5766 throw INTERP_KERNEL::Exception(oss.str().c_str());
5768 MEDFileUtilities::CheckFileForRead(fileName);
5769 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5771 ParaMEDMEM::MEDCouplingMeshType meshType;
5773 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
5774 return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
5778 * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED
5779 * file. The mesh to load is specified by its name and numbers of a time step and an
5781 * \param [in] fileName - the name of MED file to read.
5782 * \param [in] mName - the name of the mesh to read.
5783 * \param [in] dt - the number of a time step.
5784 * \param [in] it - the number of an iteration.
5785 * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this
5786 * mesh using decrRef() as it is no more needed.
5787 * \throw If the file is not readable.
5788 * \throw If there is no mesh with given attributes in the file.
5789 * \throw If the mesh in the file is not a Cartesian one.
5791 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5793 MEDFileUtilities::CheckFileForRead(fileName);
5794 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
5795 return new MEDFileCMesh(fid,mName,dt,it,mrs);
5798 std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const
5800 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
5803 std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const
5805 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
5806 ret.push_back((const MEDCouplingCMesh *)_cmesh);
5811 * Returns the dimension on cells in \a this mesh.
5812 * \return int - the mesh dimension.
5813 * \throw If there are no cells in this mesh.
5815 int MEDFileCMesh::getMeshDimension() const
5817 if(!((const MEDCouplingCMesh*)_cmesh))
5818 throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
5819 return _cmesh->getMeshDimension();
5823 * Returns the dimension on nodes in \a this mesh.
5824 * \return int - the space dimension.
5825 * \throw If there are no cells in this mesh.
5827 int MEDFileCMesh::getSpaceDimension() const
5829 if(!((const MEDCouplingCMesh*)_cmesh))
5830 throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !");
5831 return _cmesh->getSpaceDimension();
5835 * Returns a string describing \a this mesh.
5836 * \return std::string - the mesh information string.
5838 std::string MEDFileCMesh::simpleRepr() const
5840 return MEDFileStructuredMesh::simpleRepr();
5844 * Returns a full textual description of \a this mesh.
5845 * \return std::string - the string holding the mesh description.
5847 std::string MEDFileCMesh::advancedRepr() const
5849 return simpleRepr();
5852 MEDFileMesh *MEDFileCMesh::shallowCpy() const
5854 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5858 MEDFileMesh *MEDFileCMesh::createNewEmpty() const
5860 return new MEDFileCMesh;
5863 MEDFileMesh *MEDFileCMesh::deepCpy() const
5865 MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
5866 if((const MEDCouplingCMesh*)_cmesh)
5867 ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
5868 ret->deepCpyAttributes();
5873 * Checks if \a this and another mesh are equal.
5874 * \param [in] other - the mesh to compare with.
5875 * \param [in] eps - a precision used to compare real values.
5876 * \param [in,out] what - the string returning description of unequal data.
5877 * \return bool - \c true if the meshes are equal, \c false, else.
5879 bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
5881 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
5883 const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other);
5886 what="Mesh types differ ! This is cartesian and other is NOT !";
5889 clearNonDiscrAttributes();
5890 otherC->clearNonDiscrAttributes();
5891 const MEDCouplingCMesh *coo1=_cmesh;
5892 const MEDCouplingCMesh *coo2=otherC->_cmesh;
5893 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
5895 what="Mismatch of cartesian meshes ! One is defined and not other !";
5900 bool ret=coo1->isEqual(coo2,eps);
5903 what="cartesian meshes differ !";
5911 * Clears redundant attributes of incorporated data arrays.
5913 void MEDFileCMesh::clearNonDiscrAttributes() const
5915 MEDFileStructuredMesh::clearNonDiscrAttributes();
5916 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented
5919 MEDFileCMesh::MEDFileCMesh()
5923 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5926 loadCMeshFromFile(fid,mName,dt,it,mrs);
5928 catch(INTERP_KERNEL::Exception& e)
5933 void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
5935 ParaMEDMEM::MEDCouplingMeshType meshType;
5938 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
5939 if(meshType!=CARTESIAN)
5941 std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
5942 throw INTERP_KERNEL::Exception(oss.str().c_str());
5944 MEDFileCMeshL2 loaderl2;
5945 loaderl2.loadAll(fid,mid,mName,dt,it);
5946 MEDCouplingCMesh *mesh=loaderl2.getMesh();
5949 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
5953 * Returns a const pointer to MEDCouplingCMesh held by \a this mesh.
5954 * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh.
5956 const MEDCouplingCMesh *MEDFileCMesh::getMesh() const
5958 synchronizeTinyInfoOnLeaves();
5962 const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const
5964 synchronizeTinyInfoOnLeaves();
5969 * Sets the MEDCouplingCMesh holding the data of \a this mesh.
5970 * \param [in] m - the new MEDCouplingCMesh to refer to.
5971 * \throw If the name or the description of \a this mesh and \a m are not empty and are
5974 void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
5976 dealWithTinyInfo(m);
5982 void MEDFileCMesh::writeLL(med_idt fid) const
5984 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
5985 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
5986 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
5987 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
5988 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
5989 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
5990 int spaceDim(_cmesh->getSpaceDimension());
5991 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5992 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
5993 for(int i=0;i<spaceDim;i++)
5995 std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0));
5997 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
5998 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
5999 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
6001 MEDmeshCr(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
6002 MEDmeshUniversalNameWr(fid,maa);
6003 MEDmeshGridTypeWr(fid,maa,MED_CARTESIAN_GRID);
6004 for(int i=0;i<spaceDim;i++)
6006 const DataArrayDouble *da=_cmesh->getCoordsAt(i);
6007 MEDmeshGridIndexCoordinateWr(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer());
6010 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6011 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6014 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
6016 const MEDCouplingCMesh *cmesh=_cmesh;
6019 (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name);
6020 (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name);
6021 (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order);
6022 (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit);
6025 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
6027 return new MEDFileCurveLinearMesh;
6030 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
6032 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6035 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6036 throw INTERP_KERNEL::Exception(oss.str().c_str());
6038 MEDFileUtilities::CheckFileForRead(fileName);
6039 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6041 ParaMEDMEM::MEDCouplingMeshType meshType;
6043 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6044 return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
6047 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6049 MEDFileUtilities::CheckFileForRead(fileName);
6050 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6051 return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
6054 std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const
6056 return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren();
6059 std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const
6061 std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull());
6062 ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh);
6066 MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
6068 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6072 MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
6074 return new MEDFileCurveLinearMesh;
6077 MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
6079 MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
6080 if((const MEDCouplingCurveLinearMesh*)_clmesh)
6081 ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
6082 ret->deepCpyAttributes();
6086 int MEDFileCurveLinearMesh::getMeshDimension() const
6088 if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
6089 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
6090 return _clmesh->getMeshDimension();
6093 std::string MEDFileCurveLinearMesh::simpleRepr() const
6095 return MEDFileStructuredMesh::simpleRepr();
6098 std::string MEDFileCurveLinearMesh::advancedRepr() const
6100 return simpleRepr();
6103 bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const
6105 if(!MEDFileStructuredMesh::isEqual(other,eps,what))
6107 const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other);
6110 what="Mesh types differ ! This is curve linear and other is NOT !";
6113 clearNonDiscrAttributes();
6114 otherC->clearNonDiscrAttributes();
6115 const MEDCouplingCurveLinearMesh *coo1=_clmesh;
6116 const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh;
6117 if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0))
6119 what="Mismatch of curve linear meshes ! One is defined and not other !";
6124 bool ret=coo1->isEqual(coo2,eps);
6127 what="curve linear meshes differ !";
6134 void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const
6136 MEDFileStructuredMesh::clearNonDiscrAttributes();
6137 MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented
6140 void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const
6142 const MEDCouplingCurveLinearMesh *clmesh=_clmesh;
6145 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name);
6146 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name);
6147 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order);
6148 (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit);
6151 const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const
6153 synchronizeTinyInfoOnLeaves();
6157 void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
6159 dealWithTinyInfo(m);
6165 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
6167 synchronizeTinyInfoOnLeaves();
6171 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
6175 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6178 loadCLMeshFromFile(fid,mName,dt,it,mrs);
6180 catch(INTERP_KERNEL::Exception& e)
6185 void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
6187 INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
6188 INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
6189 INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
6190 MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
6191 MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
6192 MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str);
6193 int spaceDim=_clmesh->getSpaceDimension();
6194 int meshDim=_clmesh->getMeshDimension();
6195 INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6196 INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
6197 const DataArrayDouble *coords=_clmesh->getCoords();
6199 throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
6200 for(int i=0;i<spaceDim;i++)
6202 std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
6204 MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
6205 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
6206 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
6208 MEDmeshCr(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit);
6209 MEDmeshUniversalNameWr(fid,maa);
6210 MEDmeshGridTypeWr(fid,maa,MED_CURVILINEAR_GRID);
6211 std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
6212 MEDmeshGridStructWr(fid,maa,_iteration,_order,_time,&nodeGridSt[0]);
6214 MEDmeshNodeCoordinateWr(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin());
6216 std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
6217 MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
6220 void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
6222 ParaMEDMEM::MEDCouplingMeshType meshType;
6225 int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
6226 if(meshType!=CURVE_LINEAR)
6228 std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
6229 throw INTERP_KERNEL::Exception(oss.str().c_str());
6231 MEDFileCLMeshL2 loaderl2;
6232 loaderl2.loadAll(fid,mid,mName,dt,it);
6233 MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh();
6236 loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs);
6239 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
6241 return new MEDFileMeshMultiTS;
6244 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
6246 return new MEDFileMeshMultiTS(fileName);
6249 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
6251 return new MEDFileMeshMultiTS(fileName,mName);
6254 MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
6256 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
6257 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
6259 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
6260 if((const MEDFileMesh *)*it)
6261 meshOneTs[i]=(*it)->deepCpy();
6262 ret->_mesh_one_ts=meshOneTs;
6266 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
6268 return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
6271 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
6273 std::vector<const BigMemoryObject *> ret;
6274 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6275 ret.push_back((const MEDFileMesh *)*it);
6279 std::string MEDFileMeshMultiTS::getName() const
6281 if(_mesh_one_ts.empty())
6282 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !");
6283 return _mesh_one_ts[0]->getName();
6286 void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
6288 std::string oldName(getName());
6289 std::vector< std::pair<std::string,std::string> > v(1);
6290 v[0].first=oldName; v[0].second=newMeshName;
6294 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6297 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6299 MEDFileMesh *cur(*it);
6301 ret=cur->changeNames(modifTab) || ret;
6306 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
6308 if(_mesh_one_ts.empty())
6309 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !");
6310 return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0]));
6313 void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
6316 throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
6317 _mesh_one_ts.resize(1);
6318 mesh1TimeStep->incrRef();
6319 //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
6320 _mesh_one_ts[0]=mesh1TimeStep;
6323 void MEDFileMeshMultiTS::write(med_idt fid) const
6325 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
6327 (*it)->copyOptionsFrom(*this);
6332 void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
6334 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6335 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6336 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6337 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6341 void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
6342 {//for the moment to be improved
6343 _mesh_one_ts.resize(1);
6344 _mesh_one_ts[0]=MEDFileMesh::New(fileName,mName,-1,-1);
6347 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
6351 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
6354 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6357 std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
6358 throw INTERP_KERNEL::Exception(oss.str().c_str());
6360 MEDFileUtilities::CheckFileForRead(fileName);
6361 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
6363 ParaMEDMEM::MEDCouplingMeshType meshType;
6365 MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
6366 loadFromFile(fileName,ms.front());
6368 catch(INTERP_KERNEL::Exception& e)
6373 MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
6376 loadFromFile(fileName,mName);
6378 catch(INTERP_KERNEL::Exception& e)
6383 MEDFileMeshes *MEDFileMeshes::New()
6385 return new MEDFileMeshes;
6388 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
6390 return new MEDFileMeshes(fileName);
6393 void MEDFileMeshes::write(med_idt fid) const
6396 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6398 (*it)->copyOptionsFrom(*this);
6403 void MEDFileMeshes::write(const std::string& fileName, int mode) const
6405 med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
6406 MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
6407 std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\"";
6408 MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
6413 int MEDFileMeshes::getNumberOfMeshes() const
6415 return _meshes.size();
6418 MEDFileMeshesIterator *MEDFileMeshes::iterator()
6420 return new MEDFileMeshesIterator(this);
6423 /** Return a borrowed reference (caller is not responsible) */
6424 MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const
6426 if(i<0 || i>=(int)_meshes.size())
6428 std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !";
6429 throw INTERP_KERNEL::Exception(oss.str().c_str());
6431 return _meshes[i]->getOneTimeStep();
6434 /** Return a borrowed reference (caller is not responsible) */
6435 MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const
6437 std::vector<std::string> ms=getMeshesNames();
6438 std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname);
6441 std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : ";
6442 std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," "));
6443 throw INTERP_KERNEL::Exception(oss.str().c_str());
6445 return getMeshAtPos((int)std::distance(ms.begin(),it));
6448 std::vector<std::string> MEDFileMeshes::getMeshesNames() const
6450 std::vector<std::string> ret(_meshes.size());
6452 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6454 const MEDFileMeshMultiTS *f=(*it);
6457 ret[i]=f->getName();
6461 std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !";
6462 throw INTERP_KERNEL::Exception(oss.str().c_str());
6468 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
6471 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
6473 MEDFileMeshMultiTS *cur(*it);
6475 ret=cur->changeNames(modifTab) || ret;
6480 void MEDFileMeshes::resize(int newSize)
6482 _meshes.resize(newSize);
6485 void MEDFileMeshes::pushMesh(MEDFileMesh *mesh)
6488 throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !");
6489 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6490 elt->setOneTimeStep(mesh);
6491 _meshes.push_back(elt);
6494 void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh)
6497 throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !");
6498 if(i>=(int)_meshes.size())
6499 _meshes.resize(i+1);
6500 MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New();
6501 elt->setOneTimeStep(mesh);
6505 void MEDFileMeshes::destroyMeshAtPos(int i)
6507 if(i<0 || i>=(int)_meshes.size())
6509 std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !";
6510 throw INTERP_KERNEL::Exception(oss.str().c_str());
6512 _meshes.erase(_meshes.begin()+i);
6515 void MEDFileMeshes::loadFromFile(const std::string& fileName)
6517 std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
6519 _meshes.resize(ms.size());
6520 for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
6521 _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
6524 MEDFileMeshes::MEDFileMeshes()
6528 MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
6531 loadFromFile(fileName);
6533 catch(INTERP_KERNEL::Exception& /*e*/)
6537 MEDFileMeshes *MEDFileMeshes::deepCpy() const
6539 std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
6541 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6542 if((const MEDFileMeshMultiTS *)*it)
6543 meshes[i]=(*it)->deepCpy();
6544 MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
6545 ret->_meshes=meshes;
6549 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
6551 return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
6554 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
6556 std::vector<const BigMemoryObject *> ret;
6557 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
6558 ret.push_back((const MEDFileMeshMultiTS *)*it);
6562 std::string MEDFileMeshes::simpleRepr() const
6564 std::ostringstream oss;
6565 oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n";
6566 simpleReprWithoutHeader(oss);
6570 void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
6572 int nbOfMeshes=getNumberOfMeshes();
6573 oss << "There are " << nbOfMeshes << " meshes with the following names : \n";
6574 std::vector<std::string> mns=getMeshesNames();
6575 for(int i=0;i<nbOfMeshes;i++)
6576 oss << " - #" << i << " \"" << mns[i] << "\"\n";
6579 void MEDFileMeshes::checkCoherency() const
6581 static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
6583 std::set<std::string> s;
6584 for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
6586 const MEDFileMeshMultiTS *elt=(*it);
6589 std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !";
6590 throw INTERP_KERNEL::Exception(oss.str().c_str());
6592 std::size_t sz=s.size();
6593 s.insert(std::string((*it)->getName()));
6596 std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !";
6597 throw INTERP_KERNEL::Exception(oss.str().c_str());
6602 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
6607 _nb_iter=ms->getNumberOfMeshes();
6611 MEDFileMeshesIterator::~MEDFileMeshesIterator()
6615 MEDFileMesh *MEDFileMeshesIterator::nextt()
6617 if(_iter_id<_nb_iter)
6619 MEDFileMeshes *ms(_ms);
6621 return ms->getMeshAtPos(_iter_id++);