3#ifndef DUNE_MONOMIALBASIS_HH
4#define DUNE_MONOMIALBASIS_HH
11#include <dune/geometry/topologyfactory.hh>
14#include <dune/localfunctions/utility/field.hh>
15#include <dune/localfunctions/utility/multiindex.hh>
16#include <dune/localfunctions/utility/tensor.hh>
69 template<
class Topology >
70 class MonomialBasisSize;
72 template<
class Topology,
class F >
81 class MonomialBasisSize< Impl::Point >
83 typedef MonomialBasisSize< Impl::Point > This;
86 static This &instance ()
88 static This _instance;
92 typedef Impl::Point Topology;
94 friend class MonomialBasisSize< Impl::Prism< Topology > >;
95 friend class MonomialBasisSize< Impl::Pyramid< Topology > >;
97 mutable unsigned int maxOrder_;
99 mutable unsigned int *sizes_;
101 mutable unsigned int *numBaseFunctions_;
106 numBaseFunctions_( 0 )
111 ~MonomialBasisSize ()
114 delete[] numBaseFunctions_;
117 unsigned int operator() (
const unsigned int order )
const
119 return numBaseFunctions_[ order ];
122 unsigned int maxOrder ()
const
127 void computeSizes (
unsigned int order )
const
129 if (order <= maxOrder_)
135 delete [] numBaseFunctions_;
136 sizes_ =
new unsigned int [ order+1 ];
137 numBaseFunctions_ =
new unsigned int [ order+1 ];
140 numBaseFunctions_[ 0 ] = 1;
141 for(
unsigned int k = 1; k <= order; ++k )
144 numBaseFunctions_[ k ] = 1;
149 template<
class BaseTopology >
150 class MonomialBasisSize< Impl::Prism< BaseTopology > >
152 typedef MonomialBasisSize< Impl::Prism< BaseTopology > > This;
155 static This &instance ()
157 static This _instance;
161 typedef Impl::Prism< BaseTopology > Topology;
163 friend class MonomialBasisSize< Impl::Prism< Topology > >;
164 friend class MonomialBasisSize< Impl::Pyramid< Topology > >;
166 mutable unsigned int maxOrder_;
168 mutable unsigned int *sizes_;
170 mutable unsigned int *numBaseFunctions_;
175 numBaseFunctions_( 0 )
180 ~MonomialBasisSize ()
183 delete[] numBaseFunctions_;
186 unsigned int operator() (
const unsigned int order )
const
188 return numBaseFunctions_[ order ];
191 unsigned int maxOrder()
const
196 void computeSizes (
unsigned int order )
const
198 if (order <= maxOrder_)
204 delete[] numBaseFunctions_;
205 sizes_ =
new unsigned int[ order+1 ];
206 numBaseFunctions_ =
new unsigned int[ order+1 ];
208 MonomialBasisSize<BaseTopology> &baseBasis =
209 MonomialBasisSize<BaseTopology>::instance();
210 baseBasis.computeSizes( order );
211 const unsigned int *
const baseSizes = baseBasis.sizes_;
212 const unsigned int *
const baseNBF = baseBasis.numBaseFunctions_;
215 numBaseFunctions_[ 0 ] = 1;
216 for(
unsigned int k = 1; k <= order; ++k )
218 sizes_[ k ] = baseNBF[ k ] + k*baseSizes[ k ];
219 numBaseFunctions_[ k ] = numBaseFunctions_[ k-1 ] + sizes_[ k ];
224 template<
class BaseTopology >
225 class MonomialBasisSize< Impl::Pyramid< BaseTopology > >
227 typedef MonomialBasisSize< Impl::Pyramid< BaseTopology > > This;
230 static This &instance ()
232 static This _instance;
236 typedef Impl::Pyramid< BaseTopology > Topology;
238 friend class MonomialBasisSize< Impl::Prism< Topology > >;
239 friend class MonomialBasisSize< Impl::Pyramid< Topology > >;
241 mutable unsigned int maxOrder_;
243 mutable unsigned int *sizes_;
245 mutable unsigned int *numBaseFunctions_;
250 numBaseFunctions_( 0 )
255 ~MonomialBasisSize ()
258 delete[] numBaseFunctions_;
261 unsigned int operator() (
const unsigned int order )
const
263 return numBaseFunctions_[ order ];
266 unsigned int maxOrder()
const
271 void computeSizes (
unsigned int order )
const
273 if (order <= maxOrder_)
279 delete[] numBaseFunctions_;
280 sizes_ =
new unsigned int[ order+1 ];
281 numBaseFunctions_ =
new unsigned int[ order+1 ];
283 MonomialBasisSize<BaseTopology> &baseBasis =
284 MonomialBasisSize<BaseTopology>::instance();
286 baseBasis.computeSizes( order );
288 const unsigned int *
const baseNBF = baseBasis.numBaseFunctions_;
290 numBaseFunctions_[ 0 ] = 1;
291 for(
unsigned int k = 1; k <= order; ++k )
293 sizes_[ k ] = baseNBF[ k ];
294 numBaseFunctions_[ k ] = numBaseFunctions_[ k-1 ] + sizes_[ k ];
305 template<
int mydim,
int dim,
class F >
306 struct MonomialBasisHelper
308 typedef MonomialBasisSize< typename Impl::SimplexTopology< mydim >::type > MySize;
309 typedef MonomialBasisSize< typename Impl::SimplexTopology< dim >::type > Size;
311 static void copy (
const unsigned int deriv, F *&wit, F *&rit,
312 const unsigned int numBaseFunctions,
const F &z )
315 MySize &mySize = MySize::instance();
316 Size &size = Size::instance();
318 const F *
const rend = rit + size( deriv )*numBaseFunctions;
319 for( ; rit != rend; )
326 for(
unsigned d = 1; d <= deriv; ++d )
329 const F *
const derivEnd = rit + mySize.sizes_[ d ];
333 const F *
const drend = rit + mySize.sizes_[ d ] - mySize.sizes_[ d-1 ];
334 for( ; rit != drend ; ++rit, ++wit )
338 for (
unsigned int j=1; j<d; ++j)
340 const F *
const drend = rit + mySize.sizes_[ d-j ] - mySize.sizes_[ d-j-1 ];
341 for( ; rit != drend ; ++prit, ++rit, ++wit )
342 *wit = F(j) * *prit + z * *rit;
344 *wit = F(d) * *prit + z * *rit;
345 ++prit, ++rit, ++wit;
346 assert(derivEnd == rit);
347 rit += size.sizes_[d] - mySize.sizes_[d];
348 prit += size.sizes_[d-1] - mySize.sizes_[d-1];
349 const F *
const emptyWitEnd = wit + size.sizes_[d] - mySize.sizes_[d];
350 for ( ; wit != emptyWitEnd; ++wit )
362 template<
class Topology,
class F >
363 class MonomialBasisImpl;
366 class MonomialBasisImpl< Impl::Point, F >
368 typedef MonomialBasisImpl< Impl::Point, F > This;
371 typedef Impl::Point Topology;
374 static const unsigned int dimDomain = Topology::dimension;
376 typedef FieldVector< Field, dimDomain > DomainVector;
379 friend class MonomialBasis< Topology, Field >;
380 friend class MonomialBasisImpl< Impl::Prism< Topology >, Field >;
381 friend class MonomialBasisImpl< Impl::Pyramid< Topology >, Field >;
384 void evaluate ( const unsigned int deriv, const unsigned int order,
385 const FieldVector< Field, dimD > &x,
386 const unsigned int block, const unsigned int *const offsets,
387 Field *const values ) const
389 *values = Unity< F >();
390 F *
const end = values + block;
391 for( Field *it = values+1 ; it != end; ++it )
395 void integrate (
const unsigned int order,
396 const unsigned int *
const offsets,
397 Field *
const values )
const
399 values[ 0 ] = Unity< Field >();
403 template<
class BaseTopology,
class F >
404 class MonomialBasisImpl< Impl::Prism< BaseTopology >, F >
406 typedef MonomialBasisImpl< Impl::Prism< BaseTopology >, F > This;
409 typedef Impl::Prism< BaseTopology > Topology;
412 static const unsigned int dimDomain = Topology::dimension;
414 typedef FieldVector< Field, dimDomain > DomainVector;
417 friend class MonomialBasis< Topology, Field >;
418 friend class MonomialBasisImpl< Impl::Prism< Topology >, Field >;
419 friend class MonomialBasisImpl< Impl::Pyramid< Topology >, Field >;
421 typedef MonomialBasisSize< BaseTopology > BaseSize;
422 typedef MonomialBasisSize< Topology > Size;
424 MonomialBasisImpl< BaseTopology, Field > baseBasis_;
430 void evaluate (
const unsigned int deriv,
const unsigned int order,
431 const FieldVector< Field, dimD > &x,
432 const unsigned int block,
const unsigned int *
const offsets,
433 Field *
const values )
const
435 typedef MonomialBasisHelper< dimDomain, dimD, Field > Helper;
436 const BaseSize &size = BaseSize::instance();
438 const Field &z = x[ dimDomain-1 ];
441 baseBasis_.evaluate( deriv, order, x, block, offsets, values );
443 Field *row0 = values;
444 for(
unsigned int k = 1; k <= order; ++k )
446 Field *row1 = values + block*offsets[ k-1 ];
447 Field *wit = row1 + block*size.sizes_[ k ];
448 Helper::copy( deriv, wit, row1, k*size.sizes_[ k ], z );
449 Helper::copy( deriv, wit, row0, size( k-1 ), z );
454 void integrate (
const unsigned int order,
455 const unsigned int *
const offsets,
456 Field *
const values )
const
458 const BaseSize &size = BaseSize::instance();
459 const Size &mySize = Size::instance();
461 baseBasis_.integrate( order, offsets, values );
462 const unsigned int *
const baseSizes = size.sizes_;
464 Field *row0 = values;
465 for(
unsigned int k = 1; k <= order; ++k )
467 Field *
const row1begin = values + offsets[ k-1 ];
468 Field *
const row1End = row1begin + mySize.sizes_[ k ];
469 assert( (
unsigned int)(row1End - values) <= offsets[ k ] );
471 Field *row1 = row1begin;
472 Field *it = row1begin + baseSizes[ k ];
473 for(
unsigned int j = 1; j <= k; ++j )
475 Field *
const end = it + baseSizes[ k ];
476 assert( (
unsigned int)(end - values) <= offsets[ k ] );
477 for( ; it != end; ++row1, ++it )
478 *it = (Field( j ) / Field( j+1 )) * (*row1);
480 for( ; it != row1End; ++row0, ++it )
481 *it = (Field( k ) / Field( k+1 )) * (*row0);
487 template<
class BaseTopology,
class F >
488 class MonomialBasisImpl< Impl::Pyramid< BaseTopology >, F >
490 typedef MonomialBasisImpl< Impl::Pyramid< BaseTopology >, F > This;
493 typedef Impl::Pyramid< BaseTopology > Topology;
496 static const unsigned int dimDomain = Topology::dimension;
498 typedef FieldVector< Field, dimDomain > DomainVector;
501 friend class MonomialBasis< Topology, Field >;
502 friend class MonomialBasisImpl< Impl::Prism< Topology >, Field >;
503 friend class MonomialBasisImpl< Impl::Pyramid< Topology >, Field >;
505 typedef MonomialBasisSize< BaseTopology > BaseSize;
506 typedef MonomialBasisSize< Topology > Size;
508 MonomialBasisImpl< BaseTopology, Field > baseBasis_;
514 void evaluateSimplexBase (
const unsigned int deriv,
const unsigned int order,
515 const FieldVector< Field, dimD > &x,
516 const unsigned int block,
const unsigned int *
const offsets,
518 const BaseSize &size )
const
520 baseBasis_.evaluate( deriv, order, x, block, offsets, values );
524 void evaluatePyramidBase (
const unsigned int deriv,
const unsigned int order,
525 const FieldVector< Field, dimD > &x,
526 const unsigned int block,
const unsigned int *
const offsets,
528 const BaseSize &size )
const
530 Field omz = Unity< Field >() - x[ dimDomain-1 ];
532 if( Zero< Field >() < omz )
534 const Field invomz = Unity< Field >() / omz;
535 FieldVector< Field, dimD > y;
536 for(
unsigned int i = 0; i < dimDomain-1; ++i )
537 y[ i ] = x[ i ] * invomz;
540 baseBasis_.evaluate( deriv, order, y, block, offsets, values );
543 for(
unsigned int k = 1; k <= order; ++k )
545 Field *it = values + block*offsets[ k-1 ];
546 Field *
const end = it + block*size.sizes_[ k ];
547 for( ; it != end; ++it )
555 *values = Unity< Field >();
556 for(
unsigned int k = 1; k <= order; ++k )
558 Field *it = values + block*offsets[ k-1 ];
559 Field *
const end = it + block*size.sizes_[ k ];
560 for( ; it != end; ++it )
561 *it = Zero< Field >();
567 void evaluate (
const unsigned int deriv,
const unsigned int order,
568 const FieldVector< Field, dimD > &x,
569 const unsigned int block,
const unsigned int *
const offsets,
570 Field *
const values )
const
572 typedef MonomialBasisHelper< dimDomain, dimD, Field > Helper;
573 const BaseSize &size = BaseSize::instance();
575 if( Impl::IsSimplex< Topology >::value )
576 evaluateSimplexBase( deriv, order, x, block, offsets, values, size );
578 evaluatePyramidBase( deriv, order, x, block, offsets, values, size );
580 Field *row0 = values;
581 for(
unsigned int k = 1; k <= order; ++k )
583 Field *row1 = values + block*offsets[ k-1 ];
584 Field *wit = row1 + block*size.sizes_[ k ];
585 Helper::copy( deriv, wit, row0, size( k-1 ), x[ dimDomain-1 ] );
590 void integrate (
const unsigned int order,
591 const unsigned int *
const offsets,
592 Field *
const values )
const
594 const BaseSize &size = BaseSize::instance();
597 baseBasis_.integrate( order, offsets, values );
599 const unsigned int *
const baseSizes = size.sizes_;
602 Field *
const col0End = values + baseSizes[ 0 ];
603 for( Field *it = values; it != col0End; ++it )
604 *it *= Field( 1 ) / Field(
int(dimDomain) );
607 Field *row0 = values;
608 for(
unsigned int k = 1; k <= order; ++k )
610 const Field factor = (Field( 1 ) / Field( k + dimDomain ));
612 Field *
const row1 = values+offsets[ k-1 ];
613 Field *
const col0End = row1 + baseSizes[ k ];
615 for( ; it != col0End; ++it )
617 for(
unsigned int i = 1; i <= k; ++i )
619 Field *
const end = it + baseSizes[ k-i ];
620 assert( (
unsigned int)(end - values) <= offsets[ k ] );
621 for( ; it != end; ++row0, ++it )
622 *it = (*row0) * (Field( i ) * factor);
634 template<
class Topology,
class F >
636 :
public MonomialBasisImpl< Topology, F >
638 typedef MonomialBasis< Topology, F > This;
639 typedef MonomialBasisImpl< Topology, F > Base;
642 static const unsigned int dimension = Base::dimDomain;
643 static const unsigned int dimRange = 1;
645 typedef typename Base::Field Field;
647 typedef typename Base::DomainVector DomainVector;
651 typedef MonomialBasisSize<Topology> Size;
653 MonomialBasis (
unsigned int order)
656 size_(Size::instance())
661 const unsigned int *sizes (
unsigned int order )
const
663 size_.computeSizes( order );
664 return size_.numBaseFunctions_;
667 const unsigned int *sizes ()
const
669 return sizes( order_ );
672 unsigned int size ()
const
674 size_.computeSizes( order_ );
675 return size_( order_ );
678 unsigned int derivSize (
const unsigned int deriv )
const
680 typedef typename Impl::SimplexTopology< dimension >::type SimplexTopology;
681 MonomialBasisSize< SimplexTopology >::instance().computeSizes( deriv );
682 return MonomialBasisSize< SimplexTopology >::instance() ( deriv );
685 unsigned int order ()
const
690 unsigned int topologyId ( )
const
695 void evaluate (
const unsigned int deriv,
const DomainVector &x,
696 Field *
const values )
const
698 Base::evaluate( deriv, order_, x, derivSize( deriv ), sizes( order_ ), values );
701 template <
unsigned int deriv>
702 void evaluate (
const DomainVector &x,
703 Field *
const values )
const
705 evaluate( deriv, x, values );
708 template<
unsigned int deriv,
class Vector >
709 void evaluate (
const DomainVector &x,
710 Vector &values )
const
712 evaluate<deriv>(x,&(values[0]));
714 template<
unsigned int deriv, DerivativeLayout layout >
715 void evaluate (
const DomainVector &x,
716 Derivatives<Field,dimension,1,deriv,layout> *values )
const
718 evaluate<deriv>(x,&(values->block()));
720 template<
unsigned int deriv >
721 void evaluate (
const DomainVector &x,
722 FieldVector<Field,Derivatives<Field,dimension,1,deriv,value>::size> *values )
const
724 evaluate(0,x,&(values[0][0]));
727 template<
class Vector >
728 void evaluate (
const DomainVector &x,
729 Vector &values )
const
731 evaluate<0>(x,&(values[0]));
734 template<
class DVector,
class RVector >
735 void evaluate (
const DVector &x, RVector &values )
const
737 assert( DVector::dimension == dimension);
739 for(
int d = 0; d < dimension; ++d )
741 evaluate<0>( bx, values );
744 void integrate ( Field *
const values )
const
746 Base::integrate( order_, sizes( order_ ), values );
748 template <
class Vector>
749 void integrate ( Vector &values )
const
751 integrate( &(values[ 0 ]) );
754 MonomialBasis(
const This&);
755 This& operator=(
const This&);
765 template<
int dim,
class F >
766 class StandardMonomialBasis
767 :
public MonomialBasis< typename Impl::SimplexTopology< dim >::type, F >
769 typedef StandardMonomialBasis< dim, F > This;
770 typedef MonomialBasis< typename Impl::SimplexTopology< dim >::type, F > Base;
773 typedef typename Impl::SimplexTopology< dim >::type Topology;
774 static const int dimension = dim;
776 StandardMonomialBasis (
unsigned int order )
786 template<
int dim,
class F >
787 class StandardBiMonomialBasis
788 :
public MonomialBasis< typename Impl::CubeTopology< dim >::type, F >
790 typedef StandardBiMonomialBasis< dim, F > This;
791 typedef MonomialBasis< typename Impl::CubeTopology< dim >::type, F > Base;
794 typedef typename Impl::CubeTopology< dim >::type Topology;
795 static const int dimension = dim;
797 StandardBiMonomialBasis (
unsigned int order )
807 template<
int dim,
class F >
808 class VirtualMonomialBasis
810 typedef VirtualMonomialBasis< dim, F > This;
814 typedef F StorageField;
815 static const int dimension = dim;
816 static const unsigned int dimRange = 1;
818 typedef FieldVector<Field,dimension> DomainVector;
819 typedef FieldVector<Field,dimRange> RangeVector;
821 explicit VirtualMonomialBasis(
unsigned int topologyId,
823 : order_(order), topologyId_(topologyId) {}
825 virtual ~VirtualMonomialBasis() {}
827 virtual const unsigned int *sizes ( )
const = 0;
829 unsigned int size ( )
const
831 return sizes( )[ order_ ];
834 unsigned int order ()
const
839 unsigned int topologyId ( )
const
844 virtual void evaluate (
const unsigned int deriv,
const DomainVector &x,
845 Field *
const values )
const = 0;
846 template <
unsigned int deriv >
847 void evaluate (
const DomainVector &x,
848 Field *
const values )
const
850 evaluate( deriv, x, values );
852 template <
unsigned int deriv,
int size >
853 void evaluate (
const DomainVector &x,
856 evaluate( deriv, x, &(values[0][0]) );
858 template<
unsigned int deriv, DerivativeLayout layout >
859 void evaluate (
const DomainVector &x,
860 Derivatives<Field,dimension,1,deriv,layout> *values )
const
862 evaluate<deriv>(x,&(values->block()));
864 template <
unsigned int deriv,
class Vector>
865 void evaluate (
const DomainVector &x,
866 Vector &values )
const
868 evaluate<deriv>( x, &(values[ 0 ]) );
870 template<
class Vector >
871 void evaluate (
const DomainVector &x,
872 Vector &values )
const
874 evaluate<0>(x,values);
876 template<
class DVector,
class RVector >
877 void evaluate (
const DVector &x, RVector &values )
const
879 assert( DVector::dimension == dimension);
881 for(
int d = 0; d < dimension; ++d )
883 evaluate<0>( bx, values );
885 template<
unsigned int deriv,
class DVector,
class RVector >
886 void evaluate (
const DVector &x, RVector &values )
const
888 assert( DVector::dimension == dimension);
890 for(
int d = 0; d < dimension; ++d )
892 evaluate<deriv>( bx, values );
895 virtual void integrate ( Field *
const values )
const = 0;
896 template <
class Vector>
897 void integrate ( Vector &values )
const
899 integrate( &(values[ 0 ]) );
903 unsigned int topologyId_;
906 template<
class Topology,
class F >
907 class VirtualMonomialBasisImpl
908 :
public VirtualMonomialBasis< Topology::dimension, F >
910 typedef VirtualMonomialBasis< Topology::dimension, F > Base;
911 typedef VirtualMonomialBasisImpl< Topology, F > This;
914 typedef typename Base::Field Field;
915 typedef typename Base::DomainVector DomainVector;
917 VirtualMonomialBasisImpl(
unsigned int order)
918 : Base(Topology::id,order), basis_(order)
921 const unsigned int *sizes ( )
const
923 return basis_.sizes(order_);
926 void evaluate (
const unsigned int deriv,
const DomainVector &x,
927 Field *
const values )
const
929 basis_.evaluate(deriv,x,values);
932 void integrate ( Field *
const values )
const
934 basis_.integrate(values);
938 MonomialBasis<Topology,Field> basis_;
945 template<
int dim,
class F >
946 struct MonomialBasisFactory;
948 template<
int dim,
class F >
949 struct MonomialBasisFactoryTraits
951 static const unsigned int dimension = dim;
952 typedef unsigned int Key;
953 typedef const VirtualMonomialBasis< dimension, F > Object;
954 typedef MonomialBasisFactory<dim,F> Factory;
957 template<
int dim,
class F >
958 struct MonomialBasisFactory :
959 public TopologyFactory< MonomialBasisFactoryTraits<dim,F> >
961 static const unsigned int dimension = dim;
962 typedef F StorageField;
963 typedef MonomialBasisFactoryTraits<dim,F> Traits;
965 typedef typename Traits::Key Key;
966 typedef typename Traits::Object Object;
968 template <
int dd,
class FF >
969 struct EvaluationBasisFactory
971 typedef MonomialBasisFactory<dd,FF> Type;
974 template<
class Topology >
975 static Object* createObject (
const Key &order )
977 return new VirtualMonomialBasisImpl< Topology, StorageField >( order );
986 template<
int dim,
class SF >
987 struct MonomialBasisProvider
988 :
public TopologySingletonFactory< MonomialBasisFactory< dim, SF > >
990 static const unsigned int dimension = dim;
991 typedef SF StorageField;
992 template <
int dd,
class FF >
993 struct EvaluationBasisFactory
995 typedef MonomialBasisProvider<dd,FF> Type;
vector space out of a tensor product of fields.
Definition: fvector.hh:93
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
Dune namespace.
Definition: alignedallocator.hh:10
void field_cast(const F1 &f1, F2 &f2)
a helper class to cast from one field to another
Definition: field.hh:157
A unique label for each type of element that can occur in a grid.