use core::any::Any;
use core::marker::PhantomData;
use std::sync::Arc;
use super::coeffs::Coefficients;
use super::fields::Fields;
use super::grid::Grid;
use super::slab::{SlabHooks, SlabPartition};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Hooks(u8);
impl Hooks {
pub const NONE: Self = Self(0);
pub const PRE_H: Self = Self(1);
pub const POST_H: Self = Self(2);
pub const PRE_E: Self = Self(4);
pub const POST_E: Self = Self(8);
pub const ALL: Self = Self(15);
pub const fn contains(self, other: Self) -> bool {
self.0 & other.0 == other.0
}
pub const fn intersects(self, other: Self) -> bool {
self.0 & other.0 != 0
}
pub const fn is_empty(self) -> bool {
self.0 == 0
}
}
impl core::ops::BitOr for Hooks {
type Output = Self;
fn bitor(self, o: Self) -> Self {
Self(self.0 | o.0)
}
}
impl core::ops::BitOrAssign for Hooks {
fn bitor_assign(&mut self, o: Self) {
self.0 |= o.0;
}
}
#[derive(Debug, Clone, Copy)]
pub struct StepContext<'a> {
pub step: u64,
pub dt: f64,
pub grid: &'a Grid,
pub coefficients: &'a Coefficients,
}
impl StepContext<'_> {
pub fn time(&self) -> f64 {
self.step as f64 * self.dt
}
pub fn h_time(&self) -> f64 {
(self.step as f64 + 0.5) * self.dt
}
pub fn e_time(&self) -> f64 {
(self.step as f64 + 1.0) * self.dt
}
}
pub trait Operator: Any + Send {
fn pre_h(&mut self, _fields: &mut Fields<'_>, _ctx: &StepContext<'_>) {}
fn post_h(&mut self, _fields: &mut Fields<'_>, _ctx: &StepContext<'_>) {}
fn pre_e(&mut self, _fields: &mut Fields<'_>, _ctx: &StepContext<'_>) {}
fn post_e(&mut self, _fields: &mut Fields<'_>, _ctx: &StepContext<'_>) {}
fn hooks(&self) -> Hooks {
Hooks::ALL
}
fn slab_hooks(&mut self, _partition: &SlabPartition<'_>) -> Option<Arc<dyn SlabHooks>> {
None
}
fn energy(&self) -> f64 {
0.0
}
}
#[derive(Debug)]
pub struct OperatorHandle<T> {
pub(crate) engine: u64,
pub(crate) index: usize,
pub(crate) _t: PhantomData<fn() -> T>,
}
impl<T> Clone for OperatorHandle<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for OperatorHandle<T> {}