support REIN for solvent

This commit is contained in:
Tor Harald Sandve 2019-09-23 15:15:55 +02:00
parent 0b96b31d8c
commit c21428419a
6 changed files with 134 additions and 15 deletions

View File

@ -383,6 +383,14 @@ namespace Opm {
void actionOnBrokenConstraints(const Group2& group, const Group2::InjectionCMode& newControl, const int reportStepIdx, Opm::DeferredLogger& deferred_logger);
WellInterfacePtr getWell(const std::string& well_name) const;
void updateWsolvent(const Group2& group, const Schedule& schedule, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellState);
void setWsolvent(const Group2& group, const Schedule& schedule, const int reportStepIdx, double wsolvent);
};

View File

@ -407,6 +407,9 @@ namespace Opm {
}
const Group2& fieldGroup = schedule().getGroup2("FIELD", reportStepIdx);
wellGroupHelpers::updateGuideRateForGroups(fieldGroup, schedule(), phase_usage_, reportStepIdx, simulationTime, guideRate_.get(), well_state_);
// compute wsolvent fraction for REIN wells
updateWsolvent(fieldGroup, schedule(), reportStepIdx, well_state_);
}
@ -476,10 +479,10 @@ namespace Opm {
// update the rate converter with current averages pressures etc in
rateConverter_->template defineState<ElementContext>(ebosSimulator_);
const int reportStepIdx = ebosSimulator_.episodeIndex();
// calculate the well potentials
try {
std::vector<double> well_potentials;
const int reportStepIdx = ebosSimulator_.episodeIndex();
computeWellPotentials(well_potentials, reportStepIdx, local_deferredLogger);
} catch ( std::runtime_error& e ) {
const std::string msg = "A zero well potential is returned for output purposes. ";
@ -492,8 +495,6 @@ namespace Opm {
global_deferredLogger.logMessages();
}
}
@ -1580,6 +1581,26 @@ namespace Opm {
return *well_ecl;
}
template<typename TypeTag>
typename BlackoilWellModel<TypeTag>::WellInterfacePtr
BlackoilWellModel<TypeTag>::
getWell(const std::string& well_name) const
{
// finding the iterator of the well in wells_ecl
auto well = std::find_if(well_container_.begin(),
well_container_.end(),
[&well_name](const WellInterfacePtr& elem)->bool {
return elem->name() == well_name;
});
assert(well != well_container_.end());
return *well;
}
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
@ -1823,5 +1844,50 @@ namespace Opm {
wellGroupHelpers::setGroupControl(group, schedule(), reportStepIdx, /*isInjector*/true, well_state);
}
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
updateWsolvent(const Group2& group, const Schedule& schedule, const int reportStepIdx, const WellStateFullyImplicitBlackoil& wellState) {
for (const std::string& groupName : group.groups()) {
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
updateWsolvent(groupTmp, schedule, reportStepIdx, wellState);
}
if (group.isProductionGroup())
return;
const Group2::InjectionCMode& currentGroupControl = wellState.currentInjectionGroupControl(group.name());
if( currentGroupControl == Group2::InjectionCMode::REIN ) {
int gasPos = phase_usage_.phase_pos[BlackoilPhases::Vapour];
double gasProductionRate = wellGroupHelpers::sumWellRates(group, schedule, wellState, reportStepIdx, gasPos, /*isInjector*/false);
double solventProductionRate = wellGroupHelpers::sumSolventRates(group, schedule, wellState, reportStepIdx, /*isInjector*/false);
double wsolvent = 0.0;
if (std::abs(gasProductionRate) > 1e-6)
wsolvent = solventProductionRate / gasProductionRate;
setWsolvent(group, schedule, reportStepIdx, wsolvent);
}
}
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
setWsolvent(const Group2& group, const Schedule& schedule, const int reportStepIdx, double wsolvent) {
for (const std::string& groupName : group.groups()) {
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
setWsolvent(groupTmp, schedule, reportStepIdx, wsolvent);
}
for (const std::string& wellName : group.wells()) {
const auto& wellTmp = schedule.getWell2(wellName, reportStepIdx);
if (wellTmp.getStatus() == Well2::Status::SHUT)
continue;
auto well = getWell(wellName);
well->setWsolvent(wsolvent);
}
}
} // namespace Opm

View File

@ -1028,7 +1028,7 @@ namespace Opm
productionRate += wellGroupHelpers::sumWellRates(group, schedule, well_state, current_step_, phasePos, /*isInjector*/false);
productionRate /= efficiencyFactor;
double target = std::max(0.0, (groupcontrols.target_reinj_fraction*productionRate - groupTargetReduction));
control_eq = getWQTotal() - fraction * target;
control_eq = getWQTotal() - fraction * target;
break;
}
case Group2::InjectionCMode::VREP:

View File

@ -171,6 +171,38 @@ namespace Opm {
return sumWellPhaseRates(wellState.wellReservoirRates(), group, schedule, wellState, reportStepIdx, phasePos, injector);
}
inline double sumSolventRates(const Group2& group, const Schedule& schedule, const WellStateFullyImplicitBlackoil& wellState, const int reportStepIdx, const bool injector) {
double rate = 0.0;
for (const std::string& groupName : group.groups()) {
const Group2& groupTmp = schedule.getGroup2(groupName, reportStepIdx);
rate += groupTmp.getGroupEfficiencyFactor()*sumSolventRates(groupTmp, schedule, wellState, reportStepIdx, injector);
}
const auto& end = wellState.wellMap().end();
for (const std::string& wellName : group.wells()) {
const auto& it = wellState.wellMap().find( wellName );
if (it == end) // the well is not found
continue;
int well_index = it->second[0];
const auto& wellEcl = schedule.getWell2(wellName, reportStepIdx);
//only count producers or injectors
if ( (wellEcl.isProducer() && injector) || (wellEcl.isInjector() && !injector))
continue;
if (wellEcl.getStatus() == Well2::Status::SHUT)
continue;
double factor = wellEcl.getEfficiencyFactor();
if (injector)
rate += factor * wellState.solventWellRate(well_index);
else
rate -= factor * wellState.solventWellRate(well_index);
}
return rate;
}
inline void updateGuideRateForGroups(const Group2& group, const Schedule& schedule, const PhaseUsage& pu, const int reportStepIdx, const double& simTime, GuideRate* guideRate, WellStateFullyImplicitBlackoil& wellState) {
for (const std::string& groupName : group.groups()) {

View File

@ -274,6 +274,9 @@ namespace Opm
return wellIsStopped_;
}
void setWsolvent(const double wsolvent);
protected:
// to indicate a invalid completion
@ -373,6 +376,8 @@ namespace Opm
bool wellIsStopped_;
double wsolvent_;
const PhaseUsage& phaseUsage() const;
int flowPhaseToEbosCompIdx( const int phaseIdx ) const;
@ -473,6 +478,8 @@ namespace Opm
bool checkConstraints(WellState& well_state, const SummaryState& summaryState);
};

View File

@ -112,7 +112,14 @@ namespace Opm
wellIsStopped_ = true;
}
wsolvent_ = 0.0;
if (has_solvent && well.isInjector()) {
auto injectorType = well_ecl_.injectorType();
if (injectorType == Well2::InjectorType::GAS) {
wsolvent_ = well_ecl_.getSolventFraction();
}
}
}
template<typename TypeTag>
@ -308,18 +315,17 @@ namespace Opm
WellInterface<TypeTag>::
wsolvent() const
{
if (!has_solvent) {
return 0.0;
}
return wsolvent_;
}
auto injectorType = well_ecl_.injectorType();
if (injectorType == Well2::InjectorType::GAS) {
double solvent_fraction = well_ecl_.getSolventFraction();
return solvent_fraction;
} else {
// Not a gas injection well => no solvent.
return 0.0;
}
template<typename TypeTag>
void
WellInterface<TypeTag>::
setWsolvent(const double wsolvent)
{
wsolvent_ = wsolvent;
}