mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
SimulatorConvergenceOutput: move to separate class
model using has-a in SimulatorFullyImplicitBlackoil
This commit is contained in:
parent
25cd79c04b
commit
15cb87576c
@ -109,6 +109,7 @@ list (APPEND MAIN_SOURCE_FILES
|
|||||||
opm/simulators/flow/partitionCells.cpp
|
opm/simulators/flow/partitionCells.cpp
|
||||||
opm/simulators/flow/RSTConv.cpp
|
opm/simulators/flow/RSTConv.cpp
|
||||||
opm/simulators/flow/RegionPhasePVAverage.cpp
|
opm/simulators/flow/RegionPhasePVAverage.cpp
|
||||||
|
opm/simulators/flow/SimulatorConvergenceOutput.cpp
|
||||||
opm/simulators/flow/SimulatorReportBanners.cpp
|
opm/simulators/flow/SimulatorReportBanners.cpp
|
||||||
opm/simulators/flow/SimulatorSerializer.cpp
|
opm/simulators/flow/SimulatorSerializer.cpp
|
||||||
opm/simulators/flow/SolutionContainers.cpp
|
opm/simulators/flow/SolutionContainers.cpp
|
||||||
@ -843,6 +844,7 @@ list (APPEND PUBLIC_HEADER_FILES
|
|||||||
opm/simulators/flow/priVarsPacking.hpp
|
opm/simulators/flow/priVarsPacking.hpp
|
||||||
opm/simulators/flow/RSTConv.hpp
|
opm/simulators/flow/RSTConv.hpp
|
||||||
opm/simulators/flow/RegionPhasePVAverage.hpp
|
opm/simulators/flow/RegionPhasePVAverage.hpp
|
||||||
|
opm/simulators/flow/SimulatorConvergenceOutput.hpp
|
||||||
opm/simulators/flow/SimulatorFullyImplicitBlackoil.hpp
|
opm/simulators/flow/SimulatorFullyImplicitBlackoil.hpp
|
||||||
opm/simulators/flow/SimulatorReportBanners.hpp
|
opm/simulators/flow/SimulatorReportBanners.hpp
|
||||||
opm/simulators/flow/SimulatorSerializer.hpp
|
opm/simulators/flow/SimulatorSerializer.hpp
|
||||||
|
94
opm/simulators/flow/SimulatorConvergenceOutput.cpp
Normal file
94
opm/simulators/flow/SimulatorConvergenceOutput.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013, 2015, 2020 SINTEF Digital, Mathematics and Cybernetics.
|
||||||
|
Copyright 2015 Andreas Lauser
|
||||||
|
Copyright 2017 IRIS
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
#include <config.h>
|
||||||
|
#include <opm/simulators/flow/SimulatorConvergenceOutput.hpp>
|
||||||
|
|
||||||
|
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
|
||||||
|
#include <opm/input/eclipse/EclipseState/IOConfig/IOConfig.hpp>
|
||||||
|
|
||||||
|
#include <opm/simulators/flow/ConvergenceOutputConfiguration.hpp>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
|
||||||
|
void SimulatorConvergenceOutput::
|
||||||
|
startThread(std::string_view convOutputOptions,
|
||||||
|
std::string_view optionName,
|
||||||
|
ConvergenceOutputThread::ComponentToPhaseName getPhaseName)
|
||||||
|
{
|
||||||
|
const auto config = ConvergenceOutputConfiguration {
|
||||||
|
convOutputOptions, optionName
|
||||||
|
};
|
||||||
|
|
||||||
|
if (! config.want(ConvergenceOutputConfiguration::Option::Iterations)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto convertTime = ConvergenceOutputThread::ConvertToTimeUnits {
|
||||||
|
[usys = eclState_.getUnits()](const double time)
|
||||||
|
{ return usys.from_si(UnitSystem::measure::time, time); }
|
||||||
|
};
|
||||||
|
|
||||||
|
this->convergenceOutputQueue_.emplace();
|
||||||
|
this->convergenceOutputObject_.emplace
|
||||||
|
(eclState_.getIOConfig().getOutputDir(),
|
||||||
|
eclState_.getIOConfig().getBaseName(),
|
||||||
|
std::move(getPhaseName),
|
||||||
|
std::move(convertTime),
|
||||||
|
config, *this->convergenceOutputQueue_);
|
||||||
|
|
||||||
|
this->convergenceOutputThread_
|
||||||
|
.emplace(&ConvergenceOutputThread::writeASynchronous,
|
||||||
|
&this->convergenceOutputObject_.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorConvergenceOutput::
|
||||||
|
write(const std::vector<StepReport>& reports)
|
||||||
|
{
|
||||||
|
if (! this->convergenceOutputThread_.has_value()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto new_reports = std::vector<StepReport> {
|
||||||
|
reports.begin() + this->already_reported_steps_, reports.end()
|
||||||
|
};
|
||||||
|
|
||||||
|
auto requests = std::vector<ConvergenceReportQueue::OutputRequest>{};
|
||||||
|
requests.reserve(new_reports.size());
|
||||||
|
|
||||||
|
for (auto&& report : new_reports) {
|
||||||
|
requests.push_back({ report.report_step, report.current_step, std::move(report.report) });
|
||||||
|
}
|
||||||
|
this->already_reported_steps_ = reports.size();
|
||||||
|
|
||||||
|
this->convergenceOutputQueue_->enqueue(std::move(requests));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulatorConvergenceOutput::endThread()
|
||||||
|
{
|
||||||
|
if (! this->convergenceOutputThread_.has_value()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->convergenceOutputQueue_->signalLastOutputRequest();
|
||||||
|
this->convergenceOutputThread_->join();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Opm
|
66
opm/simulators/flow/SimulatorConvergenceOutput.hpp
Normal file
66
opm/simulators/flow/SimulatorConvergenceOutput.hpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2013, 2015, 2020 SINTEF Digital, Mathematics and Cybernetics.
|
||||||
|
Copyright 2015 Andreas Lauser
|
||||||
|
Copyright 2017 IRIS
|
||||||
|
|
||||||
|
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_SIMULATOR_CONVERGENCE_OUTPUT_HEADER_INCLUDED
|
||||||
|
#define OPM_SIMULATOR_CONVERGENCE_OUTPUT_HEADER_INCLUDED
|
||||||
|
|
||||||
|
#include <opm/simulators/flow/ExtraConvergenceOutputThread.hpp>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
|
#include <thread>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace Opm {
|
||||||
|
|
||||||
|
class EclipseState;
|
||||||
|
struct StepReport;
|
||||||
|
|
||||||
|
/// Class handling convergence history output for a simulator.
|
||||||
|
class SimulatorConvergenceOutput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit SimulatorConvergenceOutput(const EclipseState& eclState)
|
||||||
|
: eclState_(eclState)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void startThread(std::string_view convOutputOptions,
|
||||||
|
std::string_view optionName,
|
||||||
|
ConvergenceOutputThread::ComponentToPhaseName getPhaseName);
|
||||||
|
|
||||||
|
void write(const std::vector<StepReport>& reports);
|
||||||
|
|
||||||
|
void endThread();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const EclipseState& eclState_;
|
||||||
|
|
||||||
|
std::size_t already_reported_steps_ = 0;
|
||||||
|
|
||||||
|
std::optional<ConvergenceReportQueue> convergenceOutputQueue_{};
|
||||||
|
std::optional<ConvergenceOutputThread> convergenceOutputObject_{};
|
||||||
|
std::optional<std::thread> convergenceOutputThread_{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Opm
|
||||||
|
|
||||||
|
#endif // OPM_SIMULATOR_CONVERGENCE_OUTPUT_HEADER_INCLUDED
|
@ -34,6 +34,7 @@
|
|||||||
#include <opm/simulators/flow/ConvergenceOutputConfiguration.hpp>
|
#include <opm/simulators/flow/ConvergenceOutputConfiguration.hpp>
|
||||||
#include <opm/simulators/flow/ExtraConvergenceOutputThread.hpp>
|
#include <opm/simulators/flow/ExtraConvergenceOutputThread.hpp>
|
||||||
#include <opm/simulators/flow/NonlinearSolver.hpp>
|
#include <opm/simulators/flow/NonlinearSolver.hpp>
|
||||||
|
#include <opm/simulators/flow/SimulatorConvergenceOutput.hpp>
|
||||||
#include <opm/simulators/flow/SimulatorReportBanners.hpp>
|
#include <opm/simulators/flow/SimulatorReportBanners.hpp>
|
||||||
#include <opm/simulators/flow/SimulatorSerializer.hpp>
|
#include <opm/simulators/flow/SimulatorSerializer.hpp>
|
||||||
#include <opm/simulators/timestepping/AdaptiveTimeStepping.hpp>
|
#include <opm/simulators/timestepping/AdaptiveTimeStepping.hpp>
|
||||||
@ -45,18 +46,15 @@
|
|||||||
#include <opm/simulators/utils/HDF5Serializer.hpp>
|
#include <opm/simulators/utils/HDF5Serializer.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <fmt/format.h>
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <thread>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
namespace Opm::Parameters {
|
namespace Opm::Parameters {
|
||||||
|
|
||||||
struct EnableAdaptiveTimeStepping { static constexpr bool value = true; };
|
struct EnableAdaptiveTimeStepping { static constexpr bool value = true; };
|
||||||
@ -117,8 +115,9 @@ public:
|
|||||||
/// \param[in] eclipse_state the object which represents an internalized ECL deck
|
/// \param[in] eclipse_state the object which represents an internalized ECL deck
|
||||||
/// \param[in] output_writer
|
/// \param[in] output_writer
|
||||||
/// \param[in] threshold_pressures_by_face if nonempty, threshold pressures that inhibit flow
|
/// \param[in] threshold_pressures_by_face if nonempty, threshold pressures that inhibit flow
|
||||||
SimulatorFullyImplicitBlackoil(Simulator& simulator)
|
explicit SimulatorFullyImplicitBlackoil(Simulator& simulator)
|
||||||
: simulator_(simulator)
|
: simulator_(simulator)
|
||||||
|
, convergence_output_(simulator_.vanguard().eclState())
|
||||||
, serializer_(*this,
|
, serializer_(*this,
|
||||||
FlowGenericVanguard::comm(),
|
FlowGenericVanguard::comm(),
|
||||||
simulator_.vanguard().eclState().getIOConfig(),
|
simulator_.vanguard().eclState().getIOConfig(),
|
||||||
@ -134,15 +133,22 @@ public:
|
|||||||
if (this->grid().comm().rank() == 0) {
|
if (this->grid().comm().rank() == 0) {
|
||||||
this->terminalOutput_ = Parameters::Get<Parameters::EnableTerminalOutput>();
|
this->terminalOutput_ = Parameters::Get<Parameters::EnableTerminalOutput>();
|
||||||
|
|
||||||
this->startConvergenceOutputThread(Parameters::Get<Parameters::OutputExtraConvergenceInfo>(),
|
auto getPhaseName = ConvergenceOutputThread::ComponentToPhaseName {
|
||||||
R"(OutputExtraConvergenceInfo (--output-extra-convergence-info))");
|
[compNames = typename Model::ComponentName{}](const int compIdx)
|
||||||
|
{ return std::string_view { compNames.name(compIdx) }; }
|
||||||
|
};
|
||||||
|
|
||||||
|
convergence_output_.
|
||||||
|
startThread(Parameters::Get<Parameters::OutputExtraConvergenceInfo>(),
|
||||||
|
R"(OutputExtraConvergenceInfo (--output-extra-convergence-info))",
|
||||||
|
getPhaseName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~SimulatorFullyImplicitBlackoil()
|
~SimulatorFullyImplicitBlackoil()
|
||||||
{
|
{
|
||||||
// Safe to call on all ranks, not just the I/O rank.
|
// Safe to call on all ranks, not just the I/O rank.
|
||||||
this->endConvergenceOutputThread();
|
convergence_output_.endThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void registerParameters()
|
static void registerParameters()
|
||||||
@ -420,14 +426,7 @@ public:
|
|||||||
// Grab the step convergence reports that are new since last we
|
// Grab the step convergence reports that are new since last we
|
||||||
// were here.
|
// were here.
|
||||||
const auto& reps = this->solver_->model().stepReports();
|
const auto& reps = this->solver_->model().stepReports();
|
||||||
|
convergence_output_.write(reps);
|
||||||
auto reports = std::vector<StepReport> {
|
|
||||||
reps.begin() + this->already_reported_steps_, reps.end()
|
|
||||||
};
|
|
||||||
|
|
||||||
this->writeConvergenceOutput(std::move(reports));
|
|
||||||
|
|
||||||
this->already_reported_steps_ = reps.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment timer, remember well state.
|
// Increment timer, remember well state.
|
||||||
@ -563,65 +562,6 @@ protected:
|
|||||||
const WellModel& wellModel_() const
|
const WellModel& wellModel_() const
|
||||||
{ return simulator_.problem().wellModel(); }
|
{ return simulator_.problem().wellModel(); }
|
||||||
|
|
||||||
void startConvergenceOutputThread(std::string_view convOutputOptions,
|
|
||||||
std::string_view optionName)
|
|
||||||
{
|
|
||||||
const auto config = ConvergenceOutputConfiguration {
|
|
||||||
convOutputOptions, optionName
|
|
||||||
};
|
|
||||||
if (! config.want(ConvergenceOutputConfiguration::Option::Iterations)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto getPhaseName = ConvergenceOutputThread::ComponentToPhaseName {
|
|
||||||
[compNames = typename Model::ComponentName{}](const int compIdx)
|
|
||||||
{ return std::string_view { compNames.name(compIdx) }; }
|
|
||||||
};
|
|
||||||
|
|
||||||
auto convertTime = ConvergenceOutputThread::ConvertToTimeUnits {
|
|
||||||
[usys = this->eclState().getUnits()](const double time)
|
|
||||||
{ return usys.from_si(UnitSystem::measure::time, time); }
|
|
||||||
};
|
|
||||||
|
|
||||||
this->convergenceOutputQueue_.emplace();
|
|
||||||
this->convergenceOutputObject_.emplace
|
|
||||||
(this->eclState().getIOConfig().getOutputDir(),
|
|
||||||
this->eclState().getIOConfig().getBaseName(),
|
|
||||||
std::move(getPhaseName),
|
|
||||||
std::move(convertTime),
|
|
||||||
config, *this->convergenceOutputQueue_);
|
|
||||||
|
|
||||||
this->convergenceOutputThread_
|
|
||||||
.emplace(&ConvergenceOutputThread::writeASynchronous,
|
|
||||||
&this->convergenceOutputObject_.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeConvergenceOutput(std::vector<StepReport>&& reports)
|
|
||||||
{
|
|
||||||
if (! this->convergenceOutputThread_.has_value()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto requests = std::vector<ConvergenceReportQueue::OutputRequest>{};
|
|
||||||
requests.reserve(reports.size());
|
|
||||||
|
|
||||||
for (auto&& report : reports) {
|
|
||||||
requests.push_back({ report.report_step, report.current_step, std::move(report.report) });
|
|
||||||
}
|
|
||||||
|
|
||||||
this->convergenceOutputQueue_->enqueue(std::move(requests));
|
|
||||||
}
|
|
||||||
|
|
||||||
void endConvergenceOutputThread()
|
|
||||||
{
|
|
||||||
if (! this->convergenceOutputThread_.has_value()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->convergenceOutputQueue_->signalLastOutputRequest();
|
|
||||||
this->convergenceOutputThread_->join();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Data.
|
// Data.
|
||||||
Simulator& simulator_;
|
Simulator& simulator_;
|
||||||
|
|
||||||
@ -636,14 +576,11 @@ protected:
|
|||||||
bool terminalOutput_;
|
bool terminalOutput_;
|
||||||
|
|
||||||
SimulatorReport report_;
|
SimulatorReport report_;
|
||||||
std::size_t already_reported_steps_ = 0;
|
|
||||||
std::unique_ptr<time::StopWatch> solverTimer_;
|
std::unique_ptr<time::StopWatch> solverTimer_;
|
||||||
std::unique_ptr<time::StopWatch> totalTimer_;
|
std::unique_ptr<time::StopWatch> totalTimer_;
|
||||||
std::unique_ptr<TimeStepper> adaptiveTimeStepping_;
|
std::unique_ptr<TimeStepper> adaptiveTimeStepping_;
|
||||||
|
|
||||||
std::optional<ConvergenceReportQueue> convergenceOutputQueue_{};
|
SimulatorConvergenceOutput convergence_output_;
|
||||||
std::optional<ConvergenceOutputThread> convergenceOutputObject_{};
|
|
||||||
std::optional<std::thread> convergenceOutputThread_{};
|
|
||||||
|
|
||||||
SimulatorSerializer serializer_;
|
SimulatorSerializer serializer_;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user