DUNE-ACFEM (unstable)

plaplacianmodel.hh
1 #ifndef __DUNE_ACFEM_MODELS_MODULES_PLAPLACIANMODEL_HH__
2 #define __DUNE_ACFEM_MODELS_MODULES_PLAPLACIANMODEL_HH__
3 
4 #include "../../common/literals.hh"
5 #include "../../expressions/terminal.hh"
6 #include "../../tensors/tensor.hh"
7 
8 #include "../modelbase.hh"
9 #include "../expressiontraits.hh"
10 
11 namespace Dune {
12 
13  namespace ACFem::PDEModel {
14 
15  using namespace Literals;
16 
57  template<class FunctionSpace, class PField>
59  : public ModelBase<FunctionSpace>
60  , public Expressions::SelfExpression<P_LaplacianModel<FunctionSpace, PField> >
61  , public MPL::UniqueTags<ConditionalType<ExpressionTraits<PField>::isVolatile, VolatileExpression, void>,
62  ConditionalType<IsConstantExprArg<PField>::value, ConstantExpression, void>,
63  ConditionalType<IsTypedValue<PField>::value, TypedValueExpression, void>,
64  SemiPositiveExpression,
65  SymmetricModel>
66  {
67  using ThisType = P_LaplacianModel;
69  public:
70  using typename BaseType::DomainType;
71  using typename BaseType::RangeFieldType;
72  using typename BaseType::RangeType;
73  using typename BaseType::JacobianRangeType;
74  using typename BaseType::HessianRangeType;
75  using PFieldType = PField;
76  using ExponentType = std::decay_t<decltype(std::declval<PFieldType>() - 2_f)>;
77  using BaseType::dimDomain;
78  using BaseType::dimRange;
79 
80  // Interface methods that need to be reimplemented
81 
82  P_LaplacianModel(PFieldType&& exponent, const std::string& name = "")
83  : exponent_(exponent - 2_f),
84  name_(name == "" ? "(|grad(U)|^" + toString(exponent_) + " grad(U))" : name)
85  {}
86 
87  std::string name() const
88  {
89  return name_;
90  }
91 
93  auto flux(const JacobianRangeType& jacobian) const
94  {
95  const auto factor = std::pow(jacobian.frobenius_norm2(), 0.5*exponent_);
96 
97  auto flux = jacobian;
98  return flux *= factor;
99  }
100 
102  auto linearizedFlux(const JacobianRangeType& DuBar,
103  const JacobianRangeType& jacobian) const
104  {
105  const auto norm = DuBar.frobenius_norm2();
106 
107  auto flux = jacobian;
108  flux *= std::pow(norm, 0.5 * exponent_);
109 
110  auto tmp = DuBar;
111 
112  auto factor = exponent_*std::pow(norm, 0.5*(exponent_ - 1.));
113  auto frobscp = contractInner<2>(DuBar, jacobian);
114 
115  tmp *= factor * frobscp;
116  return flux += tmp;
117  }
118 
120  auto fluxDivergence(const JacobianRangeType& jacobian,
121  const HessianRangeType& hessian) const
122  {
123  const auto norm = jacobian.frobenius_norm2();
124  const auto factor1 = std::pow(norm, 0.5*exponent_ - 1.);
125  const auto factor2 = factor1 * norm;
126 
127  JacobianRangeType jac_hess = 0;
128 
129  for (int alpha = 0; alpha < dimRange; ++alpha) {
130  DomainType tmp;
131  hessian[alpha].mv(jacobian[alpha], tmp);
132  jac_hess[alpha] += tmp;
133  }
134  jac_hess *= factor1 * exponent_;
135 
136  RangeType result;
137  for (int beta = 0; beta < dimRange; ++beta) {
138  RangeFieldType laplacian = 0;
139  for (int i = 0; i < dimDomain; ++i) {
140  laplacian += hessian[beta][i][i];
141  }
142  result[beta] = -factor2 * laplacian; // weighted Laplacian
143  result[beta] -= (jac_hess[beta] * jacobian[beta]);
144  }
145  return result;
146  }
147 
148  const ExponentType& exponent() const { return exponent_; }
149 
150  constexpr auto p() const { return exponent_ + 2_f; }
151 
152  protected:
153  ExponentType exponent_;
154  std::string name_;
155  };
156 
158 
160 
175  template<class Object, class PField>
176  constexpr auto p_LaplacianModel(PField&& p, const Object& object, const std::string& name = "")
177  {
179  return expressionClosure(ModelType(std::forward<PField>(p), name));
180  }
181 
183 
185 
186  } // namespace ACFem::PDEModel
187 
188  namespace ACFem {
189 
191 
192  }
193 
194 } //Namespace Dune
195 
196 
197 #endif // __DUNE_ACFEM_MODELS_MODULES_PLAPLACIANMODEL_HH__
The p-Laplacian-model.
Definition: plaplacianmodel.hh:66
constexpr decltype(auto) expressionClosure(T &&t)
Do-nothing default implementation for pathologic cases.
Definition: interface.hh:93
auto fluxDivergence(const JacobianRangeType &jacobian, const HessianRangeType &hessian) const
Compute the point-wise value of the flux-part of the operator, meaning the part of the differential o...
Definition: plaplacianmodel.hh:120
constexpr auto p_LaplacianModel(PField &&p, const Object &object, const std::string &name="")
Generate Model for a (weak, of course) p-Laplacian.
Definition: plaplacianmodel.hh:176
auto linearizedFlux(const JacobianRangeType &DuBar, const JacobianRangeType &jacobian) const
Evaluate the linearized flux in local coordinates.
Definition: plaplacianmodel.hh:102
auto flux(const JacobianRangeType &jacobian) const
Evaluate in local coordinates.
Definition: plaplacianmodel.hh:93
auto pow(T1 &&t1, T2 &&t2)
Power operations with scalar exponents are promoted to component-wise power operations by multiplying...
Definition: expressions.hh:525
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
HessianRangeSelector< FunctionSpaceType > HessianRangeType
The type returned by classifyBoundary().
Definition: modelbase.hh:65
typename FunctionSpaceType::RangeFieldType RangeFieldType
The type returned by classifyBoundary().
Definition: modelbase.hh:67
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 3, 22:32, 2024)