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/RSTConv.cpp
|
||||
opm/simulators/flow/RegionPhasePVAverage.cpp
|
||||
opm/simulators/flow/SimulatorConvergenceOutput.cpp
|
||||
opm/simulators/flow/SimulatorReportBanners.cpp
|
||||
opm/simulators/flow/SimulatorSerializer.cpp
|
||||
opm/simulators/flow/SolutionContainers.cpp
|
||||
@ -843,6 +844,7 @@ list (APPEND PUBLIC_HEADER_FILES
|
||||
opm/simulators/flow/priVarsPacking.hpp
|
||||
opm/simulators/flow/RSTConv.hpp
|
||||
opm/simulators/flow/RegionPhasePVAverage.hpp
|
||||
opm/simulators/flow/SimulatorConvergenceOutput.hpp
|
||||
opm/simulators/flow/SimulatorFullyImplicitBlackoil.hpp
|
||||
opm/simulators/flow/SimulatorReportBanners.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/ExtraConvergenceOutputThread.hpp>
|
||||
#include <opm/simulators/flow/NonlinearSolver.hpp>
|
||||
#include <opm/simulators/flow/SimulatorConvergenceOutput.hpp>
|
||||
#include <opm/simulators/flow/SimulatorReportBanners.hpp>
|
||||
#include <opm/simulators/flow/SimulatorSerializer.hpp>
|
||||
#include <opm/simulators/timestepping/AdaptiveTimeStepping.hpp>
|
||||
@ -45,18 +46,15 @@
|
||||
#include <opm/simulators/utils/HDF5Serializer.hpp>
|
||||
#endif
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
namespace Opm::Parameters {
|
||||
|
||||
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] output_writer
|
||||
/// \param[in] threshold_pressures_by_face if nonempty, threshold pressures that inhibit flow
|
||||
SimulatorFullyImplicitBlackoil(Simulator& simulator)
|
||||
explicit SimulatorFullyImplicitBlackoil(Simulator& simulator)
|
||||
: simulator_(simulator)
|
||||
, convergence_output_(simulator_.vanguard().eclState())
|
||||
, serializer_(*this,
|
||||
FlowGenericVanguard::comm(),
|
||||
simulator_.vanguard().eclState().getIOConfig(),
|
||||
@ -134,15 +133,22 @@ public:
|
||||
if (this->grid().comm().rank() == 0) {
|
||||
this->terminalOutput_ = Parameters::Get<Parameters::EnableTerminalOutput>();
|
||||
|
||||
this->startConvergenceOutputThread(Parameters::Get<Parameters::OutputExtraConvergenceInfo>(),
|
||||
R"(OutputExtraConvergenceInfo (--output-extra-convergence-info))");
|
||||
auto getPhaseName = ConvergenceOutputThread::ComponentToPhaseName {
|
||||
[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()
|
||||
{
|
||||
// Safe to call on all ranks, not just the I/O rank.
|
||||
this->endConvergenceOutputThread();
|
||||
convergence_output_.endThread();
|
||||
}
|
||||
|
||||
static void registerParameters()
|
||||
@ -420,14 +426,7 @@ public:
|
||||
// Grab the step convergence reports that are new since last we
|
||||
// were here.
|
||||
const auto& reps = this->solver_->model().stepReports();
|
||||
|
||||
auto reports = std::vector<StepReport> {
|
||||
reps.begin() + this->already_reported_steps_, reps.end()
|
||||
};
|
||||
|
||||
this->writeConvergenceOutput(std::move(reports));
|
||||
|
||||
this->already_reported_steps_ = reps.size();
|
||||
convergence_output_.write(reps);
|
||||
}
|
||||
|
||||
// Increment timer, remember well state.
|
||||
@ -563,65 +562,6 @@ protected:
|
||||
const WellModel& wellModel_() const
|
||||
{ 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.
|
||||
Simulator& simulator_;
|
||||
|
||||
@ -636,14 +576,11 @@ protected:
|
||||
bool terminalOutput_;
|
||||
|
||||
SimulatorReport report_;
|
||||
std::size_t already_reported_steps_ = 0;
|
||||
std::unique_ptr<time::StopWatch> solverTimer_;
|
||||
std::unique_ptr<time::StopWatch> totalTimer_;
|
||||
std::unique_ptr<TimeStepper> adaptiveTimeStepping_;
|
||||
|
||||
std::optional<ConvergenceReportQueue> convergenceOutputQueue_{};
|
||||
std::optional<ConvergenceOutputThread> convergenceOutputObject_{};
|
||||
std::optional<std::thread> convergenceOutputThread_{};
|
||||
SimulatorConvergenceOutput convergence_output_;
|
||||
|
||||
SimulatorSerializer serializer_;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user