/* Copyright 2013 SINTEF ICT, Applied Mathematics. This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see <http://www.gnu.org/licenses/>. */ #ifndef OPM_FULLYIMPLICITBLACKOILSOLVER_HEADER_INCLUDED #define OPM_FULLYIMPLICITBLACKOILSOLVER_HEADER_INCLUDED #include <opm/autodiff/AutoDiffBlock.hpp> #include <opm/autodiff/AutoDiffHelpers.hpp> #include <opm/autodiff/BlackoilPropsAdInterface.hpp> struct UnstructuredGrid; struct Wells; namespace Opm { class DerivedGeology; class RockCompressibility; class LinearSolverInterface; class BlackoilState; class WellState; /// A fully implicit TPFA-based solver for the black-oil problem. class FullyImplicitBlackoilSolver { public: FullyImplicitBlackoilSolver(const UnstructuredGrid& grid , const BlackoilPropsAdInterface& fluid, const DerivedGeology& geo , const RockCompressibility* rock_comp_props, const Wells& wells, const LinearSolverInterface& linsolver); /// Take a single forward step, modifiying /// state.pressure() /// state.faceflux() /// state.saturation() /// state.gasoilratio() /// wstate.bhp() void step(const double dt , BlackoilState& state , WellState& wstate); private: // Types and enums typedef AutoDiff::ForwardBlock<double> ADB; typedef ADB::V V; typedef ADB::M M; typedef Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> DataBlock; struct ReservoirResidualQuant { ReservoirResidualQuant(); std::vector<ADB> accum; // Accumulations ADB mflux; // Mass flux (surface conditions) ADB b; // Reciprocal FVF ADB head; // Pressure drop across int. interfaces ADB mob; // Phase mobility (per cell) }; struct SolutionState { SolutionState(const int np); ADB pressure; std::vector<ADB> saturation; ADB rs; ADB qs; ADB bhp; }; struct WellOps { WellOps(const Wells& wells); M w2p; // well -> perf (scatter) M p2w; // perf -> well (gather) }; enum { Water = BlackoilPropsAdInterface::Water, Oil = BlackoilPropsAdInterface::Oil , Gas = BlackoilPropsAdInterface::Gas }; // Member data const UnstructuredGrid& grid_; const BlackoilPropsAdInterface& fluid_; const DerivedGeology& geo_; const RockCompressibility* rock_comp_props_; const Wells& wells_; const LinearSolverInterface& linsolver_; // For each canonical phase -> true if active const std::vector<bool> active_; // Size = # active faces. Maps active -> canonical phase indices. const std::vector<int> canph_; const std::vector<int> cells_; // All grid cells HelperOps ops_; const WellOps wops_; const M grav_; std::vector<ReservoirResidualQuant> rq_; // The mass_balance vector has one element for each active phase, // each of which has size equal to the number of cells. // The well_eq has size equal to the number of wells. struct { std::vector<ADB> mass_balance; ADB rs_or_sg_eq; // Only used if both gas and oil present ADB well_flux_eq; ADB well_eq; } residual_; // Private methods. SolutionState constantState(const BlackoilState& x, const WellState& xw); SolutionState variableState(const BlackoilState& x, const WellState& xw); void computeAccum(const SolutionState& state, const int aix ); void assemble(const V& dtpv, const BlackoilState& x , const WellState& xw ); V solveJacobianSystem() const; void updateState(const V& dx, BlackoilState& state, WellState& well_state) const; std::vector<ADB> computeRelPerm(const SolutionState& state) const; std::vector<ADB> computeRelPermWells(const SolutionState& state, const DataBlock& well_s, const std::vector<int>& well_cells) const; void computeMassFlux(const int actph , const V& transi, const std::vector<ADB>& kr , const SolutionState& state ); double residualNorm() const; ADB fluidViscosity(const int phase, const ADB& p , const ADB& rs , const std::vector<int>& cells) const; ADB fluidReciprocFVF(const int phase, const ADB& p , const ADB& rs , const std::vector<int>& cells) const; ADB fluidDensity(const int phase, const ADB& p , const ADB& rs , const std::vector<int>& cells) const; V fluidRsMax(const V& p, const std::vector<int>& cells) const; ADB fluidRsMax(const ADB& p, const std::vector<int>& cells) const; ADB poroMult(const ADB& p) const; ADB transMult(const ADB& p) const; }; } // namespace Opm #endif // OPM_FULLYIMPLICITBLACKOILSOLVER_HEADER_INCLUDED