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