Merge pull request #1888 from joakim-hove/summarystate-well-init

Use the shared SummaryState instance when initializing well rates
This commit is contained in:
Joakim Hove 2019-06-17 18:50:11 +02:00 committed by GitHub
commit e114d4a46d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 39 additions and 42 deletions

View File

@ -22,6 +22,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well2.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <boost/lexical_cast.hpp>
@ -68,7 +69,7 @@ namespace Opm
child->setParent(parent);
}
void WellCollection::addWell(const Well2& wellChild, size_t timeStep, const PhaseUsage& phaseUsage) {
void WellCollection::addWell(const Well2& wellChild, const SummaryState& summaryState, size_t timeStep, const PhaseUsage& phaseUsage) {
if (wellChild.getStatus() == WellCommon::SHUT) {
//SHUT wells are not added to the well collection
return;
@ -79,7 +80,7 @@ namespace Opm
OPM_THROW(std::runtime_error, "Trying to add well " << wellChild.name() << " Step: " << boost::lexical_cast<std::string>(timeStep) << " to group named " << wellChild.groupName() << ", but this group does not exist in the WellCollection.");
}
std::shared_ptr<WellsGroupInterface> child = createWellWellsGroup(wellChild, timeStep, phaseUsage);
std::shared_ptr<WellsGroupInterface> child = createWellWellsGroup(wellChild, summaryState, timeStep, phaseUsage);
WellsGroup* parent_as_group = static_cast<WellsGroup*> (parent);
if (!parent_as_group) {

View File

@ -31,14 +31,14 @@
namespace Opm
{
class SummaryState;
class WellCollection
{
public:
void addField(const Group& fieldGroup, size_t timeStep, const PhaseUsage& phaseUsage);
void addWell(const Well2& wellChild, size_t timeStep, const PhaseUsage& phaseUsage);
void addWell(const Well2& wellChild, const SummaryState& summaryState, size_t timeStep, const PhaseUsage& phaseUsage);
void addGroup(const Group& groupChild, std::string parent_name,
size_t timeStep, const PhaseUsage& phaseUsage);

View File

@ -1588,9 +1588,8 @@ namespace Opm
'CMODE_UNDEFINED' - we do not carry that over the specification
objects here.
*/
std::shared_ptr<WellsGroupInterface> createWellWellsGroup(const Well2& well, size_t timeStep, const PhaseUsage& phase_usage )
std::shared_ptr<WellsGroupInterface> createWellWellsGroup(const Well2& well, const SummaryState& summaryState, size_t timeStep, const PhaseUsage& phase_usage )
{
SummaryState summaryState;
InjectionSpecification injection_specification;
ProductionSpecification production_specification;
if (well.isInjector()) {

View File

@ -541,7 +541,9 @@ namespace Opm
/// \param[in] well the Well to construct object for
/// \param[in] timeStep the time step in question
/// \param[in] the phase usage
std::shared_ptr<WellsGroupInterface> createWellWellsGroup(const Well2& well, size_t timeStep,
std::shared_ptr<WellsGroupInterface> createWellWellsGroup(const Well2& well,
const SummaryState& summaryState,
size_t timeStep,
const PhaseUsage& phase_usage );
/// Creates the WellsGroupInterface for the given Group

View File

@ -205,7 +205,7 @@ namespace Opm
const UnstructuredGrid& grid)
: w_(create_wells(0,0,0)), is_parallel_run_(false)
{
init(eclipseState, schedule, timeStep, UgGridHelpers::numCells(grid),
init(eclipseState, schedule, summaryState, timeStep, UgGridHelpers::numCells(grid),
UgGridHelpers::globalCell(grid), UgGridHelpers::cartDims(grid),
UgGridHelpers::dimensions(grid),
UgGridHelpers::cell2Faces(grid), UgGridHelpers::beginFaceCentroids(grid),
@ -292,12 +292,14 @@ namespace Opm
void WellsManager::setupWellControls(const std::vector<Well2>& wells, size_t timeStep,
std::vector<std::string>& well_names, const PhaseUsage& phaseUsage,
void WellsManager::setupWellControls(const std::vector<Well2>& wells,
const SummaryState& summaryState,
size_t timeStep,
std::vector<std::string>& well_names,
const PhaseUsage& phaseUsage,
const std::vector<int>& wells_on_proc) {
int well_index = 0;
auto well_on_proc = wells_on_proc.begin();
SummaryState summaryState;
for (auto wellIter = wells.begin(); wellIter != wells.end(); ++wellIter, ++well_on_proc) {
if( ! *well_on_proc )

View File

@ -157,6 +157,7 @@ namespace Opm
template<class C2F, class FC>
void init(const Opm::EclipseState& eclipseState,
const Opm::Schedule& schedule,
const Opm::SummaryState& summaryState,
const size_t timeStep,
int num_cells,
const int* global_cell,
@ -169,7 +170,7 @@ namespace Opm
WellsManager(const WellsManager& other);
WellsManager& operator=(const WellsManager& other);
static void setupCompressedToCartesian(const int* global_cell, int number_of_cells, std::map<int,int>& cartesian_to_compressed );
void setupWellControls(const std::vector<Well2>& wells, size_t timeStep,
void setupWellControls(const std::vector<Well2>& wells, const SummaryState& summaryState, size_t timeStep,
std::vector<std::string>& well_names, const PhaseUsage& phaseUsage,
const std::vector<int>& wells_on_proc);

View File

@ -279,7 +279,7 @@ WellsManager(const Opm::EclipseState& eclipseState,
const std::unordered_set<std::string>& deactivated_wells)
: w_(create_wells(0,0,0)), is_parallel_run_(is_parallel_run)
{
init(eclipseState, schedule, timeStep, number_of_cells, global_cell,
init(eclipseState, schedule, summaryState, timeStep, number_of_cells, global_cell,
cart_dims, dimensions,
cell_to_faces, begin_face_centroids, deactivated_wells);
}
@ -289,6 +289,7 @@ template <class C2F, class FC>
void
WellsManager::init(const Opm::EclipseState& eclipseState,
const Opm::Schedule& schedule,
const Opm::SummaryState& summaryState,
const size_t timeStep,
int number_of_cells,
const int* global_cell,
@ -367,7 +368,7 @@ WellsManager::init(const Opm::EclipseState& eclipseState,
pu, cartesian_to_compressed, interleavedPerm.data(), ntg,
wells_on_proc, deactivated_wells);
setupWellControls(wells, timeStep, well_names, pu, wells_on_proc);
setupWellControls(wells, summaryState, timeStep, well_names, pu, wells_on_proc);
{
const auto& fieldGroup = schedule.getGroup( "FIELD" );
@ -392,7 +393,7 @@ WellsManager::init(const Opm::EclipseState& eclipseState,
for (size_t i = 0; i < wells_on_proc.size(); ++i) {
// wells_on_proc is a vector of flag to indicate whether a well is on the process
if (wells_on_proc[i]) {
well_collection_.addWell(wells[i], timeStep, pu);
well_collection_.addWell(wells[i], summaryState, timeStep, pu);
}
}

View File

@ -486,7 +486,6 @@ namespace Opm
{
// TODO: only_wells should be put back to save some computation
// for example, the matrices B C does not need to update if only_wells
SummaryState summaryState;
checkWellOperability(ebosSimulator, well_state, deferred_logger);
@ -607,12 +606,11 @@ namespace Opm
// change temperature for injecting fluids
if (well_type_ == INJECTOR && cq_s[activeCompIdx] > 0.0){
const auto& injProps = this->well_ecl_.injectionControls(summaryState);
auto injectorType = this->well_ecl_.injectorType();
// only handles single phase injection now
assert(injProps.injector_type != WellInjector::MULTI);
fs.setTemperature(injProps.temperature);
assert(injectorType != WellInjector::MULTI);
fs.setTemperature(this->well_ecl_.temperature());
typedef typename std::decay<decltype(fs)>::type::Scalar FsScalar;
typename FluidSystem::template ParameterCache<FsScalar> paramCache;
const unsigned pvtRegionIdx = intQuants.pvtRegionIndex();
@ -2629,7 +2627,6 @@ namespace Opm
{
assert(int(rates.size()) == 3); // the vfp related only supports three phases now.
SummaryState summaryState;
const double aqua = rates[Water];
const double liquid = rates[Oil];
const double vapour = rates[Gas];
@ -2639,16 +2636,15 @@ namespace Opm
double thp = 0.0;
if (well_type_ == INJECTOR) {
const int table_id = well_ecl_.injectionControls(summaryState).vfp_table_number;
const int table_id = well_ecl_.vfp_table_number();
const double vfp_ref_depth = vfp_properties_->getInj()->getTable(table_id)->getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);
thp = vfp_properties_->getInj()->thp(table_id, aqua, liquid, vapour, bhp + dp);
}
else if (well_type_ == PRODUCER) {
const auto controls = well_ecl_.productionControls(summaryState);
const int table_id = controls.vfp_table_number;
const double alq = controls.alq_value;
const int table_id = well_ecl_.vfp_table_number();
const double alq = well_ecl_.alq_value();
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(table_id)->getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);

View File

@ -284,9 +284,8 @@ namespace Opm
return 0.0;
}
SummaryState summaryState;
const auto controls = well_ecl_.injectionControls(summaryState);
if (controls.injector_type == WellInjector::GAS) {
auto injectorType = well_ecl_.injectorType();
if (injectorType == WellInjector::GAS) {
double solvent_fraction = well_ecl_.getSolventFraction();
return solvent_fraction;
} else {
@ -308,11 +307,10 @@ namespace Opm
return 0.0;
}
SummaryState summaryState;
const auto controls = well_ecl_.injectionControls(summaryState);
WellPolymerProperties polymer = well_ecl_.getPolymerProperties();
auto injectorType = well_ecl_.injectorType();
if (controls.injector_type == WellInjector::WATER) {
if (injectorType == WellInjector::WATER) {
WellPolymerProperties polymer = well_ecl_.getPolymerProperties();
const double polymer_injection_concentration = polymer.m_polymerConcentration;
return polymer_injection_concentration;
} else {
@ -1119,11 +1117,8 @@ namespace Opm
// we need to get the table number through the parser, in case THP constraint/target is not there.
// When THP control/limit is not active, if available VFP table is provided, we will still need to
// update THP value. However, it will only used for output purpose.
SummaryState summaryState;
if (well_type_ == PRODUCER) { // producer
const auto controls = well_ecl_.productionControls(summaryState);
const int table_id = controls.vfp_table_number;
const int table_id = well_ecl_.vfp_table_number();
if (table_id <= 0) {
return false;
} else {
@ -1136,8 +1131,7 @@ namespace Opm
}
} else { // injector
const auto controls = well_ecl_.injectionControls(summaryState);
const int table_id = controls.vfp_table_number;
const int table_id = well_ecl_.vfp_table_number();
if (table_id <= 0) {
return false;
} else {

View File

@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(AddWellsAndGroupToCollection) {
const Eclipse3DProperties eclipseProperties ( deck , table, grid);
const Runspec runspec(deck);
const Schedule sched(deck, grid, eclipseProperties, runspec);
SummaryState summaryState;
WellCollection collection;
@ -64,7 +64,7 @@ BOOST_AUTO_TEST_CASE(AddWellsAndGroupToCollection) {
WellCollection wellCollection;
const auto wells = sched.getWells2atEnd();
for (size_t i=0; i<wells.size(); i++) {
collection.addWell(wells[i], 2, pu);
collection.addWell(wells[i], summaryState, 2, pu);
}
BOOST_CHECK_EQUAL("G1", collection.findNode("INJ1")->getParent()->name());
@ -84,6 +84,7 @@ BOOST_AUTO_TEST_CASE(EfficiencyFactor) {
const Eclipse3DProperties eclipseProperties ( deck , table, grid);
const Runspec runspec(deck);
const Schedule sched(deck, grid, eclipseProperties, runspec);
SummaryState summaryState;
size_t timestep = 2;
WellCollection collection;
@ -100,7 +101,7 @@ BOOST_AUTO_TEST_CASE(EfficiencyFactor) {
// Add wells to WellCollection
const auto wells1 = sched.getWells2(timestep);
for (size_t i=0; i<wells1.size(); i++) {
collection.addWell(wells1[i], timestep, pu);
collection.addWell(wells1[i], summaryState, timestep, pu);
}
// 0.5(inj1) * 0.8(G1)

View File

@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE(ConstructGroupFromWell) {
for (size_t i=0; i<wells.size(); i++) {
const auto& well = wells[i];
std::shared_ptr<WellsGroupInterface> wellsGroup = createWellWellsGroup(well, 2, pu);
std::shared_ptr<WellsGroupInterface> wellsGroup = createWellWellsGroup(well, summaryState, 2, pu);
BOOST_CHECK_EQUAL(well.name(), wellsGroup->name());
if (well.isInjector()) {
const auto controls = well.injectionControls(summaryState);