CDT++
Causal Dynamical Triangulations in C++
Loading...
Searching...
No Matches
cdt-viewer.cpp
Go to the documentation of this file.
1/*******************************************************************************
2Causal Dynamical Triangulations in C++ using CGAL
3Copyright © 2022 Adam Getchell
4******************************************************************************/
5
9
10#ifdef NDEBUG
11#define DOCTEST_CONFIG_DISABLE
12#endif
13
14#include <CGAL/draw_triangulation_3.h>
15
16#define DOCTEST_CONFIG_IMPLEMENT
17
18#include <doctest/doctest.h>
19#include <spdlog/spdlog.h>
20
21#include <boost/program_options.hpp>
22
23#include "Manifold.hpp"
24#include "Utilities.hpp"
25
26namespace po = boost::program_options;
27
28static auto constexpr USAGE =
29 R"(Causal Dynamical Triangulations in C++ using CGAL.
30
31Copyright (c) 2022 Adam Getchell
32
33A program that views 3D triangulated spacetimes with a defined causal
34structure. Specify the filename of the triangulation to view.
35
36Usage:
37 cdt-viewer -f FILENAME
38
39Options)";
40
41auto main(int const argc, char* const argv[]) -> int
42try
43{
44 // Doctest integration into code
45 doctest::Context context;
46 context.setOption("no-breaks",
47 true); // don't break in debugger when assertions fail
48 context.applyCommandLine(argc, argv);
49
50 int const res = context.run(); // run tests unless --no-run is specified
51 if (context.shouldExit())
52 { // important - query flags (and --exit) rely on the user doing this
53 return res; // propagate the result of the tests
54 }
55
56 context.clearFilters(); // important - otherwise the context filters will be
57 // used during the next evaluation of RUN_ALL_TESTS,
58 // which will lead to wrong results
59
60 std::string const intro{USAGE};
61 // Parsed arguments
62 std::string filename;
63
64 po::options_description description(intro);
65 description.add_options()("help,h", "Show this message")(
66 "version,v", "Show program version")("dry-run",
67 "Don't actually do anything")(
68 "filename,f", po::value<std::string>(&filename),
69 "Filename of triangulation to view");
70
71 po::variables_map args;
72 po::store(po::parse_command_line(argc, argv, description), args);
73 po::notify(args);
74
75 if (args.count("help"))
76 {
77 std::cout << description << "\n";
78 return res + EXIT_SUCCESS;
79 }
80
81 if (args.count("version"))
82 {
83 fmt::print("cdt-viewer 1.0\n");
84 return res + EXIT_SUCCESS;
85 }
86
87 if (args.count("dry-run"))
88 {
89 fmt::print("Dry run. Exiting.\n");
90 return res + EXIT_SUCCESS;
91 }
92
93 fmt::print("cdt-viewer started at {}\n", utilities::current_date_time());
94 fmt::print("Reading triangulation from file {}\n",
95 std::string_view(filename));
96
97 // Read from file
98 auto const dt_in = utilities::read_file<Delaunay_t<3>>(filename);
99
100 // Draw triangulation
101 fmt::print("Drawing {}\n", filename);
102 draw(dt_in);
103
104 return res + EXIT_SUCCESS;
105}
106
107catch (std::exception const& e)
108{
109 spdlog::critical("Error: {}\n", e.what());
110 return EXIT_FAILURE;
111}
112
113catch (...)
114{
115 spdlog::critical("Something went wrong ... Exiting.\n");
116 return EXIT_FAILURE;
117}
118
119SCENARIO("Given a 3D Manifold, it can be written to file and read back in." *
120 doctest::test_suite("cdt-viewer"))
121{
122 GIVEN("A 3D Manifold.")
123 {
124 auto constexpr simplices = 640;
125 auto constexpr timeslices = 4;
126 manifolds::Manifold_3 const manifold(simplices, timeslices);
127
128 WHEN("It is written to file.")
129 {
130 auto const filename = utilities::make_filename(manifold);
131 utilities::write_file(manifold);
132
133 THEN("It can be read back in.")
134 {
135 auto dt_in = utilities::read_file<Delaunay_t<3>>(filename);
136 REQUIRE(dt_in.is_valid(true));
137 REQUIRE_EQ(dt_in.dimension(), manifold.dimensionality());
138 REQUIRE_EQ(dt_in.number_of_finite_cells(), manifold.N3());
139 REQUIRE_EQ(dt_in.number_of_finite_facets(), manifold.N2());
140 REQUIRE_EQ(dt_in.number_of_finite_edges(), manifold.N1());
141 REQUIRE_EQ(dt_in.number_of_vertices(), manifold.N0());
142 }
143 THEN("It can be drawn.")
144 {
145 auto const dt_in = utilities::read_file<Delaunay_t<3>>(filename);
146 CGAL::draw(dt_in);
147 // Cleanup test file
148 REQUIRE_NOTHROW(std::filesystem::remove(filename));
149 }
150 }
151 }
152 GIVEN("A non-existent filename.")
153 {
154 WHEN("It is read back in.")
155 {
156 THEN("An exception is thrown.")
157 {
158 REQUIRE_THROWS_AS(utilities::read_file<Delaunay_t<3>>("unused.off"),
159 std::filesystem::filesystem_error);
160 }
161 }
162 }
163}
Data structures for manifolds.
Utility functions.
auto make_filename(topology_type const &t_topology, Int_precision t_dimension, Int_precision t_number_of_simplices, Int_precision t_number_of_timeslices, double t_initial_radius, double t_foliation_spacing) noexcept -> std::filesystem::path
Generate useful filenames.
Definition: Utilities.hpp:93
void write_file(std::filesystem::path const &filename, TriangulationType triangulation)
Write triangulation to file.
Definition: Utilities.hpp:163
SCENARIO("Perform bistellar flip on Delaunay triangulation" *doctest::test_suite("bistellar"))