mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Make SimulatorIncompTwophase flexible w.r.t. transport solver.
It can now use the reordering or the full Newton-Raphson solvers.
This commit is contained in:
@@ -42,10 +42,9 @@
|
|||||||
#include <opm/core/props/IncompPropertiesInterface.hpp>
|
#include <opm/core/props/IncompPropertiesInterface.hpp>
|
||||||
#include <opm/core/props/rock/RockCompressibility.hpp>
|
#include <opm/core/props/rock/RockCompressibility.hpp>
|
||||||
|
|
||||||
#include <opm/core/utility/ColumnExtract.hpp>
|
|
||||||
#include <opm/core/simulator/TwophaseState.hpp>
|
#include <opm/core/simulator/TwophaseState.hpp>
|
||||||
#include <opm/core/simulator/WellState.hpp>
|
#include <opm/core/simulator/WellState.hpp>
|
||||||
//#include <opm/core/transport/reorder/TransportSolverTwophaseReorder.hpp>
|
#include <opm/core/transport/reorder/TransportSolverTwophaseReorder.hpp>
|
||||||
#include <opm/core/transport/TransportSolverTwophaseImplicit.hpp>
|
#include <opm/core/transport/TransportSolverTwophaseImplicit.hpp>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/scoped_ptr.hpp>
|
#include <boost/scoped_ptr.hpp>
|
||||||
@@ -87,6 +86,7 @@ namespace Opm
|
|||||||
int max_well_control_iterations_;
|
int max_well_control_iterations_;
|
||||||
// Parameters for transport solver.
|
// Parameters for transport solver.
|
||||||
int num_transport_substeps_;
|
int num_transport_substeps_;
|
||||||
|
bool use_reorder_;
|
||||||
bool use_segregation_split_;
|
bool use_segregation_split_;
|
||||||
// Observed objects.
|
// Observed objects.
|
||||||
const UnstructuredGrid& grid_;
|
const UnstructuredGrid& grid_;
|
||||||
@@ -98,11 +98,7 @@ namespace Opm
|
|||||||
const FlowBoundaryConditions* bcs_;
|
const FlowBoundaryConditions* bcs_;
|
||||||
// Solvers
|
// Solvers
|
||||||
IncompTpfa psolver_;
|
IncompTpfa psolver_;
|
||||||
// this should maybe be packed in a separate file
|
|
||||||
boost::scoped_ptr<TransportSolverTwophaseInterface> tsolver_;
|
boost::scoped_ptr<TransportSolverTwophaseInterface> tsolver_;
|
||||||
//ImpliciteTwoPhaseTransportSolver tsolver_;
|
|
||||||
// Needed by column-based gravity segregation solver.
|
|
||||||
std::vector< std::vector<int> > columns_;
|
|
||||||
// Misc. data
|
// Misc. data
|
||||||
std::vector<int> allcells_;
|
std::vector<int> allcells_;
|
||||||
};
|
};
|
||||||
@@ -320,7 +316,9 @@ namespace Opm
|
|||||||
const FlowBoundaryConditions* bcs,
|
const FlowBoundaryConditions* bcs,
|
||||||
LinearSolverInterface& linsolver,
|
LinearSolverInterface& linsolver,
|
||||||
const double* gravity)
|
const double* gravity)
|
||||||
: grid_(grid),
|
: use_reorder_(param.getDefault("use_reorder", true)),
|
||||||
|
use_segregation_split_(param.getDefault("use_segregation_split", false)),
|
||||||
|
grid_(grid),
|
||||||
props_(props),
|
props_(props),
|
||||||
rock_comp_props_(rock_comp_props),
|
rock_comp_props_(rock_comp_props),
|
||||||
wells_manager_(wells_manager),
|
wells_manager_(wells_manager),
|
||||||
@@ -333,23 +331,24 @@ namespace Opm
|
|||||||
param.getDefault("nl_pressure_maxiter", 10),
|
param.getDefault("nl_pressure_maxiter", 10),
|
||||||
gravity, wells_manager.c_wells(), src, bcs)
|
gravity, wells_manager.c_wells(), src, bcs)
|
||||||
{
|
{
|
||||||
const bool use_reorder = param.getDefault("use_reorder", true);
|
// Initialize transport solver.
|
||||||
if (use_reorder) {
|
if (use_reorder_) {
|
||||||
/*
|
tsolver_.reset(new Opm::TransportSolverTwophaseReorder(grid,
|
||||||
tsolver_.reset(new Opm::TransportModelTwoPhase(grid, props, rock_comp_props, linsolver,
|
props,
|
||||||
param.getDefault("nl_pressure_residual_tolerance", 0.0),
|
use_segregation_split_ ? gravity : NULL,
|
||||||
param.getDefault("nl_pressure_change_tolerance", 1.0),
|
param.getDefault("nl_tolerance", 1e-9),
|
||||||
param.getDefault("nl_pressure_maxiter", 10),
|
param.getDefault("nl_maxiter", 30)));
|
||||||
gravity, wells_manager.c_wells(), src, bcs));
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
if (rock_comp_props->isActive()) {
|
if (rock_comp_props->isActive()) {
|
||||||
THROW("The implicit pressure solver cannot handle rock compressibility.");
|
THROW("The implicit pressure solver cannot handle rock compressibility.");
|
||||||
}
|
}
|
||||||
|
if (use_segregation_split_) {
|
||||||
|
THROW("The implicit pressure solver is not set up to use segregation splitting.");
|
||||||
|
}
|
||||||
std::vector<double> porevol;
|
std::vector<double> porevol;
|
||||||
computePorevolume(grid, props.porosity(), porevol);
|
computePorevolume(grid, props.porosity(), porevol);
|
||||||
tsolver_.reset(new Opm::TransportSolverTwophaseImplicit(
|
tsolver_.reset(new Opm::TransportSolverTwophaseImplicit(grid,
|
||||||
grid,
|
|
||||||
props,
|
props,
|
||||||
porevol,
|
porevol,
|
||||||
gravity,
|
gravity,
|
||||||
@@ -379,7 +378,7 @@ namespace Opm
|
|||||||
|
|
||||||
// Transport related init.
|
// Transport related init.
|
||||||
num_transport_substeps_ = param.getDefault("num_transport_substeps", 1);
|
num_transport_substeps_ = param.getDefault("num_transport_substeps", 1);
|
||||||
use_segregation_split_ = param.getDefault("use_segregation_split", false);
|
|
||||||
// Misc init.
|
// Misc init.
|
||||||
const int num_cells = grid.number_of_cells;
|
const int num_cells = grid.number_of_cells;
|
||||||
allcells_.resize(num_cells);
|
allcells_.resize(num_cells);
|
||||||
@@ -445,6 +444,12 @@ namespace Opm
|
|||||||
outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_);
|
outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_);
|
||||||
}
|
}
|
||||||
outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_);
|
outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_);
|
||||||
|
if (use_reorder_) {
|
||||||
|
// This use of dynamic_cast is not ideal, but should be safe.
|
||||||
|
outputVectorMatlab(std::string("reorder_it"),
|
||||||
|
dynamic_cast<const TransportSolverTwophaseReorder&>(*tsolver_).getReorderIterations(),
|
||||||
|
timer.currentStepNum(), output_dir_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatorReport sreport;
|
SimulatorReport sreport;
|
||||||
@@ -538,10 +543,7 @@ namespace Opm
|
|||||||
double injected[2] = { 0.0 };
|
double injected[2] = { 0.0 };
|
||||||
double produced[2] = { 0.0 };
|
double produced[2] = { 0.0 };
|
||||||
for (int tr_substep = 0; tr_substep < num_transport_substeps_; ++tr_substep) {
|
for (int tr_substep = 0; tr_substep < num_transport_substeps_; ++tr_substep) {
|
||||||
tsolver_->solve(&transport_src[0],
|
tsolver_->solve(&transport_src[0], &porevol[0], stepsize, state);
|
||||||
&porevol[0],
|
|
||||||
stepsize,
|
|
||||||
state);
|
|
||||||
|
|
||||||
double substep_injected[2] = { 0.0 };
|
double substep_injected[2] = { 0.0 };
|
||||||
double substep_produced[2] = { 0.0 };
|
double substep_produced[2] = { 0.0 };
|
||||||
@@ -551,18 +553,20 @@ namespace Opm
|
|||||||
injected[1] += substep_injected[1];
|
injected[1] += substep_injected[1];
|
||||||
produced[0] += substep_produced[0];
|
produced[0] += substep_produced[0];
|
||||||
produced[1] += substep_produced[1];
|
produced[1] += substep_produced[1];
|
||||||
|
if (use_reorder_ && use_segregation_split_) {
|
||||||
|
// Again, unfortunate but safe use of dynamic_cast.
|
||||||
|
// Possible solution: refactor gravity solver to its own class.
|
||||||
|
dynamic_cast<TransportSolverTwophaseReorder&>(*tsolver_)
|
||||||
|
.solveGravity(&initial_porevol[0], stepsize, state);
|
||||||
|
}
|
||||||
watercut.push(timer.currentTime() + timer.currentStepLength(),
|
watercut.push(timer.currentTime() + timer.currentStepLength(),
|
||||||
produced[0]/(produced[0] + produced[1]),
|
produced[0]/(produced[0] + produced[1]),
|
||||||
tot_produced[0]/tot_porevol_init);
|
tot_produced[0]/tot_porevol_init);
|
||||||
|
|
||||||
if (wells_) {
|
if (wells_) {
|
||||||
wellreport.push(props_, *wells_, state.saturation(),
|
wellreport.push(props_, *wells_, state.saturation(),
|
||||||
timer.currentTime() + timer.currentStepLength(),
|
timer.currentTime() + timer.currentStepLength(),
|
||||||
well_state.bhp(), well_state.perfRates());
|
well_state.bhp(), well_state.perfRates());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
transport_timer.stop();
|
transport_timer.stop();
|
||||||
double tt = transport_timer.secsSinceStart();
|
double tt = transport_timer.secsSinceStart();
|
||||||
@@ -590,6 +594,12 @@ namespace Opm
|
|||||||
outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_);
|
outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_);
|
||||||
}
|
}
|
||||||
outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_);
|
outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_);
|
||||||
|
if (use_reorder_) {
|
||||||
|
// This use of dynamic_cast is not ideal, but should be safe.
|
||||||
|
outputVectorMatlab(std::string("reorder_it"),
|
||||||
|
dynamic_cast<const TransportSolverTwophaseReorder&>(*tsolver_).getReorderIterations(),
|
||||||
|
timer.currentStepNum(), output_dir_);
|
||||||
|
}
|
||||||
outputWaterCut(watercut, output_dir_);
|
outputWaterCut(watercut, output_dir_);
|
||||||
if (wells_) {
|
if (wells_) {
|
||||||
outputWellReport(wellreport, output_dir_);
|
outputWellReport(wellreport, output_dir_);
|
||||||
|
|||||||
Reference in New Issue
Block a user