temperature output as weighted sum of well block temperatures based on specific heat capacity of the phases

This commit is contained in:
Paul Egberts committed 2021-02-22 18:41:25 +01:00
1 parent a5c5dc2ec9
commit 3ff3d549ed
3 files changed
+69 -9

No files matched your search

@@ -703,6 +703,12 @@ namespace Opm {
const SummaryState& summaryState) const SummaryState& summaryState)
{ {
std::vector<double> cellPressures(this->local_num_cells_, 0.0); std::vector<double> cellPressures(this->local_num_cells_, 0.0);
std::vector<double> cellTemperatures(this->local_num_cells_, 0.0);
const int np = numPhases();
std::vector<std::vector<double>> cellInternalEnergy(this->local_num_cells_, std::vector<double>(np));
std::vector<std::vector<double>> cellBinv(this->local_num_cells_, std::vector<double>(np));
std::vector<std::vector<double>> cellDensity(this->local_num_cells_, std::vector<double>(np));
ElementContext elemCtx(ebosSimulator_); ElementContext elemCtx(ebosSimulator_);
const auto& gridView = ebosSimulator_.vanguard().gridView(); const auto& gridView = ebosSimulator_.vanguard().gridView();
@@ -719,6 +725,15 @@ namespace Opm {
elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0);
const auto& fs = elemCtx.intensiveQuantities(/*spaceIdx=*/0, /*timeIdx=*/0).fluidState(); const auto& fs = elemCtx.intensiveQuantities(/*spaceIdx=*/0, /*timeIdx=*/0).fluidState();
cellTemperatures[elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0)] = fs.temperature(/*phaseIdx*/0).value();
for (int phaseIdx = 0; phaseIdx < np; ++phaseIdx)
{
cellInternalEnergy[elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0)][phaseIdx] = fs.enthalpy(phaseIdx).value() - fs.pressure(phaseIdx).value() / fs.density(phaseIdx).value();
cellBinv[elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0)][phaseIdx] = fs.invB(phaseIdx).value();
cellDensity[elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0)][phaseIdx] = fs.density(phaseIdx).value();
}
// copy of get perfpressure in Standard well except for value // copy of get perfpressure in Standard well except for value
double& perf_pressure = cellPressures[elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0)]; double& perf_pressure = cellPressures[elemCtx.globalSpaceIndex(/*spaceIdx=*/0, /*timeIdx=*/0)];
@@ -731,7 +746,7 @@ namespace Opm {
} }
} }
well_state_.init(cellPressures, schedule(), wells_ecl_, local_parallel_well_info_, timeStepIdx, well_state_.init(cellPressures, cellTemperatures, cellInternalEnergy, cellBinv, cellDensity, schedule(), wells_ecl_, local_parallel_well_info_, timeStepIdx,
&previous_well_state_, phase_usage_, well_perf_data_, &previous_well_state_, phase_usage_, well_perf_data_,
summaryState, globalNumWells); summaryState, globalNumWells);
} }
+42 -6
View File
@@ -39,18 +39,23 @@
namespace Opm namespace Opm
{ {
/// The state of a set of wells. /// The state of a set of wells.
class WellState class WellState
{ {
public: public:
typedef std::array< int, 3 > mapentry_t; typedef std::array< int, 3 > mapentry_t;
typedef std::map< std::string, mapentry_t > WellMapType; typedef std::map< std::string, mapentry_t > WellMapType;
/// Allocate and initialize if wells is non-null. /// Allocate and initialize if wells is non-null.
/// Also tries to give useful initial values to the bhp() and /// Also tries to give useful initial values to the bhp() and
/// wellRates() fields, depending on controls. The /// wellRates() fields, depending on controls. The
/// perfRates() field is filled with zero, and perfPress() /// perfRates() field is filled with zero, and perfPress()
/// with -1e100. /// with -1e100.
void init(const std::vector<double>& cellPressures, void init(const std::vector<double>& cellPressures,
const std::vector<double>& cellTemperatures,
const std::vector<std::vector<double>>& cellInternalEnergy,
const std::vector<std::vector<double>>& cellBinv,
const std::vector<std::vector<double>>& cellDensity,
const std::vector<double>& perforationRates,
const std::vector<Well>& wells_ecl, const std::vector<Well>& wells_ecl,
const std::vector<ParallelWellInfo*>& parallel_well_info, const std::vector<ParallelWellInfo*>& parallel_well_info,
const PhaseUsage& pu, const PhaseUsage& pu,
@@ -73,13 +78,13 @@ namespace Opm
bhp_.resize(nw, 0.0); bhp_.resize(nw, 0.0);
thp_.resize(nw, 0.0); thp_.resize(nw, 0.0);
temperature_.resize(nw, 273.15 + 15.56); // standard condition temperature temperature_.resize(nw, 273.15 + 15.56); // standard condition temperature
wellrates_.resize(nw * np, 0.0); wellrates_.resize(nw * np, 0.0);
int connpos = 0; int connpos = 0;
for (int w = 0; w < nw; ++w) { for (int w = 0; w < nw; ++w) {
const Well& well = wells_ecl[w]; const Well& well = wells_ecl[w];
// Initialize bhp(), thp(), wellRates(), temperature(). // Initialize bhp(), thp(), wellRates(), temperature().
initSingleWell(cellPressures, w, well, *parallel_well_info[w], pu, summary_state); initSingleWell(cellPressures, cellTemperatures, cellInternalEnergy, cellBinv, cellDensity, perforationRates, w, well, *parallel_well_info[w], pu, summary_state);
// Setup wellname -> well index mapping. // Setup wellname -> well index mapping.
const int num_perf_this_well = well_perf_data[w].size(); const int num_perf_this_well = well_perf_data[w].size();
@@ -353,6 +358,11 @@ namespace Opm
sizes.data(), displ.data(), 0); sizes.data(), displ.data(), 0);
} }
void initSingleWell(const std::vector<double>& cellPressures, void initSingleWell(const std::vector<double>& cellPressures,
const std::vector<double>& cellTemperatures,
const std::vector<std::vector<double>>& cellInternalEnergy,
const std::vector<std::vector<double>>& cellBinv,
const std::vector<std::vector<double>>& cellDensity,
const std::vector<double>& perforationRates,
const int w, const int w,
const Well& well, const Well& well,
const ParallelWellInfo& well_info, const ParallelWellInfo& well_info,
@@ -368,9 +378,35 @@ namespace Opm
wellrates_[np*w + p] = 0.0; wellrates_[np*w + p] = 0.0;
} }
const int num_perf_this_well = well_perf_data_[w].size();
if ( well.isInjector() ) { if ( well.isInjector() ) {
temperature_[w] = well.injectionControls(summary_state).temperature; temperature_[w] = well.injectionControls(summary_state).temperature;
} }
if ( well.isProducer() ) {
int sz = perforationRates.size();
int connpos = 0;
for (int i = 0; i < w; ++i){
connpos += well_perf_data_[i].size();
}
connpos *= np;
double weighted_temperature = 0.0;
double total_weight = 0.0;
if (sz > 0){
for (int i = 0; i < num_perf_this_well; ++i){
int perf_cell_index = well_perf_data_[w][i].cell_index;
double weight_factor = 0.0;
for (int p = 0; p < np; ++p) {
weight_factor += cellDensity[perf_cell_index][p] * perforationRates[connpos + i*np + p]/cellBinv[perf_cell_index][p] * cellInternalEnergy[perf_cell_index][p]/cellTemperatures[perf_cell_index];
}
total_weight += weight_factor;
weighted_temperature += weight_factor * cellTemperatures[perf_cell_index];
}
temperature_[w] = weighted_temperature/total_weight;
}
else {
temperature_[w]=0;
}
}
const int num_perf_this_well = well_info.communication().sum(well_perf_data_[w].size()); const int num_perf_this_well = well_info.communication().sum(well_perf_data_[w].size());
if ( num_perf_this_well == 0 ) { if ( num_perf_this_well == 0 ) {
@@ -489,9 +525,9 @@ namespace Opm
protected: protected:
std::vector<std::vector<PerforationData>> well_perf_data_; std::vector<std::vector<PerforationData>> well_perf_data_;
std::vector<ParallelWellInfo*> parallel_well_info_; std::vector<ParallelWellInfo*> parallel_well_info_;
}; };
} // namespace Opm } // namespace Opm
#endif // OPM_WELLSTATE_HEADER_INCLUDED #endif // OPM_WELLSTATE_HEADER_INCLUDED
@@ -23,6 +23,7 @@
#include <opm/simulators/wells/WellState.hpp> #include <opm/simulators/wells/WellState.hpp>
#include <opm/core/props/BlackoilPhases.hpp> #include <opm/core/props/BlackoilPhases.hpp>
#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Well/Well.hpp>
@@ -70,6 +71,10 @@ namespace Opm
/// to give useful initial values to the bhp(), wellRates() /// to give useful initial values to the bhp(), wellRates()
/// and perfPhaseRates() fields, depending on controls /// and perfPhaseRates() fields, depending on controls
void init(const std::vector<double>& cellPressures, void init(const std::vector<double>& cellPressures,
const std::vector<double>& cellTemperatures,
const std::vector<std::vector<double>>& cellInternalEnergy,
const std::vector<std::vector<double>>& cellBinv,
const std::vector<std::vector<double>>& cellDensity,
const Schedule& schedule, const Schedule& schedule,
const std::vector<Well>& wells_ecl, const std::vector<Well>& wells_ecl,
const std::vector<ParallelWellInfo*>& parallel_well_info, const std::vector<ParallelWellInfo*>& parallel_well_info,
@@ -80,8 +85,11 @@ namespace Opm
const SummaryState& summary_state, const SummaryState& summary_state,
const int globalNumberOfWells) const int globalNumberOfWells)
{ {
//Todo: make it reservoir perforation rates
std::vector<double> perforationRates;
perforationRates = prevState->perfphaserates_;
// call init on base class // call init on base class
BaseType :: init(cellPressures, wells_ecl, parallel_well_info, pu, well_perf_data, summary_state); BaseType :: init(cellPressures, cellTemperatures, cellInternalEnergy, cellBinv, cellDensity, perforationRates, wells_ecl, parallel_well_info, pu, well_perf_data, summary_state);
for (const auto& winfo: parallel_well_info) for (const auto& winfo: parallel_well_info)
{ {
@@ -348,7 +356,8 @@ namespace Opm
const int globalNumWells) const int globalNumWells)
{ {
const std::vector<double> tmp(numCells, 0.0); // <- UGLY HACK to pass the size const std::vector<double> tmp(numCells, 0.0); // <- UGLY HACK to pass the size
init(tmp, schedule, wells_ecl, parallel_well_info, 0, nullptr, pu, well_perf_data, summary_state, globalNumWells); std::vector<std::vector<double>> tmp1(numCells, std::vector<double>( numPhases()));// <- UGLY HACK to pass the size
init(tmp, tmp, tmp1, tmp1, tmp1, schedule, wells_ecl, parallel_well_info, 0, nullptr, pu, well_perf_data, summary_state, globalNumWells);
if (handle_ms_well) { if (handle_ms_well) {
initWellStateMSWell(wells_ecl, pu, nullptr); initWellStateMSWell(wells_ecl, pu, nullptr);