use super::{
super::py::{IntoFoo, PyCoordinates, PyIntermediateError},
Blocks, Connectivity, FiniteElementMethods, FiniteElementSpecifics, HEX, Smoothing, TRI,
finite_element_data_from_exo, finite_element_data_from_inp, write_finite_elements_to_abaqus,
write_finite_elements_to_exodus, write_finite_elements_to_mesh, write_finite_elements_to_vtk,
};
use pyo3::prelude::*;
pub fn register_module(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
parent_module.add_class::<HexahedralFiniteElements>()?;
parent_module.add_class::<TriangularFiniteElements>()?;
Ok(())
}
#[pyclass]
pub struct HexahedralFiniteElements {
element_blocks: Blocks,
element_node_connectivity: Connectivity<HEX>,
nodal_coordinates: PyCoordinates,
}
#[pyclass]
pub struct TetrahedralFiniteElements {
element_blocks: Blocks,
element_node_connectivity: Connectivity<HEX>,
nodal_coordinates: PyCoordinates,
}
#[pyclass]
pub struct TriangularFiniteElements {
element_blocks: Blocks,
element_node_connectivity: Connectivity<TRI>,
nodal_coordinates: PyCoordinates,
}
#[pymethods]
impl HexahedralFiniteElements {
#[new]
pub fn from_data(
element_blocks: Blocks,
element_node_connectivity: Connectivity<HEX>,
nodal_coordinates: PyCoordinates,
) -> Self {
Self {
element_blocks,
element_node_connectivity,
nodal_coordinates,
}
}
#[staticmethod]
pub fn from_exo(file_path: &str) -> Result<Self, PyIntermediateError> {
let (element_blocks, element_node_connectivity, nodal_coordinates) =
finite_element_data_from_exo(file_path)?;
Ok(Self::from_data(
element_blocks,
element_node_connectivity,
nodal_coordinates.as_foo(),
))
}
#[staticmethod]
pub fn from_inp(file_path: &str) -> Result<Self, PyIntermediateError> {
let (element_blocks, element_node_connectivity, nodal_coordinates) =
finite_element_data_from_inp(file_path)?;
Ok(Self::from_data(
element_blocks,
element_node_connectivity,
nodal_coordinates.as_foo(),
))
}
#[pyo3(signature = (method="Taubin", hierarchical=false, iterations=10, pass_band=0.1, scale=0.6307))]
pub fn smooth(
&mut self,
method: &str,
hierarchical: bool,
iterations: usize,
pass_band: f64,
scale: f64,
) -> Result<(), PyIntermediateError> {
let mut finite_elements = super::HexahedralFiniteElements::from((
self.element_blocks.clone(),
self.element_node_connectivity.clone(),
self.nodal_coordinates.as_foo(),
));
finite_elements.node_element_connectivity()?;
finite_elements.node_node_connectivity()?;
if hierarchical {
finite_elements.nodal_hierarchy()?;
}
finite_elements.nodal_influencers();
match method {
"Gauss" | "gauss" | "Gaussian" | "gaussian" | "Laplacian" | "Laplace" | "laplacian"
| "laplace" => {
finite_elements.smooth(&Smoothing::Laplacian(iterations, scale))?;
}
"Taubin" | "taubin" => {
finite_elements.smooth(&Smoothing::Taubin(iterations, pass_band, scale))?;
}
_ => return Err(format!("Invalid smoothing method {method} specified."))?,
}
self.element_blocks = finite_elements.element_blocks;
self.element_node_connectivity = finite_elements.element_node_connectivity;
self.nodal_coordinates = finite_elements.nodal_coordinates.as_foo();
Ok(())
}
pub fn write_exo(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_exodus(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
pub fn write_inp(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_abaqus(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
pub fn write_mesh(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_mesh(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
pub fn write_metrics(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(super::HexahedralFiniteElements::from((
self.element_blocks.clone(),
self.element_node_connectivity.clone(),
self.nodal_coordinates.as_foo(),
))
.write_metrics(file_path)?)
}
pub fn write_vtk(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_vtk(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
}
#[pymethods]
impl TetrahedralFiniteElements {
#[new]
pub fn from_data(
element_blocks: Blocks,
element_node_connectivity: Connectivity<HEX>,
nodal_coordinates: PyCoordinates,
) -> Self {
Self {
element_blocks,
element_node_connectivity,
nodal_coordinates,
}
}
#[staticmethod]
pub fn from_exo(file_path: &str) -> Result<Self, PyIntermediateError> {
let (element_blocks, element_node_connectivity, nodal_coordinates) =
finite_element_data_from_exo(file_path)?;
Ok(Self::from_data(
element_blocks,
element_node_connectivity,
nodal_coordinates.as_foo(),
))
}
#[staticmethod]
pub fn from_inp(file_path: &str) -> Result<Self, PyIntermediateError> {
let (element_blocks, element_node_connectivity, nodal_coordinates) =
finite_element_data_from_inp(file_path)?;
Ok(Self::from_data(
element_blocks,
element_node_connectivity,
nodal_coordinates.as_foo(),
))
}
#[pyo3(signature = (method="Taubin", hierarchical=false, iterations=10, pass_band=0.1, scale=0.6307))]
pub fn smooth(
&mut self,
method: &str,
hierarchical: bool,
iterations: usize,
pass_band: f64,
scale: f64,
) -> Result<(), PyIntermediateError> {
let mut finite_elements = super::HexahedralFiniteElements::from((
self.element_blocks.clone(),
self.element_node_connectivity.clone(),
self.nodal_coordinates.as_foo(),
));
finite_elements.node_element_connectivity()?;
finite_elements.node_node_connectivity()?;
if hierarchical {
finite_elements.nodal_hierarchy()?;
}
finite_elements.nodal_influencers();
match method {
"Gauss" | "gauss" | "Gaussian" | "gaussian" | "Laplacian" | "Laplace" | "laplacian"
| "laplace" => {
finite_elements.smooth(&Smoothing::Laplacian(iterations, scale))?;
}
"Taubin" | "taubin" => {
finite_elements.smooth(&Smoothing::Taubin(iterations, pass_band, scale))?;
}
_ => return Err(format!("Invalid smoothing method {method} specified."))?,
}
self.element_blocks = finite_elements.element_blocks;
self.element_node_connectivity = finite_elements.element_node_connectivity;
self.nodal_coordinates = finite_elements.nodal_coordinates.as_foo();
Ok(())
}
pub fn write_exo(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_exodus(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
pub fn write_inp(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_abaqus(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
pub fn write_mesh(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_mesh(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
pub fn write_metrics(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(super::HexahedralFiniteElements::from((
self.element_blocks.clone(),
self.element_node_connectivity.clone(),
self.nodal_coordinates.as_foo(),
))
.write_metrics(file_path)?)
}
pub fn write_vtk(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_vtk(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
}
#[pymethods]
impl TriangularFiniteElements {
#[new]
pub fn from_data(
element_blocks: Blocks,
element_node_connectivity: Connectivity<TRI>,
nodal_coordinates: PyCoordinates,
) -> Self {
Self {
element_blocks,
element_node_connectivity,
nodal_coordinates,
}
}
#[staticmethod]
pub fn from_exo(file_path: &str) -> Result<Self, PyIntermediateError> {
let (element_blocks, element_node_connectivity, nodal_coordinates) =
finite_element_data_from_exo(file_path)?;
Ok(Self::from_data(
element_blocks,
element_node_connectivity,
nodal_coordinates.as_foo(),
))
}
#[staticmethod]
pub fn from_inp(file_path: &str) -> Result<Self, PyIntermediateError> {
let (element_blocks, element_node_connectivity, nodal_coordinates) =
finite_element_data_from_inp(file_path)?;
Ok(Self::from_data(
element_blocks,
element_node_connectivity,
nodal_coordinates.as_foo(),
))
}
#[pyo3(signature = (method="Taubin", hierarchical=false, iterations=10, pass_band=0.1, scale=0.6307))]
pub fn smooth(
&mut self,
method: &str,
hierarchical: bool,
iterations: usize,
pass_band: f64,
scale: f64,
) -> Result<(), PyIntermediateError> {
let mut finite_elements = super::TriangularFiniteElements::from((
self.element_blocks.clone(),
self.element_node_connectivity.clone(),
self.nodal_coordinates.as_foo(),
));
finite_elements.node_element_connectivity()?;
finite_elements.node_node_connectivity()?;
if hierarchical {
finite_elements.nodal_hierarchy()?;
}
finite_elements.nodal_influencers();
match method {
"Gauss" | "gauss" | "Gaussian" | "gaussian" | "Laplacian" | "Laplace" | "laplacian"
| "laplace" => {
finite_elements.smooth(&Smoothing::Laplacian(iterations, scale))?;
}
"Taubin" | "taubin" => {
finite_elements.smooth(&Smoothing::Taubin(iterations, pass_band, scale))?;
}
_ => return Err(format!("Invalid smoothing method {method} specified."))?,
}
self.element_blocks = finite_elements.element_blocks;
self.element_node_connectivity = finite_elements.element_node_connectivity;
self.nodal_coordinates = finite_elements.nodal_coordinates.as_foo();
Ok(())
}
pub fn write_exo(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_exodus(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
pub fn write_inp(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_abaqus(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
pub fn write_mesh(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_mesh(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
pub fn write_metrics(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(super::TriangularFiniteElements::from((
self.element_blocks.clone(),
self.element_node_connectivity.clone(),
self.nodal_coordinates.as_foo(),
))
.write_metrics(file_path)?)
}
pub fn write_vtk(&self, file_path: &str) -> Result<(), PyIntermediateError> {
Ok(write_finite_elements_to_vtk(
file_path,
&self.element_blocks,
&self.element_node_connectivity,
&self.nodal_coordinates.as_foo(),
)?)
}
}