00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <RealExpression.hpp>
00021 #include <BooleanExpression.hpp>
00022
00023 #include <FunctionExpression.hpp>
00024 #include <Vector3Expression.hpp>
00025
00026 #include <MeshExpression.hpp>
00027
00028 #include <Variable.hpp>
00029
00030 #include <Structured3DMesh.hpp>
00031 #include <MeshOfHexahedra.hpp>
00032 #include <MeshOfTetrahedra.hpp>
00033 #include <SurfaceMeshOfTriangles.hpp>
00034 #include <SurfaceMeshOfQuadrangles.hpp>
00035
00036 #include <SpectralMesh.hpp>
00037 #include <SpectralConformTransformation.hpp>
00038
00039 #include <GaussLobattoManager.hpp>
00040
00041 #include <Interval.hpp>
00042 #include <Information.hpp>
00043
00044 #include <Hexahedron.hpp>
00045 #include <Tetrahedron.hpp>
00046 #include <Triangle.hpp>
00047 #include <Quadrangle.hpp>
00048
00049 #include <ConformTransformation.hpp>
00050 #include <FiniteElementTraits.hpp>
00051
00052 #include <ScalarFunctionBase.hpp>
00053 #include <ScalarFunctionMaxComputer.hpp>
00054 #include <ScalarFunctionMinComputer.hpp>
00055
00056 #include <VariableRepository.hpp>
00057
00058 #include <limits>
00059
00060 ReferenceCounting<RealExpression>
00061 RealExpressionVariable::
00062 value()
00063 {
00064 return __expression->value();
00065 }
00066
00067 void RealExpressionVariable::execute()
00068 {
00069 RealVariable* realVariable = VariableRepository::instance().findVariable<RealVariable>(__variableName);
00070
00071 __expression = realVariable->expression();
00072 __realValue = __expression->realValue();
00073 }
00074
00075 std::istream& RealExpressionVariable::
00076 _get(std::istream& is)
00077 {
00078 if (not (is >> __realValue)) {
00079 throw ErrorHandler(__FILE__,__LINE__,
00080 "Cannot read real value",
00081 ErrorHandler::normal);
00082 }
00083 RealVariable* realVariable = VariableRepository::instance().findVariable<RealVariable>(__variableName);
00084
00085 (*realVariable) = new RealExpressionValue(__realValue);
00086
00087 return is;
00088 }
00089
00090
00091 RealExpressionVariable::
00092 RealExpressionVariable(const std::string& variableName)
00093 : __variableName(variableName),
00094 __expression(0)
00095 {
00096 ;
00097 }
00098
00099 RealExpressionVariable::RealExpressionVariable(const RealExpressionVariable& e)
00100 : __realVariable(e.__realVariable),
00101 __expression(e.__expression)
00102 {
00103 ;
00104 }
00105
00106 RealExpressionVariable::~RealExpressionVariable()
00107 {
00108 ;
00109 }
00110
00111
00112
00113 ReferenceCounting<RealExpression>
00114 RealExpressionFunctionEvaluate::
00115 value()
00116 {
00117 return new RealExpressionValue(__realValue);
00118 }
00119
00120 void RealExpressionFunctionEvaluate::execute()
00121 {
00122 (*__realFunction).execute();
00123 if ((*__realFunction).hasBoundaryExpression()) {
00124 throw ErrorHandler(__FILE__,__LINE__,
00125 "Cannot evaluate \""
00126 +stringify(*__realFunction)+
00127 "\": missing boundary",
00128 ErrorHandler::normal);
00129 }
00130 TinyVector<3,real_t> X;
00131 if (__v == 0) {
00132 (*__x).execute();
00133 (*__y).execute();
00134 (*__z).execute();
00135
00136 X[0] = (*__x).realValue();
00137 X[1] = (*__y).realValue();
00138 X[2] = (*__z).realValue();
00139 } else {
00140 (*__v).execute();
00141 for (size_t i=0; i<3; ++i) {
00142 X[i] = (*__v).value(i);
00143 }
00144 }
00145 const ScalarFunctionBase& f = *__realFunction->function();
00146 __realValue = f(X);
00147 }
00148
00149 RealExpressionFunctionEvaluate::
00150 RealExpressionFunctionEvaluate (ReferenceCounting<FunctionExpression> f,
00151 ReferenceCounting<RealExpression> x,
00152 ReferenceCounting<RealExpression> y,
00153 ReferenceCounting<RealExpression> z)
00154 : __realFunction(f),
00155 __v(0),
00156 __x(x),
00157 __y(y),
00158 __z(z)
00159 {
00160 ;
00161 }
00162
00163
00164 RealExpressionFunctionEvaluate::
00165 RealExpressionFunctionEvaluate(ReferenceCounting<FunctionExpression> f,
00166 ReferenceCounting<Vector3Expression> v)
00167 : __realFunction(f),
00168 __v(v),
00169 __x(0),
00170 __y(0),
00171 __z(0)
00172 {
00173 ;
00174 }
00175
00176 RealExpressionFunctionEvaluate::
00177 RealExpressionFunctionEvaluate(const RealExpressionFunctionEvaluate& e)
00178 : __realFunction(e.__realFunction),
00179 __v(e.__v),
00180 __x(e.__x),
00181 __y(e.__y),
00182 __z(e.__z)
00183 {
00184 ;
00185 }
00186
00187 RealExpressionFunctionEvaluate::~RealExpressionFunctionEvaluate()
00188 {
00189 ;
00190 }
00191
00192
00193
00194 ReferenceCounting<RealExpression>
00195 RealExpressionIntegrate::
00196 value()
00197 {
00198 return new RealExpressionValue(__realValue);
00199 }
00200
00201 template <typename MeshType, typename QuadratureType>
00202 real_t RealExpressionIntegrate::__integrate(const MeshType& M,
00203 const QuadratureType& Q,
00204 FunctionExpression& fe)
00205 {
00206 const ScalarFunctionBase& f = *fe.function();
00207 real_t integral=0;
00208 typedef typename MeshType::CellType CellType;
00209 for (typename MeshType::const_iterator iCell(M);
00210 not(iCell.end()); ++iCell) {
00211 const CellType& C = *iCell;
00212 typename FiniteElementTraits<CellType,
00213 ScalarDiscretizationTypeBase::lagrangianFEM1>::Transformation T(C);
00214 typename FiniteElementTraits<CellType,
00215 ScalarDiscretizationTypeBase::lagrangianFEM1>::JacobianTransformation J(T);
00216
00217 TinyVector<3, real_t> X;
00218 for (size_t i=0; i<QuadratureType::numberOfQuadraturePoints; ++i) {
00219 T.value(Q[i],X);
00220 integral += J.jacobianDet()*Q.weight(i)*f(X);
00221 }
00222 }
00223 return integral;
00224 }
00225
00226
00227 template <typename MeshType>
00228 real_t RealExpressionIntegrate::__integrate(const MeshType& M,
00229 FunctionExpression& f)
00230 {
00231 switch(this->__discretizationType) {
00232 case ScalarDiscretizationTypeBase::lagrangianFEM0: {
00233 typedef typename FiniteElementTraits<typename MeshType::CellType,
00234 ScalarDiscretizationTypeBase::lagrangianFEM0>::Type
00235 FiniteElementType;
00236 typedef typename FiniteElementType::QuadratureType QuadratureType;
00237 const QuadratureType& Q = QuadratureType::instance();
00238 return __integrate(M,Q,f);
00239 }
00240 case ScalarDiscretizationTypeBase::lagrangianFEM1: {
00241 typedef typename FiniteElementTraits<typename MeshType::CellType,
00242 ScalarDiscretizationTypeBase::lagrangianFEM1>::Type
00243 FiniteElementType;
00244 typedef typename FiniteElementType::QuadratureType QuadratureType;
00245 const QuadratureType& Q = QuadratureType::instance();
00246 return __integrate(M,Q,f);
00247 }
00248 case ScalarDiscretizationTypeBase::lagrangianFEM2: {
00249 typedef typename FiniteElementTraits<typename MeshType::CellType,
00250 ScalarDiscretizationTypeBase::lagrangianFEM2>::Type
00251 FiniteElementType;
00252 typedef typename FiniteElementType::QuadratureType QuadratureType;
00253 const QuadratureType& Q = QuadratureType::instance();
00254 return __integrate(M,Q,f);
00255 }
00256 default: {
00257 throw ErrorHandler(__FILE__,__LINE__,
00258 "unexpected quadrature type",
00259 ErrorHandler::unexpected);
00260 return 0;
00261 }
00262 }
00263 }
00264
00266 void RealExpressionIntegrate::execute()
00267 {
00268 __mesh->execute();
00269 Information::instance().setMesh(__mesh->mesh());
00270
00271 const Mesh& M = *__mesh->mesh();
00272
00273 __realFunction->execute();
00274 FunctionExpression& f = (*__realFunction);
00275
00276 if (M.family() ==Mesh::volume) {
00277 if (f.hasBoundaryExpression()) {
00278 throw ErrorHandler(__FILE__,__LINE__,
00279 "Cannot evaluate \""
00280 +stringify(f)+
00281 "\": missing boundary",
00282 ErrorHandler::normal);
00283 }
00284 }
00285
00286 real_t& integral = __realValue;
00287 integral = 0;
00288
00289 switch (M.type()) {
00290 case Mesh::cartesianHexahedraMesh: {
00291 const Structured3DMesh& m = static_cast<const Structured3DMesh&>(M);
00292 integral = __integrate(m, f);
00293 break;
00294 }
00295 case Mesh::hexahedraMesh: {
00296 const MeshOfHexahedra& m = static_cast<const MeshOfHexahedra&>(M);
00297 integral = __integrate(m, f);
00298 break;
00299 }
00300 case Mesh::tetrahedraMesh: {
00301 const MeshOfTetrahedra& m = static_cast<const MeshOfTetrahedra&>(M);
00302 integral = __integrate(m, f);
00303 break;
00304 }
00305 case Mesh::surfaceMeshTriangles: {
00306 const SurfaceMeshOfTriangles& m
00307 = static_cast<const SurfaceMeshOfTriangles&>(M);
00308 integral = __integrate(m, f);
00309 break;
00310 }
00311 case Mesh::surfaceMeshQuadrangles: {
00312 const SurfaceMeshOfQuadrangles& m
00313 = static_cast<const SurfaceMeshOfQuadrangles&>(M);
00314 integral = __integrate(m, f);
00315 break;
00316 }
00317 case Mesh::spectralMesh: {
00318 const SpectralMesh& m
00319 = static_cast<const SpectralMesh&>(M);
00320
00321 const ScalarFunctionBase& integratedFunction = *f.function();
00322 TinyVector<3, real_t> X;
00323 Interval intervalX(m.shape().a()[0],m.shape().b()[0]);
00324 Interval intervalY(m.shape().a()[1],m.shape().b()[1]);
00325 Interval intervalZ(m.shape().a()[2],m.shape().b()[2]);
00326
00327 SpectralConformTransformation transformX(intervalX);
00328 SpectralConformTransformation transformY(intervalY);
00329 SpectralConformTransformation transformZ(intervalZ);
00330
00331 const GaussLobatto& gaussLobattoX = GaussLobattoManager::instance().get(m.degree(0)+1);
00332 const GaussLobatto& gaussLobattoY = GaussLobattoManager::instance().get(m.degree(1)+1);
00333 const GaussLobatto& gaussLobattoZ = GaussLobattoManager::instance().get(m.degree(2)+1);
00334
00335 Vector<real_t> nodesX(gaussLobattoX.numberOfPoints());
00336 for (size_t i=0; i<gaussLobattoX.numberOfPoints(); ++i) {
00337 nodesX[i] = transformX(gaussLobattoX(i));
00338 }
00339 Vector<real_t> nodesY(gaussLobattoY.numberOfPoints());
00340 for (size_t i=0; i<gaussLobattoY.numberOfPoints(); ++i) {
00341 nodesY[i] = transformY(gaussLobattoY(i));
00342 }
00343 Vector<real_t> nodesZ(gaussLobattoZ.numberOfPoints());
00344 for (size_t i=0; i<gaussLobattoZ.numberOfPoints(); ++i) {
00345 nodesZ[i] = transformZ(gaussLobattoZ(i));
00346 }
00347
00348 for (size_t i=0; i < gaussLobattoX.numberOfPoints(); ++i) {
00349 X[0]= nodesX[i];
00350 const real_t& wi = gaussLobattoX.weight(i);
00351 for (size_t j=0; j < gaussLobattoY.numberOfPoints(); ++j) {
00352 X[1] = nodesY[j];
00353 const real_t& wj = gaussLobattoY.weight(j);
00354 for (size_t k=0; k < gaussLobattoZ.numberOfPoints(); ++k) {
00355 X[2]= nodesZ[k];
00356 const real_t& wk = gaussLobattoZ.weight(k);
00357 integral += wi * wj * wk *integratedFunction(X);
00358 }
00359 }
00360 }
00361 integral = integral *1/(transformX.inverseDeterminant()
00362 * transformY.inverseDeterminant()
00363 *transformZ.inverseDeterminant()
00364 );
00365 break;
00366 }
00367 default: {
00368 throw ErrorHandler(__FILE__,__LINE__,
00369 "unexpected mesh type",
00370 ErrorHandler::unexpected);
00371 }
00372 }
00373
00374 Information::instance().unsetMesh();
00375 }
00376
00377 RealExpressionIntegrate::RealExpressionIntegrate(ReferenceCounting<FunctionExpression> f,
00378 ReferenceCounting<MeshExpression> m,
00379 const ScalarDiscretizationTypeBase::Type& discretizationType)
00380 : __realFunction(f),
00381 __mesh(m),
00382 __discretizationType(discretizationType)
00383 {
00384 ;
00385 }
00386
00387 RealExpressionIntegrate::RealExpressionIntegrate(const RealExpressionIntegrate& e)
00388 : __realFunction(e.__realFunction),
00389 __mesh(e.__mesh),
00390 __discretizationType(e.__discretizationType)
00391 {
00392 }
00393
00394 RealExpressionIntegrate::~RealExpressionIntegrate()
00395 {
00396 ;
00397 }
00398
00399
00400
00401
00402 ReferenceCounting<RealExpression>
00403 RealExpressionMinMax::
00404 value()
00405 {
00406 return new RealExpressionValue(__realValue);
00407 }
00408
00409 void RealExpressionMinMax::execute()
00410 {
00411 __mesh->execute();
00412 __realFunction->execute();
00413 Information::instance().setMesh(__mesh->mesh());
00414
00415 if (__operatorName == "max") {
00416
00417 ScalarFunctionMaxComputer computer(__mesh->mesh(),
00418 __realFunction->function());
00419 __realValue = computer.getValue();
00420 } else if (__operatorName == "min") {
00421 ScalarFunctionMinComputer computer(__mesh->mesh(),
00422 __realFunction->function());
00423 __realValue = computer.getValue();
00424 } else {
00425 throw ErrorHandler(__FILE__,__LINE__,
00426 "unknown operator: "+__operatorName,
00427 ErrorHandler::unexpected);
00428 }
00429
00430 Information::instance().unsetMesh();
00431 }
00432
00433 RealExpressionMinMax::RealExpressionMinMax(const std::string& operatorName,
00434 ReferenceCounting<FunctionExpression> f,
00435 ReferenceCounting<MeshExpression> m)
00436 : __operatorName(operatorName),
00437 __realFunction(f),
00438 __mesh(m)
00439 {
00440 ;
00441 }
00442
00443 RealExpressionMinMax::RealExpressionMinMax(const RealExpressionMinMax& e)
00444 : __operatorName(e.__operatorName),
00445 __realFunction(e.__realFunction),
00446 __mesh(e.__mesh)
00447 {
00448 }
00449
00450 RealExpressionMinMax::~RealExpressionMinMax()
00451 {
00452 ;
00453 }
00454
00455
00456
00457
00458 ReferenceCounting<RealExpression>
00459 RealExpressionBoolean::
00460 value()
00461 {
00462 if((*__booleanExpression).boolValue()) {
00463 return new RealExpressionValue(1.);
00464 } else {
00465 return new RealExpressionValue(0.);
00466 }
00467 }
00468
00469 void RealExpressionBoolean::execute()
00470 {
00471 (*__booleanExpression).execute();
00472 }
00473
00474 RealExpressionBoolean::
00475 RealExpressionBoolean(ReferenceCounting<BooleanExpression> be)
00476 : __booleanExpression(be)
00477 {
00478 ;
00479 }
00480
00481 RealExpressionBoolean::RealExpressionBoolean(const RealExpressionBoolean& re)
00482 : RealExpression(re),
00483 __booleanExpression(re.__booleanExpression)
00484 {
00485 ;
00486 }
00487
00488 RealExpressionBoolean::~RealExpressionBoolean()
00489 {
00490 ;
00491 }
00492