massmatrix.hh

Go to the documentation of this file.
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         // grid types
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         // some other sizes
00058         enum {dim=GridView::dimension};
00059 
00060   public:
00061 
00062       // Number of components for the global assembler to collect
00063       enum {m=comp};
00064 
00065       // types for matrics, vectors and boundary conditions
00066       typedef FieldMatrix<RT,comp,comp> MBlockType; // one entry in the stiffness matrix
00067       typedef FieldVector<RT,comp> VBlockType;   // one entry in the global vectors
00068       typedef array<BoundaryConditions::Flags,comp> BCBlockType;     // componentwise boundary conditions
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           // extract some important parameters
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           // clear assemble data
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           // Loop over all quadrature points and assemble matrix and right hand side
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               // pos of integration point
00117               const Dune::FieldVector<DT,dim>& quadPos = Dune::QuadratureRules<DT,dim>::rule(gt,p)[g].position();
00118               
00119               // weight of quadrature point
00120               double weight = Dune::QuadratureRules<DT,dim>::rule(gt,p)[g].weight();
00121               
00122               // determinant of jacobian
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                   // Complete the symmetric matrix by copying the lower left triangular matrix
00143                   // to the upper right one
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           // evaluate boundary conditions via intersection iterator
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                   // if we have a neighbor then we assume there is no boundary
00160                   // (it might still be an interior boundary ... )
00161                   if (it.neighbor()) continue;
00162 
00163                   // determine boundary condition type for this face, initialize with processor boundary
00164                   typename BoundaryConditions::Flags bctypeface = BoundaryConditions::process;
00165 
00166                   // handle face on exterior boundary
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); // eval bctype
00176 
00177 //                                std::cout << "=== Boundary found"
00178 //                                                      << " facenumber=" << it.numberInSelf()
00179 //                                                      << " quadpoint=" << g
00180 //                                                      << " facelocal=" << facelocal
00181 //                                                      << " local=" << local
00182 //                                                      << " global=" << global
00183 //                                                      << std::endl;
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++) // loop over test function number
00191                                       if (bctype[i][0]==BoundaryConditions::neumann)
00192                                           {
00193                                                 b[i] -= J*sfs[i].evaluateFunction(0,local)*weightface*detjacface;
00194 //                                              std::cout << "Neumann BC found, accumulating" 
00195 //                                                                << -J*sfs[i].evaluateFunction(0,local)*weightface*detjacface 
00196 //                                                                << std::endl;
00197 //                                              std::cout << "J=" << J << " shapef=" << sfs[i].evaluateFunction(0,local)
00198 //                                                                << " weight=" << weightface
00199 //                                                                << " detjac=" << detjacface << std::endl;
00200                                           }
00201                                 }
00202                           if (bctypeface==BoundaryConditions::neumann) continue; // was a neumann face, go to next face
00203                         }
00204 
00205                   // If we are here, then its either an exterior boundary face with Dirichlet condition
00206                   // or a processor boundary (i.e. neither boundary() nor neighbor() was true)
00207                   // How processor boundaries are handled depends on the processor boundary mode
00208                   if (bctypeface==BoundaryConditions::process && procBoundaryAsDirichlet==false) 
00209                         continue; // then it acts like homogeneous Neumann
00210 
00211                   // now handle exterior or interior Dirichlet boundary
00212                   for (int i=0; i<sfs.size(); i++) // loop over test function number
00213                         {
00214                           if (sfs[i].codim()==0) continue; // skip interior dof
00215                           if (sfs[i].codim()==1) // handle face dofs
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                           // handle subentities of this face
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         // parameters given in constructor
00262         bool procBoundaryAsDirichlet;
00263 
00264   };
00265 
00267 }
00268 #endif

Generated on 6 Jan 2009 with Doxygen (ver 1.5.1) [logfile].