dune-localfunctions
2.2.0
|
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=8 sw=2 sts=2: 00003 00004 #ifndef DUNE_LOCALFUNCTIONS_COMMON_LOCALTOGLOBALADAPTORS_HH 00005 #define DUNE_LOCALFUNCTIONS_COMMON_LOCALTOGLOBALADAPTORS_HH 00006 00007 #include <cstddef> 00008 #include <vector> 00009 00010 #include <dune/common/fmatrix.hh> 00011 #include <dune/common/fvector.hh> 00012 #include <dune/common/static_assert.hh> 00013 #include <dune/common/typetraits.hh> 00014 00015 #include <dune/geometry/type.hh> 00016 00017 namespace Dune { 00018 00020 00028 template<class LocalBasisTraits, std::size_t dimDomainGlobal_> 00029 struct LocalToGlobalBasisAdaptorTraits { 00030 typedef typename LocalBasisTraits::DomainFieldType DomainField; 00031 static const std::size_t dimDomainLocal = LocalBasisTraits::dimDomain; 00032 static const std::size_t dimDomainGlobal = dimDomainGlobal_; 00033 typedef typename LocalBasisTraits::DomainType DomainLocal; 00034 typedef FieldVector<DomainField, dimDomainGlobal> DomainGlobal; 00035 00036 typedef typename LocalBasisTraits::RangeFieldType RangeField; 00037 static const std::size_t dimRange = LocalBasisTraits::dimRange; 00038 typedef typename LocalBasisTraits::RangeType Range; 00039 00040 typedef FieldMatrix<RangeField, dimRange, dimDomainGlobal> Jacobian; 00041 00042 static const std::size_t diffOrder = LocalBasisTraits::diffOrder; 00043 }; 00044 00046 00065 template<class LocalBasis, class Geometry> 00066 class ScalarLocalToGlobalBasisAdaptor { 00067 dune_static_assert(LocalBasis::Traits::dimRange == 1, 00068 "ScalarLocalToGlobalBasisAdaptor can only wrap a " 00069 "scalar local basis."); 00070 dune_static_assert((is_same<typename LocalBasis::Traits::DomainFieldType, 00071 typename Geometry::ctype>::value), 00072 "ScalarLocalToGlobalBasisAdaptor: LocalBasis must use " 00073 "the same ctype as Geometry"); 00074 dune_static_assert 00075 ( static_cast<std::size_t>(LocalBasis::Traits::dimDomain) == 00076 static_cast<std::size_t>(Geometry::mydimension), 00077 "ScalarLocalToGlobalBasisAdaptor: LocalBasis domain dimension must " 00078 "match local dimension of Geometry"); 00079 00080 const LocalBasis& localBasis; 00081 const Geometry& geometry; 00082 00083 public: 00084 typedef LocalToGlobalBasisAdaptorTraits<typename LocalBasis::Traits, 00085 Geometry::coorddimension> Traits; 00086 00088 00097 ScalarLocalToGlobalBasisAdaptor(const LocalBasis& localBasis_, 00098 const Geometry& geometry_) : 00099 localBasis(localBasis_), geometry(geometry_) 00100 { } 00101 00102 std::size_t size() const { return localBasis.size(); } 00104 00111 std::size_t order() const { 00112 if(geometry.affine()) 00113 // affine linear 00114 return localBasis.order(); 00115 else 00116 // assume at most order dim 00117 return localBasis.order() + Traits::dimDomainGlobal - 1; 00118 } 00119 00120 void evaluateFunction(const typename Traits::DomainLocal& in, 00121 std::vector<typename Traits::Range>& out) const 00122 { 00123 localBasis.evaluateFunction(in, out); 00124 } 00125 00126 void evaluateJacobian(const typename Traits::DomainLocal& in, 00127 std::vector<typename Traits::Jacobian>& out) const 00128 { 00129 std::vector<typename LocalBasis::Traits::JacobianType> 00130 localJacobian(size()); 00131 localBasis.evaluateJacobian(in, localJacobian); 00132 00133 const typename Geometry::Jacobian &geoJacobian = 00134 geometry.jacobianInverseTransposed(in); 00135 00136 out.resize(size()); 00137 for(std::size_t i = 0; i < size(); ++i) 00138 geoJacobian.mv(localJacobian[i][0], out[i][0]); 00139 } 00140 }; 00141 00143 00149 template<class LocalInterpolation, class Traits_> 00150 class LocalToGlobalInterpolationAdaptor { 00151 const LocalInterpolation& localInterpolation; 00152 00153 public: 00154 typedef Traits_ Traits; 00155 00157 00165 LocalToGlobalInterpolationAdaptor 00166 ( const LocalInterpolation& localInterpolation_) : 00167 localInterpolation(localInterpolation_) 00168 { } 00169 00170 template<class Function, class Coeff> 00171 void interpolate(const Function& function, std::vector<Coeff>& out) const 00172 { localInterpolation.interpolate(function, out); } 00173 }; 00174 00177 00187 template<class LocalFiniteElement, class Geometry> 00188 struct ScalarLocalToGlobalFiniteElementAdaptor { 00192 struct Traits { 00193 typedef ScalarLocalToGlobalBasisAdaptor<typename LocalFiniteElement:: 00194 Traits::LocalBasisType, Geometry> Basis; 00195 typedef LocalToGlobalInterpolationAdaptor<typename LocalFiniteElement:: 00196 Traits::LocalInterpolationType, typename Basis::Traits> 00197 Interpolation; 00198 typedef typename LocalFiniteElement::Traits::LocalCoefficientsType 00199 Coefficients; 00200 }; 00201 00202 private: 00203 const LocalFiniteElement &localFE; 00204 typename Traits::Basis basis_; 00205 typename Traits::Interpolation interpolation_; 00206 00207 public: 00209 00218 ScalarLocalToGlobalFiniteElementAdaptor 00219 ( const LocalFiniteElement& localFE_, const Geometry &geometry) : 00220 localFE(localFE_), 00221 basis_(localFE.localBasis(), geometry), 00222 interpolation_(localFE.localInterpolation()) 00223 { } 00224 00225 const typename Traits::Basis& basis() const { return basis_; } 00226 const typename Traits::Interpolation& interpolation() const 00227 { return interpolation_; } 00228 const typename Traits::Coefficients& coefficients() const 00229 { return localFE.localCoefficients(); } 00230 GeometryType type() const { return localFE.type(); } 00231 }; 00232 00234 00244 template<class LocalFiniteElement, class Geometry> 00245 class ScalarLocalToGlobalFiniteElementAdaptorFactory { 00246 const LocalFiniteElement& localFE; 00247 00248 public: 00249 typedef ScalarLocalToGlobalFiniteElementAdaptor<LocalFiniteElement, 00250 Geometry> FiniteElement; 00251 00253 00261 ScalarLocalToGlobalFiniteElementAdaptorFactory 00262 (const LocalFiniteElement &localFE_) : localFE(localFE_) {} 00263 00265 00275 const FiniteElement make(const Geometry& geometry) { 00276 return FiniteElement(localFE, geometry); 00277 } 00278 }; 00279 00280 } // namespace Dune 00281 00282 #endif // DUNE_LOCALFUNCTIONS_COMMON_LOCALTOGLOBALADAPTORS_HH