Back to index

salome-med  6.5.0
MEDCouplingGaussLocalization.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 "MEDCouplingGaussLocalization.hxx"
00021 #include "CellModel.hxx"
00022 
00023 #include <cmath>
00024 #include <numeric>
00025 #include <sstream>
00026 #include <iterator>
00027 #include <algorithm>
00028 
00029 ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
00030                                                                        const std::vector<double>& gsCoo, const std::vector<double>& w) throw(INTERP_KERNEL::Exception)
00031 try:_type(type),_ref_coord(refCoo),_gauss_coord(gsCoo),_weight(w)
00032   {
00033     checkCoherency();
00034   }
00035 catch(INTERP_KERNEL::Exception& e)
00036   {
00037     _type=INTERP_KERNEL::NORM_ERROR;
00038     _ref_coord.clear();
00039     _gauss_coord.clear();
00040     _weight.clear();
00041     throw e;
00042   }
00043 
00044 void ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherency() const throw(INTERP_KERNEL::Exception)
00045 {
00046   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type);
00047   int nbNodes=cm.getNumberOfNodes();
00048   int dim=cm.getDimension();
00049   if(!cm.isDynamic())
00050     {
00051       if((int)_ref_coord.size()!=nbNodes*dim)
00052         {
00053           std::ostringstream oss; oss << "Invalid size of refCoo : expecting to be : " << nbNodes << " (nbNodePerCell) * " << dim << " (dim) !";
00054           throw INTERP_KERNEL::Exception(oss.str().c_str());
00055         }
00056     }
00057   if(_gauss_coord.size()!=dim*_weight.size())
00058     {
00059        std::ostringstream oss; oss << "Invalid gsCoo size and weight size : gsCoo.size() must be equal to _weight.size() * " << dim << " (dim) !";
00060        throw INTERP_KERNEL::Exception(oss.str().c_str());
00061     }
00062 }
00063 
00064 int ParaMEDMEM::MEDCouplingGaussLocalization::getDimension() const
00065 {
00066   if(_weight.empty())
00067     return -1;
00068   return (int)_gauss_coord.size()/(int)_weight.size();
00069 }
00070 
00071 int ParaMEDMEM::MEDCouplingGaussLocalization::getNumberOfPtsInRefCell() const
00072 {
00073   int dim=getDimension();
00074   if(dim==0)
00075     return -1;
00076   return (int)_ref_coord.size()/dim;
00077 }
00078 
00079 std::string ParaMEDMEM::MEDCouplingGaussLocalization::getStringRepr() const
00080 {
00081   std::ostringstream oss;
00082   oss << "CellType : " << INTERP_KERNEL::CellModel::GetCellModel(_type).getRepr() << std::endl;
00083   oss << "Ref coords : "; std::copy(_ref_coord.begin(),_ref_coord.end(),std::ostream_iterator<double>(oss,", ")); oss << std::endl;
00084   oss << "Localization coords : "; std::copy(_gauss_coord.begin(),_gauss_coord.end(),std::ostream_iterator<double>(oss,", ")); oss << std::endl;
00085   oss << "Weight : "; std::copy(_weight.begin(),_weight.end(),std::ostream_iterator<double>(oss,", ")); oss << std::endl;
00086   return oss.str();
00087 }
00088 
00089 bool ParaMEDMEM::MEDCouplingGaussLocalization::isEqual(const MEDCouplingGaussLocalization& other, double eps) const
00090 {
00091   if(_type!=other._type)
00092     return false;
00093   if(!AreAlmostEqual(_ref_coord,other._ref_coord,eps))
00094     return false;
00095   if(!AreAlmostEqual(_gauss_coord,other._gauss_coord,eps))
00096     return false;
00097   if(!AreAlmostEqual(_weight,other._weight,eps))
00098     return false;
00099   return true;
00100 }
00101 
00102 double ParaMEDMEM::MEDCouplingGaussLocalization::getRefCoord(int ptIdInCell, int comp) const throw(INTERP_KERNEL::Exception)
00103 {
00104   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type);
00105   int nbNodes=cm.getNumberOfNodes();
00106   int dim=cm.getDimension();
00107   if(ptIdInCell<0 || ptIdInCell>=nbNodes)
00108     throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !");
00109   if(comp<0 || comp>=dim)
00110     throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !");
00111   return _ref_coord[ptIdInCell*dim+comp];
00112 }
00113 
00114 double ParaMEDMEM::MEDCouplingGaussLocalization::getGaussCoord(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception)
00115 {
00116   int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp);
00117   return _gauss_coord[gaussPtIdInCell*dim+comp];
00118 }
00119 
00120 double ParaMEDMEM::MEDCouplingGaussLocalization::getWeight(int gaussPtIdInCell, double newVal) const throw(INTERP_KERNEL::Exception)
00121 {
00122   checkCoherencyOfRequest(gaussPtIdInCell,0);
00123   return _weight[gaussPtIdInCell];
00124 }
00125 
00131 void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo(std::vector<int>& tinyInfo) const
00132 {
00133   tinyInfo.push_back((int)_type);
00134   tinyInfo.push_back(getNumberOfPtsInRefCell());
00135   tinyInfo.push_back(getNumberOfGaussPt());
00136 }
00137 
00143 void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo(std::vector<double>& tinyInfo) const
00144 {
00145   tinyInfo.insert(tinyInfo.end(),_ref_coord.begin(),_ref_coord.end());
00146   tinyInfo.insert(tinyInfo.end(),_gauss_coord.begin(),_gauss_coord.end());
00147   tinyInfo.insert(tinyInfo.end(),_weight.begin(),_weight.end());
00148 }
00149 
00156 const double *ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues(const double *vals)
00157 {
00158   const double *work=vals;
00159   std::copy(work,work+_ref_coord.size(),_ref_coord.begin());
00160   work+=_ref_coord.size();
00161   std::copy(work,work+_gauss_coord.size(),_gauss_coord.begin());
00162   work+=_gauss_coord.size();
00163   std::copy(work,work+_weight.size(),_weight.begin());
00164   work+=_weight.size();
00165   return work;
00166 }
00167 
00172 void ParaMEDMEM::MEDCouplingGaussLocalization::setRefCoord(int ptIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception)
00173 {
00174   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type);
00175   int nbNodes=cm.getNumberOfNodes();
00176   int dim=cm.getDimension();
00177   if(ptIdInCell<0 || ptIdInCell>=nbNodes)
00178     throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !");
00179   if(comp<0 || comp>=dim)
00180     throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !");
00181   _ref_coord[ptIdInCell*dim+comp]=newVal;
00182 }
00183 
00184 void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoord(int gaussPtIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception)
00185 {
00186   int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp);
00187   _gauss_coord[gaussPtIdInCell*dim+comp]=newVal;
00188 }
00189 
00190 void ParaMEDMEM::MEDCouplingGaussLocalization::setWeight(int gaussPtIdInCell, double newVal) throw(INTERP_KERNEL::Exception)
00191 {
00192   checkCoherencyOfRequest(gaussPtIdInCell,0);
00193   _weight[gaussPtIdInCell]=newVal;
00194 }
00195 
00199 ParaMEDMEM::MEDCouplingGaussLocalization ParaMEDMEM::MEDCouplingGaussLocalization::BuildNewInstanceFromTinyInfo(int dim, const std::vector<int>& tinyData)
00200 {
00201   std::vector<double> v1(dim*tinyData[1]),v2(dim*tinyData[2]),v3(tinyData[2]);
00202   return ParaMEDMEM::MEDCouplingGaussLocalization((INTERP_KERNEL::NormalizedCellType)tinyData[0],v1,v2,v3);
00203 }
00204 
00205 int ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception)
00206 {
00207   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type);
00208   int dim=cm.getDimension();
00209   int nbGsPts=getNumberOfGaussPt();
00210   if(gaussPtIdInCell<0 || gaussPtIdInCell>=nbGsPts)
00211     throw INTERP_KERNEL::Exception("gaussPtIdInCell specified is invalid : must be in [0:nbGsPts) !");
00212   if(comp<0 || comp>=dim)
00213     throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !");
00214   return dim;
00215 }
00216 
00217 bool ParaMEDMEM::MEDCouplingGaussLocalization::AreAlmostEqual(const std::vector<double>& v1, const std::vector<double>& v2, double eps)
00218 {
00219   std::size_t sz=v1.size();
00220   if(sz!=v2.size())
00221     return false;
00222   std::vector<double> tmp(sz);
00223   std::transform(v1.begin(),v1.end(),v2.begin(),tmp.begin(),std::minus<double>());
00224   std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::ptr_fun<double,double>(fabs));
00225   return *std::max_element(tmp.begin(),tmp.end())<eps;
00226 }