fvbaseadlocallinearizer.hh
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  Copyright (C) 2008-2015 by Andreas Lauser
5  Copyright (C) 2011-2012 by Bernd Flemisch
6  Copyright (C) 2011 by Klaus Mosthaf
7 
8  This file is part of the Open Porous Media project (OPM).
9 
10  OPM is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 2 of the License, or
13  (at your option) any later version.
14 
15  OPM is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with OPM. If not, see <http://www.gnu.org/licenses/>.
22 */
28 #ifndef EWOMS_FV_BASE_AD_LOCAL_LINEARIZER_HH
29 #define EWOMS_FV_BASE_AD_LOCAL_LINEARIZER_HH
30 
31 #include <opm/material/localad/Math.hpp>
32 
33 #include "fvbaseproperties.hh"
34 
35 #include <dune/istl/bvector.hh>
36 #include <dune/istl/matrix.hh>
37 
38 #include <dune/common/fvector.hh>
39 #include <dune/common/fmatrix.hh>
40 
41 namespace Ewoms {
42 // forward declaration
43 template<class TypeTag>
45 
46 namespace Properties {
47 // declare the property tags required for the finite differences local linearizer
48 NEW_TYPE_TAG(AutoDiffLocalLinearizer);
49 
50 NEW_PROP_TAG(LocalLinearizer);
51 NEW_PROP_TAG(Evaluation);
52 
53 NEW_PROP_TAG(LocalResidual);
55 NEW_PROP_TAG(Problem);
56 NEW_PROP_TAG(Model);
57 NEW_PROP_TAG(PrimaryVariables);
58 NEW_PROP_TAG(ElementContext);
59 NEW_PROP_TAG(Scalar);
60 NEW_PROP_TAG(Evaluation);
61 NEW_PROP_TAG(GridView);
62 
63 // set the properties to be spliced in
64 SET_TYPE_PROP(AutoDiffLocalLinearizer, LocalLinearizer,
66 
68 SET_PROP(AutoDiffLocalLinearizer, Evaluation)
69 {
70 private:
71  static const int numEq = GET_PROP_VALUE(TypeTag, NumEq);
72 
73  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
74  typedef typename GET_PROP_TYPE(TypeTag, Discretization) Discretization;
75 
76 public:
77  typedef Opm::LocalAd::Evaluation<Scalar, Discretization, numEq> type;
78 };
79 
80 } // namespace Properties
81 
90 template<class TypeTag>
91 class FvBaseAdLocalLinearizer
92 {
93 private:
94  typedef typename GET_PROP_TYPE(TypeTag, LocalLinearizer) Implementation;
95  typedef typename GET_PROP_TYPE(TypeTag, LocalResidual) LocalResidual;
96  typedef typename GET_PROP_TYPE(TypeTag, Simulator) Simulator;
97  typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
98  typedef typename GET_PROP_TYPE(TypeTag, Model) Model;
99  typedef typename GET_PROP_TYPE(TypeTag, PrimaryVariables) PrimaryVariables;
100  typedef typename GET_PROP_TYPE(TypeTag, ElementContext) ElementContext;
101  typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
102  typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
103  typedef typename GridView::template Codim<0>::Entity Element;
104 
105  enum { numEq = GET_PROP_VALUE(TypeTag, NumEq) };
106  typedef Dune::FieldMatrix<Scalar, numEq, numEq> MatrixBlock;
107  typedef Dune::Matrix<MatrixBlock> LocalBlockMatrix;
108 
109  typedef Dune::FieldVector<Scalar, numEq> VectorBlock;
110  typedef Dune::BlockVector<VectorBlock> LocalBlockVector;
111  typedef Dune::BlockVector<MatrixBlock> LocalStorageMatrix;
112 
113 #if __GNUC__ == 4 && __GNUC_MINOR__ <= 6
114 public:
115  // make older GCCs happy by providing a public copy constructor (this is necessary
116  // for their implementation of std::vector, although the method is never called...)
119  {}
120 
121 #else
122  // copying local residual objects around is a very bad idea, so we explicitly prevent
123  // it...
125 #endif
126 public:
129  { }
130 
132  { delete internalElemContext_; }
133 
137  static void registerParameters()
138  { }
139 
148  void init(Simulator &simulator)
149  {
150  simulatorPtr_ = &simulator;
151  delete internalElemContext_;
152  internalElemContext_ = new ElementContext(simulator);
153  }
154 
166  void linearize(const Element &element)
167  {
168  internalElemContext_->updateAll(element);
169 
171  }
172 
187  void linearize(ElementContext &elemCtx)
188  {
189  // update the weights of the primary variables for the context
190  model_().updatePVWeights(elemCtx);
191 
192  resize_(elemCtx);
193  reset_(elemCtx);
194 
195  // calculate the local residual
196  localResidual_.eval(elemCtx);
197 
198  // calculate the local jacobian matrix
199  int numPrimaryDof = elemCtx.numPrimaryDof(/*timeIdx=*/0);
200  for (int dofIdx = 0; dofIdx < numPrimaryDof; dofIdx++) {
201  // convert the local Jacobian matrix and the right hand side from the data
202  // structures used by the automatic differentiation code to the conventional
203  // ones used by the linear solver.
204  updateLocalLinearization_(elemCtx, dofIdx);
205  }
206  }
207 
212  static Scalar baseEpsilon()
213  { return GET_PROP_VALUE(TypeTag, BaseEpsilon); }
214 
226  Scalar numericEpsilon(const ElementContext &elemCtx,
227  int dofIdx,
228  int pvIdx) const
229  {
230  int globalIdx = elemCtx.globalSpaceIndex(dofIdx, /*timeIdx=*/0);
231  Scalar pvWeight = elemCtx.model().primaryVarWeight(globalIdx, pvIdx);
232  assert(pvWeight > 0 && std::isfinite(pvWeight));
233  Valgrind::CheckDefined(pvWeight);
234 
235  return baseEpsilon()/pvWeight;
236  }
237 
241  LocalResidual &localResidual()
242  { return localResidual_; }
243 
247  const LocalResidual &localResidual() const
248  { return localResidual_; }
249 
258  const MatrixBlock &jacobian(int domainScvIdx, int rangeScvIdx) const
259  { return jacobian_[domainScvIdx][rangeScvIdx]; }
260 
266  const MatrixBlock &jacobianStorage(int dofIdx) const
267  { return jacobianStorage_[dofIdx]; }
268 
274  const VectorBlock &residual(int dofIdx) const
275  { return residual_[dofIdx]; }
276 
282  const VectorBlock &residualStorage(int dofIdx) const
283  { return residualStorage_[dofIdx]; }
284 
285 protected:
286  Implementation &asImp_()
287  { return *static_cast<Implementation*>(this); }
288  const Implementation &asImp_() const
289  { return *static_cast<const Implementation*>(this); }
290 
291  const Simulator &simulator_() const
292  { return *simulatorPtr_; }
293  const Problem &problem_() const
294  { return simulatorPtr_->problem(); }
295  const Model &model_() const
296  { return simulatorPtr_->model(); }
297 
302  { return EWOMS_GET_PARAM(TypeTag, int, NumericDifferenceMethod); }
303 
308  void resize_(const ElementContext &elemCtx)
309  {
310  int numDof = elemCtx.numDof(/*timeIdx=*/0);
311  int numPrimaryDof = elemCtx.numPrimaryDof(/*timeIdx=*/0);
312 
313  jacobian_.setSize(numDof, numPrimaryDof);
314  jacobianStorage_.resize(numPrimaryDof);
315 
316  residual_.resize(numDof);
317  residualStorage_.resize(numPrimaryDof);
318  }
319 
323  void reset_(const ElementContext &elemCtx)
324  {
325  int numDof = elemCtx.numDof(/*timeIdx=*/0);
326  int numPrimaryDof = elemCtx.numPrimaryDof(/*timeIdx=*/0);
327  for (int primaryDofIdx = 0; primaryDofIdx < numPrimaryDof; ++ primaryDofIdx) {
328  residualStorage_[primaryDofIdx] = 0.0;
329 
330  jacobianStorage_[primaryDofIdx] = 0.0;
331  for (int dof2Idx = 0; dof2Idx < numDof; ++ dof2Idx) {
332  jacobian_[dof2Idx][primaryDofIdx] = 0.0;
333  }
334  }
335 
336  for (int primaryDofIdx = 0; primaryDofIdx < numDof; ++ primaryDofIdx)
337  residual_[primaryDofIdx] = 0.0;
338  }
339 
345  void updateLocalLinearization_(const ElementContext &elemCtx,
346  int primaryDofIdx)
347  {
348  const auto& residStorage = localResidual_.storageTerm();
349  const auto& resid = localResidual_.residual();
350 
351  for (int eqIdx = 0; eqIdx < numEq; eqIdx++) {
352  residual_[primaryDofIdx][eqIdx] = resid[primaryDofIdx][eqIdx].value;
353  residualStorage_[primaryDofIdx][eqIdx] = residStorage[primaryDofIdx][eqIdx].value;
354 
355  // store the derivative of the storage term
356  for (int pvIdx = 0; pvIdx < numEq; pvIdx++)
357  jacobianStorage_[primaryDofIdx][eqIdx][pvIdx] = residStorage[primaryDofIdx][eqIdx].derivatives[pvIdx];
358  }
359 
360  int numDof = elemCtx.numDof(/*timeIdx=*/0);
361  for (int dofIdx = 0; dofIdx < numDof; dofIdx++) {
362  for (int eqIdx = 0; eqIdx < numEq; eqIdx++) {
363  for (int pvIdx = 0; pvIdx < numEq; pvIdx++) {
364  // A[dofIdx][primaryDofIdx][eqIdx][pvIdx] is the partial derivative of
365  // the residual function 'eqIdx' for the degree of freedom 'dofIdx' with
366  // regard to the primary variable 'pvIdx' of the degree of freedom
367  // 'primaryDofIdx'
368  jacobian_[dofIdx][primaryDofIdx][eqIdx][pvIdx] = resid[dofIdx][eqIdx].derivatives[pvIdx];
369  Valgrind::CheckDefined(jacobian_[dofIdx][primaryDofIdx][eqIdx][pvIdx]);
370  }
371  }
372  }
373  }
374 
376  Model *modelPtr_;
377 
378  ElementContext *internalElemContext_;
379 
380  LocalBlockVector residual_;
381  LocalBlockVector residualStorage_;
382 
383  LocalBlockMatrix jacobian_;
384  LocalStorageMatrix jacobianStorage_;
385 
386  LocalResidual localResidual_;
387 };
388 
389 } // namespace Ewoms
390 
391 #endif
const MatrixBlock & jacobian(int domainScvIdx, int rangeScvIdx) const
Returns the local Jacobian matrix of the residual of a sub-control volume.
Definition: fvbaseadlocallinearizer.hh:258
void linearize(const Element &element)
Compute an element's local Jacobian matrix and evaluate its residual.
Definition: fvbaseadlocallinearizer.hh:166
const Simulator & simulator_() const
Definition: fvbaseadlocallinearizer.hh:291
const VectorBlock & residualStorage(int dofIdx) const
Returns the local storage term of a sub-control volume.
Definition: fvbaseadlocallinearizer.hh:282
void updateLocalLinearization_(const ElementContext &elemCtx, int primaryDofIdx)
Updates the current local Jacobian matrix with the partial derivatives of all equations in regard to ...
Definition: fvbaseadlocallinearizer.hh:345
void linearize(ElementContext &elemCtx)
Compute an element's local Jacobian matrix and evaluate its residual.
Definition: fvbaseadlocallinearizer.hh:187
LocalBlockMatrix jacobian_
Definition: fvbaseadlocallinearizer.hh:383
void init(Simulator &simulator)
Initialize the local Jacobian object.
Definition: fvbaseadlocallinearizer.hh:148
LocalBlockVector residualStorage_
Definition: fvbaseadlocallinearizer.hh:381
LocalResidual & localResidual()
Return reference to the local residual.
Definition: fvbaseadlocallinearizer.hh:241
static Scalar baseEpsilon()
Returns the unweighted epsilon value used to calculate the local derivatives.
Definition: fvbaseadlocallinearizer.hh:212
Problem & problem()
Return the object which specifies the pysical setup of the simulation.
Definition: simulator.hh:189
FvBaseAdLocalLinearizer()
Definition: fvbaseadlocallinearizer.hh:127
Declare the properties used by the infrastructure code of the finite volume discretizations.
const VectorBlock & residual(int dofIdx) const
Returns the local residual of a sub-control volume.
Definition: fvbaseadlocallinearizer.hh:274
#define GET_PROP_VALUE(TypeTag, PropTagName)
Access the value attribute of a property for a type tag.
Definition: propertysystem.hh:468
Implementation & asImp_()
Definition: fvbaseadlocallinearizer.hh:286
#define GET_PROP_TYPE(TypeTag, PropTagName)
Access the type attribute of a property for a type tag.
Definition: propertysystem.hh:485
LocalBlockVector residual_
Definition: fvbaseadlocallinearizer.hh:380
SET_PROP(NumericModel, ParameterTree)
Set the ParameterTree property.
Definition: basicproperties.hh:117
const MatrixBlock & jacobianStorage(int dofIdx) const
Returns the local Jacobian matrix the storage term of a sub-control volume.
Definition: fvbaseadlocallinearizer.hh:266
static void registerParameters()
Register all run-time parameters for the local jacobian.
Definition: fvbaseadlocallinearizer.hh:137
const LocalResidual & localResidual() const
Return reference to the local residual.
Definition: fvbaseadlocallinearizer.hh:247
Simulator * simulatorPtr_
Definition: fvbaseadlocallinearizer.hh:375
Scalar numericEpsilon(const ElementContext &elemCtx, int dofIdx, int pvIdx) const
Returns the epsilon value which is added and removed from the current solution.
Definition: fvbaseadlocallinearizer.hh:226
NEW_PROP_TAG(Grid)
The type of the DUNE grid.
void reset_(const ElementContext &elemCtx)
Reset the all relevant internal attributes to 0.
Definition: fvbaseadlocallinearizer.hh:323
ElementContext * internalElemContext_
Definition: fvbaseadlocallinearizer.hh:378
SET_TYPE_PROP(NumericModel, Scalar, double)
Set the default type of scalar values to double.
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:73
void resize_(const ElementContext &elemCtx)
Resize all internal attributes to the size of the element.
Definition: fvbaseadlocallinearizer.hh:308
Definition: baseauxiliarymodule.hh:35
Model * modelPtr_
Definition: fvbaseadlocallinearizer.hh:376
Model & model()
Return the physical model used in the simulation.
Definition: simulator.hh:176
const Implementation & asImp_() const
Definition: fvbaseadlocallinearizer.hh:288
LocalStorageMatrix jacobianStorage_
Definition: fvbaseadlocallinearizer.hh:384
NEW_TYPE_TAG(AuxModule)
static int numericDifferenceMethod_()
Returns the numeric difference method which is applied.
Definition: fvbaseadlocallinearizer.hh:301
const Problem & problem_() const
Definition: fvbaseadlocallinearizer.hh:293
Calculates the local residual and its Jacobian for a single element of the grid.
Definition: fvbaseadlocallinearizer.hh:44
const Model & model_() const
Definition: fvbaseadlocallinearizer.hh:295
LocalResidual localResidual_
Definition: fvbaseadlocallinearizer.hh:386
~FvBaseAdLocalLinearizer()
Definition: fvbaseadlocallinearizer.hh:131
#define EWOMS_GET_PARAM(TypeTag, ParamType, ParamName)
Retrieve a runtime parameter.
Definition: parametersystem.hh:95