diff --git a/include/api.hpp b/include/api.hpp index b7e4436..9741560 100644 --- a/include/api.hpp +++ b/include/api.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include struct SolverParameters{ @@ -50,11 +49,10 @@ using solver_run_fn = void (*)( ); using output_write_fn = int (*)(const OutputParameters*); -inline constexpr const char* SYMBOL_API_VERSION = - "plugin_api_version"; +inline constexpr const char* SYMBOL_API_VERSION = "plugin_api_version"; inline constexpr const char* SYMBOL_TYPE = "plugin_type"; inline constexpr const char* SYMBOL_NAME = "plugin_name"; inline constexpr const char* SYMBOL_DESCRIPTION = "plugin_description"; -inline constexpr const char* SYMBOL_TRANSFORM = "transform"; +inline constexpr const char* SYMBOL_SOLVER = "solver"; inline constexpr const char* SYMBOL_WRITE_OUTPUT = "write_output"; diff --git a/include/state.hpp b/include/state.hpp index cc03d84..8ea80cd 100644 --- a/include/state.hpp +++ b/include/state.hpp @@ -2,6 +2,7 @@ #include "api.hpp" +// x1, x2, x3 struct State { double x1; diff --git a/plugins/adams_bashforth_plugin.cpp b/plugins/adams_bashforth_plugin.cpp index 66343eb..1c1b226 100644 --- a/plugins/adams_bashforth_plugin.cpp +++ b/plugins/adams_bashforth_plugin.cpp @@ -19,39 +19,28 @@ PLUGIN_EXPORT const char* plugin_description(){ return "Explicit second-order Adams-Bashforth method with an RK4 start"; } -PLUGIN_EXPORT void transform(const SolverParameters* parameters, +PLUGIN_EXPORT void solver(const SolverParameters* parameters, SolutionPoint* output, size_t output_size){ - if (parameters == nullptr || output == nullptr || output_size == 0) - return; - - const State initial_state{1.0, 0.0, 0.0}; + State initial_state{1.0, 0.0, 0.0}; output[0] = make_step(parameters->t_begin, initial_state); - if (output_size == 1) - return; - State first_state = runge_kutta_step(initial_state, *parameters); output[1] = make_step(parameters->t_begin + parameters->step, first_state); - for (size_t index = 1; index + 1 < output_size; ++index){ + for (size_t index = 1; index + 1 < output_size; index++){ State current = state_from_point(output[index]); State previous = state_from_point(output[index - 1]); State current_derivative = derivative(current, *parameters); State previous_derivative = derivative(previous, *parameters); double h = parameters->step; - State next{ - current.x1 + h * (1.5 * current_derivative.x1 - - 0.5 * previous_derivative.x1), - current.x2 + h * (1.5 * current_derivative.x2 - - 0.5 * previous_derivative.x2), - current.x3 + h * (1.5 * current_derivative.x3 - - 0.5 * previous_derivative.x3), + State next{current.x1 + h * (1.5 * current_derivative.x1 - 0.5 * previous_derivative.x1), + current.x2 + h * (1.5 * current_derivative.x2 - 0.5 * previous_derivative.x2), + current.x3 + h * (1.5 * current_derivative.x3 - 0.5 * previous_derivative.x3), }; - const double next_time = parameters->t_begin + - static_cast(index + 1) * h; + double next_time = parameters->t_begin + static_cast(index + 1) * h; output[index + 1] = make_step(next_time, next); } } diff --git a/plugins/console_output_plugin.cpp b/plugins/console_output_plugin.cpp index 064019b..4111c0d 100644 --- a/plugins/console_output_plugin.cpp +++ b/plugins/console_output_plugin.cpp @@ -22,8 +22,6 @@ PLUGIN_EXPORT const char* plugin_description(){ } PLUGIN_EXPORT int write_output(const OutputParameters* parameters){ - if (parameters == nullptr || parameters->solver_name == nullptr || parameters->points == nullptr) - return 1; std::cout << "\nSolver: " << parameters->solver_name << '\n' << std::setw(12) << "t" @@ -41,5 +39,5 @@ PLUGIN_EXPORT int write_output(const OutputParameters* parameters){ } std::cout.flush(); - return std::cout ? 0 : 2; + return std::cout ? 0 : 1; } diff --git a/plugins/csv_output_plugin.cpp b/plugins/csv_output_plugin.cpp index 173d042..0853938 100644 --- a/plugins/csv_output_plugin.cpp +++ b/plugins/csv_output_plugin.cpp @@ -23,25 +23,20 @@ PLUGIN_EXPORT const char* plugin_description(){ } PLUGIN_EXPORT int write_output(const OutputParameters* parameters){ - if (parameters == nullptr || parameters->destination_path == nullptr || - parameters->points == nullptr) - { - return 1; - } std::ofstream stream(parameters->destination_path); if (!stream) - return 2; + return 1; stream.imbue(std::locale::classic()); stream << std::setprecision(17); stream << "t,x1,x2,x3\n"; for (size_t index = 0; index < parameters->point_count; ++index){ - const SolutionPoint& point = parameters->points[index]; + SolutionPoint point = parameters->points[index]; stream << point.t << ',' << point.x1 << ',' << point.x2 << ',' << point.x3 << '\n'; } - return stream ? 0 : 3; + return stream ? 0 : 2; } diff --git a/plugins/runge_kutta_plugin.cpp b/plugins/runge_kutta_plugin.cpp index 703918a..a8dbe46 100644 --- a/plugins/runge_kutta_plugin.cpp +++ b/plugins/runge_kutta_plugin.cpp @@ -19,19 +19,15 @@ PLUGIN_EXPORT const char* plugin_description(){ return "Explicit fourth-order Runge-Kutta method"; } -PLUGIN_EXPORT void transform(const SolverParameters* parameters, +PLUGIN_EXPORT void solver(const SolverParameters* parameters, SolutionPoint* output, size_t output_size){ - if (parameters == nullptr || output == nullptr || output_size == 0) - return; - State state{1, 0, 0}; output[0] = make_step(parameters->t_begin, state); for (size_t index = 1; index < output_size; ++index){ state = runge_kutta_step(state, *parameters); - const double t = parameters->t_begin + - static_cast(index) * parameters->step; + double t = parameters->t_begin + static_cast(index) * parameters->step; output[index] = make_step(t, state); } } diff --git a/src/main.cpp b/src/main.cpp index d11dd72..d409e47 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,6 @@ #include "api.hpp" -#include #include -#include #include #include #include @@ -115,8 +113,7 @@ std::vector find_candidates(const fs::path& directory){ if (!fs::exists(directory) || !fs::is_directory(directory)) return candidates; - for (const auto& entry : fs::directory_iterator(directory)) - { + for (const auto& entry : fs::directory_iterator(directory)){ if (entry.is_regular_file() && is_library_candidate(entry.path())) candidates.push_back(fs::absolute(entry.path())); } @@ -130,36 +127,12 @@ size_t calculate_point_count(const SolverParameters& parameters){ const double interval = parameters.t_end - parameters.t_begin; const double step_count = std::floor(interval / parameters.step + 1e-12); - if (!std::isfinite(step_count) || - step_count > static_cast(max_point_count - 1)) - { + if (!std::isfinite(step_count) || step_count > static_cast(max_point_count - 1)) throw std::runtime_error("the selected h creates too many solution points"); - } return static_cast(step_count) + 1; } -void validate_solution(const std::vector& solution, - const SolverParameters& parameters) -{ - for (size_t index = 0; index < solution.size(); ++index) - { - const SolutionPoint& point = solution[index]; - if (!std::isfinite(point.t) || !std::isfinite(point.x1) || - !std::isfinite(point.x2) || !std::isfinite(point.x3)) - { - throw std::runtime_error("solver returned a non-finite value"); - } - - const double expected_time = parameters.t_begin + - static_cast(index) * parameters.step; - const double tolerance = - 1e-10 * (std::max)(1.0, std::abs(expected_time)); - if (std::abs(point.t - expected_time) > tolerance) - throw std::runtime_error("solver returned an invalid time grid"); - } -} - int main() { try { std::string plugin_directory_text; @@ -205,30 +178,21 @@ int main() { try { SharedLibrary library(candidate); - const auto api_version = - library.require(SYMBOL_API_VERSION); - const auto type = - library.require(SYMBOL_TYPE); - const auto name = - library.require(SYMBOL_NAME); - const auto description = - library.require(SYMBOL_DESCRIPTION); + const auto api_version = library.require(SYMBOL_API_VERSION); + const auto type = library.require(SYMBOL_TYPE); + const auto name = library.require(SYMBOL_NAME); + const auto description = library.require(SYMBOL_DESCRIPTION); - if (api_version() != PLUGIN_API_VERSION){ - throw std::runtime_error( - "unsupported API version " + - std::to_string(api_version())); - } + if (api_version() != PLUGIN_API_VERSION) + throw std::runtime_error("unsupported API version " + std::to_string(api_version())); + const PluginType plugin_type = type(); const char* plugin_name = name(); const char* plugin_description = description(); - if (plugin_type != PluginType::Solver && - plugin_type != PluginType::Output) - { + if (plugin_type != PluginType::Solver && plugin_type != PluginType::Output) throw std::runtime_error("unknown plugin type"); - } if (plugin_name == nullptr || plugin_description == nullptr) throw std::runtime_error("plugin returned null metadata"); @@ -287,21 +251,15 @@ int main() { continue; try { + std::vector solution(point_count, SolutionPoint{ 0, 0, 0, 0 }); SharedLibrary solver_library(solver.path); - const auto solve = - solver_library.require(SYMBOL_TRANSFORM); - - std::vector solution( - point_count, - SolutionPoint{0, 0, 0, 0}); + const auto solve = solver_library.require(SYMBOL_SOLVER); solve(¶meters, solution.data(), solution.size()); - validate_solution(solution, parameters); fs::path csv_filename = solver.path.stem(); csv_filename += ".csv"; - const fs::path destination_path = - result_directory / csv_filename; + const fs::path destination_path = result_directory / csv_filename; const std::string destination = destination_path.string(); OutputParameters output_parameters{ @@ -317,9 +275,7 @@ int main() { try { SharedLibrary output_library(output.path); - const auto write = - output_library.require( - SYMBOL_WRITE_OUTPUT); + const auto write = output_library.require(SYMBOL_WRITE_OUTPUT); const int status = write(&output_parameters); if (status != 0){