CDT++
Causal Dynamical Triangulations in C++
Loading...
Searching...
No Matches
cdt.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 Causal Dynamical Triangulations in C++ using CGAL
3
4 Copyright © 2013 Adam Getchell
5 ******************************************************************************/
6
12
13#include <CGAL/Real_timer.h>
14
15#include <boost/program_options.hpp>
16#include <Metropolis.hpp>
17
18using Timer = CGAL::Real_timer;
19
20using namespace std;
21namespace po = boost::program_options;
22
24static string_view constexpr USAGE{
25 R"(Causal Dynamical Triangulations in C++ using CGAL.
26
27Copyright (c) 2013 Adam Getchell
28
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.
34
35Usage:./cdt (--spherical | --toroidal) -n SIMPLICES -t TIMESLICES
36 [-d DIM]
37 [--init INITIAL RADIUS]
38 [--foliate FOLIATION SPACING]
39 -k K
40 --alpha ALPHA
41 --lambda LAMBDA
42 [-p PASSES]
43 [-c CHECKPOINT]
44
45Optional arguments are in square brackets.
46
47Examples:
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
50
51Options)"};
52
57auto main(int const argc, char* const argv[]) -> int
58try
59{
60 std::string const intro{USAGE};
61 // Parsed arguments
62 topology_type topology;
63 long long simplices;
64 long long timeslices;
65 long long dimensions;
66 double initial_radius;
67 double foliation_spacing;
68 long double alpha;
69 long double k;
70 long double lambda;
71 long long passes;
72 long long checkpoint;
73
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>(&timeslices),
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),
85 "Initial radius")(
86 "foliate,f", po::value<double>(&foliation_spacing)->default_value(1.0),
87 "Foliation spacing")(
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");
96
97 po::variables_map args;
98 po::store(po::parse_command_line(argc, argv, description), args);
99 po::notify(args);
100
101 if (args.count("help"))
102 {
103 cout << description << "\n";
104 return EXIT_SUCCESS;
105 }
106
107 if (args.count("version"))
108 {
109 fmt::print("CDT++ version 0.1.8\n");
110 return EXIT_SUCCESS;
111 }
112
113 if (args.count("spherical")) { topology = topology_type::SPHERICAL; }
114 else if (args.count("toroidal")) { topology = topology_type::TOROIDAL; }
115 else
116 {
117 fmt::print("Topology not specified.\n");
118 return EXIT_FAILURE;
119 }
120
121 if (args.count("simplices"))
122 {
123 simplices = args["simplices"].as<long long>();
124 }
125 else
126 {
127 fmt::print("Number of simplices not specified.\n");
128 return EXIT_FAILURE;
129 }
130
131 if (args.count("timeslices"))
132 {
133 timeslices = args["timeslices"].as<long long>();
134 }
135 else
136 {
137 fmt::print("Number of timeslices not specified.\n");
138 return EXIT_FAILURE;
139 }
140
141 // Display job parameters
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);
154
155 // Start running time
156 Timer timer;
157 timer.start();
158 fmt::print("cdt started at {}\n", utilities::current_date_time());
159
160 if (simplices < 2 || timeslices < 2)
161 {
162 timer.stop();
163 throw invalid_argument(
164 "Simplices and timeslices should be greater or equal to 2.");
165 }
166
167 // Ensure Triangle inequalities hold
168 // See http://arxiv.org/abs/hep-th/0105267 for details
169 if (dimensions == 3 && abs(alpha) < static_cast<long double>(0.5)) // NOLINT
170 {
171 timer.stop(); // End running time counter
172 throw domain_error("Alpha in 3D should be greater than 1/2.");
173 }
174
175 // Initialize the Metropolis algorithm
176 Metropolis_3 run(alpha, k, lambda, static_cast<Int_precision>(passes),
177 static_cast<Int_precision>(checkpoint));
178
179 // Make a triangulation
180 manifolds::Manifold_3 universe;
181
182 switch (topology)
183 {
184 case topology_type::SPHERICAL:
185 if (dimensions == 3)
186 {
187 manifolds::Manifold_3 populated_universe(
188 static_cast<Int_precision>(simplices),
189 static_cast<Int_precision>(timeslices), initial_radius,
190 foliation_spacing);
191 // Manifold no-throw swapperator
192 swap(populated_universe, universe);
193 }
194 else
195 {
196 timer.stop(); // End running time counter
197 throw invalid_argument("Currently, dimensions cannot be >3.");
198 }
199 break;
200 case topology_type::TOROIDAL:
201 timer.stop(); // End running time counter
202 throw invalid_argument("Toroidal triangulations not yet supported.");
203 }
204
205 // Look at triangulation
206 universe.print();
207 universe.print_details();
209
210 // The main work of the program
211 auto const result = run(universe);
212
213 // Do we have enough timeslices?
214 if (auto max_timevalue = result.max_time(); max_timevalue < timeslices)
215 {
216 fmt::print("You wanted {} timeslices, but only got {}.\n", timeslices,
217 max_timevalue);
218 }
219
220 if (!result.is_valid()) { throw runtime_error("Result is invalid!\n"); }
221
222 // Print results
223 timer.stop(); // End running time counter
224 fmt::print("=== Run Results ===\n");
225 fmt::print("Running time is {} seconds.\n", timer.time());
226 result.print();
227 result.print_details();
228 result.print_volume_per_timeslice();
229
230 // Write results to file
231 utilities::write_file(result);
232
233 return EXIT_SUCCESS;
234}
235catch (domain_error const& DomainError)
236{
237 spdlog::critical("{}\n", DomainError.what());
238 spdlog::critical("Triangle inequalities violated ... Exiting.\n");
239 return EXIT_FAILURE;
240}
241catch (invalid_argument const& InvalidArgument)
242{
243 spdlog::critical("{}\n", InvalidArgument.what());
244 spdlog::critical("Invalid parameter ... Exiting.\n");
245 return EXIT_FAILURE;
246}
247catch (logic_error const& LogicError)
248{
249 spdlog::critical("{}\n", LogicError.what());
250 spdlog::critical("Simulation startup failed ... Exiting.\n");
251 return EXIT_FAILURE;
252}
253catch (runtime_error const& RuntimeError)
254{
255 spdlog::critical("{}\n", RuntimeError.what());
256 return EXIT_FAILURE;
257}
258catch (...)
259{
260 spdlog::critical("Something went wrong ... Exiting.\n");
261 return EXIT_FAILURE;
262}
Perform Metropolis-Hastings algorithm on Delaunay Triangulations.
std::int_fast32_t Int_precision
Definition: Settings.hpp:31
topology_type
clang-15 does not support std::format
Definition: Utilities.hpp:43
static string_view constexpr USAGE
Help message parsed by docopt into options.
Definition: cdt.cpp:24
Select a move algorithm.
void print() const
Print manifold.
Definition: Manifold.hpp:372
void print_details() const
Print details of the manifold.
Definition: Manifold.hpp:387
void print_volume_per_timeslice() const
Print the codimension 1 volume of simplices (faces) per timeslice.
Definition: Manifold.hpp:359