DUNE-ACFEM (unstable)

transportmodel.hh
1 #ifndef __DUNE_ACFEM_MODELS_MODULES_TRANSPORTMODEL_HH__
2 #define __DUNE_ACFEM_MODELS_MODULES_TRANSPORTMODEL_HH__
3 
4 #include <dune/fem/function/localfunction/const.hh>
5 
6 #include "../../expressions/terminal.hh"
7 
8 #include "../modelbase.hh"
9 
10 namespace Dune {
11 
12  namespace ACFem::PDEModel {
13 
46  template<class FunctionSpace, class GridFunction>
48  : public ModelBase<FunctionSpace>
49  , public Expressions::SelfExpression<TransportModel<FunctionSpace, GridFunction> >
50  , public MPL::UniqueTags<ConditionalType<IsConstantExprArg<GridFunction>::value, ConstantExpression, void>,
51  ConditionalType<IsTypedValue<GridFunction>::value, TypedValueExpression, void> >
52  {
54  "GridFunction must provide a local function");
55 
56  using ThisType = TransportModel;
58  using LocalFunctionType = Fem::ConstLocalFunction<std::decay_t<GridFunction> >;
59  public:
60  using GridFunctionType = GridFunction;
61  using GridFunctionDecay = std::decay_t<GridFunctionType>;
62  using GridPartType = typename GridFunctionDecay::GridPartType;
63 
64  using typename BaseType::RangeFieldType;
65  using typename BaseType::DomainType;
66  using typename BaseType::RangeType;
67  using typename BaseType::JacobianRangeType;
68  using BaseType::dimDomain;
69  using BaseType::dimRange;
70 
71  enum {
72  dimWorld = GridPartType::dimensionworld
73  };
74 
75  static_assert((int)GridFunctionDecay::FunctionSpaceType::dimRange == (int)dimWorld
76  &&
77  (int)dimDomain == (int)dimWorld,
78  "This is meant for dimensionworld vector-fields, "
79  "like fluids, deformations etc.");
80 
81  // Interface methods that need to be reimplemented
82 
83  template<class FunctionArg, std::enable_if_t<std::is_constructible<LocalFunctionType, FunctionArg>::value, int> = 0>
84  TransportModel(FunctionArg&& function, const std::string& name = "")
85  : localFunction_(std::forward<FunctionArg>(function))
86  , name_(name == "" ? "(-U_iU_jD_iPhi_j+Bndry)" : name)
87  {}
88 
89  std::string name() const
90  {
91  return name_;
92  }
93 
95  template<class Entity>
96  void bind(const Entity& entity)
97  {
98  localFunction_.bind(entity);
99  }
100 
102  void unbind()
103  {
104  localFunction_.unbind();
105  }
106 
108  template<class Intersection>
109  auto classifyBoundary(const Intersection& intersection)
110  {
111  // true is correct as higher-level code has to take care of
112  // the Dirichlet-(non-Dirichlet) splitting of the boundary.
113  return std::make_pair(true, std::bitset<dimRange>());
114  }
115 
117  template<class Quadrature>
118  auto linearizedFlux(const QuadraturePoint<Quadrature> &x, const RangeType& value) const
119  {
120  // We need to provide the tensor-product of value with the
121  // value of function_
122  const auto velocity = localFunction_.evaluate(x);
123 
124  JacobianRangeType flux = 0;
125  for (int i = 0; i < dimRange; ++i) {
126  for (int j = 0; j < dimWorld; ++j) {
127  flux[i][j] = - value[i] * velocity[j];
128  }
129  }
130  return flux;
131  }
132 
138  template<class Quadrature>
140  const RangeType& value,
141  const JacobianRangeType& jacobian) const
142  {
143  const auto velocity = localFunction_.evaluate(x);
144  const auto velocityJacobian = localFunction_.jacobian(x);
145 
146  RangeType result;
147  jacobian.mv(velocity, result);
148 
149  RangeFieldType velocityDivergence = 0.;
150 // for (int i = 0; i < dimDomain; ++i) {
151  for (int i = 0; i < dimDomain; ++i) {
152  velocityDivergence += velocityJacobian[i][i];
153  }
154  result.axpy(velocityDivergence, value);
155 
156  return result;
157  }
158 
160  template<class Quadrature>
162  const DomainType& unitOuterNormal,
163  const RangeType& value) const
164  {
165  const auto velocity = localFunction_.evaluate(x);
166  return RangeType(value) *= (velocity * unitOuterNormal); // scalar product
167  }
168 
169  protected:
170  LocalFunctionType localFunction_;
171  std::string name_;
172  };
173 
175 
187  template<class Object, class GridFunction>
188  constexpr auto
189  transportModel(const Object& object,
190  GridFunction&& velocity,
191  const std::string& name = "")
192  {
193  return expressionClosure(TransportModel<typename Object::FunctionSpaceType, GridFunction>(std::forward<GridFunction>(velocity), name));
194  }
195 
196  template<class Object, class GridFunction, std::enable_if_t<ExpressionTraits<GridFunction>::isZero, int> = 0>
197  constexpr auto
198  transportModel(const Object& object,
199  GridFunction&& velocity,
200  const std::string& name = "")
201  {
202  return zeroModel(object);
203  }
204 
206 
208 
210 
211  } // namespace ACFem::PDEModel
212 
213  namespace ACFem {
214 
215  using PDEModel::transportModel;
216 
217  }
218 
219 } //Namespace Dune
220 
221 
222 #endif // __DUNE_ACFEM_MODELS_MODULES_TRANSPORTMODEL_HH__
Define a model for an advection term.
Definition: transportmodel.hh:52
constexpr decltype(auto) expressionClosure(T &&t)
Do-nothing default implementation for pathologic cases.
Definition: interface.hh:93
std::is_base_of< Tag, std::decay_t< A > > HasTag
Evaluate to std::true_type if std::decay_t<A> is derived from Tag, otherwise to std::false_type.
Definition: tags.hh:176
auto linearizedRobinFlux(const QuadraturePoint< Quadrature > &x, const DomainType &unitOuterNormal, const RangeType &value) const
The linearized Robin-type flux term.
Definition: transportmodel.hh:161
auto classifyBoundary(const Intersection &intersection)
Bind to the given intersection and classify the components w.r.t.
Definition: transportmodel.hh:109
void bind(const Entity &entity)
Bind to the given entity.
Definition: transportmodel.hh:96
auto linearizedFlux(const QuadraturePoint< Quadrature > &x, const RangeType &value) const
Evaluate the linearized flux in local coordinates.
Definition: transportmodel.hh:118
auto fluxDivergence(const QuadraturePoint< Quadrature > &x, const RangeType &value, const JacobianRangeType &jacobian) const
!
Definition: transportmodel.hh:139
constexpr auto transportModel(const Object &object, GridFunction &&velocity, const std::string &name="")
Generate an advection-model object.
Definition: transportmodel.hh:189
void unbind()
Unbind from the previously bound entity.
Definition: transportmodel.hh:102
auto zeroModel(const T &t, const std::string &name, F closure=F{})
Generate a zero model fitting the specified object.
Definition: zeromodel.hh:77
Fem::QuadraturePointWrapper< Quadrature > QuadraturePoint
Shortcut.
Definition: quadraturepoint.hh:23
Terminals may derive from this class to express that they are expressions.
Definition: terminal.hh:25
A structure defining some basic default types and methods.
Definition: modelbase.hh:41
typename FunctionSpaceType::JacobianRangeType JacobianRangeType
The type returned by classifyBoundary().
Definition: modelbase.hh:63
typename FunctionSpaceType::DomainType DomainType
The type returned by classifyBoundary().
Definition: modelbase.hh:61
typename FunctionSpaceType::RangeType RangeType
The type returned by classifyBoundary().
Definition: modelbase.hh:62
static constexpr int dimRange
The type returned by classifyBoundary().
Definition: modelbase.hh:86
typename FunctionSpaceType::RangeFieldType RangeFieldType
The type returned by classifyBoundary().
Definition: modelbase.hh:67
static constexpr int dimDomain
The type returned by classifyBoundary().
Definition: modelbase.hh:85
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)