change trait signature for interpolation

This commit is contained in:
Magnus Ulimoen 2020-04-13 20:56:29 +02:00
parent 2adf91e1ce
commit 9cfd54253f
5 changed files with 61 additions and 28 deletions

View File

@ -16,6 +16,7 @@ struct System {
bt: Vec<euler::BoundaryCharacteristics>, bt: Vec<euler::BoundaryCharacteristics>,
eb: Vec<euler::BoundaryStorage>, eb: Vec<euler::BoundaryStorage>,
time: Float, time: Float,
interpolation_operators: Vec<euler::InterpolationOperators>,
} }
enum Metrics { enum Metrics {
@ -33,6 +34,7 @@ impl System {
fn new( fn new(
grids: Vec<grid::Grid>, grids: Vec<grid::Grid>,
bt: Vec<euler::BoundaryCharacteristics>, bt: Vec<euler::BoundaryCharacteristics>,
interpolation_operators: Vec<euler::InterpolationOperators>,
operatorx: &str, operatorx: &str,
operatory: &str, operatory: &str,
) -> Self { ) -> Self {
@ -95,6 +97,7 @@ impl System {
bt, bt,
eb, eb,
time: 0.0, time: 0.0,
interpolation_operators,
} }
} }
@ -110,15 +113,14 @@ impl System {
let bt = &self.bt; let bt = &self.bt;
let wb = &mut self.wb; let wb = &mut self.wb;
let mut eb = &mut self.eb; let mut eb = &mut self.eb;
let intops = &self.interpolation_operators;
let rhs = move |fut: &mut [euler::Field], let rhs = move |fut: &mut [euler::Field],
prev: &[euler::Field], prev: &[euler::Field],
time: Float, time: Float,
_c: (), _c: (),
_mt: &mut ()| { _mt: &mut ()| {
let bc = euler::extract_boundaries::<operators::Interpolation4>( let bc = euler::extract_boundaries(prev, &bt, &mut eb, &grids, time, Some(intops));
prev, &bt, &mut eb, &grids, time,
);
pool.scope(|s| { pool.scope(|s| {
for ((((fut, prev), bc), wb), metrics) in fut for ((((fut, prev), bc), wb), metrics) in fut
.iter_mut() .iter_mut()
@ -238,6 +240,15 @@ fn main() {
west: determine_bc(grid.dirw.as_ref()), west: determine_bc(grid.dirw.as_ref()),
}); });
} }
let interpolation_operators = jgrids
.iter()
.map(|_g| euler::InterpolationOperators {
north: Some(Box::new(operators::Interpolation4)),
south: Some(Box::new(operators::Interpolation4)),
east: Some(Box::new(operators::Interpolation4)),
west: Some(Box::new(operators::Interpolation4)),
})
.collect::<Vec<_>>();
let grids = jgrids.into_iter().map(|egrid| egrid.grid).collect(); let grids = jgrids.into_iter().map(|egrid| egrid.grid).collect();
let integration_time: Float = json["integration_time"].as_number().unwrap().into(); let integration_time: Float = json["integration_time"].as_number().unwrap().into();
@ -254,7 +265,7 @@ fn main() {
} }
}; };
let mut sys = System::new(grids, bt, operatorx, operatory); let mut sys = System::new(grids, bt, interpolation_operators, operatorx, operatory);
sys.vortex(0.0, vortexparams); sys.vortex(0.0, vortexparams);
let max_n = { let max_n = {

View File

@ -608,14 +608,15 @@ pub enum BoundaryCharacteristic {
Interpolate(usize), Interpolate(usize),
} }
#[derive(Clone, Debug)] pub struct Direction<T> {
pub struct BoundaryCharacteristics { pub north: T,
pub north: BoundaryCharacteristic, pub south: T,
pub south: BoundaryCharacteristic, pub west: T,
pub east: BoundaryCharacteristic, pub east: T,
pub west: BoundaryCharacteristic,
} }
pub type BoundaryCharacteristics = Direction<BoundaryCharacteristic>;
fn boundary_extractor<'a>( fn boundary_extractor<'a>(
field: &'a Field, field: &'a Field,
_grid: &Grid, _grid: &Grid,
@ -653,18 +654,22 @@ fn boundary_extractor<'a>(
} }
} }
pub fn extract_boundaries<'a, IO: InterpolationOperator>( pub type InterpolationOperators = Direction<Option<Box<dyn InterpolationOperator>>>;
pub fn extract_boundaries<'a>(
fields: &'a [Field], fields: &'a [Field],
bt: &[BoundaryCharacteristics], bt: &[BoundaryCharacteristics],
eb: &'a mut [BoundaryStorage], eb: &'a mut [BoundaryStorage],
grids: &[Grid], grids: &[Grid],
time: Float, time: Float,
interpolation_operators: Option<&[InterpolationOperators]>,
) -> Vec<BoundaryTerms<'a>> { ) -> Vec<BoundaryTerms<'a>> {
bt.iter() bt.iter()
.zip(eb) .zip(eb)
.zip(grids) .zip(grids)
.zip(fields) .zip(fields)
.map(|(((bt, eb), grid), field)| BoundaryTerms { .enumerate()
.map(|(ig, (((bt, eb), grid), field))| BoundaryTerms {
north: match bt.north { north: match bt.north {
BoundaryCharacteristic::This => field.south(), BoundaryCharacteristic::This => field.south(),
BoundaryCharacteristic::Grid(g) => fields[g].south(), BoundaryCharacteristic::Grid(g) => fields[g].south(),
@ -677,11 +682,16 @@ pub fn extract_boundaries<'a, IO: InterpolationOperator>(
let to = eb.n.as_mut().unwrap(); let to = eb.n.as_mut().unwrap();
let fine2coarse = field.nx() < fields[g].nx(); let fine2coarse = field.nx() < fields[g].nx();
let operator = interpolation_operators.as_ref().unwrap()[ig]
.north
.as_ref()
.unwrap();
for (mut to, from) in to.outer_iter_mut().zip(fields[g].south().outer_iter()) { for (mut to, from) in to.outer_iter_mut().zip(fields[g].south().outer_iter()) {
if fine2coarse { if fine2coarse {
IO::fine2coarse(from.view(), to.view_mut()); operator.fine2coarse(from.view(), to.view_mut());
} else { } else {
IO::coarse2fine(from.view(), to.view_mut()); operator.coarse2fine(from.view(), to.view_mut());
} }
} }
to.view() to.view()
@ -698,12 +708,16 @@ pub fn extract_boundaries<'a, IO: InterpolationOperator>(
BoundaryCharacteristic::Interpolate(g) => { BoundaryCharacteristic::Interpolate(g) => {
let to = eb.s.as_mut().unwrap(); let to = eb.s.as_mut().unwrap();
let fine2coarse = field.nx() < fields[g].nx(); let fine2coarse = field.nx() < fields[g].nx();
let operator = interpolation_operators.as_ref().unwrap()[ig]
.south
.as_ref()
.unwrap();
for (mut to, from) in to.outer_iter_mut().zip(fields[g].north().outer_iter()) { for (mut to, from) in to.outer_iter_mut().zip(fields[g].north().outer_iter()) {
if fine2coarse { if fine2coarse {
IO::fine2coarse(from.view(), to.view_mut()); operator.fine2coarse(from.view(), to.view_mut());
} else { } else {
IO::coarse2fine(from.view(), to.view_mut()); operator.coarse2fine(from.view(), to.view_mut());
} }
} }
to.view() to.view()
@ -720,12 +734,16 @@ pub fn extract_boundaries<'a, IO: InterpolationOperator>(
BoundaryCharacteristic::Interpolate(g) => { BoundaryCharacteristic::Interpolate(g) => {
let to = eb.w.as_mut().unwrap(); let to = eb.w.as_mut().unwrap();
let fine2coarse = field.ny() < fields[g].ny(); let fine2coarse = field.ny() < fields[g].ny();
let operator = interpolation_operators.as_ref().unwrap()[ig]
.west
.as_ref()
.unwrap();
for (mut to, from) in to.outer_iter_mut().zip(fields[g].east().outer_iter()) { for (mut to, from) in to.outer_iter_mut().zip(fields[g].east().outer_iter()) {
if fine2coarse { if fine2coarse {
IO::fine2coarse(from.view(), to.view_mut()); operator.fine2coarse(from.view(), to.view_mut());
} else { } else {
IO::coarse2fine(from.view(), to.view_mut()); operator.coarse2fine(from.view(), to.view_mut());
} }
} }
to.view() to.view()
@ -742,12 +760,16 @@ pub fn extract_boundaries<'a, IO: InterpolationOperator>(
BoundaryCharacteristic::Interpolate(g) => { BoundaryCharacteristic::Interpolate(g) => {
let to = eb.e.as_mut().unwrap(); let to = eb.e.as_mut().unwrap();
let fine2coarse = field.ny() < fields[g].ny(); let fine2coarse = field.ny() < fields[g].ny();
let operator = interpolation_operators.as_ref().unwrap()[ig]
.east
.as_ref()
.unwrap();
for (mut to, from) in to.outer_iter_mut().zip(fields[g].west().outer_iter()) { for (mut to, from) in to.outer_iter_mut().zip(fields[g].west().outer_iter()) {
if fine2coarse { if fine2coarse {
IO::fine2coarse(from.view(), to.view_mut()); operator.fine2coarse(from.view(), to.view_mut());
} else { } else {
IO::coarse2fine(from.view(), to.view_mut()); operator.coarse2fine(from.view(), to.view_mut());
} }
} }
to.view() to.view()

View File

@ -36,8 +36,8 @@ pub trait UpwindOperator: SbpOperator {
} }
pub trait InterpolationOperator: Send + Sync { pub trait InterpolationOperator: Send + Sync {
fn fine2coarse(fine: ArrayView1<Float>, coarse: ArrayViewMut1<Float>); fn fine2coarse(&self, fine: ArrayView1<Float>, coarse: ArrayViewMut1<Float>);
fn coarse2fine(coarse: ArrayView1<Float>, fine: ArrayViewMut1<Float>); fn coarse2fine(&self, coarse: ArrayView1<Float>, fine: ArrayViewMut1<Float>);
} }
#[inline(always)] #[inline(always)]

View File

@ -1,6 +1,6 @@
use super::*; use super::*;
pub struct Interpolation4 {} pub struct Interpolation4;
impl Interpolation4 { impl Interpolation4 {
const F2C_DIAG: &'static [[Float; 7]] = &[[ const F2C_DIAG: &'static [[Float; 7]] = &[[
@ -71,7 +71,7 @@ impl Interpolation4 {
} }
impl InterpolationOperator for Interpolation4 { impl InterpolationOperator for Interpolation4 {
fn fine2coarse(fine: ArrayView1<Float>, coarse: ArrayViewMut1<Float>) { fn fine2coarse(&self, fine: ArrayView1<Float>, coarse: ArrayViewMut1<Float>) {
assert_eq!(fine.len(), 2 * coarse.len() - 1); assert_eq!(fine.len(), 2 * coarse.len() - 1);
super::interpolate( super::interpolate(
fine, fine,
@ -81,7 +81,7 @@ impl InterpolationOperator for Interpolation4 {
(3, 2), (3, 2),
) )
} }
fn coarse2fine(coarse: ArrayView1<Float>, fine: ArrayViewMut1<Float>) { fn coarse2fine(&self, coarse: ArrayView1<Float>, fine: ArrayViewMut1<Float>) {
assert_eq!(fine.len(), 2 * coarse.len() - 1); assert_eq!(fine.len(), 2 * coarse.len() - 1);
super::interpolate( super::interpolate(
coarse, coarse,

View File

@ -1,6 +1,6 @@
use super::*; use super::*;
pub struct Interpolation9 {} pub struct Interpolation9;
impl Interpolation9 { impl Interpolation9 {
#[rustfmt::skip] #[rustfmt::skip]
@ -50,7 +50,7 @@ impl Interpolation9 {
} }
impl InterpolationOperator for Interpolation9 { impl InterpolationOperator for Interpolation9 {
fn fine2coarse(fine: ArrayView1<Float>, coarse: ArrayViewMut1<Float>) { fn fine2coarse(&self, fine: ArrayView1<Float>, coarse: ArrayViewMut1<Float>) {
assert_eq!(fine.len(), 2 * coarse.len() - 1); assert_eq!(fine.len(), 2 * coarse.len() - 1);
use ndarray::prelude::*; use ndarray::prelude::*;
use std::iter::FromIterator; use std::iter::FromIterator;
@ -62,7 +62,7 @@ impl InterpolationOperator for Interpolation9 {
.unwrap(); .unwrap();
super::interpolate(fine, coarse, block.view(), diag.view(), (5, 2)) super::interpolate(fine, coarse, block.view(), diag.view(), (5, 2))
} }
fn coarse2fine(coarse: ArrayView1<Float>, fine: ArrayViewMut1<Float>) { fn coarse2fine(&self, coarse: ArrayView1<Float>, fine: ArrayViewMut1<Float>) {
assert_eq!(fine.len(), 2 * coarse.len() - 1); assert_eq!(fine.len(), 2 * coarse.len() - 1);
use ndarray::prelude::*; use ndarray::prelude::*;
use std::iter::FromIterator; use std::iter::FromIterator;