Back to index

salome-med  6.5.0
MEDCouplingMesh.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "MEDCouplingMesh.hxx"
00021 #include "MEDCouplingUMesh.hxx"
00022 #include "MEDCouplingMemArray.hxx"
00023 #include "MEDCouplingFieldDouble.hxx"
00024 #include "MEDCouplingFieldDiscretization.hxx"
00025 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
00026 
00027 #include <set>
00028 #include <cmath>
00029 #include <sstream>
00030 #include <fstream>
00031 #include <iterator>
00032 
00033 using namespace ParaMEDMEM;
00034 
00035 MEDCouplingMesh::MEDCouplingMesh():_time(0.),_iteration(-1),_order(-1)
00036 {
00037 }
00038 
00039 MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):_name(other._name),_description(other._description),
00040                                                                _time(other._time),_iteration(other._iteration),
00041                                                                _order(other._order),_time_unit(other._time_unit)
00042 {
00043 }
00044 
00048 bool MEDCouplingMesh::isStructured() const
00049 {
00050   return getType()==CARTESIAN;
00051 }
00052 
00053 bool MEDCouplingMesh::isEqual(const MEDCouplingMesh *other, double prec) const
00054 {
00055   return _name==other->_name && _description==other->_description && _iteration==other->_iteration
00056     && _order==other->_order && _time_unit==other->_time_unit && fabs(_time-other->_time)<1e-12;
00057 }
00058 
00076 void MEDCouplingMesh::checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec,
00077                                           DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
00078 {
00079   cellCor=0;
00080   nodeCor=0;
00081   if(this==other)
00082     return ;
00083   switch(levOfCheck)
00084     {
00085     case 0:
00086       {
00087         if(!isEqual(other,prec))
00088           throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal !");
00089         return ;
00090       }
00091     case 10:
00092     case 11:
00093     case 12:
00094       {
00095         checkDeepEquivalWith(other,levOfCheck-10,prec,cellCor,nodeCor);
00096         return ;
00097       }
00098     case 20:
00099     case 21:
00100     case 22:
00101       {
00102         checkDeepEquivalOnSameNodesWith(other,levOfCheck-20,prec,cellCor);
00103         return ;
00104       }
00105     case 1:
00106       {
00107         checkFastEquivalWith(other,prec);
00108         return;
00109       }
00110     case 2:
00111       {
00112         if(!isEqualWithoutConsideringStr(other,prec))
00113           throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal without considering strings !");
00114         return ;
00115       }
00116     default:
00117       throw INTERP_KERNEL::Exception("checkGeoFitWith : Invalid levOfCheck specified ! Value must be in 0,1,2,10,11 or 12.");
00118     }
00119 }
00120 
00126 DataArrayInt *MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const
00127 {
00128   std::vector<int> crest;
00129   std::set<int> p(partBg,partEnd);
00130   int nbOfCells=getNumberOfCells();
00131   for(int i=0;i<nbOfCells;i++)
00132     {
00133       std::vector<int> conn;
00134       getNodeIdsOfCell(i,conn);
00135       bool cont=true;
00136       for(std::vector<int>::const_iterator iter=conn.begin();iter!=conn.end() && cont;iter++)
00137         if(p.find(*iter)==p.end())
00138           cont=false;
00139       if(cont)
00140         crest.push_back(i);
00141     }
00142   DataArrayInt *ret=DataArrayInt::New();
00143   ret->alloc((int)crest.size(),1);
00144   std::copy(crest.begin(),crest.end(),ret->getPointer());
00145   return ret;
00146 }
00147 
00151 void MEDCouplingMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
00152 {
00153   if(getMeshDimension()!=other->getMeshDimension())
00154     throw INTERP_KERNEL::Exception("checkFastEquivalWith : Mesh dimensions are not equal !");
00155   if(getSpaceDimension()!=other->getSpaceDimension())
00156     throw INTERP_KERNEL::Exception("checkFastEquivalWith : Space dimensions are not equal !");
00157   if(getNumberOfCells()!=other->getNumberOfCells())
00158     throw INTERP_KERNEL::Exception("checkFastEquivalWith : number of cells are not equal !");
00159 }
00160 
00164 bool MEDCouplingMesh::areCompatibleForMerge(const MEDCouplingMesh *other) const
00165 {
00166   if(getMeshDimension()!=other->getMeshDimension())
00167     return false;
00168   if(getSpaceDimension()!=other->getSpaceDimension())
00169     return false;
00170   return true;
00171 }
00172 
00188 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const
00189 {
00190   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
00191   ret->setMesh(this);
00192   ret->fillFromAnalytic(nbOfComp,func);
00193   ret->incrRef();
00194   return ret;
00195 }
00196 
00201 void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
00202 {
00203   _name=other->_name;
00204   _description=other->_description;
00205   _time_unit=other->_time_unit;
00206 }
00207 
00212 void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception)
00213 {
00214   copyTinyStringsFrom(other);
00215   _time=other->_time;
00216   _iteration=other->_iteration;
00217   _order=other->_order;
00218 }
00219 
00248 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const char *func) const
00249 {
00250   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
00251   ret->setMesh(this);
00252   ret->fillFromAnalytic(nbOfComp,func);
00253   ret->incrRef();
00254   return ret;
00255 }
00256 
00268 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const char *func) const
00269 {
00270   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
00271   ret->setMesh(this);
00272   ret->fillFromAnalytic2(nbOfComp,func);
00273   ret->incrRef();
00274   return ret;
00275 }
00276 
00288 MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) const
00289 {
00290   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,NO_TIME);
00291   ret->setMesh(this);
00292   ret->fillFromAnalytic3(nbOfComp,varsOrder,func);
00293   ret->incrRef();
00294   return ret;
00295 }
00296 
00303 MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) throw(INTERP_KERNEL::Exception)
00304 {
00305   if(!mesh1)
00306     throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : first parameter is an empty mesh !");
00307   if(!mesh2)
00308     throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : second parameter is an empty mesh !");
00309   return mesh1->mergeMyselfWith(mesh2);
00310 }
00311 
00318 MEDCouplingMesh *MEDCouplingMesh::MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes) throw(INTERP_KERNEL::Exception)
00319 {
00320   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms1(meshes.size());
00321   std::vector< const MEDCouplingUMesh * > ms2(meshes.size());
00322   for(std::size_t i=0;i<meshes.size();i++)
00323     {
00324       if(meshes[i])
00325         {
00326           MEDCouplingUMesh *cur=meshes[i]->buildUnstructured();
00327           ms1[i]=cur;  ms2[i]=cur;
00328         }
00329       else
00330         {
00331           std::ostringstream oss; oss << "MEDCouplingMesh::MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes) : mesh at pos #" << i << " of input vector of size " << meshes.size() << " is empty !";
00332           throw INTERP_KERNEL::Exception(oss.str().c_str());
00333         }
00334     }
00335   return MEDCouplingUMesh::MergeUMeshes(ms2);
00336 }
00337 
00338 void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
00339 {
00340   int ret=getCellContainingPoint(pos,eps);
00341   elts.push_back(ret);
00342 }
00343 
00344 void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, std::vector<int>& elts, std::vector<int>& eltsIndex) const
00345 {
00346   eltsIndex.resize(nbOfPoints+1);
00347   eltsIndex[0]=0;
00348   elts.clear();
00349   int spaceDim=getSpaceDimension();
00350   const double *work=pos;
00351   for(int i=0;i<nbOfPoints;i++,work+=spaceDim)
00352     {
00353       int ret=getCellContainingPoint(work,eps);
00354       if(ret>=0)
00355         {
00356           elts.push_back(ret);
00357           eltsIndex[i+1]=eltsIndex[i]+1;
00358         }
00359       else
00360         eltsIndex[i+1]=eltsIndex[i];
00361     }
00362 }
00363 
00368 void MEDCouplingMesh::writeVTK(const char *fileName) const throw(INTERP_KERNEL::Exception)
00369 {
00370   std::string cda,pda;
00371   writeVTKAdvanced(fileName,cda,pda);
00372 }
00373 
00374 void MEDCouplingMesh::writeVTKAdvanced(const char *fileName, const std::string& cda, const std::string& pda) const throw(INTERP_KERNEL::Exception)
00375 {
00376   std::ofstream ofs(fileName);
00377   ofs << "<VTKFile type=\""  << getVTKDataSetType() << "\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
00378   writeVTKLL(ofs,cda,pda);
00379   ofs << "</VTKFile>\n";
00380   ofs.close();
00381 }