OGS
CubicRoots.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <algorithm>
7#include <limits>
8#include <range/v3/algorithm/min.hpp>
9#include <range/v3/algorithm/sort.hpp>
10#include <range/v3/range/conversion.hpp>
11#include <range/v3/view/filter.hpp>
12#include <vector>
13
14#include "BaseLib/Error.h"
15#include "cubic_roots.hpp"
16namespace MathLib
17{
18
20{
21public:
22 CubicSolver(const double a, const double b, const double c, const double d)
23 : a_(a), b_(b), c_(c), d_(d)
24 {
25 if (std::abs(a_) < 1e-9)
26 {
27 OGS_FATAL("'a' must be non-zero for a cubic equation.");
28 }
29 }
30
31 std::vector<double> solve()
32 {
33 std::array<double, 3> const roots =
34 boost::math::tools::cubic_roots<double>(a_, b_, c_, d_);
35
36 std::vector<double> adjusted_roots;
37 adjusted_roots.reserve(3);
38
39 double last_valid = std::numeric_limits<double>::quiet_NaN();
40
41 for (auto root : roots)
42 {
43 if (std::isnan(root))
44 {
45 if (!std::isnan(last_valid))
46 {
47 adjusted_roots.push_back(last_valid);
48 }
49 // If we get NaN before any valid root, we just skip it
50 }
51 else
52 {
53 adjusted_roots.push_back(root);
54 last_valid = root;
55 }
56 }
57
58 ranges::sort(adjusted_roots);
59 return adjusted_roots;
60 }
61 // Method that returns the smallest positive real root
63 {
64 std::vector<double> const roots = solve();
65
66 auto positive_roots =
67 roots | ranges::views::filter([](double root) { return root > 0; });
68
69 // If no positive root exists, return NaN
70 if (ranges::empty(positive_roots))
71 {
72 return std::numeric_limits<double>::quiet_NaN();
73 }
74
75 return ranges::min(positive_roots);
76 }
77
78private:
79 double a_, b_, c_, d_; // Coefficients of the cubic equation
80};
81
82} // namespace MathLib
#define OGS_FATAL(...)
Definition Error.h:19
double smallestPositiveRealRoot()
Definition CubicRoots.h:62
CubicSolver(const double a, const double b, const double c, const double d)
Definition CubicRoots.h:22
std::vector< double > solve()
Definition CubicRoots.h:31