From d78dcbcddcce9d558e86b5fd47516cff26355b71 Mon Sep 17 00:00:00 2001
From: Wenqing Wang <wenqing.wang@ufz.de>
Date: Thu, 15 Feb 2018 11:01:55 +0100
Subject: [PATCH] [O] Added a criterion to shallDoOutput to check the specific
 times

---
 ProcessLib/Output/Output.cpp              | 61 +++++++++++++----------
 ProcessLib/Output/Output.h                |  5 ++
 ProcessLib/UncoupledProcessesTimeLoop.cpp |  9 +++-
 3 files changed, 49 insertions(+), 26 deletions(-)

diff --git a/ProcessLib/Output/Output.cpp b/ProcessLib/Output/Output.cpp
index 3d156c4f1db..e78b773c1bc 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 be4a0b2c6d3..47d83033068 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 58a4e711db8..d0b1f4ee53c 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;
         }
     }
-- 
GitLab