SemiDiscreteOT 1.0
Semi-Discrete Optimal Transport Library
Loading...
Searching...
No Matches
ExactSot.cc
Go to the documentation of this file.
3
5 : source_mesh(std::make_unique<GEO::Mesh>()),
6 max_iterations_(1000),
7 epsilon_(0.01)
8{
9 // Initialize Geogram
10 GEO::initialize();
11 using namespace GEO;
12
13 CmdLine::import_arg_group("standard");
14 CmdLine::import_arg_group("algo");
15 CmdLine::import_arg_group("opt");
16 CmdLine::declare_arg("nb_iter", 1000, "number of iterations for OTM");
17
18 CmdLine::declare_arg_group(
19 "RVD", "RVD output options", CmdLine::ARG_ADVANCED);
20 CmdLine::declare_arg("RVD", false, "save restricted Voronoi diagram");
21 CmdLine::declare_arg(
22 "RVD_iter", false, "save restricted Voronoi diagram at each iteration");
23 CmdLine::declare_arg(
24 "RVD:borders_only", false, "save only border of RVD");
25 CmdLine::declare_arg(
26 "RVD:integration_simplices", true, "export RVD as integration simplices");
27
28 CmdLine::declare_arg("multilevel", true, "use multilevel algorithm");
29 CmdLine::declare_arg("BRIO", true,
30 "use BRIO reordering to compute the levels");
31 CmdLine::declare_arg("ratio", 0.125, "ratio between levels");
32 CmdLine::declare_arg("epsilon", 0.01, "relative measure error in a cell");
33 CmdLine::declare_arg(
34 "lock", true, "Lock lower levels when sampling shape");
35 CmdLine::declare_arg(
36 "fitting_degree", 2, "degree for interpolating weights");
37 CmdLine::declare_arg(
38 "project", true, "project sampling on border");
39 CmdLine::declare_arg(
40 "feature_sensitive", true, "attempt to recover hard edges");
41 CmdLine::declare_arg(
42 "singular", false, "compute and save singular surface");
43 CmdLine::set_arg("algo:delaunay", "BPOW");
44 CmdLine::declare_arg(
45 "recenter", true, "recenter target onto source mesh");
46 CmdLine::declare_arg(
47 "rescale", true, "rescale target to match source volume");
48}
49
50ExactSot::~ExactSot() = default;
51
52bool ExactSot::load_volume_mesh(const std::string& filename, GEO::Mesh& mesh) {
53 GEO::MeshIOFlags flags;
54 flags.set_element(GEO::MESH_CELLS);
55 flags.set_attribute(GEO::MESH_CELL_REGION);
56
57 std::cout << "Loading mesh from " << filename << std::endl;
58 if (!GEO::mesh_load(filename, mesh, flags)) {
59 return false;
60 }
61
62 if (!mesh.cells.are_simplices()) {
63 std::cerr << "File " << filename
64 << " should only have tetrahedra" << std::endl;
65 return false;
66 }
67
68 if (mesh.cells.nb() == 0) {
69 std::cout << "File " << filename
70 << " does not contain a volume" << std::endl;
71 std::cout << "Trying to tetrahedralize..." << std::endl;
72 if (!GEO::mesh_tetrahedralize(mesh, true, false)) {
73 return false;
74 }
75 }
76 return true;
77}
78
79bool ExactSot::set_source_mesh(const std::string& filename) {
80 return load_volume_mesh(filename, *source_mesh);
81}
82
83bool ExactSot::set_target_points(const std::string& filename, const std::string& io_coding) {
84 return Utils::read_vector(target_points, filename, io_coding);
85}
86
87void ExactSot::set_parameters(unsigned int max_iterations,
88 double epsilon) {
89 max_iterations_ = max_iterations;
90 epsilon_ = epsilon;
91}
92
94 try {
95 if (target_points.empty()) {
96 std::cerr << "No target points loaded. Please load target points before running." << std::endl;
97 return false;
98 }
99
100 std::cout << "Setting up optimal transport computation..." << std::endl;
101
102 // Set density on source mesh (uniform density for now)
103 GEO::Attribute<double> density(source_mesh->vertices.attributes(), "density");
104 for(GEO::index_t v=0; v < source_mesh->vertices.nb(); ++v) {
105 density[v] = 1.0;
106 }
107
108 // Everything happens in dimension 4 (power diagram is seen
109 // as Voronoi diagram in dimension 4)
110 source_mesh->vertices.set_dimension(4);
111 std::cout << "Source mesh vertices dimension: " << source_mesh->vertices.dimension() << std::endl;
112
113 // Create and setup OTM
114 GEO::OptimalTransportMap3d OTM(source_mesh.get());
115 std::cout << "Optimal transport map created" << std::endl;
116
117 // Convert target points to Geogram format
118 std::vector<double> target_points_data;
119 target_points_data.reserve(target_points.size() * 3);
120 for (const auto& point : target_points) {
121 target_points_data.push_back(point[0]);
122 target_points_data.push_back(point[1]);
123 target_points_data.push_back(point[2]);
124 }
125
126 OTM.set_points(
127 target_points.size(),
128 target_points_data.data()
129 );
130
131 OTM.set_epsilon(epsilon_);
132
133 std::cout << "Running optimization with " << max_iterations_
134 << " iterations and epsilon = " << epsilon_ << std::endl;
135
136 // Run optimization
137 OTM.optimize(max_iterations_);
138
139 // Store results
140 potential.resize(OTM.nb_points());
141 for (GEO::index_t i = 0; i < OTM.nb_points(); ++i) {
142 potential[i] = OTM.weight(i);
143 }
144
145 std::cout << "Optimization completed successfully" << std::endl;
146 return true;
147 } catch (const std::exception& e) {
148 std::cerr << "Error during computation: " << e.what() << std::endl;
149 return false;
150 }
151}
152
153std::vector<double> ExactSot::get_potential() const {
154 return std::vector<double>(potential.begin(), potential.end());
155}
156
157std::vector<dealii::Point<3>> ExactSot::get_target_points() const {
158 return target_points;
159}
160
161bool ExactSot::save_results(const std::string& potential_file,
162 const std::string& points_file,
163 const std::string& io_coding) const {
164 try {
165 std::cout << "Saving potential to " << potential_file << std::endl;
166 // Save potential using Utils
167 std::vector<double> potential_vec(potential.begin(), potential.end());
168 Utils::write_vector(potential_vec, potential_file, io_coding);
169
170 std::cout << "Saving points to " << points_file << std::endl;
171 // Save points directly using Utils
172 Utils::write_vector(target_points, points_file, io_coding);
173
174 std::cout << "Results saved successfully" << std::endl;
175 return true;
176 } catch (const std::exception& e) {
177 std::cerr << "Error saving results: " << e.what() << std::endl;
178 return false;
179 }
180}
std::vector< double > get_potential() const
Get computed potential.
Definition ExactSot.cc:153
ExactSot()
Constructor.
Definition ExactSot.cc:4
double epsilon_
Definition ExactSot.h:117
std::vector< dealii::Point< 3 > > target_points
Definition ExactSot.h:113
bool set_source_mesh(const std::string &filename)
Set source mesh from file.
Definition ExactSot.cc:79
bool save_results(const std::string &potential_file, const std::string &points_file, const std::string &io_coding="txt") const
Save computation results to files.
Definition ExactSot.cc:161
void set_parameters(unsigned int max_iterations=1000, double epsilon=0.01)
Set parameters for the solver.
Definition ExactSot.cc:87
GEO::vector< double > potential
Definition ExactSot.h:112
bool set_target_points(const std::string &filename, const std::string &io_coding)
Set target points from file.
Definition ExactSot.cc:83
bool load_volume_mesh(const std::string &filename, GEO::Mesh &mesh)
Definition ExactSot.cc:52
unsigned int max_iterations_
Definition ExactSot.h:116
bool run()
Run the exact SOT computation.
Definition ExactSot.cc:93
std::unique_ptr< GEO::Mesh > source_mesh
Definition ExactSot.h:111
std::vector< dealii::Point< 3 > > get_target_points() const
Get target points.
Definition ExactSot.cc:157
~ExactSot()
Destructor.
void write_vector(const VectorContainer &points, const std::string &filepath, const std::string &fileMode="txt")
Write a vector container to a file in binary or text format.
Definition utils.h:56
bool read_vector(VectorContainer &points, const std::string &filepath, const std::string &fileMode="")
Read a vector container from a file in binary or text format.
Definition utils.h:108