BubbleProfiler  0.3.0
by Peter Athron, Csaba Balazs, Michael Bardsley, Andrew Fowlie, Dylan Harries & Graham White
shooting.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 
25 #include "shooting.hpp"
26 #include "error.hpp"
27 #include "math_wrappers.hpp"
28 #include "numeric.hpp"
29 #include "potential.hpp"
30 
31 #include <boost/math/tools/minima.hpp>
32 
33 #include <algorithm>
34 #include <limits>
35 #include <stdexcept>
36 #include <utility>
37 
38 namespace BubbleProfiler {
39 
41 {
42  if (!action_computed) {
43  throw Error("Shooting::get_euclidean_action: action not computed");
44  }
45  return euclidean_action;
46 }
47 
49 {
50  if (!profile_computed) {
51  throw Error("Shooting::get_bubble_profile: bubble profile not computed");
52  }
53  return profiles;
54 }
55 
57  const std::function<double(double)>& potential_,
58  const std::function<double(double)>& potential_first_,
59  const std::function<double(double)>& potential_second_,
60  double false_min_, double true_min_, double barrier_, int dim_)
61 {
62  potential = potential_;
63  potential_first = potential_first_;
64  potential_second = potential_second_;
65 
66  dim = dim_;
67  barrier = barrier_;
68  false_min = false_min_;
69  true_min = true_min_;
70  sign_min = Sign(false_min_ - true_min_);
71 
72  p_barrier = potential(barrier_);
73  p_false_min = potential(false_min_);
74  p_true_min = potential(true_min_);
75 
76  // Find settings for solver that depend on potential
77  scale = bubble_scale();
79 }
80 
82  const std::function<double(double)>& potential_,
83  const std::function<double(double)>& potential_first_,
84  const std::function<double(double)>& potential_second_,
85  double false_min_, double true_min_, double barrier_, int dim_,
86  unsigned int options)
87 {
88  if (dim_ != 3 && dim_ != 4) {
89  throw Setup_error("spacetime dimension must be 3 or 4");
90  }
91 
92  action_computed = false;
93  profile_computed = false;
94 
95  bool compute_action = (options & Solver_options::Compute_action) != 0;
96  bool compute_profile = (options & Solver_options::Compute_profile) != 0;
97 
98  if (!compute_action && !compute_profile) {
99  return;
100  }
101 
102  initialize_potential_parameters(potential_, potential_first_,
103  potential_second_, false_min_,
104  true_min_, barrier_, dim_);
105 
106  // Build stepper for shooting
108  = make_controlled(shoot_ode_rel, shoot_ode_abs,
110 
111  // Solve initial value problem
112  lambda_sol = shooting();
113 
114  if (compute_action) {
116  = make_controlled(action_ode_rel, action_ode_abs,
119  action_computed = true;
120  }
121 
122  if (compute_profile) {
124  profile_computed = true;
125  }
126 }
127 
128 void Shooting::solve(const Potential& potential_, double false_min_,
129  double true_min_, double barrier_, int dim_,
130  unsigned int options)
131 {
132  if (potential_.get_number_of_fields() != 1) {
133  throw Setup_error("potential must be one dimensional");
134  }
135 
136  const auto potential_func = [&potential_](double phi) {
137  Eigen::VectorXd fields(1);
138  fields(0) = phi;
139  return potential_(fields);
140  };
141 
142  const auto potential_first_ = [&potential_](double phi) {
143  Eigen::VectorXd fields(1);
144  fields(0) = phi;
145  return potential_.partial(fields, 0);
146  };
147 
148  const auto potential_second_ = [&potential_](double phi) {
149  Eigen::VectorXd fields(1);
150  fields(0) = phi;
151  return potential_.partial(fields, 0, 0);
152  };
153 
154  solve(potential_func, potential_first_, potential_second_,
155  false_min_, true_min_, barrier_, dim_, options);
156 }
157 
158 void Shooting::ode(const state_type& x, state_type& dxdt, double rho)
159 {
160  dxdt[0] = x[1];
161  dxdt[1] = -(dim - 1.) / rho * x[1] + potential_first(x[0]);
162 }
163 
164 double Shooting::calculate_roll_time(double lambda, double dVdphi,
165  double d2Vdphi2) const
166 {
167  const double change = evolve_change_rel * Abs(unmap(lambda)
168  - false_min);
169  const double prefactor = Abs(dVdphi / d2Vdphi2);
170 
171  double y = 0.;
172  if (d2Vdphi2 > 0.) {
173  if (dim == 3) {
174  if (change / prefactor > f_y_max) {
175  // Asymptotic formula
176  y = Log(2. * change / Abs(barrier - true_min)) + lambda;
177  } else {
178  y = asinch(1. + change / prefactor);
179  }
180  } else if (dim == 4) {
181  if (change / prefactor > f_y_max) {
182  // Asymptotic formula
183  y = 0.5 * Log(27. * Pi / 16.)
184  + Log(change / Abs(barrier - true_min)) + lambda;
185  } else {
186  y = approx_root_pos_4(0.5 * change / prefactor);
187  }
188  }
189  } else {
190  if (dim == 3) {
191  y = asinc(1. - change / prefactor);
192  } else if (dim == 4) {
193  y = approx_root_neg_4(0.5 * change / prefactor);
194  }
195  }
196 
197  return y;
198 }
199 
200 double Shooting::calculate_roll_velocity(double lambda, double y,
201  double dVdphi, double d2Vdphi2) const
202 {
203  const double change = evolve_change_rel * Abs(unmap(lambda)
204  - false_min);
205  const double prefactor = Abs(dVdphi / d2Vdphi2);
206  const double mass = Sqrt(Abs(d2Vdphi2));
207  const double rho = y / mass;
208 
209  double v = 0.;
210  if (d2Vdphi2 > 0.) {
211  if (dim == 3) {
212  const double sinch_y = 1. + change / prefactor;
213  if (sinch_y > f_y_max) {
214  v = sign_min * mass * change; // Asymptotic formula
215  } else if (sinch_y - 1. < f_y_min) {
216  v = 2. * sign_min * change / rho; // Asymptotic formula
217  } else {
218  v = sign_min * prefactor / rho * (Cosh(y) - sinch_y);
219  }
220  } else if (dim == 4) {
221  const double f_y = 0.5 * change / prefactor;
222  if (f_y > f_y_max) {
223  v = sign_min * mass * change; // Asymptotic formula
224  } else if (f_y < f_y_min) {
225  v = 2. * sign_min * change / rho; // Asymptotic formula
226  } else {
227  v = sign_min * prefactor / rho * 2. * BesselI(2, y);
228  }
229  }
230  } else {
231  if (dim == 3) {
232  const double sinc_y = 1. - change / prefactor;
233  if (1. - sinc_y < f_y_min) {
234  v = 2. * sign_min * change / rho; // Asymptotic formula
235  } else {
236  v = - sign_min * prefactor / rho * (Cos(y) - sinc_y);
237  }
238  } else if (dim == 4) {
239  const double f_y = 0.5 * change / prefactor;
240  if (f_y < f_y_min) {
241  v = 2. * sign_min * change / rho; // Asymptotic formula
242  } else {
243  v = sign_min * prefactor / rho * 2. * BesselJ(2, y);
244  }
245  }
246  }
247 
248  return v;
249 }
250 
252 {
253  const double phi_zero = unmap(lambda);
254  const double mass_squared = potential_second(phi_zero);
255  const double prime_start = potential_first(phi_zero);
256 
257  // Solve for \rho.
258  const double mass = Sqrt(Abs(mass_squared));
259  const double change = evolve_change_rel * Abs(phi_zero - false_min);
260 
261  const double y = calculate_roll_time(lambda, prime_start, mass_squared);
262  const double rho = y / mass;
263 
264  // Find corresponding position and velocity.
265  const double x = phi_zero + sign_min * change;
266  const double v = calculate_roll_velocity(lambda, y, prime_start,
267  mass_squared);
268 
269  if (std::isnan(rho) || std::isnan(x) || std::isnan(v)) {
270  throw Numerical_error(
271  "Could not evolve fields with approximate solution");
272  }
273 
274  return {{rho, x, v}};
275 }
276 
278 {
279  const double mass_squared = potential_second(barrier);
280  return 2. * Pi / Sqrt(-mass_squared);
281 }
282 
283 double Shooting::energy(double phi, double dot_phi) const
284 {
285  return 0.5 * pow(dot_phi, 2) - (potential(phi) - p_false_min);
286 }
287 
288 double Shooting::shoot(double lambda)
289 {
290  constexpr double over = 1.;
291  constexpr double under = -1.;
292 
293  const double phi_zero = unmap(lambda);
294 
295  // Trivial cases - don't check them explicitly as may get stuck on
296  // tops of maxima.
297  if (std::isinf(lambda)) {
298  return over;
299  } else if (phi_zero == false_min) {
300  return under;
301  }
302 
303  // Check there is sufficient energy to make a shot before evolving
304  // with approximate analytic solution etc.
305  const double x = phi_zero;
306  const double v = 0.;
307  const bool no_energy = energy(x, v) < 0.;
308 
309  if (no_energy) {
310  return under;
311  }
312 
313  // Reset stepper
314  shoot_stepper.reset();
315 
316  // Make ODE function with signature required by boost
317  const auto ode_ = [this](const state_type& x, state_type& dxdt, double rho) {
318  return this->ode(x, dxdt, rho);
319  };
320 
321  // Evolve guess of \f$\phi_0\f$ forward using approximate solution,
322  // resulting in initial conditions.
323  evolve_type evolved = evolve(lambda);
324  double rho = evolved[0]; // \f$\hat\rho\f$
325  // \f$\phi(\hat\rho)\f$ and \f$\dot\phi(\hat\rho)\f$
326  state_type y {{evolved[1], evolved[2]}};
327  double drho = drho_guess;
328  const double rho_max = rho + periods_max * scale;
329 
330  for (int iter = 0; iter < iter_max; ++iter) {
331  // Check for whether we reached an unacceptable value of \f$\rho\f$
332  if (rho >= rho_max ||
333  Abs(drho) <= std::numeric_limits<double>::epsilon()) {
334  throw Numerical_error(
335  "Could not determine whether shot was an undershot or "
336  "overshot in shoot");
337  }
338 
339  const double x = y[0];
340  const double v = y[1];
341 
342  // Check whether we have gone past the true vacuum. This must come first,
343  // as we could go past the true vacuum and then run out of energy etc.
344  const bool overshot = sign_min * (x - false_min) > 0.;
345 
346  if (overshot) {
347  return over;
348  }
349 
350  // Check whether there is sufficient energy to make a shot
351  const bool no_energy = energy(x, v) < 0.;
352 
353  if (no_energy) {
354  return under;
355  }
356 
357  // Check whether we are moving in the wrong direction
358  const bool undershot = sign_min * v < 0.;
359 
360  if (undershot) {
361  return under;
362  }
363 
364  // Step forward in \f$\rho\f$ and update \f$d\rho\f$ in place.
365  // The while loop isn't strictly necessary but avoids repeating the
366  // above checks.
367  while (shoot_stepper.try_step(ode_, y, rho, drho)) {
368  }
369  }
370 
371  throw Numerical_error("Could not determine whether shot was an undershot or "
372  "overshot in shoot");
373 }
374 
375 double Shooting::unmap(double lambda) const
376 {
377  return Exp(-lambda) * (barrier - true_min) + true_min;
378 }
379 
381 {
382  const auto shoot_ = [this](double l) { return this->shoot(l); };
383  std::pair<double, double> solution;
384  boost::math::tools::eps_tolerance<double> stop(shoot_bisect_bits);
385  double lower = 0.;
386  double upper = bisect_lambda_max;
387  double interval = bisect_lambda_max;
388 
389  // Try to find a root with bisection method between lower and upper.
390  // If no solution is found, shift the range.
391 
392  for (int iter = 0; iter < iter_max; ++iter) {
393  try {
394  solution = boost::math::tools::bisect(shoot_, lower, upper, stop);
395  } catch (boost::exception & e) {
396  interval *= 2.;
397  lower = upper;
398  upper += interval;
399  continue;
400  }
401  return 0.5 * (solution.first + solution.second);
402  }
403 
404  throw Numerical_error("No solution found from bisect after reaching "
405  + std::to_string(iter_max)
406  + " attempts extending the range.");
407 }
408 
409 double Shooting::integrand(double dot_phi, double rho) const
410 {
411  return pow(dot_phi, 2) * pow(rho, dim - 1) / dim;
412 }
413 
414 double Shooting::action(double lambda)
415 {
416  const double phi_zero = unmap(lambda);
417 
418  // Reset stepper
419  action_stepper.reset();
420 
421  const auto ode_ = [this](const state_type& x, state_type& dxdt, double rho) {
422  return this->ode(x, dxdt, rho);
423  };
424 
425  // Evolve guess of \f$\phi_0\f$ forward using approximate solution,
426  // resulting in initial conditions.
427  evolve_type evolved = evolve(lambda);
428  double rho = evolved[0]; // \f$\hat\rho\f$
429  // \f$\phi(\hat\rho)\f$ and \f$\dot\phi(\hat\rho)\f$
430  state_type y {{evolved[1], evolved[2]}};
431  double drho = drho_guess;
432  const double rho_max = rho + periods_max * scale;
433 
434  // Integrate action along bubble profile
435  double x = y[0];
436  double v = y[1];
437 
438  double action_no_prefactor = interior(lambda);
439  double f_a = integrand(v, rho);
440 
441  int iter = 0;
442  for (iter = 0; iter < iter_max; ++iter) {
443  // Check for whether we reached an unacceptable value of \f$\rho\f$
444  if (rho >= rho_max ||
445  Abs(drho) <= std::numeric_limits<double>::epsilon()) {
446  throw Numerical_error(
447  "Could not determine whether shot was an undershot or "
448  "overshot in action");
449  }
450 
451  // Break if over or under shoot, or close to false minimum.
452  const bool overshot = sign_min * (x - false_min) > 0.;
453  const bool undershot = sign_min * v < 0.;
454  const bool arrived = Abs((x - false_min) / (phi_zero - false_min))
456 
457  if (overshot || undershot || arrived) {
458  break;
459  }
460 
461  // Step forward in \f$\rho\f$ and update \f$d\rho\f$ in place.
462  const double rho_a = rho;
463  while (action_stepper.try_step(ode_, y, rho, drho)) {
464  }
465 
466  // Contribution to action from trapezoid rule
467  x = y[0];
468  v = y[1];
469 
470  double f_b = integrand(v, rho);
471 
472  // Don't use \f$d\rho\f$ as it is updated in place
473  action_no_prefactor += 0.5 * (f_a + f_b) * (rho - rho_a);
474 
475  // Cache integrand
476  f_a = f_b;
477  }
478 
479  if (iter == iter_max) {
480  throw Numerical_error(
481  "Could not determine whether shot was an undershot or "
482  "overshot in action");
483  }
484 
485  const double action = area_n_sphere(dim - 1) * action_no_prefactor;
486 
487  return action;
488 }
489 
491 {
492  const double phi_zero = unmap(lambda);
493  evolve_type evolved = evolve(lambda);
494  double rho_crit = evolved[0];
495  state_type y{{evolved[1], evolved[2]}};
496 
497  const auto ode_ = [this](const state_type& x, state_type& dxdt, double rho) {
498  return this->ode(x, dxdt, rho);
499  };
500 
501  std::vector<double> rho_vals = {rho_crit};
502  std::vector<double> field_vals = {y[0]};
503 
504  double drho = drho_guess;
505  double rho = rho_crit;
506  const double rho_max = rho + periods_max * scale;
507  controlled_stepper_type profiles_stepper
508  = make_controlled(action_ode_rel, action_ode_abs,
510 
511  int iter = 0;
512  for (iter = 0; iter < iter_max; ++iter) {
513  // Check for whether we reached an unacceptable value of \f$\rho\f$
514  if (rho >= rho_max ||
515  Abs(drho) <= std::numeric_limits<double>::epsilon()) {
516  throw Numerical_error(
517  "Could not determine whether shot was an undershot or "
518  "overshot in profile");
519  }
520 
521  // Break if over or under shoot, or close to false minimum
522  const bool overshot = sign_min * (y[0] - false_min) > 0.;
523  const bool undershot = sign_min * y[1] < 0.;
524  const bool arrived = Abs((y[0] - false_min) / (phi_zero - false_min))
526 
527  if (overshot || undershot || arrived) {
528  break;
529  }
530 
531  // Step forward in \f$\rho\f$ and update \f$d\rho\f$ in place
532  while (profiles_stepper.try_step(ode_, y, rho, drho)) {
533  }
534 
535  rho_vals.push_back(rho);
536  field_vals.push_back(y[0]);
537  }
538 
539  if (iter == iter_max) {
540  throw Numerical_error(
541  "Could not determine whether shot was an undershot or "
542  "overshot in profile");
543  }
544 
545  // Use solution assuming quadratic potential inside bubble
546  const std::size_t num_integration_points = rho_vals.size();
547  const std::size_t num_interior_points = num_integration_points / 2;
548  const double rho_step = rho_crit / num_interior_points;
549 
550  Eigen::VectorXd rho_values(Eigen::VectorXd::Zero(num_interior_points
551  + num_integration_points));
552  Eigen::MatrixXd field_values(
553  Eigen::MatrixXd::Zero(num_interior_points + num_integration_points, 1));
554  for (std::size_t i = 0; i < num_interior_points; ++i) {
555  rho_values(i) = i * rho_step;
556  try {
557  field_values(i, 0) = quadratic_potential_solution(i * rho_step);
558  } catch (const std::overflow_error & e) {
559  throw Numerical_error("Overflow error in quadratic solution for "
560  "bubble profile in bubble interior");
561  }
562  }
563 
564  rho_values.segment(num_interior_points, num_integration_points)
565  = Eigen::VectorXd::Map(rho_vals.data(), num_integration_points);
566  field_values.bottomRows(num_integration_points)
567  = Eigen::VectorXd::Map(field_vals.data(), num_integration_points);
568 
569  return Field_profiles(rho_values, field_values);
570 }
571 
573 {
575 }
576 
577 double Shooting::quadratic_potential_solution(double rho, double lambda) const
578 {
579  const double phi_zero = unmap(lambda);
580 
581  // Trivial case in which we desire \f$\phi(\rho = 0)\f$. This would
582  // otherwise result in nans in numerical evaluations of e.g.
583  // \f$\lim_{x \to 0} \sinh(x) / x\f$.
584  if (rho == 0.) {
585  return phi_zero;
586  }
587 
588  const double mass_squared = potential_second(phi_zero);
589 
590  double prime_start = potential_first(phi_zero);
591  // @todo More appropriate threshold for Taylor expansion
592  if (Abs(prime_start) <= std::numeric_limits<double>::epsilon()) {
593  prime_start = potential_second(true_min) * (phi_zero - true_min);
594  }
595  const double prefactor = prime_start / mass_squared;
596 
597  const double y = rho * Sqrt(Abs(mass_squared));
598  double delta_phi = 0.;
599  if (mass_squared > 0) {
600  if (dim == 3) {
601  delta_phi = prefactor * (Sinh(y) / y - 1.);
602  } else {
603  delta_phi = prefactor * (2. * BesselI(1, y) / y - 1.);
604  }
605  } else {
606  if (dim == 3) {
607  delta_phi = prefactor * (Sin(y) / y - 1.);
608  } else {
609  delta_phi = prefactor * (2. * BesselJ(1, y) / y - 1.);
610  }
611  }
612 
613  return phi_zero + delta_phi;
614 }
615 
616 double Shooting::interior(double lambda)
617 {
618  const double phi_zero = unmap(lambda);
619  const double mass_squared = potential_second(phi_zero);
620  const double prime_start = potential_first(phi_zero);
621  const double prefactor = Abs(prime_start / mass_squared);
622  const double mass = Sqrt(Abs(mass_squared));
623  const double change = evolve_change_rel * Abs(phi_zero - false_min);
624  evolve_type evolved = evolve(lambda);
625  const double rho = evolved[0];
626  const double y = mass * rho;
627 
628  double value = 0.;
629  if (mass_squared > 0.) {
630  if (dim == 3) {
631  if (y > y_max) {
632  value = (change * change) / (6. * mass); // Asymptotic formula
633  } else {
634  value = (prefactor * prefactor) / (6. * mass_squared * rho)
635  * (1. + mass_squared * (rho * rho)
636  - Cosh(2. * y) + 0.5 * y * Sinh(2. * y));
637  }
638  } else if (dim == 4) {
639  if (y > y_max) {
640  value = 1.6875 * (change * change) / mass_squared; // Asymptotic formula
641  } else {
642  const double bessel_1_y = BesselI(1, y);
643  const double bessel_2_y = BesselI(2, y);
644  value = 0.5 * (prefactor * prefactor) * rho / mass *
645  (-y * (bessel_1_y * bessel_1_y)
646  + 4. * bessel_1_y * bessel_2_y
647  + y * (bessel_2_y * bessel_2_y));
648  }
649  }
650  } else {
651  if (dim == 3) {
652  value = (prefactor * prefactor) / (6. * Abs(mass_squared) * rho)
653  * (-1. + Abs(mass_squared) * (rho * rho)
654  + Cos(2. * y) + 0.5 * y * Sin(2. * y));
655  } else if (dim == 4) {
656  const double bessel_1_y = BesselJ(1, y);
657  const double bessel_2_y = BesselJ(2, y);
658  value = 0.5 * (prefactor * prefactor) * rho / mass *
659  (y * (bessel_1_y * bessel_1_y)
660  - 4. * bessel_1_y * bessel_2_y
661  + y * (bessel_2_y * bessel_2_y));
662  }
663  }
664 
665  return value;
666 }
667 
668 } // namespace BubbleProfiler
Field_profiles profiles
Definition: shooting.hpp:130
T Cosh(T x) noexcept
T Abs(T x) noexcept
T Cos(T x) noexcept
evolve_type evolve(double lambda) const
Uses an approximation solution to evolve the system forward until the field changes by a required amo...
Definition: shooting.cpp:251
T Exp(T x) noexcept
T Log(T x) noexcept
boost::array< double, 2 > state_type
Definition: shooting.hpp:117
double approx_root_neg_4(double a)
Definition: numeric.cpp:108
void solve(const std::function< double(double)> &potential_, const std::function< double(double)> &potential_first_, const std::function< double(double)> &potential_second_, double false_min_, double true_min_, double barrier_, int dim_=3, unsigned int options=(Solver_options::Compute_action|Solver_options::Compute_profile))
Definition: shooting.cpp:81
double calculate_roll_velocity(double lambda, double y, double dVdphi, double d2Vdphi2) const
Find velocity .
Definition: shooting.cpp:200
auto BesselI(Order v, Argument z) -> decltype(boost::math::cyl_bessel_i(v, z))
boost::numeric::odeint::runge_kutta_dopri5< state_type > error_stepper_type
Definition: shooting.hpp:119
virtual double partial(const Eigen::VectorXd &coords, int i) const =0
Partial derivative WRT coordinate i at a point.
T Sqrt(T x) noexcept
controlled_stepper_type action_stepper
Definition: shooting.hpp:136
T Sin(T x) noexcept
double approx_root_pos_4(double a)
Definition: numeric.cpp:96
const Field_profiles & get_bubble_profile() const
Definition: shooting.cpp:48
Field_profiles calculate_bubble_profile(double lambda)
Definition: shooting.cpp:490
double get_euclidean_action() const
Definition: shooting.cpp:40
double interior(double lambda)
Definition: shooting.cpp:616
auto BesselJ(Order v, Argument z) -> decltype(boost::math::cyl_bessel_j(v, z))
int Sign(const T &x)
double asinch(double a)
Definition: numeric.cpp:63
double quadratic_potential_solution(double) const
Definition: shooting.cpp:572
double shooting()
Solve for by bisection.
Definition: shooting.cpp:380
double calculate_roll_time(double lambda, double dVdphi, double d2Vdphi2) const
Find the (dimensionless) time at which the field changes by a small amount, .
Definition: shooting.cpp:164
std::function< double(double)> potential_first
Definition: shooting.hpp:161
double bubble_scale() const
Characteristic scale of bubble.
Definition: shooting.cpp:277
boost::array< double, 3 > evolve_type
Definition: shooting.hpp:116
double action(double lambda)
Definition: shooting.cpp:414
void initialize_potential_parameters(const std::function< double(double)> &potential_, const std::function< double(double)> &potential_first_, const std::function< double(double)> &potential_second_, double false_min_, double true_min_, double barrier_, int dim_)
Definition: shooting.cpp:56
std::function< double(double)> potential_second
Definition: shooting.hpp:163
void ode(const state_type &x, state_type &dxdt, double rho)
ODE for bounce solution.
Definition: shooting.cpp:158
double shoot(double lambda)
Performs a single shot of our shooting method.
Definition: shooting.cpp:288
double area_n_sphere(int n)
Definition: numeric.cpp:29
double integrand(double dot_phi, double rho) const
Action integrand from kinetic term without pre-factor.
Definition: shooting.cpp:409
double asinc(double a)
Definition: numeric.cpp:92
virtual std::size_t get_number_of_fields() const =0
Exception indicating general setup error.
Definition: error.hpp:32
double energy(double phi, double dot_phi) const
Definition: shooting.cpp:283
Numerical functions for one-dimensional shooting method and area of -sphere.
double unmap(double lambda) const
Definition: shooting.cpp:375
One-dimensional shooting method.
std::function< double(double)> potential
Definition: shooting.hpp:159
T Sinh(T x) noexcept
Abstract base class for a generic potential.
Definition: potential.hpp:36
boost::numeric::odeint::controlled_runge_kutta< error_stepper_type > controlled_stepper_type
Definition: shooting.hpp:121
Exception indicating generic numerical error.
Definition: error.hpp:116
Discretized set of field profiles.
controlled_stepper_type shoot_stepper
Definition: shooting.hpp:135