fenris/mesh/
refinement.rs1use crate::allocators::DimAllocator;
6use crate::connectivity::Connectivity;
7use crate::mesh::Mesh;
8use nalgebra::{DefaultAllocator, DimName, OPoint, RealField};
9use std::collections::HashMap;
10use std::hash::Hash;
11
12pub mod detail;
13
14#[derive(Debug, Clone)]
15pub struct InvalidVertexCount;
16
17pub trait VertexRepresentation: Clone {
18 fn construct_vertex<T, D>(&self, all_vertices: &[OPoint<T, D>]) -> OPoint<T, D>
19 where
20 T: RealField,
21 D: DimName,
22 DefaultAllocator: DimAllocator<T, D>;
23}
24
25pub trait RefineConnectivity<Connectivity> {
27 type Intermediate;
33 type OutputConnectivity;
35 type VertexLabel: VertexRepresentation;
37
38 fn populate_refined_connectivity(&self, connectivity: &Connectivity, intermediates: &mut Vec<Self::Intermediate>);
41
42 fn populate_vertex_labels(&self, intermediate: &Self::Intermediate, labels: &mut Vec<Self::VertexLabel>);
44
45 fn construct_output_connectivity(
53 &self,
54 intermediate: &Self::Intermediate,
55 vertex_indices: &[usize],
56 ) -> Result<Self::OutputConnectivity, InvalidVertexCount>;
57}
58
59pub struct UniformRefinement;
60
61pub fn refine_mesh<T, D, C, Refinement>(
63 mesh: &Mesh<T, D, C>,
64 refinement_scheme: Refinement,
65) -> Mesh<T, D, Refinement::OutputConnectivity>
66where
67 T: RealField,
68 D: DimName,
69 Refinement: RefineConnectivity<C>,
70 Refinement::VertexLabel: Eq + Hash,
71 DefaultAllocator: DimAllocator<T, D>,
72{
73 let mut label_to_idx_map = HashMap::new();
74 let mut next_vertex_idx = 0;
75
76 let mut new_connectivity = Vec::new();
77
78 let mut intermediates = Vec::new();
80 let mut vertex_labels = Vec::new();
81 let mut new_vertex_indices = Vec::new();
82 for connectivity in mesh.connectivity() {
83 new_vertex_indices.clear();
84 intermediates.clear();
85 refinement_scheme.populate_refined_connectivity(&connectivity, &mut intermediates);
86 for intermediate in &intermediates {
87 vertex_labels.clear();
88 new_vertex_indices.clear();
89 refinement_scheme.populate_vertex_labels(&intermediate, &mut vertex_labels);
90 for label in &vertex_labels {
91 let idx = label_to_idx_map.entry(label.clone()).or_insert_with(|| {
92 let idx = next_vertex_idx;
93 next_vertex_idx += 1;
94 idx
95 });
96 new_vertex_indices.push(*idx);
97 }
98 let new_cell_connectivity = refinement_scheme
99 .construct_output_connectivity(&intermediate, &new_vertex_indices)
100 .expect("Must succeed since vertex label count is consistent with vertex index count");
101 new_connectivity.push(new_cell_connectivity);
102 }
103 }
104
105 let mut new_vertices = vec![Default::default(); next_vertex_idx];
106 for (label, index) in label_to_idx_map {
107 let vertex = label.construct_vertex(mesh.vertices());
108 new_vertices[index] = vertex;
109 }
110 Mesh::from_vertices_and_connectivity(new_vertices, new_connectivity)
111}
112
113pub fn refine_uniformly<T, D, C>(mesh: &Mesh<T, D, C>) -> Mesh<T, D, C>
117where
118 T: RealField,
119 D: DimName,
120 UniformRefinement: RefineConnectivity<C, OutputConnectivity = C>,
121 <UniformRefinement as RefineConnectivity<C>>::VertexLabel: Eq + Hash,
122 DefaultAllocator: DimAllocator<T, D>,
123{
124 refine_mesh(mesh, UniformRefinement)
125}
126
127pub fn refine_uniformly_repeat<T, D, C>(mesh: &Mesh<T, D, C>, repeat_times: usize) -> Mesh<T, D, C>
129where
130 T: RealField,
131 D: DimName,
132 C: Connectivity,
133 UniformRefinement: RefineConnectivity<C, OutputConnectivity = C>,
134 <UniformRefinement as RefineConnectivity<C>>::VertexLabel: Eq + Hash,
135 DefaultAllocator: DimAllocator<T, D>,
136{
137 let mut mesh: Mesh<_, _, _> = mesh.clone();
138 for _ in 0..repeat_times {
139 mesh = refine_uniformly(&mesh);
140 }
141 mesh
142}