00001 #ifndef DUNE_P1_MASSMATRIX_ASSEMBLER_HH
00002 #define DUNE_P1_MASSMATRIX_ASSEMBLER_HH
00003
00004 #include<iostream>
00005 #include<iomanip>
00006 #include<fstream>
00007 #include<sstream>
00008
00009 #include<dune/common/fvector.hh>
00010 #include<dune/common/fmatrix.hh>
00011 #include<dune/common/exceptions.hh>
00012 #include<dune/grid/common/grid.hh>
00013 #include<dune/grid/common/referenceelements.hh>
00014 #include<dune/grid/common/quadraturerules.hh>
00015 #include<dune/istl/operators.hh>
00016
00017 #include<dune/disc/shapefunctions/lagrangeshapefunctions.hh>
00018 #include<dune/disc/operators/p1operator.hh>
00019 #include<dune/disc/operators/boundaryconditions.hh>
00020 #include<dune/disc/functions/p1function.hh>
00021
00030 namespace Dune
00031 {
00048 template<class GridView, class RT, int comp>
00049 class MassMatrixLocalStiffness
00050 : public LinearLocalStiffness<GridView, RT, comp>
00051 {
00052
00053 typedef typename GridView::Grid::ctype DT;
00054 typedef typename GridView::template Codim<0>::Entity Entity;
00055 typedef typename GridView::template Codim<0>::EntityPointer EEntityPointer;
00056
00057
00058 enum {dim=GridView::dimension};
00059
00060 public:
00061
00062
00063 enum {m=comp};
00064
00065
00066 typedef FieldMatrix<RT,comp,comp> MBlockType;
00067 typedef FieldVector<RT,comp> VBlockType;
00068 typedef array<BoundaryConditions::Flags,comp> BCBlockType;
00069
00071 MassMatrixLocalStiffness (bool procBoundaryAsDirichlet_=true) {
00072
00073 procBoundaryAsDirichlet = procBoundaryAsDirichlet_;
00074
00075 }
00076
00077
00079
00088 void assemble (const Entity& e, int k=1)
00089 {
00090
00091 GeometryType gt = e.type();
00092 const typename LagrangeShapeFunctionSetContainer<DT,RT,dim>::value_type& sfs
00093 = LagrangeShapeFunctions<DT,RT,dim>::general(gt,k);
00094
00095
00096 setcurrentsize(sfs.size());
00097
00098 for (int i=0; i<sfs.size(); i++) {
00099 this->b[i] = 0;
00100 this->bctype[i][0] = BoundaryConditions::neumann;
00101 for (int j=0; j<sfs.size(); j++)
00102 this->A[i][j] = 0;
00103 }
00104
00105
00106
00108 int p=dim;
00109 if (gt.isPrism() || gt.isPyramid())
00110 p = 2;
00111
00112 p *= k;
00113
00114 for (size_t g=0; g<Dune::QuadratureRules<DT,dim>::rule(gt,p).size(); ++g) {
00115
00116
00117 const Dune::FieldVector<DT,dim>& quadPos = Dune::QuadratureRules<DT,dim>::rule(gt,p)[g].position();
00118
00119
00120 double weight = Dune::QuadratureRules<DT,dim>::rule(gt,p)[g].weight();
00121
00122
00123 DT detjac = e.geometry().integrationElement(quadPos);
00124
00125 RT factor = weight*detjac;
00126
00127
00128 RT v[sfs.size()];
00129 for(int i=0; i<sfs.size(); i++)
00130 v[i] = sfs[i].evaluateFunction(0,quadPos);
00131
00132 for(int i=0; i<sfs.size(); i++)
00133 for (int j=0; j<=i; j++ )
00134 for (int k=0; k<comp; k++)
00135 this->A[i][j][k][k] += ( v[i] * v[j] ) * factor;
00136
00137 }
00138
00139 for (int row=0; row<sfs.size(); row++)
00140 for (int col=0; col<=row; col++) {
00141
00142
00143
00144 if (row!=col) {
00145 for (int rcomp=0; rcomp<dim; rcomp++)
00146 for (int ccomp=0; ccomp<dim; ccomp++)
00147 this->A[col][row][ccomp][rcomp] = this->A[row][col][rcomp][ccomp];
00148 }
00149 }
00150
00151 #if 0
00152
00153 typedef typename IntersectionIteratorGetter<G,TypeTag>::IntersectionIterator
00154 IntersectionIterator;
00155
00156 IntersectionIterator endit = IntersectionIteratorGetter<G,TypeTag>::end(e);
00157 for (IntersectionIterator it = IntersectionIteratorGetter<G,TypeTag>::begin(e); it!=endit; ++it)
00158 {
00159
00160
00161 if (it.neighbor()) continue;
00162
00163
00164 typename BoundaryConditions::Flags bctypeface = BoundaryConditions::process;
00165
00166
00167 if (it.boundary())
00168 {
00169 Dune::GeometryType gtface = it.intersectionSelfLocal().type();
00170 for (size_t g=0; g<Dune::QuadratureRules<DT,n-1>::rule(gtface,p).size(); ++g)
00171 {
00172 const Dune::FieldVector<DT,n-1>& facelocal = Dune::QuadratureRules<DT,n-1>::rule(gtface,p)[g].position();
00173 FieldVector<DT,dim> local = it.intersectionSelfLocal().global(facelocal);
00174 FieldVector<DT,dim> global = it.intersectionGlobal().global(facelocal);
00175 bctypeface = problem.bctype(global,e,local);
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 if (bctypeface!=BoundaryConditions::neumann) break;
00186
00187 RT J = problem.J(global,e,local);
00188 double weightface = Dune::QuadratureRules<DT,n-1>::rule(gtface,p)[g].weight();
00189 DT detjacface = it.intersectionGlobal().integrationElement(facelocal);
00190 for (int i=0; i<sfs.size(); i++)
00191 if (bctype[i][0]==BoundaryConditions::neumann)
00192 {
00193 b[i] -= J*sfs[i].evaluateFunction(0,local)*weightface*detjacface;
00194
00195
00196
00197
00198
00199
00200 }
00201 }
00202 if (bctypeface==BoundaryConditions::neumann) continue;
00203 }
00204
00205
00206
00207
00208 if (bctypeface==BoundaryConditions::process && procBoundaryAsDirichlet==false)
00209 continue;
00210
00211
00212 for (int i=0; i<sfs.size(); i++)
00213 {
00214 if (sfs[i].codim()==0) continue;
00215 if (sfs[i].codim()==1)
00216 {
00217 if (sfs[i].entity()==it.numberInSelf())
00218 {
00219 if (bctype[i][0]<bctypeface)
00220 {
00221 bctype[i][0] = bctypeface;
00222 if (bctypeface==BoundaryConditions::process)
00223 b[i] = 0;
00224 if (bctypeface==BoundaryConditions::dirichlet)
00225 {
00226 Dune::FieldVector<DT,dim> global = e.geometry().global(sfs[i].position());
00227 b[i] = problem.g(global,e,sfs[i].position());
00228 }
00229 }
00230 }
00231 continue;
00232 }
00233
00234 for (int j=0; j<ReferenceElements<DT,dim>::general(gt).size(it.numberInSelf(),1,sfs[i].codim()); j++)
00235 if (sfs[i].entity()==ReferenceElements<DT,dim>::general(gt).subEntity(it.numberInSelf(),1,j,sfs[i].codim()))
00236 {
00237 if (bctype[i][0]<bctypeface)
00238 {
00239 bctype[i][0] = bctypeface;
00240 if (bctypeface==BoundaryConditions::process)
00241 b[i] = 0;
00242 if (bctypeface==BoundaryConditions::dirichlet)
00243 {
00244 Dune::FieldVector<DT,dim> global = e.geometry().global(sfs[i].position());
00245 b[i] = problem.g(global,e,sfs[i].position());
00246 }
00247 }
00248 }
00249 }
00250 }
00251 #endif
00252 }
00253
00255 void assembleBoundaryCondition (const Entity& e, int k=1)
00256 {
00257 DUNE_THROW(NotImplemented, "!");
00258 }
00259
00260 private:
00261
00262 bool procBoundaryAsDirichlet;
00263
00264 };
00265
00267 }
00268 #endif