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