00001 #ifndef DG_FUNCTION_HH
00002 #define DG_FUNCTION_HH
00003
00004 #include <dune/istl/bvector.hh>
00005 #include <dune/grid/common/quadraturerules.hh>
00006 #include <dune/disc/functions/functions.hh>
00007 #include <dune/disc/shapefunctions/dgspace/monomialshapefunctions.hh>
00008 #include <dune/disc/shapefunctions/dgspace/orthonormalshapefunctions.hh>
00009
00016 namespace Dune {
00017
00023
00024
00038 template<class GV, class RT, int o,
00039 template<class,class,int,int> class SFSC = MonomialShapeFunctionSetContainer>
00040 class DGFunction :
00041 virtual public GridFunction<typename GV::Grid,RT,1>,
00042 virtual public GridFunctionDefault<typename GV::Grid,RT,1>,
00043 virtual public GridFunctionGlobalEvalDefault<GV,RT,1>,
00044 virtual public FunctionDefault<typename GV::Grid::ctype,RT,GV::Grid::dimension,1>,
00045 virtual public H1Function<typename GV::Grid::ctype,RT,GV::Grid::dimension,1>,
00046 virtual public GridFunctionGlobalDifferentiationDefault<GV,RT,1>,
00047 virtual public L2Function<typename GV::Grid::ctype,RT,GV::Grid::dimension,1>
00048 {
00049 typedef typename GV::Grid G;
00050 typedef typename GV::IndexSet IS;
00051
00052 protected:
00054 typedef typename G::ctype DT;
00055
00057 typedef typename G::template Codim<0>::Entity Entity;
00058
00060 enum {n=G::dimension};
00061
00063 DGFunction (const DGFunction&);
00064
00065 public:
00067 typedef SFSC<DT,RT,G::dimension,o> ShapeFunctionSetContainer;
00069 typedef typename ShapeFunctionSetContainer::ShapeFunctionSet ShapeFunctionSet;
00070 protected:
00072 static const int BlockSize = ShapeFunctionSetContainer::maxsize;
00073 public:
00074 typedef RT ResultType;
00075 typedef DT DomainType;
00076 typedef
00077 FieldVector<ResultType,BlockSize> BlockType;
00078 typedef BlockVector< BlockType > RepresentationType;
00079
00081 DGFunction (const GV& gv)
00082 : GridFunctionGlobalEvalDefault<GV,RT,1>(gv)
00083 , GridFunctionGlobalDifferentiationDefault<GV,RT,1>(gv)
00084 , gv_(gv)
00085 {
00086 coeff_.resize(gv.indexSet().size(0), false);
00087 }
00088
00090 ~DGFunction () {}
00091
00093
00099 virtual RT evallocal (int comp, const Entity& e, const Dune::FieldVector<DT,n>& xi) const
00100 {
00101 assert(comp == 0);
00102
00103 RT value = 0;
00104 const ShapeFunctionSet & s = shapefnkts_(e.type(),o);
00105 int eid = gv_.indexSet().index(e);
00106 for (int i=0; i<BlockSize; ++i)
00107 {
00108 value += coeff_[eid][i] * s[i].evaluateFunction(0, xi);
00109 }
00110 return value;
00111 }
00112
00113 virtual RT derivativelocal (int comp, const Dune::FieldVector<int,n>& d,
00114 const Entity& e, const Dune::FieldVector<DT,n>& xi) const
00115 {
00116 assert(comp == 0);
00117
00118 const ShapeFunctionSet & s = shapefnkts_(e.type(),o);
00119
00120 typedef Dune::FieldVector<DT,n> Gradient;
00121 typedef Dune::FieldMatrix<DT,n,n> JacobianInverseMatrix;
00122 Gradient grad(0);
00123 Gradient grad_phi_ei;
00124 JacobianInverseMatrix invj;
00125 invj = e.geometry().jacobianInverseTransposed(xi);
00126 int eid = gv_.indexSet().index(e);
00127
00128 for (int i=0; i<BlockSize; ++i)
00129 {
00130 Gradient tmp(0.0);
00131 for (int d=0; d<n; d++)
00132 tmp[d] = s[i].evaluateDerivative(0, d, xi);
00133 grad_phi_ei = 0;
00134 invj.umv(tmp,grad_phi_ei);
00135 for (int d=0; d<n; d++)
00136 grad[d] += grad_phi_ei[d] * coeff_[eid][i];
00137 }
00138
00139 for (int u=0; u<n; u++)
00140 if (d[u] == 1) return grad[u];
00141 DUNE_THROW(NotImplemented,"Can not evaluate this derivative: d=" << d);
00142 }
00143
00145
00149 void interpolate (const C0Function<DT,RT,n,1>& u)
00150 {
00151 typedef typename GV::template Codim<0>::Iterator Iterator;
00152
00153 Iterator it = gv_.template begin<0> ();
00154 const Iterator endit = gv_.template end<0> ();
00155
00156 for(; it != endit; ++it)
00157 {
00158 FieldVector<RT,BlockSize> l2_b(0.0);
00159 FieldMatrix<RT,BlockSize,BlockSize> l2_A(0.0);
00160
00161 const ShapeFunctionSet & s = shapefnkts_(it->type(),o);
00162 int eid = gv_.IndexSet().index(*it);
00163 coeff_[eid] = 0;
00164
00165
00166 typedef QuadratureRule<DT,n> Quad;
00167 typedef typename QuadratureRule<DT,n>::const_iterator QuadIterator;
00168 const Quad& quad =
00169 QuadratureRules<DT,n>::rule(it->type(),
00170 o*getGeometryOrder(it->type()));
00171
00172 for (QuadIterator q=quad.begin(); q!=quad.end(); ++q)
00173 {
00174 FieldVector<DT,n> c = q->position();
00175 FieldVector<DT,n> cg = it->geometry().global(c);
00176 for(int i=0; i<BlockSize; i++)
00177 {
00178
00179 RT det = it->geometry().integrationElement(c);
00180 RT value = u.eval(0, cg);
00181 RT phi_i = s[i].evaluateFunction(0, c);
00182 l2_b[i] += q->weight() * phi_i * value * det;
00183 for(int j=0; j<BlockSize; j++)
00184 {
00185
00186 RT phi_j = s[j].evaluateFunction(0, c);
00187 l2_A[i][j] += q->weight() * phi_i * phi_j * det;
00188 }
00189 }
00190 }
00191
00192 fm_solve(l2_A, coeff_[eid], l2_b);
00193 }
00194 }
00195
00197
00201 const RepresentationType& operator* () const
00202 {
00203 return coeff_;
00204 }
00205
00207
00211 RepresentationType& operator* ()
00212 {
00213 return coeff_;
00214 }
00215
00220 void preAdapt ()
00221 {
00222 DUNE_THROW(NotImplemented, "preAdapt()");
00223 }
00224
00234 void postAdapt ()
00235 {
00236 DUNE_THROW(NotImplemented, "postAdapt()");
00237 }
00238
00240 typename VTKWriter<GV>::VTKFunction *
00241 vtkFunction (std::string s) const
00242 {
00243 return new VTKGridFunctionWrapper<GV,RT,1>(*this,s);
00244 }
00245
00246 protected:
00247 int getGeometryOrder(const Dune::GeometryType & t)
00248 {
00249 if (t.isLine()) return 1;
00250 if (t.isSimplex()) return 1;
00251 if (t.isCube()) return t.dim();
00252 if (t.isPyramid()) return 2;
00253 if (t.isPrism()) return 2;
00254 DUNE_THROW(Dune::Exception,"Unknown GeometryType " << t);
00255 }
00256
00257
00258
00259 const GV gv_;
00260
00261
00262 ShapeFunctionSetContainer shapefnkts_;
00263
00264
00265 RepresentationType coeff_;
00266 };
00267
00275 template<class G, class RT, int o,
00276 template<class,class,int,int> class SFSC = MonomialShapeFunctionSetContainer>
00277 class LeafDGFunction : public DGFunction<typename G::LeafGridView,RT,o,SFSC>
00278 {
00279 public:
00280 LeafDGFunction (const G& grid) :
00281 GridFunctionGlobalEvalDefault<typename G::LeafGridView,RT,1>(grid.leafView()),
00282 GridFunctionGlobalDifferentiationDefault<typename G::LeafGridView,RT,1>(grid.leafView()),
00283 DGFunction<typename G::LeafGridView,RT,o,SFSC>(grid.leafView())
00284 {}
00285 };
00286
00294 template<class G, class RT, int o,
00295 template<class,class,int,int> class SFSC = MonomialShapeFunctionSetContainer>
00296 class LevelDGFunction : public DGFunction<typename G::LevelGridView,RT,o,SFSC>
00297 {
00298 public:
00299 LevelDGFunction (const G& grid, int level) :
00300 GridFunctionGlobalEvalDefault<typename G::LevelGridView,RT,1>(grid.levelView(level)),
00301 GridFunctionGlobalDifferentiationDefault<typename G::LevelGridView,RT,1>(grid.levelView(level)),
00302 DGFunction<typename G::LevelGridView,RT,o,SFSC>(grid.levelView(level))
00303 {}
00304 };
00305
00308 }
00309
00310 #endif // DG_FUNCTION_HH