Chi-Tech
lbs_adjoint.cc
Go to the documentation of this file.
1#include "lbs_adjoint.h"
2
3#include "math/chi_math.h"
5
6#include "chi_runtime.h"
7#include "chi_runtime.h"
8#include "chi_log.h"
9
11{
12 std::cout << "Test Function!\n";
13}
14
15std::array<double,2> lbs::
16 MakeExpRepFromP1(const std::array<double, 4> &P1_moments,
17 bool verbose/*=false*/)
18{
19 //=============================================
20 // Custom function to implement the non-linear equations
21 // that make up the system to solve the a and b coefficients
22 // of an exponential representation of the form exp(a + b*mu).
23 // The coefficients must be such that the following equations
24 // hold:
25 // 2\pi \int_{-1}^{+1} e^{a + b\mu} d\mu = \phi
26 // 2\pi \int_{-1}^{+1} e^{a + b\mu} \mu d\mu = ||J||_2
27 //
28 // These integrals are analytical in \mu and therefore results
29 // in the equations for the F-method. The Jacobian matrix is returned
30 // with the J-method.
31 //
32 // Note that the function only accept the current normalized with
33 // 1/phi. So phi is always 1.0.
34 class CustomF : public chi_math::NonLinearFunction
35 {
36 private:
37 double J_x, J_y, J_z;
38
39 public:
40 /**Constructor. Parameters are the 3 components of the currents
41 * normalized with 1/phi.*/
42 explicit CustomF(const std::array<double,3>& input) :
43 J_x(input[0]), J_y(input[1]), J_z(input[2]) {}
44
45 /**Function evaluation at vector-x.*/
46 VecDbl F(const VecDbl& x) const override
47 {
48 assert(x.size() == 2);
49 const double a = x[0];
50 const double b = x[1];
51 const double FOUR_PI = 4.0*M_PI;
52
53 double size_J = chi_math::Vec2Norm({J_x, J_y, J_z});
54
55 return {(FOUR_PI/b) * exp(a) * sinh(b) - 1.0,
56 (FOUR_PI/b/b) * exp(a) * (b * cosh(b) - sinh(b)) - size_J};
57
58 }
59 /**Jacobian evaluation at vector-x.*/
60 MatDbl J(const VecDbl& x) const override
61 {
62 assert(x.size() == 2);
63 const double a = x[0];
64 const double b = x[1];
65 const double FOUR_PI = 4.0*M_PI;
66
67 return {{(FOUR_PI/b) * exp(a) * sinh(b),
68 (FOUR_PI/b/b) * exp(a) * (b * cosh(b) - sinh(b))},
69 {(FOUR_PI/b/b) * exp(a) * (b * cosh(b) - sinh(b)),
70 (FOUR_PI/b/b/b) * exp(a) * ((b*b + 2) * sinh(b) - 2 * b * cosh(b))}};
71 }
72 };
73
74 //======================================== Convert P1 moments to phi and J
75 double phi = P1_moments[0];
76 double J_x = P1_moments[1];
77 double J_y = P1_moments[2];
78 double J_z = P1_moments[3];
79
80 //======================================== Compute initial ratio size_J/phi
81 double size_J_i = chi_math::Vec2Norm({J_x, J_y, J_z});
82 double ratio_i = size_J_i/phi;
83
84 if (phi < 1.0e-10 or ratio_i > 0.9)
85 { J_x *= 0.9 / size_J_i; J_y *= 0.9 / size_J_i; J_z *= 0.9 / size_J_i; }
86 else
87 { J_x /= phi; J_y /= phi; J_z /= phi; }
88
89 double size_J_f = chi_math::Vec2Norm({J_x, J_y, J_z});
90 double ratio_f = size_J_f;
91
92 if (verbose)
93 {
94 std::stringstream outstr;
95 outstr << "P1 moments initial: " <<P1_moments[0]<<" "
96 <<P1_moments[1]<<" "
97 <<P1_moments[2]<<" "
98 <<P1_moments[3]<<" |J|=";
99 outstr << size_J_i << " ratio=" << ratio_i << "\n";
100 outstr << "P1 moments initial: " <<1.0<<" "<<J_x<<" "<<J_y<<" "<<J_z<<" |J|=";
101 outstr << size_J_f << " ratio=" << ratio_f << "\n";
102
103 Chi::log.Log() << outstr.str();
104 }
105
106 if (size_J_f < 1.0e-10)
107 {
108 double a = log(phi/4.0/M_PI);
109 double b = 0.0;
110
111 if (verbose) { Chi::log.Log() << "Solution: " << a << " " << b; }
112
113 return {a, b};
114 }
115 else
116 {
117 CustomF custom_function({J_x, J_y, J_z});
118 auto solution = chi_math::NewtonIteration(
119 custom_function, //Non-linear function
120 {1.0,0.1}, //Initial guess
121 100, //Max iterations
122 1.0e-8, //Tolerance
123 verbose); //Verbose output?
124
125 double a = solution[0];
126 double b = solution[1];
127
128 if (verbose) { Chi::log.Log() << "Solution: " << a << " " << b; }
129
130 return {a, b};
131 }
132}
static chi::ChiLog & log
Definition: chi_runtime.h:81
LogStream Log(LOG_LVL level=LOG_0)
Definition: chi_log.cc:35
virtual MatDbl J(const VecDbl &x) const
virtual VecDbl F(const VecDbl &x) const
VecDbl NewtonIteration(const NonLinearFunction &non_linear_function, const VecDbl &x_0, unsigned int max_iters, double epsilon, bool verbose=false)
double Vec2Norm(const VecDbl &x)
std::vector< VecDbl > MatDbl
Definition: lbs_structs.h:19
void TestFunction()
Definition: lbs_adjoint.cc:10
std::array< double, 2 > MakeExpRepFromP1(const std::array< double, 4 > &P1_moments, bool verbose=false)
Definition: lbs_adjoint.cc:16
std::vector< double > VecDbl
Definition: lbs_structs.h:18