use crate::mesh::elements::quad2d::{quad4, quad9};
use crate::mesh::quad2d::{Quad4ReferenceElement, Quad9ReferenceElement, QuadReferenceElement};
use crate::mesh::{QuadratureRule, sampling};
use crate::physics::solenoid_stress::geometry::{FaceSample, VolumeSample};
use crate::physics::solenoid_stress::model::Structural2dElementType;
use crate::physics::solenoid_stress::types::Real;
pub(crate) trait QuadElementFamily<const NODES_PER_ELEMENT: usize> {
type ReferenceElement: QuadReferenceElement<NODES_PER_ELEMENT>;
fn element_type() -> Structural2dElementType;
fn flatten_elements(elements: &[[usize; NODES_PER_ELEMENT]]) -> Vec<usize> {
let mut flat = Vec::with_capacity(elements.len() * NODES_PER_ELEMENT);
for conn in elements {
flat.extend_from_slice(conn);
}
flat
}
fn volume_samples<F: Real>(
coords: &[[F; 2]; NODES_PER_ELEMENT],
quadrature: QuadratureRule,
) -> Result<Vec<VolumeSample<F, NODES_PER_ELEMENT>>, String>;
fn face_samples<F: Real>(
coords: &[[F; 2]; NODES_PER_ELEMENT],
local_face: u8,
quadrature: QuadratureRule,
) -> Result<Vec<FaceSample<F, NODES_PER_ELEMENT>>, String>;
}
pub(crate) struct Quad4Family;
impl QuadElementFamily<{ quad4::NODES_PER_ELEMENT }> for Quad4Family {
type ReferenceElement = Quad4ReferenceElement;
fn element_type() -> Structural2dElementType {
Structural2dElementType::Quad4
}
fn volume_samples<F: Real>(
coords: &[[F; 2]; quad4::NODES_PER_ELEMENT],
quadrature: QuadratureRule,
) -> Result<Vec<VolumeSample<F, { quad4::NODES_PER_ELEMENT }>>, String> {
sampling::volume_samples_quad4(coords, quadrature)
}
fn face_samples<F: Real>(
coords: &[[F; 2]; quad4::NODES_PER_ELEMENT],
local_face: u8,
quadrature: QuadratureRule,
) -> Result<Vec<FaceSample<F, { quad4::NODES_PER_ELEMENT }>>, String> {
sampling::face_samples_quad4(coords, local_face, quadrature)
}
}
pub(crate) struct Quad9Family;
impl QuadElementFamily<{ quad9::NODES_PER_ELEMENT }> for Quad9Family {
type ReferenceElement = Quad9ReferenceElement;
fn element_type() -> Structural2dElementType {
Structural2dElementType::Quad9
}
fn volume_samples<F: Real>(
coords: &[[F; 2]; quad9::NODES_PER_ELEMENT],
quadrature: QuadratureRule,
) -> Result<Vec<VolumeSample<F, { quad9::NODES_PER_ELEMENT }>>, String> {
sampling::volume_samples_quad9(coords, quadrature)
}
fn face_samples<F: Real>(
coords: &[[F; 2]; quad9::NODES_PER_ELEMENT],
local_face: u8,
quadrature: QuadratureRule,
) -> Result<Vec<FaceSample<F, { quad9::NODES_PER_ELEMENT }>>, String> {
sampling::face_samples_quad9(coords, local_face, quadrature)
}
}