2 #ifndef MESH_OPTIMIZER_HH_ 3 #define MESH_OPTIMIZER_HH_ 24 return (vec - shift_) / scalar_;
36 static_assert(DIM == 2 || DIM == 3,
"DIM must be either 2 or 3.");
42 for (
auto nod : mesh_->node_range()) {
45 double mesh_longest_size = bounding_box.longest_size();
46 normalizer_ =
Normalizer(bounding_box.min(), mesh_longest_size);
48 node_sizes_.resize(mesh_->n_nodes(), INFINITY);
49 element_sizes_.reserve(mesh_->n_elements());
51 double elm_norm_size = elm.bounding_box().longest_size() / mesh_longest_size;
52 element_sizes_.push_back(elm_norm_size);
53 for (
uint i = 0; i < elm.dim() + 1; ++i) {
54 node_sizes_[elm->node_idx(i)] = std::min({ node_sizes_[elm->node_idx(i)], elm_norm_size });
60 node_refs_.reserve(mesh_->n_nodes());
62 for (
auto nod : mesh_->node_range()) {
63 node_refs_.emplace_back(i, hilbert_value(normalizer_.normalize( *nod ), node_sizes_[i]));
69 node_refs_.reserve(mesh_->n_nodes());
71 for (
auto nod : mesh_->node_range()) {
72 node_refs_.emplace_back(i, zcurve_value(normalizer_.normalize( *nod ), node_sizes_[i]));
77 node_refs_.reserve(mesh_->n_nodes());
78 for (
uint i = 0; i < mesh_->n_elements(); ++i) {
80 for (
uint j = 0; j < elm->dim() + 1; ++j) {
81 node_refs_.emplace_back(elm->node_idx(j), element_refs_[i].curve_value_);
87 element_refs_.reserve(mesh_->n_elements());
89 for (
auto elm : mesh_->elements_range()) {
90 element_refs_.emplace_back(i, hilbert_value(normalizer_.normalize(elm.centre()), element_sizes_[i]));
96 element_refs_.reserve(mesh_->n_elements());
98 for (
auto elm : mesh_->elements_range()) {
99 element_refs_.emplace_back(i, zcurve_value(normalizer_.normalize(elm.centre()), element_sizes_[i]));
105 return this->sort(node_refs_, node_permutation);
109 return this->sort(element_refs_, elem_permutation);
126 return hilbert_value(2 * y, 2 * x, 4 * eps) / 4;
128 return (1 + hilbert_value(2 * x, 2 * y - 1, 4 * eps)) / 4;
132 return (2 + hilbert_value(2 * x - 1, 2 * y - 1, 4 * eps)) / 4;
134 return (3 + hilbert_value(1 - 2 * y, 2 - 2 * x, 4 * eps)) / 4;
140 inline double hilbert_value(
double x,
double y,
double z,
double eps)
const {
147 return hilbert_value(2 * z, 2 * x, 2 * y, 8 * eps) / 8;
149 return (1 + hilbert_value(2 * y - 1, 2 * z, 2 * x, 8 * eps)) / 8;
153 return (2 + hilbert_value(2 * y - 1, 2 * z, 2 * x - 1, 8 * eps)) / 8;
155 return (3 + hilbert_value(2 - 2 * x, 1 - 2 * y, 2 * z, 8 * eps)) / 8;
161 return (4 + hilbert_value(2 - 2 * x, 1 - 2 * y, 2 * z - 1, 8 * eps)) / 8;
163 return (5 + hilbert_value(2 * y - 1, 2 - 2 * z, 2 - 2 * x, 8 * eps)) / 8;
167 return (6 + hilbert_value(2 * y - 1, 2 - 2 * z, 1 - 2 * x, 8 * eps)) / 8;
169 return (7 + hilbert_value(2 - 2 * z, 2 * x, 1 - 2 * y, 8 * eps)) / 8;
182 return zcurve_value(2 * x, 2 * y, 4 * eps) / 4;
184 return (1 + zcurve_value(2 * x - 1, 2 * y, 4 * eps)) / 4;
188 return (2 + zcurve_value(2 * x, 2 * y - 1, 4 * eps)) / 4;
190 return (3 + zcurve_value(2 * x - 1, 2 * y - 1, 4 * eps)) / 4;
196 inline double zcurve_value(
double x,
double y,
double z,
double eps)
const {
203 return zcurve_value(2 * x, 2 * y, 2 * z, 8 * eps) / 8;
205 return (1 + zcurve_value(2 * x - 1, 2 * y, 2 * z, 8 * eps)) / 8;
209 return (2 + zcurve_value(2 * x, 2 * y - 1, 2 * z, 8 * eps)) / 8;
211 return (3 + zcurve_value(2 * x - 1, 2 * y - 1, 2 * z, 8 * eps)) / 8;
217 return (4 + zcurve_value(2 * x, 2 * y, 2 * z - 1, 8 * eps)) / 8;
219 return (5 + zcurve_value(2 * x - 1, 2 * y, 2 * z - 1, 8 * eps)) / 8;
223 return (6 + zcurve_value(2 * x, 2 * y - 1, 2 * z - 1, 8 * eps)) / 8;
225 return (7 + zcurve_value(2 * x - 1, 2 * y - 1, 2 * z - 1, 8 * eps)) / 8;
233 return hilbert_value(vec[0], vec[1], vec[2], size * size * size);
237 return zcurve_value(vec[0], vec[1], vec[2], size * size * size);
242 std::sort(refs.begin(), refs.end());
244 mesh_ids.reserve(refs.size());
245 for (
uint i = 0; i < refs.size(); ++i) {
246 mesh_perm[ refs[i].original_index_ ] = i;
256 return hilbert_value(vec[0], vec[1], size * size);
261 return zcurve_value(vec[0], vec[1], size * size);
Bounding box in 3d ambient space.
void calculate_node_curve_values_as_zcurve()
std::vector< Permutee > element_refs_
std::vector< int > sort_nodes(std::vector< unsigned int > &node_permutation)
std::vector< int > sort(std::vector< Permutee > &refs, std::vector< unsigned int > &mesh_perm)
arma::vec3 normalize(const arma::vec3 vec)
std::vector< double > element_sizes_
void expand(const Point &point)
bool operator<(const Permutee &first, const Permutee &second)
std::vector< double > node_sizes_
double hilbert_value(arma::vec3 vec, double size) const
std::vector< Permutee > node_refs_
double zcurve_value(double x, double y, double z, double eps) const
void calculate_element_curve_values_as_hilbert_of_centers()
void calculate_element_curve_values_as_zcurve_of_center()
MeshOptimizer(Mesh *mesh)
Normalizer(arma::vec3 shift, double scalar)
void calculate_node_curve_values_as_obtained_from_elements()
double zcurve_value(double x, double y, double eps) const
double hilbert_value(double x, double y, double z, double eps) const
double hilbert_value(double x, double y, double eps) const
Permutee(uint original_index, double curve_value)
double zcurve_value(arma::vec3 vec, double size) const
void calculate_node_curve_values_as_hilbert()
Implementation of range helper class.
std::vector< int > sort_elements(std::vector< unsigned int > &elem_permutation)