extern crate alloc;
use alloc::boxed::Box;
use super::stencil::{cross_stencil_beta, cross_stencil_scalar};
use crate::{float::SemiflowFloat, grid2d::Grid2D, grid_fn2d::GridFn2D};
pub(crate) trait MixedDerivOp<F: SemiflowFloat>: Send + Sync {
fn norm_bound(&self) -> f64;
fn is_zero(&self) -> bool;
fn apply_mixed_into(&self, src: &GridFn2D<F>, dst: &mut GridFn2D<F>, grid: &Grid2D<F>);
fn clone_box(&self) -> Box<dyn MixedDerivOp<F>>;
fn debug_label(&self) -> &'static str;
}
pub(crate) struct ScalarCoupling<F: SemiflowFloat> {
pub(crate) c: fn(F, F) -> F,
pub(crate) c_norm_bound: f64,
pub(crate) is_zero: bool,
}
impl<F: SemiflowFloat> MixedDerivOp<F> for ScalarCoupling<F> {
fn norm_bound(&self) -> f64 {
self.c_norm_bound
}
fn is_zero(&self) -> bool {
self.is_zero
}
fn apply_mixed_into(&self, src: &GridFn2D<F>, dst: &mut GridFn2D<F>, grid: &Grid2D<F>) {
cross_stencil_scalar(src, dst, grid, self.c);
}
fn clone_box(&self) -> Box<dyn MixedDerivOp<F>> {
Box::new(ScalarCoupling {
c: self.c,
c_norm_bound: self.c_norm_bound,
is_zero: self.is_zero,
})
}
fn debug_label(&self) -> &'static str {
"ScalarCoupling"
}
}
pub(crate) struct BetaCoupling<F: SemiflowFloat> {
pub(crate) beta: fn(F, F) -> F,
pub(crate) beta_norm_bound: f64,
pub(crate) is_zero: bool,
}
impl<F: SemiflowFloat> MixedDerivOp<F> for BetaCoupling<F> {
fn norm_bound(&self) -> f64 {
self.beta_norm_bound
}
fn is_zero(&self) -> bool {
self.is_zero
}
fn apply_mixed_into(&self, src: &GridFn2D<F>, dst: &mut GridFn2D<F>, grid: &Grid2D<F>) {
cross_stencil_beta(src, dst, grid, self.beta);
}
fn clone_box(&self) -> Box<dyn MixedDerivOp<F>> {
Box::new(BetaCoupling {
beta: self.beta,
beta_norm_bound: self.beta_norm_bound,
is_zero: self.is_zero,
})
}
fn debug_label(&self) -> &'static str {
"BetaCoupling"
}
}