mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-12-26 01:01:00 -06:00
support REIN for solvent
This commit is contained in:
parent
0b96b31d8c
commit
c21428419a
@ -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);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user