dune-localfunctions
2.1.1
|
00001 #ifndef DUNE_LOBATTOBASIS_HH 00002 #define DUNE_LOBATTOBASIS_HH 00003 00004 #include <fstream> 00005 00006 #include <dune/common/forloop.hh> 00007 00008 #include <dune/grid/common/topologyfactory.hh> 00009 #include <dune/grid/common/quadraturerules/lobattoquadrature.hh> 00010 #include <dune/grid/common/genericreferenceelements.hh> 00011 #include <dune/grid/genericgeometry/referenceelements.hh> 00012 00013 #include <dune/localfunctions/utility/lfematrix.hh> 00014 #include <dune/localfunctions/utility/field.hh> 00015 #include <dune/localfunctions/lagrange/lagrangecoefficients.hh> 00016 #include <dune/localfunctions/lagrange/emptypoints.hh> 00017 00018 namespace Dune 00019 { 00020 00021 template< class Field > 00022 struct LobattoPoints 00023 { 00024 LobattoPoints ( unsigned int order ) 00025 : points_( 0 ) 00026 { 00027 if( order < 2 ) 00028 return; 00029 points_.resize(order-1); 00030 #if HAVE_ALGLIB 00031 typedef amp::ampf< Precision< Field >::value > MPField; 00032 #else 00033 typedef Field MPField; 00034 #endif 00035 GenericGeometry::LobattoPoints<MPField> lobatto(order+1); 00036 00037 for (unsigned int i=1;i<order;++i) { 00038 points_[i-1] = field_cast<Field>(lobatto[i].position()); 00039 } 00040 } 00041 00042 const unsigned int size() 00043 { 00044 return points_.size(); 00045 } 00046 const unsigned int order() 00047 { 00048 return points_.size()+1; 00049 } 00050 const Field &point(int i) 00051 { 00052 return points_[i]; 00053 } 00054 std::vector<Field> points_; 00055 }; 00056 00057 template <class Field,class Topology> 00058 struct LobattoInnerPoints; 00059 00060 template <class Field> 00061 struct LobattoInnerPoints<Field,GenericGeometry::Point> 00062 { 00063 static const unsigned int dimension = 0; 00064 static unsigned int size(const unsigned int order) 00065 { 00066 return 1; 00067 } 00068 template <unsigned int dim> 00069 static unsigned int setupSimplex( 00070 const unsigned int iup, 00071 const unsigned int dimStart, 00072 unsigned int startPos, 00073 const std::vector<Field> &points1D, 00074 LagrangePoint< Field, dim > *points ) 00075 { 00076 const unsigned int order = points1D.size()+1; 00077 unsigned int i = order+1-iup; 00078 if (i-2>=points1D.size()) 00079 { 00080 return startPos; 00081 } 00082 for ( unsigned int d=0;d<dimStart;++d ) 00083 { 00084 points[startPos].point_[d] = -points1D[i-2]; 00085 } 00086 00087 return startPos+1; 00088 } 00089 template <unsigned int dim> 00090 static void setup(const std::vector<Field> &points1D, 00091 LagrangePoint< Field, dim > *points ) 00092 { 00093 points->point_[0] = Zero<Field>(); 00094 } 00095 }; 00096 template <class Field,class Base> 00097 struct LobattoInnerPoints<Field,GenericGeometry::Pyramid<Base> > 00098 { 00099 typedef LobattoInnerPoints<Field,Base> LobattoBase; 00100 static const unsigned int dimension = Base::dimension+1; 00101 static unsigned int size(const unsigned int order) 00102 { 00103 if (order<=dimension) return 0; 00104 unsigned int size=0; 00105 for (unsigned int o=0;o<order-dimension;++o) 00106 size += LobattoBase::size(o+dimension); 00107 return size; 00108 } 00109 template <unsigned int dim> 00110 static unsigned int setupSimplex( 00111 const unsigned int iup, 00112 const unsigned int dimStart, 00113 unsigned int startPos, 00114 const std::vector<Field> &points1D, 00115 LagrangePoint< Field, dim > *points ) 00116 { 00117 const unsigned int order = points1D.size()+1; 00118 unsigned int endPos = startPos; 00119 for (unsigned int i=2;i<=order-iup;++i) 00120 { 00121 endPos = LobattoBase::template setupSimplex<dim>(iup+i-1,dimStart,startPos,points1D,points); 00122 for (unsigned int j=startPos;j<endPos;++j) 00123 { 00124 for (unsigned int d=0;d<dimStart;++d) 00125 { 00126 if ( d==dimStart-dimension ) 00127 points[j].point_[d] += dimStart*points1D[i-2]; 00128 else 00129 points[j].point_[d] -= points1D[i-2]; 00130 } 00131 } 00132 startPos = endPos; 00133 } 00134 return endPos; 00135 } 00136 template <unsigned int dim> 00137 static void setup(const std::vector<Field> &points1D, 00138 LagrangePoint< Field, dim > *points ) 00139 { 00140 const unsigned int order = points1D.size()+1; 00141 unsigned int startPos=0,endPos=0; 00142 for (unsigned int i=2;i<=order;++i) 00143 { 00144 endPos = LobattoBase::template setupSimplex<dim>(i-1,dimension,startPos,points1D,points); 00145 00146 for (unsigned int j=startPos;j<endPos;++j) 00147 { 00148 for (unsigned int d=0;d<dimension;++d) 00149 { 00150 if ( d==0 ) 00151 points[j].point_[d] += 1.+int(dimension)*points1D[i-2]; 00152 else 00153 points[j].point_[d] += 1.-points1D[i-2]; 00154 points[j].point_[d] /= (dimension+1); 00155 } 00156 } 00157 startPos = endPos; 00158 } 00159 } 00160 }; 00161 template <class Field,class Base> 00162 struct LobattoInnerPoints<Field,GenericGeometry::Prism<Base> > 00163 { 00164 typedef LobattoInnerPoints<Field,Base> LobattoBase; 00165 static const unsigned int dimension = Base::dimension+1; 00166 static unsigned int size(const unsigned int order) 00167 { 00168 return LobattoBase::size(order)*(order-1); 00169 } 00170 template <unsigned int dim> 00171 static unsigned int setupSimplex( 00172 const unsigned int iup, 00173 const unsigned int dimStart, 00174 unsigned int startPos, 00175 const std::vector<Field> &points1D, 00176 LagrangePoint< Field, dim > *points ) 00177 { 00178 const unsigned int order = points1D.size()+1; 00179 unsigned int endPos = startPos; 00180 for (unsigned int i=2;i<=order-iup;++i) 00181 { 00182 endPos = LobattoBase::template setupSimplex<dim>(iup+i-1,dimStart,startPos,points1D,points); 00183 for (unsigned int j=startPos;j<endPos;++j) 00184 { 00185 for (unsigned int d=0;d<dimStart;++d) 00186 { 00187 if ( d==dimStart-dimension ) 00188 points[j].point_[d] += dimStart*points1D[i-2]; 00189 else 00190 points[j].point_[d] -= points1D[i-2]; 00191 } 00192 } 00193 startPos = endPos; 00194 } 00195 return endPos; 00196 } 00197 template <unsigned int dim> 00198 static void setup(const std::vector<Field> &points1D, 00199 LagrangePoint< Field, dim > *points ) 00200 { 00201 const unsigned int order = points1D.size()+1; 00202 assert(dim>=dimension); 00203 assert(points1D.size()==order-1); 00204 LobattoBase::template setup<dim>(points1D,points); 00205 const unsigned int baseSize = LobattoBase::size(order); 00206 for (unsigned int q=0;q<points1D.size();q++) 00207 { 00208 for (unsigned int i=0;i<baseSize;++i) 00209 { 00210 const unsigned int pos = q*baseSize+i; 00211 for (unsigned int d=0;d<dimension-1;++d) 00212 points[pos].point_[d] = points[i].point_[d]; 00213 points[pos].point_[dimension-1]=points1D[q]; 00214 } 00215 } 00216 } 00217 }; 00218 00219 template< class F, unsigned int dim > 00220 struct LobattoPointSet : public EmptyPointSet<F,dim> 00221 { 00222 // friend class LagrangeCoefficientsFactory<LobattoPointSet,dim,F>; 00223 static const unsigned int dimension = dim; 00224 typedef F Field; 00225 typedef EmptyPointSet<F,dim> Base; 00226 typedef typename Base::LagrangePoint Point; 00227 LobattoPointSet(unsigned int order) 00228 : Base(order) 00229 { 00230 } 00231 00232 template< class Topology > 00233 bool build ( ) 00234 { 00235 unsigned int order = Base::order(); 00236 LobattoPoints<Field> points1D(order); 00237 ForLoop<Setup<Topology>::template InitCodim,0,dimension>:: 00238 apply(order,points1D.points_,points_); 00239 return true; 00240 } 00241 template< class Topology > 00242 static bool supports ( unsigned int order ) 00243 { 00244 if ( GenericGeometry::IsSimplex< Topology >::value || 00245 GenericGeometry::IsGeneralizedPrism< Topology >::value ) 00246 return true; 00247 else 00248 return false; 00249 } 00250 protected: 00251 using Base::points_; 00252 private: 00253 template <class Topology> 00254 struct Setup 00255 { 00256 template <int pdim> 00257 struct InitCodim 00258 { 00259 static const unsigned int codim = dimension-pdim; 00260 static void apply(const unsigned int order, 00261 const std::vector<Field> &points1D, 00262 std::vector<Point> &points) 00263 { 00264 const unsigned int size = GenericGeometry::Size<Topology,codim>::value; 00265 ForLoop<InitSub,0,size-1>::apply(order,points1D,points); 00266 } 00267 template <int i> 00268 struct InitSub 00269 { 00270 typedef typename GenericGeometry::SubTopology<Topology,codim,i>::type SubTopology; 00271 static void apply(const unsigned int order, 00272 const std::vector<Field> &points1D, 00273 std::vector<Point> &points) 00274 { 00275 Setup<Topology>::template Init<SubTopology>::template apply<i>(order,points1D,points); 00276 } 00277 }; 00278 }; 00279 template <class SubTopology> 00280 struct Init 00281 { 00282 static const unsigned int codimension = dimension - SubTopology::dimension; 00283 00284 typedef GenericReferenceElements< Field, dimension > RefElements; 00285 typedef GenericReferenceElement< Field, dimension > RefElement; 00286 typedef typename RefElement::template Codim< codimension >::Mapping Mapping; 00287 00288 typedef LobattoInnerPoints<Field,SubTopology> InnerPoints; 00289 template <unsigned int subEntity> 00290 static void apply(const unsigned int order, 00291 const std::vector<Field> &points1D, 00292 std::vector<Point> &points) 00293 { 00294 unsigned int oldSize = points.size(); 00295 unsigned int size = InnerPoints::size(order); 00296 if (size==0) 00297 return; 00298 points.resize(oldSize+size); 00299 std::vector< LagrangePoint<Field,dimension-codimension> > subPoints(size); 00300 00301 InnerPoints::template setup<dimension-codimension>( points1D,&(subPoints[0]) ); 00302 00303 const GeometryType geoType( Topology::id, dimension ); 00304 const RefElement &refElement = RefElements::general( geoType ); 00305 const Mapping &mapping = refElement.template mapping< codimension >( subEntity ); 00306 00307 LagrangePoint<Field,dimension> *p = &(points[oldSize]); 00308 for ( unsigned int nr = 0; nr<size; ++nr, ++p) 00309 { 00310 p->point_ = mapping.global( subPoints[nr].point_ ); 00311 p->localKey_ = LocalKey( subEntity, codimension, nr ); 00312 #ifndef NDEBUG 00313 bool test = GenericGeometry::ReferenceElement<Topology,Field>::checkInside(p->point_); 00314 if (!test) 00315 std::cout << "not inside" << std::endl; 00316 #endif 00317 } 00318 } 00319 }; 00320 }; 00321 00322 }; 00323 } 00324 #endif // DUNE_LOBATTOBASIS_HH 00325