00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef BASE_FEM_DISCRETIZATION_HPP
00021 #define BASE_FEM_DISCRETIZATION_HPP
00022
00023 #include <FiniteElementTraits.hpp>
00024 #include <Discretization.hpp>
00025
00026 #include <DiscretizedOperators.hpp>
00027 #include <DegreeOfFreedomSet.hpp>
00028
00029 #include <PDE.hpp>
00030 #include <PDEProblem.hpp>
00031 #include <MassOperator.hpp>
00032 #include <FirstOrderOperator.hpp>
00033 #include <DivMuGrad.hpp>
00034 #include <SecondOrderOperator.hpp>
00035
00036 #include <VariationalProblem.hpp>
00037
00038 #include <VariationalOperatorFV.hpp>
00039 #include <VariationalOperatorFdxGV.hpp>
00040 #include <VariationalOperatorFdxV.hpp>
00041 #include <VariationalOperatorFgradGgradV.hpp>
00042
00043 #include <ConformTransformation.hpp>
00044
00045 #include <ErrorHandler.hpp>
00046
00060 template <typename GivenMeshType,
00061 ScalarDiscretizationTypeBase::Type TypeOfDiscretization>
00062 class BaseFEMDiscretization
00063 : public Discretization
00064 {
00065 protected:
00067 typedef GivenMeshType MeshType;
00068
00070 typedef typename MeshType::CellType CellType;
00071
00073 typedef typename FiniteElementTraits<CellType,
00074 TypeOfDiscretization>::Type FiniteElement;
00075
00077 typedef typename FiniteElement::ElementaryMatrix ElementaryMatrixType;
00078
00080 typedef typename FiniteElement::ElementaryVector ElementaryVectorType;
00081
00083 typedef
00084 typename FiniteElementTraits<CellType,
00085 TypeOfDiscretization>::Transformation
00086 ConformTransformation;
00087
00089 typedef
00090 typename FiniteElementTraits<CellType,
00091 TypeOfDiscretization>::JacobianTransformation
00092 JacobianTransformation;
00093
00095 const MeshType& __mesh;
00096
00098 mutable ElementaryMatrixSet <ElementaryMatrixType> __eSet;
00099
00101 mutable DiscretizedOperators<ElementaryMatrixType> __discretizedOperators;
00102
00104 const DegreeOfFreedomSet& __degreeOfFreedomSet;
00105
00113 void
00114 generatesElementaryVector(ElementaryVectorType& eVector,
00115 const JacobianTransformation& J,
00116 const TinyVector<FiniteElement::numberOfQuadraturePoints,real_t>& f) const
00117 {
00118 FiniteElement::instance().integrateWj(eVector,J,f);
00119 }
00120
00127 void
00128 generatesElementaryMatrix(ElementaryMatrixSet<ElementaryMatrixType>& eSet,
00129 const JacobianTransformation& J) const
00130 {
00131 if (eSet.isMassOperator()) {
00132 generatesElementaryMatrix(PDEOperator::massop,
00133 J, eSet.massOperator());
00134 }
00135 if (eSet.isFirstOrderOperator()) {
00136 for (size_t i=0; i<3; ++i) {
00137 if (eSet.isFirstOrderUdxV(i)) {
00138 generatesElementaryMatrix(PDEOperator::firstorderopTransposed,
00139 J,eSet.firstOrderOperatorUdxV(i),i);
00140 }
00141 if (eSet.isFirstOrderDxUV(i)) {
00142 generatesElementaryMatrix(PDEOperator::firstorderop, J,
00143 eSet.firstOrderOperatorDxUV(i),i);
00144 }
00145 }
00146 }
00147 if (eSet.isSecondOrderOperator()) {
00148 for (size_t i=0; i<3; ++i)
00149 for (size_t j=0; j<3; ++j) {
00150 if (eSet.isSecondOrderOperator(i,j)) {
00151 generatesElementaryMatrix(PDEOperator::secondorderop, J,
00152 eSet.secondOrderOperator(i,j),i,j);
00153 }
00154 }
00155 }
00156 if (eSet.isDivMuGrad()) {
00157 generatesElementaryMatrix(PDEOperator::divmugrad, J, eSet.divMuGrad());
00158 }
00159 }
00160
00172 void
00173 generatesElementaryMatrix(const PDEOperator::Type operatorType,
00174 const JacobianTransformation& J,
00175 ElementaryMatrixType& matelem,
00176 const size_t i = 0, const size_t j = 0) const
00177 {
00178 matelem = 0;
00179 switch(operatorType) {
00180 case PDEOperator::firstorderop: {
00181 FiniteElement::instance().integrateDWjWi(matelem,i,J);
00182 matelem *= J.jacobianDet();
00183 break;
00184 }
00185 case PDEOperator::firstorderopTransposed: {
00186 FiniteElement::instance().integrateWjDWi(matelem,i,J);
00187 matelem *= J.jacobianDet();
00188 break;
00189 }
00190 case PDEOperator::divmugrad: {
00191 FiniteElement::instance().integrateDWjDWi(matelem,0,0,J);
00192 FiniteElement::instance().integrateDWjDWi(matelem,1,1,J);
00193 FiniteElement::instance().integrateDWjDWi(matelem,2,2,J);
00194 matelem *= J.jacobianDet();
00195 break;
00196 }
00197 case PDEOperator::secondorderop: {
00198 FiniteElement::instance().integrateDWjDWi(matelem,i,j,J);
00199 matelem *= J.jacobianDet();
00200 break;
00201 }
00202 case PDEOperator::massop: {
00203 FiniteElement::instance().integrateWjWi(matelem,J);
00204 matelem *= J.jacobianDet();
00205 break;
00206 }
00207 default: {
00208 throw ErrorHandler(__FILE__,__LINE__,
00209 "unable to built elementary matrix for this operator",
00210 ErrorHandler::unexpected);
00211 }
00212 }
00213 }
00214
00226 BaseFEMDiscretization(const Problem& p,
00227 const MeshType& mesh,
00228 const DiscretizationType& discretisationType,
00229 BaseMatrix& a,
00230 BaseVector& bb,
00231 const DegreeOfFreedomSet& dof)
00232 : Discretization(discretisationType, p, a, bb),
00233 __mesh(mesh),
00234 __eSet(problem()),
00235 __discretizedOperators(__eSet,problem()),
00236 __degreeOfFreedomSet(dof)
00237 {
00238 ;
00239 }
00240
00245 virtual ~BaseFEMDiscretization()
00246 {
00247 ;
00248 }
00249 };
00250
00251 #endif // BASE_FEM_DISCRETIZATION_HPP