/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/physics/integration/optimize.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/physics/integration/optimize.hh Source File
DiFfRG
optimize.hh
Go to the documentation of this file.
1#pragma once
2
5
6namespace DiFfRG
7{
8 template <typename Regulator, int dim = 4> double optimize_x_extent(const JSONValue &json)
9 {
10 static bool already_run = false;
11 static double x_extent = 1.;
12
13 if (already_run) return x_extent;
14
15 const uint order = json.get_uint("/integration/x_order");
16 const int verbosity = json.get_int("/output/verbosity");
17 const double x_extent_tolerance = json.get_double("/integration/x_extent_tolerance");
18 constexpr uint quadrature_factor = 8;
19 auto optimize_x = [](double x) -> double { return 1. / (x + Regulator::RB(1., x)) * Regulator::RBdot(1., x); };
20
21 // Optimize the extent of the momentum integral
22 // we will integrate the optimize_x function over the intervals I1 = [0, x_extent], I2 = [0, x_extent * 2] and I3
23 // = [0, x_extent * 10] and then search for an x_extent such that (I2 + I1) / I1 < x_extent_tolerance and (I2 +
24 // I3) / I2 < x_extent_tolerance
25
26 const dealii::QGauss<1> quadrature_1(quadrature_factor * 1 * order);
27 const dealii::QGauss<1> quadrature_2(quadrature_factor * 2 * order);
28 const dealii::QGauss<1> quadrature_3(quadrature_factor * 10 * order);
29
30 double eps1 = 1., eps2 = 1.;
31 uint decrease_counter = 0;
32
33 if (verbosity > 1) std::cout << "Optimizing x_extent" << std::endl;
34
35 bool all_zero = true;
36 for (uint i = 0; i < 10; i++) {
37 const double x = 1. + 1e-3 + (std::pow(1.5, (double)i) - 1.);
38 const double x_test = optimize_x(x);
39 if (!is_close(x_test, 0.)) all_zero = false;
40 }
41 if (all_zero) {
42 x_extent = 1.;
43 if (verbosity > 1) std::cout << "x_extent is set to 1.\n" << std::endl;
44 already_run = true;
45 return x_extent;
46 }
47
48 while (eps1 > x_extent_tolerance || eps2 > x_extent_tolerance) {
49 const double I1 = LoopIntegrals::integrate<double, 4>(optimize_x, quadrature_1, x_extent, 1.);
50 const double I2 = LoopIntegrals::integrate<double, 4>(optimize_x, quadrature_2, 2. * x_extent, 1.);
51 const double I3 = LoopIntegrals::integrate<double, 4>(optimize_x, quadrature_3, 10. * x_extent, 1.);
52
53 if (std::abs((I2 - I1) / I1) > eps1 && std::abs((I2 - I3) / I2) > eps2)
54 decrease_counter++;
55 else
56 decrease_counter = 0;
57 if (decrease_counter > 2)
58 throw std::runtime_error("Cannot reach requested precision for x_extent - increase x_quadrature_order or "
59 "decrease x_extent_tolerance.");
60
61 eps1 = std::abs((I2 - I1) / I1);
62 eps2 = std::abs((I2 - I3) / I2);
63
64 if (verbosity > 1)
65 std::cout << "x_extent: " << x_extent << " I1: " << I1 << " I2: " << I2 << " I3: " << I3 << " eps1: " << eps1
66 << " eps2: " << eps2 << std::endl;
67
68 if (eps1 > x_extent_tolerance || eps2 > x_extent_tolerance) x_extent *= 1.15;
69 }
70 if (verbosity > 1) std::cout << "Optimizing x_extent done.\n" << std::endl;
71
72 already_run = true;
73 return x_extent;
74 }
75} // namespace DiFfRG
A wrapper around the boost json value class.
Definition json.hh:19
double get_double(const std::string &key) const
Get the value of a key in the json object.
int get_int(const std::string &key) const
Get the value of a key in the json object.
uint get_uint(const std::string &key) const
Get the value of a key in the json object.
NT integrate(const FUN &fun, const QGauss< 1 > &x_quadrature, const double x_extent, const double k)
Performs the integral.
Definition loop_integrals.hh:35
Definition complex_math.hh:10
bool KOKKOS_INLINE_FUNCTION is_close(T1 a, T2 b, T3 eps_)
Function to evaluate whether two floats are equal to numerical precision. Tests for both relative and...
Definition math.hh:168
unsigned int uint
Definition utils.hh:24
double optimize_x_extent(const JSONValue &json)
Definition optimize.hh:8