diff --git a/ProcessLib/Output/Output.cpp b/ProcessLib/Output/Output.cpp index 3d156c4f1db6630f3219418a2467f47f468aa432..e78b773c1bc1d7efaf2d89ea40cb147d4fc235cf 100644 --- a/ProcessLib/Output/Output.cpp +++ b/ProcessLib/Output/Output.cpp @@ -22,29 +22,6 @@ namespace { -//! Determines if there should be output at the given \c timestep. -template <typename CountsSteps> -bool shallDoOutput(unsigned timestep, CountsSteps const& repeats_each_steps) -{ - unsigned each_steps = 1; - - for (auto const& pair : repeats_each_steps) - { - each_steps = pair.each_steps; - - if (timestep > pair.repeat * each_steps) - { - timestep -= pair.repeat * each_steps; - } - else - { - break; - } - } - - return timestep % each_steps == 0; -} - //! Converts a vtkXMLWriter's data mode string to an int. See /// Output::_output_file_data_mode. int convertVtkDataMode(std::string const& data_mode) @@ -70,6 +47,40 @@ int convertVtkDataMode(std::string const& data_mode) namespace ProcessLib { +bool Output::shallDoOutput(unsigned timestep, double const t) +{ + unsigned each_steps = 1; + + for (auto const& pair : _repeats_each_steps) + { + each_steps = pair.each_steps; + + if (timestep > pair.repeat * each_steps) + { + timestep -= pair.repeat * each_steps; + } + else + { + break; + } + } + + bool make_output = timestep % each_steps == 0; + + if (_specific_times.empty()) + return make_output; + + const double specific_time = _specific_times.back(); + const double zero_threshold = std::numeric_limits<double>::epsilon(); + if (std::fabs(specific_time - t) < zero_threshold) + { + _specific_times.pop_back(); + make_output = true; + } + + return make_output; +} + Output::Output(std::string output_directory, std::string prefix, bool const compress_output, std::string const& data_mode, bool const output_nonlinear_iteration_results, @@ -170,7 +181,7 @@ void Output::doOutput(Process const& process, const double t, GlobalVector const& x) { - if (shallDoOutput(timestep, _repeats_each_steps)) + if (shallDoOutput(timestep, t)) { doOutputAlways(process, process_id, process_output, timestep, t, x); } @@ -188,7 +199,7 @@ void Output::doOutputLastTimestep(Process const& process, const double t, GlobalVector const& x) { - if (!shallDoOutput(timestep, _repeats_each_steps)) + if (!shallDoOutput(timestep, t)) { doOutputAlways(process, process_id, process_output, timestep, t, x); } diff --git a/ProcessLib/Output/Output.h b/ProcessLib/Output/Output.h index be4a0b2c6d3b3c201fa73a4bba4adea9d0fe0fe7..47d83033068d85a369e4b0a7d355ac98da2e164f 100644 --- a/ProcessLib/Output/Output.h +++ b/ProcessLib/Output/Output.h @@ -115,6 +115,11 @@ private: * @return Address of a ProcessData. */ ProcessData* findProcessData(Process const& process, const int process_id); + + //! Determines if there should be output at the given \c timestep or \c t. + bool shallDoOutput(unsigned timestep, double const t); }; + + } // namespace ProcessLib diff --git a/ProcessLib/UncoupledProcessesTimeLoop.cpp b/ProcessLib/UncoupledProcessesTimeLoop.cpp index 58a4e711db8ff71d1781f785b6ea716a13a186a5..d0b1f4ee53c6c17777dd88564245ebe7af1220ba 100644 --- a/ProcessLib/UncoupledProcessesTimeLoop.cpp +++ b/ProcessLib/UncoupledProcessesTimeLoop.cpp @@ -515,7 +515,7 @@ bool UncoupledProcessesTimeLoop::loop() { // initialize output, convergence criterion, etc. { - unsigned process_id = 0; + int process_id = 0; for (auto& process_data : _per_process_data) { auto& pcs = process_data->process; @@ -532,6 +532,13 @@ bool UncoupledProcessesTimeLoop::loop() pcs.getMesh()); } + // Add the specific times of output to time stepper in order that + // the time stepping is performed and the results are output at + // these times. Note: only the adaptive time steppers can have the + // the specific times. + auto& timestepper = process_data->timestepper; + timestepper->addSpecificTimes(_output->getSpecificTimes()); + ++process_id; } }