mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
replace well switching logger with deferred logger
This commit is contained in:
parent
1b79501060
commit
129e7d181e
@ -39,7 +39,6 @@ list (APPEND MAIN_SOURCE_FILES
|
|||||||
opm/core/wells/WellsManager.cpp
|
opm/core/wells/WellsManager.cpp
|
||||||
opm/core/wells/well_controls.c
|
opm/core/wells/well_controls.c
|
||||||
opm/core/wells/wells.c
|
opm/core/wells/wells.c
|
||||||
opm/simulators/WellSwitchingLogger.cpp
|
|
||||||
opm/simulators/DeferredLogger.cpp
|
opm/simulators/DeferredLogger.cpp
|
||||||
opm/simulators/timestepping/TimeStepControl.cpp
|
opm/simulators/timestepping/TimeStepControl.cpp
|
||||||
opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp
|
opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp
|
||||||
@ -58,7 +57,6 @@ list (APPEND TEST_SOURCE_FILES
|
|||||||
tests/test_milu.cpp
|
tests/test_milu.cpp
|
||||||
tests/test_multmatrixtransposed.cpp
|
tests/test_multmatrixtransposed.cpp
|
||||||
tests/test_wellmodel.cpp
|
tests/test_wellmodel.cpp
|
||||||
tests/test_wellswitchlogger.cpp
|
|
||||||
tests/test_deferredlogger.cpp
|
tests/test_deferredlogger.cpp
|
||||||
tests/test_timer.cpp
|
tests/test_timer.cpp
|
||||||
tests/test_invert.cpp
|
tests/test_invert.cpp
|
||||||
@ -165,7 +163,6 @@ list (APPEND PUBLIC_HEADER_FILES
|
|||||||
opm/core/wells/WellsManager.hpp
|
opm/core/wells/WellsManager.hpp
|
||||||
opm/core/wells/WellsManager_impl.hpp
|
opm/core/wells/WellsManager_impl.hpp
|
||||||
opm/simulators/ParallelFileMerger.hpp
|
opm/simulators/ParallelFileMerger.hpp
|
||||||
opm/simulators/WellSwitchingLogger.hpp
|
|
||||||
opm/simulators/DeferredLogger.hpp
|
opm/simulators/DeferredLogger.hpp
|
||||||
opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp
|
opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp
|
||||||
opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp
|
opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
|
|
||||||
#include <opm/material/densead/Math.hpp>
|
#include <opm/material/densead/Math.hpp>
|
||||||
|
|
||||||
#include <opm/simulators/WellSwitchingLogger.hpp>
|
#include <opm/simulators/DeferredLogger.hpp>
|
||||||
|
|
||||||
BEGIN_PROPERTIES
|
BEGIN_PROPERTIES
|
||||||
|
|
||||||
|
@ -320,7 +320,7 @@ namespace Opm {
|
|||||||
// no wells needing testing, otherwise we will have locking.
|
// no wells needing testing, otherwise we will have locking.
|
||||||
std::vector< Scalar > B_avg(numComponents(), Scalar() );
|
std::vector< Scalar > B_avg(numComponents(), Scalar() );
|
||||||
computeAverageFormationFactor(B_avg);
|
computeAverageFormationFactor(B_avg);
|
||||||
wellhelpers::WellSwitchingLogger logger;
|
Opm::DeferredLogger local_deferredLogger;
|
||||||
|
|
||||||
const auto& wellsForTesting = wellTestState_.updateWell(wtest_config, simulationTime);
|
const auto& wellsForTesting = wellTestState_.updateWell(wtest_config, simulationTime);
|
||||||
for (const auto& testWell : wellsForTesting) {
|
for (const auto& testWell : wellsForTesting) {
|
||||||
@ -338,8 +338,12 @@ namespace Opm {
|
|||||||
|
|
||||||
const WellTestConfig::Reason testing_reason = testWell.second;
|
const WellTestConfig::Reason testing_reason = testWell.second;
|
||||||
|
|
||||||
well->wellTesting(ebosSimulator_, B_avg, simulationTime, timeStepIdx, terminal_output_,
|
well->wellTesting(ebosSimulator_, B_avg, simulationTime, timeStepIdx,
|
||||||
testing_reason, well_state_, wellTestState_, logger);
|
testing_reason, well_state_, wellTestState_, local_deferredLogger);
|
||||||
|
}
|
||||||
|
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
|
||||||
|
if (terminal_output_) {
|
||||||
|
global_deferredLogger.logMessages();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -936,15 +940,20 @@ namespace Opm {
|
|||||||
updateWellControls()
|
updateWellControls()
|
||||||
{
|
{
|
||||||
// Even if there no wells active locally, we cannot
|
// Even if there no wells active locally, we cannot
|
||||||
// return as the Destructor of the WellSwitchingLogger
|
// return as the Destructor of the DeferredLogger
|
||||||
// uses global communication. For no well active globally
|
// uses global communication. For no well active globally
|
||||||
// we simply return.
|
// we simply return.
|
||||||
if( !wellsActive() ) return ;
|
if( !wellsActive() ) return ;
|
||||||
|
|
||||||
wellhelpers::WellSwitchingLogger logger;
|
Opm::DeferredLogger local_deferredLogger;
|
||||||
|
|
||||||
for (const auto& well : well_container_) {
|
for (const auto& well : well_container_) {
|
||||||
well->updateWellControl(ebosSimulator_, well_state_, logger);
|
well->updateWellControl(ebosSimulator_, well_state_, local_deferredLogger);
|
||||||
|
}
|
||||||
|
|
||||||
|
Opm::DeferredLogger global_deferredLogger = gatherDeferredLogger(local_deferredLogger);
|
||||||
|
if (terminal_output_) {
|
||||||
|
global_deferredLogger.logMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateGroupControls();
|
updateGroupControls();
|
||||||
|
@ -352,8 +352,7 @@ namespace Opm
|
|||||||
|
|
||||||
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step,
|
const double simulation_time, const int report_step,
|
||||||
const bool terminal_output,
|
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) override;
|
||||||
WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) override;
|
|
||||||
|
|
||||||
virtual void updateWaterThroughput(const double dt, WellState& well_state) const override;
|
virtual void updateWaterThroughput(const double dt, WellState& well_state) const override;
|
||||||
};
|
};
|
||||||
|
@ -1896,8 +1896,8 @@ namespace Opm
|
|||||||
void
|
void
|
||||||
MultisegmentWell<TypeTag>::
|
MultisegmentWell<TypeTag>::
|
||||||
wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger)
|
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger)
|
||||||
{
|
{
|
||||||
const std::string msg = "Support of well testing for physical limits for multisegment wells is not "
|
const std::string msg = "Support of well testing for physical limits for multisegment wells is not "
|
||||||
"implemented yet, wellTestingPhysical() for " + name() + " will do nothing";
|
"implemented yet, wellTestingPhysical() for " + name() + " will do nothing";
|
||||||
|
@ -413,8 +413,8 @@ namespace Opm
|
|||||||
const BVectorWell& dwells);
|
const BVectorWell& dwells);
|
||||||
|
|
||||||
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) override;
|
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) override;
|
||||||
|
|
||||||
virtual void updateWaterThroughput(const double dt, WellState& well_state) const override;
|
virtual void updateWaterThroughput(const double dt, WellState& well_state) const override;
|
||||||
};
|
};
|
||||||
|
@ -418,8 +418,8 @@ namespace Opm
|
|||||||
const BVectorWell& dwells);
|
const BVectorWell& dwells);
|
||||||
|
|
||||||
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) override;
|
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) override;
|
||||||
|
|
||||||
// calculate the skin pressure based on water velocity, throughput and polymer concentration.
|
// calculate the skin pressure based on water velocity, throughput and polymer concentration.
|
||||||
// throughput is used to describe the formation damage during water/polymer injection.
|
// throughput is used to describe the formation damage during water/polymer injection.
|
||||||
|
@ -2867,8 +2867,8 @@ namespace Opm
|
|||||||
void
|
void
|
||||||
StandardWellV<TypeTag>::
|
StandardWellV<TypeTag>::
|
||||||
wellTestingPhysical(Simulator& ebos_simulator, const std::vector<double>& B_avg,
|
wellTestingPhysical(Simulator& ebos_simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger)
|
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger)
|
||||||
{
|
{
|
||||||
OpmLog::debug(" well " + name() + " is being tested for physical limits");
|
OpmLog::debug(" well " + name() + " is being tested for physical limits");
|
||||||
|
|
||||||
@ -2903,7 +2903,7 @@ namespace Opm
|
|||||||
updatePrimaryVariables(well_state_copy);
|
updatePrimaryVariables(well_state_copy);
|
||||||
initPrimaryVariablesEvaluation();
|
initPrimaryVariablesEvaluation();
|
||||||
|
|
||||||
const bool converged = this->solveWellEqUntilConverged(ebos_simulator, B_avg, well_state_copy, logger);
|
const bool converged = this->solveWellEqUntilConverged(ebos_simulator, B_avg, well_state_copy, deferredLogger);
|
||||||
|
|
||||||
if (!converged) {
|
if (!converged) {
|
||||||
const std::string msg = " well " + name() + " did not get converged during well testing for physical reason";
|
const std::string msg = " well " + name() + " did not get converged during well testing for physical reason";
|
||||||
|
@ -2747,8 +2747,8 @@ namespace Opm
|
|||||||
void
|
void
|
||||||
StandardWell<TypeTag>::
|
StandardWell<TypeTag>::
|
||||||
wellTestingPhysical(Simulator& ebos_simulator, const std::vector<double>& B_avg,
|
wellTestingPhysical(Simulator& ebos_simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger)
|
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger)
|
||||||
{
|
{
|
||||||
OpmLog::debug(" well " + name() + " is being tested for physical limits");
|
OpmLog::debug(" well " + name() + " is being tested for physical limits");
|
||||||
|
|
||||||
@ -2783,7 +2783,7 @@ namespace Opm
|
|||||||
updatePrimaryVariables(well_state_copy);
|
updatePrimaryVariables(well_state_copy);
|
||||||
initPrimaryVariablesEvaluation();
|
initPrimaryVariablesEvaluation();
|
||||||
|
|
||||||
const bool converged = this->solveWellEqUntilConverged(ebos_simulator, B_avg, well_state_copy, logger);
|
const bool converged = this->solveWellEqUntilConverged(ebos_simulator, B_avg, well_state_copy, deferredLogger);
|
||||||
|
|
||||||
if (!converged) {
|
if (!converged) {
|
||||||
const std::string msg = " well " + name() + " did not get converged during well testing for physical reason";
|
const std::string msg = " well " + name() + " did not get converged during well testing for physical reason";
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
#include <opm/autodiff/RateConverter.hpp>
|
#include <opm/autodiff/RateConverter.hpp>
|
||||||
|
|
||||||
#include <opm/simulators/timestepping/ConvergenceReport.hpp>
|
#include <opm/simulators/timestepping/ConvergenceReport.hpp>
|
||||||
#include <opm/simulators/WellSwitchingLogger.hpp>
|
#include <opm/simulators/DeferredLogger.hpp>
|
||||||
|
|
||||||
#include<dune/common/fmatrix.hh>
|
#include<dune/common/fmatrix.hh>
|
||||||
#include<dune/istl/bcrsmatrix.hh>
|
#include<dune/istl/bcrsmatrix.hh>
|
||||||
@ -183,7 +183,7 @@ namespace Opm
|
|||||||
|
|
||||||
void updateWellControl(/* const */ Simulator& ebos_simulator,
|
void updateWellControl(/* const */ Simulator& ebos_simulator,
|
||||||
WellState& well_state,
|
WellState& well_state,
|
||||||
wellhelpers::WellSwitchingLogger& logger) /* const */;
|
Opm::DeferredLogger& deferredLogger) /* const */;
|
||||||
|
|
||||||
virtual void updatePrimaryVariables(const WellState& well_state) const = 0;
|
virtual void updatePrimaryVariables(const WellState& well_state) const = 0;
|
||||||
|
|
||||||
@ -226,10 +226,10 @@ namespace Opm
|
|||||||
// TODO: theoretically, it should be a const function
|
// TODO: theoretically, it should be a const function
|
||||||
// Simulator is not const is because that assembleWellEq is non-const Simulator
|
// Simulator is not const is because that assembleWellEq is non-const Simulator
|
||||||
void wellTesting(Simulator& simulator, const std::vector<double>& B_avg,
|
void wellTesting(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
const WellTestConfig::Reason testing_reason,
|
const WellTestConfig::Reason testing_reason,
|
||||||
/* const */ WellState& well_state, WellTestState& welltest_state,
|
/* const */ WellState& well_state, WellTestState& welltest_state,
|
||||||
wellhelpers::WellSwitchingLogger& logger);
|
Opm::DeferredLogger& deferredLogger);
|
||||||
|
|
||||||
void updatePerforatedCell(std::vector<bool>& is_cell_perforated);
|
void updatePerforatedCell(std::vector<bool>& is_cell_perforated);
|
||||||
|
|
||||||
@ -374,12 +374,12 @@ namespace Opm
|
|||||||
OperabilityStatus operability_status_;
|
OperabilityStatus operability_status_;
|
||||||
|
|
||||||
void wellTestingEconomic(Simulator& simulator, const std::vector<double>& B_avg,
|
void wellTestingEconomic(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
const WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger);
|
const WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger);
|
||||||
|
|
||||||
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
virtual void wellTestingPhysical(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger) = 0;
|
WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger) = 0;
|
||||||
|
|
||||||
void updateWellTestStateEconomic(const WellState& well_state,
|
void updateWellTestStateEconomic(const WellState& well_state,
|
||||||
const double simulation_time,
|
const double simulation_time,
|
||||||
@ -392,13 +392,13 @@ namespace Opm
|
|||||||
WellTestState& well_test_state) const;
|
WellTestState& well_test_state) const;
|
||||||
|
|
||||||
void solveWellForTesting(Simulator& ebosSimulator, WellState& well_state,
|
void solveWellForTesting(Simulator& ebosSimulator, WellState& well_state,
|
||||||
const std::vector<double>& B_avg, bool terminal_output,
|
const std::vector<double>& B_avg,
|
||||||
wellhelpers::WellSwitchingLogger& logger);
|
Opm::DeferredLogger& deferredLogger);
|
||||||
|
|
||||||
bool solveWellEqUntilConverged(Simulator& ebosSimulator,
|
bool solveWellEqUntilConverged(Simulator& ebosSimulator,
|
||||||
const std::vector<double>& B_avg,
|
const std::vector<double>& B_avg,
|
||||||
WellState& well_state,
|
WellState& well_state,
|
||||||
wellhelpers::WellSwitchingLogger& logger);
|
Opm::DeferredLogger& deferredLogger);
|
||||||
|
|
||||||
void scaleProductivityIndex(const int perfIdx, double& productivity_index);
|
void scaleProductivityIndex(const int perfIdx, double& productivity_index);
|
||||||
|
|
||||||
@ -453,6 +453,7 @@ namespace Opm
|
|||||||
bool obey_bhp_limit_with_thp_limit = true;
|
bool obey_bhp_limit_with_thp_limit = true;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
const std::string modestring[4] = { "BHP", "THP", "RESERVOIR_RATE", "SURFACE_RATE" };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +431,7 @@ namespace Opm
|
|||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
updateWellControl(/* const */ Simulator& ebos_simulator,
|
updateWellControl(/* const */ Simulator& ebos_simulator,
|
||||||
WellState& well_state,
|
WellState& well_state,
|
||||||
wellhelpers::WellSwitchingLogger& logger) /* const */
|
Opm::DeferredLogger& deferredLogger) /* const */
|
||||||
{
|
{
|
||||||
const int np = number_of_phases_;
|
const int np = number_of_phases_;
|
||||||
const int w = index_of_well_;
|
const int w = index_of_well_;
|
||||||
@ -493,9 +493,15 @@ namespace Opm
|
|||||||
|
|
||||||
// checking whether control changed
|
// checking whether control changed
|
||||||
if (updated_control_index != old_control_index) {
|
if (updated_control_index != old_control_index) {
|
||||||
logger.wellSwitched(name(),
|
|
||||||
well_controls_iget_type(wc, old_control_index),
|
auto from = well_controls_iget_type(wc, old_control_index);
|
||||||
well_controls_iget_type(wc, updated_control_index));
|
auto to = well_controls_iget_type(wc, updated_control_index);
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << " Switching control mode for well " << name()
|
||||||
|
<< " from " << modestring[from]
|
||||||
|
<< " to " << modestring[to];
|
||||||
|
deferredLogger.info(ss.str());
|
||||||
|
//logger.wellSwitched(name()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updated_control_index != old_control_index) { // || well_collection_->groupControlActive()) {
|
if (updated_control_index != old_control_index) { // || well_collection_->groupControlActive()) {
|
||||||
@ -924,20 +930,20 @@ namespace Opm
|
|||||||
void
|
void
|
||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
wellTesting(Simulator& simulator, const std::vector<double>& B_avg,
|
wellTesting(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
const WellTestConfig::Reason testing_reason,
|
const WellTestConfig::Reason testing_reason,
|
||||||
/* const */ WellState& well_state,
|
/* const */ WellState& well_state,
|
||||||
WellTestState& well_test_state,
|
WellTestState& well_test_state,
|
||||||
wellhelpers::WellSwitchingLogger& logger)
|
Opm::DeferredLogger& deferredLogger)
|
||||||
{
|
{
|
||||||
if (testing_reason == WellTestConfig::Reason::PHYSICAL) {
|
if (testing_reason == WellTestConfig::Reason::PHYSICAL) {
|
||||||
wellTestingPhysical(simulator, B_avg, simulation_time, report_step,
|
wellTestingPhysical(simulator, B_avg, simulation_time, report_step,
|
||||||
terminal_output, well_state, well_test_state, logger);
|
well_state, well_test_state, deferredLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (testing_reason == WellTestConfig::Reason::ECONOMIC) {
|
if (testing_reason == WellTestConfig::Reason::ECONOMIC) {
|
||||||
wellTestingEconomic(simulator, B_avg, simulation_time, report_step,
|
wellTestingEconomic(simulator, B_avg, simulation_time, report_step,
|
||||||
terminal_output, well_state, well_test_state, logger);
|
well_state, well_test_state, deferredLogger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,8 +955,8 @@ namespace Opm
|
|||||||
void
|
void
|
||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
wellTestingEconomic(Simulator& simulator, const std::vector<double>& B_avg,
|
wellTestingEconomic(Simulator& simulator, const std::vector<double>& B_avg,
|
||||||
const double simulation_time, const int report_step, const bool terminal_output,
|
const double simulation_time, const int report_step,
|
||||||
const WellState& well_state, WellTestState& welltest_state, wellhelpers::WellSwitchingLogger& logger)
|
const WellState& well_state, WellTestState& welltest_state, Opm::DeferredLogger& deferredLogger)
|
||||||
{
|
{
|
||||||
OpmLog::debug(" well " + name() + " is being tested for economic limits");
|
OpmLog::debug(" well " + name() + " is being tested for economic limits");
|
||||||
|
|
||||||
@ -968,7 +974,7 @@ namespace Opm
|
|||||||
// untill the number of closed completions do not increase anymore.
|
// untill the number of closed completions do not increase anymore.
|
||||||
while (testWell) {
|
while (testWell) {
|
||||||
const size_t original_number_closed_completions = welltest_state_temp.sizeCompletions();
|
const size_t original_number_closed_completions = welltest_state_temp.sizeCompletions();
|
||||||
solveWellForTesting(simulator, well_state_copy, B_avg, terminal_output, logger);
|
solveWellForTesting(simulator, well_state_copy, B_avg, deferredLogger);
|
||||||
updateWellTestState(well_state_copy, simulation_time, /*writeMessageToOPMLog=*/ false, welltest_state_temp);
|
updateWellTestState(well_state_copy, simulation_time, /*writeMessageToOPMLog=*/ false, welltest_state_temp);
|
||||||
closeCompletions(welltest_state_temp);
|
closeCompletions(welltest_state_temp);
|
||||||
|
|
||||||
@ -1156,7 +1162,7 @@ namespace Opm
|
|||||||
solveWellEqUntilConverged(Simulator& ebosSimulator,
|
solveWellEqUntilConverged(Simulator& ebosSimulator,
|
||||||
const std::vector<double>& B_avg,
|
const std::vector<double>& B_avg,
|
||||||
WellState& well_state,
|
WellState& well_state,
|
||||||
wellhelpers::WellSwitchingLogger& logger)
|
Opm::DeferredLogger& deferredLogger)
|
||||||
{
|
{
|
||||||
const int max_iter = param_.max_welleq_iter_;
|
const int max_iter = param_.max_welleq_iter_;
|
||||||
int it = 0;
|
int it = 0;
|
||||||
@ -1175,7 +1181,7 @@ namespace Opm
|
|||||||
++it;
|
++it;
|
||||||
solveEqAndUpdateWellState(well_state);
|
solveEqAndUpdateWellState(well_state);
|
||||||
|
|
||||||
updateWellControl(ebosSimulator, well_state, logger);
|
updateWellControl(ebosSimulator, well_state, deferredLogger);
|
||||||
initPrimaryVariablesEvaluation();
|
initPrimaryVariablesEvaluation();
|
||||||
} while (it < max_iter);
|
} while (it < max_iter);
|
||||||
|
|
||||||
@ -1225,22 +1231,18 @@ namespace Opm
|
|||||||
void
|
void
|
||||||
WellInterface<TypeTag>::
|
WellInterface<TypeTag>::
|
||||||
solveWellForTesting(Simulator& ebosSimulator, WellState& well_state,
|
solveWellForTesting(Simulator& ebosSimulator, WellState& well_state,
|
||||||
const std::vector<double>& B_avg, bool terminal_output,
|
const std::vector<double>& B_avg,
|
||||||
wellhelpers::WellSwitchingLogger& logger)
|
Opm::DeferredLogger& deferredLogger)
|
||||||
{
|
{
|
||||||
// keep a copy of the original well state
|
// keep a copy of the original well state
|
||||||
const WellState well_state0 = well_state;
|
const WellState well_state0 = well_state;
|
||||||
const bool converged = solveWellEqUntilConverged(ebosSimulator, B_avg, well_state, logger);
|
const bool converged = solveWellEqUntilConverged(ebosSimulator, B_avg, well_state, deferredLogger);
|
||||||
if (converged) {
|
if (converged) {
|
||||||
if ( terminal_output ) {
|
OpmLog::debug("WellTest: Well equation for well " + name() + " solution gets converged");
|
||||||
OpmLog::debug("WellTest: Well equation for well " + name() + " solution gets converged");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if ( terminal_output ) {
|
const int max_iter = param_.max_welleq_iter_;
|
||||||
const int max_iter = param_.max_welleq_iter_;
|
OpmLog::debug("WellTest: Well equation for well" +name() + " solution failed in getting converged with "
|
||||||
OpmLog::debug("WellTest: Well equation for well" +name() + " solution failed in getting converged with "
|
+ std::to_string(max_iter) + " iterations");
|
||||||
+ std::to_string(max_iter) + " iterations");
|
|
||||||
}
|
|
||||||
well_state = well_state0;
|
well_state = well_state0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,205 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2016 Dr. Blatt - HPC-Simulation-Software & Services
|
|
||||||
Copyright 2016 Statoil AS
|
|
||||||
|
|
||||||
This file is part of the Open Porous Media project (OPM).
|
|
||||||
|
|
||||||
OPM is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OPM is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif // HAVE_CONFIG_H
|
|
||||||
|
|
||||||
#include <opm/simulators/WellSwitchingLogger.hpp>
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
namespace Opm
|
|
||||||
{
|
|
||||||
namespace wellhelpers
|
|
||||||
{
|
|
||||||
|
|
||||||
#if HAVE_MPI
|
|
||||||
int WellSwitchingLogger::calculateMessageSize(std::vector<int>& well_name_lengths)
|
|
||||||
{
|
|
||||||
|
|
||||||
// Each process will send a message to the root process with
|
|
||||||
// the following data:
|
|
||||||
// total number of switches, for each switch the length of the
|
|
||||||
// well name, for each switch the well name and the two controls.
|
|
||||||
well_name_lengths.reserve(switchMap_.size());
|
|
||||||
|
|
||||||
for(const auto& switchEntry : switchMap_)
|
|
||||||
{
|
|
||||||
int length = switchEntry.first.size() +1; //we write an additional \0
|
|
||||||
well_name_lengths.push_back(length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// compute the message size
|
|
||||||
int message_size = 0;
|
|
||||||
int increment = 0;
|
|
||||||
// number of switches
|
|
||||||
MPI_Pack_size(1, MPI_INT, MPI_COMM_WORLD, &message_size);
|
|
||||||
// const char* length include delimiter for each switch
|
|
||||||
MPI_Pack_size(switchMap_.size(), MPI_INT, MPI_COMM_WORLD, &increment);
|
|
||||||
message_size += increment;
|
|
||||||
|
|
||||||
// for each well the name + two controls in one write
|
|
||||||
for(const auto& length : well_name_lengths)
|
|
||||||
{
|
|
||||||
// well name
|
|
||||||
MPI_Pack_size(length, MPI_CHAR, MPI_COMM_WORLD, &increment);
|
|
||||||
message_size += increment;
|
|
||||||
// controls
|
|
||||||
MPI_Pack_size(2, MPI_CHAR, MPI_COMM_WORLD, &increment);
|
|
||||||
message_size += increment;
|
|
||||||
}
|
|
||||||
return message_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WellSwitchingLogger::packData(std::vector<int>& well_name_lengths,
|
|
||||||
std::vector<char>& buffer)
|
|
||||||
{
|
|
||||||
// Pack the data
|
|
||||||
// number of switches
|
|
||||||
int offset = 0;
|
|
||||||
int no_switches = switchMap_.size();
|
|
||||||
MPI_Pack(&no_switches, 1, MPI_INT, buffer.data(), buffer.size(),
|
|
||||||
&offset, MPI_COMM_WORLD);
|
|
||||||
MPI_Pack(well_name_lengths.data(), well_name_lengths.size(),
|
|
||||||
MPI_INT, buffer.data(), buffer.size(),
|
|
||||||
&offset, MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
for(const auto& switchEntry : switchMap_)
|
|
||||||
{
|
|
||||||
// well name
|
|
||||||
auto& well_name = switchEntry.first;
|
|
||||||
MPI_Pack(const_cast<char*>(well_name.c_str()), well_name.size()+1,
|
|
||||||
MPI_CHAR, buffer.data(), buffer.size(),
|
|
||||||
&offset, MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
// controls
|
|
||||||
MPI_Pack(const_cast<char*>(switchEntry.second.data()), 2 , MPI_CHAR,
|
|
||||||
buffer.data(), buffer.size(), &offset, MPI_COMM_WORLD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WellSwitchingLogger::unpackDataAndLog(std::vector<char>& recv_buffer,
|
|
||||||
const std::vector<int>& displ)
|
|
||||||
{
|
|
||||||
for(int p=1; p < cc_.size(); ++p)
|
|
||||||
{
|
|
||||||
int offset = displ[p];
|
|
||||||
int no_switches = 0;
|
|
||||||
MPI_Unpack(recv_buffer.data(), recv_buffer.size(), &offset,
|
|
||||||
&no_switches, 1, MPI_INT, MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
if ( no_switches == 0 )
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> well_name_lengths(no_switches);
|
|
||||||
|
|
||||||
MPI_Unpack(recv_buffer.data(), recv_buffer.size(), &offset,
|
|
||||||
well_name_lengths.data(), well_name_lengths.size(),
|
|
||||||
MPI_INT, MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
std::vector<char> well_name;
|
|
||||||
for ( int i = 0; i < no_switches; ++i )
|
|
||||||
{
|
|
||||||
well_name.resize(well_name_lengths[i]);
|
|
||||||
MPI_Unpack(recv_buffer.data(), recv_buffer.size(), &offset,
|
|
||||||
well_name.data(), well_name_lengths[i], MPI_CHAR,
|
|
||||||
MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
std::array<char,2> fromto{{}};
|
|
||||||
MPI_Unpack(recv_buffer.data(), recv_buffer.size(), &offset,
|
|
||||||
fromto.data(), 2, MPI_CHAR, MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
logSwitch(well_name.data(), fromto, p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WellSwitchingLogger::logSwitch(const char* name, std::array<char,2> fromto,
|
|
||||||
int rank)
|
|
||||||
{
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << " Switching control mode for well " << name
|
|
||||||
<< " from " << modestring[WellControlType(fromto[0])]
|
|
||||||
<< " to " << modestring[WellControlType(fromto[1])]
|
|
||||||
<< " on rank " << rank;
|
|
||||||
OpmLog::info(ss.str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void WellSwitchingLogger::gatherDataAndLog()
|
|
||||||
{
|
|
||||||
|
|
||||||
#if HAVE_MPI
|
|
||||||
if(cc_.size() == 1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<int> message_sizes;
|
|
||||||
std::vector<int> well_name_lengths;
|
|
||||||
int message_size = calculateMessageSize(well_name_lengths);
|
|
||||||
|
|
||||||
if ( cc_.rank() == 0 ){
|
|
||||||
for(const auto& entry : switchMap_)
|
|
||||||
{
|
|
||||||
logSwitch(entry.first.c_str(), entry.second,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
message_sizes.resize(cc_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
MPI_Gather(&message_size, 1, MPI_INT, message_sizes.data(),
|
|
||||||
1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
||||||
|
|
||||||
std::vector<char> buffer(message_size);
|
|
||||||
packData(well_name_lengths, buffer);
|
|
||||||
|
|
||||||
std::vector<int> displ;
|
|
||||||
|
|
||||||
if ( cc_.rank() == 0){
|
|
||||||
// last entry will be total size of
|
|
||||||
displ.resize(cc_.size() + 1, 0);
|
|
||||||
std::partial_sum(message_sizes.begin(), message_sizes.end(),
|
|
||||||
displ.begin()+1);
|
|
||||||
}
|
|
||||||
std::vector<char> recv_buffer;
|
|
||||||
if ( cc_.rank() == 0 ){
|
|
||||||
recv_buffer.resize(displ[cc_.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
MPI_Gatherv(buffer.data(), buffer.size(), MPI_PACKED,
|
|
||||||
recv_buffer.data(), message_sizes.data(),
|
|
||||||
displ.data(), MPI_PACKED, 0, MPI_COMM_WORLD);
|
|
||||||
if ( cc_.rank() == 0 )
|
|
||||||
{
|
|
||||||
unpackDataAndLog(recv_buffer, displ);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WellSwitchingLogger::~WellSwitchingLogger()
|
|
||||||
{
|
|
||||||
gatherDataAndLog();
|
|
||||||
}
|
|
||||||
} // end namespace wellhelpers
|
|
||||||
} // end namespace Opm
|
|
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2016 Dr. Blatt - HPC-Simulation-Software & Services
|
|
||||||
Copyright 2016 Statoil AS
|
|
||||||
|
|
||||||
This file is part of the Open Porous Media project (OPM).
|
|
||||||
|
|
||||||
OPM is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OPM is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef OPM_WELLSWITCHINGLOGGER_HEADER_INCLUDED
|
|
||||||
#define OPM_WELLSWITCHINGLOGGER_HEADER_INCLUDED
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include <dune/common/parallel/mpihelper.hh>
|
|
||||||
|
|
||||||
#include <opm/common/OpmLog/OpmLog.hpp>
|
|
||||||
|
|
||||||
#include <opm/core/well_controls.h>
|
|
||||||
|
|
||||||
namespace Opm
|
|
||||||
{
|
|
||||||
namespace wellhelpers
|
|
||||||
{
|
|
||||||
|
|
||||||
/// \brief Utility class to handle the log messages about well switching.
|
|
||||||
///
|
|
||||||
/// In parallel all the messages will be send to a root processor
|
|
||||||
/// and logged there.
|
|
||||||
class WellSwitchingLogger
|
|
||||||
{
|
|
||||||
typedef std::map<std::string, std::array<char,2> > SwitchMap;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// \brief The type of the collective communication used.
|
|
||||||
typedef Dune::CollectiveCommunication<typename Dune::MPIHelper::MPICommunicator>
|
|
||||||
Communication;
|
|
||||||
|
|
||||||
/// \brief Constructor.
|
|
||||||
///
|
|
||||||
/// \param cc The collective communication to use.
|
|
||||||
explicit WellSwitchingLogger(const Communication& cc =
|
|
||||||
Dune::MPIHelper::getCollectiveCommunication())
|
|
||||||
: cc_(cc)
|
|
||||||
{}
|
|
||||||
|
|
||||||
/// \brief Log that a well switched.
|
|
||||||
/// \param name The name of the well.
|
|
||||||
/// \param from The control of the well before the switch.
|
|
||||||
/// \param to The control of the well after the switch.
|
|
||||||
void wellSwitched(std::string name,
|
|
||||||
WellControlType from,
|
|
||||||
WellControlType to)
|
|
||||||
{
|
|
||||||
if( cc_.size() > 1 )
|
|
||||||
{
|
|
||||||
using Pair = typename SwitchMap::value_type;
|
|
||||||
switchMap_.insert(Pair(name, {{char(from), char(to)}}));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << " Switching control mode for well " << name
|
|
||||||
<< " from " << modestring[from]
|
|
||||||
<< " to " << modestring[to];
|
|
||||||
OpmLog::info(ss.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \brief Destructor send does the actual logging.
|
|
||||||
~WellSwitchingLogger();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
#if HAVE_MPI
|
|
||||||
void unpackDataAndLog(std::vector<char>& recv_buffer,
|
|
||||||
const std::vector<int>& displ);
|
|
||||||
|
|
||||||
void packData(std::vector<int>& well_name_length,
|
|
||||||
std::vector<char>& buffer);
|
|
||||||
|
|
||||||
int calculateMessageSize(std::vector<int>& well_name_length);
|
|
||||||
|
|
||||||
void logSwitch(const char* name, std::array<char,2> fromto,
|
|
||||||
int rank);
|
|
||||||
|
|
||||||
#endif // HAVE_MPI
|
|
||||||
|
|
||||||
void gatherDataAndLog();
|
|
||||||
|
|
||||||
/// \brief A map containing the local switches
|
|
||||||
SwitchMap switchMap_;
|
|
||||||
/// \brief Collective communication object.
|
|
||||||
Communication cc_;
|
|
||||||
/// \brief The strings for printing.
|
|
||||||
const std::string modestring[4] = { "BHP", "THP", "RESERVOIR_RATE", "SURFACE_RATE" };
|
|
||||||
};
|
|
||||||
} // end namespace wellhelpers
|
|
||||||
} // end namespace Opm
|
|
||||||
#endif
|
|
@ -1,62 +0,0 @@
|
|||||||
#include <config.h>
|
|
||||||
#include <dune/common/version.hh>
|
|
||||||
|
|
||||||
#define BOOST_TEST_MODULE DistributedCpGridTests
|
|
||||||
#define BOOST_TEST_NO_MAIN
|
|
||||||
|
|
||||||
#include <boost/test/unit_test.hpp>
|
|
||||||
|
|
||||||
#include <opm/simulators/WellSwitchingLogger.hpp>
|
|
||||||
|
|
||||||
#if HAVE_MPI
|
|
||||||
class MPIError {
|
|
||||||
public:
|
|
||||||
/** @brief Constructor. */
|
|
||||||
MPIError(std::string s, int e) : errorstring(s), errorcode(e){}
|
|
||||||
/** @brief The error string. */
|
|
||||||
std::string errorstring;
|
|
||||||
/** @brief The mpi error code. */
|
|
||||||
int errorcode;
|
|
||||||
};
|
|
||||||
|
|
||||||
void MPI_err_handler(MPI_Comm *, int *err_code, ...){
|
|
||||||
char *err_string=new char[MPI_MAX_ERROR_STRING];
|
|
||||||
int err_length;
|
|
||||||
MPI_Error_string(*err_code, err_string, &err_length);
|
|
||||||
std::string s(err_string, err_length);
|
|
||||||
std::cerr << "An MPI Error ocurred:"<<std::endl<<s<<std::endl;
|
|
||||||
delete[] err_string;
|
|
||||||
throw MPIError(s, *err_code);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool
|
|
||||||
init_unit_test_func()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
BOOST_AUTO_TEST_CASE(wellswitchlog)
|
|
||||||
{
|
|
||||||
auto cc = Dune::MPIHelper::getCollectiveCommunication();
|
|
||||||
|
|
||||||
Opm::wellhelpers::WellSwitchingLogger logger(cc);
|
|
||||||
std::ostringstream name;
|
|
||||||
name <<"Well on rank "<<cc.rank()<<std::flush;
|
|
||||||
|
|
||||||
logger.wellSwitched(name.str(), BHP, THP);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
Dune::MPIHelper::instance(argc, argv);
|
|
||||||
#if HAVE_MPI
|
|
||||||
// register a throwing error handler to allow for
|
|
||||||
// debugging with "catch throw" in gdb
|
|
||||||
MPI_Errhandler handler;
|
|
||||||
MPI_Comm_create_errhandler(MPI_err_handler, &handler);
|
|
||||||
MPI_Comm_set_errhandler(MPI_COMM_WORLD, handler);
|
|
||||||
#endif
|
|
||||||
return boost::unit_test::unit_test_main(&init_unit_test_func,
|
|
||||||
argc, argv);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user