42 #include <boost/program_options.hpp>    43 #include <boost/filesystem.hpp>    52 namespace fs = boost::filesystem;
    53 namespace po = boost::program_options;
   142               const std::vector<std::string>& values,
   147    validators::check_first_occurrence(v);
   149    const std::string& val = validators::get_single_string(values);
   151    if (val == 
"runge-kutta-4") {
   153    } 
else if (val == 
"euler") {
   156       throw validation_error(validation_error::invalid_option_value);
   164    po::options_description desc(
"run_cmd_line_potential options");
   166       (
"ansatz-file", po::value<std::string>(&input.
ansatz_file)->default_value(default_ansatz_file),
   167        "Text file containing a predefined ansatz")
   168       (
"false-vacuum-at-origin",
   170        "If given, assume the false location is at the origin of field space unless specified otherwise")
   171       (
"barrier", po::value<std::vector<double> >()->multitoken(),
   172        "Location of barrier. Applies only when using the shooting method for 1-field problems."   173        " If not supplied, barrier will be found numerically.")
   174       (
"domain-start", po::value<double>(&input.
domain_start)->default_value(default_domain_start),
   175        "Domain of integration start.  If negative, the profiler will attempt to guess a suitable value.")
   176       (
"domain-end", po::value<double>(&input.
domain_end)->default_value(default_domain_end),
   177        "Domain of integration end.  If negative, the profiler will attempt to guess a suitable value.")
   178       (
"field", po::value<std::vector<std::string> >(&input.
fields)->required(),
   179        "Specify a field name")
   180       (
"force-output", po::bool_switch(&input.
force_output)->default_value(default_force_output),
   181        "If given, overwrite existing output files")
   182       (
"global-minimum", po::value<std::vector<double> >()->multitoken(),
   183        "Location of global minimum")
   184       (
"initial-step-size", po::value<double>(&input.
initial_step_size)->default_value(default_initial_step_size),
   185        "Approximate initial step size to use in solving ODE")
   186       (
"help", 
"print help message")
   187       (
"integration-method", po::value<Integration_algorithm>(&input.
algorithm)->default_value(default_algorithm, 
"runge-kutta-4"),
   188        "Algorithm to use for integrating ODEs (valid options: runge-kutta-4, euler)")
   189       (
"interpolation-fraction", po::value<double>(&input.
interpolation_fraction)->default_value(default_interp_fraction),
   190        "Approximate fraction of grid points to use for interpolation")
   191       (
"local-minimum", po::value<std::vector<double> >()->multitoken(),
   192        "Location of local minimum")
   193       (
"max-iterations", po::value<int>(),
   194        "Perform at most this many iterations")
   195       (
"opt-timeout", po::value<double>(&input.
opt_timeout)->default_value(default_opt_timeout),
   196        "Timeout if using the optimizer to locate global minimum (0 for no timeout)")
   197       (
"output-file", po::value<std::string>(&input.
output_file)->default_value(default_output_file),
   198        "Name of output file.  If '-' is given, write to standard output")
   199       (
"output-path", po::value<std::string>(&input.
output_path)->default_value(
""),
   200        "Output path for additional generated data files")
   201       (
"perturbative", po::bool_switch(&input.
use_perturbative)->default_value(default_use_perturbative),
   202        "If given, use perturbative method for one-dimensional potentials")
   203       (
"potential", po::value<std::string>(&input.
potential)->required(),
   204        "Specify a potential as GiNaCs string")
   205       (
"n-dims", po::value<int>(&input.
n_dims)->default_value(3),
   206        "number of spacetime dimensions")
   207       (
"rtol-action", po::value<double>(&input.
rtol_action)->default_value(default_rtol_action),
   208        "Relative tolerance in bounce action")
   209       (
"rtol-fields", po::value<double>(&input.
rtol_fields)->default_value(default_rtol_fields),
   210        "Relative tolerance in fields at r = 0")
   211       (
"write-profiles",  po::bool_switch(&input.
write_profiles)->default_value(default_write_profiles),
   212        "If given, write the field profiles to disk as well as the action")
   213       (
"shooting-ansatz",  po::bool_switch(&input.
shooting_ansatz)->default_value(default_shooting_ansatz),
   214        "If given, use the shooting method to calculate an ansatz")
   215       (
"verbose", po::bool_switch(&input.
verbose)->default_value(default_verbose),
   216        "If given, produce verbose logging output")
   217       (
"shoot-bisect-bits", po::value<int>(&input.
shoot_bisect_bits)->default_value(default_shoot_bisect_bits),
   218        "1D shooting: target relative precision in significant bits when bisecting")
   219       (
"action-arrived-rel", po::value<double>(&input.
action_arrived_rel)->default_value(default_action_arrived_rel),
   220        "1D shooting: relative tolerance for arriving at false vacuum when calculating action")
   221       (
"shoot-ode-abs", po::value<double>(&input.
shoot_ode_abs)->default_value(default_shoot_ode_abs),
   222        "1D shooting: absolute error tolerance for ODE integrator (bubble profile)")
   223       (
"shoot-ode-rel", po::value<double>(&input.
shoot_ode_rel)->default_value(default_shoot_ode_rel),
   224        "1D shooting: relative error tolerance for ODE integrator (bubble profile)")
   225       (
"action-ode-abs", po::value<double>(&input.
action_ode_abs)->default_value(default_action_ode_abs),
   226        "1D shooting: absolute error tolerance for ODE integrator (action integral)")
   227       (
"action-ode-rel", po::value<double>(&input.
action_ode_rel)->default_value(default_action_ode_rel),
   228        "1D shooting: relative error tolerance for ODE integrator (action integral)")
   229       (
"drho-frac", po::value<double>(&input.
drho_frac)->default_value(default_drho_frac),
   230        "1D shooting: initial step size relative to characteristic bubble scale")
   231       (
"evolve-change-rel", po::value<double>(&input.
evolve_change_rel)->default_value(default_evolve_change_rel),
   232        "1D shooting: evolve using approximate solution until field has changed by this much, relative to false vacuum")
   233       (
"bisect-lambda-max", po::value<double>(&input.
bisect_lambda_max)->default_value(default_bisect_lambda_max),
   234        "1D shooting: maximum value of bisection parameter lambda")
   235       (
"iter-max", po::value<int>(&input.
iter_max)->default_value(default_iter_max),
   236        "1D shooting: set maximum number of shooting iterations")
   237       (
"periods-max", po::value<double>(&input.
periods_max)->default_value(default_periods_max),
   238        "1D shooting: domain size in terms of characteristic oscillation periods")
   239       (
"f-y-max", po::value<double>(&input.
f_y_max)->default_value(default_f_y_max),
   240        "1D shooting: threshold for asymptotic approximation in analytic evolution")
   241       (
"f-y-min", po::value<double>(&input.
f_y_min)->default_value(default_f_y_min),
   242        "1D shooting: threshold for asymptotic approximation in analytic evolution")
   243       (
"y-max", po::value<double>(&input.
y_max)->default_value(default_y_max),
   244        "1D shooting: threshold for asymptotic approximation in analytic evolution")
   247    po::variables_map vm;
   249       po::parse_command_line(
   251          po::command_line_style::unix_style ^ po::command_line_style::allow_short),
   254    if (vm.count(
"help")) {
   255       std::cout << desc << std::endl;
   261    if (vm.count(
"max-iterations")) {
   262       const int max_iterations = vm[
"max-iterations"].as<
int>();
   263       if (max_iterations < 0) {
   264          std::cerr << 
"Error: number of iterations must be non-negative"   273    if (vm.count(
"global-minimum")) {
   274       input.
global_min = vm[
"global-minimum"].as<std::vector<double> >();
   276    if (vm.count(
"local-minimum")) {
   277       input.
local_min = vm[
"local-minimum"].as<std::vector<double> >();
   279    if (vm.count(
"barrier")) {
   280       input.
barrier = vm[
"barrier"].as<std::vector<double> >();
   294    ostr << 
"# Action: " << action << std::endl;
   308         << std::left << std::setw(16) << 
"rho";
   310    for (
const auto& name: fields) {
   311       ostr << 
' ' << std::left << std::setw(16) << name;
   318    const int n_grid_points = coord_values.size();
   321    for (
int i = 0; i < n_grid_points; ++i) {
   322       ostr << 
"  " << std::left
   323            << std::setw(16) << std::setprecision(8)
   324            << std::scientific << coord_values(i);
   325       for (
int j = 0; j < 
n_fields; ++j) {
   326          ostr << 
' ' << std::left
   327               << std::setw(16) << std::setprecision(8)
   328               << std::scientific << field_values(i, j);
   343    const auto v = [&potential](
const Eigen::VectorXd& x) -> 
double {
   352    const Eigen::VectorXd initial_guess(Eigen::VectorXd::Zero(n_fields));
   353    const auto status = optimizer.
optimize(initial_guess);
   356       std::cerr << 
"Error: unable to locate global minimum." << std::endl;
   379    const Eigen::VectorXd& true_vacuum_loc,
   380    const Eigen::VectorXd& false_vacuum_loc,
   385       throw Setup_error(
"automatically locating potential barrier only "   386                         "supported for single field case");
   389    const auto v = [&potential](
const Eigen::VectorXd& x) {
   401                                        false_vacuum_loc(0)));
   403                                        false_vacuum_loc(0)));
   406    Eigen::VectorXd initial_guess(0.5 * (true_vacuum_loc + false_vacuum_loc));
   407    const auto status = optimizer.
optimize(initial_guess);
   410       std::cerr << 
"Error: unable to locate barrier. NLOPT status = "   411                 << status << std::endl;
   442                         Eigen::VectorXd& true_vacuum_loc,
   443                         Eigen::VectorXd& false_vacuum_loc)
   449          false_vacuum_loc = Eigen::VectorXd::Zero(n_fields);
   451          throw Setup_error(
"location of false vacuum not specified");
   455          throw Setup_error(
"number of fields does not match dimensions "   459       false_vacuum_loc = Eigen::VectorXd::Map(input.
local_min.data(),
   467          throw Setup_error(
"number of fields does not match dimensions "   468                            "of global minimum");
   471       true_vacuum_loc = Eigen::VectorXd::Map(input.
global_min.data(),
   507                         Eigen::VectorXd& true_vacuum_loc,
   508                         Eigen::VectorXd& false_vacuum_loc,
   509                         Eigen::VectorXd& barrier_loc)
   514       throw Setup_error(
"automatically locating potential barrier only "   515                         "supported for single field case");
   527          throw Setup_error(
"number of fields does not match dimensions "   528                            "of barrier location");
   530       barrier_loc = Eigen::VectorXd::Map(input.
barrier.data(),
   548    Eigen::VectorXd true_vacuum_loc(n_fields);
   549    Eigen::VectorXd false_vacuum_loc(n_fields);
   550    Eigen::VectorXd barrier(n_fields);
   555    unsigned int options = Shooting::Solver_options::Compute_action;
   557       options = options | Shooting::Solver_options::Compute_profile;
   576    solver.
solve(potential, false_vacuum_loc(0),
   577                 true_vacuum_loc(0), barrier(0), input.
n_dims, options);
   598 template <
class Profiler>
   606    Eigen::VectorXd false_vacuum_loc(n_fields);
   607    Eigen::VectorXd true_vacuum_loc(n_fields);
   619    profiler.set_false_vacuum_loc(false_vacuum_loc);
   620    profiler.set_true_vacuum_loc(true_vacuum_loc);
   621    profiler.set_number_of_dimensions(input.
n_dims);
   623    auto root_finder = std::make_shared<GSL_root_finder<Eigen::Dynamic> >();
   624    profiler.set_root_finder(root_finder);
   626    std::shared_ptr<Profile_guesser> guesser;
   628       guesser = std::make_shared<Shooting_profile_guesser>();
   631       guesser = std::make_shared<Instream_profile_guesser>(ansatz_input);
   633       guesser = std::make_shared<Kink_profile_guesser>();
   635    profiler.set_initial_guesser(guesser);
   637    auto convergence_tester = std::make_shared<Relative_convergence_tester>(
   642    profiler.set_convergence_tester(convergence_tester);
   646       profiler.calculate_bubble_profile(potential, observer);
   648       profiler.calculate_bubble_profile(potential);
   653       profiles = profiler.get_bubble_profile();
   656    return std::make_tuple(profiler.get_euclidean_action(), profiles);
   683       throw Setup_error(
"unrecognized integration method");
   697    std::tuple<double, Field_profiles> result;
   733 int main(
int argc, 
const char* argv[])
   743       std::cout << 
"Potential: " << input.
potential << std::endl;
   744       for (
const auto& f: input.
fields) {
   745          std::cout << 
"Field: " << f << std::endl;
   752             if (fs::exists(output_file)) {
   753                std::cerr << 
"Error: output file already exists.\n";
   754                std::cerr << 
"Please specify a different output file, or use\n";
   755                std::cerr << 
"the --force-output option.\n";
   764             fs::create_directory(output_path);
   765          } 
else if (fs::is_regular_file(output_path)) {
   766             throw Setup_error(
"Error: output path is a regular file");
   768             std::cerr << 
"Error: output directory already exists.\n";
   769             std::cerr << 
"Please specify a different output path, or use\n";
   770             std::cerr << 
"the --force-output option.\n";
   778       std::cerr << 
"Error: " << e.what() << std::endl;
   780    } 
catch (
const Error& e) {
   781       std::cerr << 
"Error: " << e.what() << std::endl;
   783    } 
catch (
const std::runtime_error& e) {
   784       std::cerr << 
"runtime error:  " <<  e.what() << std::endl;
   786    } 
catch (
const std::exception& e) {
   787       std::cerr << 
"Exception:  " <<  e.what() << std::endl;
   789    } 
catch (
const std::string& a) {
   793       std::cerr << 
"Unknown type of exception caught.\n";
 
void run_profiler(const Bubble_profiler_inputs &input)
Calculates the action and bubble profile for the given potential. 
void set_shooting_rel_tol(double tol)
const int default_shoot_bisect_bits
const bool default_shooting_ansatz
const Eigen::VectorXd & get_spatial_grid() const 
Get a vector of the grid point coordinates. 
void initialize_extrema(const Potential &potential, const Bubble_profiler_inputs &input, Eigen::VectorXd &true_vacuum_loc, Eigen::VectorXd &false_vacuum_loc)
Locate the requested critical points if not already provided. 
const double default_evolve_change_rel
void set_max_iterations(int i)
nlopt::result optimize(const Eigen::VectorXd &guess)
void set_max_time(double maxtime)
const std::string default_output_file
const double default_bisect_lambda_max
const int default_iter_max
std::tuple< double, Field_profiles > run_shooting_profiler(const Bubble_profiler_inputs &input)
Calculates the action and bubble profile using the shooting method. 
Bubble_profiler_inputs parse_cmd_line_args(int argc, const char *argv[])
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))
const double default_initial_step_size
bool optimization_succeeded(nlopt::result)
int main(int argc, const char *argv[])
contains the definition of the Instream_profile_guesser class 
void set_bisect_lambda_max(double l)
virtual std::size_t get_number_of_fields() const override
Eigen::VectorXd find_one_dimensional_barrier(const Potential &potential, const Eigen::VectorXd &true_vacuum_loc, const Eigen::VectorXd &false_vacuum_loc, double opt_timeout)
Find barrier directly between two minima of a 1D potential. 
const double default_action_ode_abs
void write_profiles(const std::vector< std::string > &fields, const Field_profiles &profiles, std::ostream &ostr)
Write the given field profiles to requested output stream. 
static Logging_manager & get_manager()
const Field_profiles & get_bubble_profile() const 
void set_upper_bounds(double ub)
double get_euclidean_action() const 
const double default_periods_max
const std::string default_ansatz_file
const double default_f_y_min
const double default_drho_frac
void configure_logging(const Bubble_profiler_inputs &input)
void set_f_y_max(double f)
const bool default_assume_origin_false_vacuum
const bool default_write_profiles
const double default_rtol_fields
const double default_f_y_max
void set_action_rel_tol(double tol)
const double default_y_max
const double default_shoot_ode_abs
const double default_domain_start
const double default_domain_end
void set_f_y_min(double f)
const double default_opt_timeout
void write_action(double action, std::ostream &ostr)
Write the value of the action to requested output stream. 
void set_evolve_change_rel(double frac)
const bool default_force_output
void set_lower_bounds(double lb)
Observes the profile during iteration and writes out profile, perturbations and action for each step ...
void set_action_arrived_rel(double tol)
void set_action_abs_tol(double tol)
const int default_interp_fraction
void set_max_periods(double p)
const bool default_write_perturbations
void set_drho_frac(double frac)
std::tuple< double, Field_profiles > run_perturbative_profiler(const Bubble_profiler_inputs &input, Profiler &profiler)
Calculates the action and bubble profile using the perturbative method. 
Solve the one-dimensional problem using the shooting method. 
void set_extremum_type(Extremum_type e)
Eigen::VectorXd get_extremum_location() const 
virtual std::size_t get_number_of_fields() const =0
Exception indicating general setup error. 
const Integration_algorithm default_algorithm
void set_ftol_rel(double ftol_rel_)
One-dimensional shooting method. 
const bool default_use_perturbative
const double default_action_arrived_rel
const int default_max_iterations
Implements a multi dimensional scalar field potential, which may be expressed as almost any algerbrai...
Abstract base class for a generic potential. 
const double default_rtol_action
Eigen::VectorXd find_global_min(const Potential &potential, double opt_timeout)
Find the global minimum of the given potential. 
void set_shooting_abs_tol(double tol)
const bool default_verbose
void validate(boost::any &v, const std::vector< std::string > &values, Integration_algorithm *, int)
void set_xtol_rel(double xtol_rel_)
void set_bisection_precision_bits(int b)
Discretized set of field profiles. 
Bounce solver using perturbative method. 
const Eigen::MatrixXd & get_field_profiles() const 
Get the field profile data in matrix form. 
const double default_action_ode_rel
const double default_shoot_ode_rel