mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
adding the few injectivity related functions to StandardWellV
This commit is contained in:
parent
a08216efd5
commit
7923628f83
@ -534,7 +534,7 @@ namespace Opm {
|
|||||||
const int pvtreg = pvt_region_idx_[well_cell_top];
|
const int pvtreg = pvt_region_idx_[well_cell_top];
|
||||||
|
|
||||||
if ( !well_ecl->isMultiSegment(time_step) || !param_.use_multisegment_well_) {
|
if ( !well_ecl->isMultiSegment(time_step) || !param_.use_multisegment_well_) {
|
||||||
if ( GET_PROP_VALUE(TypeTag, EnablePolymerMW) ) {
|
if ( GET_PROP_VALUE(TypeTag, EnablePolymerMW) && well_ecl->isInjector(time_step) ) {
|
||||||
well_container.emplace_back(new StandardWellV<TypeTag>(well_ecl, time_step, wells(),
|
well_container.emplace_back(new StandardWellV<TypeTag>(well_ecl, time_step, wells(),
|
||||||
param_, *rateConverter_, pvtreg, numComponents() ) );
|
param_, *rateConverter_, pvtreg, numComponents() ) );
|
||||||
} else {
|
} else {
|
||||||
|
@ -177,6 +177,9 @@ namespace Opm
|
|||||||
return param_.matrix_add_well_contributions_;
|
return param_.matrix_add_well_contributions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update perforation water throughput based on solved water rate
|
||||||
|
virtual void updateWaterThroughput(const double dt, WellState& well_state) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// protected functions from the Base class
|
// protected functions from the Base class
|
||||||
@ -409,6 +412,17 @@ namespace Opm
|
|||||||
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step, const bool terminal_output,
|
||||||
WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) override;
|
WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) override;
|
||||||
|
|
||||||
|
EvalWell pskin(const double througput,
|
||||||
|
const EvalWell& water_velocity,
|
||||||
|
const EvalWell& poly_inj_conc) const;
|
||||||
|
|
||||||
|
EvalWell pskinwater(const double througput,
|
||||||
|
const EvalWell& water_velocity) const;
|
||||||
|
|
||||||
|
// return the injecting polymer molecular weight
|
||||||
|
EvalWell wpolymermw(const double throughput,
|
||||||
|
const EvalWell& water_velocity) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2810,4 +2810,127 @@ namespace Opm
|
|||||||
OpmLog::debug(msg);
|
OpmLog::debug(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TypeTag>
|
||||||
|
typename StandardWellV<TypeTag>::EvalWell
|
||||||
|
StandardWellV<TypeTag>::
|
||||||
|
pskinwater(const double throughput,
|
||||||
|
const EvalWell& water_velocity) const
|
||||||
|
{
|
||||||
|
if (!this->has_polymermw) {
|
||||||
|
OPM_THROW(std::runtime_error, "Polymermw is not activated, "
|
||||||
|
"while injecting skin pressure is requested" << name());
|
||||||
|
}
|
||||||
|
const int water_table_id = well_ecl_->getPolymerProperties(current_step_).m_skprwattable;
|
||||||
|
if (water_table_id <= 0) {
|
||||||
|
OPM_THROW(std::runtime_error, "Unused SKPRWAT table id used for well " << name());
|
||||||
|
}
|
||||||
|
const auto& water_table_func = PolymerModule::getSkprwatTable(water_table_id);
|
||||||
|
const EvalWell throughput_eval(throughput, numWellEq + numEq);
|
||||||
|
// the skin pressure when injecting water, which also means the polymer concentration is zero
|
||||||
|
EvalWell pskin_water(0.0, numWellEq + numEq);
|
||||||
|
water_table_func.eval(throughput_eval, water_velocity, pskin_water);
|
||||||
|
return pskin_water;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TypeTag>
|
||||||
|
typename StandardWellV<TypeTag>::EvalWell
|
||||||
|
StandardWellV<TypeTag>::
|
||||||
|
pskin(const double throughput,
|
||||||
|
const EvalWell& water_velocity,
|
||||||
|
const EvalWell& poly_inj_conc) const
|
||||||
|
{
|
||||||
|
// TODO: for the current implementation, without calculating the wellbore polymer concentration, poly_inj_conc can just be a scalar
|
||||||
|
// TODO: should we ignore the skin pressure when flowing from the reservoir into wellbore.
|
||||||
|
const double sign = water_velocity >= 0. ? 1.0 : -1.0;
|
||||||
|
const EvalWell water_velocity_magnitude = Opm::abs(water_velocity);
|
||||||
|
// TODO: we need to consider the direction of the water velocity here
|
||||||
|
if (!this->has_polymermw) {
|
||||||
|
OPM_THROW(std::runtime_error, "Polymermw is not activated, "
|
||||||
|
"while injecting skin pressure is requested" << name());
|
||||||
|
}
|
||||||
|
if (poly_inj_conc == 0.) {
|
||||||
|
// std::cout << " pksin calculated is " << sign * pskinwater(throughput, water_velocity_magnitude) << std::endl;
|
||||||
|
return sign * pskinwater(throughput, water_velocity_magnitude);
|
||||||
|
}
|
||||||
|
// otherwise, we need to use the skin pressure from polymer injection
|
||||||
|
// currently, we do not consider the reference concentration table. When there is polymer
|
||||||
|
// injection, we use SKPRPOLY table provided.
|
||||||
|
// TODO: we might need to do the interpolation when the polymer injection concentration
|
||||||
|
// is different from the reference concentration of the table.
|
||||||
|
const int polymer_table_id = well_ecl_->getPolymerProperties(current_step_).m_skprpolytable;
|
||||||
|
if (polymer_table_id <= 0) {
|
||||||
|
OPM_THROW(std::runtime_error, "Unavailable SKPRPOLY table id used for well " << name());
|
||||||
|
}
|
||||||
|
const auto& skprpolytable = PolymerModule::getSkprpolyTable(polymer_table_id);
|
||||||
|
// TODO: eventually it should be used
|
||||||
|
const double referene_concentration = skprpolytable.refConcentration;
|
||||||
|
const EvalWell throughput_eval(throughput, numWellEq + numEq);
|
||||||
|
// the skin pressure when injecting water, which also means the polymer concentration is zero
|
||||||
|
EvalWell pskin_poly(0.0, numWellEq + numEq);
|
||||||
|
skprpolytable.table_func.eval(throughput_eval, water_velocity_magnitude, pskin_poly);
|
||||||
|
if (poly_inj_conc == referene_concentration) {
|
||||||
|
return sign * pskin_poly;
|
||||||
|
}
|
||||||
|
// poly_inj_conc != reference concentration of the table, then some interpolation will be required
|
||||||
|
const EvalWell pskin_water = pskinwater(throughput, water_velocity_magnitude);
|
||||||
|
const EvalWell pskin = pskin_water + (pskin_poly - pskin_water) / referene_concentration * poly_inj_conc;
|
||||||
|
return sign * pskin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TypeTag>
|
||||||
|
typename StandardWellV<TypeTag>::EvalWell
|
||||||
|
StandardWellV<TypeTag>::
|
||||||
|
wpolymermw(const double throughput,
|
||||||
|
const EvalWell& water_velocity) const
|
||||||
|
{
|
||||||
|
if (!this->has_polymermw) {
|
||||||
|
OPM_THROW(std::runtime_error, "Polymermw is not activated, "
|
||||||
|
"while injecting polymer molecular weight is requested" << name());
|
||||||
|
}
|
||||||
|
const int table_id = well_ecl_->getPolymerProperties(current_step_).m_plymwinjtable;
|
||||||
|
const auto& table_func = PolymerModule::getPlymwinjTable(table_id);
|
||||||
|
// TODO: more likely we can use extrapolation for the throughput while not for the velocity
|
||||||
|
// TODO: basically for velocity, we need to request a new table when it exceeds the velocity range
|
||||||
|
// TODO: from the table, we should give a clear message for that
|
||||||
|
const EvalWell throughput_eval(throughput, numWellEq + numEq);
|
||||||
|
EvalWell molecular_weight(0., numWellEq + numEq);
|
||||||
|
if (wpolymer() == 0.) { // not injecting polymer
|
||||||
|
return molecular_weight;
|
||||||
|
}
|
||||||
|
table_func.eval(throughput_eval, Opm::abs(water_velocity), molecular_weight);
|
||||||
|
return molecular_weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TypeTag>
|
||||||
|
void
|
||||||
|
StandardWellV<TypeTag>::
|
||||||
|
updateWaterThroughput(const double dt, WellState &well_state) const
|
||||||
|
{
|
||||||
|
if (well_type_ == INJECTOR) {
|
||||||
|
for (int perf = 0; perf < number_of_perforations_; ++perf) {
|
||||||
|
const double perf_water_vel = primary_variables_[Bhp + 1 + perf];
|
||||||
|
// we do not consider the formation damage due to water flowing from reservoir into wellbore
|
||||||
|
if (perf_water_vel > 0.) {
|
||||||
|
well_state.perfThroughput()[first_perf_ + perf] += perf_water_vel * dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user