3#include "integrator_decorator.hpp"
4#include "timeout_decorator.hpp"
5#include "parallel_decorator.hpp"
6#include "output_decorator.hpp"
7#include "signal_decorator.hpp"
8#include "interpolation_decorator.hpp"
9#include "interprocess_decorator.hpp"
13namespace diffeq::core::composable {
38template<system_state S>
41 std::unique_ptr<AbstractIntegrator<S>> integrator_;
49 : integrator_(std::move(integrator)) {
52 throw std::invalid_argument(
"Base integrator cannot be null");
63 integrator_ = std::make_unique<TimeoutDecorator<S>>(
64 std::move(integrator_), std::move(config));
75 integrator_ = std::make_unique<ParallelDecorator<S>>(
76 std::move(integrator_), std::move(config));
88 std::function<void(
const S&,
typename AbstractIntegrator<S>::time_type,
size_t)> handler =
nullptr) {
89 integrator_ = std::make_unique<OutputDecorator<S>>(
90 std::move(integrator_), std::move(config), std::move(handler));
101 integrator_ = std::make_unique<SignalDecorator<S>>(
102 std::move(integrator_), std::move(config));
113 integrator_ = std::make_unique<InterpolationDecorator<S>>(
114 std::move(integrator_), std::move(config));
125 integrator_ = std::make_unique<InterprocessDecorator<S>>(
126 std::move(integrator_), std::move(config));
146 std::unique_ptr<AbstractIntegrator<S>>
build() {
148 throw std::runtime_error(
"Builder has already been used or is in invalid state");
150 return std::move(integrator_);
170 template<
typename DecoratorType>
172 return dynamic_cast<DecoratorType*
>(integrator_.get());
180 return integrator_ !=
nullptr;
189 return "Builder is empty or has been built";
192 std::string info =
"Composition: ";
199 info +=
"Timeout -> ";
202 info +=
"Parallel -> ";
205 info +=
"Output -> ";
208 info +=
"Signal -> ";
211 info +=
"Interpolation -> ";
214 info +=
"Interprocess -> ";
239template<system_state S>
250template<
typename Integrator>
251auto make_builder_copy(
const Integrator& integrator) {
253 std::make_unique<Integrator>(integrator));
267template<system_state S>
268auto with_timeout_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
269 TimeoutConfig config = {}) {
270 return make_builder(std::move(integrator)).with_timeout(std::move(config)).build();
280template<system_state S>
281auto with_parallel_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
282 ParallelConfig config = {}) {
283 return make_builder(std::move(integrator)).with_parallel(std::move(config)).build();
293template<system_state S>
294auto with_interpolation_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
295 InterpolationConfig config = {}) {
296 return make_builder(std::move(integrator)).with_interpolation(std::move(config)).build();
306template<system_state S>
307auto with_interprocess_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
308 InterprocessConfig config = {}) {
309 return make_builder(std::move(integrator)).with_interprocess(std::move(config)).build();
329template<system_state S>
330auto with_output_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
331 OutputConfig config = {},
332 std::function<void(
const S&,
typename AbstractIntegrator<S>::time_type,
size_t)> handler =
nullptr) {
333 return make_builder(std::move(integrator))
334 .with_output(std::move(config), std::move(handler)).build();
344template<system_state S>
345auto with_signals_only(std::unique_ptr<AbstractIntegrator<S>> integrator,
346 SignalConfig config = {}) {
347 return make_builder(std::move(integrator)).with_signals(std::move(config)).build();
361template<system_state S>
362auto for_realtime(std::unique_ptr<AbstractIntegrator<S>> integrator,
363 std::chrono::milliseconds timeout_ms = std::chrono::milliseconds{100}) {
364 return make_builder(std::move(integrator))
365 .with_timeout(TimeoutConfig{.timeout_duration = timeout_ms})
377template<system_state S>
378auto for_research(std::unique_ptr<AbstractIntegrator<S>> integrator,
379 size_t max_threads = 0) {
380 return make_builder(std::move(integrator))
381 .with_timeout(TimeoutConfig{.timeout_duration = std::chrono::hours{24}})
382 .with_parallel(ParallelConfig{.max_threads = max_threads})
383 .with_output(OutputConfig{.mode = OutputMode::OFFLINE})
393template<system_state S>
394auto for_production(std::unique_ptr<AbstractIntegrator<S>> integrator) {
395 return make_builder(std::move(integrator))
396 .with_timeout(TimeoutConfig{
397 .timeout_duration = std::chrono::seconds{30},
398 .throw_on_timeout =
false
400 .with_output(OutputConfig{.mode = OutputMode::HYBRID})
Builder for composing multiple facilities.
IntegratorBuilder(std::unique_ptr< AbstractIntegrator< S > > integrator)
Construct builder with base integrator.
bool is_valid() const
Check if the builder has a valid integrator.
IntegratorBuilder & with_parallel(ParallelConfig config={})
Add parallel execution facility.
IntegratorBuilder & with_output(OutputConfig config={}, std::function< void(const S &, typename AbstractIntegrator< S >::time_type, size_t)> handler=nullptr)
Add output handling facility.
IntegratorBuilder & with_timeout(TimeoutConfig config={})
Add timeout protection facility.
IntegratorBuilder & with_interprocess(InterprocessConfig config={})
Add interprocess facility.
std::string get_composition_info() const
Get information about the current composition.
DecoratorType * get_as()
Get specific decorator type from the composition chain.
IntegratorBuilder & with_interpolation(InterpolationConfig config={})
Add interpolation facility.
std::unique_ptr< AbstractIntegrator< S > > build()
Build the final composed integrator.
IntegratorBuilder & with_signals(SignalConfig config={})
Add signal processing facility.
Interpolation decorator - adds dense output capabilities to any integrator.
Interprocess communication decorator.
Output decorator - adds configurable output to any integrator.
Parallel execution decorator - adds batch processing to any integrator.
Signal decorator - adds signal processing to any integrator.
Timeout decorator - adds timeout protection to any integrator.
Configuration for interpolation and dense output.
Configuration for interprocess communication.
Configuration for output handling.
Configuration for parallel execution.
Configuration for signal processing.
Timeout configuration for integration protection.