LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
dirac_operator_test.cc
1
7#include <dirac_operator_experiment.h>
8
9using lf::uscalfe::operator-;
10using complex = std::complex<double>;
11
16int main(int argc, char *argv[]) {
17 if (argc != 4 && argc != 5) {
18 std::cerr << "Usage: " << argv[0]
19 << " max_refinement_level min_k max_k step=0.1 " << std::endl;
20 exit(1);
21 }
22
23 double min_k;
24 double max_k;
25 double step = 0.1;
26 const unsigned refinement_level = atoi(argv[1]);
27 sscanf(argv[2], "%lf", &min_k);
28 sscanf(argv[3], "%lf", &max_k);
29 if (argc == 5) sscanf(argv[4], "%lf", &step);
30 std::cout << "max_refinement_level : " << refinement_level << std::endl;
31 std::cout << "min_k : " << min_k << ", max_k = " << max_k
32 << " step = " << step << std::endl;
33
34 // needs to be a reference such that it can be reassigned
35 double &k = min_k;
36
37 std::vector<unsigned> refinement_levels(refinement_level + 1);
38 for (int i = 0; i < refinement_level + 1; i++) {
39 refinement_levels[i] = i;
40 }
41
42 std::vector<double> ks;
43 for (double i = min_k; i <= max_k; i += step) {
44 ks.push_back(i);
45 }
46
47 // mathematica function output requries the following helpers
48 auto Power = [](complex a, complex b) -> complex { return std::pow(a, b); };
49 auto Complex = [](double a, double b) -> complex { return complex(a, b); };
50 auto Sin = [](complex a) -> complex { return std::sin(a); };
51 auto Cos = [](complex a) -> complex { return std::cos(a); };
52 auto Sqrt = [](complex a) -> complex { return std::sqrt(a); };
53
54 // righthandside for the zero and two form
55 auto f_zero = [&](const Eigen::Vector3d &x_vec) -> complex {
56 // first scale to the circle
57 Eigen::Vector3d x_ = x_vec / x_vec.norm();
58 double x = x_(0);
59 double y = x_(1);
60 double z = x_(2);
61
62 // autogenerated by mathematica
63 complex ret = Complex(0, 1) * k * (Cos(y) + Sin(x) + Sin(z)) +
64 (x * z * Cos(x) + x * y * Cos(y) + y * z * Cos(z) +
65 2 * z * Sin(x) + 2 * x * Sin(y) + 2 * y * Sin(z)) /
66 (Power(x, 2) + Power(y, 2) + Power(z, 2));
67 return ret;
68 };
69
70 // righthandside for the one form
71 auto f_one = [&](const Eigen::Vector3d &x_vec) -> Eigen::VectorXcd {
72 // first scale to the circle
73 Eigen::Vector3d x_ = x_vec / x_vec.norm();
74 double x = x_(0);
75 double y = x_(1);
76 double z = x_(2);
77
78 // autogenerated by mathematica
79 Eigen::VectorXcd ret(3);
80 ret << ((Power(y, 2) + Power(z, 2)) * Cos(x) - x * z * Cos(z) +
81 x * y * Sin(y) +
82 Sqrt(Power(x, 2) + Power(y, 2) + Power(z, 2)) *
83 (y * Cos(z) + z * Sin(y)) -
84 Complex(0, 1) * k *
85 (x * z * Sin(x) - (Power(y, 2) + Power(z, 2)) * Sin(y) +
86 x * y * Sin(z))) /
87 (Power(x, 2) + Power(y, 2) + Power(z, 2)),
88 -((x * y * Cos(x) + y * z * Cos(z) +
89 Sqrt(Power(x, 2) + Power(y, 2) + Power(z, 2)) *
90 (-(z * Cos(x)) + x * Cos(z)) +
91 (Power(x, 2) + Power(z, 2)) * Sin(y) +
92 Complex(0, 1) * k *
93 (y * z * Sin(x) + x * y * Sin(y) -
94 (Power(x, 2) + Power(z, 2)) * Sin(z))) /
95 (Power(x, 2) + Power(y, 2) + Power(z, 2))),
96 (-(x * z * Cos(x)) + (Power(x, 2) + Power(y, 2)) * Cos(z) +
97 y * z * Sin(y) -
98 Sqrt(Power(x, 2) + Power(y, 2) + Power(z, 2)) *
99 (y * Cos(x) + x * Sin(y)) +
100 Complex(0, 1) * k *
101 ((Power(x, 2) + Power(y, 2)) * Sin(x) -
102 z * (x * Sin(y) + y * Sin(z)))) /
103 (Power(x, 2) + Power(y, 2) + Power(z, 2));
104 return ret;
105 };
106
107 // righthandside for the two form
108 auto f_two = [&](const Eigen::Vector3d &x_vec) -> complex {
109 // first scale to the circle
110 Eigen::Vector3d x_ = x_vec / x_vec.norm();
111 double x = x_(0);
112 double y = x_(1);
113 double z = x_(2);
114
115 // autogenerated by mathematica
116 complex ret = (y * Cos(x) + z * Cos(y) + x * Cos(z)) /
117 Sqrt(Power(x, 2) + Power(y, 2) + Power(z, 2)) +
118 Complex(0, 1) * k * (Cos(y) + Sin(x) + Sin(z));
119 return ret;
120 };
121
122 // Compute the analytic solution of the problem
123 auto u_zero = [&](const Eigen::Vector3d x_vec) -> complex {
124 // first scale to the circle
125 Eigen::Vector3d x_ = x_vec / x_vec.norm();
126 double x = x_(0);
127 double y = x_(1);
128 double z = x_(2);
129
130 return Cos(y) + Sin(x) + Sin(z);
131 };
132
133 // Compute the analytic solution of the problem
134 auto u_one = [&](const Eigen::Vector3d x_vec) -> Eigen::Vector3cd {
135 // first scale to the circle
136 Eigen::Vector3d x_ = x_vec / x_vec.norm();
137 double x = x_(0);
138 double y = x_(1);
139 double z = x_(2);
140
141 Eigen::VectorXcd ret(3);
142
143 // mathematica autocompute
144 ret << (-(x * z * Sin(x)) + (Power(y, 2) + Power(z, 2)) * Sin(y) -
145 x * y * Sin(z)) /
146 (Power(x, 2) + Power(y, 2) + Power(z, 2)),
147 (-(y * z * Sin(x)) - x * y * Sin(y) +
148 (Power(x, 2) + Power(z, 2)) * Sin(z)) /
149 (Power(x, 2) + Power(y, 2) + Power(z, 2)),
150 ((Power(x, 2) + Power(y, 2)) * Sin(x) - z * (x * Sin(y) + y * Sin(z))) /
151 (Power(x, 2) + Power(y, 2) + Power(z, 2));
152 return ret;
153 };
154
155 // Compute the analytic solution of the problem
156 auto u_two = [&](const Eigen::Vector3d x_vec) -> complex {
157 // first scale to the circle
158 Eigen::Vector3d x_ = x_vec / x_vec.norm();
159 double x = x_(0);
160 double y = x_(1);
161 double z = x_(2);
162
163 return Cos(y) + Sin(x) + Sin(z);
164 };
165
167 u_zero, u_one, u_two, f_zero, f_one, f_two, k, "test");
168
169 experiment.Compute(refinement_levels, ks);
170
171 return 0;
172}
Creates and solves the discretised Dirac Operator source problems for a given list of levels and valu...