Skip to main content

conspire/geometry/mesh/partition/part/
mod.rs

1use super::Partition;
2use crate::{
3    geometry::{
4        Coordinates,
5        mesh::{Connectivities, Mesh, NodeSets, SideSets, retain::subset},
6    },
7    math::{Set, TensorVec},
8};
9
10impl Partition {
11    pub fn part<const D: usize>(&self, mesh: &Mesh<D>, part: usize) -> (Mesh<D>, Vec<usize>) {
12        let old_nodes = self.parts_nodes[part].clone();
13        let mut nodes = vec![usize::MAX; mesh.number_of_nodes()];
14        old_nodes
15            .iter()
16            .enumerate()
17            .for_each(|(new, &old)| nodes[old] = new);
18        let mut elements = vec![usize::MAX; mesh.number_of_elements()];
19        self.parts_elements[part]
20            .iter()
21            .enumerate()
22            .for_each(|(new, &old)| elements[old] = new);
23        let mut index = 0;
24        let mut blocks = Vec::new();
25        let mut block_numbers = Vec::new();
26        for (block, connectivity) in mesh.iter().enumerate() {
27            let mut kept = Vec::new();
28            let mut element_numbers = Vec::new();
29            for (local, element) in connectivity.iter().enumerate() {
30                let global = index + local;
31                if elements[global] != usize::MAX {
32                    kept.push(element);
33                    element_numbers.push(match connectivity.element_numbers() {
34                        Some(numbers) => numbers[local],
35                        None => global + 1,
36                    })
37                }
38            }
39            index += connectivity.number_of_elements();
40            if !kept.is_empty() {
41                let mut new_block = subset(connectivity, &kept, &mut |node| nodes[node]);
42                new_block.number_elements(element_numbers);
43                blocks.push(new_block);
44                block_numbers.push(mesh.blocks().map_or(block + 1, |numbers| numbers[block]))
45            }
46        }
47        let mut coordinates = Coordinates::new();
48        old_nodes
49            .iter()
50            .for_each(|&node| coordinates.push(mesh.coordinates()[node].clone()));
51        let node_numbers = old_nodes
52            .iter()
53            .map(|&node| {
54                mesh.coordinates
55                    .numbers()
56                    .map_or(node + 1, |numbers| numbers[node])
57            })
58            .collect::<Vec<_>>();
59        let mut submesh: Mesh<D> = (
60            Connectivities::from((blocks, block_numbers)),
61            Set::from((coordinates, node_numbers)),
62        )
63            .into();
64        let (mut node_sets, mut node_set_numbers) = (Vec::new(), Vec::new());
65        mesh.node_sets()
66            .iter()
67            .enumerate()
68            .for_each(|(set, members)| {
69                let kept: Vec<usize> = members
70                    .iter()
71                    .filter(|&&node| nodes[node] != usize::MAX)
72                    .map(|&node| nodes[node])
73                    .collect();
74                if !kept.is_empty() {
75                    node_sets.push(kept);
76                    node_set_numbers.push(
77                        mesh.node_set_numbers()
78                            .map_or(set + 1, |numbers| numbers[set]),
79                    )
80                }
81            });
82        let (mut side_sets, mut side_set_numbers) = (Vec::new(), Vec::new());
83        mesh.side_sets()
84            .iter()
85            .enumerate()
86            .for_each(|(set, members)| {
87                let kept: Vec<(usize, usize)> = members
88                    .iter()
89                    .filter(|&&(element, _)| elements[element] != usize::MAX)
90                    .map(|&(element, side)| (elements[element], side))
91                    .collect();
92                if !kept.is_empty() {
93                    side_sets.push(kept);
94                    side_set_numbers.push(
95                        mesh.side_set_numbers()
96                            .map_or(set + 1, |numbers| numbers[set]),
97                    )
98                }
99            });
100        submesh.set_node_sets(NodeSets::from((node_sets, node_set_numbers)));
101        submesh.set_side_sets(SideSets::from((side_sets, side_set_numbers)));
102        (submesh, old_nodes)
103    }
104}