Finite Volume Solver  prototype
A framework to build finite volume solvers for the AG Klein at the Freie Universität Berlin.
MultipleOutputs.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_OUTPUT_MULTIPLE_OUTPUTS_HPP
22 #define FUB_OUTPUT_MULTIPLE_OUTPUTS_HPP
23 
26 
27 #include <pybind11/stl.h>
28 
29 #include <algorithm>
30 #include <memory>
31 #include <numeric>
32 #include <vector>
33 
34 namespace fub {
35 
36 template <typename Grid> class MultipleOutputs : public BasicOutput<Grid> {
37 public:
38  using ProgramOptions = std::map<std::string, pybind11::object>;
39 
40  MultipleOutputs() = default;
41 
43  : factory_(std::move(factory)), outputs_{} {
44  std::vector<int> frequencies =
45  GetOptionOr(opts, "frequencies", std::vector<int>{});
46  std::vector<double> intervals =
47  GetOptionOr(opts, "intervals", std::vector<double>{});
48  std::vector<pybind11::dict> outputs{};
49  outputs = GetOptionOr(opts, "outputs", outputs);
50  for (const pybind11::dict& output : outputs) {
51  auto opts = ToMap(output);
52  if (auto type = opts.find("type"); type != opts.end()) {
53  using namespace std::literals;
54  const std::string type_name = type->second.cast<std::string>();
55  opts.emplace(std::pair{"frequencies", pybind11::cast(frequencies)});
56  opts.emplace(std::pair{"intervals", pybind11::cast(intervals)});
57  outputs_.push_back(factory_.MakeOutput(type_name, opts));
58  }
59  }
60  }
61 
62  template <typename T> void AddOutput(std::unique_ptr<T>&& output) {
63  outputs_.emplace_back(output.release());
64  }
65 
66  /// Returns the time point at which the simulation shall stop to do some
67  /// output.
68  Duration NextOutputTime(Duration time_point) override {
69  return std::accumulate(
70  outputs_.begin(), outputs_.end(),
71  Duration(std::numeric_limits<double>::max()),
72  [time_point](Duration min,
73  const std::unique_ptr<BasicOutput<Grid>>& output) {
74  return output ? std::min(min, output->NextOutputTime(time_point))
75  : min;
76  });
77  }
78 
79  /// Returns true if this output class shall be invoked at the specified time
80  /// point.
81  bool ShallOutputNow(const Grid& grid) override {
82  return std::any_of(outputs_.begin(), outputs_.end(),
83  [&grid](const auto& output) {
84  return output && output->ShallOutputNow(grid);
85  });
86  }
87 
88  /// Invoke the actual output logic.
89  void operator()(const Grid& grid) override {
90  for (const auto& output : outputs_) {
91  if (output && output->ShallOutputNow(grid)) {
92  (*output)(grid);
93  }
94  }
95  }
96 
97 private:
99  std::vector<std::unique_ptr<BasicOutput<Grid>>> outputs_{};
100 };
101 
102 } // namespace fub
103 
104 #endif
Definition: MultipleOutputs.hpp:36
void operator()(const Grid &grid) override
Invoke the actual output logic.
Definition: MultipleOutputs.hpp:89
MultipleOutputs()=default
std::vector< std::unique_ptr< BasicOutput< Grid > > > outputs_
Definition: MultipleOutputs.hpp:99
MultipleOutputs(OutputFactory< Grid > factory, const ProgramOptions &opts)
Definition: MultipleOutputs.hpp:42
Duration NextOutputTime(Duration time_point) override
Returns the time point at which the simulation shall stop to do some output.
Definition: MultipleOutputs.hpp:68
OutputFactory< Grid > factory_
Definition: MultipleOutputs.hpp:98
void AddOutput(std::unique_ptr< T > &&output)
Definition: MultipleOutputs.hpp:62
bool ShallOutputNow(const Grid &grid) override
Returns true if this output class shall be invoked at the specified time point.
Definition: MultipleOutputs.hpp:81
std::map< std::string, pybind11::object > ProgramOptions
Definition: MultipleOutputs.hpp:38
Definition: OutputFactory.hpp:33
The fub namespace.
Definition: AnyBoundaryCondition.hpp:31
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
ProgramOptions ToMap(const pybind11::dict &dict)
This is a abstract base class for an output strategy.
Definition: BasicOutput.hpp:33