pk2dlocalbasis.hh

Go to the documentation of this file.
00001 #ifndef DUNE_PK2DLOCALBASIS_HH
00002 #define DUNE_PK2DLOCALBASIS_HH
00003 
00004 #include <dune/common/fmatrix.hh>
00005 
00006 #include <dune/localfunctions/common/localbasis.hh>
00007 
00008 namespace Dune 
00009 {
00022   template<class D, class R, unsigned int k>
00023   class Pk2DLocalBasis
00024   {
00025   public:
00026 
00028         enum {N = (k+1)*(k+2)/2};
00029 
00033         enum {O = k};
00034 
00035         typedef LocalBasisTraits<D,2,Dune::FieldVector<D,2>,R,1,Dune::FieldVector<R,1>,
00036                                                            Dune::FieldMatrix<R,1,2> > Traits;
00037 
00039   Pk2DLocalBasis ()
00040   {
00041         for (unsigned int i=0; i<=k; i++) 
00042             pos[i] = (1.0*i)/k;
00043   }
00044 
00046   unsigned int size () const
00047   {
00048         return N;
00049   }
00050 
00052   inline void evaluateFunction (const typename Traits::DomainType& x,
00053                                                                 std::vector<typename Traits::RangeType>& out) const
00054   { 
00055         out.resize(N);
00056         int n=0;
00057         for (unsigned int j=0; j<=k; j++)
00058           for (unsigned int i=0; i<=k-j; i++)
00059                 {
00060                   out[n] = 1.0;
00061                   for (unsigned int alpha=0; alpha<i; alpha++) 
00062                         out[n] *= (x[0]-pos[alpha])/(pos[i]-pos[alpha]);
00063                   for (unsigned int beta=0; beta<j; beta++) 
00064                         out[n] *= (x[1]-pos[beta])/(pos[j]-pos[beta]);
00065                   for (unsigned int gamma=i+j+1; gamma<=k; gamma++) 
00066                         out[n] *= (pos[gamma]-x[0]-x[1])/(pos[gamma]-pos[i]-pos[j]);
00067                   n++;
00068                 }
00069   }
00070 
00072   inline void 
00073   evaluateJacobian (const typename Traits::DomainType& x,         // position
00074                                         std::vector<typename Traits::JacobianType>& out) const      // return value
00075   {  
00076         out.resize(N);
00077         int n=0;
00078         for (unsigned int j=0; j<=k; j++)
00079           for (unsigned int i=0; i<=k-j; i++)
00080                 {
00081                   // x_0 derivative
00082                   out[n][0][0] = 0.0;
00083                   R factor=1.0;
00084                   for (unsigned int beta=0; beta<j; beta++) 
00085                         factor *= (x[1]-pos[beta])/(pos[j]-pos[beta]);
00086                   for (unsigned int a=0; a<i; a++)
00087                         {
00088                           R product=factor;
00089                           for (unsigned int alpha=0; alpha<i; alpha++)
00090                                 if (alpha==a)
00091                                   product *= 1.0/(pos[i]-pos[alpha]);
00092                                 else
00093                                   product *= (x[0]-pos[alpha])/(pos[i]-pos[alpha]);
00094                           for (unsigned int gamma=i+j+1; gamma<=k; gamma++) 
00095                                 product *= (pos[gamma]-x[0]-x[1])/(pos[gamma]-pos[i]-pos[j]);
00096                           out[n][0][0] += product;
00097                         }
00098                   for (unsigned int c=i+j+1; c<=k; c++)
00099                         {
00100                           R product=factor;
00101                           for (unsigned int alpha=0; alpha<i; alpha++)
00102                                 product *= (x[0]-pos[alpha])/(pos[i]-pos[alpha]);
00103                           for (unsigned int gamma=i+j+1; gamma<=k; gamma++) 
00104                                 if (gamma==c)
00105                                   product *= -1.0/(pos[gamma]-pos[i]-pos[j]);
00106                                 else
00107                                   product *= (pos[gamma]-x[0]-x[1])/(pos[gamma]-pos[i]-pos[j]);
00108                           out[n][0][0] += product;
00109                         }
00110 
00111                   // x_1 derivative
00112                   out[n][0][1] = 0.0;
00113                   factor = 1.0;
00114                   for (unsigned int alpha=0; alpha<i; alpha++) 
00115                         factor *= (x[0]-pos[alpha])/(pos[i]-pos[alpha]);
00116                   for (unsigned int b=0; b<j; b++) 
00117                         {
00118                           R product=factor;
00119                           for (unsigned int beta=0; beta<j; beta++)
00120                                 if (beta==b)
00121                                   product *= 1.0/(pos[j]-pos[beta]);
00122                                 else
00123                                   product *= (x[1]-pos[beta])/(pos[j]-pos[beta]);
00124                           for (unsigned int gamma=i+j+1; gamma<=k; gamma++) 
00125                                 product *= (pos[gamma]-x[0]-x[1])/(pos[gamma]-pos[i]-pos[j]);
00126                           out[n][0][1] += product;
00127                         }
00128                   for (unsigned int c=i+j+1; c<=k; c++)
00129                         {
00130                           R product=factor;
00131                           for (unsigned int beta=0; beta<j; beta++)
00132                                 product *= (x[1]-pos[beta])/(pos[j]-pos[beta]);
00133                           for (unsigned int gamma=i+j+1; gamma<=k; gamma++)
00134                                 if (gamma==c)
00135                                   product *= -1.0/(pos[gamma]-pos[i]-pos[j]);
00136                                 else
00137                                   product *= (pos[gamma]-x[0]-x[1])/(pos[gamma]-pos[i]-pos[j]);
00138                           out[n][0][1] += product;
00139                         }
00140 
00141                   n++;
00142                 }
00143 
00144         //      for (int i=0; i<N; i++)
00145         //        std::cout << i << " " << out[i][0][0] << " " << out[i][0][1] << std::endl;
00146   }
00147 
00149   unsigned int order () const
00150   {
00151         return k;
00152   }
00153 
00154 private:
00155   R pos[k+1]; // positions on the interval
00156 };
00157 
00158 
00159 //Specialization for k=0
00160 template<class D, class R>
00161 class Pk2DLocalBasis<D,R,0>
00162 {
00163 public:
00164   typedef LocalBasisTraits<D,2,Dune::FieldVector<D,2>,R,1,Dune::FieldVector<R,1>,
00165                              Dune::FieldMatrix<R,1,2> > Traits;
00166 
00168 enum {N = 1};
00169 
00171 enum {O = 0};
00172 
00173 unsigned int size () const
00174 {
00175   return 1;
00176 }
00177 
00178 inline void evaluateFunction (const typename Traits::DomainType& in,
00179                                                           std::vector<typename Traits::RangeType>& out) const
00180 { 
00181   out.resize(1);
00182   out[0] = 1;
00183 }
00184 
00185 // evaluate derivative of a single component
00186 inline void 
00187 evaluateJacobian (const typename Traits::DomainType& in,         // position
00188                                   std::vector<typename Traits::JacobianType>& out) const      // return value
00189 {  
00190   out.resize(1);
00191   out[0][0][0] = 0; out[0][0][1] = 0; 
00192 }
00193 
00194 // local interpolation of a function
00195 template<typename E, typename F, typename C>
00196 void interpolate (const E& e, const F& f, std::vector<C>& out) const
00197 {
00198   typename Traits::DomainType x;
00199   typename Traits::RangeType y;
00200   x[0] = 1.0/3.0; x[1] = 1.0/3.0; f.eval_local(e,x,y); out[0] = y;
00201 }
00202 
00203 unsigned int order () const
00204 {
00205   return 0;
00206 }
00207 };
00208 }
00209 #endif

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].