BubbleProfiler  0.3.0
by Peter Athron, Csaba Balazs, Michael Bardsley, Andrew Fowlie, Dylan Harries & Graham White
kink_profile_guesser.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of BubbleProfiler.
3  *
4  * BubbleProfiler is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * BubbleProfiler is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with BubbleProfiler. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
23 #include "kink_profile_guesser.hpp"
24 #include "error.hpp"
25 #include "field_profiles.hpp"
26 #include "math_wrappers.hpp"
27 #include "potential.hpp"
28 #include "rotation.hpp"
30 
31 #include <boost/math/tools/roots.hpp>
32 
33 namespace BubbleProfiler {
34 
35 const std::array<double,50> Kink_profile_guesser::alpha_grid_thin_3d = {{
36  0.5001, 0.500527, 0.500953, 0.50138, 0.501806, 0.502233, 0.502659,
37  0.503086, 0.503512, 0.503939, 0.504365, 0.504792, 0.505218, 0.505645,
38  0.506071, 0.506498, 0.506924, 0.507351, 0.507778, 0.508204, 0.508631,
39  0.509057, 0.509484, 0.50991, 0.510337, 0.510763, 0.51119, 0.511616,
40  0.512043, 0.512469, 0.512896, 0.513322, 0.513749, 0.514176, 0.514602,
41  0.515029, 0.515455, 0.515882, 0.516308, 0.516735, 0.517161, 0.517588,
42  0.518014, 0.518441, 0.518867, 0.519294, 0.51972, 0.520147, 0.520573,
43  0.521}};
44 
45 const std::array<double,46> Kink_profile_guesser::alpha_grid_3d = {{
46  0.52, 0.525, 0.53, 0.535, 0.54, 0.545, 0.55, 0.555, 0.56, 0.565,
47  0.57, 0.575, 0.58, 0.585, 0.59, 0.595, 0.600, 0.605, 0.61, 0.615,
48  0.62, 0.625, 0.63, 0.635, 0.64, 0.645, 0.65, 0.655, 0.66, 0.665,
49  0.67, 0.675, 0.68, 0.685, 0.69, 0.695, 0.7, 0.705, 0.71, 0.715,
50  0.72, 0.725, 0.73, 0.735, 0.74, 0.745
51 }};
52 
53 const std::array<double,46> Kink_profile_guesser::phi0_grid_3d = {{
54  0.999937813492861, 0.9998455972594864, 0.999652910051955,
55  0.9992783058948789, 0.9986121924679547, 0.9975330072377783,
56  0.9959228817337971, 0.9936814248400437, 0.9907300277928794,
57  0.9870109949684415, 0.982483019871098, 0.9771146067103315,
58  0.970878370010354, 0.9637457498588253, 0.9556829606935944,
59  0.9466496322134932, 0.9365966418954739, 0.9254664043974916,
60  0.9131939076638974, 0.8997081810874542, 0.8849327027971878,
61  0.8687916528072536, 0.8512041830047752, 0.8320951904597592,
62  0.8113942473212112, 0.7890322303569218, 0.7649566854809807,
63  0.739107381734247, 0.7114770571965077, 0.6820156405313316,
64  0.6507569028925989, 0.6176739734302936, 0.582774829968536,
65  0.5461906624510391, 0.5080001141498214, 0.46818937520654036,
66  0.4271774192183204, 0.3846163877046799, 0.3412559463076824,
67  0.296820457223674, 0.2527890892404611, 0.20800300649099204,
68  0.16344942922240233, 0.1202112946983806, 0.07758879848049229,
69  0.037771036089571164
70 }};
71 
72 const std::array<double,46> Kink_profile_guesser::delta_grid_3d = {{
73  16.922965327830823, 13.571272753610996, 11.331058461502998,
74  9.72627170004579, 8.519044051949859, 7.5773396148807715,
75  6.8220259834118355, 6.202755088082414, 5.685949302276117,
76  5.248324348086186, 4.873204003649857, 4.5483236996146585,
77  4.264459482747917, 4.014532790397335, 3.7930339560854938,
78  3.5956130450569255, 3.4187907702727114, 3.259765623821998,
79  3.116263124736558, 2.9864196062891506, 2.868715598188374,
80  2.7618916064251007, 2.6649334010445216, 2.577006806373881,
81  2.49744140180639, 2.4257380368287387, 2.36149961287304,
82  2.30454310848976, 2.2546361711122795, 2.211949872156462,
83  2.176486424050091, 2.1488285065012924, 2.1297593976297686,
84  2.1197410864630797, 2.1200099384640447, 2.133318744013215,
85  2.159801924117392, 2.208161283258402, 2.278358268171038,
86  2.3859178077488314, 2.5221002614889048, 2.735787838200772,
87  3.0589449017018593, 3.5337903678436287, 4.483072657771913,
88  6.610083260474584
89 }};
90 
91 const std::array<double, 50> Kink_profile_guesser::delta_grid_thin_3d = {{
92  3333.65, 633.37, 350.034, 241.893, 184.827, 149.564, 125.612,
93  108.282, 95.1601, 84.88, 76.6086, 69.8097, 64.122, 59.2939, 55.144,
94  51.539, 48.3781, 45.584, 43.0964, 40.8675, 38.8589, 37.0396, 35.3839,
95  33.8709, 32.4827, 31.2046, 30.024, 28.9302, 27.9139, 26.9672,
96  26.0831, 25.2558, 24.4798, 23.7506, 23.064, 22.4165, 21.8048,
97  21.2259, 20.6774, 20.157, 19.6624, 19.1919, 18.7438, 18.3164,
98  17.9084, 17.5185, 17.1455, 16.7883, 16.4461, 16.1177
99 }};
100 
101 const std::array<double,46> Kink_profile_guesser::lw_grid_3d = {{
102  1.978459028942803, 1.9783391533653445, 1.980043620351959,
103  1.9833183792496498, 1.9878550345245096, 1.9933922235764878,
104  1.9997509461627188, 2.006889929263504, 2.014866291525423,
105  2.0237981316444924, 2.033830355729957, 2.0451032141949237,
106  2.0577449824900045, 2.071869407260343, 2.0875710013249194,
107  2.104938421173479, 2.124057138088258, 2.145017377292984,
108  2.1679122623900757, 2.1928592764450814, 2.219982766555708,
109  2.2494508959415302, 2.2814351023846937, 2.3161624866512835,
110  2.353904767566588, 2.394955773457391, 2.439715745121684,
111  2.488559304923917, 2.542169733478082, 2.6010349012110594,
112  2.666156356944669, 2.7382744146654523, 2.8184, 2.908544332472897,
113  3.0106358023449724, 3.1262251590796586, 3.2611183199814784,
114  3.414688887232135, 3.598807799913082, 3.8148923549129865,
115  4.1005191039906865, 4.449432554257999, 4.910068487998784,
116  5.623565898325162, 6.7095735786822, 9.468675012670683
117 }};
118 
119 const std::array<double,50> Kink_profile_guesser::alpha_grid_thin_4d = {{
120  0.5001, 0.500527, 0.500953, 0.50138, 0.501806, 0.502233, 0.502659,
121  0.503086, 0.503512, 0.503939, 0.504365, 0.504792, 0.505218, 0.505645,
122  0.506071, 0.506498, 0.506924, 0.507351, 0.507778, 0.508204, 0.508631,
123  0.509057, 0.509484, 0.50991, 0.510337, 0.510763, 0.51119, 0.511616,
124  0.512043, 0.512469, 0.512896, 0.513322, 0.513749, 0.514176, 0.514602,
125  0.515029, 0.515455, 0.515882, 0.516308, 0.516735, 0.517161, 0.517588,
126  0.518014, 0.518441, 0.518867, 0.519294, 0.51972, 0.520147, 0.520573,
127  0.521
128 }};
129 
130 const std::array<double,44> Kink_profile_guesser::alpha_grid_4d = {{
131  0.53, 0.535, 0.54, 0.545, 0.55, 0.555, 0.56, 0.565, 0.57, 0.575,
132  0.58, 0.585, 0.59, 0.595, 0.6, 0.605, 0.61, 0.615, 0.62, 0.625,
133  0.63, 0.635, 0.64, 0.645, 0.65, 0.655, 0.66, 0.665, 0.67, 0.675,
134  0.68, 0.685, 0.69, 0.695, 0.7, 0.705, 0.71, 0.715, 0.72, 0.725,
135  0.73, 0.735, 0.74, 0.745
136 }};
137 
138 const std::array<double,44> Kink_profile_guesser::phi0_grid_4d = {{
139  0.9999141709240298, 0.9998414842279946, 0.9997210500020388,
140  0.9995268952112457, 0.9992242029930557, 0.9987705244339796,
141  0.9981181124984616, 0.9972175993269528, 0.9960185973241946,
142  0.9944735499229372, 0.9925382119835573, 0.9901722726359306,
143  0.9873385812085601, 0.9840030619353041, 0.9801330122384383,
144  0.9756962485383627, 0.9706583978537124, 0.9649824145474486,
145  0.9586249329012729, 0.9515359099943811, 0.9436552518345606,
146  0.9349102241623806, 0.9252134935980744, 0.9144601969894771,
147  0.9025250825209266, 0.889258109081031, 0.8744833042541158,
148  0.8579917056433094, 0.8395440710509201, 0.8188595500222173,
149  0.7956105375419259, 0.7694379924848905, 0.7399297435387302,
150  0.7066287141400789, 0.6690428076412978, 0.6266415529455245,
151  0.5788928016787105, 0.5252831220500885, 0.46536938556791574,
152  0.39893460155848304, 0.32606063251956485, 0.24743515221041074,
153  0.16466040885708588, 0.08063706717114749
154 }};
155 
156 const std::array<double,44> Kink_profile_guesser::delta_grid_4d = {{
157  17.014894262950175, 14.610028788855214, 12.800671189297544,
158  11.388389548619989, 10.254164050435781, 9.322275602753079,
159  8.542272010441318, 7.879224731566165, 7.308229590060747,
160  6.811001429309676, 6.373827028154778, 5.986200667646987,
161  5.639951332382715, 5.3286044388913085, 5.0469741633258645,
162  4.790842036367612, 4.556758794482891, 4.341858143037507,
163  3.9604595901218995, 3.790266654774057, 3.6317516751117074,
164  3.4837041965355393, 3.3451012152698394, 3.2150778258445367,
165  3.0929205912403455, 3.0929205912403455, 2.978040500905868,
166  2.8699958171049054, 2.7684347628427344, 2.6731754668612733,
167  2.5842339494473108, 2.5017100804638246, 2.4260077761703513,
168  2.3578695501593203, 2.298451406267639, 2.2497129307648507,
169  2.2146397850561472, 2.198121465069571, 2.208773532335836,
170  2.2602870981624075, 2.3801778022550835, 2.6258827676267256,
171  3.1429424551592477, 4.498054491401064
172 }};
173 
174 const std::array<double, 50> Kink_profile_guesser::delta_grid_thin_4d = {{
175  5000.47, 950.055, 525.051, 362.84, 277.241, 224.346, 188.419,
176  162.423, 142.74, 127.32, 114.913, 104.714, 96.183, 88.9408, 82.7161,
177  77.3085, 72.5671, 68.376, 64.6446, 61.3012, 58.2884, 55.5594,
178  53.0759, 50.8063, 48.724, 46.8069, 45.036, 43.3953, 41.8708, 40.4508,
179  39.1247, 37.8837, 36.7197, 35.6259, 34.596, 33.6247, 32.7071,
180  31.8389, 31.0162, 30.2355, 29.4937, 28.7879, 28.1157, 27.4746,
181  26.8626, 26.2777, 25.7182, 25.1825, 24.6691, 24.1766
182 }};
183 
184 const std::array<double,44> Kink_profile_guesser::lw_grid_4d = {{
185  1.9675754641180123, 1.9669686361875212, 1.9675684754392428,
186  1.9692935533810652, 1.9720420676162898, 1.9757017740428529,
187  1.9765326531478618, 1.9801619870000806, 1.9853477052970907,
188  1.9911895601726401, 1.9976692121812891, 2.004802765595383,
189  2.0126443146996595, 2.0212657580229862, 2.030762873784664,
190  2.041244603971598, 2.052835375514101, 2.0656593514562167,
191  2.0798588663907114, 2.1129636599979453, 2.1321986035241296,
192  2.153465859759776, 2.1769749714123137, 2.202966433768833,
193  2.2317241480939427, 2.2635750036552706, 2.2635750036552706,
194  2.2989230797415345, 2.338229004268684, 2.3821155890530012,
195  2.43130198377452, 2.4866304500518366, 2.5493444959232843,
196  2.620939177741102, 2.703373914257843, 2.79937476709974,
197  2.912552742082108, 3.0481985390720396, 3.2140493335989815,
198  3.4214023205717288, 3.6909247111377415, 4.057576779696893,
199  4.5943599048717525, 5.492260348908478
200 }};
201 
203 {
204  if (r < 0.) {
205  throw Domain_error("lower boundary of domain must be non-negative");
206  }
207  max_domain_start = r;
208 }
209 
211 {
212  if (r < 0.) {
213  throw Domain_error("upper boundary of domain must be non-negative");
214  }
215  min_domain_end = r;
216 }
217 
219  const Potential& potential, const Eigen::VectorXd& true_vacuum)
220 {
221  dist_true_vacuum = true_vacuum.norm();
222 
223  assert(dist_true_vacuum > 0);
224 
225  if (dist_true_vacuum == 0) {
226  throw Setup_error("Kink_profile_guesser::get_profile_guess: "
227  "True and false vacua are coincident");
228  }
229 
230  num_fields = potential.get_number_of_fields();
231  Eigen::VectorXd origin(Eigen::VectorXd::Zero(num_fields));
232  if (Abs(potential(true_vacuum) - potential(origin)) < 1.e-12) {
233  throw Setup_error("Kink_profile_guesser::get_profile_guess: "
234  "True and false vacua are degenerate");
235  }
236 }
237 
239  const Potential& potential, const Eigen::VectorXd& true_vacuum, int d)
240 {
241  calculate_potential_parameters(potential, true_vacuum);
242 
243  // Look up / interpolate the three ansatz parameters
244  if (d == 3) {
247  } else {
250  }
251 
252  if (d == 3) {
253  if (alpha < 0.521) {
256  }
257  else {
260  }
261  } else {
262  if (alpha < 0.521) {
265  }
266  else {
269  }
270  }
271  if (d == 3) {
274  } else {
277  }
278 
280  "phi0: " + std::to_string(phi0));
282  "Delta: " + std::to_string(delta));
283  logger.log_message(logging::Log_level::Trace, "Lw: " + std::to_string(lw));
285  + std::to_string(dist_true_vacuum));
286 }
287 
312  const Potential& potential, const Eigen::VectorXd& true_vacuum, int d,
313  double domain_start, double domain_end, double initial_step_size,
314  double interpolation_points_fraction)
315 {
316  compute_vacuum_distance(potential, true_vacuum);
317  fit_ansatz_parameters(potential, true_vacuum, d);
318 
319  return calculate_field_profiles(d, domain_start, domain_end,
320  initial_step_size,
321  interpolation_points_fraction);
322 }
323 
325  const Potential& potential, const Eigen::VectorXd& true_vacuum)
326 {
327  // Make a copy of the potential for use in ansatz construction
328  auto ansatz_potential = std::unique_ptr<Potential>(potential.clone());
329 
330  // Get change of basis matrix that orients first component
331  // in direction of true vacuum
332  cob_matrix = calculate_rotation_to_target(true_vacuum).transpose();
333 
334  std::stringstream log_str;
335  log_str << "COB: " << cob_matrix;
337 
338  // Apply the change of basis matrix. Note that we add
339  // the distance to the true vacuum as a scale factor so that the
340  // true vacuum is located at (1,0,0,...,0).
341  ansatz_potential->apply_basis_change(dist_true_vacuum * cob_matrix);
342 
343  // Add a constant term to enforce V(false_vacuum) = 0
344  ansatz_potential->add_constant_term(-1*ansatz_potential->operator()(
345  Eigen::VectorXd::Zero(num_fields)));
346 
347  // New coordinates of the true vacuum
348  Eigen::VectorXd _true_vacuum = Eigen::VectorXd::Zero(num_fields);
349  _true_vacuum(0) = 1;
350 
351  // Calculate ansatz parameters
353  "d: " + std::to_string(trial_dist));
354 
355  Eigen::VectorXd trial_vec = Eigen::VectorXd::Zero(num_fields);
356  trial_vec(0) = trial_dist;
357 
358  double vtrial = ansatz_potential->operator()(trial_vec);
359  double vmin = ansatz_potential->operator()(_true_vacuum);
360  double r = vmin / vtrial;
361 
362  aE = 2. * Abs(((2. - trial_dist * trial_dist) * vmin
363  - vtrial / (trial_dist * trial_dist))
364  / ((trial_dist - 1.) * (trial_dist - 1.)));
365  alpha = (r * trial_dist * trial_dist * (trial_dist - 1.5) + 0.5)
366  / (1. - r * trial_dist * trial_dist * (2. - trial_dist * trial_dist));
367 
368  if ((Abs(alpha) < alpha_threshold)) {
369  throw Thin_wall_error("Ansatz alpha = " + std::to_string(alpha) +
370  " < " + std::to_string(alpha_threshold) + " indicates thin walled "
371  "bubble; profiler will not converge");
372  }
373 
374  if ((Abs(alpha - 0.5) <= std::numeric_limits<double>::epsilon())
375  || (Abs(alpha - 0.75) <= std::numeric_limits<double>::epsilon())) {
376  throw Setup_error(
377  "Kink_profile_guesser::calculate_potential_parameters: "
378  "cannot construct ansatz for this potential");
379  }
380 
382  "Alpha: " + std::to_string(alpha));
383  logger.log_message(logging::Log_level::Trace, "|E|: " + std::to_string(aE));
384 }
385 
387  int d, double domain_start, double domain_end,
388  double initial_step_size, double interpolation_points_fraction)
389 {
390  double min_rho = domain_start >= 0. ? domain_start
391  : guess_domain_start();
392  double max_rho = domain_end >= 0. ? domain_end
393  : guess_domain_end();
394 
395  if (min_rho > max_rho) {
396  std::swap(min_rho, max_rho);
397  }
398 
399  const int num_grid_points = 1 + static_cast<int>(
400  std::ceil((max_rho - min_rho) / initial_step_size));
401 
402  const Eigen::VectorXd rho(
403  Eigen::VectorXd::LinSpaced(num_grid_points, min_rho, max_rho));
404 
405  Eigen::VectorXd ansatz =
406  rho.unaryExpr([this](double r) { return this->evaluate_ansatz_at(r); });
407 
408  // We still need to undo the change of basis
409  Eigen::MatrixXd cob_reverse = cob_matrix.transpose();
410 
411  // Note - we're building all the profiles here, then
412  // passing them over one at a time. This is inefficient,
413  // but (I think) the path of least resistance right now.
414  // Could be improved later.
415  Eigen::MatrixXd m_profiles(num_grid_points, num_fields);
416 
417  Eigen::VectorXd temp_field_vec = Eigen::VectorXd::Zero(num_fields);
418 
419  for (int x = 0; x < num_grid_points; ++x) {
420  // Ansatz basis field vec @ this radius
421  temp_field_vec(0) = ansatz(x);
422 
423  // Transform it to the original field basis (and undo the
424  // field coordinate scaling)
425  Eigen::VectorXd orig_field_vec
426  = cob_reverse * (dist_true_vacuum) * temp_field_vec;
427 
428  m_profiles.row(x) = orig_field_vec;
429  }
430 
431  Field_profiles profiles(rho, m_profiles, interpolation_points_fraction);
432  profiles.set_number_of_dimensions(d);
433 
434  return profiles;
435 }
436 
438 {
439  const double sE = Sqrt(aE);
440  // The ansatz form assumes that coordinates are scaled
441  // by this factor.
442  const double coord_scaling = dist_true_vacuum / sE;
443 
444  // Note we divide by the scale factor to recover the
445  // original spatial coordinate scale.
446  const double kink_profile = 0.5 * phi0 *
447  (1. - Tanh((rho / coord_scaling - delta) / lw));
448 
449  const double correction = -0.5 * phi0 * Exp(-rho * sE)
450  * Sech(delta / lw) * Sech(delta / lw) / (lw * dist_true_vacuum);
451 
452  return kink_profile + correction;
453 }
454 
456 {
457  const double sE = Sqrt(aE);
458  const double coord_scaling = dist_true_vacuum / sE;
459 
460  const double sechr = Sech((rho / coord_scaling - delta) / lw);
461  const double sech0 = Sech(delta / lw);
462 
463  const double kink_deriv = -0.5 * phi0 * sechr * sechr / (lw * coord_scaling);
464 
465  const double correction_deriv = 0.5 * phi0 * sech0 * sech0
466  * Exp(-rho * sE) / (lw * coord_scaling);
467 
468  return kink_deriv + correction_deriv;
469 }
470 
472 {
473  const double tolerance = 1.e-5;
474 
475  const double target_value = 1.e-5;
476 
477 
478  if (Abs(evaluate_ansatz_deriv_at(max_domain_start)) <= target_value) {
479  return max_domain_start;
480  }
481 
482  const auto target_fn = [this, target_value](double r) {
483  return Abs(this->evaluate_ansatz_deriv_at(r)) / target_value - 1.;
484  };
485 
486  const double lower_value = target_fn(0.);
487  const double upper_value = target_fn(max_domain_start);
488  if (lower_value * upper_value >= 0.) {
489  return max_domain_start;
490  }
491 
492  double r_guess = max_domain_start;
493  try {
494  const auto convergence_test
495  = [&target_fn, tolerance](double lower, double upper) {
496  return (Abs(target_fn(lower)) <= tolerance &&
497  Abs(target_fn(upper)) <= tolerance);
498  };
499 
500  const auto solution = boost::math::tools::bisect(
501  target_fn, 0., max_domain_start, convergence_test);
502 
503  r_guess = 0.5 * (solution.first + solution.second);
504  } catch (const boost::exception& e) {
505  r_guess = max_domain_start;
506  }
507 
508  logger.log_message(logging::Log_level::Trace, "guessed domain start: "
509  + std::to_string(r_guess));
510 
511  return r_guess;
512 }
513 
515 {
516  const double threshold = 1.e-5;
517 
518  const double sE = Sqrt(aE);
519  const double coord_scaling = dist_true_vacuum / sE;
520 
521  double result = coord_scaling*(lw * ArcTanh(1 - ((2*threshold)/phi0))
522  + delta);
523  logger.log_message(logging::Log_level::Trace, "guessed domain end: "
524  + std::to_string(result));
525 
526  return std::max(min_domain_end, result);
527 }
528 
529 } // namespace BubbleProfiler
contains the definition of the Field_profiles clas
void set_min_domain_end(double r)
Sets the minimum required distance if guessing the domain end.
Exception indicating a thin-wall ansatz which we can&#39;t solve (yet!)
Definition: error.hpp:38
T Abs(T x) noexcept
void set_max_domain_start(double r)
Sets the maximum allowed distance if guessing the domain start.
static const std::array< double, 44 > delta_grid_4d
static const std::array< double, 46 > delta_grid_3d
static const std::array< double, 46 > phi0_grid_3d
Exception indicating function evaluation out of allowed domain.
Definition: error.hpp:110
T Exp(T x) noexcept
static const std::array< double, 44 > lw_grid_4d
static const std::array< double, 46 > alpha_grid_3d
void compute_vacuum_distance(const Potential &, const Eigen::VectorXd &)
void calculate_potential_parameters(const Potential &, const Eigen::VectorXd &)
double alpha_threshold
Minimum value of alpha before throwing a Thin_wall_error.
static const std::array< double, 50 > alpha_grid_thin_3d
T Sqrt(T x) noexcept
void log_message(Log_level level, const std::string &msg) const
void fit_ansatz_parameters(const Potential &, const Eigen::VectorXd &, int)
static const std::array< double, 46 > lw_grid_3d
static const std::array< double, 50 > delta_grid_thin_4d
virtual Potential * clone() const =0
Subclasses must implement a clone method.
virtual Field_profiles get_profile_guess(const Potential &, const Eigen::VectorXd &, int, double, double, double, double) override
Calculate an initial guess for the bubble profile.
Field_profiles calculate_field_profiles(int, double, double, double, double)
static const std::array< double, 50 > delta_grid_thin_3d
static const std::array< double, 44 > alpha_grid_4d
auto Sech(T x) noexcept-> decltype(Cosh(x))
Eigen::MatrixXd calculate_rotation_to_target(const Eigen::VectorXd &target)
Calculate the rotation matrix for a rotation to the target vector.
Definition: rotation.cpp:36
static const std::array< double, 50 > alpha_grid_thin_4d
virtual std::size_t get_number_of_fields() const =0
Exception indicating general setup error.
Definition: error.hpp:32
static const std::array< double, 44 > phi0_grid_4d
T Tanh(T x) noexcept
T ArcTanh(T x) noexcept
Abstract base class for a generic potential.
Definition: potential.hpp:36
Discretized set of field profiles.
Scalar quadratic_lagrange_interpolation_at_point(Scalar x, const Data &xdata, const Data &ydata)