Merge pull request #5490 from totto82/useCellTempRESV

Use cell temperature in perforated cell to compute reservoir rates
This commit is contained in:
Tor Harald Sandve
2024-08-02 08:34:22 +02:00
committed by GitHub
8 changed files with 38 additions and 16 deletions

View File

@@ -812,6 +812,7 @@ namespace Opm {
initializeWellState(const int timeStepIdx) initializeWellState(const int timeStepIdx)
{ {
std::vector<Scalar> cellPressures(this->local_num_cells_, 0.0); std::vector<Scalar> cellPressures(this->local_num_cells_, 0.0);
std::vector<Scalar> cellTemperatures(this->local_num_cells_, 0.0);
ElementContext elemCtx(simulator_); ElementContext elemCtx(simulator_);
const auto& gridView = simulator_.vanguard().gridView(); const auto& gridView = simulator_.vanguard().gridView();
@@ -831,10 +832,11 @@ namespace Opm {
} else { } else {
perf_pressure = fs.pressure(FluidSystem::gasPhaseIdx).value(); perf_pressure = fs.pressure(FluidSystem::gasPhaseIdx).value();
} }
cellTemperatures[elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0)] = fs.temperature(0).value();
} }
OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::initializeWellState() failed: ", simulator_.vanguard().grid().comm()); OPM_END_PARALLEL_TRY_CATCH("BlackoilWellModel::initializeWellState() failed: ", simulator_.vanguard().grid().comm());
this->wellState().init(cellPressures, this->schedule(), this->wells_ecl_, this->wellState().init(cellPressures, cellTemperatures, this->schedule(), this->wells_ecl_,
this->local_parallel_well_info_, timeStepIdx, this->local_parallel_well_info_, timeStepIdx,
&this->prevWellState(), this->well_perf_data_, &this->prevWellState(), this->well_perf_data_,
this->summaryState()); this->summaryState());

View File

@@ -711,7 +711,7 @@ namespace Opm
this->segments_.copyPhaseDensities(ws.pu, ws.segments); this->segments_.copyPhaseDensities(ws.pu, ws.segments);
} }
Base::calculateReservoirRates(well_state.well(this->index_of_well_)); Base::calculateReservoirRates(simulator.vanguard().eclState().runspec().co2Storage(), well_state.well(this->index_of_well_));
} }

View File

@@ -706,7 +706,7 @@ namespace Opm
const auto& summary_state = simulator.vanguard().summaryState(); const auto& summary_state = simulator.vanguard().summaryState();
updateWellStateFromPrimaryVariables(stop_or_zero_rate_target, well_state, summary_state, deferred_logger); updateWellStateFromPrimaryVariables(stop_or_zero_rate_target, well_state, summary_state, deferred_logger);
Base::calculateReservoirRates(well_state.well(this->index_of_well_)); Base::calculateReservoirRates(simulator.vanguard().eclState().runspec().co2Storage(), well_state.well(this->index_of_well_));
} }
@@ -2587,7 +2587,7 @@ namespace Opm
if (this->isInjector() && cq_s[activeCompIdx] > 0.0){ if (this->isInjector() && cq_s[activeCompIdx] > 0.0){
// only handles single phase injection now // only handles single phase injection now
assert(this->well_ecl_.injectorType() != InjectorType::MULTI); assert(this->well_ecl_.injectorType() != InjectorType::MULTI);
fs.setTemperature(this->well_ecl_.temperature()); fs.setTemperature(this->well_ecl_.inj_temperature());
typedef typename std::decay<decltype(fs)>::type::Scalar FsScalar; typedef typename std::decay<decltype(fs)>::type::Scalar FsScalar;
typename FluidSystem::template ParameterCache<FsScalar> paramCache; typename FluidSystem::template ParameterCache<FsScalar> paramCache;
const unsigned pvtRegionIdx = intQuants.pvtRegionIndex(); const unsigned pvtRegionIdx = intQuants.pvtRegionIndex();

View File

@@ -64,12 +64,12 @@ WellInterfaceFluidSystem(const Well& well,
template <typename FluidSystem> template <typename FluidSystem>
void void
WellInterfaceFluidSystem<FluidSystem>:: WellInterfaceFluidSystem<FluidSystem>::
calculateReservoirRates(SingleWellState<Scalar>& ws) const calculateReservoirRates(const bool co2store, SingleWellState<Scalar>& ws) const
{ {
const int np = this->number_of_phases_; const int np = this->number_of_phases_;
const auto& pu = this->phaseUsage(); const auto& pu = this->phaseUsage();
// Calculate reservoir rates from average pressure and temperature // Calculate reservoir rates from average pressure and temperature
if ( !pu.has_energy || this->wellEcl().isProducer()) { if ( !(co2store || pu.has_energy) || this->wellEcl().isProducer()) {
const int fipreg = 0; // not considering the region for now const int fipreg = 0; // not considering the region for now
this->rateConverter_ this->rateConverter_
.calcReservoirVoidageRates(fipreg, .calcReservoirVoidageRates(fipreg,
@@ -99,7 +99,8 @@ calculateReservoirRates(SingleWellState<Scalar>& ws) const
} }
return; return;
} }
// For injectors in a thermal case we convert using the well bhp and temperature // For injectors in a co2 storage case or a thermal case
// we convert using the well bhp and temperature
// Assume pure phases in the injector // Assume pure phases in the injector
const Scalar saltConc = 0.0; const Scalar saltConc = 0.0;
Scalar rsMax = 0.0; Scalar rsMax = 0.0;

View File

@@ -81,7 +81,7 @@ protected:
const std::vector<PerforationData<Scalar>>& perf_data); const std::vector<PerforationData<Scalar>>& perf_data);
// updating the voidage rates in well_state when requested // updating the voidage rates in well_state when requested
void calculateReservoirRates(SingleWellState<Scalar>& ws) const; void calculateReservoirRates(const bool co2store, SingleWellState<Scalar>& ws) const;
bool checkIndividualConstraints(SingleWellState<Scalar>& ws, bool checkIndividualConstraints(SingleWellState<Scalar>& ws,
const SummaryState& summaryState, const SummaryState& summaryState,

View File

@@ -149,6 +149,7 @@ serializationTestObject(const ParallelWellInfo<Scalar>& pinfo)
template<class Scalar> template<class Scalar>
void WellState<Scalar>::base_init(const std::vector<Scalar>& cellPressures, void WellState<Scalar>::base_init(const std::vector<Scalar>& cellPressures,
const std::vector<Scalar>& cellTemperatures,
const std::vector<Well>& wells_ecl, const std::vector<Well>& wells_ecl,
const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info, const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data, const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data,
@@ -164,7 +165,7 @@ void WellState<Scalar>::base_init(const std::vector<Scalar>& cellPressures,
const Well& well = wells_ecl[w]; const Well& well = wells_ecl[w];
// Initialize bhp(), thp(), wellRates(), temperature(). // Initialize bhp(), thp(), wellRates(), temperature().
initSingleWell(cellPressures, well, well_perf_data[w], parallel_well_info[w], summary_state); initSingleWell(cellPressures, cellTemperatures, well, well_perf_data[w], parallel_well_info[w], summary_state);
} }
} }
} }
@@ -202,12 +203,12 @@ template<class Scalar>
void WellState<Scalar>::initSingleInjector(const Well& well, void WellState<Scalar>::initSingleInjector(const Well& well,
const ParallelWellInfo<Scalar>& well_info, const ParallelWellInfo<Scalar>& well_info,
Scalar pressure_first_connection, Scalar pressure_first_connection,
Scalar temperature_first_connection,
const std::vector<PerforationData<Scalar>>& well_perf_data, const std::vector<PerforationData<Scalar>>& well_perf_data,
const SummaryState& summary_state) const SummaryState& summary_state)
{ {
const auto& pu = this->phase_usage_; const auto& pu = this->phase_usage_;
const Scalar temp = well.temperature(); const Scalar temp = well.hasInjTemperature() ? well.inj_temperature() : temperature_first_connection;
auto& ws = this->wells_.add(well.name(), SingleWellState<Scalar>{well.name(), auto& ws = this->wells_.add(well.name(), SingleWellState<Scalar>{well.name(),
well_info, well_info,
false, false,
@@ -228,18 +229,25 @@ void WellState<Scalar>::initSingleInjector(const Well& well,
template<class Scalar> template<class Scalar>
void WellState<Scalar>::initSingleWell(const std::vector<Scalar>& cellPressures, void WellState<Scalar>::initSingleWell(const std::vector<Scalar>& cellPressures,
const std::vector<Scalar>& cellTemperatures,
const Well& well, const Well& well,
const std::vector<PerforationData<Scalar>>& well_perf_data, const std::vector<PerforationData<Scalar>>& well_perf_data,
const ParallelWellInfo<Scalar>& well_info, const ParallelWellInfo<Scalar>& well_info,
const SummaryState& summary_state) const SummaryState& summary_state)
{ {
Scalar pressure_first_connection = -1; Scalar pressure_first_connection = -1;
if (!well_perf_data.empty()) if (!well_perf_data.empty()) {
pressure_first_connection = cellPressures[well_perf_data[0].cell_index]; pressure_first_connection = cellPressures[well_perf_data[0].cell_index];
}
pressure_first_connection = well_info.broadcastFirstPerforationValue(pressure_first_connection); pressure_first_connection = well_info.broadcastFirstPerforationValue(pressure_first_connection);
if (well.isInjector()) { if (well.isInjector()) {
this->initSingleInjector(well, well_info, pressure_first_connection, Scalar temperature_first_connection = -1;
if (!well_perf_data.empty()) {
temperature_first_connection = cellTemperatures[well_perf_data[0].cell_index];
}
temperature_first_connection = well_info.broadcastFirstPerforationValue(temperature_first_connection);
this->initSingleInjector(well, well_info, pressure_first_connection, temperature_first_connection,
well_perf_data, summary_state); well_perf_data, summary_state);
} else { } else {
this->initSingleProducer(well, well_info, pressure_first_connection, this->initSingleProducer(well, well_info, pressure_first_connection,
@@ -249,6 +257,7 @@ void WellState<Scalar>::initSingleWell(const std::vector<Scalar>& cellPressures,
template<class Scalar> template<class Scalar>
void WellState<Scalar>::init(const std::vector<Scalar>& cellPressures, void WellState<Scalar>::init(const std::vector<Scalar>& cellPressures,
const std::vector<Scalar>& cellTemperatures,
const Schedule& schedule, const Schedule& schedule,
const std::vector<Well>& wells_ecl, const std::vector<Well>& wells_ecl,
const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info, const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
@@ -258,7 +267,7 @@ void WellState<Scalar>::init(const std::vector<Scalar>& cellPressures,
const SummaryState& summary_state) const SummaryState& summary_state)
{ {
// call init on base class // call init on base class
this->base_init(cellPressures, wells_ecl, parallel_well_info, this->base_init(cellPressures, cellTemperatures, wells_ecl, parallel_well_info,
well_perf_data, summary_state); well_perf_data, summary_state);
this->global_well_info = std::make_optional<GlobalWellInfo>(schedule, this->global_well_info = std::make_optional<GlobalWellInfo>(schedule,
report_step, report_step,
@@ -428,7 +437,7 @@ void WellState<Scalar>::resize(const std::vector<Well>& wells_ecl,
const SummaryState& summary_state) const SummaryState& summary_state)
{ {
const std::vector<Scalar> tmp(numCells, 0.0); // <- UGLY HACK to pass the size const std::vector<Scalar> tmp(numCells, 0.0); // <- UGLY HACK to pass the size
init(tmp, schedule, wells_ecl, parallel_well_info, 0, nullptr, well_perf_data, summary_state); init(tmp, tmp, schedule, wells_ecl, parallel_well_info, 0, nullptr, well_perf_data, summary_state);
if (handle_ms_well) { if (handle_ms_well) {
initWellStateMSWell(wells_ecl, nullptr); initWellStateMSWell(wells_ecl, nullptr);

View File

@@ -97,6 +97,7 @@ public:
/// to give useful initial values to the bhp(), wellRates() /// to give useful initial values to the bhp(), wellRates()
/// and perfPhaseRatesORG() fields, depending on controls /// and perfPhaseRatesORG() fields, depending on controls
void init(const std::vector<Scalar>& cellPressures, void init(const std::vector<Scalar>& cellPressures,
const std::vector<Scalar>& cellTemperatures,
const Schedule& schedule, const Schedule& schedule,
const std::vector<Well>& wells_ecl, const std::vector<Well>& wells_ecl,
const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info, const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
@@ -377,12 +378,14 @@ private:
/// perfRates() field is filled with zero, and perfPress() /// perfRates() field is filled with zero, and perfPress()
/// with -1e100. /// with -1e100.
void base_init(const std::vector<Scalar>& cellPressures, void base_init(const std::vector<Scalar>& cellPressures,
const std::vector<Scalar>& cellTemperatures,
const std::vector<Well>& wells_ecl, const std::vector<Well>& wells_ecl,
const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info, const std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>>& parallel_well_info,
const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data, const std::vector<std::vector<PerforationData<Scalar>>>& well_perf_data,
const SummaryState& summary_state); const SummaryState& summary_state);
void initSingleWell(const std::vector<Scalar>& cellPressures, void initSingleWell(const std::vector<Scalar>& cellPressures,
const std::vector<Scalar>& cellTemperatures,
const Well& well, const Well& well,
const std::vector<PerforationData<Scalar>>& well_perf_data, const std::vector<PerforationData<Scalar>>& well_perf_data,
const ParallelWellInfo<Scalar>& well_info, const ParallelWellInfo<Scalar>& well_info,
@@ -397,6 +400,7 @@ private:
void initSingleInjector(const Well& well, void initSingleInjector(const Well& well,
const ParallelWellInfo<Scalar>& well_info, const ParallelWellInfo<Scalar>& well_info,
Scalar pressure_first_connection, Scalar pressure_first_connection,
Scalar temperature_first_connection,
const std::vector<PerforationData<Scalar>>& well_perf_data, const std::vector<PerforationData<Scalar>>& well_perf_data,
const SummaryState& summary_state); const SummaryState& summary_state);
}; };

View File

@@ -158,6 +158,12 @@ namespace {
std::vector<double>(setup.grid.c_grid()->number_of_cells, std::vector<double>(setup.grid.c_grid()->number_of_cells,
100.0*Opm::unit::barsa); 100.0*Opm::unit::barsa);
const auto& unit_sytem = setup.es.getDeckUnitSystem();
const double temp = unit_sytem.to_si(Opm::UnitSystem::measure::temperature, 25);
const auto ctemp =
std::vector<double>(setup.grid.c_grid()->number_of_cells,
temp);
auto wells = setup.sched.getWells(timeStep); auto wells = setup.sched.getWells(timeStep);
pinfos.resize(wells.size()); pinfos.resize(wells.size());
std::vector<std::reference_wrapper<Opm::ParallelWellInfo<double>>> ppinfos; std::vector<std::reference_wrapper<Opm::ParallelWellInfo<double>>> ppinfos;
@@ -171,7 +177,7 @@ namespace {
++pw; ++pw;
} }
state.init(cpress, setup.sched, state.init(cpress, ctemp, setup.sched,
wells, ppinfos, wells, ppinfos,
timeStep, nullptr, setup.well_perf_data, setup.st); timeStep, nullptr, setup.well_perf_data, setup.st);