opm-simulators
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  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
28 #ifndef EWOMS_FV_BASE_AD_LOCAL_LINEARIZER_HH
29 #define EWOMS_FV_BASE_AD_LOCAL_LINEARIZER_HH
30 
31 #include <dune/common/fmatrix.hh>
32 #include <dune/common/fvector.hh>
33 
34 #include <dune/istl/bvector.hh>
35 #include <dune/istl/matrix.hh>
36 
37 #include <opm/material/common/Valgrind.hpp>
38 #include <opm/material/densead/Math.hpp>
39 
41 
43 
44 #include <cstddef>
45 #include <memory>
46 
47 namespace Opm {
48 // forward declaration
49 template<class TypeTag>
51 }
52 
53 namespace Opm::Properties {
54 
55 // declare the property tags required for the finite differences local linearizer
56 
57 namespace TTag {
59 } // namespace TTag
60 
61 // set the properties to be spliced in
62 template<class TypeTag>
63 struct LocalLinearizer<TypeTag, TTag::AutoDiffLocalLinearizer>
65 
67 template<class TypeTag>
68 struct Evaluation<TypeTag, TTag::AutoDiffLocalLinearizer>
69 {
70 private:
71  static constexpr unsigned numDerivatives = getPropValue<TypeTag, Properties::NumDerivatives>();
73 
74 public:
75  using type = DenseAd::Evaluation<Scalar, numDerivatives>;
76 };
77 
78 } // namespace Opm::Properties
79 
80 namespace Opm {
81 
90 template<class TypeTag>
92 {
93 private:
103  using Element = typename GridView::template Codim<0>::Entity;
104 
105  enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
106 
107  using ScalarVectorBlock = Dune::FieldVector<Scalar, numEq>;
108  // extract local matrices from jacobian matrix for consistency
109  using ScalarMatrixBlock = typename GetPropType<TypeTag, Properties::SparseMatrixAdapter>::MatrixBlock;
110 
111  using ScalarLocalBlockVector = Dune::BlockVector<ScalarVectorBlock>;
112  using ScalarLocalBlockMatrix = Dune::Matrix<ScalarMatrixBlock>;
113 
114 public:
115  FvBaseAdLocalLinearizer() = default;
116 
117  // copying local linearizer objects around is a very bad idea, so we explicitly
118  // prevent it...
119  FvBaseAdLocalLinearizer(const FvBaseAdLocalLinearizer&) = delete;
120 
124  static void registerParameters()
125  {}
126 
135  void init(Simulator& simulator)
136  {
137  simulatorPtr_ = &simulator;
138  internalElemContext_ = std::make_unique<ElementContext>(simulator);
139  }
140 
152  void linearize(const Element& element)
153  {
154  linearize(*internalElemContext_, element);
155  }
156 
172  void linearize(ElementContext& elemCtx, const Element& elem)
173  {
174  elemCtx.updateStencil(elem);
175  elemCtx.updateAllIntensiveQuantities();
176 
177  // update the weights of the primary variables for the context
178  model_().updatePVWeights(elemCtx);
179 
180  // resize the internal arrays of the linearizer
181  resize_(elemCtx);
182 
183  // compute the local residual and its Jacobian
184  const unsigned numPrimaryDof = elemCtx.numPrimaryDof(/*timeIdx=*/0);
185  for (unsigned focusDofIdx = 0; focusDofIdx < numPrimaryDof; ++focusDofIdx) {
186  elemCtx.setFocusDofIndex(focusDofIdx);
187  elemCtx.updateAllExtensiveQuantities();
188 
189  // calculate the local residual
190  localResidual_.eval(elemCtx);
191 
192  // convert the local Jacobian matrix and the right hand side from the data
193  // structures used by the automatic differentiation code to the conventional
194  // ones used by the linear solver.
195  updateLocalLinearization_(elemCtx, focusDofIdx);
196  }
197  }
198 
202  LocalResidual& localResidual()
203  { return localResidual_; }
204 
208  const LocalResidual& localResidual() const
209  { return localResidual_; }
210 
219  const ScalarMatrixBlock& jacobian(unsigned domainScvIdx, unsigned rangeScvIdx) const
220  { return jacobian_[domainScvIdx][rangeScvIdx]; }
221 
227  const ScalarVectorBlock& residual(unsigned dofIdx) const
228  { return residual_[dofIdx]; }
229 
230 protected:
231  Implementation& asImp_()
232  { return *static_cast<Implementation*>(this); }
233 
234  const Implementation& asImp_() const
235  { return *static_cast<const Implementation*>(this); }
236 
237  const Simulator& simulator_() const
238  { return *simulatorPtr_; }
239 
240  const Problem& problem_() const
241  { return simulatorPtr_->problem(); }
242 
243  const Model& model_() const
244  { return simulatorPtr_->model(); }
245 
250  void resize_(const ElementContext& elemCtx)
251  {
252  const std::size_t numDof = elemCtx.numDof(/*timeIdx=*/0);
253  const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(/*timeIdx=*/0);
254 
255  residual_.resize(numDof);
256  if (jacobian_.N() != numDof || jacobian_.M() != numPrimaryDof) {
257  jacobian_.setSize(numDof, numPrimaryDof);
258  }
259  }
260 
264  void reset_(const ElementContext&)
265  {
266  residual_ = 0.0;
267  jacobian_ = 0.0;
268  }
269 
274  void updateLocalLinearization_(const ElementContext& elemCtx,
275  unsigned focusDofIdx)
276  {
277  const auto& resid = localResidual_.residual();
278 
279  for (unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
280  residual_[focusDofIdx][eqIdx] = resid[focusDofIdx][eqIdx].value();
281  }
282 
283  const std::size_t numDof = elemCtx.numDof(/*timeIdx=*/0);
284  for (unsigned dofIdx = 0; dofIdx < numDof; ++dofIdx) {
285  for (unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
286  for (unsigned pvIdx = 0; pvIdx < numEq; ++pvIdx) {
287  // A[dofIdx][focusDofIdx][eqIdx][pvIdx] is the partial derivative of
288  // the residual function 'eqIdx' for the degree of freedom 'dofIdx'
289  // with regard to the focus variable 'pvIdx' of the degree of freedom
290  // 'focusDofIdx'
291  jacobian_[dofIdx][focusDofIdx][eqIdx][pvIdx] = resid[dofIdx][eqIdx].derivative(pvIdx);
292  Valgrind::CheckDefined(jacobian_[dofIdx][focusDofIdx][eqIdx][pvIdx]);
293  }
294  }
295  }
296  }
297 
298  Simulator* simulatorPtr_{};
299 
300  std::unique_ptr<ElementContext> internalElemContext_{};
301 
302  LocalResidual localResidual_{};
303 
304  ScalarLocalBlockVector residual_{};
305  ScalarLocalBlockMatrix jacobian_{};
306 };
307 
308 } // namespace Opm
309 
310 #endif
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(...))
Definition: propertysystem.hh:233
The type of the local linearizer.
Definition: fvbaseproperties.hh:97
void reset_(const ElementContext &)
Reset the all relevant internal attributes to 0.
Definition: fvbaseadlocallinearizer.hh:264
const ScalarVectorBlock & residual(unsigned dofIdx) const
Returns the local residual of a sub-control volume.
Definition: fvbaseadlocallinearizer.hh:227
LocalResidual & localResidual()
Return reference to the local residual.
Definition: fvbaseadlocallinearizer.hh:202
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Definition: fvbaseadlocallinearizer.hh:58
Declare the properties used by the infrastructure code of the finite volume discretizations.
const LocalResidual & localResidual() const
Return reference to the local residual.
Definition: fvbaseadlocallinearizer.hh:208
Calculates the local residual and its Jacobian for a single element of the grid.
Definition: fvbaseadlocallinearizer.hh:50
void resize_(const ElementContext &elemCtx)
Resize all internal attributes to the size of the element.
Definition: fvbaseadlocallinearizer.hh:250
void linearize(ElementContext &elemCtx, const Element &elem)
Compute an element&#39;s local Jacobian matrix and evaluate its residual.
Definition: fvbaseadlocallinearizer.hh:172
void linearize(const Element &element)
Compute an element&#39;s local Jacobian matrix and evaluate its residual.
Definition: fvbaseadlocallinearizer.hh:152
const ScalarMatrixBlock & jacobian(unsigned domainScvIdx, unsigned rangeScvIdx) const
Returns the local Jacobian matrix of the residual of a sub-control volume.
Definition: fvbaseadlocallinearizer.hh:219
void updateLocalLinearization_(const ElementContext &elemCtx, unsigned focusDofIdx)
Updates the current local Jacobian matrix with the partial derivatives of all equations for the degre...
Definition: fvbaseadlocallinearizer.hh:274
void init(Simulator &simulator)
Initialize the local Jacobian object.
Definition: fvbaseadlocallinearizer.hh:135
static void registerParameters()
Register all run-time parameters for the local jacobian.
Definition: fvbaseadlocallinearizer.hh:124
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:83
Representation of a function evaluation and all necessary derivatives with regard to the intensive qu...
Definition: fvbaseproperties.hh:66
Definition: blackoilmodel.hh:80
Declares the properties required by the black oil model.