From e99ac651b8c11ad26db672cae86e117948ae4cb9 Mon Sep 17 00:00:00 2001 From: Tor Andre Haugdahl Date: Tue, 1 Oct 2024 12:07:30 +0200 Subject: [PATCH 1/2] Add snapshot frequency to Euler Forward driver and print disable flag. Add snapshot frequency for euler forward and printer disable flag for CSV printer --- include/marco/Runtime/Printers/CSV/Options.h | 1 + include/marco/Runtime/Simulation/Runtime.h | 1 + .../Runtime/Solvers/EulerForward/Options.h | 1 + lib/Drivers/EulerForward/CLI.cpp | 4 +- lib/Drivers/EulerForward/Driver.cpp | 104 +++++++++--------- lib/Printers/CSV/CLI.cpp | 10 +- lib/Printers/CSV/Printer.cpp | 87 +++++++-------- lib/Simulation/Runtime.cpp | 1 + 8 files changed, 107 insertions(+), 102 deletions(-) diff --git a/include/marco/Runtime/Printers/CSV/Options.h b/include/marco/Runtime/Printers/CSV/Options.h index ce7546aaa..a8281101c 100644 --- a/include/marco/Runtime/Printers/CSV/Options.h +++ b/include/marco/Runtime/Printers/CSV/Options.h @@ -7,6 +7,7 @@ namespace marco::runtime::printing { bool scientificNotation = false; unsigned int precision = 9; + bool disablePrinting = false; }; PrintOptions& printOptions(); diff --git a/include/marco/Runtime/Simulation/Runtime.h b/include/marco/Runtime/Simulation/Runtime.h index af3cfb0c7..1ce58cc6c 100644 --- a/include/marco/Runtime/Simulation/Runtime.h +++ b/include/marco/Runtime/Simulation/Runtime.h @@ -34,6 +34,7 @@ namespace marco::runtime std::vector derOrders; + private: Printer* printer; }; diff --git a/include/marco/Runtime/Solvers/EulerForward/Options.h b/include/marco/Runtime/Solvers/EulerForward/Options.h index 0b5973af3..08e555e89 100644 --- a/include/marco/Runtime/Solvers/EulerForward/Options.h +++ b/include/marco/Runtime/Solvers/EulerForward/Options.h @@ -8,6 +8,7 @@ namespace marco::runtime::eulerforward struct Options { double timeStep = 0.1; + std::size_t snapshotSteps = 1; }; Options& getOptions(); diff --git a/lib/Drivers/EulerForward/CLI.cpp b/lib/Drivers/EulerForward/CLI.cpp index c682439c2..19f012f00 100644 --- a/lib/Drivers/EulerForward/CLI.cpp +++ b/lib/Drivers/EulerForward/CLI.cpp @@ -8,7 +8,8 @@ std::string CommandLineOptions::getTitle() const { return "Euler forward"; } void CommandLineOptions::printCommandLineOptions(std::ostream &os) const { // clang-format off - os << " --time-step= Set the time step (in seconds). Defaults to " << getOptions().timeStep << "." << std::endl; + os << " --time-step= Set the time step (in seconds). Defaults to " << getOptions().timeStep << "." << std::endl; + os << " --snapshot-steps= Print simulation state every time steps. Defaults to " << getOptions().snapshotSteps << "." << std::endl; // clang-format on } @@ -16,6 +17,7 @@ void CommandLineOptions::parseCommandLineOptions( const argh::parser &options) const { // clang-format off options("time-step") >> getOptions().timeStep; + options("snapshot-steps") >> getOptions().snapshotSteps; // clang-format on } } // namespace marco::runtime::eulerforward diff --git a/lib/Drivers/EulerForward/Driver.cpp b/lib/Drivers/EulerForward/Driver.cpp index ab2343036..b0d54e6f6 100644 --- a/lib/Drivers/EulerForward/Driver.cpp +++ b/lib/Drivers/EulerForward/Driver.cpp @@ -1,77 +1,79 @@ #include "marco/Runtime/Drivers/EulerForward/Driver.h" #include "marco/Runtime/Drivers/EulerForward/CLI.h" -#include "marco/Runtime/Solvers/EulerForward/Options.h" -#include "marco/Runtime/Solvers/EulerForward/Profiler.h" #include "marco/Runtime/Simulation/Options.h" #include "marco/Runtime/Simulation/Profiler.h" #include "marco/Runtime/Simulation/Runtime.h" +#include "marco/Runtime/Solvers/EulerForward/Options.h" +#include "marco/Runtime/Solvers/EulerForward/Profiler.h" #include -namespace marco::runtime -{ - EulerForward::EulerForward(Simulation* simulation) - : Driver(simulation) - { - } +namespace marco::runtime { +EulerForward::EulerForward(Simulation *simulation) : Driver(simulation) {} #ifdef CLI_ENABLE - std::unique_ptr EulerForward::getCLIOptions() - { - return std::make_unique(); - } +std::unique_ptr EulerForward::getCLIOptions() { + return std::make_unique(); +} #endif // CLI_ENABLE - int EulerForward::run() - { - if (marco::runtime::simulation::getOptions().debug) { - std::cerr << "[Euler Forward] Starting simulation" << std::endl; - } - - double time; +int EulerForward::run() { + if (marco::runtime::simulation::getOptions().debug) { + std::cerr << "[Euler Forward] Starting simulation" << std::endl; + } - do { - // Compute the next values of the state variables. - if (marco::runtime::simulation::getOptions().debug) { - std::cerr << "[Euler Forward] Updating state variables" << std::endl; - } + double time; + std::size_t iterationStep = 0; - EULER_FORWARD_PROFILER_STATEVAR_START; - updateStateVariables(eulerforward::getOptions().timeStep); - EULER_FORWARD_PROFILER_STATEVAR_STOP; + do { + iterationStep++; - // Move to the next step. - if (marco::runtime::simulation::getOptions().debug) { - std::cerr << "[Euler Forward] Updating time and non-state variables" << std::endl; - } + // Compute the next values of the state variables. + if (marco::runtime::simulation::getOptions().debug) { + std::cerr << "[Euler Forward] Updating state variables" << std::endl; + } - EULER_FORWARD_PROFILER_NONSTATEVAR_START; - time = getTime() + eulerforward::getOptions().timeStep; - setTime(time); + EULER_FORWARD_PROFILER_STATEVAR_START; + updateStateVariables(eulerforward::getOptions().timeStep); + EULER_FORWARD_PROFILER_STATEVAR_STOP; - updateNonStateVariables(); - EULER_FORWARD_PROFILER_NONSTATEVAR_STOP; + // Move to the next step. + if (marco::runtime::simulation::getOptions().debug) { + std::cerr << "[Euler Forward] Updating time and non-state variables" + << std::endl; + } - if (marco::runtime::simulation::getOptions().debug) { - std::cerr << "[Euler Forward] Printing values" << std::endl; - } + EULER_FORWARD_PROFILER_NONSTATEVAR_START; + time = getTime() + eulerforward::getOptions().timeStep; + setTime(time); - // Print the values. - getSimulation()->getPrinter()->printValues(); - } while (std::abs(simulation::getOptions().endTime - time) >= - eulerforward::getOptions().timeStep); + updateNonStateVariables(); + EULER_FORWARD_PROFILER_NONSTATEVAR_STOP; if (marco::runtime::simulation::getOptions().debug) { - std::cerr << "[Euler Forward] Simulation finished" << std::endl; + std::cerr << "[Euler Forward] Printing values" << std::endl; } - return EXIT_SUCCESS; + // Print the values at a specified frequency. + if (iterationStep % eulerforward::getOptions().snapshotSteps == 0) { + getSimulation()->getPrinter()->printValues(); + } + + } while (std::abs(simulation::getOptions().endTime - time) >= + eulerforward::getOptions().timeStep); + + iterationStep++; + getSimulation()->getPrinter()->printValues(); + + if (marco::runtime::simulation::getOptions().debug) { + std::cerr << "[Euler Forward] Simulation finished" << std::endl; } + + return EXIT_SUCCESS; } +} // namespace marco::runtime -namespace marco::runtime -{ - std::unique_ptr getDriver(Simulation* simulation) - { - return std::make_unique(simulation); - } +namespace marco::runtime { +std::unique_ptr getDriver(Simulation *simulation) { + return std::make_unique(simulation); } +} // namespace marco::runtime diff --git a/lib/Printers/CSV/CLI.cpp b/lib/Printers/CSV/CLI.cpp index 2a8d393f6..1828d478b 100644 --- a/lib/Printers/CSV/CLI.cpp +++ b/lib/Printers/CSV/CLI.cpp @@ -8,16 +8,18 @@ std::string CommandLineOptions::getTitle() const { return "Formatting"; } void CommandLineOptions::printCommandLineOptions(std::ostream &os) const { // clang-format off - os << " --scientific-notation Print the values using the scientific notation." << std::endl; - os << " --precision= Set the number of decimals to be printed. Defaults to " << printOptions().precision << "." << std::endl; + os << " --scientific-notation Print the values using the scientific notation." << std::endl; + os << " --precision= Set the number of decimals to be printed. Defaults to " << printOptions().precision << "." << std::endl; + os << " --disable-printing Disables output. Useful for testing performance without I/O overhead. Defaults to " << printOptions().disablePrinting << "." << std::endl; // clang-format on } void CommandLineOptions::parseCommandLineOptions( const argh::parser &options) const { // clang-format off - printOptions().scientificNotation = options["scientific-notation"]; - options("precision") >> printOptions().precision; + printOptions().scientificNotation = options["scientific-notation"]; + options("precision") >> printOptions().precision; + printOptions().disablePrinting = options["disable-printing"]; // clang-format on } } // namespace marco::runtime::printing diff --git a/lib/Printers/CSV/Printer.cpp b/lib/Printers/CSV/Printer.cpp index 4cff2843d..945177e8a 100644 --- a/lib/Printers/CSV/Printer.cpp +++ b/lib/Printers/CSV/Printer.cpp @@ -11,8 +11,7 @@ using namespace ::marco::runtime; using namespace ::marco::runtime::printing; -static void printDerWrapOpening(int64_t order) -{ +static void printDerWrapOpening(int64_t order) { for (int64_t i = 0; i < order; ++i) { PRINT_PROFILER_STRING_START; std::cout << "der("; @@ -20,8 +19,7 @@ static void printDerWrapOpening(int64_t order) } } -static void printDerWrapClosing(int64_t order) -{ +static void printDerWrapClosing(int64_t order) { for (int64_t i = 0; i < order; ++i) { PRINT_PROFILER_STRING_START; std::cout << ')'; @@ -29,8 +27,7 @@ static void printDerWrapClosing(int64_t order) } } -static void printName(char* name, int64_t rank, const int64_t* indices) -{ +static void printName(char *name, int64_t rank, const int64_t *indices) { PRINT_PROFILER_STRING_START; std::cout << name; PRINT_PROFILER_STRING_STOP; @@ -58,8 +55,12 @@ static void printName(char* name, int64_t rank, const int64_t* indices) } } -static void printHeader(const Simulation& simulation) -{ +static void printHeader(const Simulation &simulation) { + + if (printOptions().disablePrinting) { + return; + } + PRINT_PROFILER_STRING_START; std::cout << '"' << "time" << '"'; PRINT_PROFILER_STRING_STOP; @@ -85,7 +86,7 @@ static void printHeader(const Simulation& simulation) } assert(baseVar != -1); - char* name = simulation.variablesNames[baseVar]; + char *name = simulation.variablesNames[baseVar]; if (rank == 0) { // Print only the variable name. @@ -104,7 +105,7 @@ static void printHeader(const Simulation& simulation) // Print the name of the array and the indices, for each possible // combination of printable indices. - for (const auto& range : simulation.variablesPrintableIndices[var]) { + for (const auto &range : simulation.variablesPrintableIndices[var]) { auto beginIt = MultidimensionalRangeIterator::begin(range); auto endIt = MultidimensionalRangeIterator::end(range); @@ -130,9 +131,13 @@ static void printHeader(const Simulation& simulation) PRINT_PROFILER_STRING_STOP; } -static void printValues(const Simulation& simulation) -{ - auto& options = printOptions(); +static void printValues(const Simulation &simulation) { + auto &options = printOptions(); + + if (options.disablePrinting) { + return; + } + std::cout.precision(options.precision); if (options.scientificNotation) { @@ -173,7 +178,7 @@ static void printValues(const Simulation& simulation) PRINT_PROFILER_FLOAT_STOP; } else { // Print the components of the array variable. - for (const auto& range : simulation.variablesPrintableIndices[var]) { + for (const auto &range : simulation.variablesPrintableIndices[var]) { auto beginIt = MultidimensionalRangeIterator::begin(range); auto endIt = MultidimensionalRangeIterator::end(range); @@ -197,44 +202,34 @@ static void printValues(const Simulation& simulation) PRINT_PROFILER_STRING_STOP; } -namespace marco::runtime::printing -{ - CSVPrinter::CSVPrinter(Simulation* simulation) - : Printer(simulation) - { - } +namespace marco::runtime::printing { +CSVPrinter::CSVPrinter(Simulation *simulation) : Printer(simulation) {} #ifdef CLI_ENABLE - std::unique_ptr CSVPrinter::getCLIOptions() - { - return std::make_unique(); - } +std::unique_ptr CSVPrinter::getCLIOptions() { + return std::make_unique(); +} #endif // CLI_ENABLE - void CSVPrinter::simulationBegin() - { - SIMULATION_PROFILER_PRINTING_START; - ::printHeader(*getSimulation()); - SIMULATION_PROFILER_PRINTING_STOP; - } +void CSVPrinter::simulationBegin() { + SIMULATION_PROFILER_PRINTING_START; + ::printHeader(*getSimulation()); + SIMULATION_PROFILER_PRINTING_STOP; +} - void CSVPrinter::printValues() - { - SIMULATION_PROFILER_PRINTING_START; - ::printValues(*getSimulation()); - SIMULATION_PROFILER_PRINTING_STOP; - } +void CSVPrinter::printValues() { + SIMULATION_PROFILER_PRINTING_START; + ::printValues(*getSimulation()); + SIMULATION_PROFILER_PRINTING_STOP; +} - void CSVPrinter::simulationEnd() - { - // Do nothing. - } +void CSVPrinter::simulationEnd() { + // Do nothing. } +} // namespace marco::runtime::printing -namespace marco::runtime -{ - std::unique_ptr getPrinter(Simulation* simulation) - { - return std::make_unique(simulation); - } +namespace marco::runtime { +std::unique_ptr getPrinter(Simulation *simulation) { + return std::make_unique(simulation); } +} // namespace marco::runtime diff --git a/lib/Simulation/Runtime.cpp b/lib/Simulation/Runtime.cpp index 0d3bdc5a8..c0954b5c0 100644 --- a/lib/Simulation/Runtime.cpp +++ b/lib/Simulation/Runtime.cpp @@ -270,6 +270,7 @@ namespace dynamicModelEnd(); SIMULATION_PROFILER_DYNAMIC_MODEL_STOP; + // Tell the printer that the simulation has finished. simulation.getPrinter()->simulationEnd(); From 49aade2ddb02d7408a7b2a1f2b2e9c13246ddb29 Mon Sep 17 00:00:00 2001 From: Tor Andre Haugdahl Date: Mon, 14 Oct 2024 13:41:27 +0200 Subject: [PATCH 2/2] Only update nonstate variables when snapshot condition holds for EulerForward --- lib/Drivers/EulerForward/Driver.cpp | 16 +- lib/Simulation/Runtime.cpp | 243 +++++++++++++--------------- 2 files changed, 126 insertions(+), 133 deletions(-) diff --git a/lib/Drivers/EulerForward/Driver.cpp b/lib/Drivers/EulerForward/Driver.cpp index b0d54e6f6..9a75dc883 100644 --- a/lib/Drivers/EulerForward/Driver.cpp +++ b/lib/Drivers/EulerForward/Driver.cpp @@ -26,6 +26,8 @@ int EulerForward::run() { do { iterationStep++; + bool snapshotCondition = + iterationStep % eulerforward::getOptions().snapshotSteps == 0; // Compute the next values of the state variables. if (marco::runtime::simulation::getOptions().debug) { @@ -42,19 +44,21 @@ int EulerForward::run() { << std::endl; } - EULER_FORWARD_PROFILER_NONSTATEVAR_START; - time = getTime() + eulerforward::getOptions().timeStep; - setTime(time); + if (snapshotCondition) { + EULER_FORWARD_PROFILER_NONSTATEVAR_START; + time = getTime() + eulerforward::getOptions().timeStep; + setTime(time); - updateNonStateVariables(); - EULER_FORWARD_PROFILER_NONSTATEVAR_STOP; + updateNonStateVariables(); + EULER_FORWARD_PROFILER_NONSTATEVAR_STOP; + } if (marco::runtime::simulation::getOptions().debug) { std::cerr << "[Euler Forward] Printing values" << std::endl; } // Print the values at a specified frequency. - if (iterationStep % eulerforward::getOptions().snapshotSteps == 0) { + if (snapshotCondition) { getSimulation()->getPrinter()->printValues(); } diff --git a/lib/Simulation/Runtime.cpp b/lib/Simulation/Runtime.cpp index c0954b5c0..c461af7a7 100644 --- a/lib/Simulation/Runtime.cpp +++ b/lib/Simulation/Runtime.cpp @@ -1,12 +1,12 @@ #include "marco/Runtime/Simulation/Runtime.h" #include "marco/Runtime/CLI/CLI.h" +#include "marco/Runtime/Drivers/Driver.h" #include "marco/Runtime/Multithreading/CLI.h" +#include "marco/Runtime/Printers/Printer.h" #include "marco/Runtime/Profiling/Profiling.h" #include "marco/Runtime/Simulation/CLI.h" #include "marco/Runtime/Simulation/Options.h" #include "marco/Runtime/Simulation/Profiler.h" -#include "marco/Runtime/Drivers/Driver.h" -#include "marco/Runtime/Printers/Printer.h" #include #include @@ -16,21 +16,19 @@ using namespace ::marco::runtime; // Functions defined inside the module of the compiled model //===---------------------------------------------------------------------===// -extern "C" -{ - /// Initialize the simulation. - void init(); +extern "C" { +/// Initialize the simulation. +void init(); - /// Deinitialize the simulation. - void deinit(); +/// Deinitialize the simulation. +void deinit(); } //===---------------------------------------------------------------------===// // CLI //===---------------------------------------------------------------------===// -static void printHelp() -{ +static void printHelp() { std::cout << "Modelica simulation.\n"; std::cout << "Model: " << getModelName() << "\n"; std::cout << "Generated with MARCO compiler.\n\n"; @@ -39,7 +37,7 @@ static void printHelp() std::cout << "OPTIONS:\n"; std::cout << " --help Display the available options.\n\n"; - auto& cli = getCLI(); + auto &cli = getCLI(); for (size_t i = 0; i < cli.size(); ++i) { std::cout << cli[i].getTitle() << "\n"; @@ -53,160 +51,152 @@ static void printHelp() // Simulation //===---------------------------------------------------------------------===// -namespace marco::runtime -{ - Printer* Simulation::getPrinter() - { - assert(printer != nullptr); - return printer; - } +namespace marco::runtime { +Printer *Simulation::getPrinter() { + assert(printer != nullptr); + return printer; +} - const Printer* Simulation::getPrinter() const - { - assert(printer != nullptr); - return printer; - } +const Printer *Simulation::getPrinter() const { + assert(printer != nullptr); + return printer; +} - void Simulation::setPrinter(Printer* newPrinter) - { - assert(newPrinter != nullptr); - printer = newPrinter; - } +void Simulation::setPrinter(Printer *newPrinter) { + assert(newPrinter != nullptr); + printer = newPrinter; } +} // namespace marco::runtime -namespace -{ - Simulation runtimeInit() - { - #ifdef MARCO_PROFILING - profilingInit(); - #endif +namespace { +Simulation runtimeInit() { +#ifdef MARCO_PROFILING + profilingInit(); +#endif - Simulation result; + Simulation result; - // Number of array variables of the model (both state and algebraic ones). - int64_t numOfVariables = getNumOfVariables(); + // Number of array variables of the model (both state and algebraic ones). + int64_t numOfVariables = getNumOfVariables(); - // Pre-fetch the names. - result.variablesNames.resize(numOfVariables); + // Pre-fetch the names. + result.variablesNames.resize(numOfVariables); - for (int64_t var = 0; var < numOfVariables; ++var) { - result.variablesNames[var] = getVariableName(var); - } + for (int64_t var = 0; var < numOfVariables; ++var) { + result.variablesNames[var] = getVariableName(var); + } - // Pre-fetch the ranks. - result.variablesRanks.resize(numOfVariables); + // Pre-fetch the ranks. + result.variablesRanks.resize(numOfVariables); - for (int64_t var = 0; var < numOfVariables; ++var) { - result.variablesRanks[var] = getVariableRank(var); - } + for (int64_t var = 0; var < numOfVariables; ++var) { + result.variablesRanks[var] = getVariableRank(var); + } - // Pre-fetch whether each variable is printable. - result.printableVariables.resize(numOfVariables); + // Pre-fetch whether each variable is printable. + result.printableVariables.resize(numOfVariables); - for (int64_t var = 0; var < numOfVariables; ++var) { - result.printableVariables[var] = isPrintable(var); - } + for (int64_t var = 0; var < numOfVariables; ++var) { + result.printableVariables[var] = isPrintable(var); + } - // Pre-fetch the printable indices. - result.variablesPrintableIndices.resize(numOfVariables); - result.variablesPrintOrder.resize(numOfVariables); + // Pre-fetch the printable indices. + result.variablesPrintableIndices.resize(numOfVariables); + result.variablesPrintOrder.resize(numOfVariables); - for (int64_t var = 0; var < numOfVariables; ++var) { - int64_t numOfPrintableRanges = getVariableNumOfPrintableRanges(var); - result.variablesPrintableIndices[var].resize(numOfPrintableRanges); + for (int64_t var = 0; var < numOfVariables; ++var) { + int64_t numOfPrintableRanges = getVariableNumOfPrintableRanges(var); + result.variablesPrintableIndices[var].resize(numOfPrintableRanges); - for (int64_t range = 0; range < numOfPrintableRanges; ++range) { - int64_t rank = result.variablesRanks[var]; - result.variablesPrintableIndices[var][range].resize(rank); + for (int64_t range = 0; range < numOfPrintableRanges; ++range) { + int64_t rank = result.variablesRanks[var]; + result.variablesPrintableIndices[var][range].resize(rank); - for (int64_t dim = 0; dim < rank; ++dim) { - result.variablesPrintableIndices[var][range][dim].begin = - getVariablePrintableRangeBegin(var, range, dim); + for (int64_t dim = 0; dim < rank; ++dim) { + result.variablesPrintableIndices[var][range][dim].begin = + getVariablePrintableRangeBegin(var, range, dim); - result.variablesPrintableIndices[var][range][dim].end = - getVariablePrintableRangeEnd(var, range, dim); - } + result.variablesPrintableIndices[var][range][dim].end = + getVariablePrintableRangeEnd(var, range, dim); } - - result.variablesPrintOrder[var] = var; } - // Pre-fetch the derivatives map. - result.derivativesMap.resize(numOfVariables); + result.variablesPrintOrder[var] = var; + } + + // Pre-fetch the derivatives map. + result.derivativesMap.resize(numOfVariables); - for (int64_t var = 0; var < numOfVariables; ++var) { - result.derivativesMap[var] = -1; - } + for (int64_t var = 0; var < numOfVariables; ++var) { + result.derivativesMap[var] = -1; + } - for (int64_t var = 0; var < numOfVariables; ++var) { - int64_t derivative = getDerivative(var); + for (int64_t var = 0; var < numOfVariables; ++var) { + int64_t derivative = getDerivative(var); - if (derivative != -1) { - result.derivativesMap[derivative] = var; - } + if (derivative != -1) { + result.derivativesMap[derivative] = var; } + } - // Compute the derivative order of each variable. - result.derOrders.resize(numOfVariables); - - for (int64_t var = 0; var < numOfVariables; ++var) { - int64_t currentVar = result.derivativesMap[var]; - int64_t order = 0; + // Compute the derivative order of each variable. + result.derOrders.resize(numOfVariables); - while (currentVar != -1) { - ++order; - currentVar = result.derivativesMap[currentVar]; - } + for (int64_t var = 0; var < numOfVariables; ++var) { + int64_t currentVar = result.derivativesMap[var]; + int64_t order = 0; - result.derOrders[var] = order; + while (currentVar != -1) { + ++order; + currentVar = result.derivativesMap[currentVar]; } - // Determine the print ordering for the variables. - std::sort(result.variablesPrintOrder.begin(), - result.variablesPrintOrder.end(), - [&](const int64_t& x, const int64_t& y) -> bool { - int64_t xDerOrder = result.derOrders[x]; - int64_t yDerOrder = result.derOrders[y]; + result.derOrders[var] = order; + } - if (xDerOrder < yDerOrder) { - return true; - } + // Determine the print ordering for the variables. + std::sort(result.variablesPrintOrder.begin(), + result.variablesPrintOrder.end(), + [&](const int64_t &x, const int64_t &y) -> bool { + int64_t xDerOrder = result.derOrders[x]; + int64_t yDerOrder = result.derOrders[y]; - if (xDerOrder > yDerOrder) { - return false; - } + if (xDerOrder < yDerOrder) { + return true; + } - int64_t first = x; - int64_t second = y; + if (xDerOrder > yDerOrder) { + return false; + } - if (xDerOrder != 0) { - for (int64_t i = 0; i < xDerOrder; ++i) { - first = result.derivativesMap[first]; - } + int64_t first = x; + int64_t second = y; - for (int64_t i = 0; i < yDerOrder; ++i) { - second = result.derivativesMap[second]; - } + if (xDerOrder != 0) { + for (int64_t i = 0; i < xDerOrder; ++i) { + first = result.derivativesMap[first]; } - return std::string_view(result.variablesNames[first]) < - std::string_view(result.variablesNames[second]); - }); + for (int64_t i = 0; i < yDerOrder; ++i) { + second = result.derivativesMap[second]; + } + } - return result; - } + return std::string_view(result.variablesNames[first]) < + std::string_view(result.variablesNames[second]); + }); - void runtimeDeinit(Simulation& simulationInfo) - { - #ifdef MARCO_PROFILING - printProfilingStats(); - #endif - } + return result; } -[[maybe_unused]] int runSimulation(int argc, char* argv[]) -{ +void runtimeDeinit(Simulation &simulationInfo) { +#ifdef MARCO_PROFILING + printProfilingStats(); +#endif +} +} // namespace + +[[maybe_unused]] int runSimulation(int argc, char *argv[]) { // Initialize the runtime library. Simulation simulation = runtimeInit(); @@ -220,7 +210,7 @@ namespace // Parse the command-line arguments. #ifdef CLI_ENABLE SIMULATION_PROFILER_ARG_START; - auto& cli = getCLI(); + auto &cli = getCLI(); cli += simulation::getCLIOptions(); #ifdef THREADS_ENABLE @@ -270,7 +260,6 @@ namespace dynamicModelEnd(); SIMULATION_PROFILER_DYNAMIC_MODEL_STOP; - // Tell the printer that the simulation has finished. simulation.getPrinter()->simulationEnd();