本文整理汇总了C++中WellState::bhp方法的典型用法代码示例。如果您正苦于以下问题:C++ WellState::bhp方法的具体用法?C++ WellState::bhp怎么用?C++ WellState::bhp使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类WellState
的用法示例。
在下文中一共展示了WellState::bhp方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: solveIncomp
// Solve with no rock compressibility (linear eqn).
void IncompTpfa::solveIncomp(const double dt,
SimulatorState& state,
WellState& well_state)
{
// Set up properties.
computePerSolveDynamicData(dt, state, well_state);
// Assemble.
UnstructuredGrid* gg = const_cast<UnstructuredGrid*>(&grid_);
int ok = ifs_tpfa_assemble(gg, &forces_, &trans_[0], &gpress_omegaweighted_[0], h_);
if (!ok) {
OPM_THROW(std::runtime_error, "Failed assembling pressure system.");
}
// Solve.
linsolver_.solve(h_->A, h_->b, h_->x);
// Obtain solution.
assert(int(state.pressure().size()) == grid_.number_of_cells);
assert(int(state.faceflux().size()) == grid_.number_of_faces);
ifs_tpfa_solution soln = { NULL, NULL, NULL, NULL };
soln.cell_press = &state.pressure()[0];
soln.face_flux = &state.faceflux()[0];
if (wells_ != NULL) {
assert(int(well_state.bhp().size()) == wells_->number_of_wells);
assert(int(well_state.perfRates().size()) == wells_->well_connpos[ wells_->number_of_wells ]);
soln.well_flux = &well_state.perfRates()[0];
soln.well_press = &well_state.bhp()[0];
}
ifs_tpfa_press_flux(gg, &forces_, &trans_[0], h_, &soln);
}
示例2: computeResults
/// Compute the output.
void IncompTpfa::computeResults(SimulatorState& state,
WellState& well_state) const
{
// Make sure h_ contains the direct-solution matrix
// and right hand side (not jacobian and residual).
// TODO: optimize by only adjusting b and diagonal of A.
UnstructuredGrid* gg = const_cast<UnstructuredGrid*>(&grid_);
ifs_tpfa_assemble(gg, &forces_, &trans_[0], &gpress_omegaweighted_[0], h_);
// Make sure h_->x contains the direct solution vector.
assert(int(state.pressure().size()) == grid_.number_of_cells);
assert(int(state.faceflux().size()) == grid_.number_of_faces);
std::copy(state.pressure().begin(), state.pressure().end(), h_->x);
std::copy(well_state.bhp().begin(), well_state.bhp().end(), h_->x + grid_.number_of_cells);
// Obtain solution.
ifs_tpfa_solution soln = { NULL, NULL, NULL, NULL };
soln.cell_press = &state.pressure()[0];
soln.face_flux = &state.faceflux()[0];
if (wells_ != NULL) {
assert(int(well_state.bhp().size()) == wells_->number_of_wells);
assert(int(well_state.perfRates().size()) == wells_->well_connpos[ wells_->number_of_wells ]);
soln.well_flux = &well_state.perfRates()[0];
soln.well_press = &well_state.bhp()[0];
}
ifs_tpfa_press_flux(gg, &forces_, &trans_[0], h_, &soln); // TODO: Check what parts of h_ are used here.
}
示例3: computeResults
/// Compute the output.
void CompressibleTpfa::computeResults(BlackoilState& state,
WellState& well_state) const
{
UnstructuredGrid* gg = const_cast<UnstructuredGrid*>(&grid_);
CompletionData completion_data;
completion_data.wdp = ! wellperf_wdp_.empty() ? const_cast<double*>(&wellperf_wdp_[0]) : 0;
completion_data.A = ! wellperf_A_.empty() ? const_cast<double*>(&wellperf_A_[0]) : 0;
completion_data.phasemob = ! wellperf_phasemob_.empty() ? const_cast<double*>(&wellperf_phasemob_[0]) : 0;
cfs_tpfa_res_wells wells_tmp;
wells_tmp.W = const_cast<Wells*>(wells_);
wells_tmp.data = &completion_data;
cfs_tpfa_res_forces forces;
forces.wells = &wells_tmp;
forces.src = NULL;
double* wpress = ! well_state.bhp ().empty() ? & well_state.bhp ()[0] : 0;
double* wflux = ! well_state.perfRates().empty() ? & well_state.perfRates()[0] : 0;
cfs_tpfa_res_flux(gg,
&forces,
props_.numPhases(),
&trans_[0],
&cell_phasemob_[0],
&face_phasemob_[0],
&face_gravcap_[0],
&state.pressure()[0],
wpress,
&state.faceflux()[0],
wflux);
cfs_tpfa_res_fpress(gg,
props_.numPhases(),
&htrans_[0],
&face_phasemob_[0],
&face_gravcap_[0],
h_,
&state.pressure()[0],
&state.faceflux()[0],
&state.facepressure()[0]);
// Compute well perforation pressures (not done by the C code).
if (wells_ != 0) {
const int nw = wells_->number_of_wells;
for (int w = 0; w < nw; ++w) {
for (int j = wells_->well_connpos[w]; j < wells_->well_connpos[w+1]; ++j) {
const double bhp = well_state.bhp()[w];
well_state.perfPress()[j] = bhp + wellperf_wdp_[j];
}
}
}
}
示例4: restoreOPM_XWELKeyword
void restoreOPM_XWELKeyword(const std::string& restart_filename, int reportstep, bool unified, WellState& wellstate)
{
const char * keyword = "OPM_XWEL";
const char* filename = restart_filename.c_str();
ecl_file_type* file_type = ecl_file_open(filename, 0);
if (file_type != NULL) {
bool block_selected = unified ? ecl_file_select_rstblock_report_step(file_type , reportstep) : true;
if (block_selected) {
ecl_kw_type* xwel = ecl_file_iget_named_kw(file_type , keyword, 0);
const double* xwel_data = ecl_kw_get_double_ptr(xwel);
std::copy_n(xwel_data + wellstate.getRestartTemperatureOffset(), wellstate.temperature().size(), wellstate.temperature().begin());
std::copy_n(xwel_data + wellstate.getRestartBhpOffset(), wellstate.bhp().size(), wellstate.bhp().begin());
std::copy_n(xwel_data + wellstate.getRestartPerfPressOffset(), wellstate.perfPress().size(), wellstate.perfPress().begin());
std::copy_n(xwel_data + wellstate.getRestartPerfRatesOffset(), wellstate.perfRates().size(), wellstate.perfRates().begin());
std::copy_n(xwel_data + wellstate.getRestartWellRatesOffset(), wellstate.wellRates().size(), wellstate.wellRates().begin());
} else {
std::string error_str = "Restart file " + restart_filename + " does not contain data for report step " + std::to_string(reportstep) + "!\n";
throw std::runtime_error(error_str);
}
ecl_file_close(file_type);
} else {
std::string error_str = "Restart file " + restart_filename + " not found!\n";
throw std::runtime_error(error_str);
}
}
示例5:
void SimulatorBase<Implementation>::computeWellPotentials(const Wells* wells,
const BlackoilState& x,
const WellState& xw,
std::vector<double>& well_potentials)
{
const int nw = wells->number_of_wells;
const int np = wells->number_of_phases;
well_potentials.clear();
well_potentials.resize(nw*np,0.0);
for (int w = 0; w < nw; ++w) {
for (int perf = wells->well_connpos[w]; perf < wells->well_connpos[w + 1]; ++perf) {
const double well_cell_pressure = x.pressure()[wells->well_cells[perf]];
const double drawdown_used = well_cell_pressure - xw.perfPress()[perf];
const WellControls* ctrl = wells->ctrls[w];
const int nwc = well_controls_get_num(ctrl);
//Loop over all controls until we find a BHP control
//that specifies what we need...
double bhp = 0.0;
for (int ctrl_index=0; ctrl_index < nwc; ++ctrl_index) {
if (well_controls_iget_type(ctrl, ctrl_index) == BHP) {
bhp = well_controls_iget_target(ctrl, ctrl_index);
}
// TODO: do something for thp;
}
// Calculate the pressure difference in the well perforation
const double dp = xw.perfPress()[perf] - xw.bhp()[w];
const double drawdown_maximum = well_cell_pressure - (bhp + dp);
for (int phase = 0; phase < np; ++phase) {
well_potentials[w*np + phase] += (drawdown_maximum / drawdown_used * xw.perfPhaseRates()[perf*np + phase]);
}
}
}
}
示例6: computePerIterationDynamicData
/// Compute per-iteration dynamic properties.
void IncompTpfa::computePerIterationDynamicData(const double /*dt*/,
const SimulatorState& state,
const WellState& well_state)
{
// These are the variables that get computed by this function:
//
// std::vector<double> porevol_
// std::vector<double> rock_comp_
// std::vector<double> pressures_
computePorevolume(grid_, props_.porosity(), *rock_comp_props_, state.pressure(), porevol_);
if (rock_comp_props_ && rock_comp_props_->isActive()) {
for (int cell = 0; cell < grid_.number_of_cells; ++cell) {
rock_comp_[cell] = rock_comp_props_->rockComp(state.pressure()[cell]);
}
}
if (wells_) {
std::copy(state.pressure().begin(), state.pressure().end(), pressures_.begin());
std::copy(well_state.bhp().begin(), well_state.bhp().end(), pressures_.begin() + grid_.number_of_cells);
}
}
示例7: assemble
/// Compute the residual and Jacobian.
void CompressibleTpfa::assemble(const double dt,
const BlackoilState& state,
const WellState& well_state)
{
const double* cell_press = &state.pressure()[0];
const double* well_bhp = well_state.bhp().empty() ? NULL : &well_state.bhp()[0];
const double* z = &state.surfacevol()[0];
UnstructuredGrid* gg = const_cast<UnstructuredGrid*>(&grid_);
CompletionData completion_data;
completion_data.wdp = ! wellperf_wdp_.empty() ? &wellperf_wdp_[0] : 0;
completion_data.A = ! wellperf_A_.empty() ? &wellperf_A_[0] : 0;
completion_data.phasemob = ! wellperf_phasemob_.empty() ? &wellperf_phasemob_[0] : 0;
cfs_tpfa_res_wells wells_tmp;
wells_tmp.W = const_cast<Wells*>(wells_);
wells_tmp.data = &completion_data;
cfs_tpfa_res_forces forces;
forces.wells = &wells_tmp;
forces.src = NULL; // Check if it is legal to leave it as NULL.
compr_quantities_gen cq;
cq.nphases = props_.numPhases();
cq.Ac = &cell_A_[0];
cq.dAc = &cell_dA_[0];
cq.Af = &face_A_[0];
cq.phasemobf = &face_phasemob_[0];
cq.voldiscr = &cell_voldisc_[0];
int was_adjusted = 0;
if (! (rock_comp_props_ && rock_comp_props_->isActive())) {
was_adjusted =
cfs_tpfa_res_assemble(gg, dt, &forces, z, &cq, &trans_[0],
&face_gravcap_[0], cell_press, well_bhp,
&porevol_[0], h_);
} else {
was_adjusted =
cfs_tpfa_res_comprock_assemble(gg, dt, &forces, z, &cq, &trans_[0],
&face_gravcap_[0], cell_press, well_bhp,
&porevol_[0], &initial_porevol_[0],
&rock_comp_[0], h_);
}
singular_ = (was_adjusted == 1);
}
示例8: computeWellDynamicData
/// Compute per-iteration dynamic properties for wells.
void CompressibleTpfa::computeWellDynamicData(const double /*dt*/,
const BlackoilState& /*state*/,
const WellState& well_state)
{
// These are the variables that get computed by this function:
//
// std::vector<double> wellperf_A_;
// std::vector<double> wellperf_phasemob_;
const int np = props_.numPhases();
const int nw = (wells_ != 0) ? wells_->number_of_wells : 0;
const int nperf = (wells_ != 0) ? wells_->well_connpos[nw] : 0;
wellperf_A_.resize(nperf*np*np);
wellperf_phasemob_.resize(nperf*np);
// The A matrix is set equal to the perforation grid cells'
// matrix for producers, computed from bhp and injection
// component fractions from
// The mobilities are set equal to the perforation grid cells'
// mobilities for producers.
std::vector<double> mu(np);
for (int w = 0; w < nw; ++w) {
bool producer = (wells_->type[w] == PRODUCER);
const double* comp_frac = &wells_->comp_frac[np*w];
for (int j = wells_->well_connpos[w]; j < wells_->well_connpos[w+1]; ++j) {
const int c = wells_->well_cells[j];
double* wpA = &wellperf_A_[np*np*j];
double* wpM = &wellperf_phasemob_[np*j];
if (producer) {
const double* cA = &cell_A_[np*np*c];
std::copy(cA, cA + np*np, wpA);
const double* cM = &cell_phasemob_[np*c];
std::copy(cM, cM + np, wpM);
} else {
const double bhp = well_state.bhp()[w];
double perf_p = bhp + wellperf_wdp_[j];
// Hack warning: comp_frac is used as a component
// surface-volume variable in calls to matrix() and
// viscosity(), but as a saturation in the call to
// relperm(). This is probably ok as long as injectors
// only inject pure fluids.
props_.matrix(1, &perf_p, comp_frac, &c, wpA, NULL);
props_.viscosity(1, &perf_p, comp_frac, &c, &mu[0], NULL);
assert(std::fabs(std::accumulate(comp_frac, comp_frac + np, 0.0) - 1.0) < 1e-6);
props_.relperm (1, comp_frac, &c, wpM , NULL);
for (int phase = 0; phase < np; ++phase) {
wpM[phase] /= mu[phase];
}
}
}
}
}
示例9: solve
/// Solve pressure equation, by Newton iterations.
void CompressibleTpfa::solve(const double dt,
BlackoilState& state,
WellState& well_state)
{
const int nc = grid_.number_of_cells;
const int nw = (wells_ != 0) ? wells_->number_of_wells : 0;
// Set up dynamic data.
computePerSolveDynamicData(dt, state, well_state);
computePerIterationDynamicData(dt, state, well_state);
// Assemble J and F.
assemble(dt, state, well_state);
double inc_norm = 0.0;
int iter = 0;
double res_norm = residualNorm();
std::cout << "\nIteration Residual Change in p\n"
<< std::setw(9) << iter
<< std::setw(18) << res_norm
<< std::setw(18) << '*' << std::endl;
while ((iter < maxiter_) && (res_norm > residual_tol_)) {
// Solve for increment in Newton method:
// incr = x_{n+1} - x_{n} = -J^{-1}F
// (J is Jacobian matrix, F is residual)
solveIncrement();
++iter;
// Update pressure vars with increment.
for (int c = 0; c < nc; ++c) {
state.pressure()[c] += pressure_increment_[c];
}
for (int w = 0; w < nw; ++w) {
well_state.bhp()[w] += pressure_increment_[nc + w];
}
// Stop iterating if increment is small.
inc_norm = incrementNorm();
if (inc_norm <= change_tol_) {
std::cout << std::setw(9) << iter
<< std::setw(18) << '*'
<< std::setw(18) << inc_norm << std::endl;
break;
}
// Set up dynamic data.
computePerIterationDynamicData(dt, state, well_state);
// Assemble J and F.
assemble(dt, state, well_state);
// Update residual norm.
res_norm = residualNorm();
std::cout << std::setw(9) << iter
<< std::setw(18) << res_norm
<< std::setw(18) << inc_norm << std::endl;
}
if ((iter == maxiter_) && (res_norm > residual_tol_) && (inc_norm > change_tol_)) {
OPM_THROW(std::runtime_error, "CompressibleTpfa::solve() failed to converge in " << maxiter_ << " iterations.");
}
std::cout << "Solved pressure in " << iter << " iterations." << std::endl;
// Compute fluxes and face pressures.
computeResults(state, well_state);
}
示例10: computePorevolume
SimulatorReport SimulatorCompressiblePolymer::Impl::run(SimulatorTimer& timer,
PolymerBlackoilState& state,
WellState& well_state)
{
std::vector<double> transport_src(grid_.number_of_cells);
std::vector<double> polymer_inflow_c(grid_.number_of_cells);
// Initialisation.
std::vector<double> initial_pressure;
std::vector<double> porevol;
if (rock_comp_props_ && rock_comp_props_->isActive()) {
computePorevolume(grid_, props_.porosity(), *rock_comp_props_, state.pressure(), porevol);
} else {
computePorevolume(grid_, props_.porosity(), porevol);
}
const double tot_porevol_init = std::accumulate(porevol.begin(), porevol.end(), 0.0);
std::vector<double> initial_porevol = porevol;
// Main simulation loop.
Opm::time::StopWatch pressure_timer;
double ptime = 0.0;
Opm::time::StopWatch transport_timer;
double ttime = 0.0;
Opm::time::StopWatch total_timer;
total_timer.start();
double init_surfvol[2] = { 0.0 };
double inplace_surfvol[2] = { 0.0 };
double polymass = computePolymerMass(porevol, state.saturation(), state.getCellData( state.CONCENTRATION ), poly_props_.deadPoreVol());
double polymass_adsorbed = computePolymerAdsorbed(grid_, props_, poly_props_, state, rock_comp_props_);
double init_polymass = polymass + polymass_adsorbed;
double tot_injected[2] = { 0.0 };
double tot_produced[2] = { 0.0 };
double tot_polyinj = 0.0;
double tot_polyprod = 0.0;
Opm::computeSaturatedVol(porevol, state.surfacevol(), init_surfvol);
Opm::Watercut watercut;
watercut.push(0.0, 0.0, 0.0);
Opm::WellReport wellreport;
std::vector<double> fractional_flows;
std::vector<double> well_resflows_phase;
if (wells_) {
well_resflows_phase.resize((wells_->number_of_phases)*(wells_->number_of_wells), 0.0);
wellreport.push(props_, *wells_, state.pressure(), state.surfacevol(),
state.saturation(), 0.0, well_state.bhp(), well_state.perfRates());
}
// Report timestep and (optionally) write state to disk.
timer.report(std::cout);
if (output_ && (timer.currentStepNum() % output_interval_ == 0)) {
if (output_vtk_) {
outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_);
}
outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_);
}
initial_pressure = state.pressure();
// Solve pressure equation.
if (check_well_controls_) {
computeFractionalFlow(props_, poly_props_, allcells_,
state.pressure(), state.temperature(), state.surfacevol(), state.saturation(),
state.getCellData( state.CONCENTRATION ), state.getCellData( state.CMAX ) ,
fractional_flows);
wells_manager_.applyExplicitReinjectionControls(well_resflows_phase, well_resflows_phase);
}
bool well_control_passed = !check_well_controls_;
int well_control_iteration = 0;
do {
// Run solver
pressure_timer.start();
psolver_.solve(timer.currentStepLength(), state, well_state);
// Renormalize pressure if both fluids and rock are
// incompressible, and there are no pressure
// conditions (bcs or wells). It is deemed sufficient
// for now to renormalize using geometric volume
// instead of pore volume.
if (psolver_.singularPressure()) {
// Compute average pressures of previous and last
// step, and total volume.
double av_prev_press = 0.0;
double av_press = 0.0;
double tot_vol = 0.0;
const int num_cells = grid_.number_of_cells;
for (int cell = 0; cell < num_cells; ++cell) {
av_prev_press += initial_pressure[cell]*grid_.cell_volumes[cell];
av_press += state.pressure()[cell]*grid_.cell_volumes[cell];
tot_vol += grid_.cell_volumes[cell];
}
// Renormalization constant
const double ren_const = (av_prev_press - av_press)/tot_vol;
for (int cell = 0; cell < num_cells; ++cell) {
state.pressure()[cell] += ren_const;
}
const int num_wells = (wells_ == NULL) ? 0 : wells_->number_of_wells;
for (int well = 0; well < num_wells; ++well) {
well_state.bhp()[well] += ren_const;
}
}
// Stop timer and report
//.........这里部分代码省略.........
示例11: computePorevolume
SimulatorReport SimulatorCompressibleAd::Impl::run(SimulatorTimer& timer,
BlackoilState& state,
WellState& well_state)
{
std::vector<double> transport_src;
// Initialisation.
std::vector<double> porevol;
if (rock_comp_props_ && rock_comp_props_->isActive()) {
computePorevolume(grid_, props_.porosity(), *rock_comp_props_, state.pressure(), porevol);
} else {
computePorevolume(grid_, props_.porosity(), porevol);
}
const double tot_porevol_init = std::accumulate(porevol.begin(), porevol.end(), 0.0);
std::vector<double> initial_porevol = porevol;
// Main simulation loop.
Opm::time::StopWatch pressure_timer;
double ptime = 0.0;
Opm::time::StopWatch transport_timer;
double ttime = 0.0;
Opm::time::StopWatch step_timer;
Opm::time::StopWatch total_timer;
total_timer.start();
double init_surfvol[2] = { 0.0 };
double inplace_surfvol[2] = { 0.0 };
double tot_injected[2] = { 0.0 };
double tot_produced[2] = { 0.0 };
Opm::computeSaturatedVol(porevol, state.surfacevol(), init_surfvol);
Opm::Watercut watercut;
watercut.push(0.0, 0.0, 0.0);
Opm::WellReport wellreport;
std::vector<double> fractional_flows;
std::vector<double> well_resflows_phase;
if (wells_) {
well_resflows_phase.resize((wells_->number_of_phases)*(wells_->number_of_wells), 0.0);
wellreport.push(props_, *wells_,
state.pressure(), state.surfacevol(), state.saturation(),
0.0, well_state.bhp(), well_state.perfRates());
}
std::fstream tstep_os;
if (output_) {
std::string filename = output_dir_ + "/step_timing.param";
tstep_os.open(filename.c_str(), std::fstream::out | std::fstream::app);
}
for (; !timer.done(); ++timer) {
// Report timestep and (optionally) write state to disk.
step_timer.start();
timer.report(std::cout);
if (output_ && (timer.currentStepNum() % output_interval_ == 0)) {
if (output_vtk_) {
outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_);
}
outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_);
}
SimulatorReport sreport;
// Solve pressure equation.
if (check_well_controls_) {
computeFractionalFlow(props_, allcells_,
state.pressure(), state.surfacevol(), state.saturation(),
fractional_flows);
wells_manager_.applyExplicitReinjectionControls(well_resflows_phase, well_resflows_phase);
}
bool well_control_passed = !check_well_controls_;
int well_control_iteration = 0;
do {
// Run solver.
pressure_timer.start();
std::vector<double> initial_pressure = state.pressure();
psolver_.solve(timer.currentStepLength(), state, well_state);
#if 0
// Renormalize pressure if both fluids and rock are
// incompressible, and there are no pressure
// conditions (bcs or wells). It is deemed sufficient
// for now to renormalize using geometric volume
// instead of pore volume.
if (psolver_.singularPressure()) {
// Compute average pressures of previous and last
// step, and total volume.
double av_prev_press = 0.0;
double av_press = 0.0;
double tot_vol = 0.0;
const int num_cells = grid_.number_of_cells;
for (int cell = 0; cell < num_cells; ++cell) {
av_prev_press += initial_pressure[cell]*grid_.cell_volumes[cell];
av_press += state.pressure()[cell]*grid_.cell_volumes[cell];
tot_vol += grid_.cell_volumes[cell];
}
// Renormalization constant
const double ren_const = (av_prev_press - av_press)/tot_vol;
for (int cell = 0; cell < num_cells; ++cell) {
state.pressure()[cell] += ren_const;
}
const int num_wells = (wells_ == NULL) ? 0 : wells_->number_of_wells;
for (int well = 0; well < num_wells; ++well) {
well_state.bhp()[well] += ren_const;
}
//.........这里部分代码省略.........
示例12: computePorevolume
SimulatorReport SimulatorPolymer::Impl::run(SimulatorTimer& timer,
PolymerState& state,
WellState& well_state)
{
std::vector<double> transport_src;
// Initialisation.
std::vector<double> porevol;
if (rock_comp_props_ && rock_comp_props_->isActive()) {
computePorevolume(grid_, props_.porosity(), *rock_comp_props_, state.pressure(), porevol);
} else {
computePorevolume(grid_, props_.porosity(), porevol);
}
const double tot_porevol_init = std::accumulate(porevol.begin(), porevol.end(), 0.0);
// Main simulation loop.
Opm::time::StopWatch pressure_timer;
double ptime = 0.0;
Opm::time::StopWatch transport_timer;
double ttime = 0.0;
Opm::time::StopWatch total_timer;
total_timer.start();
double init_satvol[2] = { 0.0 };
double init_polymass = 0.0;
double satvol[2] = { 0.0 };
double polymass = 0.0;
double polymass_adsorbed = 0.0;
double injected[2] = { 0.0 };
double produced[2] = { 0.0 };
double polyinj = 0.0;
double polyprod = 0.0;
double tot_injected[2] = { 0.0 };
double tot_produced[2] = { 0.0 };
double tot_polyinj = 0.0;
double tot_polyprod = 0.0;
Opm::computeSaturatedVol(porevol, state.saturation(), init_satvol);
std::cout << "\nInitial saturations are " << init_satvol[0]/tot_porevol_init
<< " " << init_satvol[1]/tot_porevol_init << std::endl;
Opm::Watercut watercut;
watercut.push(0.0, 0.0, 0.0);
Opm::WellReport wellreport;
std::vector<double> fractional_flows;
std::vector<double> well_resflows_phase;
if (wells_) {
well_resflows_phase.resize((wells_->number_of_phases)*(wells_->number_of_wells), 0.0);
wellreport.push(props_, *wells_, state.saturation(), 0.0, well_state.bhp(), well_state.perfRates());
}
for (; !timer.done(); ++timer) {
// Report timestep and (optionally) write state to disk.
timer.report(std::cout);
if (output_ && (timer.currentStepNum() % output_interval_ == 0)) {
outputState(grid_, state, timer.currentStepNum(), output_dir_);
}
// Solve pressure.
do {
pressure_timer.start();
psolver_.solve(timer.currentStepLength(), state, well_state);
pressure_timer.stop();
double pt = pressure_timer.secsSinceStart();
std::cout << "Pressure solver took: " << pt << " seconds." << std::endl;
ptime += pt;
} while (false);
// Update pore volumes if rock is compressible.
if (rock_comp_props_ && rock_comp_props_->isActive()) {
computePorevolume(grid_, props_.porosity(), *rock_comp_props_, state.pressure(), porevol);
}
// Process transport sources (to include bdy terms and well flows).
Opm::computeTransportSource(grid_, src_, state.faceflux(), 1.0,
wells_, well_state.perfRates(), transport_src);
// Find inflow rate.
const double current_time = timer.currentTime();
double stepsize = timer.currentStepLength();
const double inflowc0 = poly_inflow_(current_time + 1e-5*stepsize);
const double inflowc1 = poly_inflow_(current_time + (1.0 - 1e-5)*stepsize);
if (inflowc0 != inflowc1) {
std::cout << "**** Warning: polymer inflow rate changes during timestep. Using rate near start of step.";
}
const double inflow_c = inflowc0;
// Solve transport.
transport_timer.start();
if (num_transport_substeps_ != 1) {
stepsize /= double(num_transport_substeps_);
std::cout << "Making " << num_transport_substeps_ << " transport substeps." << std::endl;
}
for (int tr_substep = 0; tr_substep < num_transport_substeps_; ++tr_substep) {
tsolver_.solve(&state.faceflux()[0], &porevol[0], &transport_src[0], stepsize, inflow_c,
state.saturation(), state.concentration(), state.maxconcentration());
Opm::computeInjectedProduced(props_, poly_props_,
state.saturation(), state.concentration(), state.maxconcentration(),
transport_src, timer.currentStepLength(), inflow_c,
injected, produced, polyinj, polyprod);
if (use_segregation_split_) {
tsolver_.solveGravity(columns_, &porevol[0], stepsize,
state.saturation(), state.concentration(), state.maxconcentration());
//.........这里部分代码省略.........
示例13: computePorevolume
SimulatorReport SimulatorIncompTwophase::Impl::run(SimulatorTimer& timer,
TwophaseState& state,
WellState& well_state)
{
std::vector<double> transport_src;
// Initialisation.
std::vector<double> porevol;
if (rock_comp_props_ && rock_comp_props_->isActive()) {
computePorevolume(grid_, props_.porosity(), *rock_comp_props_, state.pressure(), porevol);
} else {
computePorevolume(grid_, props_.porosity(), porevol);
}
const double tot_porevol_init = std::accumulate(porevol.begin(), porevol.end(), 0.0);
std::vector<double> initial_porevol = porevol;
// Main simulation loop.
Opm::time::StopWatch pressure_timer;
double ptime = 0.0;
Opm::time::StopWatch transport_timer;
double ttime = 0.0;
Opm::time::StopWatch callback_timer;
double time_in_callbacks = 0.0;
Opm::time::StopWatch step_timer;
Opm::time::StopWatch total_timer;
total_timer.start();
double init_satvol[2] = { 0.0 };
double satvol[2] = { 0.0 };
double tot_injected[2] = { 0.0 };
double tot_produced[2] = { 0.0 };
Opm::computeSaturatedVol(porevol, state.saturation(), init_satvol);
*log_ << "\nInitial saturations are " << init_satvol[0]/tot_porevol_init
<< " " << init_satvol[1]/tot_porevol_init << std::endl;
Opm::Watercut watercut;
watercut.push(0.0, 0.0, 0.0);
Opm::WellReport wellreport;
std::vector<double> fractional_flows;
std::vector<double> well_resflows_phase;
if (wells_) {
well_resflows_phase.resize((wells_->number_of_phases)*(wells_->number_of_wells), 0.0);
wellreport.push(props_, *wells_, state.saturation(), 0.0, well_state.bhp(), well_state.perfRates());
}
std::fstream tstep_os;
if (output_) {
std::string filename = output_dir_ + "/step_timing.param";
tstep_os.open(filename.c_str(), std::fstream::out | std::fstream::app);
}
while (!timer.done()) {
// Report timestep and (optionally) write state to disk.
step_timer.start();
timer.report(*log_);
if (output_ && (timer.currentStepNum() % output_interval_ == 0)) {
if (output_vtk_) {
outputStateVtk(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;
// Solve pressure equation.
if (check_well_controls_) {
computeFractionalFlow(props_, allcells_, state.saturation(), fractional_flows);
wells_manager_.applyExplicitReinjectionControls(well_resflows_phase, well_resflows_phase);
}
bool well_control_passed = !check_well_controls_;
int well_control_iteration = 0;
do {
// Run solver.
pressure_timer.start();
std::vector<double> initial_pressure = state.pressure();
psolver_.solve(timer.currentStepLength(), state, well_state);
// Renormalize pressure if rock is incompressible, and
// there are no pressure conditions (bcs or wells).
// It is deemed sufficient for now to renormalize
// using geometric volume instead of pore volume.
if ((rock_comp_props_ == NULL || !rock_comp_props_->isActive())
&& allNeumannBCs(bcs_) && allRateWells(wells_)) {
// Compute average pressures of previous and last
// step, and total volume.
double av_prev_press = 0.0;
double av_press = 0.0;
double tot_vol = 0.0;
const int num_cells = grid_.number_of_cells;
for (int cell = 0; cell < num_cells; ++cell) {
av_prev_press += initial_pressure[cell]*grid_.cell_volumes[cell];
av_press += state.pressure()[cell]*grid_.cell_volumes[cell];
tot_vol += grid_.cell_volumes[cell];
}
// Renormalization constant
const double ren_const = (av_prev_press - av_press)/tot_vol;
for (int cell = 0; cell < num_cells; ++cell) {
state.pressure()[cell] += ren_const;
//.........这里部分代码省略.........
示例14: computePorevolume
SimulatorReport SimulatorFullyImplicitBlackoil::Impl::run(SimulatorTimer& timer,
BlackoilState& state,
WellState& well_state)
{
// Initialisation.
std::vector<double> porevol;
if (rock_comp_props_ && rock_comp_props_->isActive()) {
computePorevolume(grid_, props_.porosity(), *rock_comp_props_, state.pressure(), porevol);
} else {
computePorevolume(grid_, props_.porosity(), porevol);
}
// const double tot_porevol_init = std::accumulate(porevol.begin(), porevol.end(), 0.0);
std::vector<double> initial_porevol = porevol;
// Main simulation loop.
Opm::time::StopWatch solver_timer;
double stime = 0.0;
Opm::time::StopWatch step_timer;
Opm::time::StopWatch total_timer;
total_timer.start();
#if 0
// These must be changed for three-phase.
double init_surfvol[2] = { 0.0 };
double inplace_surfvol[2] = { 0.0 };
double tot_injected[2] = { 0.0 };
double tot_produced[2] = { 0.0 };
Opm::computeSaturatedVol(porevol, state.surfacevol(), init_surfvol);
Opm::Watercut watercut;
watercut.push(0.0, 0.0, 0.0);
Opm::WellReport wellreport;
#endif
std::vector<double> fractional_flows;
std::vector<double> well_resflows_phase;
if (wells_) {
well_resflows_phase.resize((wells_->number_of_phases)*(wells_->number_of_wells), 0.0);
#if 0
wellreport.push(props_, *wells_,
state.pressure(), state.surfacevol(), state.saturation(),
0.0, well_state.bhp(), well_state.perfRates());
#endif
}
std::fstream tstep_os;
if (output_) {
std::string filename = output_dir_ + "/step_timing.param";
tstep_os.open(filename.c_str(), std::fstream::out | std::fstream::app);
}
for (; !timer.done(); ++timer) {
// Report timestep and (optionally) write state to disk.
step_timer.start();
timer.report(std::cout);
if (output_ && (timer.currentStepNum() % output_interval_ == 0)) {
if (output_vtk_) {
outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_);
}
outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_);
outputWellStateMatlab(well_state,timer.currentStepNum(), output_dir_);
}
SimulatorReport sreport;
// Solve pressure equation.
// if (check_well_controls_) {
// computeFractionalFlow(props_, allcells_,
// state.pressure(), state.surfacevol(), state.saturation(),
// fractional_flows);
// wells_manager_.applyExplicitReinjectionControls(well_resflows_phase, well_resflows_phase);
// }
bool well_control_passed = !check_well_controls_;
int well_control_iteration = 0;
do {
// Run solver.
solver_timer.start();
std::vector<double> initial_pressure = state.pressure();
solver_.step(timer.currentStepLength(), state, well_state);
// Stop timer and report.
solver_timer.stop();
const double st = solver_timer.secsSinceStart();
std::cout << "Fully implicit solver took: " << st << " seconds." << std::endl;
stime += st;
sreport.pressure_time = st;
// Optionally, check if well controls are satisfied.
if (check_well_controls_) {
Opm::computePhaseFlowRatesPerWell(*wells_,
well_state.perfRates(),
fractional_flows,
well_resflows_phase);
std::cout << "Checking well conditions." << std::endl;
// For testing we set surface := reservoir
well_control_passed = wells_manager_.conditionsMet(well_state.bhp(), well_resflows_phase, well_resflows_phase);
++well_control_iteration;
if (!well_control_passed && well_control_iteration > max_well_control_iterations_) {
OPM_THROW(std::runtime_error, "Could not satisfy well conditions in " << max_well_control_iterations_ << " tries.");
}
if (!well_control_passed) {
std::cout << "Well controls not passed, solving again." << std::endl;
} else {
std::cout << "Well conditions met." << std::endl;
//.........这里部分代码省略.........