/* define how to combine observers */ template struct CombinedObserver { private: Obs1 a; /**< First Observer. */ Obs2 b; /**< Second Observer. */ Mo mo; /**< Combination of First and Second Observers' Monitors */ public: void before_timestepping(const view_constgbx gbxs) const { a.before_timestepping(gbxs); b.before_timestepping(gbxs); } void after_timestepping() const { a.after_timestepping(); b.after_timestepping(); } unsigned int next_step(const unsigned int t) const { return Kokkos::min(a.next_step(t), b.next_step(t)); } bool on_step(const unsigned int t) const { return a.on_step(t) || b.on_step(t); } void at_start_step(const unsigned int t, const view_constgbx, const view_constsupers supers) const { a.at_start_step(t, gbxs, supers); b.at_start_step(t, gbxs, supers); } Monitor auto get_monitor() const { return mo; } }; auto operator>>(const Observer auto obs1, const Observer auto obs2) { const Monitor auto mo12 = CombinedMonitor{obs1.get_monitor(), obs2.get_monitor()}; return CombinedObserver{obs1, obs2, mo12}; } // ... // /* use a combination of observers */ const Observer auto obs1 = StreamOutObserver(config); const Observer auto obs2 = TimeObserver(config, dataset); const Observer auto obs3 = StateObserver(config, dataset); const Observer auto obs4 = SuperdropsObserver(config, dataset); const Observer auto observer = obs4 >> obs3 >> obs2 >> obs1; // change this line to change observer }