use crate::topology::cell_type::CellType;
use std::collections::{BTreeMap, HashMap};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum RegionKey {
Label { name: String, value: i32 },
CellType(CellType),
}
impl RegionKey {
pub fn label(name: impl Into<String>, value: i32) -> Self {
Self::Label {
name: name.into(),
value,
}
}
pub fn cell_type(cell_type: CellType) -> Self {
Self::CellType(cell_type)
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct DiscretizationMetadata {
pub basis: String,
pub basis_order: Option<usize>,
pub shape_functions: Vec<String>,
pub quadrature: String,
pub quadrature_order: Option<usize>,
pub quadrature_points: Vec<Vec<f64>>,
pub quadrature_weights: Vec<f64>,
}
impl DiscretizationMetadata {
pub fn new(basis: impl Into<String>, quadrature: impl Into<String>) -> Self {
Self {
basis: basis.into(),
basis_order: None,
shape_functions: Vec::new(),
quadrature: quadrature.into(),
quadrature_order: None,
quadrature_points: Vec::new(),
quadrature_weights: Vec::new(),
}
}
pub fn with_basis_metadata(
mut self,
order: usize,
shape_functions: impl IntoIterator<Item = impl Into<String>>,
) -> Self {
self.basis_order = Some(order);
self.shape_functions = shape_functions.into_iter().map(Into::into).collect();
self
}
pub fn with_quadrature_metadata(
mut self,
order: usize,
points: Vec<Vec<f64>>,
weights: Vec<f64>,
) -> Self {
self.quadrature_order = Some(order);
self.quadrature_points = points;
self.quadrature_weights = weights;
self
}
pub fn has_quadrature_data(&self) -> bool {
!self.quadrature_points.is_empty()
&& self.quadrature_points.len() == self.quadrature_weights.len()
}
}
#[derive(Clone, Debug, Default)]
pub struct FieldDiscretization {
metadata: HashMap<RegionKey, DiscretizationMetadata>,
}
impl FieldDiscretization {
pub fn new() -> Self {
Self::default()
}
pub fn set_metadata(
&mut self,
region: RegionKey,
metadata: DiscretizationMetadata,
) -> Option<DiscretizationMetadata> {
self.metadata.insert(region, metadata)
}
pub fn set_label_metadata(
&mut self,
name: impl Into<String>,
value: i32,
metadata: DiscretizationMetadata,
) -> Option<DiscretizationMetadata> {
self.set_metadata(RegionKey::label(name, value), metadata)
}
pub fn set_cell_type_metadata(
&mut self,
cell_type: CellType,
metadata: DiscretizationMetadata,
) -> Option<DiscretizationMetadata> {
self.set_metadata(RegionKey::cell_type(cell_type), metadata)
}
pub fn metadata_for(&self, region: &RegionKey) -> Option<&DiscretizationMetadata> {
self.metadata.get(region)
}
pub fn iter(&self) -> impl Iterator<Item = (&RegionKey, &DiscretizationMetadata)> {
self.metadata.iter()
}
}
#[derive(Clone, Debug, Default)]
pub struct Discretization {
fields: BTreeMap<String, FieldDiscretization>,
}
impl Discretization {
pub fn new() -> Self {
Self::default()
}
pub fn insert_field(
&mut self,
name: impl Into<String>,
field: FieldDiscretization,
) -> Option<FieldDiscretization> {
self.fields.insert(name.into(), field)
}
pub fn field(&self, name: &str) -> Option<&FieldDiscretization> {
self.fields.get(name)
}
pub fn field_mut(&mut self, name: &str) -> &mut FieldDiscretization {
self.fields.entry(name.to_string()).or_default()
}
pub fn iter(&self) -> impl Iterator<Item = (&str, &FieldDiscretization)> {
self.fields
.iter()
.map(|(name, field)| (name.as_str(), field))
}
}