Skip to content
This repository has been archived by the owner on Mar 12, 2024. It is now read-only.

Commit

Permalink
Add builder for mixed grid
Browse files Browse the repository at this point in the history
  • Loading branch information
mscroggs committed Mar 7, 2024
1 parent ba5bde1 commit 07b4f21
Showing 1 changed file with 105 additions and 0 deletions.
105 changes: 105 additions & 0 deletions src/grid/mixed_grid/builder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//! Grid builder
use crate::grid::mixed_grid::grid::SerialMixedGrid;
use crate::traits::builder::Builder;
use crate::types::ReferenceCellType;
use bempp_element::element::{create_element, ElementFamily, Inverse};
use bempp_traits::element::{Continuity, FiniteElement};
use num::Float;
use rlst_common::types::Scalar;
use rlst_dense::{rlst_array_from_slice2, rlst_dynamic_array2};
use std::collections::HashMap;

pub struct SerialMixedGridBuilder<const GDIM: usize, T: Float + Scalar<Real = T> + Inverse> {
elements_to_npoints: HashMap<(ReferenceCellType, usize), usize>,
points: Vec<T>,
cells: Vec<usize>,
cell_types: Vec<ReferenceCellType>,
cell_degrees: Vec<usize>,
point_indices_to_ids: Vec<usize>,
cell_indices_to_ids: Vec<usize>,
point_ids_to_indices: HashMap<usize, usize>,
cell_ids_to_indices: HashMap<usize, usize>,
}

impl<const GDIM: usize, T: Float + Scalar<Real = T> + Inverse> Builder<GDIM>
for SerialMixedGridBuilder<GDIM, T>
{
type GridType = SerialMixedGrid<T>;
type T = T;
type CellData = (Vec<usize>, ReferenceCellType, usize);
type GridMetadata = ();

fn new(_data: ()) -> Self {
Self {
elements_to_npoints: HashMap::new(),
points: vec![],
cells: vec![],
cell_types: vec![],
cell_degrees: vec![],
point_indices_to_ids: vec![],
cell_indices_to_ids: vec![],
point_ids_to_indices: HashMap::new(),
cell_ids_to_indices: HashMap::new(),
}
}

fn new_with_capacity(npoints: usize, ncells: usize, _data: ()) -> Self {
Self {
elements_to_npoints: HashMap::new(),
points: Vec::with_capacity(npoints * Self::GDIM),
cells: vec![],
cell_types: vec![],
cell_degrees: vec![],
point_indices_to_ids: Vec::with_capacity(npoints),
cell_indices_to_ids: Vec::with_capacity(ncells),
point_ids_to_indices: HashMap::new(),
cell_ids_to_indices: HashMap::new(),
}
}

fn add_point(&mut self, id: usize, data: [T; GDIM]) {
self.point_ids_to_indices
.insert(id, self.point_indices_to_ids.len());
self.point_indices_to_ids.push(id);
self.points.extend_from_slice(&data);
}

fn add_cell(&mut self, id: usize, cell_data: (Vec<usize>, ReferenceCellType, usize)) {
let points_per_cell =
if let Some(npts) = self.elements_to_npoints.get(&(cell_data.1, cell_data.2)) {
*npts
} else {
let npts = create_element::<T>(
ElementFamily::Lagrange,
cell_data.1,
cell_data.2,
Continuity::Continuous,
)
.dim();
self.elements_to_npoints
.insert((cell_data.1, cell_data.2), npts);
npts
};
assert_eq!(cell_data.0.len(), points_per_cell);
self.cell_ids_to_indices
.insert(id, self.cell_indices_to_ids.len());
self.cell_indices_to_ids.push(id);
self.cells.extend_from_slice(&cell_data.0);
self.cell_types.push(cell_data.1);
self.cell_degrees.push(cell_data.2);
}

fn create_grid(&self) -> Self::GridType {
// TODO: remove this transposing
let npts = self.point_indices_to_ids.len();
let mut points = rlst_dynamic_array2!(T, [npts, 3]);
points.fill_from(rlst_array_from_slice2!(
T,
&self.points,
[npts, 3],
[1, npts]
));
SerialMixedGrid::new(points, &self.cells, &self.cell_types, &self.cell_degrees)
}
}

0 comments on commit 07b4f21

Please sign in to comment.