diff --git a/MathLib/Curve/CreatePiecewiseLinearCurve.cpp b/MathLib/Curve/CreatePiecewiseLinearCurve.cpp index e52be4fa8dcdd373ba29e5fae97315ca4a0d096f..b7cc4950de6b1e70f1e854c751ff42413b86ae3c 100644 --- a/MathLib/Curve/CreatePiecewiseLinearCurve.cpp +++ b/MathLib/Curve/CreatePiecewiseLinearCurve.cpp @@ -12,21 +12,91 @@ #include "CreatePiecewiseLinearCurve.h" +#include <boost/endian/conversion.hpp> +#include <fstream> +#include <iostream> +#include <vector> + #include "BaseLib/ConfigTree.h" #include "BaseLib/Error.h" +#include "BaseLib/FileTools.h" +#include "BaseLib/StringTools.h" namespace MathLib { +std::vector<double> readDoublesFromBinaryFile(const std::string& filename) +{ + auto prj_dir = BaseLib::getProjectDirectory(); + std::string path_to_file = BaseLib::joinPaths(prj_dir, filename); + + std::ifstream file(path_to_file, std::ios::binary); + if (!file) + { + OGS_FATAL("File {:s} at path {:s} for curve definition not found", + filename, prj_dir); + } + + // Determine file size + file.seekg(0, std::ios::end); + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + + // Initialize vector with the right size + std::vector<double> result(size / sizeof(double)); + + // read data directly into the vector + if (!file.read(reinterpret_cast<char*>(result.data()), size)) + { + OGS_FATAL("Could not read curve definition from file {:s}.", filename); + } + + if constexpr (std::endian::native != std::endian::little) + { + // swap endians if needed + std::transform( + result.begin(), result.end(), result.begin(), + [](double value) + { + return std::bit_cast<double>(boost::endian::endian_reverse( + std::bit_cast<uint64_t>(value))); + }); + } + + return result; +} + PiecewiseLinearCurveConfig parsePiecewiseLinearCurveConfig( BaseLib::ConfigTree const& config) { - auto x = - //! \ogs_file_param{curve__coords} - config.getConfigParameter<std::vector<double>>("coords"); - auto y = - //! \ogs_file_param{curve__values} - config.getConfigParameter<std::vector<double>>("values"); + const bool read_from_file = //! \ogs_file_param{curve__read_from_file} + config.getConfigParameter<bool>("read_from_file", false); + + std::vector<double> x; + std::vector<double> y; + + if (read_from_file == true) + { + auto const coords_file_name = + //! \ogs_file_param{curve__coords} + config.getConfigParameter<std::string>("coords"); + auto const values_file_name = + //! \ogs_file_param{curve__values} + config.getConfigParameter<std::string>("values"); + + x = readDoublesFromBinaryFile(coords_file_name); + + y = readDoublesFromBinaryFile(values_file_name); + } + else + { + x = + //! \ogs_file_param{curve__coords} + config.getConfigParameter<std::vector<double>>("coords"); + y = + //! \ogs_file_param{curve__values} + config.getConfigParameter<std::vector<double>>("values"); + } if (x.empty() || y.empty()) { diff --git a/MathLib/Curve/CreatePiecewiseLinearCurve.h b/MathLib/Curve/CreatePiecewiseLinearCurve.h index f1f45fccb867750b096332d40a382b7748f61c52..b1b7a1246904b1478341ca307c528459d5483061 100644 --- a/MathLib/Curve/CreatePiecewiseLinearCurve.h +++ b/MathLib/Curve/CreatePiecewiseLinearCurve.h @@ -28,6 +28,8 @@ struct PiecewiseLinearCurveConfig std::vector<double> ys; }; +std::vector<double> readDoublesFromBinaryFile(const std::string& filename); + PiecewiseLinearCurveConfig parsePiecewiseLinearCurveConfig( BaseLib::ConfigTree const& config);