1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : Anthony Geay (CEA/DEN)
21 #include "MEDCouplingGaussLocalization.hxx"
22 #include "CellModel.hxx"
30 ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
31 const std::vector<double>& gsCoo, const std::vector<double>& w) throw(INTERP_KERNEL::Exception)
32 try:_type(type),_ref_coord(refCoo),_gauss_coord(gsCoo),_weight(w)
36 catch(INTERP_KERNEL::Exception& e)
38 _type=INTERP_KERNEL::NORM_ERROR;
45 void ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherency() const throw(INTERP_KERNEL::Exception)
47 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type);
48 int nbNodes=cm.getNumberOfNodes();
49 int dim=cm.getDimension();
52 if((int)_ref_coord.size()!=nbNodes*dim)
54 std::ostringstream oss; oss << "Invalid size of refCoo : expecting to be : " << nbNodes << " (nbNodePerCell) * " << dim << " (dim) !";
55 throw INTERP_KERNEL::Exception(oss.str().c_str());
58 if(_gauss_coord.size()!=dim*_weight.size())
60 std::ostringstream oss; oss << "Invalid gsCoo size and weight size : gsCoo.size() must be equal to _weight.size() * " << dim << " (dim) !";
61 throw INTERP_KERNEL::Exception(oss.str().c_str());
65 int ParaMEDMEM::MEDCouplingGaussLocalization::getDimension() const
69 return (int)_gauss_coord.size()/(int)_weight.size();
72 int ParaMEDMEM::MEDCouplingGaussLocalization::getNumberOfPtsInRefCell() const
74 int dim=getDimension();
77 return (int)_ref_coord.size()/dim;
80 std::string ParaMEDMEM::MEDCouplingGaussLocalization::getStringRepr() const
82 std::ostringstream oss;
83 oss << "CellType : " << INTERP_KERNEL::CellModel::GetCellModel(_type).getRepr() << std::endl;
84 oss << "Ref coords : "; std::copy(_ref_coord.begin(),_ref_coord.end(),std::ostream_iterator<double>(oss,", ")); oss << std::endl;
85 oss << "Localization coords : "; std::copy(_gauss_coord.begin(),_gauss_coord.end(),std::ostream_iterator<double>(oss,", ")); oss << std::endl;
86 oss << "Weight : "; std::copy(_weight.begin(),_weight.end(),std::ostream_iterator<double>(oss,", ")); oss << std::endl;
90 std::size_t ParaMEDMEM::MEDCouplingGaussLocalization::getHeapMemorySize() const
93 ret+=_ref_coord.capacity()*sizeof(double);
94 ret+=_gauss_coord.capacity()*sizeof(double);
95 ret+=_weight.capacity()*sizeof(double);
99 bool ParaMEDMEM::MEDCouplingGaussLocalization::isEqual(const MEDCouplingGaussLocalization& other, double eps) const
101 if(_type!=other._type)
103 if(!AreAlmostEqual(_ref_coord,other._ref_coord,eps))
105 if(!AreAlmostEqual(_gauss_coord,other._gauss_coord,eps))
107 if(!AreAlmostEqual(_weight,other._weight,eps))
112 double ParaMEDMEM::MEDCouplingGaussLocalization::getRefCoord(int ptIdInCell, int comp) const throw(INTERP_KERNEL::Exception)
114 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type);
115 int nbNodes=cm.getNumberOfNodes();
116 int dim=cm.getDimension();
117 if(ptIdInCell<0 || ptIdInCell>=nbNodes)
118 throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !");
119 if(comp<0 || comp>=dim)
120 throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !");
121 return _ref_coord[ptIdInCell*dim+comp];
124 double ParaMEDMEM::MEDCouplingGaussLocalization::getGaussCoord(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception)
126 int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp);
127 return _gauss_coord[gaussPtIdInCell*dim+comp];
130 double ParaMEDMEM::MEDCouplingGaussLocalization::getWeight(int gaussPtIdInCell, double newVal) const throw(INTERP_KERNEL::Exception)
132 checkCoherencyOfRequest(gaussPtIdInCell,0);
133 return _weight[gaussPtIdInCell];
137 * Completely useless method for end user. Only for CORBA MPI serialization/unserialization.
138 * push at the end of tinyInfo its basic serialization info. The size of pushed data is always the same.
139 * @param tinyInfo inout parameter.
141 void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo(std::vector<int>& tinyInfo) const
143 tinyInfo.push_back((int)_type);
144 tinyInfo.push_back(getNumberOfPtsInRefCell());
145 tinyInfo.push_back(getNumberOfGaussPt());
149 * Completely useless method for end user. Only for CORBA MPI serialization/unserialization.
150 * push at the end of tinyInfo its basic serialization info. The size of pushed data is \b NOT always the same contrary to pushTinySerializationIntInfo.
151 * @param tinyInfo inout parameter.
153 void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo(std::vector<double>& tinyInfo) const
155 tinyInfo.insert(tinyInfo.end(),_ref_coord.begin(),_ref_coord.end());
156 tinyInfo.insert(tinyInfo.end(),_gauss_coord.begin(),_gauss_coord.end());
157 tinyInfo.insert(tinyInfo.end(),_weight.begin(),_weight.end());
161 * This method operates the exact inverse operation than ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo method. This is one of the last step of unserialization process.
162 * This method should be called on an object resized by buildNewInstanceFromTinyInfo static method.
163 * This method takes in argument a pointer 'vals' that point to the begin of double data pushed remotely by pushTinySerializationDblInfo method.
164 * This method returns the pointer 'vals' with an offset of size what it has been read in this method.
166 const double *ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues(const double *vals)
168 const double *work=vals;
169 std::copy(work,work+_ref_coord.size(),_ref_coord.begin());
170 work+=_ref_coord.size();
171 std::copy(work,work+_gauss_coord.size(),_gauss_coord.begin());
172 work+=_gauss_coord.size();
173 std::copy(work,work+_weight.size(),_weight.begin());
174 work+=_weight.size();
179 * This method sets the comp_th component of ptIdInCell_th point coordinate of reference element of type this->_type.
180 * @throw if not 0<=ptIdInCell<nbOfNodePerCell or if not 0<=comp<dim
182 void ParaMEDMEM::MEDCouplingGaussLocalization::setRefCoord(int ptIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception)
184 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type);
185 int nbNodes=cm.getNumberOfNodes();
186 int dim=cm.getDimension();
187 if(ptIdInCell<0 || ptIdInCell>=nbNodes)
188 throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !");
189 if(comp<0 || comp>=dim)
190 throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !");
191 _ref_coord[ptIdInCell*dim+comp]=newVal;
194 void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoord(int gaussPtIdInCell, int comp, double newVal) throw(INTERP_KERNEL::Exception)
196 int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp);
197 _gauss_coord[gaussPtIdInCell*dim+comp]=newVal;
200 void ParaMEDMEM::MEDCouplingGaussLocalization::setWeight(int gaussPtIdInCell, double newVal) throw(INTERP_KERNEL::Exception)
202 checkCoherencyOfRequest(gaussPtIdInCell,0);
203 _weight[gaussPtIdInCell]=newVal;
207 * The format of 'tinyData' parameter is the same than pushed in method ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo.
209 ParaMEDMEM::MEDCouplingGaussLocalization ParaMEDMEM::MEDCouplingGaussLocalization::BuildNewInstanceFromTinyInfo(int dim, const std::vector<int>& tinyData)
211 std::vector<double> v1(dim*tinyData[1]),v2(dim*tinyData[2]),v3(tinyData[2]);
212 return ParaMEDMEM::MEDCouplingGaussLocalization((INTERP_KERNEL::NormalizedCellType)tinyData[0],v1,v2,v3);
215 int ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception)
217 const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type);
218 int dim=cm.getDimension();
219 int nbGsPts=getNumberOfGaussPt();
220 if(gaussPtIdInCell<0 || gaussPtIdInCell>=nbGsPts)
221 throw INTERP_KERNEL::Exception("gaussPtIdInCell specified is invalid : must be in [0:nbGsPts) !");
222 if(comp<0 || comp>=dim)
223 throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !");
227 bool ParaMEDMEM::MEDCouplingGaussLocalization::AreAlmostEqual(const std::vector<double>& v1, const std::vector<double>& v2, double eps)
229 std::size_t sz=v1.size();
232 std::vector<double> tmp(sz);
233 std::transform(v1.begin(),v1.end(),v2.begin(),tmp.begin(),std::minus<double>());
234 std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::ptr_fun<double,double>(fabs));
235 return *std::max_element(tmp.begin(),tmp.end())<eps;