Correct Logging for Black Oil Well Model for parallel runs using DeferredLogger

This commit is contained in:
Franz G. Fuchs 2019-02-03 08:13:11 +01:00
parent e39f68787f
commit 42f6f4d784
10 changed files with 274 additions and 191 deletions

View File

@ -348,7 +348,7 @@ namespace Opm {
void updateWellControls();
void updateGroupControls();
void updateGroupControls(Opm::DeferredLogger& deferred_logger);
// setting the well_solutions_ based on well_state.
void updatePrimaryVariables();
@ -379,7 +379,7 @@ namespace Opm {
/// at the beginning of the time step and no derivatives are included in these quantities
void calculateExplicitQuantities() const;
SimulatorReport solveWellEq(const double dt);
SimulatorReport solveWellEq(const double dt, Opm::DeferredLogger& deferred_logger);
void initPrimaryVariablesEvaluation() const;
@ -392,11 +392,11 @@ namespace Opm {
void resetWellControlFromState() const;
void assembleWellEq(const double dt);
void assembleWellEq(const double dt, Opm::DeferredLogger& deferred_logger);
// some preparation work, mostly related to group control and RESV,
// at the beginning of each time step (Not report step)
void prepareTimeStep();
void prepareTimeStep(Opm::DeferredLogger& deferred_logger);
void prepareGroupControl();

View File

@ -311,36 +311,35 @@ namespace Opm {
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::wellTesting(const int timeStepIdx, const double simulationTime) {
const auto& wtest_config = schedule().wtestConfig(timeStepIdx);
if (wtest_config.size() == 0) { // there is no WTEST request
return;
}
// average B factors are required for the convergence checking of well equations
// Note: this must be done on all processes, even those with
// no wells needing testing, otherwise we will have locking.
std::vector< Scalar > B_avg(numComponents(), Scalar() );
computeAverageFormationFactor(B_avg);
Opm::DeferredLogger local_deferredLogger;
const auto& wtest_config = schedule().wtestConfig(timeStepIdx);
if (wtest_config.size() != 0) { // there is a WTEST request
const auto& wellsForTesting = wellTestState_.updateWell(wtest_config, simulationTime);
for (const auto& testWell : wellsForTesting) {
const std::string& well_name = testWell.first;
// average B factors are required for the convergence checking of well equations
// Note: this must be done on all processes, even those with
// no wells needing testing, otherwise we will have locking.
std::vector< Scalar > B_avg(numComponents(), Scalar() );
computeAverageFormationFactor(B_avg);
// this is the well we will test
WellInterfacePtr well = createWellForWellTest(well_name, timeStepIdx);
const auto& wellsForTesting = wellTestState_.updateWell(wtest_config, simulationTime);
for (const auto& testWell : wellsForTesting) {
const std::string& well_name = testWell.first;
// some preparation before the well can be used
well->init(&phase_usage_, depth_, gravity_, number_of_cells_);
const WellNode& well_node = wellCollection().findWellNode(well_name);
const double well_efficiency_factor = well_node.getAccumulativeEfficiencyFactor();
well->setWellEfficiencyFactor(well_efficiency_factor);
well->setVFPProperties(vfp_properties_.get());
// this is the well we will test
WellInterfacePtr well = createWellForWellTest(well_name, timeStepIdx);
const WellTestConfig::Reason testing_reason = testWell.second;
// some preparation before the well can be used
well->init(&phase_usage_, depth_, gravity_, number_of_cells_);
const WellNode& well_node = wellCollection().findWellNode(well_name);
const double well_efficiency_factor = well_node.getAccumulativeEfficiencyFactor();
well->setWellEfficiencyFactor(well_efficiency_factor);
well->setVFPProperties(vfp_properties_.get());
well->wellTesting(ebosSimulator_, B_avg, simulationTime, timeStepIdx,
testing_reason, well_state_, wellTestState_, local_deferredLogger);
const WellTestConfig::Reason testing_reason = testWell.second;
well->wellTesting(ebosSimulator_, B_avg, simulationTime, timeStepIdx,
testing_reason, well_state_, wellTestState_, local_deferredLogger);
}
}
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
if (terminal_output_) {
@ -366,6 +365,8 @@ namespace Opm {
void
BlackoilWellModel<TypeTag>::
timeStepSucceeded(const double& simulationTime, const double dt) {
Opm::DeferredLogger local_deferredLogger;
// TODO: when necessary
rateConverter_->template defineState<ElementContext>(ebosSimulator_);
for (const auto& well : well_container_) {
@ -386,9 +387,15 @@ namespace Opm {
catch ( std::runtime_error& e )
{
const std::string msg = "A zero well potential is returned for output purposes. ";
OpmLog::warning("WELL_POTENTIAL_CALCULATION_FAILED", msg);
local_deferredLogger.warning("WELL_POTENTIAL_CALCULATION_FAILED", msg);
}
previous_well_state_ = well_state_;
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
if (terminal_output_) {
global_deferredLogger.logMessages();
}
}
@ -621,18 +628,19 @@ namespace Opm {
const double dt)
{
last_report_ = SimulatorReport();
if ( ! wellsActive() ) {
return;
}
Opm::DeferredLogger local_deferredLogger;
updatePerforationIntensiveQuantities();
if (iterationIdx == 0) {
calculateExplicitQuantities();
prepareTimeStep();
prepareTimeStep(local_deferredLogger);
}
updateWellControls();
@ -641,20 +649,26 @@ namespace Opm {
if (param_.solve_welleq_initially_ && iterationIdx == 0) {
// solve the well equations as a pre-processing step
last_report_ = solveWellEq(dt);
last_report_ = solveWellEq(dt, local_deferredLogger);
if (initial_step_) {
// update the explicit quantities to get the initial fluid distribution in the well correct.
calculateExplicitQuantities();
prepareTimeStep();
last_report_ = solveWellEq(dt);
prepareTimeStep(local_deferredLogger);
last_report_ = solveWellEq(dt, local_deferredLogger);
initial_step_ = false;
}
// TODO: should we update the explicit related here again, or even prepareTimeStep().
// basically, this is a more updated state from the solveWellEq based on fixed
// reservoir state, will tihs be a better place to inialize the explict information?
}
assembleWellEq(dt);
assembleWellEq(dt, local_deferredLogger);
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
if (terminal_output_) {
global_deferredLogger.logMessages();
}
last_report_.converged = true;
}
@ -666,10 +680,10 @@ namespace Opm {
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
assembleWellEq(const double dt)
assembleWellEq(const double dt, Opm::DeferredLogger& deferred_logger)
{
for (auto& well : well_container_) {
well->assembleWellEq(ebosSimulator_, dt, well_state_);
well->assembleWellEq(ebosSimulator_, dt, well_state_, deferred_logger);
}
}
@ -817,7 +831,7 @@ namespace Opm {
template<typename TypeTag>
SimulatorReport
BlackoilWellModel<TypeTag>::
solveWellEq(const double dt)
solveWellEq(const double dt, Opm::DeferredLogger& deferred_logger)
{
WellState well_state0 = well_state_;
@ -830,7 +844,7 @@ namespace Opm {
int it = 0;
bool converged;
do {
assembleWellEq(dt);
assembleWellEq(dt, deferred_logger);
const auto report = getWellConvergence(B_avg);
converged = report.converged();
@ -862,12 +876,12 @@ namespace Opm {
} while (it < max_iter);
if (converged) {
if ( terminal_output_ ) {
OpmLog::debug("Well equation solution gets converged with " + std::to_string(it) + " iterations");
if (terminal_output_) {
deferred_logger.debug("Well equation solution gets converged with " + std::to_string(it) + " iterations");
}
} else {
if ( terminal_output_ ) {
OpmLog::debug("Well equation solution failed in getting converged with " + std::to_string(it) + " iterations");
if (terminal_output_) {
deferred_logger.debug("Well equation solution failed in getting converged with " + std::to_string(it) + " iterations");
}
well_state_ = well_state0;
@ -905,11 +919,13 @@ namespace Opm {
ConvergenceReport report = gatherConvergenceReport(local_report);
// Log debug messages for NaN or too large residuals.
for (const auto& f : report.wellFailures()) {
if (f.severity() == ConvergenceReport::Severity::NotANumber) {
OpmLog::debug("NaN residual found with phase " + std::to_string(f.phase()) + " for well " + f.wellName());
} else if (f.severity() == ConvergenceReport::Severity::TooLarge) {
OpmLog::debug("Too large residual found with phase " + std::to_string(f.phase()) + " for well " + f.wellName());
if (terminal_output_) {
for (const auto& f : report.wellFailures()) {
if (f.severity() == ConvergenceReport::Severity::NotANumber) {
OpmLog::debug("NaN residual found with phase " + std::to_string(f.phase()) + " for well " + f.wellName());
} else if (f.severity() == ConvergenceReport::Severity::TooLarge) {
OpmLog::debug("Too large residual found with phase " + std::to_string(f.phase()) + " for well " + f.wellName());
}
}
}
@ -951,12 +967,13 @@ namespace Opm {
well->updateWellControl(ebosSimulator_, well_state_, local_deferredLogger);
}
updateGroupControls(local_deferredLogger);
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
if (terminal_output_) {
global_deferredLogger.logMessages();
}
updateGroupControls();
}
@ -968,8 +985,13 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
updateWellTestState(const double& simulationTime, WellTestState& wellTestState) const
{
Opm::DeferredLogger local_deferredLogger;
for (const auto& well : well_container_) {
well->updateWellTestState(well_state_, simulationTime, /*writeMessageToOPMLog=*/ true, wellTestState);
well->updateWellTestState(well_state_, simulationTime, /*writeMessageToOPMLog=*/ true, wellTestState, local_deferredLogger);
}
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
if (terminal_output_) {
global_deferredLogger.logMessages();
}
}
@ -980,6 +1002,7 @@ namespace Opm {
BlackoilWellModel<TypeTag>::
computeWellPotentials(std::vector<double>& well_potentials)
{
Opm::DeferredLogger local_deferredLogger;
// number of wells and phases
const int nw = numWells();
const int np = numPhases();
@ -998,7 +1021,7 @@ namespace Opm {
if (needed_for_output || wellCollection().requireWellPotentials())
{
std::vector<double> potentials;
well->computeWellPotentials(ebosSimulator_, well_state_, potentials);
well->computeWellPotentials(ebosSimulator_, well_state_, potentials, local_deferredLogger);
// putting the sucessfully calculated potentials to the well_potentials
for (int p = 0; p < np; ++p) {
@ -1010,6 +1033,11 @@ namespace Opm {
// Store it in the well state
well_state_.wellPotentials() = well_potentials;
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
if (terminal_output_) {
global_deferredLogger.logMessages();
}
}
@ -1019,7 +1047,7 @@ namespace Opm {
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
prepareTimeStep()
prepareTimeStep(Opm::DeferredLogger& deferred_logger)
{
if ( wellCollection().havingVREPGroups() ) {
@ -1037,7 +1065,7 @@ namespace Opm {
prepareGroupControl();
for (const auto& well : well_container_) {
well->checkWellOperability(ebosSimulator_, well_state_);
well->checkWellOperability(ebosSimulator_, well_state_, deferred_logger);
}
// since the controls are all updated, we should update well_state accordingly
@ -1050,7 +1078,7 @@ namespace Opm {
if (!well->isOperable() ) continue;
if (well_state_.effectiveEventsOccurred(w) ) {
well->updateWellStateWithTarget(ebosSimulator_, well_state_);
well->updateWellStateWithTarget(ebosSimulator_, well_state_, deferred_logger);
}
// there is no new well control change input within a report step,
@ -1275,7 +1303,7 @@ namespace Opm {
template<typename TypeTag>
void
BlackoilWellModel<TypeTag>::
updateGroupControls()
updateGroupControls(Opm::DeferredLogger& deferred_logger)
{
if (wellCollection().groupControlActive()) {
@ -1302,7 +1330,7 @@ namespace Opm {
// TODO: we should only do the well is involved in the update group targets
for (auto& well : well_container_) {
well->updateWellStateWithTarget(ebosSimulator_, well_state_);
well->updateWellStateWithTarget(ebosSimulator_, well_state_, deferred_logger);
well->updatePrimaryVariables(well_state_);
}
}

View File

@ -114,11 +114,13 @@ namespace Opm
virtual void assembleWellEq(const Simulator& ebosSimulator,
const double dt,
WellState& well_state) override;
WellState& well_state,
Opm::DeferredLogger& deferred_logger) override;
/// updating the well state based the current control mode
virtual void updateWellStateWithTarget(const Simulator& ebos_simulator,
WellState& well_state) const override;
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const override;
/// check whether the well equations get converged for this well
virtual ConvergenceReport getWellConvergence(const std::vector<double>& B_avg) const override;
@ -136,7 +138,8 @@ namespace Opm
/// computing the well potentials for group control
virtual void computeWellPotentials(const Simulator& ebosSimulator,
const WellState& well_state,
std::vector<double>& well_potentials) override;
std::vector<double>& well_potentials,
Opm::DeferredLogger& deferred_logger) override;
virtual void updatePrimaryVariables(const WellState& well_state) const override;
@ -333,7 +336,8 @@ namespace Opm
// checking the operability of the well based on current reservoir condition
// it is not implemented for multisegment well yet
virtual void checkWellOperability(const Simulator& ebos_simulator,
const WellState& well_state) override;
const WellState& well_state,
Opm::DeferredLogger& deferred_logger) override;
void updateWellStateFromPrimaryVariables(WellState& well_state) const;

View File

@ -234,7 +234,8 @@ namespace Opm
MultisegmentWell<TypeTag>::
assembleWellEq(const Simulator& ebosSimulator,
const double dt,
WellState& well_state)
WellState& well_state,
Opm::DeferredLogger& deferred_logger)
{
const bool use_inner_iterations = param_.use_inner_iterations_ms_wells_;
@ -253,7 +254,8 @@ namespace Opm
void
MultisegmentWell<TypeTag>::
updateWellStateWithTarget(const Simulator& ebos_simulator,
WellState& well_state) const
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const
{
// Updating well state bas on well control
// Target values are used as initial conditions for BHP, THP, and SURFACE_RATE
@ -558,17 +560,19 @@ namespace Opm
MultisegmentWell<TypeTag>::
computeWellPotentials(const Simulator& /* ebosSimulator */,
const WellState& /* well_state */,
std::vector<double>& well_potentials)
std::vector<double>& well_potentials,
Opm::DeferredLogger& deferred_logger)
{
const std::string msg = std::string("Well potential calculation is not supported for multisegment wells \n")
+ "A well potential of zero is returned for output purposes. \n"
+ "If you need well potential to set the guide rate for group controled wells \n"
+ "you will have to change the " + name() + " well to a standard well \n";
OpmLog::warning("WELL_POTENTIAL_NOT_IMPLEMENTED_FOR_MULTISEG_WELLS", msg);
deferred_logger.warning("WELL_POTENTIAL_NOT_IMPLEMENTED_FOR_MULTISEG_WELLS", msg);
const int np = number_of_phases_;
well_potentials.resize(np, 0.0);
}
@ -1646,11 +1650,12 @@ namespace Opm
void
MultisegmentWell<TypeTag>::
checkWellOperability(const Simulator& /* ebos_simulator */,
const WellState& /* well_state */)
const WellState& /* well_state */,
Opm::DeferredLogger& deferred_logger)
{
const std::string msg = "Support of well operability checking for multisegment wells is not implemented "
"yet, checkWellOperability() for " + name() + " will do nothing";
OpmLog::warning("NO_OPERATABILITY_CHECKING_MS_WELLS", msg);
deferred_logger.warning("NO_OPERATABILITY_CHECKING_MS_WELLS", msg);
}
@ -1901,7 +1906,7 @@ namespace Opm
{
const std::string msg = "Support of well testing for physical limits for multisegment wells is not "
"implemented yet, wellTestingPhysical() for " + name() + " will do nothing";
OpmLog::warning("NO_WELLTESTPHYSICAL_CHECKING_MS_WELLS", msg);
deferred_logger.warning("NO_WELLTESTPHYSICAL_CHECKING_MS_WELLS", msg);
}

View File

@ -143,10 +143,12 @@ namespace Opm
virtual void assembleWellEq(const Simulator& ebosSimulator,
const double dt,
WellState& well_state) override;
WellState& well_state,
Opm::DeferredLogger& deferred_logger) override;
virtual void updateWellStateWithTarget(const Simulator& ebos_simulator,
WellState& well_state) const override;
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const override;
/// check whether the well equations get converged for this well
virtual ConvergenceReport getWellConvergence(const std::vector<double>& B_avg) const override;
@ -164,7 +166,8 @@ namespace Opm
/// computing the well potentials for group control
virtual void computeWellPotentials(const Simulator& ebosSimulator,
const WellState& well_state,
std::vector<double>& well_potentials) /* const */ override;
std::vector<double>& well_potentials,
Opm::DeferredLogger& deferred_logger) /* const */ override;
virtual void updatePrimaryVariables(const WellState& well_state) const override;
@ -348,29 +351,33 @@ namespace Opm
void updateThp(WellState& well_state) const;
void assembleControlEq();
void assembleControlEq(Opm::DeferredLogger& deferred_logger);
// handle the non reasonable fractions due to numerical overshoot
void processFractions() const;
// updating the inflow based on the current reservoir condition
void updateIPR(const Simulator& ebos_simulator) const;
void updateIPR(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger) const;
// update the operability status of the well is operable under the current reservoir condition
// mostly related to BHP limit and THP limit
virtual void checkWellOperability(const Simulator& ebos_simulator,
const WellState& well_state) override;
const WellState& well_state,
Opm::DeferredLogger& deferred_logger
) override;
// check whether the well is operable under the current reservoir condition
// mostly related to BHP limit and THP limit
void updateWellOperability(const Simulator& ebos_simulator,
const WellState& well_state);
const WellState& well_state,
Opm::DeferredLogger& deferred_logger
);
// check whether the well is operable under BHP limit with current reservoir condition
void checkOperabilityUnderBHPLimitProducer(const Simulator& ebos_simulator);
// check whether the well is operable under THP limit with current reservoir condition
void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator);
void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger);
// update WellState based on IPR and associated VFP table
void updateWellStateWithTHPTargetIPR(const Simulator& ebos_simulator,
@ -385,7 +392,8 @@ namespace Opm
// whether the well can produce / inject based on the current well state (bhp)
bool canProduceInjectWithCurrentBhp(const Simulator& ebos_simulator,
const WellState& well_state);
const WellState& well_state,
Opm::DeferredLogger& deferred_logger);
// turn on crossflow to avoid singular well equations
// when the well is banned from cross-flow and the BHP is not properly initialized,
@ -414,7 +422,8 @@ namespace Opm
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
const double simulation_time, const int report_step,
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger) override;
WellState& well_state, WellTestState& welltest_state,
Opm::DeferredLogger& deferred_logger) override;
virtual void updateWaterThroughput(const double dt, WellState& well_state) const override;
};

View File

@ -144,10 +144,12 @@ namespace Opm
virtual void assembleWellEq(const Simulator& ebosSimulator,
const double dt,
WellState& well_state) override;
WellState& well_state,
Opm::DeferredLogger& deferred_logger) override;
virtual void updateWellStateWithTarget(const Simulator& ebos_simulator,
WellState& well_state) const override;
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const override;
/// check whether the well equations get converged for this well
virtual ConvergenceReport getWellConvergence(const std::vector<double>& B_avg) const override;
@ -165,7 +167,8 @@ namespace Opm
/// computing the well potentials for group control
virtual void computeWellPotentials(const Simulator& ebosSimulator,
const WellState& well_state,
std::vector<double>& well_potentials) /* const */ override;
std::vector<double>& well_potentials,
Opm::DeferredLogger& deferred_logger) /* const */ override;
virtual void updatePrimaryVariables(const WellState& well_state) const override;
@ -353,29 +356,31 @@ namespace Opm
void updateThp(WellState& well_state) const;
void assembleControlEq();
void assembleControlEq(Opm::DeferredLogger& deferred_logger);
// handle the non reasonable fractions due to numerical overshoot
void processFractions() const;
// updating the inflow based on the current reservoir condition
void updateIPR(const Simulator& ebos_simulator) const;
void updateIPR(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger) const;
// update the operability status of the well is operable under the current reservoir condition
// mostly related to BHP limit and THP limit
virtual void checkWellOperability(const Simulator& ebos_simulator,
const WellState& well_state) override;
const WellState& well_state,
Opm::DeferredLogger& deferred_logger) override;
// check whether the well is operable under the current reservoir condition
// mostly related to BHP limit and THP limit
void updateWellOperability(const Simulator& ebos_simulator,
const WellState& well_state);
const WellState& well_state,
Opm::DeferredLogger& deferred_logger);
// check whether the well is operable under BHP limit with current reservoir condition
void checkOperabilityUnderBHPLimitProducer(const Simulator& ebos_simulator);
// check whether the well is operable under THP limit with current reservoir condition
void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator);
void checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger);
// update WellState based on IPR and associated VFP table
void updateWellStateWithTHPTargetIPR(const Simulator& ebos_simulator,
@ -390,7 +395,8 @@ namespace Opm
// whether the well can produce / inject based on the current well state (bhp)
bool canProduceInjectWithCurrentBhp(const Simulator& ebos_simulator,
const WellState& well_state);
const WellState& well_state,
Opm::DeferredLogger& deferred_logger);
// turn on crossflow to avoid singular well equations
// when the well is banned from cross-flow and the BHP is not properly initialized,

View File

@ -479,11 +479,13 @@ namespace Opm
StandardWellV<TypeTag>::
assembleWellEq(const Simulator& ebosSimulator,
const double dt,
WellState& well_state)
WellState& well_state,
Opm::DeferredLogger& deferred_logger
)
{
// TODO: only_wells should be put back to save some computation
checkWellOperability(ebosSimulator, well_state);
checkWellOperability(ebosSimulator, well_state, deferred_logger);
if (!this->isOperable()) return;
@ -675,7 +677,7 @@ namespace Opm
const unsigned int compIdx = flowPhaseToEbosCompIdx(p);
const double drawdown = well_state.perfPress()[first_perf_ + perf] - intQuants.fluidState().pressure(FluidSystem::oilPhaseIdx).value();
double productivity_index = cq_s[compIdx].value() / drawdown;
scaleProductivityIndex(perf, productivity_index);
scaleProductivityIndex(perf, productivity_index, deferred_logger);
well_state.productivityIndex()[np*index_of_well_ + p] += productivity_index;
}
}
@ -693,7 +695,7 @@ namespace Opm
resWell_[0][componentIdx] += resWell_loc.value();
}
assembleControlEq();
assembleControlEq(deferred_logger);
// do the local inversion of D.
try
@ -715,7 +717,7 @@ namespace Opm
template <typename TypeTag>
void
StandardWellV<TypeTag>::
assembleControlEq()
assembleControlEq(Opm::DeferredLogger& deferred_logger)
{
EvalWell control_eq(numWellEq_ + numEq, 0.);
switch (well_controls_get_current_type(well_controls_)) {
@ -770,7 +772,7 @@ namespace Opm
const std::string msg = " Setting all rates to be zero for well " + name()
+ " due to un-solvable situation. There is non-zero target for the phase "
+ " that does not exist in the wellbore for the situation";
OpmLog::warning("NON_SOLVABLE_WELL_SOLUTION", msg);
deferred_logger.warning("NON_SOLVABLE_WELL_SOLUTION", msg);
control_eq = getWQTotal() - target_rate;
}
@ -1188,7 +1190,8 @@ namespace Opm
void
StandardWellV<TypeTag>::
updateWellStateWithTarget(const Simulator& ebos_simulator,
WellState& well_state) const
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const
{
// number of phases
const int np = number_of_phases_;
@ -1217,7 +1220,7 @@ namespace Opm
} else { // go to BHP limit
assert(this->operability_status_.isOperableUnderBHPLimit() );
OpmLog::info("well " + name() + " can not work with THP target, switching to BHP control");
deferred_logger.info("well " + name() + " can not work with THP target, switching to BHP control");
well_state.bhp()[well_index] = mostStrictBhpFromBhpLimits();
}
@ -1294,7 +1297,7 @@ namespace Opm
template<typename TypeTag>
void
StandardWellV<TypeTag>::
updateIPR(const Simulator& ebos_simulator) const
updateIPR(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger) const
{
// TODO: not handling solvent related here for now
@ -1337,7 +1340,7 @@ namespace Opm
// it should not be negative anyway. If it is negative, we might need to re-formulate
// to taking into consideration the crossflow here.
if (pressure_diff <= 0.) {
OpmLog::warning("NON_POSITIVE_DRAWDOWN_IPR",
deferred_logger.warning("NON_POSITIVE_DRAWDOWN_IPR",
"non-positive drawdown found when updateIPR for well " + name());
}
@ -1391,7 +1394,8 @@ namespace Opm
void
StandardWellV<TypeTag>::
checkWellOperability(const Simulator& ebos_simulator,
const WellState& well_state)
const WellState& well_state,
Opm::DeferredLogger& deferred_logger)
{
// focusing on PRODUCER for now
if (well_type_ == INJECTOR) {
@ -1404,14 +1408,14 @@ namespace Opm
const bool old_well_operable = this->operability_status_.isOperable();
updateWellOperability(ebos_simulator, well_state);
updateWellOperability(ebos_simulator, well_state, deferred_logger);
const bool well_operable = this->operability_status_.isOperable();
if (!well_operable && old_well_operable) {
OpmLog::info(" well " + name() + " gets SHUT during iteration ");
deferred_logger.info(" well " + name() + " gets SHUT during iteration ");
} else if (well_operable && !old_well_operable) {
OpmLog::info(" well " + name() + " gets REVIVED during iteration ");
deferred_logger.info(" well " + name() + " gets REVIVED during iteration ");
}
}
@ -1423,18 +1427,19 @@ namespace Opm
void
StandardWellV<TypeTag>::
updateWellOperability(const Simulator& ebos_simulator,
const WellState& well_state)
const WellState& well_state,
Opm::DeferredLogger& deferred_logger)
{
this->operability_status_.reset();
updateIPR(ebos_simulator);
updateIPR(ebos_simulator, deferred_logger);
// checking the BHP limit related
checkOperabilityUnderBHPLimitProducer(ebos_simulator);
// checking whether the well can operate under the THP constraints.
if (this->wellHasTHPConstraints()) {
checkOperabilityUnderTHPLimitProducer(ebos_simulator);
checkOperabilityUnderTHPLimitProducer(ebos_simulator, deferred_logger);
}
}
@ -1498,7 +1503,7 @@ namespace Opm
template<typename TypeTag>
void
StandardWellV<TypeTag>::
checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator)
checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger)
{
const double obtain_bhp = calculateBHPWithTHPTargetIPR();
@ -1514,12 +1519,12 @@ namespace Opm
+ " bars is SMALLER than thp limit "
+ std::to_string(unit::convert::to(thp_limit, unit::barsa))
+ " bars as a producer for well " + name();
OpmLog::debug(msg);
deferred_logger.debug(msg);
}
} else {
this->operability_status_.can_obtain_bhp_with_thp_limit = false;
const double thp_limit = this->getTHPConstraint();
OpmLog::debug(" COULD NOT find bhp value under thp_limit "
deferred_logger.debug(" COULD NOT find bhp value under thp_limit "
+ std::to_string(unit::convert::to(thp_limit, unit::barsa))
+ " bars for well " + name() + ", the well might need to be closed ");
this->operability_status_.obey_bhp_limit_with_thp_limit = false;
@ -1569,7 +1574,8 @@ namespace Opm
bool
StandardWellV<TypeTag>::
canProduceInjectWithCurrentBhp(const Simulator& ebos_simulator,
const WellState& well_state)
const WellState& well_state,
Opm::DeferredLogger& deferred_logger)
{
const double bhp = well_state.bhp()[index_of_well_];
std::vector<double> well_rates;
@ -1590,7 +1596,7 @@ namespace Opm
}
if (!can_produce_inject) {
OpmLog::debug(" well " + name() + " CANNOT produce or inejct ");
deferred_logger.debug(" well " + name() + " CANNOT produce or inejct ");
}
return can_produce_inject;
@ -2413,7 +2419,8 @@ namespace Opm
StandardWellV<TypeTag>::
computeWellPotentials(const Simulator& ebosSimulator,
const WellState& well_state,
std::vector<double>& well_potentials) // const
std::vector<double>& well_potentials,
Opm::DeferredLogger& deferred_logger) // const
{
updatePrimaryVariables(well_state);
computeWellConnectionPressures(ebosSimulator, well_state);
@ -2870,7 +2877,7 @@ namespace Opm
const double simulation_time, const int report_step,
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger)
{
OpmLog::debug(" well " + name() + " is being tested for physical limits");
deferred_logger.debug(" well " + name() + " is being tested for physical limits");
// some most difficult things are the explicit quantities, since there is no information
// in the WellState to do a decent initialization
@ -2889,15 +2896,15 @@ namespace Opm
// we should be able to provide a better initialization
calculateExplicitQuantities(ebos_simulator, well_state_copy);
updateWellOperability(ebos_simulator, well_state_copy);
updateWellOperability(ebos_simulator, well_state_copy, deferred_logger);
if ( !this->isOperable() ) {
const std::string msg = " well " + name() + " is not operable during well testing for physical reason";
OpmLog::debug(msg);
deferred_logger.debug(msg);
return;
}
updateWellStateWithTarget(ebos_simulator, well_state_copy);
updateWellStateWithTarget(ebos_simulator, well_state_copy, deferred_logger);
calculateExplicitQuantities(ebos_simulator, well_state_copy);
updatePrimaryVariables(well_state_copy);
@ -2907,18 +2914,18 @@ namespace Opm
if (!converged) {
const std::string msg = " well " + name() + " did not get converged during well testing for physical reason";
OpmLog::debug(msg);
deferred_logger.debug(msg);
return;
}
if (this->isOperable() ) {
welltest_state.openWell(name() );
const std::string msg = " well " + name() + " is re-opened through well testing for physical reason";
OpmLog::info(msg);
deferred_logger.info(msg);
well_state = well_state_copy;
} else {
const std::string msg = " well " + name() + " is not operable during well testing for physical reason";
OpmLog::debug(msg);
deferred_logger.debug(msg);
}
}

View File

@ -444,10 +444,11 @@ namespace Opm
StandardWell<TypeTag>::
assembleWellEq(const Simulator& ebosSimulator,
const double dt,
WellState& well_state)
WellState& well_state,
Opm::DeferredLogger& deferred_logger)
{
checkWellOperability(ebosSimulator, well_state);
checkWellOperability(ebosSimulator, well_state, deferred_logger);
if (!this->isOperable()) return;
@ -621,7 +622,7 @@ namespace Opm
const unsigned int compIdx = flowPhaseToEbosCompIdx(p);
const double drawdown = well_state.perfPress()[first_perf_ + perf] - intQuants.fluidState().pressure(FluidSystem::oilPhaseIdx).value();
double productivity_index = cq_s[compIdx].value() / drawdown;
scaleProductivityIndex(perf, productivity_index);
scaleProductivityIndex(perf, productivity_index, deferred_logger);
well_state.productivityIndex()[np*index_of_well_ + p] += productivity_index;
}
}
@ -639,7 +640,7 @@ namespace Opm
resWell_[0][componentIdx] += resWell_loc.value();
}
assembleControlEq();
assembleControlEq(deferred_logger);
// do the local inversion of D.
try
@ -661,7 +662,7 @@ namespace Opm
template <typename TypeTag>
void
StandardWell<TypeTag>::
assembleControlEq()
assembleControlEq(Opm::DeferredLogger& deferred_logger)
{
EvalWell control_eq(0.0);
switch (well_controls_get_current_type(well_controls_)) {
@ -716,7 +717,7 @@ namespace Opm
const std::string msg = " Setting all rates to be zero for well " + name()
+ " due to un-solvable situation. There is non-zero target for the phase "
+ " that does not exist in the wellbore for the situation";
OpmLog::warning("NON_SOLVABLE_WELL_SOLUTION", msg);
deferred_logger.warning("NON_SOLVABLE_WELL_SOLUTION", msg);
control_eq = getWQTotal() - target_rate;
}
@ -1111,7 +1112,8 @@ namespace Opm
void
StandardWell<TypeTag>::
updateWellStateWithTarget(const Simulator& ebos_simulator,
WellState& well_state) const
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const
{
// number of phases
const int np = number_of_phases_;
@ -1140,7 +1142,7 @@ namespace Opm
} else { // go to BHP limit
assert(this->operability_status_.isOperableUnderBHPLimit() );
OpmLog::info("well " + name() + " can not work with THP target, switching to BHP control");
deferred_logger.info("well " + name() + " can not work with THP target, switching to BHP control");
well_state.bhp()[well_index] = mostStrictBhpFromBhpLimits();
}
@ -1217,7 +1219,7 @@ namespace Opm
template<typename TypeTag>
void
StandardWell<TypeTag>::
updateIPR(const Simulator& ebos_simulator) const
updateIPR(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger) const
{
// TODO: not handling solvent related here for now
@ -1260,7 +1262,7 @@ namespace Opm
// it should not be negative anyway. If it is negative, we might need to re-formulate
// to taking into consideration the crossflow here.
if (pressure_diff <= 0.) {
OpmLog::warning("NON_POSITIVE_DRAWDOWN_IPR",
deferred_logger.warning("NON_POSITIVE_DRAWDOWN_IPR",
"non-positive drawdown found when updateIPR for well " + name());
}
@ -1314,7 +1316,9 @@ namespace Opm
void
StandardWell<TypeTag>::
checkWellOperability(const Simulator& ebos_simulator,
const WellState& well_state)
const WellState& well_state,
Opm::DeferredLogger& deferred_logger
)
{
// focusing on PRODUCER for now
if (well_type_ == INJECTOR) {
@ -1327,14 +1331,14 @@ namespace Opm
const bool old_well_operable = this->operability_status_.isOperable();
updateWellOperability(ebos_simulator, well_state);
updateWellOperability(ebos_simulator, well_state, deferred_logger);
const bool well_operable = this->operability_status_.isOperable();
if (!well_operable && old_well_operable) {
OpmLog::info(" well " + name() + " gets SHUT during iteration ");
deferred_logger.info(" well " + name() + " gets SHUT during iteration ");
} else if (well_operable && !old_well_operable) {
OpmLog::info(" well " + name() + " gets REVIVED during iteration ");
deferred_logger.info(" well " + name() + " gets REVIVED during iteration ");
}
}
@ -1346,18 +1350,20 @@ namespace Opm
void
StandardWell<TypeTag>::
updateWellOperability(const Simulator& ebos_simulator,
const WellState& well_state)
const WellState& well_state,
Opm::DeferredLogger& deferred_logger
)
{
this->operability_status_.reset();
updateIPR(ebos_simulator);
updateIPR(ebos_simulator, deferred_logger);
// checking the BHP limit related
checkOperabilityUnderBHPLimitProducer(ebos_simulator);
// checking whether the well can operate under the THP constraints.
if (this->wellHasTHPConstraints()) {
checkOperabilityUnderTHPLimitProducer(ebos_simulator);
checkOperabilityUnderTHPLimitProducer(ebos_simulator, deferred_logger);
}
}
@ -1421,7 +1427,7 @@ namespace Opm
template<typename TypeTag>
void
StandardWell<TypeTag>::
checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator)
checkOperabilityUnderTHPLimitProducer(const Simulator& ebos_simulator, Opm::DeferredLogger& deferred_logger)
{
const double obtain_bhp = calculateBHPWithTHPTargetIPR();
@ -1437,12 +1443,12 @@ namespace Opm
+ " bars is SMALLER than thp limit "
+ std::to_string(unit::convert::to(thp_limit, unit::barsa))
+ " bars as a producer for well " + name();
OpmLog::debug(msg);
deferred_logger.debug(msg);
}
} else {
this->operability_status_.can_obtain_bhp_with_thp_limit = false;
const double thp_limit = this->getTHPConstraint();
OpmLog::debug(" COULD NOT find bhp value under thp_limit "
deferred_logger.debug(" COULD NOT find bhp value under thp_limit "
+ std::to_string(unit::convert::to(thp_limit, unit::barsa))
+ " bars for well " + name() + ", the well might need to be closed ");
this->operability_status_.obey_bhp_limit_with_thp_limit = false;
@ -1492,7 +1498,9 @@ namespace Opm
bool
StandardWell<TypeTag>::
canProduceInjectWithCurrentBhp(const Simulator& ebos_simulator,
const WellState& well_state)
const WellState& well_state,
Opm::DeferredLogger& deferred_logger
)
{
const double bhp = well_state.bhp()[index_of_well_];
std::vector<double> well_rates;
@ -1513,7 +1521,7 @@ namespace Opm
}
if (!can_produce_inject) {
OpmLog::debug(" well " + name() + " CANNOT produce or inejct ");
deferred_logger.debug(" well " + name() + " CANNOT produce or inejct ");
}
return can_produce_inject;
@ -2303,7 +2311,8 @@ namespace Opm
StandardWell<TypeTag>::
computeWellPotentials(const Simulator& ebosSimulator,
const WellState& well_state,
std::vector<double>& well_potentials) // const
std::vector<double>& well_potentials,
Opm::DeferredLogger& deferred_logger) // const
{
updatePrimaryVariables(well_state);
computeWellConnectionPressures(ebosSimulator, well_state);
@ -2748,9 +2757,10 @@ namespace Opm
StandardWell<TypeTag>::
wellTestingPhysical(Simulator& ebos_simulator, const std::vector<double>& B_avg,
const double simulation_time, const int report_step,
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferred_logger)
WellState& well_state, WellTestState& welltest_state,
Opm::DeferredLogger& deferred_logger)
{
OpmLog::debug(" well " + name() + " is being tested for physical limits");
deferred_logger.debug(" well " + name() + " is being tested for physical limits");
// some most difficult things are the explicit quantities, since there is no information
// in the WellState to do a decent initialization
@ -2769,15 +2779,15 @@ namespace Opm
// we should be able to provide a better initialization
calculateExplicitQuantities(ebos_simulator, well_state_copy);
updateWellOperability(ebos_simulator, well_state_copy);
updateWellOperability(ebos_simulator, well_state_copy, deferred_logger);
if ( !this->isOperable() ) {
const std::string msg = " well " + name() + " is not operable during well testing for physical reason";
OpmLog::debug(msg);
deferred_logger.debug(msg);
return;
}
updateWellStateWithTarget(ebos_simulator, well_state_copy);
updateWellStateWithTarget(ebos_simulator, well_state_copy, deferred_logger);
calculateExplicitQuantities(ebos_simulator, well_state_copy);
updatePrimaryVariables(well_state_copy);
@ -2787,18 +2797,18 @@ namespace Opm
if (!converged) {
const std::string msg = " well " + name() + " did not get converged during well testing for physical reason";
OpmLog::debug(msg);
deferred_logger.debug(msg);
return;
}
if (this->isOperable() ) {
welltest_state.openWell(name() );
const std::string msg = " well " + name() + " is re-opened through well testing for physical reason";
OpmLog::info(msg);
deferred_logger.info(msg);
well_state = well_state_copy;
} else {
const std::string msg = " well " + name() + " is not operable during well testing for physical reason";
OpmLog::debug(msg);
deferred_logger.debug(msg);
}
}

View File

@ -150,13 +150,15 @@ namespace Opm
virtual void assembleWellEq(const Simulator& ebosSimulator,
const double dt,
WellState& well_state) = 0;
WellState& well_state,
Opm::DeferredLogger& deferred_logger
) = 0;
void updateWellTestState(const WellState& well_state,
const double& simulationTime,
const bool& writeMessageToOPMLog,
WellTestState& wellTestState
) const;
WellTestState& wellTestState,
Opm::DeferredLogger& deferred_logger) const;
void setWellEfficiencyFactor(const double efficiency_factor);
@ -176,10 +178,12 @@ namespace Opm
// TODO: before we decide to put more information under mutable, this function is not const
virtual void computeWellPotentials(const Simulator& ebosSimulator,
const WellState& well_state,
std::vector<double>& well_potentials) = 0;
std::vector<double>& well_potentials,
Opm::DeferredLogger& deferred_logger) = 0;
virtual void updateWellStateWithTarget(const Simulator& ebos_simulator,
WellState& well_state) const = 0;
WellState& well_state,
Opm::DeferredLogger& deferred_logger) const = 0;
void updateWellControl(/* const */ Simulator& ebos_simulator,
WellState& well_state,
@ -233,7 +237,7 @@ namespace Opm
void updatePerforatedCell(std::vector<bool>& is_cell_perforated);
virtual void checkWellOperability(const Simulator& ebos_simulator, const WellState& well_state) = 0;
virtual void checkWellOperability(const Simulator& ebos_simulator, const WellState& well_state, Opm::DeferredLogger& deferred_logger) = 0;
// whether the well is operable
bool isOperable() const;
@ -339,7 +343,8 @@ namespace Opm
double wpolymer() const;
bool checkRateEconLimits(const WellEconProductionLimits& econ_production_limits,
const WellState& well_state) const;
const WellState& well_state,
Opm::DeferredLogger& deferred_logger) const;
double getTHPConstraint() const;
@ -362,7 +367,8 @@ namespace Opm
const WellState& well_state) const;
RatioCheckTuple checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits,
const WellState& well_state) const;
const WellState& well_state,
Opm::DeferredLogger& deferred_logger) const;
double scalingFactor(const int comp_idx) const;
@ -384,12 +390,14 @@ namespace Opm
void updateWellTestStateEconomic(const WellState& well_state,
const double simulation_time,
const bool write_message_to_opmlog,
WellTestState& well_test_state) const;
WellTestState& well_test_state,
Opm::DeferredLogger& deferred_logger) const;
void updateWellTestStatePhysical(const WellState& well_state,
const double simulation_time,
const bool write_message_to_opmlog,
WellTestState& well_test_state) const;
WellTestState& well_test_state,
Opm::DeferredLogger& deferred_logger) const;
void solveWellForTesting(Simulator& ebosSimulator, WellState& well_state,
const std::vector<double>& B_avg,
@ -400,7 +408,7 @@ namespace Opm
WellState& well_state,
Opm::DeferredLogger& deferred_logger);
void scaleProductivityIndex(const int perfIdx, double& productivity_index);
void scaleProductivityIndex(const int perfIdx, double& productivity_index, Opm::DeferredLogger& deferred_logger);
// count the number of times an output log message is created in the productivity
// index calculations

View File

@ -508,7 +508,7 @@ namespace Opm
}
if (updated_control_index != old_control_index) { // || well_collection_->groupControlActive()) {
updateWellStateWithTarget(ebos_simulator, well_state);
updateWellStateWithTarget(ebos_simulator, well_state, deferred_logger);
updatePrimaryVariables(well_state);
}
}
@ -546,7 +546,8 @@ namespace Opm
bool
WellInterface<TypeTag>::
checkRateEconLimits(const WellEconProductionLimits& econ_production_limits,
const WellState& well_state) const
const WellState& well_state,
Opm::DeferredLogger& deferred_logger) const
{
const Opm::PhaseUsage& pu = phaseUsage();
const int np = number_of_phases_;
@ -582,7 +583,7 @@ namespace Opm
}
if (econ_production_limits.onMinReservoirFluidRate()) {
OpmLog::warning("NOT_SUPPORTING_MIN_RESERVOIR_FLUID_RATE", "Minimum reservoir fluid production rate limit is not supported yet");
deferred_logger.warning("NOT_SUPPORTING_MIN_RESERVOIR_FLUID_RATE", "Minimum reservoir fluid production rate limit is not supported yet");
}
return false;
@ -683,7 +684,8 @@ namespace Opm
typename WellInterface<TypeTag>::RatioCheckTuple
WellInterface<TypeTag>::
checkRatioEconLimits(const WellEconProductionLimits& econ_production_limits,
const WellState& well_state) const
const WellState& well_state,
Opm::DeferredLogger& deferred_logger) const
{
// TODO: not sure how to define the worst-offending completion when more than one
// ratio related limit is violated.
@ -711,15 +713,15 @@ namespace Opm
}
if (econ_production_limits.onMaxGasOilRatio()) {
OpmLog::warning("NOT_SUPPORTING_MAX_GOR", "the support for max Gas-Oil ratio is not implemented yet!");
deferred_logger.warning("NOT_SUPPORTING_MAX_GOR", "the support for max Gas-Oil ratio is not implemented yet!");
}
if (econ_production_limits.onMaxWaterGasRatio()) {
OpmLog::warning("NOT_SUPPORTING_MAX_WGR", "the support for max Water-Gas ratio is not implemented yet!");
deferred_logger.warning("NOT_SUPPORTING_MAX_WGR", "the support for max Water-Gas ratio is not implemented yet!");
}
if (econ_production_limits.onMaxGasLiquidRatio()) {
OpmLog::warning("NOT_SUPPORTING_MAX_GLR", "the support for max Gas-Liquid ratio is not implemented yet!");
deferred_logger.warning("NOT_SUPPORTING_MAX_GLR", "the support for max Gas-Liquid ratio is not implemented yet!");
}
if (any_limit_violated) {
@ -740,8 +742,10 @@ namespace Opm
updateWellTestState(const WellState& well_state,
const double& simulationTime,
const bool& writeMessageToOPMLog,
WellTestState& wellTestState) const
WellTestState& wellTestState,
Opm::DeferredLogger& deferred_logger) const
{
// currently, we only updateWellTestState for producers
if (wellType() != PRODUCER) {
return;
@ -754,10 +758,10 @@ namespace Opm
}
// updating well test state based on physical (THP/BHP) limits.
updateWellTestStatePhysical(well_state, simulationTime, writeMessageToOPMLog, wellTestState);
updateWellTestStatePhysical(well_state, simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger);
// updating well test state based on Economic limits.
updateWellTestStateEconomic(well_state, simulationTime, writeMessageToOPMLog, wellTestState);
updateWellTestStateEconomic(well_state, simulationTime, writeMessageToOPMLog, wellTestState, deferred_logger);
// TODO: well can be shut/closed due to other reasons
}
@ -772,7 +776,8 @@ namespace Opm
updateWellTestStatePhysical(const WellState& well_state,
const double simulation_time,
const bool write_message_to_opmlog,
WellTestState& well_test_state) const
WellTestState& well_test_state,
Opm::DeferredLogger& deferred_logger) const
{
if (!isOperable()) {
well_test_state.addClosedWell(name(), WellTestConfig::Reason::PHYSICAL, simulation_time);
@ -780,7 +785,7 @@ namespace Opm
// TODO: considering auto shut in?
const std::string msg = "well " + name()
+ std::string(" will be shut as it can not operate under current reservoir condition");
OpmLog::info(msg);
deferred_logger.info(msg);
}
}
@ -796,7 +801,8 @@ namespace Opm
updateWellTestStateEconomic(const WellState& well_state,
const double simulation_time,
const bool write_message_to_opmlog,
WellTestState& well_test_state) const
WellTestState& well_test_state,
Opm::DeferredLogger& deferred_logger) const
{
const WellEconProductionLimits& econ_production_limits = well_ecl_->getEconProductionLimits(current_step_);
@ -814,11 +820,11 @@ namespace Opm
if (quantity_limit == WellEcon::POTN) {
const std::string msg = std::string("POTN limit for well ") + name() + std::string(" is not supported for the moment. \n")
+ std::string("All the limits will be evaluated based on RATE. ");
OpmLog::warning("NOT_SUPPORTING_POTN", msg);
deferred_logger.warning("NOT_SUPPORTING_POTN", msg);
}
if (econ_production_limits.onAnyRateLimit()) {
rate_limit_violated = checkRateEconLimits(econ_production_limits, well_state);
rate_limit_violated = checkRateEconLimits(econ_production_limits, well_state, deferred_logger);
}
if (rate_limit_violated) {
@ -827,21 +833,21 @@ namespace Opm
+ std::string("is not supported yet \n")
+ std::string("the program will keep running after ") + name()
+ std::string(" is closed");
OpmLog::warning("NOT_SUPPORTING_ENDRUN", warning_message);
deferred_logger.warning("NOT_SUPPORTING_ENDRUN", warning_message);
}
if (econ_production_limits.validFollowonWell()) {
OpmLog::warning("NOT_SUPPORTING_FOLLOWONWELL", "opening following on well after well closed is not supported yet");
deferred_logger.warning("NOT_SUPPORTING_FOLLOWONWELL", "opening following on well after well closed is not supported yet");
}
well_test_state.addClosedWell(name(), WellTestConfig::Reason::ECONOMIC, simulation_time);
if (write_message_to_opmlog) {
if (well_ecl_->getAutomaticShutIn()) {
const std::string msg = std::string("well ") + name() + std::string(" will be shut due to rate economic limit");
OpmLog::info(msg);
deferred_logger.info(msg);
} else {
const std::string msg = std::string("well ") + name() + std::string(" will be stopped due to rate economic limit");
OpmLog::info(msg);
deferred_logger.info(msg);
}
}
// the well is closed, not need to check other limits
@ -853,7 +859,7 @@ namespace Opm
RatioCheckTuple ratio_check_return;
if (econ_production_limits.onAnyRatioLimit()) {
ratio_check_return = checkRatioEconLimits(econ_production_limits, well_state);
ratio_check_return = checkRatioEconLimits(econ_production_limits, well_state, deferred_logger);
ratio_limits_violated = std::get<0>(ratio_check_return);
}
@ -869,11 +875,11 @@ namespace Opm
if (worst_offending_completion < 0) {
const std::string msg = std::string("Connection ") + std::to_string(- worst_offending_completion)
+ std::string(" for well ") + name() + std::string(" will be closed due to economic limit");
OpmLog::info(msg);
deferred_logger.info(msg);
} else {
const std::string msg = std::string("Completion ") + std::to_string(worst_offending_completion)
+ std::string(" for well ") + name() + std::string(" will be closed due to economic limit");
OpmLog::info(msg);
deferred_logger.info(msg);
}
}
@ -890,10 +896,10 @@ namespace Opm
if (write_message_to_opmlog) {
if (well_ecl_->getAutomaticShutIn()) {
const std::string msg = name() + std::string(" will be shut due to last completion closed");
OpmLog::info(msg);
deferred_logger.info(msg);
} else {
const std::string msg = name() + std::string(" will be stopped due to last completion closed");
OpmLog::info(msg);
deferred_logger.info(msg);
}
}
}
@ -906,10 +912,10 @@ namespace Opm
if (well_ecl_->getAutomaticShutIn()) {
// tell the controll that the well is closed
const std::string msg = name() + std::string(" will be shut due to ratio economic limit");
OpmLog::info(msg);
deferred_logger.info(msg);
} else {
const std::string msg = name() + std::string(" will be stopped due to ratio economic limit");
OpmLog::info(msg);
deferred_logger.info(msg);
}
}
break;
@ -918,7 +924,7 @@ namespace Opm
break;
default:
{
OpmLog::warning("NOT_SUPPORTED_WORKOVER_TYPE",
deferred_logger.warning("NOT_SUPPORTED_WORKOVER_TYPE",
"not supporting workover type " + WellEcon::WorkoverEnumToString(workover) );
}
}
@ -978,7 +984,7 @@ namespace Opm
while (testWell) {
const size_t original_number_closed_completions = welltest_state_temp.sizeCompletions();
solveWellForTesting(simulator, well_state_copy, B_avg, deferred_logger);
updateWellTestState(well_state_copy, simulation_time, /*writeMessageToOPMLog=*/ false, welltest_state_temp);
updateWellTestState(well_state_copy, simulation_time, /*writeMessageToOPMLog=*/ false, welltest_state_temp, deferred_logger);
closeCompletions(welltest_state_temp);
// Stop testing if the well is closed or shut due to all completions shut
@ -995,7 +1001,7 @@ namespace Opm
if (!welltest_state_temp.hasWell(name(), WellTestConfig::Reason::ECONOMIC)) {
welltest_state.openWell(name());
const std::string msg = std::string("well ") + name() + std::string(" is re-opened");
OpmLog::info(msg);
deferred_logger.info(msg);
// also reopen completions
for (auto& completion : well_ecl_->getCompletions(report_step)) {
@ -1173,7 +1179,7 @@ namespace Opm
bool converged;
WellState well_state0 = well_state;
do {
assembleWellEq(ebosSimulator, dt, well_state);
assembleWellEq(ebosSimulator, dt, well_state, deferred_logger);
auto report = getWellConvergence(B_avg);
converged = report.converged();
@ -1252,7 +1258,7 @@ namespace Opm
template<typename TypeTag>
void
WellInterface<TypeTag>::scaleProductivityIndex(const int perfIdx, double& productivity_index)
WellInterface<TypeTag>::scaleProductivityIndex(const int perfIdx, double& productivity_index, Opm::DeferredLogger& deferred_logger)
{
const auto& connection = well_ecl_->getConnections(current_step_)[perfIdx];
@ -1261,7 +1267,7 @@ namespace Opm
if (well_ecl_->getDrainageRadius(current_step_) < 0) {
if (new_well && perfIdx == 0) {
OpmLog::warning("PRODUCTIVITY_INDEX_WARNING", "Negative drainage radius not supported. The productivity index is set to zero");
deferred_logger.warning("PRODUCTIVITY_INDEX_WARNING", "Negative drainage radius not supported. The productivity index is set to zero");
}
productivity_index = 0.0;
return;
@ -1269,7 +1275,7 @@ namespace Opm
if (connection.r0() > well_ecl_->getDrainageRadius(current_step_)) {
if (new_well && well_productivity_index_logger_counter_ < 1) {
OpmLog::info("PRODUCTIVITY_INDEX_INFO", "The effective radius is larger than the well drainage radius for well " + name() +
deferred_logger.info("PRODUCTIVITY_INDEX_INFO", "The effective radius is larger than the well drainage radius for well " + name() +
" They are set to equal in the well productivity index calculations");
well_productivity_index_logger_counter_++;
}