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;
00056
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 AbstractLinearEllipticPde<ELEMENT_DIM,SPACE_DIM>* mpEllipticPde;
00066
00067 protected:
00073 virtual c_matrix<double,1*(ELEMENT_DIM+1),1*(ELEMENT_DIM+1)> ComputeMatrixTerm(
00074 c_vector<double, ELEMENT_DIM+1> &rPhi,
00075 c_matrix<double, ELEMENT_DIM, ELEMENT_DIM+1> &rGradPhi,
00076 ChastePoint<SPACE_DIM> &rX,
00077 c_vector<double,1> &u,
00078 c_matrix<double,1,SPACE_DIM> &rGradU,
00079 Element<ELEMENT_DIM,SPACE_DIM>* pElement)
00080 {
00081 c_matrix<double, ELEMENT_DIM, ELEMENT_DIM> pde_diffusion_term = mpEllipticPde->ComputeDiffusionTerm(rX);
00082
00083
00084 if(mpEllipticPde->ComputeLinearInUCoeffInSourceTerm(rX,pElement)!=0)
00085 {
00086 return prod( trans(rGradPhi), c_matrix<double, ELEMENT_DIM, ELEMENT_DIM+1>(prod(pde_diffusion_term, rGradPhi)) )
00087 - mpEllipticPde->ComputeLinearInUCoeffInSourceTerm(rX,pElement)*outer_prod(rPhi,rPhi);
00088 }
00089 else
00090 {
00091 return prod( trans(rGradPhi), c_matrix<double, ELEMENT_DIM, ELEMENT_DIM+1>(prod(pde_diffusion_term, rGradPhi)) );
00092 }
00093 }
00094
00099 virtual c_vector<double,1*(ELEMENT_DIM+1)> ComputeVectorTerm(
00100 c_vector<double, ELEMENT_DIM+1> &rPhi,
00101 c_matrix<double, ELEMENT_DIM, ELEMENT_DIM+1> &rGradPhi,
00102 ChastePoint<SPACE_DIM> &rX,
00103 c_vector<double,1> &u,
00104 c_matrix<double,1,SPACE_DIM> &rGradU,
00105 Element<ELEMENT_DIM,SPACE_DIM>* pElement)
00106 {
00107 return mpEllipticPde->ComputeConstantInUSourceTerm(rX) * rPhi;
00108 }
00109
00110
00111
00112 virtual c_vector<double, ELEMENT_DIM> ComputeVectorSurfaceTerm(const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM> &rSurfaceElement,
00113 c_vector<double, ELEMENT_DIM> &rPhi,
00114 ChastePoint<SPACE_DIM> &rX )
00115 {
00116
00117 double D_times_gradu_dot_n = this->mpBoundaryConditions->GetNeumannBCValue(&rSurfaceElement, rX);
00118 return rPhi * D_times_gradu_dot_n;
00119 }
00120
00121
00122
00123 public:
00127 SimpleLinearEllipticAssembler(AbstractMesh<ELEMENT_DIM,SPACE_DIM>* pMesh,
00128 AbstractLinearEllipticPde<ELEMENT_DIM,SPACE_DIM>* pPde,
00129 BoundaryConditionsContainer<ELEMENT_DIM,SPACE_DIM,1>* pBoundaryConditions,
00130 unsigned numQuadPoints = 2) :
00131 AbstractAssembler<ELEMENT_DIM,SPACE_DIM,1>(),
00132 BaseClassType(numQuadPoints)
00133 {
00134
00135
00136 mpEllipticPde = pPde;
00137 this->SetMesh(pMesh);
00138 this->SetBoundaryConditionsContainer(pBoundaryConditions);
00139 }
00140
00144 void PrepareForSolve()
00145 {
00146 BaseClassType::PrepareForSolve();
00147 assert(mpEllipticPde != NULL);
00148 }
00149 };
00150
00152 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM, class CONCRETE>
00153 struct AssemblerTraits<SimpleLinearEllipticAssembler<ELEMENT_DIM, SPACE_DIM, CONCRETE> >
00154 {
00155 typedef typename boost::mpl::if_<boost::mpl::is_void_<CONCRETE>,
00156 SimpleLinearEllipticAssembler<ELEMENT_DIM, SPACE_DIM, CONCRETE>,
00157 typename AssemblerTraits<CONCRETE>::CVT_CLS>::type
00158 CVT_CLS;
00159 typedef typename boost::mpl::if_<boost::mpl::is_void_<CONCRETE>,
00160 SimpleLinearEllipticAssembler<ELEMENT_DIM, SPACE_DIM, CONCRETE>,
00161 typename AssemblerTraits<CONCRETE>::CMT_CLS>::type
00162 CMT_CLS;
00164 typedef typename boost::mpl::if_<boost::mpl::is_void_<CONCRETE>,
00165 AbstractAssembler<ELEMENT_DIM, SPACE_DIM, 1u>,
00166 typename AssemblerTraits<CONCRETE>::CMT_CLS>::type
00167 INTERPOLATE_CLS;
00168 };
00169
00170 #endif //_SIMPLELINEARELLIPTICASSEMBLER_HPP_