My Project
PressureSolverPolicy.hpp
1 /*
2  Copyright 2019 SINTEF Digital, Mathematics and Cybernetics.
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 3 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 
20 #ifndef OPM_PRESSURE_SOLVER_POLICY_HEADER_INCLUDED
21 #define OPM_PRESSURE_SOLVER_POLICY_HEADER_INCLUDED
22 
23 #include <opm/simulators/linalg/PressureTransferPolicy.hpp>
24 #include <opm/simulators/linalg/PropertyTree.hpp>
25 
26 #include <dune/istl/solver.hh>
27 #include <dune/istl/owneroverlapcopy.hh>
28 
29 namespace Dune
30 {
31 namespace Amg
32 {
33  template <class OperatorType, class Solver, class LevelTransferPolicy>
35  {
36  public:
38  using Operator = OperatorType;
44  : prm_(prm)
45  {
46  }
47 
48  private:
49  using X = typename Operator::range_type;
56  struct PressureInverseOperator : public Dune::InverseOperator<X, X>
57  {
58 #if HAVE_MPI
59  template <typename GlobalIndex, typename LocalIndex>
60  PressureInverseOperator(Operator& op,
61  const Opm::PropertyTree& prm,
62  const Dune::OwnerOverlapCopyCommunication<GlobalIndex, LocalIndex>& comm)
63  : linsolver_()
64  {
65  assert(op.category() == Dune::SolverCategory::overlapping);
66  // Assuming that we do not use Cpr as Pressure solver and use hard
67  // coded pressure index that might be wrong but should be unused.
68  linsolver_ = std::make_unique<Solver>(op, comm, prm, std::function<X()>(),
69  /* pressureIndex = */ 1);
70  }
71 #endif // HAVE_MPI
72 
73  PressureInverseOperator(Operator& op,
74  const Opm::PropertyTree& prm,
75  const SequentialInformation&)
76  : linsolver_()
77  {
78  assert(op.category() != Dune::SolverCategory::overlapping);
79  // Assuming that we do not use Cpr as Pressure solver and use hard
80  // coded pressure index that might be wrong but should be unused.
81  linsolver_ = std::make_unique<Solver>(op, prm, std::function<X()>(),
82  /* pressureIndex = */ 1);
83  }
84 
85 
86  Dune::SolverCategory::Category category() const override
87  {
88  return linsolver_->category();
89  }
90 
91  void apply(X& x, X& b, double reduction, Dune::InverseOperatorResult& res) override
92  {
93  linsolver_->apply(x, b, reduction, res);
94  }
95 
96  void apply(X& x, X& b, Dune::InverseOperatorResult& res) override
97  {
98  linsolver_->apply(x, b, res);
99  }
100 
101  void updatePreconditioner()
102  {
103  linsolver_->preconditioner().update();
104  }
105 
106  private:
107  std::unique_ptr<Solver> linsolver_;
108  };
109 
110  public:
112  using CoarseLevelSolver = PressureInverseOperator;
113 
120  template <class LTP>
121  void setCoarseOperator(LTP& transferPolicy)
122  {
123  coarseOperator_ = transferPolicy.getCoarseLevelOperator();
124  }
125  template <class LTP>
126  CoarseLevelSolver* createCoarseLevelSolver(LTP& transferPolicy)
127  {
128  coarseOperator_ = transferPolicy.getCoarseLevelOperator();
129  auto& tp = dynamic_cast<LevelTransferPolicy&>(transferPolicy); // TODO: make this unnecessary.
130  PressureInverseOperator* inv
131  = new PressureInverseOperator(*coarseOperator_, prm_, tp.getCoarseLevelCommunication());
132  return inv;
133  }
134 
135  private:
137  std::shared_ptr<Operator> coarseOperator_;
138  Opm::PropertyTree prm_;
139  };
140 } // namespace Amg
141 } // namespace Dune
142 
143 
144 #endif // OPM_PRESSURE_SOLVER_POLICY_HEADER_INCLUDED
Definition: PressureSolverPolicy.hpp:35
PressureSolverPolicy(const Opm::PropertyTree &prm)
Constructs the coarse solver policy.
Definition: PressureSolverPolicy.hpp:43
OperatorType Operator
The type of the linear operator used.
Definition: PressureSolverPolicy.hpp:38
PressureInverseOperator CoarseLevelSolver
The type of solver constructed for the coarse level.
Definition: PressureSolverPolicy.hpp:112
void setCoarseOperator(LTP &transferPolicy)
Constructs a coarse level solver.
Definition: PressureSolverPolicy.hpp:121
Definition: PropertyTree.hpp:37