DUNE-ACFEM (2.5.1)

plaplacianmodel.hh
1 #ifndef __DUNE_ACFEM_MODELS_MODULES_PLAPLACIANMODEL_HH__
2 #define __DUNE_ACFEM_MODELS_MODULES_PLAPLACIANMODEL_HH__
3 
4 #include "../operatorparts/modeladapter.hh"
5 
6 namespace Dune {
7 
8  namespace ACFem {
9 
50  template<class FunctionSpace>
52  : public OperatorPartsExpression<P_LaplacianOperatorParts<FunctionSpace> >
53  {
58  public:
59  typedef FunctionSpace FunctionSpaceType;
60 
61  typedef typename FunctionSpaceType::DomainType DomainType;
62  typedef typename FunctionSpaceType::RangeType RangeType;
63  typedef typename FunctionSpaceType::JacobianRangeType JacobianRangeType;
64  typedef typename FunctionSpaceType::HessianRangeType HessianRangeType;
65 
66  enum {
67  dimDomain = FunctionSpaceType::dimDomain,
68  dimRange = FunctionSpaceType::dimRange
69  };
70 
71  typedef typename FunctionSpaceType::DomainFieldType DomainFieldType;
72  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
73 
74  // Interface methods that need to be reimplemented
75 
76  P_LaplacianOperatorParts(const RangeFieldType& exponent, const std::string& name = "")
77  : exponent_(exponent - 2.),
78  name_(name == "" ? "(|grad(U)|^" + std::to_string(exponent_) + " grad(U))" : name)
79  {}
80 
81  std::string name() const
82  {
83  return name_;
84  }
85 
87  template<class Entity, class Point>
88  void flux(const Entity& entity,
89  const Point &x,
90  const RangeType& value,
91  const JacobianRangeType& jacobian,
92  JacobianRangeType& flux) const
93  {
94  RangeFieldType factor = std::pow(jacobian.frobenius_norm2(), 0.5*exponent_);
95 
96  flux = jacobian;
97  flux *= factor;
98  }
99 
101  template<class Entity, class Point>
102  void linearizedFlux(const RangeType& uBar,
103  const JacobianRangeType& DuBar,
104  const Entity& entity,
105  const Point &x,
106  const RangeType& value,
107  const JacobianRangeType& jacobian,
108  JacobianRangeType& flux) const
109  {
110  RangeFieldType norm = DuBar.frobenius_norm2();
111 
112  flux = jacobian;
113  flux *= std::pow(norm, 0.5 * exponent_);
114 
115  JacobianRangeType tmp(DuBar);
116 
117  RangeFieldType factor = exponent_*std::pow(norm, 0.5*exponent_ - 1.);
118  RangeFieldType frobscp = 0;
119  for (int i = 0; i< dimRange; ++i) {
120  frobscp += (DuBar[i] * jacobian[i]);
121  }
122 
123  tmp *= factor * frobscp;
124  flux += tmp;
125  }
126 
128  template<class Entity, class Point>
129  void fluxDivergence(const Entity& entity,
130  const Point &x,
131  const RangeType& value,
132  const JacobianRangeType& jacobian,
133  const HessianRangeType& hessian,
134  RangeType& result) const
135  {
136  RangeFieldType norm = jacobian.frobenius_norm2();
137  RangeFieldType factor1 = std::pow(norm, 0.5*exponent_ - 1.);
138  RangeFieldType factor2 = factor1 * norm;
139 
140  JacobianRangeType jac_hess(0);
141 
142  for (int alpha = 0; alpha < dimRange; ++alpha) {
143  DomainType tmp;
144  hessian[alpha].mv(jacobian[alpha], tmp);
145  jac_hess[alpha] += tmp;
146  }
147  jac_hess *= factor1 * exponent_;
148 
149  for (int beta = 0; beta < dimRange; ++beta) {
150  RangeFieldType laplacian(0);
151  for (int i = 0; i < dimDomain; ++i) {
152  laplacian += hessian[beta][i][i];
153  }
154  result[beta] = -factor2 * laplacian; // weighted Laplacian
155  result[beta] -= (jac_hess[beta] * jacobian[beta]);
156  }
157  }
158 
159  protected:
160  const RangeFieldType exponent_;
161  const std::string name_;
162  };
163 
164  template<class FunctionSpace>
165  struct OperatorPartsTraits<P_LaplacianOperatorParts<FunctionSpace> >
166  : public DefaultOperatorPartsTraits<FunctionSpace>
167  {
170  {
171  isLinear = false,
172  isSymmetric = true,
173  isSemiDefinite = true
174  };
175 
178  hasFlux = true,
179  hasSources = false,
180  hasRobinFlux = false,
181  };
182  };
183 
185 
187 
198  template<class Object>
199  static inline
200  P_LaplacianOperatorParts<typename Object::FunctionSpaceType>
201  p_LaplacianOperatorParts(const typename Object::FunctionSpaceType::RangeFieldType& p,
202  const Object& object,
203  const std::string& name = "")
204  {
206  return OperatorPartsType(p, name);
207  }
208 
215  template<class Object>
216  static inline
217  OperatorPartsAdapterModel<P_LaplacianOperatorParts<typename Object::FunctionSpaceType>,
218  typename Object::GridPartType>
219  p_LaplacianModel(const typename Object::FunctionSpaceType::RangeFieldType& p,
220  const Object& object,
221  const std::string& name = "")
222  {
224  typedef typename Object::GridPartType GridPartType;
225  return OperatorPartsAdapterModel<OperatorPartsType, GridPartType>(OperatorPartsType(p, name));
226  }
227 
229 
231 
232  } // namespace ACFem
233 
234 } //Namespace Dune
235 
236 
237 #endif // __DUNE_ACFEM_MODELS_MODULES_PLAPLACIANMODEL_HH__
Default model implementation.
Definition: operatorparts.hh:387
Interface class for second order elliptic models.
Definition: operatorparts.hh:92
The p-Laplacian-model.
Definition: plaplacianmodel.hh:53
void flux(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
Evaluate in local coordinates.
Definition: plaplacianmodel.hh:88
void fluxDivergence(const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, const HessianRangeType &hessian, RangeType &result) const
Compute the point-wise value of the flux-part of the operator, meaning the part of the differential o...
Definition: plaplacianmodel.hh:129
static P_LaplacianOperatorParts< typename Object::FunctionSpaceType > p_LaplacianOperatorParts(const typename Object::FunctionSpaceType::RangeFieldType &p, const Object &object, const std::string &name="")
Generate OperatorParts for a (weak, of course) p-Laplacian.
Definition: plaplacianmodel.hh:201
StructureFlags
Static flags for the overall structure of the operator.
Definition: plaplacianmodel.hh:170
ConstituentFlags
Provide information about the constituents of the model.
Definition: plaplacianmodel.hh:177
void linearizedFlux(const RangeType &uBar, const JacobianRangeType &DuBar, const Entity &entity, const Point &x, const RangeType &value, const JacobianRangeType &jacobian, JacobianRangeType &flux) const
Evaluate the linearized flux in local coordinates.
Definition: plaplacianmodel.hh:102
static OperatorPartsAdapterModel< P_LaplacianOperatorParts< typename Object::FunctionSpaceType >, typename Object::GridPartType > p_LaplacianModel(const typename Object::FunctionSpaceType::RangeFieldType &p, const Object &object, const std::string &name="")
Generate a P-laplacian model fitting the specified object.
Definition: plaplacianmodel.hh:219
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)