Introduce Diff type for euler
This commit is contained in:
parent
27abaebc2c
commit
5f7d38dd55
|
@ -16,7 +16,7 @@ pub const GAMMA: Float = 1.4;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct System<SBP: SbpOperator2d> {
|
pub struct System<SBP: SbpOperator2d> {
|
||||||
sys: (Field, Field),
|
sys: (Field, Field),
|
||||||
k: [Field; 4],
|
k: [Diff; 4],
|
||||||
wb: WorkBuffers,
|
wb: WorkBuffers,
|
||||||
grid: (Grid, Metrics),
|
grid: (Grid, Metrics),
|
||||||
op: SBP,
|
op: SBP,
|
||||||
|
@ -34,10 +34,10 @@ impl<SBP: SbpOperator2d> System<SBP> {
|
||||||
sys: (Field::new(ny, nx), Field::new(ny, nx)),
|
sys: (Field::new(ny, nx), Field::new(ny, nx)),
|
||||||
grid: (grid, metrics),
|
grid: (grid, metrics),
|
||||||
k: [
|
k: [
|
||||||
Field::new(ny, nx),
|
Diff::zeros((ny, nx)),
|
||||||
Field::new(ny, nx),
|
Diff::zeros((ny, nx)),
|
||||||
Field::new(ny, nx),
|
Diff::zeros((ny, nx)),
|
||||||
Field::new(ny, nx),
|
Diff::zeros((ny, nx)),
|
||||||
],
|
],
|
||||||
wb: WorkBuffers::new(ny, nx),
|
wb: WorkBuffers::new(ny, nx),
|
||||||
op,
|
op,
|
||||||
|
@ -55,7 +55,7 @@ impl<SBP: SbpOperator2d> System<SBP> {
|
||||||
let wb = &mut self.wb.0;
|
let wb = &mut self.wb.0;
|
||||||
let grid = &self.grid.0;
|
let grid = &self.grid.0;
|
||||||
let metrics = &self.grid.1;
|
let metrics = &self.grid.1;
|
||||||
let rhs_trad = |k: &mut Field, y: &Field, _time: Float| {
|
let rhs_trad = |k: &mut Diff, y: &Field, _time: Float| {
|
||||||
let boundaries = boundary_extractor(y, grid, &bc);
|
let boundaries = boundary_extractor(y, grid, &bc);
|
||||||
RHS_trad(op, k, y, metrics, &boundaries, wb)
|
RHS_trad(op, k, y, metrics, &boundaries, wb)
|
||||||
};
|
};
|
||||||
|
@ -128,7 +128,7 @@ impl<UO: UpwindOperator2d + SbpOperator2d> System<UO> {
|
||||||
let op = &self.op;
|
let op = &self.op;
|
||||||
let grid = &self.grid;
|
let grid = &self.grid;
|
||||||
let wb = &mut self.wb.0;
|
let wb = &mut self.wb.0;
|
||||||
let rhs_upwind = |k: &mut Field, y: &Field, _time: Float| {
|
let rhs_upwind = |k: &mut Diff, y: &Field, _time: Float| {
|
||||||
let (grid, metrics) = grid;
|
let (grid, metrics) = grid;
|
||||||
let boundaries = boundary_extractor(y, grid, &bc);
|
let boundaries = boundary_extractor(y, grid, &bc);
|
||||||
RHS_upwind(op, k, y, metrics, &boundaries, wb)
|
RHS_upwind(op, k, y, metrics, &boundaries, wb)
|
||||||
|
@ -153,7 +153,7 @@ impl<UO: UpwindOperator2d + SbpOperator2d> System<UO> {
|
||||||
let op = &self.op;
|
let op = &self.op;
|
||||||
let grid = &self.grid;
|
let grid = &self.grid;
|
||||||
let wb = &mut self.wb.0;
|
let wb = &mut self.wb.0;
|
||||||
let mut rhs_upwind = |k: &mut Field, y: &Field, _time: Float| {
|
let mut rhs_upwind = |k: &mut Diff, y: &Field, _time: Float| {
|
||||||
let (grid, metrics) = grid;
|
let (grid, metrics) = grid;
|
||||||
let boundaries = boundary_extractor(y, grid, &bc);
|
let boundaries = boundary_extractor(y, grid, &bc);
|
||||||
RHS_upwind(op, k, y, metrics, &boundaries, wb)
|
RHS_upwind(op, k, y, metrics, &boundaries, wb)
|
||||||
|
@ -186,9 +186,13 @@ impl<UO: UpwindOperator2d + SbpOperator2d> System<UO> {
|
||||||
/// A 4 x ny x nx array
|
/// A 4 x ny x nx array
|
||||||
pub struct Field(pub(crate) Array3<Float>);
|
pub struct Field(pub(crate) Array3<Float>);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
/// A 4 x ny x nx array
|
||||||
|
pub struct Diff(pub(crate) Array3<Float>);
|
||||||
|
|
||||||
impl integrate::Integrable for Field {
|
impl integrate::Integrable for Field {
|
||||||
type State = Field;
|
type State = Field;
|
||||||
type Diff = Field;
|
type Diff = Diff;
|
||||||
|
|
||||||
fn assign(s: &mut Self::State, o: &Self::State) {
|
fn assign(s: &mut Self::State, o: &Self::State) {
|
||||||
s.0.assign(&o.0);
|
s.0.assign(&o.0);
|
||||||
|
@ -288,17 +292,21 @@ impl Field {
|
||||||
pub fn west(&self) -> ArrayView2<Float> {
|
pub fn west(&self) -> ArrayView2<Float> {
|
||||||
self.slice(s![.., .., 0])
|
self.slice(s![.., .., 0])
|
||||||
}
|
}
|
||||||
|
#[allow(unused)]
|
||||||
fn north_mut(&mut self) -> ArrayViewMut2<Float> {
|
fn north_mut(&mut self) -> ArrayViewMut2<Float> {
|
||||||
let ny = self.ny();
|
let ny = self.ny();
|
||||||
self.slice_mut(s![.., ny - 1, ..])
|
self.slice_mut(s![.., ny - 1, ..])
|
||||||
}
|
}
|
||||||
|
#[allow(unused)]
|
||||||
fn south_mut(&mut self) -> ArrayViewMut2<Float> {
|
fn south_mut(&mut self) -> ArrayViewMut2<Float> {
|
||||||
self.slice_mut(s![.., 0, ..])
|
self.slice_mut(s![.., 0, ..])
|
||||||
}
|
}
|
||||||
|
#[allow(unused)]
|
||||||
fn east_mut(&mut self) -> ArrayViewMut2<Float> {
|
fn east_mut(&mut self) -> ArrayViewMut2<Float> {
|
||||||
let nx = self.nx();
|
let nx = self.nx();
|
||||||
self.slice_mut(s![.., .., nx - 1])
|
self.slice_mut(s![.., .., nx - 1])
|
||||||
}
|
}
|
||||||
|
#[allow(unused)]
|
||||||
fn west_mut(&mut self) -> ArrayViewMut2<Float> {
|
fn west_mut(&mut self) -> ArrayViewMut2<Float> {
|
||||||
self.slice_mut(s![.., .., 0])
|
self.slice_mut(s![.., .., 0])
|
||||||
}
|
}
|
||||||
|
@ -448,6 +456,34 @@ fn h2_diff() {
|
||||||
assert!((field0.h2_err(&field1, &SBP8).powi(2) - 4.0).abs() < 1e-3);
|
assert!((field0.h2_err(&field1, &SBP8).powi(2) - 4.0).abs() < 1e-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lazy inheritance...
|
||||||
|
impl core::ops::Deref for Diff {
|
||||||
|
type Target = Array3<Float>;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Diff {
|
||||||
|
pub fn zeros((ny, nx): (usize, usize)) -> Self {
|
||||||
|
Self(Array3::zeros((4, ny, nx)))
|
||||||
|
}
|
||||||
|
fn north_mut(&mut self) -> ArrayViewMut2<Float> {
|
||||||
|
let ny = self.shape()[1];
|
||||||
|
self.0.slice_mut(s![.., ny - 1, ..])
|
||||||
|
}
|
||||||
|
fn south_mut(&mut self) -> ArrayViewMut2<Float> {
|
||||||
|
self.0.slice_mut(s![.., 0, ..])
|
||||||
|
}
|
||||||
|
fn east_mut(&mut self) -> ArrayViewMut2<Float> {
|
||||||
|
let nx = self.shape()[2];
|
||||||
|
self.0.slice_mut(s![.., .., nx - 1])
|
||||||
|
}
|
||||||
|
fn west_mut(&mut self) -> ArrayViewMut2<Float> {
|
||||||
|
self.0.slice_mut(s![.., .., 0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn pressure(gamma: Float, rho: Float, rhou: Float, rhov: Float, e: Float) -> Float {
|
fn pressure(gamma: Float, rho: Float, rhou: Float, rhov: Float, e: Float) -> Float {
|
||||||
(gamma - 1.0) * (e - (rhou * rhou + rhov * rhov) / (2.0 * rho))
|
(gamma - 1.0) * (e - (rhou * rhou + rhov * rhov) / (2.0 * rho))
|
||||||
}
|
}
|
||||||
|
@ -455,7 +491,7 @@ fn pressure(gamma: Float, rho: Float, rhou: Float, rhov: Float, e: Float) -> Flo
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn RHS_trad(
|
pub fn RHS_trad(
|
||||||
op: &dyn SbpOperator2d,
|
op: &dyn SbpOperator2d,
|
||||||
k: &mut Field,
|
k: &mut Diff,
|
||||||
y: &Field,
|
y: &Field,
|
||||||
metrics: &Metrics,
|
metrics: &Metrics,
|
||||||
boundaries: &BoundaryTerms,
|
boundaries: &BoundaryTerms,
|
||||||
|
@ -490,7 +526,7 @@ pub fn RHS_trad(
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn RHS_upwind(
|
pub fn RHS_upwind(
|
||||||
op: &dyn SbpOperator2d,
|
op: &dyn SbpOperator2d,
|
||||||
k: &mut Field,
|
k: &mut Diff,
|
||||||
y: &Field,
|
y: &Field,
|
||||||
metrics: &Metrics,
|
metrics: &Metrics,
|
||||||
boundaries: &BoundaryTerms,
|
boundaries: &BoundaryTerms,
|
||||||
|
@ -880,17 +916,20 @@ fn vortexify(
|
||||||
/// Boundary conditions (SAT)
|
/// Boundary conditions (SAT)
|
||||||
fn SAT_characteristics(
|
fn SAT_characteristics(
|
||||||
op: &dyn SbpOperator2d,
|
op: &dyn SbpOperator2d,
|
||||||
k: &mut Field,
|
k: &mut Diff,
|
||||||
y: &Field,
|
y: &Field,
|
||||||
metrics: &Metrics,
|
metrics: &Metrics,
|
||||||
boundaries: &BoundaryTerms,
|
boundaries: &BoundaryTerms,
|
||||||
) {
|
) {
|
||||||
|
let ny = y.ny();
|
||||||
|
let nx = y.nx();
|
||||||
|
|
||||||
// North boundary
|
// North boundary
|
||||||
{
|
{
|
||||||
let hi = if op.is_h2eta() {
|
let hi = if op.is_h2eta() {
|
||||||
(k.ny() - 2) as Float / op.heta()[0]
|
(ny - 2) as Float / op.heta()[0]
|
||||||
} else {
|
} else {
|
||||||
(k.ny() - 1) as Float / op.heta()[0]
|
(ny - 1) as Float / op.heta()[0]
|
||||||
};
|
};
|
||||||
let sign = -1.0;
|
let sign = -1.0;
|
||||||
let tau = 1.0;
|
let tau = 1.0;
|
||||||
|
@ -910,9 +949,9 @@ fn SAT_characteristics(
|
||||||
// South boundary
|
// South boundary
|
||||||
{
|
{
|
||||||
let hi = if op.is_h2eta() {
|
let hi = if op.is_h2eta() {
|
||||||
(k.ny() - 2) as Float / op.heta()[0]
|
(ny - 2) as Float / op.heta()[0]
|
||||||
} else {
|
} else {
|
||||||
(k.ny() - 1) as Float / op.heta()[0]
|
(ny - 1) as Float / op.heta()[0]
|
||||||
};
|
};
|
||||||
let sign = 1.0;
|
let sign = 1.0;
|
||||||
let tau = -1.0;
|
let tau = -1.0;
|
||||||
|
@ -932,9 +971,9 @@ fn SAT_characteristics(
|
||||||
// West Boundary
|
// West Boundary
|
||||||
{
|
{
|
||||||
let hi = if op.is_h2xi() {
|
let hi = if op.is_h2xi() {
|
||||||
(k.nx() - 2) as Float / op.hxi()[0]
|
(nx - 2) as Float / op.hxi()[0]
|
||||||
} else {
|
} else {
|
||||||
(k.nx() - 1) as Float / op.hxi()[0]
|
(nx - 1) as Float / op.hxi()[0]
|
||||||
};
|
};
|
||||||
let sign = 1.0;
|
let sign = 1.0;
|
||||||
let tau = -1.0;
|
let tau = -1.0;
|
||||||
|
@ -954,9 +993,9 @@ fn SAT_characteristics(
|
||||||
// East Boundary
|
// East Boundary
|
||||||
{
|
{
|
||||||
let hi = if op.is_h2xi() {
|
let hi = if op.is_h2xi() {
|
||||||
(k.nx() - 2) as Float / op.hxi()[0]
|
(nx - 2) as Float / op.hxi()[0]
|
||||||
} else {
|
} else {
|
||||||
(k.nx() - 1) as Float / op.hxi()[0]
|
(nx - 1) as Float / op.hxi()[0]
|
||||||
};
|
};
|
||||||
let sign = -1.0;
|
let sign = -1.0;
|
||||||
let tau = 1.0;
|
let tau = 1.0;
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct System {
|
||||||
fnow: Vec<euler::Field>,
|
fnow: Vec<euler::Field>,
|
||||||
fnext: Vec<euler::Field>,
|
fnext: Vec<euler::Field>,
|
||||||
wb: Vec<euler::WorkBuffers>,
|
wb: Vec<euler::WorkBuffers>,
|
||||||
k: [Vec<euler::Field>; 4],
|
k: [Vec<euler::Diff>; 4],
|
||||||
grids: Vec<grid::Grid>,
|
grids: Vec<grid::Grid>,
|
||||||
metrics: Vec<grid::Metrics>,
|
metrics: Vec<grid::Metrics>,
|
||||||
bt: Vec<euler::BoundaryCharacteristics>,
|
bt: Vec<euler::BoundaryCharacteristics>,
|
||||||
|
@ -26,7 +26,7 @@ pub(crate) static MULTITHREAD: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
impl integrate::Integrable for System {
|
impl integrate::Integrable for System {
|
||||||
type State = Vec<euler::Field>;
|
type State = Vec<euler::Field>;
|
||||||
type Diff = Vec<euler::Field>;
|
type Diff = Vec<euler::Diff>;
|
||||||
fn assign(s: &mut Self::State, o: &Self::State) {
|
fn assign(s: &mut Self::State, o: &Self::State) {
|
||||||
if MULTITHREAD.load(Ordering::Acquire) {
|
if MULTITHREAD.load(Ordering::Acquire) {
|
||||||
s.par_iter_mut()
|
s.par_iter_mut()
|
||||||
|
@ -66,7 +66,11 @@ impl System {
|
||||||
.iter()
|
.iter()
|
||||||
.map(|g| euler::WorkBuffers::new(g.ny(), g.nx()))
|
.map(|g| euler::WorkBuffers::new(g.ny(), g.nx()))
|
||||||
.collect();
|
.collect();
|
||||||
let k = [fnow.clone(), fnow.clone(), fnow.clone(), fnow.clone()];
|
let k = grids
|
||||||
|
.iter()
|
||||||
|
.map(|g| euler::Diff::zeros((g.ny(), g.nx())))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let k = [k.clone(), k.clone(), k.clone(), k];
|
||||||
let metrics = grids
|
let metrics = grids
|
||||||
.iter()
|
.iter()
|
||||||
.zip(&operators)
|
.zip(&operators)
|
||||||
|
@ -107,7 +111,7 @@ impl System {
|
||||||
let eb = &mut self.eb;
|
let eb = &mut self.eb;
|
||||||
let operators = &self.operators;
|
let operators = &self.operators;
|
||||||
|
|
||||||
let rhs = move |fut: &mut Vec<euler::Field>, prev: &Vec<euler::Field>, time: Float| {
|
let rhs = move |fut: &mut Vec<euler::Diff>, prev: &Vec<euler::Field>, time: Float| {
|
||||||
let prev_all = &prev;
|
let prev_all = &prev;
|
||||||
if MULTITHREAD.load(Ordering::Acquire) {
|
if MULTITHREAD.load(Ordering::Acquire) {
|
||||||
rayon::scope(|s| {
|
rayon::scope(|s| {
|
||||||
|
|
Loading…
Reference in New Issue