Make BlackoilPolymerModel usable with NewtonSolver from opm-autodiff.

This commit is contained in:
Atgeirr Flø Rasmussen
2015-05-19 21:29:14 +02:00
parent 300f236cef
commit 65e7a934a9
4 changed files with 269 additions and 339 deletions

View File

@@ -43,15 +43,15 @@ namespace Opm {
class RockCompressibility;
class NewtonIterationBlackoilInterface;
class PolymerBlackoilState;
class WellStateFullyImplicitBlackoil;
class WellStateFullyImplicitBlackoilPolymer;
/// A fully implicit solver for the black-oil-polymer problem.
/// A model implementation for three-phase black oil with polymer.
///
/// The simulator is capable of handling three-phase problems
/// where gas can be dissolved in oil (but not vice versa). It
/// uses an industry-standard TPFA discretization with per-phase
/// upwind weighting of mobilities.
/// where gas can be dissolved in oil and vice versa, with polymer
/// in the water phase. It uses an industry-standard TPFA
/// discretization with per-phase upwind weighting of mobilities.
///
/// It uses automatic differentiation via the class AutoDiffBlock
/// to simplify assembly of the jacobian matrix.
@@ -59,33 +59,35 @@ namespace Opm {
class BlackoilPolymerModel
{
public:
// the Newton relaxation type
enum RelaxType { DAMPEN, SOR };
// class holding the solver parameters
struct SolverParameter
// --------- Types and enums ---------
typedef AutoDiffBlock<double> ADB;
typedef ADB::V V;
typedef ADB::M M;
typedef PolymerBlackoilState ReservoirState;
typedef WellStateFullyImplicitBlackoilPolymer WellState;
/// Model-specific solver parameters.
struct ModelParameter
{
double dp_max_rel_;
double ds_max_;
double dr_max_rel_;
enum RelaxType relax_type_;
double relax_max_;
double relax_increment_;
double relax_rel_tol_;
double max_residual_allowed_;
double tolerance_mb_;
double tolerance_cnv_;
double tolerance_wells_;
int max_iter_; // max newton iterations
int min_iter_; // min newton iterations
double dp_max_rel_;
double ds_max_;
double dr_max_rel_;
double max_residual_allowed_;
double tolerance_mb_;
double tolerance_cnv_;
double tolerance_wells_;
SolverParameter( const parameter::ParameterGroup& param );
SolverParameter();
ModelParameter( const parameter::ParameterGroup& param );
ModelParameter();
void reset();
};
/// Construct a solver. It will retain references to the
// --------- Public methods ---------
/// Construct the model. It will retain references to the
/// arguments of this functions, and they are expected to
/// remain in scope for the lifetime of the solver.
/// \param[in] param parameters
@@ -95,7 +97,11 @@ namespace Opm {
/// \param[in] rock_comp_props if non-null, rock compressibility properties
/// \param[in] wells well structure
/// \param[in] linsolver linear solver
BlackoilPolymerModel(const SolverParameter& param,
/// \param[in] has_disgas turn on dissolved gas
/// \param[in] has_vapoil turn on vaporized oil feature
/// \param[in] has_polymer turn on polymer feature
/// \param[in] terminal_output request output to cout/cerr
BlackoilPolymerModel(const ModelParameter& param,
const Grid& grid ,
const BlackoilPropsAdInterface& fluid,
const DerivedGeology& geo ,
@@ -118,30 +124,70 @@ namespace Opm {
/// of the grid passed in the constructor.
void setThresholdPressures(const std::vector<double>& threshold_pressures_by_face);
/// Take a single forward step, modifiying
/// state.pressure()
/// state.faceflux()
/// state.saturation()
/// state.gasoilratio()
/// wstate.bhp()
/// \param[in] dt time step size
/// \param[in] state reservoir state
/// \param[in] wstate well state
/// \return number of linear iterations used
int
step(const double dt ,
PolymerBlackoilState& state ,
WellStateFullyImplicitBlackoil& wstate,
const std::vector<double>& polymer_inflow);
/// Called once before each time step.
/// \param[in] dt time step size
/// \param[in] reservoir_state reservoir state variables
/// \param[in] well_state well state variables
void prepareStep(const double dt,
ReservoirState& reservoir_state,
WellState& well_state);
unsigned int newtonIterations () const { return newtonIterations_; }
unsigned int linearIterations () const { return linearIterations_; }
/// Called once after each time step.
/// \param[in] dt time step size
/// \param[in] reservoir_state reservoir state variables
/// \param[in] well_state well state variables
void afterStep(const double dt,
ReservoirState& reservoir_state,
WellState& well_state);
/// Assemble the residual and Jacobian of the nonlinear system.
/// \param[in] reservoir_state reservoir state variables
/// \param[in, out] well_state well state variables
/// \param[in] initial_assembly pass true if this is the first call to assemble() in this timestep
void assemble(const ReservoirState& reservoir_state,
WellState& well_state,
const bool initial_assembly);
/// \brief Compute the residual norms of the mass balance for each phase,
/// the well flux, and the well equation.
/// \return a vector that contains for each phase the norm of the mass balance
/// and afterwards the norm of the residual of the well flux and the well equation.
std::vector<double> computeResidualNorms() const;
/// The size (number of unknowns) of the nonlinear system of equations.
int sizeNonLinear() const;
/// Number of linear iterations used in last call to solveJacobianSystem().
int linearIterationsLastSolve() const;
/// Solve the Jacobian system Jx = r where J is the Jacobian and
/// r is the residual.
V solveJacobianSystem() const;
/// Apply an update to the primary variables, chopped if appropriate.
/// \param[in] dx updates to apply to primary variables
/// \param[in, out] reservoir_state reservoir state variables
/// \param[in, out] well_state well state variables
void updateState(const V& dx,
ReservoirState& reservoir_state,
WellState& well_state);
/// Return true if output to cout is wanted.
bool terminalOutput() const;
/// Compute convergence based on total mass balance (tol_mb) and maximum
/// residual mass balance (tol_cnv).
/// \param[in] dt timestep length
/// \param[in] iteration current iteration number
bool getConvergence(const double dt, const int iteration);
/// The number of active phases in the model.
int numPhases() const;
private:
// Types and enums
typedef AutoDiffBlock<double> ADB;
typedef ADB::V V;
typedef ADB::M M;
// --------- Types and enums ---------
typedef Eigen::Array<double,
Eigen::Dynamic,
Eigen::Dynamic,
@@ -184,7 +230,8 @@ namespace Opm {
enum PrimalVariables { Sg = 0, RS = 1, RV = 2 };
// Member data
// --------- Data members ---------
const Grid& grid_;
const BlackoilPropsAdInterface& fluid_;
const DerivedGeology& geo_;
@@ -205,7 +252,7 @@ namespace Opm {
const bool has_polymer_;
const int poly_pos_;
SolverParameter param_;
ModelParameter param_;
bool use_threshold_pressure_;
V threshold_pressures_by_interior_face_;
@@ -221,8 +268,9 @@ namespace Opm {
unsigned int linearIterations_;
std::vector<int> primalVariable_;
V pvdt_;
// Private methods.
// --------- Private methods ---------
// return true if wells are available
bool wellsActive() const { return wells_ ? wells_->number_of_wells > 0 : false ; }
@@ -231,47 +279,33 @@ namespace Opm {
SolutionState
constantState(const PolymerBlackoilState& x,
const WellStateFullyImplicitBlackoil& xw) const;
const WellStateFullyImplicitBlackoilPolymer& xw) const;
void
makeConstantState(SolutionState& state) const;
SolutionState
variableState(const PolymerBlackoilState& x,
const WellStateFullyImplicitBlackoil& xw) const;
const WellStateFullyImplicitBlackoilPolymer& xw) const;
void
computeAccum(const SolutionState& state,
const int aix );
void computeWellConnectionPressures(const SolutionState& state,
const WellStateFullyImplicitBlackoil& xw);
const WellStateFullyImplicitBlackoilPolymer& xw);
void
addWellControlEq(const SolutionState& state,
const WellStateFullyImplicitBlackoil& xw,
const WellStateFullyImplicitBlackoilPolymer& xw,
const V& aliveWells);
void
addWellEq(const SolutionState& state,
WellStateFullyImplicitBlackoil& xw,
V& aliveWells,
const std::vector<double>& polymer_inflow);
WellStateFullyImplicitBlackoilPolymer& xw,
V& aliveWells);
void updateWellControls(WellStateFullyImplicitBlackoil& xw) const;
void
assemble(const V& dtpv,
const PolymerBlackoilState& x,
const bool initial_assembly,
WellStateFullyImplicitBlackoil& xw,
const std::vector<double>& polymer_inflow);
V solveJacobianSystem() const;
void updateState(const V& dx,
PolymerBlackoilState& state,
WellStateFullyImplicitBlackoil& well_state);
void updateWellControls(WellStateFullyImplicitBlackoilPolymer& xw) const;
std::vector<ADB>
computePressures(const SolutionState& state) const;
@@ -306,15 +340,6 @@ namespace Opm {
void applyThresholdPressures(ADB& dp);
double
residualNorm() const;
/// \brief Compute the residual norms of the mass balance for each phase,
/// the well flux, and the well equation.
/// \return a vector that contains for each phase the norm of the mass balance
/// and afterwards the norm of the residual of the well flux and the well equation.
std::vector<double> computeResidualNorms() const;
ADB
fluidViscosity(const int phase,
const ADB& p ,
@@ -388,10 +413,6 @@ namespace Opm {
void
updatePhaseCondFromPrimalVariable();
/// Compute convergence based on total mass balance (tol_mb) and maximum
/// residual mass balance (tol_cnv).
bool getConvergence(const double dt, const int iteration);
/// \brief Compute the reduction within the convergence check.
/// \param[in] B A matrix with MaxNumPhases columns and the same number rows
/// as the number of cells of the grid. B.col(i) contains the values
@@ -420,21 +441,9 @@ namespace Opm {
std::array<double,MaxNumPhases+1>& B_avg,
int nc) const;
void detectNewtonOscillations(const std::vector<std::vector<double>>& residual_history,
const int it, const double relaxRelTol,
bool& oscillate, bool& stagnate) const;
void stablizeNewton(V& dx, V& dxOld, const double omega, const RelaxType relax_type) const;
double dpMaxRel() const { return param_.dp_max_rel_; }
double dsMax() const { return param_.ds_max_; }
double drMaxRel() const { return param_.dr_max_rel_; }
enum RelaxType relaxType() const { return param_.relax_type_; }
double relaxMax() const { return param_.relax_max_; };
double relaxIncrement() const { return param_.relax_increment_; };
double relaxRelTol() const { return param_.relax_rel_tol_; };
double maxIter() const { return param_.max_iter_; }
double minIter() const { return param_.min_iter_; }
double maxResidualAllowed() const { return param_.max_residual_allowed_; }
};