Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
OutputAtFrequencyOrInterval.hpp
Go to the documentation of this file.
1 // Copyright (c) 2019 Maikel Nadolski
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #ifndef FUB_OTPUT_OUTPUT_AT_FREQ_AND_INTERV_HPP
22 #define FUB_OTPUT_OUTPUT_AT_FREQ_AND_INTERV_HPP
23 
26 
27 #include <pybind11/stl.h>
28 
29 namespace fub {
30 
31 template <typename GriddingAlgorithm>
32 class OutputAtFrequencyOrInterval : public BasicOutput<GriddingAlgorithm> {
33 public:
35 
36  /// Initialize this module by a program options map.
38  const std::map<std::string, pybind11::object>& options) {
39  frequencies_ = GetOptionOr(options, "frequencies", frequencies_);
40  std::vector<double> intervals =
41  GetOptionOr(options, "intervals", std::vector<double>{});
42  std::transform(intervals.begin(), intervals.end(),
43  std::back_inserter(intervals_),
44  [](double dur) { return Duration(dur); });
45  smallest_time_step_size_ = GetOptionOr(options, "smallest_time_step_size",
47  }
48 
50  std::vector<std::ptrdiff_t> frequencies,
51  std::vector<fub::Duration> intervals,
52  Duration smallest_time_step_size = Duration(1e-12))
53  : frequencies_(frequencies), intervals_(intervals),
54  smallest_time_step_size_(smallest_time_step_size) {}
55 
56  Duration NextOutputTime(Duration time_point) override {
57  Duration next_output_time(std::numeric_limits<double>::max());
58  for (std::size_t i = 0; i < intervals_.size(); ++i) {
59  if (intervals_[i].count() > 0.0) {
60  Duration dt(intervals_[i].count() -
61  std::fmod(time_point.count(), intervals_[i].count()));
63  next_output_time = std::min(next_output_time, time_point + dt);
64  }
65  }
66  return next_output_time;
67  }
68 
69  bool ShallOutputNow(const GriddingAlgorithm& grid) override {
70  const std::ptrdiff_t cycle = grid.GetCycles();
71  if (std::any_of(
72  frequencies_.begin(), frequencies_.end(),
73  [cycle](std::ptrdiff_t freq) { return cycle % freq == 0; })) {
74  return true;
75  }
76  const Duration time_point = grid.GetTimePoint();
77  if (time_point == Duration{} ||
78  std::any_of(intervals_.begin(), intervals_.end(),
79  [this, time_point](Duration freq) {
80  return std::abs(
81  std::fmod(time_point.count(), freq.count())) <
82  2 * smallest_time_step_size_.count();
83  })) {
84  return true;
85  }
86  return false;
87  }
88 
89  template <typename Log>
90  void Print(Log& log) {
91  BOOST_LOG(log) << fmt::format(" - frequencies = {{{}}} [-]", fmt::join(frequencies_, ", "));
92  std::vector<double> interval_counts(intervals_.size());
93  std::transform(intervals_.begin(), intervals_.end(), interval_counts.begin(), [](fub::Duration dur) {
94  return dur.count();
95  });
96  BOOST_LOG(log) << fmt::format(" - intervals = {{{}}} [s]", fmt::join(interval_counts, ", "));
97  BOOST_LOG(log) << fmt::format(" - smallest_time_step_size = {} [s]", smallest_time_step_size_.count());
98  }
99 
100 protected:
101  std::vector<std::ptrdiff_t> frequencies_{};
102  std::vector<fub::Duration> intervals_{};
104 };
105 
106 } // namespace fub
107 
108 #endif
Definition: OutputAtFrequencyOrInterval.hpp:32
std::vector< std::ptrdiff_t > frequencies_
Definition: OutputAtFrequencyOrInterval.hpp:101
Duration NextOutputTime(Duration time_point) override
Returns the time point at which the simulation shall stop to do some output.
Definition: OutputAtFrequencyOrInterval.hpp:56
OutputAtFrequencyOrInterval(std::vector< std::ptrdiff_t > frequencies, std::vector< fub::Duration > intervals, Duration smallest_time_step_size=Duration(1e-12))
Definition: OutputAtFrequencyOrInterval.hpp:49
OutputAtFrequencyOrInterval(const std::map< std::string, pybind11::object > &options)
Initialize this module by a program options map.
Definition: OutputAtFrequencyOrInterval.hpp:37
void Print(Log &log)
Definition: OutputAtFrequencyOrInterval.hpp:90
Duration smallest_time_step_size_
Definition: OutputAtFrequencyOrInterval.hpp:103
bool ShallOutputNow(const GriddingAlgorithm &grid) override
Returns true if this output class shall be invoked at the specified time point.
Definition: OutputAtFrequencyOrInterval.hpp:69
std::vector< fub::Duration > intervals_
Definition: OutputAtFrequencyOrInterval.hpp:102
std::decay_t< decltype(*std::declval< T >().GetGriddingAlgorithm())> GriddingAlgorithm
A template typedef to detect the member function.
Definition: Meta.hpp:56
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
void Log(std::string message, Duration timepoint, boost::log::trivial::severity_level level=boost::log::trivial::severity_level::info)
std::chrono::duration< double > Duration
Definition: Duration.hpp:31
T GetOptionOr(const ProgramOptions &map, const std::string &name, const T &value)
Definition: ProgramOptions.hpp:48
This is a abstract base class for an output strategy.
Definition: BasicOutput.hpp:33