MySources/simulationhistoryplotter.hpp

153 lines
5.3 KiB
C++
Raw Normal View History

2020-11-27 11:47:21 +01:00
#ifndef SIMULATIONHISTORYPLOTTER_HPP
#define SIMULATIONHISTORYPLOTTER_HPP
2021-04-08 20:03:23 +02:00
#include "simulationmesh.hpp"
#include "simulation_structs.hpp"
2020-11-27 11:47:21 +01:00
#include "utilities.hpp"
#include <algorithm>
#include <matplot/matplot.h>
struct SimulationResultsReporter {
using VertexType = VCGEdgeMesh::VertexType;
using CoordType = VCGEdgeMesh::CoordType;
SimulationResultsReporter() {}
void writeStatistics(const SimulationResults &results,
const std::string &reportFolderPath) {
ofstream file;
file.open(
std::filesystem::path(reportFolderPath).append("results.txt").string());
const size_t numberOfSteps = results.history.numberOfSteps;
file << "Number of steps " << numberOfSteps << "\n";
// file << "Force threshold used " << 1000 << "\n";
// assert(numberOfSteps == results.history.potentialEnergy.size() &&
// numberOfSteps == results.history.residualForces.size());
// Write kinetic energies
const SimulationHistory &history = results.history;
if (!history.kineticEnergy.empty()) {
file << "Kinetic energies"
<< "\n";
for (size_t step = 0; step < numberOfSteps; step++) {
file << history.kineticEnergy[step] << "\n";
}
file << "\n";
}
if (!history.residualForces.empty()) {
file << "Residual forces"
<< "\n";
for (size_t step = 0; step < numberOfSteps; step++) {
file << history.residualForces[step] << "\n";
}
file << "\n";
}
if (!history.potentialEnergies.empty()) {
file << "Potential energies"
<< "\n";
for (size_t step = 0; step < numberOfSteps; step++) {
file << history.potentialEnergies[step] << "\n";
}
file << "\n";
}
file.close();
}
void reportResults(const std::vector<SimulationResults> &results,
const std::string &reportFolderPath,
const std::string &graphSuffix = std::string()) {
2020-11-27 11:47:21 +01:00
if (results.empty()) {
return;
}
// std::filesystem::remove_all(debuggerFolder);
std::filesystem::create_directory(reportFolderPath);
for (const SimulationResults &simulationResult : results) {
const auto simulationResultPath =
std::filesystem::path(reportFolderPath)
.append(simulationResult.getLabel());
2020-11-27 11:47:21 +01:00
std::filesystem::create_directory(simulationResultPath.string());
createPlots(simulationResult.history, simulationResultPath.string(),
graphSuffix);
writeStatistics(simulationResult, simulationResultPath.string());
2020-11-27 11:47:21 +01:00
}
}
static void createPlot(const std::string &xLabel, const std::string &yLabel,
const std::vector<double> &XvaluesToPlot,
2020-11-27 11:47:21 +01:00
const std::vector<double> &YvaluesToPlot,
const std::string &saveTo = {}) {
// matplot::figure(true);
2020-11-27 11:47:21 +01:00
matplot::xlabel(xLabel);
matplot::ylabel(yLabel);
matplot::grid(matplot::on);
matplot::scatter(XvaluesToPlot, YvaluesToPlot);
if (!saveTo.empty()) {
matplot::save(saveTo);
}
}
static void createPlot(const std::string &xLabel, const std::string &yLabel,
const std::vector<double> &YvaluesToPlot,
const std::string &saveTo = {}) {
auto x =
matplot::linspace(0, YvaluesToPlot.size() - 1, YvaluesToPlot.size());
createPlot(xLabel, yLabel, x, YvaluesToPlot, saveTo);
2021-01-12 13:40:25 +01:00
// matplot::figure(true);
2020-11-27 11:47:21 +01:00
// matplot::hold(matplot::on);
// ->marker_indices(history.redMarks)
// ->marker_indices(truncatedRedMarks)
// .marker_color("r")
// ->marker_size(1)
;
2020-11-27 11:47:21 +01:00
// auto greenMarksY = matplot::transform(
// history.greenMarks, [&](auto x) { return history.kineticEnergy[x];
// });
// matplot::scatter(history.greenMarks, greenMarksY)
// ->color("green")
// .marker_size(10);
// matplot::hold(matplot::off);
}
void createPlots(const SimulationHistory &history,
const std::string &reportFolderPath,
const std::string &graphSuffix) {
const auto graphsFolder =
std::filesystem::path(reportFolderPath).append("Graphs");
std::filesystem::remove_all(graphsFolder);
std::filesystem::create_directory(graphsFolder.string());
if (!history.kineticEnergy.empty()) {
createPlot("Number of Iterations", "Log of Kinetic Energy",
history.kineticEnergy,
std::filesystem::path(graphsFolder)
.append("KineticEnergy" + graphSuffix + ".png")
.string());
}
if (!history.residualForces.empty()) {
createPlot("Number of Iterations", "Residual Forces norm",
history.residualForces,
std::filesystem::path(graphsFolder)
.append("ResidualForces" + graphSuffix + ".png")
.string());
}
if (!history.potentialEnergies.empty()) {
createPlot("Number of Iterations", "Potential energy",
history.potentialEnergies,
std::filesystem::path(graphsFolder)
.append("PotentialEnergy" + graphSuffix + ".png")
.string());
}
}
};
#endif // SIMULATIONHISTORYPLOTTER_HPP