2013-05-23 11:28:50 -05:00
|
|
|
/*
|
2015-05-24 02:59:40 -05:00
|
|
|
Copyright 2013, 2015 SINTEF ICT, Applied Mathematics.
|
|
|
|
Copyright 2014, 2015 Statoil ASA.
|
2015-05-20 02:26:25 -05:00
|
|
|
Copyright 2014, 2015 Dr. Markus Blatt - HPC-Simulation-Software & Services
|
|
|
|
Copyright 2015 NTNU
|
2013-05-23 11:28:50 -05:00
|
|
|
|
2013-05-24 03:49:59 -05:00
|
|
|
This file is part of the Open Porous Media project (OPM).
|
2013-05-23 11:28:50 -05:00
|
|
|
|
|
|
|
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/>.
|
|
|
|
*/
|
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
#ifndef OPM_BLACKOILMODELBASE_HEADER_INCLUDED
|
|
|
|
#define OPM_BLACKOILMODELBASE_HEADER_INCLUDED
|
2013-05-23 11:28:50 -05:00
|
|
|
|
2015-01-20 05:55:46 -06:00
|
|
|
#include <cassert>
|
|
|
|
|
2013-05-23 11:28:50 -05:00
|
|
|
#include <opm/autodiff/AutoDiffBlock.hpp>
|
|
|
|
#include <opm/autodiff/AutoDiffHelpers.hpp>
|
|
|
|
#include <opm/autodiff/BlackoilPropsAdInterface.hpp>
|
2014-04-08 08:56:08 -05:00
|
|
|
#include <opm/autodiff/LinearisedBlackoilResidual.hpp>
|
2014-04-08 09:11:08 -05:00
|
|
|
#include <opm/autodiff/NewtonIterationBlackoilInterface.hpp>
|
2015-05-25 16:06:03 -05:00
|
|
|
#include <opm/autodiff/BlackoilModelEnums.hpp>
|
2015-08-19 04:46:29 -05:00
|
|
|
#include <opm/autodiff/VFPProperties.hpp>
|
2016-04-06 08:31:58 -05:00
|
|
|
#include <opm/autodiff/StandardWells.hpp>
|
2015-06-10 02:25:45 -05:00
|
|
|
#include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
|
2013-05-23 11:28:50 -05:00
|
|
|
|
2015-01-20 07:21:45 -06:00
|
|
|
#include <array>
|
|
|
|
|
2013-05-24 04:00:55 -05:00
|
|
|
struct Wells;
|
|
|
|
|
2013-05-23 11:28:50 -05:00
|
|
|
namespace Opm {
|
|
|
|
|
2014-05-16 11:02:55 -05:00
|
|
|
namespace parameter { class ParameterGroup; }
|
2013-05-24 04:00:55 -05:00
|
|
|
class DerivedGeology;
|
2013-06-03 07:14:48 -05:00
|
|
|
class RockCompressibility;
|
2014-04-08 09:11:08 -05:00
|
|
|
class NewtonIterationBlackoilInterface;
|
2015-07-03 05:16:50 -05:00
|
|
|
class VFPProperties;
|
2016-02-28 04:27:00 -06:00
|
|
|
class SimulationDataContainer;
|
2015-05-24 17:46:28 -05:00
|
|
|
|
|
|
|
/// Struct for containing iteration variables.
|
|
|
|
struct DefaultBlackoilSolutionState
|
|
|
|
{
|
|
|
|
typedef AutoDiffBlock<double> ADB;
|
|
|
|
explicit DefaultBlackoilSolutionState(const int np)
|
|
|
|
: pressure ( ADB::null())
|
|
|
|
, temperature( ADB::null())
|
|
|
|
, saturation(np, ADB::null())
|
|
|
|
, rs ( ADB::null())
|
|
|
|
, rv ( ADB::null())
|
|
|
|
, qs ( ADB::null())
|
|
|
|
, bhp ( ADB::null())
|
|
|
|
, canonical_phase_pressures(3, ADB::null())
|
|
|
|
{
|
|
|
|
}
|
|
|
|
ADB pressure;
|
|
|
|
ADB temperature;
|
|
|
|
std::vector<ADB> saturation;
|
|
|
|
ADB rs;
|
|
|
|
ADB rv;
|
|
|
|
ADB qs;
|
|
|
|
ADB bhp;
|
|
|
|
// Below are quantities stored in the state for optimization purposes.
|
|
|
|
std::vector<ADB> canonical_phase_pressures; // Always has 3 elements, even if only 2 phases active.
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-05-24 04:00:55 -05:00
|
|
|
|
2013-05-24 04:14:05 -05:00
|
|
|
|
2015-10-02 06:51:40 -05:00
|
|
|
/// Class used for reporting the outcome of a nonlinearIteration() call.
|
|
|
|
struct IterationReport
|
|
|
|
{
|
|
|
|
bool failed;
|
|
|
|
bool converged;
|
|
|
|
int linear_iterations;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-05-24 10:36:29 -05:00
|
|
|
/// Traits to encapsulate the types used by classes using or
|
|
|
|
/// extending this model. Forward declared here, must be
|
|
|
|
/// specialised for each concrete model class.
|
|
|
|
template <class ConcreteModel>
|
|
|
|
struct ModelTraits;
|
|
|
|
|
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
/// A model implementation for three-phase black oil.
|
2013-09-20 07:55:43 -05:00
|
|
|
///
|
|
|
|
/// The simulator is capable of handling three-phase problems
|
2015-05-24 02:59:40 -05:00
|
|
|
/// where gas can be dissolved in oil and vice versa. It
|
2013-09-20 07:55:43 -05:00
|
|
|
/// 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.
|
2015-05-24 10:36:29 -05:00
|
|
|
/// \tparam Grid UnstructuredGrid or CpGrid.
|
|
|
|
/// \tparam Implementation Provides concrete state types.
|
|
|
|
template<class Grid, class Implementation>
|
2015-05-24 02:59:40 -05:00
|
|
|
class BlackoilModelBase
|
2013-05-24 04:00:55 -05:00
|
|
|
{
|
2013-05-23 11:28:50 -05:00
|
|
|
public:
|
2015-05-24 02:59:40 -05:00
|
|
|
// --------- Types and enums ---------
|
|
|
|
typedef AutoDiffBlock<double> ADB;
|
|
|
|
typedef ADB::V V;
|
|
|
|
typedef ADB::M M;
|
2015-05-24 10:36:29 -05:00
|
|
|
|
|
|
|
typedef typename ModelTraits<Implementation>::ReservoirState ReservoirState;
|
|
|
|
typedef typename ModelTraits<Implementation>::WellState WellState;
|
|
|
|
typedef typename ModelTraits<Implementation>::ModelParameters ModelParameters;
|
2015-05-24 17:46:28 -05:00
|
|
|
typedef typename ModelTraits<Implementation>::SolutionState SolutionState;
|
2014-10-01 05:48:41 -05:00
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
// --------- Public methods ---------
|
|
|
|
|
|
|
|
/// Construct the model. It will retain references to the
|
2013-09-20 07:55:43 -05:00
|
|
|
/// arguments of this functions, and they are expected to
|
|
|
|
/// remain in scope for the lifetime of the solver.
|
2014-10-01 05:48:41 -05:00
|
|
|
/// \param[in] param parameters
|
2013-09-20 07:55:43 -05:00
|
|
|
/// \param[in] grid grid data structure
|
|
|
|
/// \param[in] fluid fluid properties
|
|
|
|
/// \param[in] geo rock properties
|
|
|
|
/// \param[in] rock_comp_props if non-null, rock compressibility properties
|
|
|
|
/// \param[in] wells well structure
|
2015-07-03 05:16:50 -05:00
|
|
|
/// \param[in] vfp_properties Vertical flow performance tables
|
2013-09-20 07:55:43 -05:00
|
|
|
/// \param[in] linsolver linear solver
|
2015-06-10 02:25:45 -05:00
|
|
|
/// \param[in] eclState eclipse state
|
2015-05-24 02:59:40 -05:00
|
|
|
/// \param[in] has_disgas turn on dissolved gas
|
|
|
|
/// \param[in] has_vapoil turn on vaporized oil feature
|
|
|
|
/// \param[in] terminal_output request output to cout/cerr
|
|
|
|
BlackoilModelBase(const ModelParameters& param,
|
|
|
|
const Grid& grid ,
|
|
|
|
const BlackoilPropsAdInterface& fluid,
|
|
|
|
const DerivedGeology& geo ,
|
|
|
|
const RockCompressibility* rock_comp_props,
|
|
|
|
const Wells* wells,
|
|
|
|
const NewtonIterationBlackoilInterface& linsolver,
|
2015-06-10 02:25:45 -05:00
|
|
|
Opm::EclipseStateConstPtr eclState,
|
2015-05-24 02:59:40 -05:00
|
|
|
const bool has_disgas,
|
|
|
|
const bool has_vapoil,
|
|
|
|
const bool terminal_output);
|
2013-05-23 11:28:50 -05:00
|
|
|
|
2014-08-27 04:30:42 -05:00
|
|
|
/// \brief Set threshold pressures that prevent or reduce flow.
|
|
|
|
/// This prevents flow across faces if the potential
|
|
|
|
/// difference is less than the threshold. If the potential
|
|
|
|
/// difference is greater, the threshold value is subtracted
|
|
|
|
/// before calculating flow. This is treated symmetrically, so
|
|
|
|
/// flow is prevented or reduced in both directions equally.
|
2014-08-27 07:21:34 -05:00
|
|
|
/// \param[in] threshold_pressures_by_face array of size equal to the number of faces
|
2014-08-27 04:30:42 -05:00
|
|
|
/// of the grid passed in the constructor.
|
2014-08-27 07:21:34 -05:00
|
|
|
void setThresholdPressures(const std::vector<double>& threshold_pressures_by_face);
|
2014-08-27 04:30:42 -05:00
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
/// Called once before each time step.
|
|
|
|
/// \param[in] dt time step size
|
|
|
|
/// \param[in, out] reservoir_state reservoir state variables
|
|
|
|
/// \param[in, out] well_state well state variables
|
|
|
|
void prepareStep(const double dt,
|
|
|
|
ReservoirState& reservoir_state,
|
|
|
|
WellState& well_state);
|
|
|
|
|
2015-10-02 06:51:40 -05:00
|
|
|
/// Called once per nonlinear iteration.
|
|
|
|
/// This model will perform a Newton-Raphson update, changing reservoir_state
|
|
|
|
/// and well_state. It will also use the nonlinear_solver to do relaxation of
|
|
|
|
/// updates if necessary.
|
|
|
|
/// \param[in] iteration should be 0 for the first call of a new timestep
|
|
|
|
/// \param[in] dt time step size
|
|
|
|
/// \param[in] nonlinear_solver nonlinear solver used (for oscillation/relaxation control)
|
|
|
|
/// \param[in, out] reservoir_state reservoir state variables
|
|
|
|
/// \param[in, out] well_state well state variables
|
|
|
|
template <class NonlinearSolverType>
|
|
|
|
IterationReport nonlinearIteration(const int iteration,
|
|
|
|
const double dt,
|
|
|
|
NonlinearSolverType& nonlinear_solver,
|
|
|
|
ReservoirState& reservoir_state,
|
|
|
|
WellState& well_state);
|
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
/// Called once after each time step.
|
|
|
|
/// In this class, this function does nothing.
|
|
|
|
/// \param[in] dt time step size
|
|
|
|
/// \param[in, out] reservoir_state reservoir state variables
|
|
|
|
/// \param[in, out] 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
|
2015-05-25 16:49:09 -05:00
|
|
|
void assemble(const ReservoirState& reservoir_state,
|
|
|
|
WellState& well_state,
|
2015-05-24 02:59:40 -05:00
|
|
|
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;
|
|
|
|
|
2015-10-31 06:32:54 -05:00
|
|
|
/// \brief compute the relative change between to simulation states
|
|
|
|
// \return || u^n+1 - u^n || / || u^n+1 ||
|
2016-02-28 04:27:00 -06:00
|
|
|
double relativeChange( const SimulationDataContainer& previous, const SimulationDataContainer& current ) const;
|
2015-10-31 06:32:54 -05:00
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
/// 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,
|
2015-05-25 16:49:09 -05:00
|
|
|
ReservoirState& reservoir_state,
|
|
|
|
WellState& well_state);
|
2015-05-24 02:59:40 -05:00
|
|
|
|
|
|
|
/// Return true if output to cout is wanted.
|
|
|
|
bool terminalOutputEnabled() 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);
|
|
|
|
|
2015-09-30 07:44:50 -05:00
|
|
|
/// The number of active fluid phases in the model.
|
2015-05-24 02:59:40 -05:00
|
|
|
int numPhases() const;
|
2015-03-04 08:02:00 -06:00
|
|
|
|
2015-09-30 07:44:50 -05:00
|
|
|
/// The number of active materials in the model.
|
|
|
|
/// This should be equal to the number of material balance
|
|
|
|
/// equations.
|
|
|
|
int numMaterials() const;
|
|
|
|
|
|
|
|
/// The name of an active material in the model.
|
|
|
|
/// It is required that material_index < numMaterials().
|
|
|
|
const std::string& materialName(int material_index) const;
|
2015-09-30 05:48:16 -05:00
|
|
|
|
2015-08-27 09:58:44 -05:00
|
|
|
/// Update the scaling factors for mass balance equations
|
|
|
|
void updateEquationsScaling();
|
|
|
|
|
2015-05-24 10:36:29 -05:00
|
|
|
protected:
|
2015-05-24 02:59:40 -05:00
|
|
|
|
|
|
|
// --------- Types and enums ---------
|
|
|
|
|
2013-05-23 11:28:50 -05:00
|
|
|
typedef Eigen::Array<double,
|
|
|
|
Eigen::Dynamic,
|
|
|
|
Eigen::Dynamic,
|
|
|
|
Eigen::RowMajor> DataBlock;
|
|
|
|
|
|
|
|
struct ReservoirResidualQuant {
|
2013-05-24 04:14:05 -05:00
|
|
|
ReservoirResidualQuant();
|
2013-05-23 11:28:50 -05:00
|
|
|
std::vector<ADB> accum; // Accumulations
|
|
|
|
ADB mflux; // Mass flux (surface conditions)
|
|
|
|
ADB b; // Reciprocal FVF
|
2015-05-26 09:33:00 -05:00
|
|
|
ADB dh; // Pressure drop across int. interfaces
|
2013-05-23 11:28:50 -05:00
|
|
|
ADB mob; // Phase mobility (per cell)
|
|
|
|
};
|
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
// --------- Data members ---------
|
|
|
|
|
2014-02-20 06:17:18 -06:00
|
|
|
const Grid& grid_;
|
2013-05-23 11:28:50 -05:00
|
|
|
const BlackoilPropsAdInterface& fluid_;
|
2013-05-24 04:00:55 -05:00
|
|
|
const DerivedGeology& geo_;
|
2013-06-03 07:14:48 -05:00
|
|
|
const RockCompressibility* rock_comp_props_;
|
2016-04-08 03:20:11 -05:00
|
|
|
StandardWells std_wells_;
|
2015-08-19 04:46:29 -05:00
|
|
|
VFPProperties vfp_properties_;
|
2014-04-08 09:11:08 -05:00
|
|
|
const NewtonIterationBlackoilInterface& linsolver_;
|
2013-05-24 03:39:10 -05:00
|
|
|
// For each canonical phase -> true if active
|
|
|
|
const std::vector<bool> active_;
|
2014-06-03 03:59:50 -05:00
|
|
|
// Size = # active phases. Maps active -> canonical phase indices.
|
2013-05-24 03:39:10 -05:00
|
|
|
const std::vector<int> canph_;
|
2013-05-23 11:28:50 -05:00
|
|
|
const std::vector<int> cells_; // All grid cells
|
|
|
|
HelperOps ops_;
|
2014-05-27 06:36:22 -05:00
|
|
|
const bool has_disgas_;
|
|
|
|
const bool has_vapoil_;
|
2014-10-01 05:48:41 -05:00
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
ModelParameters param_;
|
2014-08-27 03:27:49 -05:00
|
|
|
bool use_threshold_pressure_;
|
2015-12-08 03:56:42 -06:00
|
|
|
V threshold_pressures_by_connection_;
|
2013-05-23 11:28:50 -05:00
|
|
|
|
|
|
|
std::vector<ReservoirResidualQuant> rq_;
|
2014-01-10 07:19:37 -06:00
|
|
|
std::vector<PhasePresence> phaseCondition_;
|
2015-05-26 07:38:25 -05:00
|
|
|
V isRs_;
|
|
|
|
V isRv_;
|
|
|
|
V isSg_;
|
2013-05-23 11:28:50 -05:00
|
|
|
|
2014-04-08 08:56:08 -05:00
|
|
|
LinearisedBlackoilResidual residual_;
|
2013-05-23 11:28:50 -05:00
|
|
|
|
2015-02-20 09:03:08 -06:00
|
|
|
/// \brief Whether we print something to std::cout
|
2015-02-20 09:02:06 -06:00
|
|
|
bool terminal_output_;
|
2015-10-26 18:29:22 -05:00
|
|
|
/// \brief The number of cells of the global grid.
|
|
|
|
int global_nc_;
|
2015-02-20 04:35:47 -06:00
|
|
|
|
2014-05-27 08:09:58 -05:00
|
|
|
std::vector<int> primalVariable_;
|
2015-05-24 02:59:40 -05:00
|
|
|
V pvdt_;
|
2015-09-30 07:44:50 -05:00
|
|
|
std::vector<std::string> material_name_;
|
2015-10-02 06:51:40 -05:00
|
|
|
std::vector<std::vector<double>> residual_norms_history_;
|
|
|
|
double current_relaxation_;
|
|
|
|
V dx_old_;
|
2014-05-27 08:09:58 -05:00
|
|
|
|
2015-05-24 10:36:29 -05:00
|
|
|
// --------- Protected methods ---------
|
2015-01-19 07:14:18 -06:00
|
|
|
|
2015-05-25 18:48:45 -05:00
|
|
|
/// Access the most-derived class used for
|
|
|
|
/// static polymorphism (CRTP).
|
|
|
|
Implementation& asImpl()
|
|
|
|
{
|
|
|
|
return static_cast<Implementation&>(*this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Access the most-derived class used for
|
|
|
|
/// static polymorphism (CRTP).
|
|
|
|
const Implementation& asImpl() const
|
|
|
|
{
|
|
|
|
return static_cast<const Implementation&>(*this);
|
|
|
|
}
|
|
|
|
|
2016-04-06 05:52:54 -05:00
|
|
|
/// return the StandardWells object
|
2016-04-08 03:20:11 -05:00
|
|
|
StandardWells& stdWells() { return std_wells_; }
|
|
|
|
const StandardWells& stdWells() const { return std_wells_; }
|
2015-01-19 07:14:18 -06:00
|
|
|
|
2016-04-06 05:52:54 -05:00
|
|
|
/// return the Well struct in the StandardWells
|
|
|
|
const Wells& wells() const { return std_wells_.wells(); }
|
|
|
|
|
|
|
|
/// return true if wells are available in the reservoir
|
|
|
|
bool wellsActive() const { return std_wells_.wellsActive(); }
|
|
|
|
|
|
|
|
/// return true if wells are available on this process
|
|
|
|
bool localWellsActive() const { return std_wells_.localWellsActive(); }
|
|
|
|
|
2015-11-20 04:45:35 -06:00
|
|
|
int numWellVars() const;
|
|
|
|
|
2015-03-06 06:05:37 -06:00
|
|
|
void
|
|
|
|
makeConstantState(SolutionState& state) const;
|
2013-05-23 11:28:50 -05:00
|
|
|
|
|
|
|
SolutionState
|
2015-05-25 16:49:09 -05:00
|
|
|
variableState(const ReservoirState& x,
|
|
|
|
const WellState& xw) const;
|
2013-05-23 11:28:50 -05:00
|
|
|
|
2015-05-26 04:16:21 -05:00
|
|
|
std::vector<V>
|
|
|
|
variableStateInitials(const ReservoirState& x,
|
|
|
|
const WellState& xw) const;
|
2015-06-11 01:03:28 -05:00
|
|
|
void
|
|
|
|
variableReservoirStateInitials(const ReservoirState& x,
|
|
|
|
std::vector<V>& vars0) const;
|
|
|
|
void
|
|
|
|
variableWellStateInitials(const WellState& xw,
|
|
|
|
std::vector<V>& vars0) const;
|
2015-05-26 04:16:21 -05:00
|
|
|
|
|
|
|
std::vector<int>
|
|
|
|
variableStateIndices() const;
|
|
|
|
|
2015-06-11 01:03:28 -05:00
|
|
|
std::vector<int>
|
2015-06-16 03:40:25 -05:00
|
|
|
variableWellStateIndices() const;
|
2015-06-11 01:03:28 -05:00
|
|
|
|
2015-05-26 04:16:21 -05:00
|
|
|
SolutionState
|
|
|
|
variableStateExtractVars(const ReservoirState& x,
|
|
|
|
const std::vector<int>& indices,
|
|
|
|
std::vector<ADB>& vars) const;
|
|
|
|
|
2015-06-11 01:03:28 -05:00
|
|
|
void
|
|
|
|
variableStateExtractWellsVars(const std::vector<int>& indices,
|
|
|
|
std::vector<ADB>& vars,
|
|
|
|
SolutionState& state) const;
|
|
|
|
|
2013-05-23 11:28:50 -05:00
|
|
|
void
|
|
|
|
computeAccum(const SolutionState& state,
|
2013-05-24 04:14:05 -05:00
|
|
|
const int aix );
|
2013-05-23 11:28:50 -05:00
|
|
|
|
2014-03-18 02:48:34 -05:00
|
|
|
void computeWellConnectionPressures(const SolutionState& state,
|
2015-05-25 16:49:09 -05:00
|
|
|
const WellState& xw);
|
2014-03-18 02:48:34 -05:00
|
|
|
|
2015-05-25 17:31:50 -05:00
|
|
|
void
|
|
|
|
assembleMassBalanceEq(const SolutionState& state);
|
|
|
|
|
2016-04-11 10:10:15 -05:00
|
|
|
// TODO: only kept for now due to flow_multisegment
|
|
|
|
// will be removed soon
|
2015-10-13 01:50:13 -05:00
|
|
|
void
|
2016-04-01 08:52:38 -05:00
|
|
|
extractWellPerfProperties(const SolutionState& state,
|
|
|
|
std::vector<ADB>& mob_perfcells,
|
|
|
|
std::vector<ADB>& b_perfcells) const;
|
2015-10-13 01:50:13 -05:00
|
|
|
|
2015-11-19 06:49:42 -06:00
|
|
|
bool
|
2015-06-11 23:49:25 -05:00
|
|
|
solveWellEq(const std::vector<ADB>& mob_perfcells,
|
|
|
|
const std::vector<ADB>& b_perfcells,
|
|
|
|
SolutionState& state,
|
|
|
|
WellState& well_state);
|
|
|
|
|
2015-05-26 07:07:08 -05:00
|
|
|
void
|
Refactor addWellEq().
The method has been split in three parts:
computeWellFlux(const SolutionState& state,
const std::vector<ADB>& mob_perfcells,
const std::vector<ADB>& b_perfcells,
V& aliveWells,
std::vector<ADB>& cq_s);
void
updatePerfPhaseRatesAndPressures(const std::vector<ADB>& cq_s,
const SolutionState& state,
WellState& xw);
void
addWellFluxEq(const std::vector<ADB>& cq_s,
const SolutionState& state);
This reduces the function length, although most of the content of addWellEq()
now is in computeWellFlux(), so that function is still quite long. It also
allows us to use smaller sets of function arguments, which makes methods easier
to understand.
Finally, it makes it easier to create derived models with custom behaviour.
2015-06-22 04:34:10 -05:00
|
|
|
addWellFluxEq(const std::vector<ADB>& cq_s,
|
|
|
|
const SolutionState& state);
|
|
|
|
|
|
|
|
void
|
|
|
|
addWellContributionToMassBalanceEq(const std::vector<ADB>& cq_s,
|
|
|
|
const SolutionState& state,
|
|
|
|
const WellState& xw);
|
|
|
|
|
|
|
|
void
|
|
|
|
addWellControlEq(const SolutionState& state,
|
|
|
|
const WellState& xw,
|
|
|
|
const V& aliveWells);
|
2015-05-26 07:07:08 -05:00
|
|
|
|
2015-06-11 23:49:25 -05:00
|
|
|
bool getWellConvergence(const int iteration);
|
|
|
|
|
2015-08-18 07:53:36 -05:00
|
|
|
bool isVFPActive() const;
|
2015-08-18 03:24:57 -05:00
|
|
|
|
2015-01-07 04:24:11 -06:00
|
|
|
std::vector<ADB>
|
|
|
|
computePressures(const ADB& po,
|
|
|
|
const ADB& sw,
|
|
|
|
const ADB& so,
|
|
|
|
const ADB& sg) const;
|
|
|
|
|
2015-03-06 09:02:22 -06:00
|
|
|
V
|
|
|
|
computeGasPressure(const V& po,
|
|
|
|
const V& sw,
|
|
|
|
const V& so,
|
|
|
|
const V& sg) const;
|
|
|
|
|
2013-05-23 11:28:50 -05:00
|
|
|
std::vector<ADB>
|
2013-05-25 03:47:22 -05:00
|
|
|
computeRelPerm(const SolutionState& state) const;
|
|
|
|
|
2013-05-23 11:28:50 -05:00
|
|
|
void
|
|
|
|
computeMassFlux(const int actph ,
|
|
|
|
const V& transi,
|
2013-11-26 06:51:10 -06:00
|
|
|
const ADB& kr ,
|
2016-02-03 04:26:11 -06:00
|
|
|
const ADB& mu ,
|
|
|
|
const ADB& rho ,
|
2013-11-26 06:51:10 -06:00
|
|
|
const ADB& p ,
|
2013-05-24 04:14:05 -05:00
|
|
|
const SolutionState& state );
|
2013-05-23 11:28:50 -05:00
|
|
|
|
2014-08-27 03:27:49 -05:00
|
|
|
void applyThresholdPressures(ADB& dp);
|
|
|
|
|
2013-05-23 11:28:50 -05:00
|
|
|
ADB
|
|
|
|
fluidViscosity(const int phase,
|
|
|
|
const ADB& p ,
|
2014-11-20 05:31:50 -06:00
|
|
|
const ADB& temp ,
|
2013-05-30 07:43:32 -05:00
|
|
|
const ADB& rs ,
|
2014-01-10 07:19:37 -06:00
|
|
|
const ADB& rv ,
|
2015-06-24 03:22:23 -05:00
|
|
|
const std::vector<PhasePresence>& cond) const;
|
2013-05-23 11:28:50 -05:00
|
|
|
|
|
|
|
ADB
|
|
|
|
fluidReciprocFVF(const int phase,
|
|
|
|
const ADB& p ,
|
2014-11-20 05:31:50 -06:00
|
|
|
const ADB& temp ,
|
2013-05-30 07:43:32 -05:00
|
|
|
const ADB& rs ,
|
2014-01-10 07:19:37 -06:00
|
|
|
const ADB& rv ,
|
2015-06-24 03:22:23 -05:00
|
|
|
const std::vector<PhasePresence>& cond) const;
|
2013-05-23 11:28:50 -05:00
|
|
|
|
|
|
|
ADB
|
2015-06-24 03:22:23 -05:00
|
|
|
fluidDensity(const int phase,
|
|
|
|
const ADB& b,
|
|
|
|
const ADB& rs,
|
|
|
|
const ADB& rv) const;
|
2013-05-27 03:29:04 -05:00
|
|
|
|
2013-05-30 07:43:32 -05:00
|
|
|
V
|
2014-01-10 07:19:37 -06:00
|
|
|
fluidRsSat(const V& p,
|
2014-07-05 08:06:12 -05:00
|
|
|
const V& so,
|
2013-05-30 07:43:32 -05:00
|
|
|
const std::vector<int>& cells) const;
|
|
|
|
|
2013-05-27 03:29:04 -05:00
|
|
|
ADB
|
2014-01-10 07:19:37 -06:00
|
|
|
fluidRsSat(const ADB& p,
|
2014-07-05 08:06:12 -05:00
|
|
|
const ADB& so,
|
2014-01-10 07:19:37 -06:00
|
|
|
const std::vector<int>& cells) const;
|
|
|
|
|
|
|
|
V
|
|
|
|
fluidRvSat(const V& p,
|
2014-07-05 08:06:12 -05:00
|
|
|
const V& so,
|
2014-01-10 07:19:37 -06:00
|
|
|
const std::vector<int>& cells) const;
|
|
|
|
|
|
|
|
ADB
|
|
|
|
fluidRvSat(const ADB& p,
|
2014-07-05 08:06:12 -05:00
|
|
|
const ADB& so,
|
2013-05-27 03:29:04 -05:00
|
|
|
const std::vector<int>& cells) const;
|
2013-06-03 07:14:48 -05:00
|
|
|
|
|
|
|
ADB
|
|
|
|
poroMult(const ADB& p) const;
|
|
|
|
|
|
|
|
ADB
|
|
|
|
transMult(const ADB& p) const;
|
2013-11-28 04:27:25 -06:00
|
|
|
|
2014-01-10 07:19:37 -06:00
|
|
|
const std::vector<PhasePresence>
|
|
|
|
phaseCondition() const {return phaseCondition_;}
|
|
|
|
|
|
|
|
void
|
2015-05-25 16:49:09 -05:00
|
|
|
classifyCondition(const ReservoirState& state);
|
2014-01-10 07:19:37 -06:00
|
|
|
|
2014-06-03 06:30:35 -05:00
|
|
|
|
|
|
|
/// update the primal variable for Sg, Rv or Rs. The Gas phase must
|
|
|
|
/// be active to call this method.
|
2014-05-27 08:09:58 -05:00
|
|
|
void
|
2015-05-25 16:49:09 -05:00
|
|
|
updatePrimalVariableFromState(const ReservoirState& state);
|
2014-05-27 08:09:58 -05:00
|
|
|
|
2014-07-17 07:34:07 -05:00
|
|
|
/// Update the phaseCondition_ member based on the primalVariable_ member.
|
2015-05-26 07:38:25 -05:00
|
|
|
/// Also updates isRs_, isRv_ and isSg_;
|
2014-07-17 07:34:07 -05:00
|
|
|
void
|
|
|
|
updatePhaseCondFromPrimalVariable();
|
|
|
|
|
2015-01-27 05:49:55 -06:00
|
|
|
/// \brief Compute the reduction within the convergence check.
|
2015-01-28 09:53:16 -06:00
|
|
|
/// \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
|
|
|
|
/// for phase i.
|
|
|
|
/// \param[in] tempV A matrix with MaxNumPhases columns and the same number rows
|
|
|
|
/// as the number of cells of the grid. tempV.col(i) contains the
|
|
|
|
/// values
|
|
|
|
/// for phase i.
|
|
|
|
/// \param[in] R A matrix with MaxNumPhases columns and the same number rows
|
|
|
|
/// as the number of cells of the grid. B.col(i) contains the values
|
|
|
|
/// for phase i.
|
|
|
|
/// \param[out] R_sum An array of size MaxNumPhases where entry i contains the sum
|
|
|
|
/// of R for the phase i.
|
2015-01-28 12:08:48 -06:00
|
|
|
/// \param[out] maxCoeff An array of size MaxNumPhases where entry i contains the
|
2015-01-28 12:17:25 -06:00
|
|
|
/// maximum of tempV for the phase i.
|
2015-01-28 12:08:48 -06:00
|
|
|
/// \param[out] B_avg An array of size MaxNumPhases where entry i contains the average
|
|
|
|
/// of B for the phase i.
|
2015-10-12 08:49:10 -05:00
|
|
|
/// \param[out] maxNormWell The maximum of the well flux equations for each phase.
|
2015-01-28 09:53:16 -06:00
|
|
|
/// \param[in] nc The number of cells of the local grid.
|
|
|
|
/// \return The total pore volume over all cells.
|
2015-01-27 05:49:55 -06:00
|
|
|
double
|
2015-09-30 03:03:48 -05:00
|
|
|
convergenceReduction(const Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic>& B,
|
|
|
|
const Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic>& tempV,
|
|
|
|
const Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic>& R,
|
|
|
|
std::vector<double>& R_sum,
|
|
|
|
std::vector<double>& maxCoeff,
|
|
|
|
std::vector<double>& B_avg,
|
2015-05-13 05:00:38 -05:00
|
|
|
std::vector<double>& maxNormWell,
|
2015-10-12 08:49:10 -05:00
|
|
|
int nc) const;
|
2015-01-20 07:21:45 -06:00
|
|
|
|
2014-10-01 05:48:41 -05:00
|
|
|
double dpMaxRel() const { return param_.dp_max_rel_; }
|
|
|
|
double dsMax() const { return param_.ds_max_; }
|
2014-11-05 06:03:00 -06:00
|
|
|
double drMaxRel() const { return param_.dr_max_rel_; }
|
2015-01-21 08:43:18 -06:00
|
|
|
double maxResidualAllowed() const { return param_.max_residual_allowed_; }
|
2014-01-10 07:19:37 -06:00
|
|
|
|
2013-05-23 11:28:50 -05:00
|
|
|
};
|
|
|
|
} // namespace Opm
|
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
#include "BlackoilModelBase_impl.hpp"
|
2013-05-24 03:49:59 -05:00
|
|
|
|
2015-05-24 02:59:40 -05:00
|
|
|
#endif // OPM_BLACKOILMODELBASE_HEADER_INCLUDED
|