SemiDiscreteOT 1.0
Semi-Discrete Optimal Transport Library
Loading...
Searching...
No Matches
PowerDiagramDealII.cc
Go to the documentation of this file.
3#include <fstream>
4
5namespace PowerDiagramSpace {
6
7template <int dim, int spacedim>
8DealIIPowerDiagram<dim, spacedim>::DealIIPowerDiagram(const Triangulation<dim, spacedim> &source_mesh)
9 : source_triangulation(&source_mesh),
10 distance_function(euclidean_distance<spacedim>)
11{}
12
13template <int dim, int spacedim>
14void DealIIPowerDiagram<dim, spacedim>::set_generators(const std::vector<Point<spacedim>> &points, const Vector<double> &potentials)
15{
16 Assert(points.size() == potentials.size(),
17 ExcDimensionMismatch(points.size(), potentials.size()));
18
19 this->generator_points = points;
20 this->generator_potentials.resize(potentials.size());
21 for (unsigned int i = 0; i < potentials.size(); ++i)
22 this->generator_potentials[i] = potentials[i];
23}
24
25template <int dim, int spacedim>
27 const Point<spacedim> &point, const unsigned int generator_idx) const
28{
29 Assert(generator_idx < this->generator_points.size(),
30 ExcIndexRange(generator_idx, 0, this->generator_points.size()));
31 const double squared_distance =
32 std::pow(distance_function(point, this->generator_points[generator_idx]), 2);
33 return squared_distance - this->generator_potentials[generator_idx];
34}
35
36template <int dim, int spacedim>
38{
39 cell_assignments.clear();
40 cell_assignments.resize(source_triangulation->n_active_cells());
41
42 for (const auto &cell : source_triangulation->active_cell_iterators())
43 {
44 const Point<spacedim> cell_center = cell->center();
45 unsigned int closest_generator = 0;
46 double min_power_distance = power_distance(cell_center, 0);
47
48 for (unsigned int i = 1; i < this->generator_points.size(); ++i)
49 {
50 const double current_power_distance =
51 power_distance(cell_center, i);
52 if (current_power_distance < min_power_distance)
53 {
54 min_power_distance = current_power_distance;
55 closest_generator = i;
56 }
57 }
58 cell_assignments[cell->active_cell_index()] = closest_generator;
59 }
60}
61
62template <int dim, int spacedim>
63void DealIIPowerDiagram<dim, spacedim>::output_vtu(const std::string& filename) const
64{
65 // Convert cell_assignments to vector<double> for compatibility
66 std::vector<double> cell_data(cell_assignments.begin(), cell_assignments.end());
67
68 // Use Utils::write_mesh with VTU format
69 Utils::write_mesh(*source_triangulation,
70 filename,
71 std::vector<std::string>{"vtu"},
72 &cell_data,
73 "power_region");
74}
75
76template <int dim, int spacedim>
77unsigned int DealIIPowerDiagram<dim, spacedim>::get_cell_assignment(const unsigned int cell_index) const
78{
79 Assert(cell_index < cell_assignments.size(),
80 ExcIndexRange(cell_index, 0, cell_assignments.size()));
81 return cell_assignments[cell_index];
82}
83
84template <int dim, int spacedim>
85const std::vector<unsigned int>& DealIIPowerDiagram<dim, spacedim>::get_cell_assignments() const
86{
87 return cell_assignments;
88}
89
90template <int dim, int spacedim>
92{
93 Assert(!cell_assignments.empty(),
94 ExcMessage("Power diagram must be computed before calculating cell centroids."));
95
96 const unsigned int n_cells = this->generator_points.size();
97 this->cell_centroids.clear();
98 std::vector<Point<spacedim>> temp_centroids(n_cells, Point<spacedim>());
99 std::vector<double> cell_volumes(n_cells, 0.0);
100 unsigned int empty_cells = 0;
101
102 // Compute weighted sum of mesh element centers for each power cell
103 for (const auto &element : source_triangulation->active_cell_iterators())
104 {
105 const unsigned int cell_idx = cell_assignments[element->active_cell_index()];
106 const double volume = element->measure();
107 temp_centroids[cell_idx] += element->center() * volume;
108 cell_volumes[cell_idx] += volume;
109 }
110
111 // Store only valid centroids
112 for (unsigned int i = 0; i < n_cells; ++i)
113 {
114 if (cell_volumes[i] > 0.0)
115 {
116 this->cell_centroids.push_back(temp_centroids[i] / cell_volumes[i]);
117 }
118 else
119 {
120 empty_cells++;
121 }
122 }
123
124 std::cout << "Found " << empty_cells << " empty power cells out of "
125 << n_cells << " generators." << std::endl;
126}
127
128template <int dim, int spacedim>
130{
131 Assert(!this->cell_centroids.empty(),
132 ExcMessage("Cell centroids have not been computed. Call compute_cell_centroids() first."));
133
134 // Use Utils::write_vector for centroid output
135 Utils::write_vector(this->cell_centroids, filename, "txt");
136}
137
138template <int dim, int spacedim>
139const std::vector<Point<spacedim>>& DealIIPowerDiagram<dim, spacedim>::get_cell_centroids() const
140{
141 Assert(!this->cell_centroids.empty(),
142 ExcMessage("Cell centroids have not been computed. Call compute_cell_centroids() first."));
143 return this->cell_centroids;
144}
145
146// Explicit instantiation
147template class DealIIPowerDiagram<2>;
148template class DealIIPowerDiagram<3>;
149template class DealIIPowerDiagram<2, 3>;
150}
double euclidean_distance(const Point< spacedim > a, const Point< spacedim > b)
Computes the Euclidean distance between two points.
Definition Distance.h:24
A class for computing power diagrams using deal.II.
void output_vtu(const std::string &filename) const override
Outputs the power diagram to a VTU file.
unsigned int get_cell_assignment(const unsigned int cell_index) const
Returns the assignment of a cell to a generator.
DealIIPowerDiagram(const Triangulation< dim, spacedim > &source_mesh)
Constructor for the DealIIPowerDiagram class.
void compute_cell_centroids() override
Computes the centroids of the power cells.
void set_generators(const std::vector< Point< spacedim > > &points, const Vector< double > &potentials) override
Sets the generator points and their potentials.
void save_centroids_to_file(const std::string &filename) const override
Saves the centroids of the power cells to a file.
double power_distance(const Point< spacedim > &point, const unsigned int generator_idx) const
Computes the power distance between a point and a generator.
const std::vector< unsigned int > & get_cell_assignments() const
Returns the assignments of all cells to generators.
void compute_power_diagram() override
Computes the power diagram.
const std::vector< Point< spacedim > > & get_cell_centroids() const override
Returns the centroids of the power cells.
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 write_mesh(const dealii::Triangulation< dim, spacedim > &mesh, const std::string &filepath, const std::vector< std::string > &formats, const std::vector< double > *cell_data=nullptr, const std::string &data_name="cell_data")
Write mesh to file in specified formats with optional cell data.
Definition utils.h:410