opm-simulators
NonlinearSystemBlackOilReservoir.hpp
1 /*
2  Copyright 2013, 2015 SINTEF ICT, Applied Mathematics.
3  Copyright 2014, 2015 Dr. Blatt - HPC-Simulation-Software & Services
4  Copyright 2014, 2015 Statoil ASA.
5  Copyright 2015 NTNU
6  Copyright 2015, 2016, 2017 IRIS AS
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 3 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 */
23 
24 #ifndef OPM_NONLINEAR_SYSTEM_BLACK_OIL_RESERVOIR_HEADER_INCLUDED
25 #define OPM_NONLINEAR_SYSTEM_BLACK_OIL_RESERVOIR_HEADER_INCLUDED
26 
27 #include <opm/simulators/aquifers/BlackoilAquiferModel.hpp>
28 
29 #include <opm/simulators/flow/NonlinearSystem.hpp>
30 
31 #include <opm/simulators/flow/BlackoilModelConvergenceMonitor.hpp>
32 #include <opm/simulators/flow/NonlinearSystemNldd.hpp>
33 #include <opm/simulators/flow/BlackoilModelProperties.hpp>
35 #include <opm/simulators/flow/RSTConv.hpp>
36 
37 #include <opm/simulators/linalg/ISTLSolver.hpp>
38 
39 #include <opm/simulators/timestepping/ConvergenceReport.hpp>
40 #include <opm/simulators/timestepping/SimulatorReport.hpp>
41 #include <opm/simulators/timestepping/SimulatorTimer.hpp>
42 
43 #include <opm/simulators/utils/ComponentName.hpp>
44 
45 #include <opm/simulators/wells/BlackoilWellModel.hpp>
46 
47 #include <memory>
48 #include <tuple>
49 #include <vector>
50 
51 #include <fmt/format.h>
52 
53 namespace Opm {
54 
61 template <class TypeTag>
63 {
64 public:
65  // --------- Types and enums ---------
67  using Simulator = typename ParentType::Simulator;
68  using Grid = typename ParentType::Grid;
79  using GlobalEqVector = typename ParentType::GlobalEqVector;
81 
82  static constexpr bool enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>();
83 
84  static constexpr int numEq = Indices::numEq;
85  static constexpr int contiSolventEqIdx = Indices::contiSolventEqIdx;
86  static constexpr int contiZfracEqIdx = Indices::contiZfracEqIdx;
87  static constexpr int contiPolymerEqIdx = Indices::contiPolymerEqIdx;
88  static constexpr int contiEnergyEqIdx = Indices::contiEnergyEqIdx;
89  static constexpr int contiPolymerMWEqIdx = Indices::contiPolymerMWEqIdx;
90  static constexpr int contiFoamEqIdx = Indices::contiFoamEqIdx;
91  static constexpr int contiBrineEqIdx = Indices::contiBrineEqIdx;
92  static constexpr int contiMicrobialEqIdx = Indices::contiMicrobialEqIdx;
93  static constexpr int contiOxygenEqIdx = Indices::contiOxygenEqIdx;
94  static constexpr int contiUreaEqIdx = Indices::contiUreaEqIdx;
95  static constexpr int contiBiofilmEqIdx = Indices::contiBiofilmEqIdx;
96  static constexpr int contiCalciteEqIdx = Indices::contiCalciteEqIdx;
97  static constexpr unsigned solventSaturationIdx = Indices::solventSaturationIdx;
98  static constexpr unsigned zFractionIdx = Indices::zFractionIdx;
99  static constexpr unsigned polymerConcentrationIdx = Indices::polymerConcentrationIdx;
100  static constexpr unsigned polymerMoleWeightIdx = Indices::polymerMoleWeightIdx;
101  static constexpr unsigned temperatureIdx = Indices::temperatureIdx;
102  static constexpr unsigned foamConcentrationIdx = Indices::foamConcentrationIdx;
103  static constexpr unsigned saltConcentrationIdx = Indices::saltConcentrationIdx;
104  static constexpr unsigned microbialConcentrationIdx = Indices::microbialConcentrationIdx;
105  static constexpr unsigned oxygenConcentrationIdx = Indices::oxygenConcentrationIdx;
106  static constexpr unsigned ureaConcentrationIdx = Indices::ureaConcentrationIdx;
107  static constexpr unsigned biofilmVolumeFractionIdx = Indices::biofilmVolumeFractionIdx;
108  static constexpr unsigned calciteVolumeFractionIdx = Indices::calciteVolumeFractionIdx;
109 
110  using VectorBlockType = Dune::FieldVector<Scalar, numEq>;
111  using MatrixBlockType = typename SparseMatrixAdapter::MatrixBlock;
112  using Mat = typename SparseMatrixAdapter::IstlMatrix;
113  using BVector = Dune::BlockVector<VectorBlockType>;
114 
116 
117  // Helper structs
118  struct CnvPvSplitData {
119  std::pair<std::vector<double>, std::vector<int>> cnvPvSplit;
120  std::vector<unsigned> ixCells;
121  };
122 
124  Scalar dPMax = 0.0;
125  Scalar dSMax = 0.0;
126  Scalar dRsMax = 0.0;
127  Scalar dRvMax = 0.0;
128  };
129 
130  // Output debug flags for which tolerances used
131  enum class DebugFlags {
132  STRICT = 0,
133  RELAXED = 1,
134  TUNINGDP = 2
135  };
136 
137  // --------- Public methods ---------
138 
147  const ModelParameters& param,
148  BlackoilWellModel<TypeTag>& well_model,
149  const bool terminal_output);
150 
151  const EclipseState& eclState() const
152  { return this->simulator_.vanguard().eclState(); }
153 
156  SimulatorReportSingle prepareStep(const SimulatorTimerInterface& timer);
157 
158  void initialLinearization(SimulatorReportSingle& report,
159  const int minIter,
160  const int maxIter,
161  const SimulatorTimerInterface& timer) override;
162 
170  template <class NonlinearSolverType>
171  SimulatorReportSingle nonlinearIteration(const SimulatorTimerInterface& timer,
172  NonlinearSolverType& nonlinear_solver);
173 
174  template <class NonlinearSolverType>
175  SimulatorReportSingle nonlinearIterationNewton(const SimulatorTimerInterface& timer,
176  NonlinearSolverType& nonlinear_solver);
177 
178  // compute the "relative" change of the solution between time steps
179  Scalar relativeChange() const;
180 
183  { return this->simulator_.model().newtonMethod().linearSolver().iterations (); }
184 
185  // Obtain reference to linear solver setup time
186  double& linearSolveSetupTime()
187  { return this->linear_solve_setup_time_; }
188 
191  void solveJacobianSystem(BVector& x);
192 
194  bool shouldStoreSolutionUpdate() const override;
195  void prepareSolutionUpdate() override;
196  void storeSolutionUpdate(const GlobalEqVector& dx) override;
197  MaxSolutionUpdateData getMaxSolutionUpdate(const std::vector<unsigned>& ixCells);
198 
199  std::tuple<Scalar,Scalar>
200  convergenceReduction(Parallel::Communication comm,
201  const Scalar pvSumLocal,
202  const Scalar numAquiferPvSumLocal,
203  std::vector<Scalar>& R_sum,
204  std::vector<Scalar>& maxCoeff,
205  std::vector<Scalar>& B_avg);
206 
210  std::pair<Scalar,Scalar>
211  localConvergenceData(std::vector<Scalar>& R_sum,
212  std::vector<Scalar>& maxCoeff,
213  std::vector<Scalar>& B_avg,
214  std::vector<int>& maxCoeffCell);
215 
220  CnvPvSplitData characteriseCnvPvSplit(const std::vector<Scalar>& B_avg, const double dt);
221 
224  void convergencePerCell(const std::vector<Scalar>& B_avg,
225  const double dt,
226  const double tol_cnv,
227  const double tol_cnv_energy);
228 
229  ConvergenceReport
230  getReservoirConvergence(const double reportTime,
231  const double dt,
232  const int maxIter,
233  std::vector<Scalar>& B_avg,
234  std::vector<Scalar>& residual_norms);
235 
241  ConvergenceReport
242  getConvergence(const SimulatorTimerInterface& timer,
243  const int maxIter,
244  std::vector<Scalar>& residual_norms);
245 
247  template<class T>
248  std::vector<std::vector<Scalar> >
249  computeFluidInPlace(const T&, const std::vector<int>& fipnum) const
250  { return this->computeFluidInPlace(fipnum); }
251 
253  std::vector<std::vector<Scalar> >
254  computeFluidInPlace(const std::vector<int>& /*fipnum*/) const;
255 
258 
260  const std::vector<SimulatorReport>& domainAccumulatedReports() const;
261 
263  void writeNonlinearIterationsPerCell(const std::filesystem::path& odir) const;
264 
267  {
268  this->popLastStepReport();
269  this->residual_norms_history_.pop_back();
270  }
271 
272  void writePartitions(const std::filesystem::path& odir) const;
273 
274  template<class FluidState, class Residual>
275  void getMaxCoeff(const unsigned cell_idx,
276  const IntensiveQuantities& intQuants,
277  const FluidState& fs,
278  const Residual& modelResid,
279  const Scalar pvValue,
280  std::vector<Scalar>& B_avg,
281  std::vector<Scalar>& R_sum,
282  std::vector<Scalar>& maxCoeff,
283  std::vector<int>& maxCoeffCell);
284 
286  bool hasNlddSolver() const
287  { return nlddSolver_ != nullptr; }
288 
289 protected:
290  // --------- Data members ---------
291  static constexpr bool has_solvent_ = getPropValue<TypeTag, Properties::EnableSolvent>();
292  static constexpr bool has_extbo_ = getPropValue<TypeTag, Properties::EnableExtbo>();
293  static constexpr bool has_polymer_ = getPropValue<TypeTag, Properties::EnablePolymer>();
294  static constexpr bool has_polymermw_ = getPropValue<TypeTag, Properties::EnablePolymerMW>();
295  static constexpr bool has_energy_ = getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal;
296  static constexpr bool has_foam_ = getPropValue<TypeTag, Properties::EnableFoam>();
297  static constexpr bool has_brine_ = getPropValue<TypeTag, Properties::EnableBrine>();
298  static constexpr bool has_bioeffects_ = getPropValue<TypeTag, Properties::EnableBioeffects>();
299  static constexpr bool has_micp_ = Indices::enableMICP;
300 
302  long int global_nc_;
303 
304  SolutionVector solUpd_;
305 
306  std::unique_ptr<NonlinearSystemNldd<TypeTag>> nlddSolver_;
308 
309 private:
310  Scalar dpMaxRel() const { return this->param_.dp_max_rel_; }
311  Scalar dsMax() const { return this->param_.ds_max_; }
312  Scalar drMaxRel() const { return this->param_.dr_max_rel_; }
313  Scalar maxResidualAllowed() const { return this->param_.max_residual_allowed_; }
314  double linear_solve_setup_time_;
315  std::vector<bool> wasSwitched_;
316 };
317 
318 } // namespace Opm
319 
320 #include <opm/simulators/flow/NonlinearSystemBlackOilReservoir_impl.hpp>
321 
322 #endif // OPM_NONLINEAR_SYSTEM_BLACK_OIL_RESERVOIR_HEADER_INCLUDED
Definition: NonlinearSystemBlackOilReservoir.hpp:118
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
Class for handling the blackoil well model.
Definition: BlackoilModelProperties.hpp:32
Definition: NonlinearSystemBlackOilReservoir.hpp:123
std::unique_ptr< NonlinearSystemNldd< TypeTag > > nlddSolver_
Non-linear DD solver.
Definition: NonlinearSystemBlackOilReservoir.hpp:306
std::pair< Scalar, Scalar > localConvergenceData(std::vector< Scalar > &R_sum, std::vector< Scalar > &maxCoeff, std::vector< Scalar > &B_avg, std::vector< int > &maxCoeffCell)
Get reservoir quantities on this process needed for convergence calculations.
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:580
int linearIterationsLastSolve() const
Number of linear iterations used in last call to solveJacobianSystem().
Definition: NonlinearSystemBlackOilReservoir.hpp:182
void writeNonlinearIterationsPerCell(const std::filesystem::path &odir) const
Write the number of nonlinear iterations per cell to a file in ResInsight compatible format...
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:1058
const SimulatorReport & localAccumulatedReports() const
return the statistics of local solves accumulated for this rank
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:1037
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
CnvPvSplitData characteriseCnvPvSplit(const std::vector< Scalar > &B_avg, const double dt)
Compute pore-volume/cell count split among "converged", "relaxed converged", "unconverged" cells base...
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:631
Implementation of penalty cards for three-phase black oil.
Definition: BlackoilModelConvergenceMonitor.hpp:34
Solver parameters for the NonlinearSystemBlackOilReservoir.
Definition: BlackoilModelParameters.hpp:200
void popLastConvergenceReport()
Remove the last convergence report entry and residual norms history entry.
Definition: NonlinearSystemBlackOilReservoir.hpp:266
bool hasNlddSolver() const
Returns true if an NLDD solver exists.
Definition: NonlinearSystemBlackOilReservoir.hpp:286
bool shouldStoreSolutionUpdate() const override
Get solution update vector as a PrimaryVariable.
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:458
ConvergenceReport getConvergence(const SimulatorTimerInterface &timer, const int maxIter, std::vector< Scalar > &residual_norms)
Compute convergence based on total mass balance (tol_mb) and maximum residual mass balance (tol_cnv)...
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:1001
void solveJacobianSystem(BVector &x)
Solve the Jacobian system Jx = r where J is the Jacobian and r is the residual.
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:398
A model implementation for three-phase black oil.
Definition: NonlinearSystemBlackOilReservoir.hpp:62
SimulatorReportSingle prepareStep(const SimulatorTimerInterface &timer)
Called once before each time step.
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:107
const std::vector< SimulatorReport > & domainAccumulatedReports() const
return the statistics of local solves accumulated for each domain on this rank
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:1048
void convergencePerCell(const std::vector< Scalar > &B_avg, const double dt, const double tol_cnv, const double tol_cnv_energy)
Compute the number of Newtons required by each cell in order to satisfy the solution change convergen...
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:955
long int global_nc_
The number of cells of the global grid.
Definition: NonlinearSystemBlackOilReservoir.hpp:302
Scalar max_residual_allowed_
Absolute max limit for residuals.
Definition: BlackoilModelParameters.hpp:214
NonlinearSystemBlackOilReservoir(Simulator &simulator, const ModelParameters &param, BlackoilWellModel< TypeTag > &well_model, const bool terminal_output)
Construct the model.
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:78
Definition: SimulatorReport.hpp:121
Definition: NonlinearSystem.hpp:43
Manages the initializing and running of time dependent problems.
Definition: simulator.hh:83
SimulatorReportSingle nonlinearIteration(const SimulatorTimerInterface &timer, NonlinearSolverType &nonlinear_solver)
Called once per nonlinear iteration.
Definition: NonlinearSystemBlackOilReservoir_impl.hpp:203
std::vector< std::vector< Scalar > > computeFluidInPlace(const T &, const std::vector< int > &fipnum) const
Wrapper required due to not following generic API.
Definition: NonlinearSystemBlackOilReservoir.hpp:249
Definition: ComponentName.hpp:33