mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Correct Logging for Black Oil Well Model for parallel runs using DeferredLogger
This commit is contained in:
parent
e39f68787f
commit
42f6f4d784
@ -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();
|
||||
|
||||
|
@ -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_);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user