mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
adding functions to calcuate between thp and bhp
to reduce some code duplication in StandardWell
This commit is contained in:
parent
8a12ec677f
commit
fe3d2f91e0
@ -285,6 +285,11 @@ namespace Opm
|
|||||||
const double initial_bhp, // bhp from BHP constraints
|
const double initial_bhp, // bhp from BHP constraints
|
||||||
const std::vector<double>& initial_potential) const;
|
const std::vector<double>& initial_potential) const;
|
||||||
|
|
||||||
|
template <class ValueType>
|
||||||
|
ValueType calculateBhpFromThp(const std::vector<ValueType>& rates, const int control_index) const;
|
||||||
|
|
||||||
|
double calculateThpFromBhp(const std::vector<double>& rates, const int control_index, const double bhp) const;
|
||||||
|
|
||||||
// get the mobility for specific perforation
|
// get the mobility for specific perforation
|
||||||
void getMobility(const Simulator& ebosSimulator,
|
void getMobility(const Simulator& ebosSimulator,
|
||||||
const int perf,
|
const int perf,
|
||||||
|
@ -132,40 +132,19 @@ namespace Opm
|
|||||||
return bhp;
|
return bhp;
|
||||||
} else if (well_controls_get_current_type(wc) == THP) {
|
} else if (well_controls_get_current_type(wc) == THP) {
|
||||||
const int control = well_controls_get_current(wc);
|
const int control = well_controls_get_current(wc);
|
||||||
const double thp = well_controls_get_current_target(wc);
|
|
||||||
const double alq = well_controls_iget_alq(wc, control);
|
|
||||||
const int table_id = well_controls_iget_vfp(wc, control);
|
|
||||||
EvalWell aqua = 0.0;
|
|
||||||
EvalWell liquid = 0.0;
|
|
||||||
EvalWell vapour = 0.0;
|
|
||||||
EvalWell bhp = 0.0;
|
|
||||||
double vfp_ref_depth = 0.0;
|
|
||||||
|
|
||||||
const Opm::PhaseUsage& pu = phaseUsage();
|
const Opm::PhaseUsage& pu = phaseUsage();
|
||||||
|
std::vector<EvalWell> rates(3, 0.0);
|
||||||
if (active()[ Water ]) {
|
if (active()[ Water ]) {
|
||||||
aqua = getQs(pu.phase_pos[ Water]);
|
rates[ Water ]= getQs(pu.phase_pos[ Water]);
|
||||||
}
|
}
|
||||||
if (active()[ Oil ]) {
|
if (active()[ Oil ]) {
|
||||||
liquid = getQs(pu.phase_pos[ Oil ]);
|
rates[ Oil ] = getQs(pu.phase_pos[ Oil ]);
|
||||||
}
|
}
|
||||||
if (active()[ Gas ]) {
|
if (active()[ Gas ]) {
|
||||||
vapour = getQs(pu.phase_pos[ Gas ]);
|
rates[ Gas ] = getQs(pu.phase_pos[ Gas ]);
|
||||||
}
|
}
|
||||||
if (well_type_ == INJECTOR) {
|
return calculateBhpFromThp(rates, control);
|
||||||
bhp = vfp_properties_->getInj()->bhp(table_id, aqua, liquid, vapour, thp);
|
|
||||||
vfp_ref_depth = vfp_properties_->getInj()->getTable(table_id)->getDatumDepth();
|
|
||||||
} else {
|
|
||||||
bhp = vfp_properties_->getProd()->bhp(table_id, aqua, liquid, vapour, thp, alq);
|
|
||||||
vfp_ref_depth = vfp_properties_->getProd()->getTable(table_id)->getDatumDepth();
|
|
||||||
}
|
|
||||||
|
|
||||||
// pick the density in the top layer
|
|
||||||
const double rho = perf_densities_[0];
|
|
||||||
const double well_ref_depth = ref_depth_;
|
|
||||||
const double dp = wellhelpers::computeHydrostaticCorrection(well_ref_depth, vfp_ref_depth, rho, gravity_);
|
|
||||||
bhp -= dp;
|
|
||||||
return bhp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return well_variables_[XvarWell];
|
return well_variables_[XvarWell];
|
||||||
@ -955,49 +934,20 @@ namespace Opm
|
|||||||
if (well_controls_iget_type(wc, current) == THP) {
|
if (well_controls_iget_type(wc, current) == THP) {
|
||||||
|
|
||||||
// Calculate bhp from thp control and well rates
|
// Calculate bhp from thp control and well rates
|
||||||
double aqua = 0.0;
|
std::vector<double> rates(3, 0.0); // the vfp related only supports three phases for the moment
|
||||||
double liquid = 0.0;
|
|
||||||
double vapour = 0.0;
|
|
||||||
|
|
||||||
const Opm::PhaseUsage& pu = phaseUsage();
|
const Opm::PhaseUsage& pu = phaseUsage();
|
||||||
|
|
||||||
if (active()[ Water ]) {
|
if (active()[ Water ]) {
|
||||||
aqua = well_state.wellRates()[index_of_well_ * np + pu.phase_pos[ Water ] ];
|
rates[ Water ] = well_state.wellRates()[index_of_well_ * np + pu.phase_pos[ Water ] ];
|
||||||
}
|
}
|
||||||
if (active()[ Oil ]) {
|
if (active()[ Oil ]) {
|
||||||
liquid = well_state.wellRates()[index_of_well_ * np + pu.phase_pos[ Oil ] ];
|
rates[ Oil ]= well_state.wellRates()[index_of_well_ * np + pu.phase_pos[ Oil ] ];
|
||||||
}
|
}
|
||||||
if (active()[ Gas ]) {
|
if (active()[ Gas ]) {
|
||||||
vapour = well_state.wellRates()[index_of_well_ * np + pu.phase_pos[ Gas ] ];
|
rates[ Gas ]= well_state.wellRates()[index_of_well_ * np + pu.phase_pos[ Gas ] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
const int vfp = well_controls_iget_vfp(wc, current);
|
well_state.bhp()[index_of_well_] = calculateBhpFromThp(rates, current);
|
||||||
const double& thp = well_controls_iget_target(wc, current);
|
|
||||||
const double& alq = well_controls_iget_alq(wc, current);
|
|
||||||
|
|
||||||
// Set *BHP* target by calculating bhp from THP
|
|
||||||
const WellType& well_type = well_type_;
|
|
||||||
// pick the density in the top layer
|
|
||||||
const double rho = perf_densities_[0];
|
|
||||||
const double well_ref_depth = ref_depth_;
|
|
||||||
|
|
||||||
if (well_type == INJECTOR) {
|
|
||||||
const double vfp_ref_depth = vfp_properties_->getInj()->getTable(vfp)->getDatumDepth();
|
|
||||||
|
|
||||||
const double dp = wellhelpers::computeHydrostaticCorrection(well_ref_depth, vfp_ref_depth, rho, gravity_);
|
|
||||||
|
|
||||||
well_state.bhp()[index_of_well_] = vfp_properties_->getInj()->bhp(vfp, aqua, liquid, vapour, thp) - dp;
|
|
||||||
}
|
|
||||||
else if (well_type == PRODUCER) {
|
|
||||||
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(vfp)->getDatumDepth();
|
|
||||||
|
|
||||||
const double dp = wellhelpers::computeHydrostaticCorrection(well_ref_depth, vfp_ref_depth, rho, gravity_);
|
|
||||||
|
|
||||||
well_state.bhp()[index_of_well_] = vfp_properties_->getProd()->bhp(vfp, aqua, liquid, vapour, thp, alq) - dp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
OPM_THROW(std::logic_error, "Expected INJECTOR or PRODUCER well");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1056,42 +1006,21 @@ namespace Opm
|
|||||||
double vapour = 0.0;
|
double vapour = 0.0;
|
||||||
|
|
||||||
const Opm::PhaseUsage& pu = phaseUsage();
|
const Opm::PhaseUsage& pu = phaseUsage();
|
||||||
|
std::vector<double> rates(3, 0.0);
|
||||||
|
|
||||||
if (active()[ Water ]) {
|
if (active()[ Water ]) {
|
||||||
aqua = well_state.wellRates()[index_of_well_*np + pu.phase_pos[ Water ] ];
|
rates[ Water ] = well_state.wellRates()[index_of_well_*np + pu.phase_pos[ Water ] ];
|
||||||
}
|
}
|
||||||
if (active()[ Oil ]) {
|
if (active()[ Oil ]) {
|
||||||
liquid = well_state.wellRates()[index_of_well_*np + pu.phase_pos[ Oil ] ];
|
rates[ Oil ] = well_state.wellRates()[index_of_well_*np + pu.phase_pos[ Oil ] ];
|
||||||
}
|
}
|
||||||
if (active()[ Gas ]) {
|
if (active()[ Gas ]) {
|
||||||
vapour = well_state.wellRates()[index_of_well_*np + pu.phase_pos[ Gas ] ];
|
rates[ Gas ] = well_state.wellRates()[index_of_well_*np + pu.phase_pos[ Gas ] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
const double alq = well_controls_iget_alq(wc, ctrl_index);
|
const double bhp = well_state.bhp()[index_of_well_];
|
||||||
const int table_id = well_controls_iget_vfp(wc, ctrl_index);
|
|
||||||
|
|
||||||
const WellType& well_type = well_type_;
|
well_state.thp()[index_of_well_] = calculateThpFromBhp(rates, ctrl_index, bhp);
|
||||||
const double rho = perf_densities_[0];
|
|
||||||
const double well_ref_depth = ref_depth_;
|
|
||||||
if (well_type == INJECTOR) {
|
|
||||||
const double vfp_ref_depth = vfp_properties_->getInj()->getTable(table_id)->getDatumDepth();
|
|
||||||
|
|
||||||
const double dp = wellhelpers::computeHydrostaticCorrection(well_ref_depth, vfp_ref_depth, rho, gravity_);
|
|
||||||
|
|
||||||
const double bhp = well_state.bhp()[index_of_well_];
|
|
||||||
|
|
||||||
well_state.thp()[index_of_well_] = vfp_properties_->getInj()->thp(table_id, aqua, liquid, vapour, bhp + dp);
|
|
||||||
} else if (well_type == PRODUCER) {
|
|
||||||
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(table_id)->getDatumDepth();
|
|
||||||
|
|
||||||
const double dp = wellhelpers::computeHydrostaticCorrection(well_ref_depth, vfp_ref_depth, rho, gravity_);
|
|
||||||
|
|
||||||
const double bhp = well_state.bhp()[index_of_well_];
|
|
||||||
|
|
||||||
well_state.thp()[index_of_well_] = vfp_properties_->getProd()->thp(table_id, aqua, liquid, vapour, bhp + dp, alq);
|
|
||||||
} else {
|
|
||||||
OPM_THROW(std::logic_error, "Expected INJECTOR or PRODUCER well");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the THP control is found, we leave the loop now
|
// the THP control is found, we leave the loop now
|
||||||
@ -1150,51 +1079,23 @@ namespace Opm
|
|||||||
case THP: {
|
case THP: {
|
||||||
xw.thp()[well_index] = target;
|
xw.thp()[well_index] = target;
|
||||||
|
|
||||||
double aqua = 0.0;
|
const Opm::PhaseUsage& pu = phaseUsage();
|
||||||
double liquid = 0.0;
|
std::vector<double> rates(3, 0.0);
|
||||||
double vapour = 0.0;
|
|
||||||
|
|
||||||
const Opm::PhaseUsage& pu = *phase_usage_;
|
|
||||||
|
|
||||||
if (active()[ Water ]) {
|
if (active()[ Water ]) {
|
||||||
aqua = xw.wellRates()[well_index*np + pu.phase_pos[ Water ] ];
|
rates[ Water ] = xw.wellRates()[well_index*np + pu.phase_pos[ Water ] ];
|
||||||
}
|
}
|
||||||
if (active()[ Oil ]) {
|
if (active()[ Oil ]) {
|
||||||
liquid = xw.wellRates()[well_index*np + pu.phase_pos[ Oil ] ];
|
rates[ Oil ] = xw.wellRates()[well_index*np + pu.phase_pos[ Oil ] ];
|
||||||
}
|
}
|
||||||
if (active()[ Gas ]) {
|
if (active()[ Gas ]) {
|
||||||
vapour = xw.wellRates()[well_index*np + pu.phase_pos[ Gas ] ];
|
rates[ Gas ] = xw.wellRates()[well_index*np + pu.phase_pos[ Gas ] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
const int table_id = well_controls_iget_vfp(wc, current);
|
const int table_id = well_controls_iget_vfp(wc, current);
|
||||||
const double& thp = well_controls_iget_target(wc, current);
|
const double& thp = well_controls_iget_target(wc, current);
|
||||||
const double& alq = well_controls_iget_alq(wc, current);
|
const double& alq = well_controls_iget_alq(wc, current);
|
||||||
|
|
||||||
//Set *BHP* target by calculating bhp from THP
|
xw.bhp()[well_index] = calculateBhpFromThp(rates, current);
|
||||||
|
|
||||||
// pick the density in the top layer
|
|
||||||
const double rho = perf_densities_[0];
|
|
||||||
const double well_ref_depth = ref_depth_;
|
|
||||||
|
|
||||||
// TODO: make the following a function and we call it so many times.
|
|
||||||
if (well_type_ == INJECTOR) {
|
|
||||||
|
|
||||||
const double vfp_ref_depth = vfp_properties_->getInj()->getTable(table_id)->getDatumDepth();
|
|
||||||
|
|
||||||
const double dp = wellhelpers::computeHydrostaticCorrection(well_ref_depth, vfp_ref_depth, rho, gravity_);
|
|
||||||
|
|
||||||
xw.bhp()[well_index] = vfp_properties_->getInj()->bhp(table_id, aqua, liquid, vapour, thp) - dp;
|
|
||||||
}
|
|
||||||
else if (well_type_ == PRODUCER) {
|
|
||||||
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(table_id)->getDatumDepth();
|
|
||||||
|
|
||||||
const double dp = wellhelpers::computeHydrostaticCorrection(well_ref_depth, vfp_ref_depth, rho, gravity_);
|
|
||||||
|
|
||||||
xw.bhp()[well_index] = vfp_properties_->getProd()->bhp(table_id, aqua, liquid, vapour, thp, alq) - dp;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
OPM_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1868,43 +1769,25 @@ namespace Opm
|
|||||||
|
|
||||||
const Opm::PhaseUsage& pu = *phase_usage_;
|
const Opm::PhaseUsage& pu = *phase_usage_;
|
||||||
|
|
||||||
|
std::vector<double> rates(3, 0.0);
|
||||||
if (active()[ Water ]) {
|
if (active()[ Water ]) {
|
||||||
aqua = potentials[pu.phase_pos[ Water ] ];
|
rates[ Water ] = potentials[pu.phase_pos[ Water ] ];
|
||||||
}
|
}
|
||||||
if (active()[ Oil ]) {
|
if (active()[ Oil ]) {
|
||||||
liquid = potentials[pu.phase_pos[ Oil ] ];
|
rates[ Oil ] = potentials[pu.phase_pos[ Oil ] ];
|
||||||
}
|
}
|
||||||
if (active()[ Gas ]) {
|
if (active()[ Gas ]) {
|
||||||
vapour = potentials[pu.phase_pos[ Gas ] ];
|
rates[ Gas ] = potentials[pu.phase_pos[ Gas ] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
const int vfp = well_controls_iget_vfp(well_controls_, ctrl_index);
|
const double bhp_calculated = calculateBhpFromThp(rates, ctrl_index);
|
||||||
const double thp = well_controls_iget_target(well_controls_, ctrl_index);
|
|
||||||
const double alq = well_controls_iget_alq(well_controls_, ctrl_index);
|
|
||||||
|
|
||||||
// Calculating the BHP value based on THP
|
if (well_type_ == INJECTOR && bhp_calculated < bhp ) {
|
||||||
// TODO: check whether it is always correct to do calculation based on the depth of the first perforation.
|
bhp = bhp_calculated;
|
||||||
const double rho = perf_densities_[0]; // TODO: this item is the one keeping the function from WellInterface
|
|
||||||
const double well_ref_depth = ref_depth_;
|
|
||||||
if (well_type_ == INJECTOR) {
|
|
||||||
const double vfp_ref_depth = vfp_properties_->getInj()->getTable(vfp)->getDatumDepth();
|
|
||||||
const double dp = wellhelpers::computeHydrostaticCorrection(well_ref_depth, vfp_ref_depth, rho, gravity_);
|
|
||||||
const double bhp_calculated = vfp_properties_->getInj()->bhp(vfp, aqua, liquid, vapour, thp) - dp;
|
|
||||||
// apply the strictest of the bhp controlls i.e. smallest bhp for injectors
|
|
||||||
if (bhp_calculated < bhp) {
|
|
||||||
bhp = bhp_calculated;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (well_type_ == PRODUCER) {
|
|
||||||
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(vfp)->getDatumDepth();
|
if (well_type_ == PRODUCER && bhp_calculated > bhp) {
|
||||||
const double dp = wellhelpers::computeHydrostaticCorrection(well_ref_depth, vfp_ref_depth, rho, gravity_);
|
bhp = bhp_calculated;
|
||||||
const double bhp_calculated = vfp_properties_->getProd()->bhp(vfp, aqua, liquid, vapour, thp, alq) - dp;
|
|
||||||
// apply the strictest of the bhp controlls i.e. largest bhp for producers
|
|
||||||
if (bhp_calculated > bhp) {
|
|
||||||
bhp = bhp_calculated;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
OPM_THROW(std::logic_error, "Expected PRODUCER or INJECTOR type of well");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2088,4 +1971,95 @@ namespace Opm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TypeTag>
|
||||||
|
template<class ValueType>
|
||||||
|
ValueType
|
||||||
|
StandardWell<TypeTag>::
|
||||||
|
calculateBhpFromThp(const std::vector<ValueType>& rates,
|
||||||
|
const int control_index) const
|
||||||
|
{
|
||||||
|
assert(int(rates.size()) == 3); // the vfp related only supports three phases now.
|
||||||
|
|
||||||
|
const ValueType aqua = rates[Water];
|
||||||
|
const ValueType liquid = rates[Oil];
|
||||||
|
const ValueType vapour = rates[Gas];
|
||||||
|
|
||||||
|
const int vfp = well_controls_iget_vfp(well_controls_, control_index);
|
||||||
|
const double& thp = well_controls_iget_target(well_controls_, control_index);
|
||||||
|
const double& alq = well_controls_iget_alq(well_controls_, control_index);
|
||||||
|
|
||||||
|
// pick the density in the top layer
|
||||||
|
const double rho = perf_densities_[0];
|
||||||
|
|
||||||
|
ValueType bhp = 0.;
|
||||||
|
if (well_type_ == INJECTOR) {
|
||||||
|
const double vfp_ref_depth = vfp_properties_->getInj()->getTable(vfp)->getDatumDepth();
|
||||||
|
|
||||||
|
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);
|
||||||
|
|
||||||
|
bhp = vfp_properties_->getInj()->bhp(vfp, aqua, liquid, vapour, thp) - dp;
|
||||||
|
}
|
||||||
|
else if (well_type_ == PRODUCER) {
|
||||||
|
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(vfp)->getDatumDepth();
|
||||||
|
|
||||||
|
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);
|
||||||
|
|
||||||
|
bhp = vfp_properties_->getProd()->bhp(vfp, aqua, liquid, vapour, thp, alq) - dp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
OPM_THROW(std::logic_error, "Expected INJECTOR or PRODUCER well");
|
||||||
|
}
|
||||||
|
|
||||||
|
return bhp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TypeTag>
|
||||||
|
double
|
||||||
|
StandardWell<TypeTag>::
|
||||||
|
calculateThpFromBhp(const std::vector<double>& rates,
|
||||||
|
const int control_index,
|
||||||
|
const double bhp) const
|
||||||
|
{
|
||||||
|
assert(int(rates.size()) == 3); // the vfp related only supports three phases now.
|
||||||
|
|
||||||
|
const double aqua = rates[Water];
|
||||||
|
const double liquid = rates[Oil];
|
||||||
|
const double vapour = rates[Gas];
|
||||||
|
|
||||||
|
const int vfp = well_controls_iget_vfp(well_controls_, control_index);
|
||||||
|
const double& alq = well_controls_iget_alq(well_controls_, control_index);
|
||||||
|
|
||||||
|
// pick the density in the top layer
|
||||||
|
const double rho = perf_densities_[0];
|
||||||
|
|
||||||
|
double thp = 0.0;
|
||||||
|
if (well_type_ == INJECTOR) {
|
||||||
|
const double vfp_ref_depth = vfp_properties_->getInj()->getTable(vfp)->getDatumDepth();
|
||||||
|
|
||||||
|
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);
|
||||||
|
|
||||||
|
thp = vfp_properties_->getInj()->thp(vfp, aqua, liquid, vapour, bhp + dp);
|
||||||
|
}
|
||||||
|
else if (well_type_ == PRODUCER) {
|
||||||
|
const double vfp_ref_depth = vfp_properties_->getProd()->getTable(vfp)->getDatumDepth();
|
||||||
|
|
||||||
|
const double dp = wellhelpers::computeHydrostaticCorrection(ref_depth_, vfp_ref_depth, rho, gravity_);
|
||||||
|
|
||||||
|
thp = vfp_properties_->getProd()->thp(vfp, aqua, liquid, vapour, bhp + dp, alq);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
OPM_THROW(std::logic_error, "Expected INJECTOR or PRODUCER well");
|
||||||
|
}
|
||||||
|
|
||||||
|
return thp;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user