00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _SIMPLELINEARELLIPTICASSEMBLER_HPP_
00029 #define _SIMPLELINEARELLIPTICASSEMBLER_HPP_
00030
00031
00032 #include <vector>
00033 #include <petscvec.h>
00034
00035 #include "LinearSystem.hpp"
00036 #include "AbstractLinearEllipticPde.hpp"
00037 #include "AbstractLinearAssembler.hpp"
00038 #include "BoundaryConditionsContainer.hpp"
00039 #include "GaussianQuadratureRule.hpp"
00040
00041 #include <boost/mpl/void.hpp>
00042 #include <boost/mpl/if.hpp>
00043
00049 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, class CONCRETE = boost::mpl::void_>
00050 class SimpleLinearEllipticAssembler : public AbstractLinearAssembler<ELEMENT_DIM, SPACE_DIM, 1, true, SimpleLinearEllipticAssembler<ELEMENT_DIM, SPACE_DIM, CONCRETE> >
00051 {
00052 public:
00053 static const unsigned E_DIM = ELEMENT_DIM;
00054 static const unsigned S_DIM = SPACE_DIM;
00055 static const unsigned P_DIM = 1u;
00057 friend class TestSimpleLinearEllipticAssembler;
00058
00059 typedef SimpleLinearEllipticAssembler<ELEMENT_DIM, SPACE_DIM, CONCRETE> SelfType;
00060 typedef AbstractLinearAssembler<ELEMENT_DIM, SPACE_DIM, 1, true, SelfType> BaseClassType;
00062 friend class AbstractStaticAssembler<ELEMENT_DIM, SPACE_DIM, 1, true, SelfType>;
00063
00064 protected:
00065
00067 AbstractLinearEllipticPde<ELEMENT_DIM,SPACE_DIM>* mpEllipticPde;
00068
00081 virtual c_matrix<double, 1*(ELEMENT_DIM+1), 1*(ELEMENT_DIM+1)> ComputeMatrixTerm(
00082 c_vector<double, ELEMENT_DIM+1>& rPhi,
00083 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>& rGradPhi,
00084 ChastePoint<SPACE_DIM>& rX,
00085 c_vector<double,1>& rU,
00086 c_matrix<double,1,SPACE_DIM>& rGradU,
00087 Element<ELEMENT_DIM,SPACE_DIM>* pElement)
00088 {
00089 c_matrix<double, SPACE_DIM, SPACE_DIM> pde_diffusion_term = mpEllipticPde->ComputeDiffusionTerm(rX);
00090
00091
00092 if (mpEllipticPde->ComputeLinearInUCoeffInSourceTerm(rX,pElement)!=0)
00093 {
00094 return prod( trans(rGradPhi), c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>(prod(pde_diffusion_term, rGradPhi)) )
00095 - mpEllipticPde->ComputeLinearInUCoeffInSourceTerm(rX,pElement)*outer_prod(rPhi,rPhi);
00096 }
00097 else
00098 {
00099 return prod( trans(rGradPhi), c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>(prod(pde_diffusion_term, rGradPhi)) );
00100 }
00101 }
00102
00114 virtual c_vector<double,1*(ELEMENT_DIM+1)> ComputeVectorTerm(
00115 c_vector<double, ELEMENT_DIM+1>& rPhi,
00116 c_matrix<double, SPACE_DIM, ELEMENT_DIM+1>& rGradPhi,
00117 ChastePoint<SPACE_DIM>& rX,
00118 c_vector<double,1>& rU,
00119 c_matrix<double,1,SPACE_DIM>& rGradU,
00120 Element<ELEMENT_DIM,SPACE_DIM>* pElement)
00121 {
00122 return mpEllipticPde->ComputeConstantInUSourceTerm(rX) * rPhi;
00123 }
00124
00136 virtual c_vector<double, ELEMENT_DIM> ComputeVectorSurfaceTerm(const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>& rSurfaceElement,
00137 c_vector<double, ELEMENT_DIM>& rPhi,
00138 ChastePoint<SPACE_DIM>& rX)
00139 {
00140
00141 double D_times_gradu_dot_n = this->mpBoundaryConditions->GetNeumannBCValue(&rSurfaceElement, rX);
00142 return rPhi * D_times_gradu_dot_n;
00143 }
00144
00145 public:
00146
00155 SimpleLinearEllipticAssembler(AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* pMesh,
00156 AbstractLinearEllipticPde<ELEMENT_DIM,SPACE_DIM>* pPde,
00157 BoundaryConditionsContainer<ELEMENT_DIM,SPACE_DIM,1>* pBoundaryConditions,
00158 unsigned numQuadPoints = 2)
00159 : AbstractAssembler<ELEMENT_DIM,SPACE_DIM,1>(),
00160 BaseClassType(numQuadPoints)
00161 {
00162
00163
00164 mpEllipticPde = pPde;
00165 this->SetMesh(pMesh);
00166 this->SetBoundaryConditionsContainer(pBoundaryConditions);
00167 }
00168
00172 void PrepareForSolve()
00173 {
00174 BaseClassType::PrepareForSolve();
00175 assert(mpEllipticPde != NULL);
00176 }
00177 };
00178
00180 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, class CONCRETE>
00181 struct AssemblerTraits<SimpleLinearEllipticAssembler<ELEMENT_DIM, SPACE_DIM, CONCRETE> >
00182 {
00184 typedef typename boost::mpl::if_<boost::mpl::is_void_<CONCRETE>,
00185 SimpleLinearEllipticAssembler<ELEMENT_DIM, SPACE_DIM, CONCRETE>,
00186 typename AssemblerTraits<CONCRETE>::CVT_CLASS>::type
00187 CVT_CLASS;
00188
00190 typedef typename boost::mpl::if_<boost::mpl::is_void_<CONCRETE>,
00191 SimpleLinearEllipticAssembler<ELEMENT_DIM, SPACE_DIM, CONCRETE>,
00192 typename AssemblerTraits<CONCRETE>::CMT_CLASS>::type
00193 CMT_CLASS;
00194
00196 typedef typename boost::mpl::if_<boost::mpl::is_void_<CONCRETE>,
00197 AbstractAssembler<ELEMENT_DIM, SPACE_DIM, 1u>,
00198 typename AssemblerTraits<CONCRETE>::CMT_CLASS>::type
00199 INTERPOLATE_CLASS;
00200 };
00201
00202 #endif //_SIMPLELINEARELLIPTICASSEMBLER_HPP_