/usr/include/dune/localfunctions/common/interfaceswitch.hh is in libdune-localfunctions-dev 2.5.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_LOCALFUNCTIONS_COMMON_INTERFACESWITCH_HH
#define DUNE_LOCALFUNCTIONS_COMMON_INTERFACESWITCH_HH
#include <cstddef>
#include <memory>
#include <vector>
#include <dune/common/fmatrix.hh>
#include <dune/common/std/type_traits.hh>
namespace Dune {
//! \brief Switch for uniform treatment of finite element with either the
//! local or the global interface
/**
* \tparam FiniteElement Type of the finite element to handle.
* \tparam Dummy Dummy parameter for enable_if. This must be left
* at the default value of \c void.
*
* \note The local interface is detected by the presence of the type
* FiniteElement::Traits::LocalBasisType.
*/
template<class FiniteElement, class Dummy = void>
struct FiniteElementInterfaceSwitch {
//! export the type of the basis
typedef typename FiniteElement::Traits::Basis Basis;
//! export the type of the interpolation
typedef typename FiniteElement::Traits::Interpolation Interpolation;
//! export the type of the coefficients
typedef typename FiniteElement::Traits::Coefficients Coefficients;
//! access basis
static const Basis &basis(const FiniteElement& fe)
{ return fe.basis(); }
//! access interpolation
static const Interpolation &interpolation(const FiniteElement& fe)
{ return fe.interpolation(); }
//! access coefficients
static const Coefficients &coefficients(const FiniteElement& fe)
{ return fe.coefficients(); }
//! Type for storing finite elements
/**
* Some algorithms use one variable to store (a pointer) a finite element
* and update that pointer while iterating through the grid. This works
* well for local finite elements, since they exists in a finite number of
* variants, which can be stored somewhere and don't need to change for
* the duration of the algorithm, so we can always store a simple pointer.
* For global finite elements we have to store the object itself however,
* and we must make sure that we destroy the object when we are done with
* it. Since global finite elements are not assignable in general, we
* needs to copy-construct them for each grid element we visit.
*
* To accommodate both interfaces, we define a store: for local finite
* elements it is a simple pointer, and if we want to store a finite
* element in it we simply store its address. For global finite elements
* we use a shared_ptr, and if we want to store a finite element in it we
* allocate a new object and initialise it with the copy-constructor. For
* local finite elements we don't need to do anything when we are done
* with it, global finite elements are automatically destructed by the
* shared_ptr when we store a new one or when the shared_ptr itself is
* destroyed. Access to the finite element is done by simply
* dereferencing the store in both cases.
*/
typedef std::shared_ptr<const FiniteElement> Store;
//! Store a finite element in the store.
/**
* For local finite elements this means storing the address of the passed
* reference, for global finite element this means creating a new object
* with allocation and copy-construction and storing that.
*/
static void setStore(Store& store, const FiniteElement& fe)
{ store.reset(new FiniteElement(fe)); }
};
#ifndef DOXYGEN
//! \brief Switch for uniform treatment of finite element with either the
//! local or the global interface
template<class FiniteElement>
struct FiniteElementInterfaceSwitch<
FiniteElement,
typename std::enable_if<Std::to_true_type<typename FiniteElement::Traits::
LocalBasisType>::value>::type
>
{
//! export the type of the basis
typedef typename FiniteElement::Traits::LocalBasisType Basis;
//! export the type of the interpolation
typedef typename FiniteElement::Traits::LocalInterpolationType
Interpolation;
//! export the type of the coefficients
typedef typename FiniteElement::Traits::LocalCoefficientsType Coefficients;
//! access basis
static const Basis &basis(const FiniteElement& fe)
{ return fe.localBasis(); }
//! access interpolation
static const Interpolation &interpolation(const FiniteElement& fe)
{ return fe.localInterpolation(); }
//! access coefficients
static const Coefficients &coefficients(const FiniteElement& fe)
{ return fe.localCoefficients(); }
//! Type for storing finite elements
typedef const FiniteElement *Store;
//! Store a finite element in the store.
static void setStore(Store& store, const FiniteElement& fe)
{ store = &fe; }
};
#endif // !DOXYGEN
//! Switch for uniform treatment of local and global basis classes
/**
* \tparam Basis Type of the basis to handle.
* \tparam Dummy Dummy parameter for enable_if. This must be left at the
* default value of \c void.
*
* We don't provide any uniform access to the types and constants pertaining
* to the global domain. Providing this would require the Geometry as
* template parameter as well, and the user code can build them itself if it
* needs them with the help of the geometry. The omitted types are \c
* DomainGlobal and \c Jacobian, the omitted constant is \c dimDomainGlobal.
*
* \note The local interface is assumed if the constant
* Basis::Traits::dimDomain exists and has a value greater than 0.
*/
template<class Basis, class Dummy = void>
struct BasisInterfaceSwitch {
//! export field types of the coordinates
typedef typename Basis::Traits::DomainField DomainField;
//! export dimension of local coordinates
static const std::size_t dimDomainLocal = Basis::Traits::dimDomainLocal;
//! export vector type of the local coordinates
typedef typename Basis::Traits::DomainLocal DomainLocal;
//! export field type of the values
typedef typename Basis::Traits::RangeField RangeField;
//! export dimension of the values
static const std::size_t dimRange = Basis::Traits::dimRange;
//! export vector type of the values
typedef typename Basis::Traits::Range Range;
//! export number of supported differentiations
static const std::size_t diffOrder = Basis::Traits::diffOrder;
//! Compute global gradient for scalar valued bases
/**
* \param basis The basis to get the derivatives from.
* \param geometry The geometry to use to transform the derivatives (for a
* local basis, unused in the case of a global basis).
* \param xl The local coordinates where to evaluate the gradient.
* \param grad The result (will be resized to the appropriate number
* of entries.
*
* \note This make sense only for a scalar valued basis.
*/
template<typename Geometry>
static void gradient(const Basis& basis, const Geometry& geometry,
const DomainLocal& xl,
std::vector<FieldMatrix<RangeField, 1,
Geometry::coorddimension> >& grad)
{
grad.resize(basis.size());
basis.evaluateJacobian(xl, grad);
}
};
#ifndef DOXYGEN
//! Switch for uniform treatment of local and global basis classes
template<class Basis>
struct BasisInterfaceSwitch<Basis,
typename std::enable_if<
Std::to_true_type<
std::integral_constant<
std::size_t,
Basis::Traits::dimDomain
>
>::value
>::type
>
{
//! export field types of the coordinates
typedef typename Basis::Traits::DomainFieldType DomainField;
//! export dimension of local coordinates
static const std::size_t dimDomainLocal = Basis::Traits::dimDomain;
//! export vector type of the local coordinates
typedef typename Basis::Traits::DomainType DomainLocal;
//! export field type of the values
typedef typename Basis::Traits::RangeFieldType RangeField;
//! export dimension of the values
static const std::size_t dimRange = Basis::Traits::dimRange;
//! export vector type of the values
typedef typename Basis::Traits::RangeType Range;
//! export number of supported differentiations
static const std::size_t diffOrder = Basis::Traits::diffOrder;
//! Compute global gradient for scalar valued bases
template<typename Geometry>
static void gradient(const Basis& basis, const Geometry& geometry,
const DomainLocal& xl,
std::vector<FieldMatrix<RangeField, 1,
Geometry::coorddimension> >& grad)
{
std::vector<typename Basis::Traits::JacobianType> lgrad(basis.size());
basis.evaluateJacobian(xl, lgrad);
const typename Geometry::JacobianInverseTransposed& jac =
geometry.jacobianInverseTransposed(xl);
grad.resize(basis.size());
for(std::size_t i = 0; i < basis.size(); ++i)
jac.mv(lgrad[i][0], grad[i][0]);
}
};
#endif // !DOXYGEN
} // namespace Dune
#endif // DUNE_LOCALFUNCTIONS_COMMON_INTERFACESWITCH_HH
|