13#include <CGAL/Real_timer.h>
15#include <boost/program_options.hpp>
18using Timer = CGAL::Real_timer;
21namespace po = boost::program_options;
24static string_view
constexpr USAGE{
25 R
"(Causal Dynamical Triangulations in C++ using CGAL.
27Copyright (c) 2013 Adam Getchell
29A program that generates d-dimensional triangulated spacetimes
30with a defined causal structure and evolves them according
31to the Metropolis algorithm. Specify the number of passes to control
32how much evolution is desired. Each pass attempts a number of ergodic
33moves equal to the number of simplices in the simulation.
35Usage:./cdt (--spherical | --toroidal) -n SIMPLICES -t TIMESLICES
37 [--init INITIAL RADIUS]
38 [--foliate FOLIATION SPACING]
45Optional arguments are in square brackets.
48./cdt --spherical -n 32000 -t 11 --alpha 0.6 -k 1.1 --lambda 0.1 --passes 1000
49./cdt -s -n32000 -t11 -a.6 -k1.1 -l.1 -p1000
57auto main(
int const argc,
char*
const argv[]) ->
int
60 std::string
const intro{
USAGE};
66 double initial_radius;
67 double foliation_spacing;
74 po::options_description description(intro);
75 description.add_options()(
"help,h",
"Show this message")(
76 "version,v",
"Show program version")(
"spherical,s",
"Spherical topology")(
77 "toroidal,e",
"Toroidal topology")(
"simplices,n",
78 po::value<long long>(&simplices),
79 "Approximate number of simplices")(
80 "timeslices,t", po::value<long long>(×lices),
81 "Number of timeslices")(
82 "dimensions,d", po::value<long long>(&dimensions)->default_value(3),
83 "Dimensionality")(
"init,i",
84 po::value<double>(&initial_radius)->default_value(1.0),
86 "foliate,f", po::value<double>(&foliation_spacing)->default_value(1.0),
88 "alpha,a", po::value<long double>(&alpha),
89 "Negative squared geodesic length of 1-d timelike edges")(
90 "k,k", po::value<long double>(&k),
"K = 1/(8*pi*G_newton)")(
91 "lambda,l", po::value<long double>(&lambda),
"K * Cosmological constant")(
92 "passes,p", po::value<long long>(&passes)->default_value(100),
93 "Number of passes")(
"checkpoint,c",
94 po::value<long long>(&checkpoint)->default_value(10),
95 "Checkpoint every n passes");
97 po::variables_map args;
98 po::store(po::parse_command_line(argc, argv, description), args);
101 if (args.count(
"help"))
103 cout << description <<
"\n";
107 if (args.count(
"version"))
109 fmt::print(
"CDT++ version 0.1.8\n");
113 if (args.count(
"spherical")) { topology = topology_type::SPHERICAL; }
114 else if (args.count(
"toroidal")) { topology = topology_type::TOROIDAL; }
117 fmt::print(
"Topology not specified.\n");
121 if (args.count(
"simplices"))
123 simplices = args[
"simplices"].as<
long long>();
127 fmt::print(
"Number of simplices not specified.\n");
131 if (args.count(
"timeslices"))
133 timeslices = args[
"timeslices"].as<
long long>();
137 fmt::print(
"Number of timeslices not specified.\n");
142 fmt::print(
"Topology is {}\n", utilities::topology_to_str(topology));
143 fmt::print(
"Dimensionality: {}+{}\n", dimensions - 1, 1);
144 fmt::print(
"Initial radius: {}\n", initial_radius);
145 fmt::print(
"Foliation spacing: {}\n", foliation_spacing);
146 fmt::print(
"Number of desired simplices: {}\n", simplices);
147 fmt::print(
"Number of desired timeslices: {}\n", timeslices);
148 fmt::print(
"Number of passes: {}\n", passes);
149 fmt::print(
"Checkpoint every {} passes.\n", checkpoint);
150 fmt::print(
"=== Parameters ===\n");
151 fmt::print(
"Alpha: {}\n", alpha);
152 fmt::print(
"K: {}\n", k);
153 fmt::print(
"Lambda: {}\n", lambda);
158 fmt::print(
"cdt started at {}\n", utilities::current_date_time());
160 if (simplices < 2 || timeslices < 2)
163 throw invalid_argument(
164 "Simplices and timeslices should be greater or equal to 2.");
169 if (dimensions == 3 && abs(alpha) <
static_cast<long double>(0.5))
172 throw domain_error(
"Alpha in 3D should be greater than 1/2.");
184 case topology_type::SPHERICAL:
192 swap(populated_universe, universe);
197 throw invalid_argument(
"Currently, dimensions cannot be >3.");
200 case topology_type::TOROIDAL:
202 throw invalid_argument(
"Toroidal triangulations not yet supported.");
211 auto const result = run(universe);
214 if (
auto max_timevalue = result.max_time(); max_timevalue < timeslices)
216 fmt::print(
"You wanted {} timeslices, but only got {}.\n", timeslices,
220 if (!result.is_valid()) {
throw runtime_error(
"Result is invalid!\n"); }
224 fmt::print(
"=== Run Results ===\n");
225 fmt::print(
"Running time is {} seconds.\n", timer.time());
227 result.print_details();
228 result.print_volume_per_timeslice();
231 utilities::write_file(result);
235catch (domain_error
const& DomainError)
237 spdlog::critical(
"{}\n", DomainError.what());
238 spdlog::critical(
"Triangle inequalities violated ... Exiting.\n");
241catch (invalid_argument
const& InvalidArgument)
243 spdlog::critical(
"{}\n", InvalidArgument.what());
244 spdlog::critical(
"Invalid parameter ... Exiting.\n");
247catch (logic_error
const& LogicError)
249 spdlog::critical(
"{}\n", LogicError.what());
250 spdlog::critical(
"Simulation startup failed ... Exiting.\n");
253catch (runtime_error
const& RuntimeError)
255 spdlog::critical(
"{}\n", RuntimeError.what());
260 spdlog::critical(
"Something went wrong ... Exiting.\n");
Perform Metropolis-Hastings algorithm on Delaunay Triangulations.
std::int_fast32_t Int_precision
topology_type
clang-15 does not support std::format
static string_view constexpr USAGE
Help message parsed by docopt into options.
void print() const
Print manifold.
void print_details() const
Print details of the manifold.
void print_volume_per_timeslice() const
Print the codimension 1 volume of simplices (faces) per timeslice.