Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
3d90a918d5
@ -286,6 +286,7 @@ list (APPEND PUBLIC_HEADER_FILES
|
||||
opm/core/grid/cpgpreprocess/preprocess.h
|
||||
opm/core/grid/cpgpreprocess/uniquepoints.h
|
||||
opm/core/io/eclipse/CornerpointChopper.hpp
|
||||
opm/core/io/eclipse/EclipseIOUtil.hpp
|
||||
opm/core/io/eclipse/EclipseGridInspector.hpp
|
||||
opm/core/io/eclipse/EclipseUnits.hpp
|
||||
opm/core/io/eclipse/EclipseWriter.hpp
|
||||
|
@ -58,6 +58,9 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
const static double alq_invalid = -std::numeric_limits<double>::max();
|
||||
const static int vfp_invalid = -std::numeric_limits<int>::max();
|
||||
|
||||
void warnIfUnusedParams(const Opm::parameter::ParameterGroup& param)
|
||||
{
|
||||
if (param.anyUnused()) {
|
||||
@ -90,7 +93,9 @@ namespace
|
||||
WellControls* ctrl = wells.ctrls[w];
|
||||
const double target = (wells.type[w] == INJECTOR) ? 200*Opm::unit::barsa : 100*Opm::unit::barsa;
|
||||
const double distr[3] = { 1.0, 0.0, 0.0 }; // Large enough irrespective of #phases.
|
||||
well_controls_add_new(BHP, target, distr, ctrl);
|
||||
well_controls_add_new(BHP, target,
|
||||
alq_invalid, vfp_invalid,
|
||||
distr, ctrl);
|
||||
well_controls_set_current(ctrl, well_controls_get_num(ctrl) - 1);
|
||||
}
|
||||
}
|
||||
|
34
opm/core/io/eclipse/EclipseIOUtil.hpp
Normal file
34
opm/core/io/eclipse/EclipseIOUtil.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef ECLIPSE_IO_UTIL_HPP
|
||||
#define ECLIPSE_IO_UTIL_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
namespace EclipseIOUtil
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
void addToStripedData(const std::vector<T>& data, std::vector<T>& result, size_t offset, size_t stride) {
|
||||
int dataindex = 0;
|
||||
for (size_t index = offset; index < result.size(); index += stride) {
|
||||
result[index] = data[dataindex];
|
||||
++dataindex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void extractFromStripedData(const std::vector<T>& data, std::vector<T>& result, size_t offset, size_t stride) {
|
||||
for (size_t index = offset; index < data.size(); index += stride) {
|
||||
result.push_back(data[index]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} //namespace EclipseIOUtil
|
||||
} //namespace Opm
|
||||
|
||||
#endif //ECLIPSE_IO_UTIL_HPP
|
@ -19,6 +19,11 @@
|
||||
|
||||
#include "EclipseReader.hpp"
|
||||
#include <opm/core/simulator/WellState.hpp>
|
||||
#include <opm/core/simulator/SimulatorState.hpp>
|
||||
#include <opm/core/utility/Units.hpp>
|
||||
#include <opm/core/grid/GridHelpers.hpp>
|
||||
#include <opm/core/io/eclipse/EclipseIOUtil.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <ert/ecl/ecl_file.h>
|
||||
@ -48,4 +53,105 @@ namespace Opm
|
||||
ecl_file_close(file_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
void restoreTemperatureData(const ecl_file_type* file,
|
||||
const EclipseState& eclipse_state,
|
||||
const UnstructuredGrid& grid,
|
||||
SimulatorState& simulator_state) {
|
||||
const char* temperature_keyword = "TEMP";
|
||||
|
||||
if (ecl_file_has_kw(file , temperature_keyword)) {
|
||||
ecl_kw_type* temperature_kw = ecl_file_iget_named_kw(file, temperature_keyword, 0);
|
||||
|
||||
if (ecl_kw_get_size(temperature_kw) != Opm::UgGridHelpers::numCells(grid)) {
|
||||
throw std::runtime_error("Read of restart file: Could not restore temperature data, length of data from file not equal number of cells");
|
||||
}
|
||||
|
||||
float* temperature_data = ecl_kw_get_float_ptr(temperature_kw);
|
||||
|
||||
// factor and offset from the temperature values given in the deck to Kelvin
|
||||
double scaling = eclipse_state.getDeckUnitSystem()->parse("Temperature")->getSIScaling();
|
||||
double offset = eclipse_state.getDeckUnitSystem()->parse("Temperature")->getSIOffset();
|
||||
|
||||
for (size_t index = 0; index < simulator_state.temperature().size(); ++index) {
|
||||
simulator_state.temperature()[index] = unit::convert::from((double)temperature_data[index] - offset, scaling);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void restorePressureData(const ecl_file_type* file,
|
||||
const EclipseState& eclipse_state,
|
||||
const UnstructuredGrid& grid,
|
||||
SimulatorState& simulator_state) {
|
||||
const char* pressure_keyword = "PRESSURE";
|
||||
|
||||
if (ecl_file_has_kw(file , pressure_keyword)) {
|
||||
|
||||
ecl_kw_type* pressure_kw = ecl_file_iget_named_kw(file, pressure_keyword, 0);
|
||||
|
||||
if (ecl_kw_get_size(pressure_kw) != Opm::UgGridHelpers::numCells(grid)) {
|
||||
throw std::runtime_error("Read of restart file: Could not restore pressure data, length of data from file not equal number of cells");
|
||||
}
|
||||
|
||||
float* pressure_data = ecl_kw_get_float_ptr(pressure_kw);
|
||||
const double deck_pressure_unit = (eclipse_state.getDeckUnitSystem()->getType() == UnitSystem::UNIT_TYPE_METRIC) ? Opm::unit::barsa : Opm::unit::psia;
|
||||
for (size_t index = 0; index < simulator_state.pressure().size(); ++index) {
|
||||
simulator_state.pressure()[index] = unit::convert::from((double)pressure_data[index], deck_pressure_unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void restoreSOLUTIONData(const std::string& restart_filename,
|
||||
int reportstep,
|
||||
const EclipseState& eclipseState,
|
||||
const UnstructuredGrid& grid,
|
||||
const PhaseUsage& phaseUsage,
|
||||
SimulatorState& simulator_state)
|
||||
{
|
||||
const char* filename = restart_filename.c_str();
|
||||
ecl_file_type* file_type = ecl_file_open(filename, 0);
|
||||
|
||||
if (file_type != NULL) {
|
||||
bool block_selected = ecl_file_select_rstblock_report_step(file_type , reportstep);
|
||||
|
||||
if (block_selected) {
|
||||
|
||||
restorePressureData(file_type, eclipseState, grid, simulator_state);
|
||||
restoreTemperatureData(file_type, eclipseState, grid, simulator_state);
|
||||
|
||||
int numcells = Opm::UgGridHelpers::numCells(grid);
|
||||
|
||||
float* sgas_data = NULL;
|
||||
float* swat_data = NULL;
|
||||
|
||||
if (phaseUsage.phase_used[BlackoilPhases::Aqua]) {
|
||||
ecl_kw_type* swat_kw = ecl_file_iget_named_kw(file_type , "SWAT", 0);
|
||||
swat_data = ecl_kw_get_float_ptr(swat_kw);
|
||||
std::vector<double> swat_datavec(&swat_data[0], &swat_data[numcells]);
|
||||
EclipseIOUtil::addToStripedData(swat_datavec, simulator_state.saturation(), phaseUsage.phase_pos[BlackoilPhases::Aqua], phaseUsage.num_phases);
|
||||
}
|
||||
|
||||
if (phaseUsage.phase_used[BlackoilPhases::Vapour]) {
|
||||
ecl_kw_type* sgas_kw = ecl_file_iget_named_kw(file_type , "SGAS", 0);
|
||||
sgas_data = ecl_kw_get_float_ptr(sgas_kw);
|
||||
std::vector<double> sgas_datavec(&sgas_data[0], &sgas_data[numcells]);
|
||||
EclipseIOUtil::addToStripedData(sgas_datavec, simulator_state.saturation(), phaseUsage.phase_pos[BlackoilPhases::Vapour], phaseUsage.num_phases);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Warning: Could not load solution data for report step " << reportstep << ", data for reportstep not found on file " << filename << std::endl;
|
||||
}
|
||||
|
||||
ecl_file_close(file_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace Opm
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
#include <string>
|
||||
#include <opm/core/simulator/WellState.hpp>
|
||||
#include <opm/core/simulator/SimulatorState.hpp>
|
||||
#include <opm/core/props/BlackoilPhases.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
@ -18,6 +21,14 @@ namespace Opm
|
||||
/// An instance of a WellState object, with correct size for each of the 5 contained std::vector<double> objects.
|
||||
///
|
||||
void restoreOPM_XWELKeyword(const std::string& restart_filename, int report_step, WellState& wellState);
|
||||
void restoreSOLUTIONData(const std::string& restart_filename,
|
||||
int report_step,
|
||||
const EclipseState &eclipseState,
|
||||
const UnstructuredGrid& grid,
|
||||
const PhaseUsage& phaseUsage,
|
||||
SimulatorState& simulator_state);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // ECLIPSEREADER_HPP
|
||||
|
@ -876,6 +876,7 @@ assemble_completion_to_well(int i, int w, int c, int nc, int np,
|
||||
else {
|
||||
switch (well_controls_get_current_type(ctrl)) {
|
||||
case BHP :
|
||||
case THP : // THP is implemented as a BHP target
|
||||
welleq_coeff_bhp(np, pw - well_controls_get_current_target( ctrl ),
|
||||
h, &res, &w2c, &w2w);
|
||||
break;
|
||||
|
@ -374,6 +374,7 @@ assemble_well_contrib(int nc ,
|
||||
|
||||
switch (well_controls_get_current_type(ctrls)) {
|
||||
case BHP:
|
||||
case THP : // THP is implemented as a BHP target
|
||||
*all_rate = 0;
|
||||
assemble_bhp_well (nc, w, W, mt, wdp, h);
|
||||
break;
|
||||
|
@ -44,8 +44,8 @@ namespace Opm {
|
||||
, solver_restart_max_( param.getDefault("solver.restart", int(10) ) )
|
||||
, solver_verbose_( param.getDefault("solver.verbose", bool(true) ) )
|
||||
, timestep_verbose_( param.getDefault("timestep.verbose", bool(true) ) )
|
||||
, full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) )
|
||||
, last_timestep_( -1.0 )
|
||||
, full_timestep_initially_( param.getDefault("full_timestep_initially", bool(false) ) )
|
||||
{
|
||||
// valid are "pid" and "pid+iteration"
|
||||
std::string control = param.getDefault("timestep.control", std::string("pid+iteration") );
|
||||
|
@ -45,6 +45,7 @@ namespace Opm
|
||||
const int nw = wells->number_of_wells;
|
||||
const int np = wells->number_of_phases;
|
||||
bhp_.resize(nw);
|
||||
thp_.resize(nw);
|
||||
temperature_.resize(nw, 273.15 + 20); // standard temperature for now
|
||||
wellrates_.resize(nw * np, 0.0);
|
||||
for (int w = 0; w < nw; ++w) {
|
||||
@ -52,11 +53,11 @@ namespace Opm
|
||||
const WellControls* ctrl = wells->ctrls[w];
|
||||
if (well_controls_well_is_stopped(ctrl)) {
|
||||
// Stopped well:
|
||||
// 1. Assign zero well rates.
|
||||
// 1. Rates: assign zero well rates.
|
||||
for (int p = 0; p < np; ++p) {
|
||||
wellrates_[np*w + p] = 0.0;
|
||||
}
|
||||
// 2. Assign bhp equal to bhp control, if
|
||||
// 2. Bhp: assign bhp equal to bhp control, if
|
||||
// applicable, otherwise assign equal to
|
||||
// first perforation cell pressure.
|
||||
if (well_controls_get_current_type(ctrl) == BHP) {
|
||||
@ -65,9 +66,16 @@ namespace Opm
|
||||
const int first_cell = wells->well_cells[wells->well_connpos[w]];
|
||||
bhp_[w] = state.pressure()[first_cell];
|
||||
}
|
||||
// 3. Thp: assign thp equal to thp control, if applicable,
|
||||
// otherwise assign equal to bhp value.
|
||||
if (well_controls_get_current_type(ctrl) == THP) {
|
||||
thp_[w] = well_controls_get_current_target( ctrl );
|
||||
} else {
|
||||
thp_[w] = bhp_[w];
|
||||
}
|
||||
} else {
|
||||
// Open well:
|
||||
// 1. Initialize well rates to match controls
|
||||
// 1. Rates: initialize well rates to match controls
|
||||
// if type is SURFACE_RATE. Otherwise, we
|
||||
// cannot set the correct value here, so we
|
||||
// assign a small rate with the correct
|
||||
@ -86,20 +94,30 @@ namespace Opm
|
||||
wellrates_[np*w + p] = small_rate * sign;
|
||||
}
|
||||
}
|
||||
// 2. Initialize bhp to be target pressure if
|
||||
|
||||
// 2. Bhp: initialize bhp to be target pressure if
|
||||
// bhp-controlled well, otherwise set to a
|
||||
// little above or below (depending on if
|
||||
// the well is an injector or producer)
|
||||
// pressure in first perforation cell.
|
||||
if (well_controls_get_current_type(ctrl) == BHP) {
|
||||
bhp_[w] = well_controls_get_current_target( ctrl );
|
||||
} else {
|
||||
const int first_cell = wells->well_cells[wells->well_connpos[w]];
|
||||
const double safety_factor = (wells->type[w] == INJECTOR) ? 1.01 : 0.99;
|
||||
bhp_[w] = safety_factor*state.pressure()[first_cell];
|
||||
if (well_controls_get_current_type(ctrl) == BHP) {
|
||||
bhp_[w] = well_controls_get_current_target( ctrl );
|
||||
} else {
|
||||
const int first_cell = wells->well_cells[wells->well_connpos[w]];
|
||||
const double safety_factor = (wells->type[w] == INJECTOR) ? 1.01 : 0.99;
|
||||
bhp_[w] = safety_factor*state.pressure()[first_cell];
|
||||
}
|
||||
|
||||
// 3. Thp: assign thp equal to thp control, if applicable,
|
||||
// otherwise assign equal to bhp value.
|
||||
if (well_controls_get_current_type(ctrl) == THP) {
|
||||
thp_[w] = well_controls_get_current_target( ctrl );
|
||||
} else {
|
||||
thp_[w] = bhp_[w];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The perforation rates and perforation pressures are
|
||||
// not expected to be consistent with bhp_ and wellrates_
|
||||
// after init().
|
||||
@ -112,6 +130,10 @@ namespace Opm
|
||||
std::vector<double>& bhp() { return bhp_; }
|
||||
const std::vector<double>& bhp() const { return bhp_; }
|
||||
|
||||
/// One thp pressure per well.
|
||||
std::vector<double>& thp() { return thp_; }
|
||||
const std::vector<double>& thp() const { return thp_; }
|
||||
|
||||
/// One temperature per well.
|
||||
std::vector<double>& temperature() { return temperature_; }
|
||||
const std::vector<double>& temperature() const { return temperature_; }
|
||||
@ -150,6 +172,7 @@ namespace Opm
|
||||
|
||||
private:
|
||||
std::vector<double> bhp_;
|
||||
std::vector<double> thp_;
|
||||
std::vector<double> temperature_;
|
||||
std::vector<double> wellrates_;
|
||||
std::vector<double> perfrates_;
|
||||
|
@ -33,6 +33,7 @@ extern "C" {
|
||||
|
||||
enum WellControlType {
|
||||
BHP, /**< Well constrained by BHP target */
|
||||
THP, /**< Well constrained by THP target */
|
||||
RESERVOIR_RATE, /**< Well constrained by reservoir volume flow rate */
|
||||
SURFACE_RATE /**< Well constrained by surface volume flow rate */
|
||||
};
|
||||
@ -82,7 +83,7 @@ void
|
||||
well_controls_stop_well( struct WellControls * ctrl);
|
||||
|
||||
int
|
||||
well_controls_add_new(enum WellControlType type , double target , const double * distr , struct WellControls * ctrl);
|
||||
well_controls_add_new(enum WellControlType type , double target , double alq , int vfp , const double * distr , struct WellControls * ctrl);
|
||||
|
||||
enum WellControlType
|
||||
well_controls_iget_type(const struct WellControls * ctrl, int control_index);
|
||||
@ -99,6 +100,18 @@ well_controls_iset_target(struct WellControls * ctrl, int control_index , double
|
||||
double
|
||||
well_controls_iget_target(const struct WellControls * ctrl, int control_index);
|
||||
|
||||
void
|
||||
well_controls_iset_alq(struct WellControls * ctrl, int control_index , double alq);
|
||||
|
||||
double
|
||||
well_controls_iget_alq(const struct WellControls * ctrl, int control_index );
|
||||
|
||||
void
|
||||
well_controls_iset_vfp(struct WellControls * ctrl, int control_index , int vfp);
|
||||
|
||||
int
|
||||
well_controls_iget_vfp(const struct WellControls * ctrl, int control_index );
|
||||
|
||||
double
|
||||
well_controls_get_current_target(const struct WellControls * ctrl);
|
||||
|
||||
|
@ -212,6 +212,8 @@ add_well(enum WellType type ,
|
||||
*
|
||||
* \param[in] type Control type.
|
||||
* \param[in] target Target value for the control.
|
||||
* \param[in] alq Artificial lift quantity for control (for THP type only)
|
||||
* \param[in] vfp VFP table number for control (for THP type only)
|
||||
* \param[in] distr Array of size W->number_of_phases or NULL.
|
||||
* \param[in] well_index Index of well to receive additional control.
|
||||
* \param[in,out] W Existing set of well controls.
|
||||
@ -222,6 +224,8 @@ add_well(enum WellType type ,
|
||||
int
|
||||
append_well_controls(enum WellControlType type ,
|
||||
double target,
|
||||
double alq,
|
||||
int vfp,
|
||||
const double *distr,
|
||||
int well_index,
|
||||
struct Wells *W);
|
||||
|
@ -26,6 +26,12 @@
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
static double invalid_alq = -1e100;
|
||||
static double invalid_vfp = -2147483647;
|
||||
} //Namespace
|
||||
|
||||
namespace Opm
|
||||
{
|
||||
|
||||
@ -678,6 +684,11 @@ namespace Opm
|
||||
break;
|
||||
}
|
||||
|
||||
case THP: {
|
||||
//TODO: Implement support
|
||||
OPM_THROW(std::invalid_argument, "THP not implemented in WellNode::conditionsMet.");
|
||||
}
|
||||
|
||||
case RESERVOIR_RATE: {
|
||||
double my_rate = 0.0;
|
||||
const double * ctrls_distr = well_controls_iget_distr( ctrls , ctrl_index );
|
||||
@ -751,11 +762,14 @@ namespace Opm
|
||||
}
|
||||
else {
|
||||
const double target = 0.0;
|
||||
const double alq = 0.0;
|
||||
const double distr[3] = {1.0, 1.0, 1.0};
|
||||
|
||||
if (group_control_index_ < 0) {
|
||||
// The well only had its own controls, no group controls.
|
||||
append_well_controls(SURFACE_RATE, target, distr, self_index_, wells_);
|
||||
append_well_controls(SURFACE_RATE, target,
|
||||
invalid_alq, invalid_vfp,
|
||||
distr, self_index_, wells_);
|
||||
group_control_index_ = well_controls_get_num(wells_->ctrls[self_index_]) - 1;
|
||||
} else {
|
||||
// We will now modify the last control, that
|
||||
@ -763,6 +777,7 @@ namespace Opm
|
||||
|
||||
well_controls_iset_type( wells_->ctrls[self_index_] , group_control_index_ , SURFACE_RATE);
|
||||
well_controls_iset_target( wells_->ctrls[self_index_] , group_control_index_ , target);
|
||||
well_controls_iset_alq( wells_->ctrls[self_index_] , group_control_index_ , alq);
|
||||
well_controls_iset_distr(wells_->ctrls[self_index_] , group_control_index_ , distr);
|
||||
}
|
||||
well_controls_open_well( wells_->ctrls[self_index_]);
|
||||
@ -810,13 +825,14 @@ namespace Opm
|
||||
|
||||
if (group_control_index_ < 0) {
|
||||
// The well only had its own controls, no group controls.
|
||||
append_well_controls(wct, target, distr, self_index_, wells_);
|
||||
append_well_controls(wct, target, invalid_alq, invalid_vfp, distr, self_index_, wells_);
|
||||
group_control_index_ = well_controls_get_num(wells_->ctrls[self_index_]) - 1;
|
||||
} else {
|
||||
// We will now modify the last control, that
|
||||
// "belongs to" the group control.
|
||||
well_controls_iset_type(wells_->ctrls[self_index_] , group_control_index_ , wct);
|
||||
well_controls_iset_target(wells_->ctrls[self_index_] , group_control_index_ ,target);
|
||||
well_controls_iset_alq(wells_->ctrls[self_index_] , group_control_index_ , -1e100);
|
||||
well_controls_iset_distr(wells_->ctrls[self_index_] , group_control_index_ , distr);
|
||||
}
|
||||
set_current_control(self_index_, group_control_index_, wells_);
|
||||
@ -921,13 +937,14 @@ namespace Opm
|
||||
|
||||
if (group_control_index_ < 0) {
|
||||
// The well only had its own controls, no group controls.
|
||||
append_well_controls(wct, ntarget, distr, self_index_, wells_);
|
||||
append_well_controls(wct, ntarget, invalid_alq, invalid_vfp, distr, self_index_, wells_);
|
||||
group_control_index_ = well_controls_get_num(wells_->ctrls[self_index_]) - 1;
|
||||
} else {
|
||||
// We will now modify the last control, that
|
||||
// "belongs to" the group control.
|
||||
well_controls_iset_type(wells_->ctrls[self_index_] , group_control_index_ , wct);
|
||||
well_controls_iset_target(wells_->ctrls[self_index_] , group_control_index_ , ntarget);
|
||||
well_controls_iset_alq(wells_->ctrls[self_index_] , group_control_index_ , -1e100);
|
||||
well_controls_iset_distr(wells_->ctrls[self_index_] , group_control_index_ , distr);
|
||||
}
|
||||
set_current_control(self_index_, group_control_index_, wells_);
|
||||
|
@ -39,6 +39,11 @@
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
static double invalid_alq = -1e100;
|
||||
static double invalid_vfp = -2147483647;
|
||||
} //Namespace
|
||||
|
||||
// Helper structs and functions for the implementation.
|
||||
namespace WellsManagerDetail
|
||||
@ -452,6 +457,8 @@ namespace Opm
|
||||
|
||||
ok = append_well_controls(SURFACE_RATE,
|
||||
injectionProperties.surfaceInjectionRate,
|
||||
invalid_alq,
|
||||
invalid_vfp,
|
||||
distr,
|
||||
well_index,
|
||||
w_);
|
||||
@ -472,23 +479,35 @@ namespace Opm
|
||||
|
||||
ok = append_well_controls(RESERVOIR_RATE,
|
||||
injectionProperties.reservoirInjectionRate,
|
||||
invalid_alq,
|
||||
invalid_vfp,
|
||||
distr,
|
||||
well_index,
|
||||
w_);
|
||||
}
|
||||
|
||||
if (ok && injectionProperties.hasInjectionControl(WellInjector::BHP)) {
|
||||
control_pos[WellsManagerDetail::InjectionControl::BHP] = well_controls_get_num(w_->ctrls[well_index]);
|
||||
control_pos[WellsManagerDetail::InjectionControl::BHP] = well_controls_get_num(w_->ctrls[well_index]);
|
||||
ok = append_well_controls(BHP,
|
||||
injectionProperties.BHPLimit,
|
||||
injectionProperties.BHPLimit,
|
||||
invalid_alq,
|
||||
invalid_vfp,
|
||||
NULL,
|
||||
well_index,
|
||||
w_);
|
||||
}
|
||||
|
||||
if (ok && injectionProperties.hasInjectionControl(WellInjector::THP)) {
|
||||
OPM_THROW(std::runtime_error, "We cannot handle THP limit for well " << well_names[well_index]);
|
||||
control_pos[WellsManagerDetail::InjectionControl::THP] = well_controls_get_num(w_->ctrls[well_index]);
|
||||
const double thp_limit = injectionProperties.THPLimit;
|
||||
const int vfp_number = injectionProperties.VFPTableNumber;
|
||||
ok = append_well_controls(THP,
|
||||
thp_limit,
|
||||
invalid_alq,
|
||||
vfp_number,
|
||||
NULL,
|
||||
well_index,
|
||||
w_);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
@ -548,9 +567,11 @@ namespace Opm
|
||||
double distr[3] = { 0.0, 0.0, 0.0 };
|
||||
distr[phaseUsage.phase_pos[BlackoilPhases::Liquid]] = 1.0;
|
||||
ok = append_well_controls(SURFACE_RATE,
|
||||
-productionProperties.OilRate,
|
||||
-productionProperties.OilRate,
|
||||
invalid_alq,
|
||||
invalid_vfp,
|
||||
distr,
|
||||
well_index,
|
||||
well_index,
|
||||
w_);
|
||||
}
|
||||
|
||||
@ -563,6 +584,8 @@ namespace Opm
|
||||
distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0;
|
||||
ok = append_well_controls(SURFACE_RATE,
|
||||
-productionProperties.WaterRate,
|
||||
invalid_alq,
|
||||
invalid_vfp,
|
||||
distr,
|
||||
well_index,
|
||||
w_);
|
||||
@ -577,6 +600,8 @@ namespace Opm
|
||||
distr[phaseUsage.phase_pos[BlackoilPhases::Vapour]] = 1.0;
|
||||
ok = append_well_controls(SURFACE_RATE,
|
||||
-productionProperties.GasRate,
|
||||
invalid_alq,
|
||||
invalid_vfp,
|
||||
distr,
|
||||
well_index,
|
||||
w_);
|
||||
@ -594,7 +619,9 @@ namespace Opm
|
||||
distr[phaseUsage.phase_pos[BlackoilPhases::Aqua]] = 1.0;
|
||||
distr[phaseUsage.phase_pos[BlackoilPhases::Liquid]] = 1.0;
|
||||
ok = append_well_controls(SURFACE_RATE,
|
||||
-productionProperties.LiquidRate ,
|
||||
-productionProperties.LiquidRate,
|
||||
invalid_alq,
|
||||
invalid_vfp,
|
||||
distr,
|
||||
well_index,
|
||||
w_);
|
||||
@ -604,12 +631,28 @@ namespace Opm
|
||||
control_pos[WellsManagerDetail::ProductionControl::RESV] = well_controls_get_num(w_->ctrls[well_index]);
|
||||
double distr[3] = { 1.0, 1.0, 1.0 };
|
||||
ok = append_well_controls(RESERVOIR_RATE,
|
||||
-productionProperties.ResVRate ,
|
||||
-productionProperties.ResVRate,
|
||||
invalid_alq,
|
||||
invalid_vfp,
|
||||
distr,
|
||||
well_index,
|
||||
w_);
|
||||
}
|
||||
|
||||
if (ok && productionProperties.hasProductionControl(WellProducer::THP)) {
|
||||
const double thp_limit = productionProperties.THPLimit;
|
||||
const double alq_value = productionProperties.ALQValue;
|
||||
const int vfp_number = productionProperties.VFPTableNumber;
|
||||
control_pos[WellsManagerDetail::ProductionControl::THP] = well_controls_get_num(w_->ctrls[well_index]);
|
||||
ok = append_well_controls(THP,
|
||||
thp_limit,
|
||||
alq_value,
|
||||
vfp_number,
|
||||
NULL,
|
||||
well_index,
|
||||
w_);
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
// Always append a BHP control.
|
||||
// If no explicit BHP control given, use a 1 atm control.
|
||||
@ -618,15 +661,13 @@ namespace Opm
|
||||
control_pos[WellsManagerDetail::ProductionControl::BHP] = well_controls_get_num(w_->ctrls[well_index]);
|
||||
ok = append_well_controls(BHP,
|
||||
bhp_limit,
|
||||
invalid_alq,
|
||||
invalid_vfp,
|
||||
NULL,
|
||||
well_index,
|
||||
w_);
|
||||
}
|
||||
|
||||
if (ok && productionProperties.hasProductionControl(WellProducer::THP)) {
|
||||
OPM_THROW(std::runtime_error, "We cannot handle THP limit for well " << well_names[well_index]);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
OPM_THROW(std::runtime_error, "Failure occured appending controls for well " << well_names[well_index]);
|
||||
}
|
||||
|
@ -48,7 +48,8 @@
|
||||
* one control can be active at a time, indicated by current. The
|
||||
* meaning of each control's target value depends on the control type:
|
||||
*
|
||||
* - BHP -> target pressure in Pascal.
|
||||
* - BHP -> target bottom hole pressure in Pascal.
|
||||
* - THP -> target tubing head pressure in Pascal.
|
||||
* - RESERVOIR_RATE -> target reservoir volume rate in cubic(meter)/second
|
||||
* - SURFACE_RATE -> target surface volume rate in cubic(meter)/second
|
||||
*
|
||||
@ -87,6 +88,16 @@ struct WellControls
|
||||
*/
|
||||
double *target;
|
||||
|
||||
/**
|
||||
* Array of artificial lift quantities.
|
||||
*/
|
||||
double *alq;
|
||||
|
||||
/**
|
||||
* Array of VFP table numbers
|
||||
*/
|
||||
int *vfp;
|
||||
|
||||
/**
|
||||
* Array of rate control distributions,
|
||||
* <CODE>number_of_phases</CODE> numbers for each control
|
||||
@ -137,6 +148,8 @@ well_controls_create(void)
|
||||
ctrl->number_of_phases = 0;
|
||||
ctrl->type = NULL;
|
||||
ctrl->target = NULL;
|
||||
ctrl->alq = NULL;
|
||||
ctrl->vfp = NULL;
|
||||
ctrl->distr = NULL;
|
||||
ctrl->current = -1;
|
||||
ctrl->cpty = 0;
|
||||
@ -153,18 +166,22 @@ well_controls_reserve(int nctrl, struct WellControls *ctrl)
|
||||
/* ---------------------------------------------------------------------- */
|
||||
{
|
||||
int c, p, ok;
|
||||
void *type, *target, *distr;
|
||||
void *type, *target, *alq, *vfp, *distr;
|
||||
|
||||
type = realloc(ctrl->type , nctrl * 1 * sizeof *ctrl->type );
|
||||
target = realloc(ctrl->target, nctrl * 1 * sizeof *ctrl->target);
|
||||
alq = realloc(ctrl->alq , nctrl * 1 * sizeof *ctrl->alq );
|
||||
vfp = realloc(ctrl->vfp , nctrl * 1 * sizeof *ctrl->vfp );
|
||||
distr = realloc(ctrl->distr , nctrl * ctrl->number_of_phases * sizeof *ctrl->distr );
|
||||
|
||||
ok = 0;
|
||||
if (type != NULL) { ctrl->type = type ; ok++; }
|
||||
if (target != NULL) { ctrl->target = target; ok++; }
|
||||
if (alq != NULL) { ctrl->alq = alq; ok++; }
|
||||
if (vfp != NULL) { ctrl->vfp = vfp; ok++; }
|
||||
if (distr != NULL) { ctrl->distr = distr ; ok++; }
|
||||
|
||||
if (ok == 3) {
|
||||
if (ok == 5) {
|
||||
for (c = ctrl->cpty; c < nctrl; c++) {
|
||||
ctrl->type [c] = BHP;
|
||||
ctrl->target[c] = -1.0;
|
||||
@ -177,7 +194,7 @@ well_controls_reserve(int nctrl, struct WellControls *ctrl)
|
||||
ctrl->cpty = nctrl;
|
||||
}
|
||||
|
||||
return ok == 3;
|
||||
return ok == 5;
|
||||
}
|
||||
|
||||
|
||||
@ -188,6 +205,8 @@ well_controls_clone(const struct WellControls *ctrl)
|
||||
{
|
||||
int ok, i, n;
|
||||
double target;
|
||||
double alq;
|
||||
int vfp;
|
||||
const double *distr;
|
||||
struct WellControls *new;
|
||||
enum WellControlType type;
|
||||
@ -210,8 +229,10 @@ well_controls_clone(const struct WellControls *ctrl)
|
||||
type = well_controls_iget_type (ctrl, i);
|
||||
distr = well_controls_iget_distr (ctrl, i);
|
||||
target = well_controls_iget_target(ctrl, i);
|
||||
alq = well_controls_iget_alq (ctrl, i);
|
||||
vfp = well_controls_iget_vfp (ctrl, i);
|
||||
|
||||
ok = well_controls_add_new(type, target, distr, new);
|
||||
ok = well_controls_add_new(type, target, alq, vfp, distr, new);
|
||||
}
|
||||
|
||||
if (i < n) {
|
||||
@ -305,6 +326,26 @@ well_controls_iset_target(struct WellControls * ctrl, int control_index , double
|
||||
ctrl->target[control_index] = target;
|
||||
}
|
||||
|
||||
double
|
||||
well_controls_iget_alq(const struct WellControls * ctrl, int control_index) {
|
||||
return ctrl->alq[control_index];
|
||||
}
|
||||
|
||||
void
|
||||
well_controls_iset_alq(struct WellControls * ctrl, int control_index , double alq) {
|
||||
ctrl->alq[control_index] = alq;
|
||||
}
|
||||
|
||||
int
|
||||
well_controls_iget_vfp(const struct WellControls * ctrl, int control_index) {
|
||||
return ctrl->vfp[control_index];
|
||||
}
|
||||
|
||||
void
|
||||
well_controls_iset_vfp(struct WellControls * ctrl, int control_index , int vfp) {
|
||||
ctrl->vfp[control_index] = vfp;
|
||||
}
|
||||
|
||||
|
||||
const double *
|
||||
well_controls_iget_distr(const struct WellControls * ctrl, int control_index) {
|
||||
@ -345,7 +386,7 @@ well_controls_clear(struct WellControls * ctrl) {
|
||||
|
||||
|
||||
int
|
||||
well_controls_add_new(enum WellControlType type , double target , const double * distr , struct WellControls * ctrl) {
|
||||
well_controls_add_new(enum WellControlType type , double target , double alq , int vfp , const double * distr , struct WellControls * ctrl) {
|
||||
if (ctrl->num == ctrl->cpty) {
|
||||
int new_cpty = 2*ctrl->cpty;
|
||||
if (new_cpty == ctrl->num)
|
||||
@ -357,6 +398,8 @@ well_controls_add_new(enum WellControlType type , double target , const double *
|
||||
|
||||
well_controls_iset_type( ctrl , ctrl->num , type);
|
||||
well_controls_iset_target( ctrl , ctrl->num , target);
|
||||
well_controls_iset_alq(ctrl , ctrl->num , alq);
|
||||
well_controls_iset_vfp(ctrl , ctrl->num , vfp);
|
||||
|
||||
if (distr != NULL)
|
||||
well_controls_iset_distr( ctrl , ctrl->num , distr);
|
||||
|
@ -422,6 +422,8 @@ add_well(enum WellType type ,
|
||||
int
|
||||
append_well_controls(enum WellControlType type,
|
||||
double target,
|
||||
double alq,
|
||||
int vfp,
|
||||
const double *distr,
|
||||
int well_index,
|
||||
struct Wells *W)
|
||||
@ -436,7 +438,7 @@ append_well_controls(enum WellControlType type,
|
||||
assert (ctrl != NULL);
|
||||
|
||||
well_controls_assert_number_of_phases( ctrl , W->number_of_phases);
|
||||
return well_controls_add_new(type , target , distr , ctrl);
|
||||
return well_controls_add_new(type , target , alq , vfp , distr , ctrl);
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,8 +27,10 @@
|
||||
|
||||
#include <opm/core/io/eclipse/EclipseWriter.hpp>
|
||||
#include <opm/core/io/eclipse/EclipseReader.hpp>
|
||||
#include <opm/core/io/eclipse/EclipseIOUtil.hpp>
|
||||
#include <opm/core/grid/GridManager.hpp>
|
||||
#include <opm/core/props/phaseUsageFromDeck.hpp>
|
||||
#include <opm/core/props/BlackoilPhases.hpp>
|
||||
#include <opm/core/simulator/BlackoilState.hpp>
|
||||
#include <opm/core/simulator/WellState.hpp>
|
||||
#include <opm/core/simulator/SimulatorTimer.hpp>
|
||||
@ -251,6 +253,7 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData)
|
||||
simTimer->init(eclipseState->getSchedule()->getTimeMap());
|
||||
eclipseWriter->writeInit(*simTimer);
|
||||
std::shared_ptr<Opm::WellState> wellState(new Opm::WellState());
|
||||
Opm::PhaseUsage phaseUsage = Opm::phaseUsageFromDeck(deck);
|
||||
|
||||
Opm::GridManager gridManager(deck);
|
||||
Opm::WellsManager wellsManager(eclipseState, 1, *gridManager.c_grid(), NULL);
|
||||
@ -258,6 +261,26 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData)
|
||||
std::shared_ptr<Opm::BlackoilState> blackoilState = createBlackOilState(eclipseState->getEclipseGrid());
|
||||
wellState->init(wells, *blackoilState);
|
||||
|
||||
//Set test data for pressure
|
||||
std::vector<double>& pressure = blackoilState->pressure();
|
||||
for (std::vector<double>::iterator iter = pressure.begin(); iter != pressure.end(); ++iter) {
|
||||
*iter = 6.0;
|
||||
}
|
||||
|
||||
//Set test data for temperature
|
||||
std::vector<double>& temperature = blackoilState->temperature();
|
||||
for (std::vector<double>::iterator iter = temperature.begin(); iter != temperature.end(); ++iter) {
|
||||
*iter = 7.0;
|
||||
}
|
||||
|
||||
//Set test data for saturation water
|
||||
std::vector<double> swatdata(1000, 8);
|
||||
Opm::EclipseIOUtil::addToStripedData(swatdata, blackoilState->saturation(), phaseUsage.phase_pos[Opm::BlackoilPhases::Aqua], phaseUsage.num_phases);
|
||||
|
||||
//Set test data for saturation gas
|
||||
std::vector<double> sgasdata(1000, 9);
|
||||
Opm::EclipseIOUtil::addToStripedData(sgasdata, blackoilState->saturation(), phaseUsage.phase_pos[Opm::BlackoilPhases::Vapour], phaseUsage.num_phases);
|
||||
|
||||
setValuesInWellState(wellState);
|
||||
simTimer->setCurrentStepNum(1);
|
||||
eclipseWriter->writeTimeStep(*simTimer, *blackoilState, *wellState , false);
|
||||
@ -267,6 +290,8 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData)
|
||||
const std::string restart_filename = test_area_path + slash + eclipse_restart_filename;
|
||||
std::shared_ptr<Opm::WellState> wellStateRestored(new Opm::WellState());
|
||||
wellStateRestored->init(wells, *blackoilState);
|
||||
|
||||
//Read and verify OPM XWEL data
|
||||
Opm::restoreOPM_XWELKeyword(restart_filename, 1, *wellStateRestored);
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(wellState->bhp().begin(), wellState->bhp().end(), wellStateRestored->bhp().begin(), wellStateRestored->bhp().end());
|
||||
@ -275,5 +300,26 @@ BOOST_AUTO_TEST_CASE(EclipseReadWriteWellStateData)
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(wellState->perfRates().begin(), wellState->perfRates().end(), wellStateRestored->perfRates().begin(), wellStateRestored->perfRates().end());
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS(wellState->perfPress().begin(), wellState->perfPress().end(), wellStateRestored->perfPress().begin(), wellStateRestored->perfPress().end());
|
||||
|
||||
|
||||
//Read and verify pressure, temperature and saturation data
|
||||
std::shared_ptr<Opm::BlackoilState> blackoilStateRestored = createBlackOilState(eclipseState->getEclipseGrid());
|
||||
Opm::restoreSOLUTIONData(restart_filename, 1, *eclipseState, *gridManager.c_grid(), phaseUsage, *blackoilStateRestored);
|
||||
|
||||
std::vector<double> swat_restored;
|
||||
std::vector<double> swat;
|
||||
std::vector<double> sgas_restored;
|
||||
std::vector<double> sgas;
|
||||
Opm::EclipseIOUtil::extractFromStripedData(blackoilStateRestored->saturation(), swat_restored, phaseUsage.phase_pos[Opm::BlackoilPhases::Aqua], phaseUsage.num_phases);
|
||||
Opm::EclipseIOUtil::extractFromStripedData(blackoilState->saturation(), swat, phaseUsage.phase_pos[Opm::BlackoilPhases::Aqua], phaseUsage.num_phases);
|
||||
Opm::EclipseIOUtil::extractFromStripedData(blackoilStateRestored->saturation(), sgas_restored, phaseUsage.phase_pos[Opm::BlackoilPhases::Vapour], phaseUsage.num_phases);
|
||||
Opm::EclipseIOUtil::extractFromStripedData(blackoilState->saturation(), sgas, phaseUsage.phase_pos[Opm::BlackoilPhases::Vapour], phaseUsage.num_phases);
|
||||
|
||||
for (size_t cellindex = 0; cellindex < 1000; ++cellindex) {
|
||||
BOOST_CHECK_CLOSE(blackoilState->pressure()[cellindex], blackoilStateRestored->pressure()[cellindex], 0.00001);
|
||||
BOOST_CHECK_CLOSE(blackoilState->temperature()[cellindex], blackoilStateRestored->temperature()[cellindex], 0.00001);
|
||||
BOOST_CHECK_CLOSE(swat[cellindex], swat_restored[cellindex], 0.00001);
|
||||
BOOST_CHECK_CLOSE(sgas[cellindex], sgas_restored[cellindex], 0.00001);
|
||||
}
|
||||
|
||||
test_work_area_free(test_area);
|
||||
}
|
||||
|
@ -52,15 +52,21 @@ BOOST_AUTO_TEST_CASE(Construction)
|
||||
double dist1[3] = {0 , 1 , 2};
|
||||
double dist2[3] = {10, 11 , 12};
|
||||
double target = 77;
|
||||
double alq = 88;
|
||||
int vfp = 42;
|
||||
|
||||
well_controls_assert_number_of_phases( ctrls , num_phases );
|
||||
well_controls_add_new( type1 , target , dist1 , ctrls );
|
||||
well_controls_add_new( type2 , 2*target , dist2 , ctrls );
|
||||
well_controls_add_new( type1 , target , alq , vfp , dist1 , ctrls );
|
||||
well_controls_add_new( type2 , 2*target , 2*alq , 2*vfp , dist2 , ctrls );
|
||||
|
||||
BOOST_CHECK_EQUAL( target , well_controls_iget_target(ctrls , 0 ));
|
||||
BOOST_CHECK_EQUAL( alq , well_controls_iget_alq(ctrls , 0 ));
|
||||
BOOST_CHECK_EQUAL( vfp , well_controls_iget_vfp(ctrls , 0 ));
|
||||
BOOST_CHECK_EQUAL( type1 , well_controls_iget_type(ctrls , 0 ));
|
||||
|
||||
BOOST_CHECK_EQUAL( 2*target , well_controls_iget_target(ctrls , 1 ));
|
||||
BOOST_CHECK_EQUAL( 2*alq , well_controls_iget_alq(ctrls , 1 ));
|
||||
BOOST_CHECK_EQUAL( 2*vfp , well_controls_iget_vfp(ctrls , 1 ));
|
||||
BOOST_CHECK_EQUAL( type2 , well_controls_iget_type(ctrls , 1 ));
|
||||
well_controls_set_current( ctrls , 1 );
|
||||
BOOST_CHECK_EQUAL( type2 , well_controls_get_current_type( ctrls ));
|
||||
@ -79,6 +85,16 @@ BOOST_AUTO_TEST_CASE(Construction)
|
||||
well_controls_iset_target( ctrls , 1 , 456);
|
||||
BOOST_CHECK_EQUAL( 456 , well_controls_iget_target( ctrls , 1 ));
|
||||
|
||||
well_controls_iset_alq( ctrls , 0 , 789);
|
||||
BOOST_CHECK_EQUAL( 789 , well_controls_iget_alq( ctrls , 0 ));
|
||||
well_controls_iset_alq( ctrls , 1 , 234);
|
||||
BOOST_CHECK_EQUAL( 234 , well_controls_iget_alq( ctrls , 1 ));
|
||||
|
||||
well_controls_iset_vfp( ctrls , 0 , 567);
|
||||
BOOST_CHECK_EQUAL( 567 , well_controls_iget_vfp( ctrls , 0 ));
|
||||
well_controls_iset_vfp( ctrls , 1 , 890);
|
||||
BOOST_CHECK_EQUAL( 890 , well_controls_iget_vfp( ctrls , 1 ));
|
||||
|
||||
well_controls_iset_type( ctrls , 0 , SURFACE_RATE);
|
||||
BOOST_CHECK_EQUAL( SURFACE_RATE , well_controls_iget_type( ctrls , 0 ));
|
||||
well_controls_iset_type( ctrls , 1 , BHP);
|
||||
@ -130,10 +146,12 @@ BOOST_AUTO_TEST_CASE(Clone)
|
||||
const double dist1[] = { 0, 1, 2};
|
||||
const double dist2[] = {10, 11, 12};
|
||||
const double target = 77;
|
||||
const double alq = 88;
|
||||
const int vfp = 42;
|
||||
|
||||
well_controls_assert_number_of_phases(ctrls.get(), num_phases);
|
||||
well_controls_add_new(type1, target, dist1, ctrls.get());
|
||||
well_controls_add_new(type2, 2*target, dist2, ctrls.get());
|
||||
well_controls_add_new(type1, target, alq, vfp, dist1, ctrls.get());
|
||||
well_controls_add_new(type2, 2*target, 2*alq, 2*vfp, dist2, ctrls.get());
|
||||
|
||||
std::shared_ptr<WellControls>
|
||||
c(well_controls_clone(ctrls.get()),
|
||||
|
@ -35,6 +35,12 @@
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace
|
||||
{
|
||||
static double invalid_alq = -1e100;
|
||||
static double invalid_vfp = -2147483647;
|
||||
} //Namespace
|
||||
|
||||
BOOST_AUTO_TEST_CASE(Construction)
|
||||
{
|
||||
const int nphases = 2;
|
||||
@ -97,10 +103,14 @@ BOOST_AUTO_TEST_CASE(Controls)
|
||||
|
||||
if (ok) {
|
||||
const double distr[] = { 1.0, 0.0 };
|
||||
const bool ok1 = append_well_controls(BHP, 1, &distr[0],
|
||||
const bool ok1 = append_well_controls(BHP, 1,
|
||||
invalid_alq, invalid_vfp,
|
||||
&distr[0],
|
||||
0, W.get());
|
||||
const bool ok2 = append_well_controls(SURFACE_RATE, 1,
|
||||
&distr[0], 0, W.get());
|
||||
invalid_alq, invalid_vfp,
|
||||
&distr[0],
|
||||
0, W.get());
|
||||
|
||||
if (ok1 && ok2) {
|
||||
WellControls* ctrls = W->ctrls[0];
|
||||
@ -150,9 +160,12 @@ BOOST_AUTO_TEST_CASE(Copy)
|
||||
bool ok = ok0 && ok1;
|
||||
for (int w = 0; ok && (w < W1->number_of_wells); ++w) {
|
||||
const double distr[] = { 1.0, 0.0 };
|
||||
const bool okc1 = append_well_controls(BHP, 1, &distr[0],
|
||||
w, W1.get());
|
||||
const bool okc1 = append_well_controls(BHP, 1,
|
||||
invalid_alq, invalid_vfp,
|
||||
&distr[0], w,
|
||||
W1.get());
|
||||
const bool okc2 = append_well_controls(SURFACE_RATE, 1,
|
||||
invalid_alq, invalid_vfp,
|
||||
&distr[0], w,
|
||||
W1.get());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user