diff --git a/Documentation/ProjectFile/prj/time_loop/output/t_fixed_output_times.md b/Documentation/ProjectFile/prj/time_loop/output/t_fixed_output_times.md
new file mode 100644
index 0000000000000000000000000000000000000000..a933a2d49f7fd18cdc8564805763bdfc46c8c79d
--- /dev/null
+++ b/Documentation/ProjectFile/prj/time_loop/output/t_fixed_output_times.md
@@ -0,0 +1,2 @@
+An option input of fixed times, at which the output of the results must be
+ conducted.
diff --git a/Documentation/ProjectFile/prj/time_loop/processes/process/time_stepping/EvolutionaryPIDcontroller/t_fixed_output_times.md b/Documentation/ProjectFile/prj/time_loop/processes/process/time_stepping/EvolutionaryPIDcontroller/t_fixed_output_times.md
new file mode 100644
index 0000000000000000000000000000000000000000..e57ef89f7f00401c2ba2a207b788757d96c9aed8
--- /dev/null
+++ b/Documentation/ProjectFile/prj/time_loop/processes/process/time_stepping/EvolutionaryPIDcontroller/t_fixed_output_times.md
@@ -0,0 +1 @@
+The fixed times that must be reached in the time stepping.
diff --git a/Documentation/ProjectFile/prj/time_loop/processes/process/time_stepping/EvolutionaryPIDcontroller/t_specific_times.md b/Documentation/ProjectFile/prj/time_loop/processes/process/time_stepping/EvolutionaryPIDcontroller/t_specific_times.md
deleted file mode 100644
index 92fff5fadbdc54f4f17ebfe9d85beb72be5ee700..0000000000000000000000000000000000000000
--- a/Documentation/ProjectFile/prj/time_loop/processes/process/time_stepping/EvolutionaryPIDcontroller/t_specific_times.md
+++ /dev/null
@@ -1,2 +0,0 @@
-The specified times that must be reached in the time stepping.
-
diff --git a/NumLib/TimeStepping/Algorithms/CreateEvolutionaryPIDcontroller.cpp b/NumLib/TimeStepping/Algorithms/CreateEvolutionaryPIDcontroller.cpp
index a5607a2e0c5e1444e2bd9beee31c0b6b11bf363f..19837d03975bf3b2a1bfa290dd3de501068b1657 100644
--- a/NumLib/TimeStepping/Algorithms/CreateEvolutionaryPIDcontroller.cpp
+++ b/NumLib/TimeStepping/Algorithms/CreateEvolutionaryPIDcontroller.cpp
@@ -42,18 +42,14 @@ std::unique_ptr<TimeStepAlgorithm> createEvolutionaryPIDcontroller(
     //! \ogs_file_param{prj__time_loop__processes__process__time_stepping__EvolutionaryPIDcontroller__rel_dt_max}
     auto const rel_h_max = config.getConfigParameter<double>("rel_dt_max");
 
-    auto specific_times =
-        //! \ogs_file_param{prj__time_loop__processes__process__time_stepping__EvolutionaryPIDcontroller__specific_times}
-        config.getConfigParameter<std::vector<double>>("specific_times",
+    auto fixed_output_times =
+        //! \ogs_file_param{prj__time_loop__processes__process__time_stepping__EvolutionaryPIDcontroller__fixed_output_times}
+        config.getConfigParameter<std::vector<double>>("fixed_output_times",
                                                        std::vector<double>{});
-    if (!specific_times.empty())
+    if (!fixed_output_times.empty())
     {
-        // Sort in descending order.
-        std::sort(specific_times.begin(),
-                  specific_times.end(),
-                  std::greater<double>());
-        // Remove possible duplicated elements.
-        BaseLib::makeVectorUnique(specific_times);
+        // Remove possible duplicated elements and sort in descending order.
+        BaseLib::makeVectorUnique(fixed_output_times, std::greater<double>());
     }
 
     //! \ogs_file_param{prj__time_loop__processes__process__time_stepping__EvolutionaryPIDcontroller__tol}
@@ -61,6 +57,6 @@ std::unique_ptr<TimeStepAlgorithm> createEvolutionaryPIDcontroller(
 
     return std::make_unique<EvolutionaryPIDcontroller>(
         t0, t_end, h0, h_min, h_max, rel_h_min, rel_h_max,
-        std::move(specific_times), tol);
+        std::move(fixed_output_times), tol);
 }
 }  // end of namespace NumLib
diff --git a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp
index bb7a954f47068d45c4d3f6a2e972ec908a00f0b4..f98d91a426b371f6d8b26374c4bb49ec168845f2 100644
--- a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp
+++ b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.cpp
@@ -13,10 +13,11 @@
 #include <functional>
 #include <limits>
 #include <vector>
+#include <logog/include/logog.hpp>
 
-#include "EvolutionaryPIDcontroller.h"
+#include "BaseLib/makeVectorUnique.h"
 
-#include <logog/include/logog.hpp>
+#include "EvolutionaryPIDcontroller.h"
 
 namespace NumLib
 {
@@ -142,18 +143,28 @@ double EvolutionaryPIDcontroller::limitStepSize(
 
 double EvolutionaryPIDcontroller::checkSpecificTimeReached(const double h_new)
 {
-    if (_specific_times.empty())
+    if (_fixed_output_times.empty())
         return h_new;
 
-    const double specific_time = _specific_times.back();
-    const double zero_threshold = std::numeric_limits<double>::epsilon();
+    const double specific_time = _fixed_output_times.back();
     if ((specific_time > _ts_current.current()) &&
-        (_ts_current.current() + h_new - specific_time > zero_threshold))
+        (_ts_current.current() + h_new - specific_time > 0.0))
     {
-        _specific_times.pop_back();
+        _fixed_output_times.pop_back();
         return specific_time - _ts_current.current();
     }
 
     return h_new;
 }
+
+void EvolutionaryPIDcontroller::addFixedOutputTimes(
+    std::vector<double> const& extra_fixed_output_times)
+{
+    _fixed_output_times.insert(_fixed_output_times.end(),
+                               extra_fixed_output_times.begin(),
+                               extra_fixed_output_times.end());
+
+    // Remove possible duplicated elements and sort in descending order.
+    BaseLib::makeVectorUnique(_fixed_output_times, std::greater<double>());
+}
 }  // end of namespace NumLib
diff --git a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h
index 49d0f7fd60dc02206b9faae101b1375d11a6f165..3b308b0d2015d706f50df97276afc99afcd00052 100644
--- a/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h
+++ b/NumLib/TimeStepping/Algorithms/EvolutionaryPIDcontroller.h
@@ -55,7 +55,7 @@ public:
                               const double h0, const double h_min,
                               const double h_max, const double rel_h_min,
                               const double rel_h_max,
-                              const std::vector<double>&& specific_times,
+                              const std::vector<double>&& fixed_output_times,
                               const double tol)
         : TimeStepAlgorithm(t0, t_end),
           _h0(h0),
@@ -63,7 +63,7 @@ public:
           _h_max(h_max),
           _rel_h_min(rel_h_min),
           _rel_h_max(rel_h_max),
-          _specific_times(std::move(specific_times)),
+          _fixed_output_times(std::move(fixed_output_times)),
           _tol(tol),
           _e_n_minus1(0.),
           _e_n_minus2(0.),
@@ -91,6 +91,11 @@ public:
     /// Get a flag to indicate that this algorithm need to compute
     /// solution error.
     bool isSolutionErrorComputationNeeded() override { return true; }
+
+    /// \copydoc NumLib::TimeStepAlgorithm::addFixedOutputTimes
+    void addFixedOutputTimes(
+        std::vector<double> const& extra_fixed_output_times) override;
+
 private:
     const double _kP = 0.075;  ///< Parameter. \see EvolutionaryPIDcontroller
     const double _kI = 0.175;  ///< Parameter. \see EvolutionaryPIDcontroller
@@ -106,7 +111,7 @@ private:
     const double _rel_h_max;
 
     // Given times that steps have to reach.
-    std::vector<double> _specific_times;
+    std::vector<double> _fixed_output_times;
 
     const double _tol;
 
diff --git a/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.h b/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.h
index 0d4f99ef9a313c3b8a337b5f0f36ca46f6303123..48cd0da6212fd8912e85c19b0378dbe728caf43c 100644
--- a/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.h
+++ b/NumLib/TimeStepping/Algorithms/TimeStepAlgorithm.h
@@ -85,6 +85,19 @@ public:
     /// Get a flag to indicate whether this algorithm needs to compute
     /// solution error. The default return value is false.
     virtual bool isSolutionErrorComputationNeeded() { return false; }
+
+    /**
+     * Add specified times to the existing vector of the specified times.
+     * If there are specified times, they will be used as constraints in the
+     * computing of time step size such that the time step can exactly reach at
+     * the specified times. The function is mainly used to accept the specified
+     * times from the configuration of output.
+     */
+    virtual void addFixedOutputTimes(
+        std::vector<double> const& /*fixed_output_times*/)
+    {
+    }
+
 protected:
     /// initial time
     const double _t_initial;
diff --git a/ProcessLib/Output/CreateOutput.cpp b/ProcessLib/Output/CreateOutput.cpp
index 88ee97252592e5941e50cb6e53a75f39e80093bd..972f759221bd16974e27452df30b7020da70966c 100644
--- a/ProcessLib/Output/CreateOutput.cpp
+++ b/ProcessLib/Output/CreateOutput.cpp
@@ -15,6 +15,7 @@
 
 #include "BaseLib/ConfigTree.h"
 #include "BaseLib/FileTools.h"
+#include "BaseLib/makeVectorUnique.h"
 
 #include "Output.h"
 
@@ -43,6 +44,8 @@ std::unique_ptr<Output> createOutput(const BaseLib::ConfigTree& config,
     // Construction of output times
     std::vector<Output::PairRepeatEachSteps> repeats_each_steps;
 
+    std::vector<double> fixed_output_times;
+
     //! \ogs_file_param{prj__time_loop__output__timesteps}
     if (auto const timesteps = config.getConfigSubtreeOptional("timesteps"))
     {
@@ -71,13 +74,25 @@ std::unique_ptr<Output> createOutput(const BaseLib::ConfigTree& config,
         repeats_each_steps.emplace_back(1, 1);
     }
 
+    auto fixed_output_times_ptr =
+        //! \ogs_file_param{prj__time_loop__output__fixed_output_times}
+        config.getConfigParameterOptional<std::vector<double>>(
+            "fixed_output_times");
+    if (fixed_output_times_ptr)
+    {
+        fixed_output_times = std::move(*fixed_output_times_ptr);
+        // Remove possible duplicated elements and sort in descending order.
+        BaseLib::makeVectorUnique(fixed_output_times, std::greater<double>());
+    }
+
     bool const output_iteration_results =
         //! \ogs_file_param{prj__time_loop__output__output_iteration_results}
         config.getConfigParameter<bool>("output_iteration_results", false);
 
     return std::make_unique<Output>(output_directory, prefix, compress_output,
                                     data_mode, output_iteration_results,
-                                    std::move(repeats_each_steps));
+                                    std::move(repeats_each_steps),
+                                    std::move(fixed_output_times));
 }
 
 }  // namespace ProcessLib
diff --git a/ProcessLib/Output/Output.cpp b/ProcessLib/Output/Output.cpp
index 47088c4fd2509ea26abe55abcadff61a1e00444f..e62fc84c96f04ffd61f57d4babd6d2ab259db5a0 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,16 +47,52 @@ 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 (_fixed_output_times.empty())
+        return make_output;
+
+    const double specific_time = _fixed_output_times.back();
+    const double zero_threshold = std::numeric_limits<double>::min();
+    if (std::fabs(specific_time - t) < zero_threshold)
+    {
+        _fixed_output_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,
-               std::vector<PairRepeatEachSteps> repeats_each_steps)
+               std::vector<PairRepeatEachSteps> repeats_each_steps,
+               std::vector<double>&& fixed_output_times)
     : _output_directory(std::move(output_directory)),
       _output_file_prefix(std::move(prefix)),
       _output_file_compression(compress_output),
       _output_file_data_mode(convertVtkDataMode(data_mode)),
       _output_nonlinear_iteration_results(output_nonlinear_iteration_results),
-      _repeats_each_steps(std::move(repeats_each_steps))
+      _repeats_each_steps(std::move(repeats_each_steps)),
+      _fixed_output_times(std::move(fixed_output_times))
 {
 }
 
@@ -168,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);
     }
@@ -186,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 4a728d00ea8f2dc87303399e161b38fc7c0ae47d..4200f0c6de6c1e73463ccedfd17e741951ad5ee0 100644
--- a/ProcessLib/Output/Output.h
+++ b/ProcessLib/Output/Output.h
@@ -42,7 +42,8 @@ public:
     Output(std::string output_directory, std::string prefix,
            bool const compress_output, std::string const& data_mode,
            bool const output_nonlinear_iteration_results,
-           std::vector<PairRepeatEachSteps> repeats_each_steps);
+           std::vector<PairRepeatEachSteps> repeats_each_steps,
+           std::vector<double>&& fixed_output_times);
 
     //! TODO doc. Opens a PVD file for each process.
     void addProcess(ProcessLib::Process const& process, const int process_id);
@@ -77,6 +78,8 @@ public:
                                     GlobalVector const& x,
                                     const unsigned iteration);
 
+    std::vector<double> getFixedOutputTimes() {return _fixed_output_times;}
+
 private:
     struct ProcessData
     {
@@ -100,6 +103,9 @@ private:
     //! Describes after which timesteps to write output.
     std::vector<PairRepeatEachSteps> _repeats_each_steps;
 
+    //! Given times that steps have to reach.
+    std::vector<double> _fixed_output_times;
+
     std::multimap<Process const*, ProcessData> _process_to_process_data;
 
     /**
@@ -109,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/RichardsFlow/Tests.cmake b/ProcessLib/RichardsFlow/Tests.cmake
index 823c453dac79db243947f10aaf6ab930a8bf456a..454713a71520e94478069778109f3c54fea7ce2e 100644
--- a/ProcessLib/RichardsFlow/Tests.cmake
+++ b/ProcessLib/RichardsFlow/Tests.cmake
@@ -37,6 +37,12 @@ AddTest(
     TESTER vtkdiff
     DIFF_DATA
     ref_t_1600.000000.vtu richards_pcs_0_ts_803_t_1600.000000.vtu pressure pressure 1e-8 1e-3
+# The following three comparisons are used just to check whether the output is
+# made at the fixed times of 50, 100 and 500, which are given in the project
+# file of RichardsFlow_2d_small_adaptive_dt.prj
+    richards_pcs_0_ts_28_spec_t_50.000000.vtu richards_pcs_0_ts_28_t_50.000000.vtu pressure pressure 1e-10 1e-10
+    richards_pcs_0_ts_53_spec_t_100.000000.vtu richards_pcs_0_ts_53_t_100.000000.vtu pressure pressure 1e-10 1e-10
+    richards_pcs_0_ts_253_spec_t_500.000000.vtu richards_pcs_0_ts_253_t_500.000000.vtu pressure pressure 1e-10 1e-10
     REQUIREMENTS NOT OGS_USE_MPI
 )
 
diff --git a/ProcessLib/UncoupledProcessesTimeLoop.cpp b/ProcessLib/UncoupledProcessesTimeLoop.cpp
index 58a4e711db8ff71d1781f785b6ea716a13a186a5..488bc004eeb4668caa5afc0e1cf191f1f32223b0 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 fixed 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 fixed times.
+            auto& timestepper = process_data->timestepper;
+            timestepper->addFixedOutputTimes(_output->getFixedOutputTimes());
+
             ++process_id;
         }
     }
diff --git a/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500_staggered_scheme_adaptive_dt.prj b/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500_staggered_scheme_adaptive_dt.prj
index 0eb5b012447bf38ea90743e637299c5f7b915637..d71de36f310daf5039fb1a9fe3504fdc96b34d83 100644
--- a/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500_staggered_scheme_adaptive_dt.prj
+++ b/Tests/Data/Parabolic/HT/StaggeredCoupling/ConstViscosity/square_5500x5500_staggered_scheme_adaptive_dt.prj
@@ -100,7 +100,7 @@
                     <rel_dt_min> 0.1 </rel_dt_min>
                     <rel_dt_max> 10 </rel_dt_max>
                     <tol> 10.0 </tol>
-                    <specific_times>5.0e9 2.e10</specific_times>
+                    <fixed_output_times>5.0e9 2.e10</fixed_output_times>
                 </time_stepping>
             </process>
             <process ref="ConstViscosityThermalConvection">
@@ -128,7 +128,7 @@
                     <rel_dt_min> 0.1 </rel_dt_min>
                     <rel_dt_max> 10 </rel_dt_max>
                     <tol> 10.0 </tol>
-                    <specific_times>5.0e9 2.e10</specific_times>
+                    <fixed_output_times>5.0e9 2.e10</fixed_output_times>
                 </time_stepping>
             </process>
         </processes>
diff --git a/Tests/Data/Parabolic/Richards/RichardsFlow_2d_small_adaptive_dt.prj b/Tests/Data/Parabolic/Richards/RichardsFlow_2d_small_adaptive_dt.prj
index 2b85b7fc6187f642437f4c5bc070f287f3639988..3f64bd298833cfc21e442868f49c5832c49490a7 100644
--- a/Tests/Data/Parabolic/Richards/RichardsFlow_2d_small_adaptive_dt.prj
+++ b/Tests/Data/Parabolic/Richards/RichardsFlow_2d_small_adaptive_dt.prj
@@ -109,6 +109,7 @@
                     <each_steps>100000000</each_steps>
                 </pair>
             </timesteps>
+            <fixed_output_times> 50.0 100.0 500.</fixed_output_times>
             <output_iteration_results>false</output_iteration_results>
         </output>
     </time_loop>
diff --git a/Tests/Data/Parabolic/Richards/richards_pcs_0_ts_253_spec_t_500.000000.vtu b/Tests/Data/Parabolic/Richards/richards_pcs_0_ts_253_spec_t_500.000000.vtu
new file mode 100644
index 0000000000000000000000000000000000000000..b2e504420ae5341261a2706a9b6249cb19b41f31
--- /dev/null
+++ b/Tests/Data/Parabolic/Richards/richards_pcs_0_ts_253_spec_t_500.000000.vtu
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1bf1742f39e5118c9fc5018d3d201158a5ca2d3df194f4069140b1dd9ba42cf2
+size 4157
diff --git a/Tests/Data/Parabolic/Richards/richards_pcs_0_ts_28_spec_t_50.000000.vtu b/Tests/Data/Parabolic/Richards/richards_pcs_0_ts_28_spec_t_50.000000.vtu
new file mode 100644
index 0000000000000000000000000000000000000000..6c02dc51cb09b557f143a12462346167662dc462
--- /dev/null
+++ b/Tests/Data/Parabolic/Richards/richards_pcs_0_ts_28_spec_t_50.000000.vtu
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2118df616b1475cd281caaa08a9c1e2158dbab3528dd0778a30facc4ad05058f
+size 3950
diff --git a/Tests/Data/Parabolic/Richards/richards_pcs_0_ts_53_spec_t_100.000000.vtu b/Tests/Data/Parabolic/Richards/richards_pcs_0_ts_53_spec_t_100.000000.vtu
new file mode 100644
index 0000000000000000000000000000000000000000..43fcd7d8e1083c4863f30e90249cb6e9c460eb5a
--- /dev/null
+++ b/Tests/Data/Parabolic/Richards/richards_pcs_0_ts_53_spec_t_100.000000.vtu
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9d00e13c8488c4603fb1b27560a6681c1eef9d9599347dee66c2e3978cba1fb1
+size 4030