DUNE-ACFEM (2.5.1)

transportmodel.hh
1 #ifndef __DUNE_ACFEM_MODELS_MODULES_TRANSPORTMODEL_HH__
2 #define __DUNE_ACFEM_MODELS_MODULES_TRANSPORTMODEL_HH__
3 
4 #include "../operatorparts/modeladapter.hh"
5 
6 namespace Dune {
7 
8  namespace ACFem {
9 
42  template<class FunctionSpace, class Velocity>
44  : public OperatorPartsExpression<TransportOperatorParts<FunctionSpace, Velocity> >
45  {
50  typedef typename Velocity::LocalFunctionType LocalVelocityType;
51  public:
52  typedef Velocity VelocityType;
53  typedef typename TraitsType::FunctionSpaceType FunctionSpaceType;
54  typedef typename VelocityType::GridPartType GridPartType;
55 
56  typedef typename FunctionSpaceType::DomainType DomainType;
57  typedef typename FunctionSpaceType::RangeType RangeType;
58  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
59  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
60 
61  enum {
62  dimDomain = FunctionSpaceType::dimDomain,
63  dimRange = FunctionSpaceType::dimRange,
64  dimWorld = GridPartType::dimensionworld
65  };
66 
67  static_assert((int)VelocityType::FunctionSpaceType::dimRange == (int)dimWorld && dimDomain == dimWorld,
68  "This is meant for dimensionworld vector-fields, "
69  "like fluids, deformations etc.");
70 
71  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
72  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
73 
74  // Interface methods that need to be reimplemented
75 
76  TransportOperatorParts(const Fem::Function<typename VelocityType::FunctionSpaceType, VelocityType>& velocity,
77  const std::string& name = "")
78  : velocity_(velocity),
79  localVelocity_(velocity_()),
80  name_(name == "" ? "(-U_iU_jD_iPhi_j+Bndry)" : name)
81  {}
82 
83  std::string name() const
84  {
85  return name_;
86  }
87 
89  template<class Entity>
90  void setEntity(const Entity& entity) const
91  {
92  localVelocity_.init(entity);
93  }
94 
96  template<class Intersection>
97  bool setIntersection(const Intersection& intersection) const
98  {
99  // true is correct as higher-level code has to take care of
100  // the Dirichlet-(non-Dirichlet) splitting of the boundary.
101  return true;
102  }
103 
105  template<class Entity, class Point>
106  void linearizedFlux (const RangeType& uBar,
107  const JacobianRangeType& DuBar,
108  const Entity& entity,
109  const Point &x,
110  const RangeType& value,
111  const JacobianRangeType& jacobian,
112  JacobianRangeType& flux) const
113  {
114  assert(&entity == &localVelocity_.entity());
115 
116  // We need to provide the tensor-product of value with the
117  // value of velocity_
118  typename VelocityType::RangeType velocity;
119  localVelocity_.evaluate(x, velocity);
120 
121  flux = 0;
122  for (int i = 0; i < dimRange; ++i) {
123  for (int j = 0; j < dimWorld; ++j) {
124  flux[i][j] = - value[i] * velocity[j];
125  }
126  }
127  }
128 
134  template<class Entity, class Point>
135  void fluxDivergence(const Entity& entity,
136  const Point &x,
137  const RangeType& value,
138  const JacobianRangeType& jacobian,
139  const HessianRangeType& hessian,
140  RangeType& result) const
141  {
142  assert(&entity == &localVelocity_.entity());
143 
144  typename VelocityType::RangeType velocity;
145  localVelocity_.evaluate(x, velocity);
146  typename VelocityType::JacobianRangeType velocityJacobian;
147  localVelocity_.jacobian(x, velocityJacobian);
148 
149  jacobian.mv(velocity, result);
150 
151  RangeFieldType velocityDivergence = 0.;
152  for (int i = 0; i < dimDomain; ++i) {
153  velocityDivergence += velocityJacobian[i][i];
154  }
155  result.axpy(velocityDivergence, value);
156  }
157 
159  template<class Intersection, class Point>
160  void linearizedRobinFlux(const RangeType& uBar,
161  const Intersection& intersection,
162  const Point& x,
163  const DomainType& unitOuterNormal,
164  const RangeType& value,
165  RangeType& result) const
166  {
167  typename VelocityType::RangeType velocity;
168  localVelocity_.evaluate(x, velocity);
169 
170  result = value;
171  result *= (velocity * unitOuterNormal); // scalar product
172  }
173 
174  protected:
176  mutable LocalVelocityType localVelocity_;
177  const std::string name_;
178  };
179 
180  template<class FunctionSpace, class Velocity>
181  struct OperatorPartsTraits<TransportOperatorParts<FunctionSpace, Velocity> >
182  : public DefaultOperatorPartsTraits<FunctionSpace>
183  {
186  {
187  isLinear = true,
188  isSymmetric = false,
189  isSemiDefinite = false, // Mmmh.
190  };
191 
194  hasFlux = true,
195  hasSources = false,
196  hasRobinFlux= true,
197  };
198  };
199 
201 
213  template<class Object, class Velocity>
214  static inline
215  TransportOperatorParts<typename Object::FunctionSpaceType, Velocity>
216  transportOperatorParts(const Object& object,
217  const Fem::Function<typename Velocity::FunctionSpaceType, Velocity>& velocity,
218  const std::string& name = "")
219  {
221  }
222 
230  template<class Object, class Velocity>
231  static inline
232  OperatorPartsAdapterModel<TransportOperatorParts<typename Object::FunctionSpaceType, Velocity>, typename Velocity::GridPartType>
233  transportModel(const Object& object,
234  const Fem::Function<typename Velocity::FunctionSpaceType, Velocity>& velocity,
235  const std::string& name = "")
236  {
238  typedef typename Velocity::GridPartType GridPartType;
239  return OperatorPartsAdapterModel<OperatorPartsType, GridPartType>(OperatorPartsType(velocity, name));
240  }
241 
243 
245 
247 
248  } // namespace ACFem
249 
250 } //Namespace Dune
251 
252 
253 #endif // __DUNE_ACFEM_MODELS_MODULES_TRANSPORTMODEL_HH__
Default model implementation.
Definition: operatorparts.hh:387
void flux(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
Definition: operatorparts.hh:450
Interface class for second order elliptic models.
Definition: operatorparts.hh:92
Define a model for an advection term.
Definition: transportmodel.hh:45
void linearizedFlux(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
Definition: transportmodel.hh:106
bool setIntersection(const Intersection &intersection) const
Per-intersection initialization for the boundary contributions.
Definition: transportmodel.hh:97
void fluxDivergence(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, const HessianRangeType &hessian, RangeType &result) const
!
Definition: transportmodel.hh:135
void setEntity(const Entity &entity) const
Per entity initialization, if that is needed.
Definition: transportmodel.hh:90
static TransportOperatorParts< typename Object::FunctionSpaceType, Velocity > transportOperatorParts(const Object &object, const Fem::Function< typename Velocity::FunctionSpaceType, Velocity > &velocity, const std::string &name="")
Generate an advection-model object.
Definition: transportmodel.hh:216
static OperatorPartsAdapterModel< TransportOperatorParts< typename Object::FunctionSpaceType, Velocity >, typename Velocity::GridPartType > transportModel(const Object &object, const Fem::Function< typename Velocity::FunctionSpaceType, Velocity > &velocity, const std::string &name="")
Generate an advection-model object.
Definition: transportmodel.hh:233
void linearizedRobinFlux(const RangeType &uBar, const Intersection &intersection, const Point &x, const DomainType &unitOuterNormal, const RangeType &value, RangeType &result) const
Definition: transportmodel.hh:160
Traits-template which has to be specialized for each individual model.
Definition: operatorparts.hh:36
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)