Add Evaluator for defining IC/BC in json config
This commit is contained in:
		
							
								
								
									
										97
									
								
								euler/src/eval.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								euler/src/eval.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
//! Traits for evaluating initial conditions, exact solutions, or boundary conditions
 | 
			
		||||
 | 
			
		||||
use super::Float;
 | 
			
		||||
use super::GAMMA;
 | 
			
		||||
use ndarray::{azip, ArrayView, ArrayViewMut, Dimension};
 | 
			
		||||
 | 
			
		||||
pub trait Evaluator<D: Dimension>: Send + Sync {
 | 
			
		||||
    fn evaluate(
 | 
			
		||||
        &self,
 | 
			
		||||
        t: Float,
 | 
			
		||||
        x: ArrayView<Float, D>,
 | 
			
		||||
        y: ArrayView<Float, D>,
 | 
			
		||||
        rho: ArrayViewMut<Float, D>,
 | 
			
		||||
        rhou: ArrayViewMut<Float, D>,
 | 
			
		||||
        rhov: ArrayViewMut<Float, D>,
 | 
			
		||||
        e: ArrayViewMut<Float, D>,
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Necessary to avoid specialisation of `Evaluator` trait for items
 | 
			
		||||
/// that could implement both this and `Evaluator`
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct EvaluatorPressureWrapper<'a, D: Dimension, E: EvaluatorPressure<D>>(
 | 
			
		||||
    &'a E,
 | 
			
		||||
    std::marker::PhantomData<D>,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
impl<'a, D: Dimension, E: EvaluatorPressure<D>> EvaluatorPressureWrapper<'a, D, E> {
 | 
			
		||||
    pub fn new(e: &'a E) -> Self {
 | 
			
		||||
        Self(e, std::marker::PhantomData)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait EvaluatorPressure<D: Dimension>: Send + Sync {
 | 
			
		||||
    fn rho(
 | 
			
		||||
        &self,
 | 
			
		||||
        t: Float,
 | 
			
		||||
        x: ArrayView<Float, D>,
 | 
			
		||||
        y: ArrayView<Float, D>,
 | 
			
		||||
        out: ArrayViewMut<Float, D>,
 | 
			
		||||
    );
 | 
			
		||||
    fn u(
 | 
			
		||||
        &self,
 | 
			
		||||
        t: Float,
 | 
			
		||||
        x: ArrayView<Float, D>,
 | 
			
		||||
        y: ArrayView<Float, D>,
 | 
			
		||||
        rho: ArrayView<Float, D>,
 | 
			
		||||
        out: ArrayViewMut<Float, D>,
 | 
			
		||||
    );
 | 
			
		||||
    fn v(
 | 
			
		||||
        &self,
 | 
			
		||||
        t: Float,
 | 
			
		||||
        x: ArrayView<Float, D>,
 | 
			
		||||
        y: ArrayView<Float, D>,
 | 
			
		||||
        rho: ArrayView<Float, D>,
 | 
			
		||||
        out: ArrayViewMut<Float, D>,
 | 
			
		||||
    );
 | 
			
		||||
    fn p(
 | 
			
		||||
        &self,
 | 
			
		||||
        t: Float,
 | 
			
		||||
        x: ArrayView<Float, D>,
 | 
			
		||||
        y: ArrayView<Float, D>,
 | 
			
		||||
        rho: ArrayView<Float, D>,
 | 
			
		||||
        u: ArrayView<Float, D>,
 | 
			
		||||
        v: ArrayView<Float, D>,
 | 
			
		||||
        out: ArrayViewMut<Float, D>,
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a, D: Dimension, BP: EvaluatorPressure<D>> Evaluator<D>
 | 
			
		||||
    for EvaluatorPressureWrapper<'a, D, BP>
 | 
			
		||||
{
 | 
			
		||||
    fn evaluate(
 | 
			
		||||
        &self,
 | 
			
		||||
        t: Float,
 | 
			
		||||
        x: ArrayView<Float, D>,
 | 
			
		||||
        y: ArrayView<Float, D>,
 | 
			
		||||
        mut rho: ArrayViewMut<Float, D>,
 | 
			
		||||
        mut rhou: ArrayViewMut<Float, D>,
 | 
			
		||||
        mut rhov: ArrayViewMut<Float, D>,
 | 
			
		||||
        mut e: ArrayViewMut<Float, D>,
 | 
			
		||||
    ) {
 | 
			
		||||
        let eva = &self.0;
 | 
			
		||||
        eva.rho(t, x.view(), y.view(), rho.view_mut());
 | 
			
		||||
        eva.u(t, x.view(), y.view(), rho.view(), rhou.view_mut());
 | 
			
		||||
        eva.v(t, x.view(), y.view(), rho.view(), rhov.view_mut());
 | 
			
		||||
        eva.p(t, x, y, rho.view(), rhou.view(), rhov.view(), e.view_mut());
 | 
			
		||||
 | 
			
		||||
        azip!((rho in &rho, u in &rhou, v in &rhov, e in &mut e) {
 | 
			
		||||
            let p = *e;
 | 
			
		||||
            *e = p / (GAMMA - 1.0) + rho * (u*u + v*v) / 2.0;
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
        azip!((rho in &rho, rhou in &mut rhou) *rhou /= rho);
 | 
			
		||||
        azip!((rho in &rho, rhov in &mut rhov) *rhov /= rho);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -6,6 +6,8 @@ use sbp::operators::{InterpolationOperator, SbpOperator2d, UpwindOperator2d};
 | 
			
		||||
use sbp::utils::Direction;
 | 
			
		||||
use sbp::Float;
 | 
			
		||||
 | 
			
		||||
pub mod eval;
 | 
			
		||||
 | 
			
		||||
mod vortex;
 | 
			
		||||
pub use vortex::{vortex, VortexParameters, Vortice};
 | 
			
		||||
 | 
			
		||||
@@ -691,11 +693,25 @@ pub enum BoundaryCharacteristic {
 | 
			
		||||
    This,
 | 
			
		||||
    Grid(usize),
 | 
			
		||||
    Vortex(VortexParameters),
 | 
			
		||||
    Eval(std::sync::Arc<dyn eval::Evaluator<ndarray::Ix1>>),
 | 
			
		||||
    // Vortices(Vec<VortexParameters>),
 | 
			
		||||
    Interpolate(usize, Box<dyn InterpolationOperator>),
 | 
			
		||||
    MultiGrid(Vec<(usize, usize, usize)>),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl std::fmt::Debug for BoundaryCharacteristic {
 | 
			
		||||
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
			
		||||
        match self {
 | 
			
		||||
            Self::This => write!(f, "This"),
 | 
			
		||||
            Self::Grid(g) => write!(f, "Grid({})", g),
 | 
			
		||||
            Self::Vortex(vp) => write!(f, "{:?}", vp),
 | 
			
		||||
            Self::Eval(_) => write!(f, "Eval"),
 | 
			
		||||
            Self::Interpolate(_, _) => write!(f, "Interpolate"),
 | 
			
		||||
            Self::MultiGrid(m) => write!(f, "Multigrid: {:?}", m),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub type BoundaryTerms<'a> = Direction<ArrayView2<'a, Float>>;
 | 
			
		||||
pub type BoundaryCharacteristics = Direction<BoundaryCharacteristic>;
 | 
			
		||||
 | 
			
		||||
@@ -708,6 +724,7 @@ fn boundary_extractor<'a>(
 | 
			
		||||
        north: match &bc.north {
 | 
			
		||||
            BoundaryCharacteristic::This => field.south(),
 | 
			
		||||
            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
			
		||||
            BoundaryCharacteristic::Eval(_) => todo!(),
 | 
			
		||||
            BoundaryCharacteristic::Grid(_)
 | 
			
		||||
            | BoundaryCharacteristic::Interpolate(_, _)
 | 
			
		||||
            | BoundaryCharacteristic::MultiGrid(_) => panic!("Only working on self grid"),
 | 
			
		||||
@@ -715,6 +732,7 @@ fn boundary_extractor<'a>(
 | 
			
		||||
        south: match &bc.south {
 | 
			
		||||
            BoundaryCharacteristic::This => field.north(),
 | 
			
		||||
            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
			
		||||
            BoundaryCharacteristic::Eval(_) => todo!(),
 | 
			
		||||
            BoundaryCharacteristic::Grid(_)
 | 
			
		||||
            | BoundaryCharacteristic::Interpolate(_, _)
 | 
			
		||||
            | BoundaryCharacteristic::MultiGrid(_) => panic!("Only working on self grid"),
 | 
			
		||||
@@ -722,6 +740,7 @@ fn boundary_extractor<'a>(
 | 
			
		||||
        west: match &bc.west {
 | 
			
		||||
            BoundaryCharacteristic::This => field.east(),
 | 
			
		||||
            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
			
		||||
            BoundaryCharacteristic::Eval(_) => todo!(),
 | 
			
		||||
            BoundaryCharacteristic::Grid(_)
 | 
			
		||||
            | BoundaryCharacteristic::Interpolate(_, _)
 | 
			
		||||
            | BoundaryCharacteristic::MultiGrid(_) => panic!("Only working on self grid"),
 | 
			
		||||
@@ -729,6 +748,7 @@ fn boundary_extractor<'a>(
 | 
			
		||||
        east: match &bc.east {
 | 
			
		||||
            BoundaryCharacteristic::This => field.west(),
 | 
			
		||||
            BoundaryCharacteristic::Vortex(_params) => todo!(),
 | 
			
		||||
            BoundaryCharacteristic::Eval(_) => todo!(),
 | 
			
		||||
            BoundaryCharacteristic::Grid(_)
 | 
			
		||||
            | BoundaryCharacteristic::Interpolate(_, _)
 | 
			
		||||
            | BoundaryCharacteristic::MultiGrid(_) => panic!("Only working on self grid"),
 | 
			
		||||
@@ -748,11 +768,6 @@ fn boundary_extract<'a>(
 | 
			
		||||
    match bc {
 | 
			
		||||
        BoundaryCharacteristic::This => seldir(field),
 | 
			
		||||
        BoundaryCharacteristic::Grid(g) => seldir(&fields[*g]),
 | 
			
		||||
        BoundaryCharacteristic::Vortex(v) => {
 | 
			
		||||
            let field = eb.unwrap();
 | 
			
		||||
            vortexify(field.view_mut(), grid, v, time);
 | 
			
		||||
            field.view()
 | 
			
		||||
        }
 | 
			
		||||
        BoundaryCharacteristic::Interpolate(g, operator) => {
 | 
			
		||||
            let to = eb.unwrap();
 | 
			
		||||
            let fine2coarse = field.nx() < fields[*g].nx();
 | 
			
		||||
@@ -785,6 +800,24 @@ fn boundary_extract<'a>(
 | 
			
		||||
            }
 | 
			
		||||
            to.view()
 | 
			
		||||
        }
 | 
			
		||||
        BoundaryCharacteristic::Vortex(v) => {
 | 
			
		||||
            let field = eb.unwrap();
 | 
			
		||||
            vortexify(field.view_mut(), grid, v, time);
 | 
			
		||||
            field.view()
 | 
			
		||||
        }
 | 
			
		||||
        BoundaryCharacteristic::Eval(expr) => {
 | 
			
		||||
            let field = eb.unwrap();
 | 
			
		||||
            let (x, y) = grid;
 | 
			
		||||
            let mut fiter = field.outer_iter_mut();
 | 
			
		||||
            let (rho, rhou, rhov, e) = (
 | 
			
		||||
                fiter.next().unwrap(),
 | 
			
		||||
                fiter.next().unwrap(),
 | 
			
		||||
                fiter.next().unwrap(),
 | 
			
		||||
                fiter.next().unwrap(),
 | 
			
		||||
            );
 | 
			
		||||
            expr.evaluate(time, x, y, rho, rhou, rhov, e);
 | 
			
		||||
            field.view()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -864,6 +897,7 @@ impl BoundaryStorage {
 | 
			
		||||
        Self {
 | 
			
		||||
            north: match bt.north() {
 | 
			
		||||
                BoundaryCharacteristic::Vortex(_)
 | 
			
		||||
                | BoundaryCharacteristic::Eval(_)
 | 
			
		||||
                | BoundaryCharacteristic::Interpolate(_, _)
 | 
			
		||||
                | BoundaryCharacteristic::MultiGrid(_) => {
 | 
			
		||||
                    Some(ndarray::Array2::zeros((4, grid.nx())))
 | 
			
		||||
@@ -872,6 +906,7 @@ impl BoundaryStorage {
 | 
			
		||||
            },
 | 
			
		||||
            south: match bt.south() {
 | 
			
		||||
                BoundaryCharacteristic::Vortex(_)
 | 
			
		||||
                | BoundaryCharacteristic::Eval(_)
 | 
			
		||||
                | BoundaryCharacteristic::Interpolate(_, _)
 | 
			
		||||
                | BoundaryCharacteristic::MultiGrid(_) => {
 | 
			
		||||
                    Some(ndarray::Array2::zeros((4, grid.nx())))
 | 
			
		||||
@@ -880,6 +915,7 @@ impl BoundaryStorage {
 | 
			
		||||
            },
 | 
			
		||||
            east: match bt.east() {
 | 
			
		||||
                BoundaryCharacteristic::Vortex(_)
 | 
			
		||||
                | BoundaryCharacteristic::Eval(_)
 | 
			
		||||
                | BoundaryCharacteristic::Interpolate(_, _)
 | 
			
		||||
                | BoundaryCharacteristic::MultiGrid(_) => {
 | 
			
		||||
                    Some(ndarray::Array2::zeros((4, grid.ny())))
 | 
			
		||||
@@ -888,6 +924,7 @@ impl BoundaryStorage {
 | 
			
		||||
            },
 | 
			
		||||
            west: match bt.west() {
 | 
			
		||||
                BoundaryCharacteristic::Vortex(_)
 | 
			
		||||
                | BoundaryCharacteristic::Eval(_)
 | 
			
		||||
                | BoundaryCharacteristic::Interpolate(_, _)
 | 
			
		||||
                | BoundaryCharacteristic::MultiGrid(_) => {
 | 
			
		||||
                    Some(ndarray::Array2::zeros((4, grid.ny())))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user