use rayon::prelude::*;
use crate::{chunksize, ranges_for_len};
mod body_force;
mod pressure;
mod thermal;
mod traction;
#[derive(Debug, Clone)]
pub struct SparseOperator {
pub rows: Vec<usize>,
pub cols: Vec<usize>,
pub vals: Vec<f64>,
pub nrow: usize,
pub ncol: usize,
}
#[derive(Debug, Clone)]
pub struct ThermalLoadOperator {
pub temperature_to_rhs: SparseOperator,
pub reference_rhs: Vec<f64>,
}
fn concat_sparse_operators(
chunks: Vec<SparseOperator>,
nrow: usize,
ncol: usize,
capacity: usize,
) -> SparseOperator {
let mut rows = Vec::with_capacity(capacity);
let mut cols = Vec::with_capacity(capacity);
let mut vals = Vec::with_capacity(capacity);
for chunk in chunks {
debug_assert_eq!(chunk.nrow, nrow);
debug_assert_eq!(chunk.ncol, ncol);
rows.extend(chunk.rows);
cols.extend(chunk.cols);
vals.extend(chunk.vals);
}
SparseOperator {
rows,
cols,
vals,
nrow,
ncol,
}
}
fn concat_thermal_load_operators(
chunks: Vec<ThermalLoadOperator>,
ndof: usize,
ncol: usize,
capacity: usize,
) -> ThermalLoadOperator {
let mut reference_rhs = vec![0.0; ndof];
let sparse_chunks = chunks
.into_iter()
.map(|chunk| {
for (dst, src) in reference_rhs.iter_mut().zip(chunk.reference_rhs) {
*dst += src;
}
chunk.temperature_to_rhs
})
.collect::<Vec<_>>();
ThermalLoadOperator {
temperature_to_rhs: concat_sparse_operators(sparse_chunks, ndof, ncol, capacity),
reference_rhs,
}
}
fn collect_sparse_operator_chunks(
len: usize,
build: impl Fn(usize, usize) -> Result<SparseOperator, String> + Sync,
) -> Result<Vec<SparseOperator>, String> {
ranges_for_len(len, chunksize(len))
.into_par_iter()
.map(|(start, end)| build(start, end))
.collect()
}
fn collect_thermal_load_operator_chunks(
len: usize,
build: impl Fn(usize, usize) -> Result<ThermalLoadOperator, String> + Sync,
) -> Result<Vec<ThermalLoadOperator>, String> {
ranges_for_len(len, chunksize(len))
.into_par_iter()
.map(|(start, end)| build(start, end))
.collect()
}
pub(crate) use body_force::{
apply_body_force_rhs_for_family, body_force_operator_for_family,
body_force_operator_for_family_par,
};
pub(crate) use pressure::{
apply_pressure_rhs_for_family, pressure_operator_for_family, pressure_operator_for_family_par,
};
pub(crate) use thermal::{
apply_temperature_rhs_for_family, temperature_operator_for_family,
temperature_operator_for_family_par, thermal_reference_rhs_for_family,
};
pub(crate) use traction::{
apply_traction_rhs_for_family, traction_operator_for_family, traction_operator_for_family_par,
};