From ed0f0e4a20ff2ca87ab378a28580d40106b6f46c Mon Sep 17 00:00:00 2001 From: Magnus Ulimoen Date: Sun, 19 Apr 2020 18:49:43 +0200 Subject: [PATCH] add tsection type interfaces This interface combines grids which do not have clean interfaces. The type of interface has not been tested or verified here. --- multigrid/examples/tsection.json | 48 +++++++++++++ multigrid/src/parsing.rs | 21 ++++++ sbp/src/euler.rs | 117 ++++++++++++++++++++++++++----- 3 files changed, 170 insertions(+), 16 deletions(-) create mode 100644 multigrid/examples/tsection.json diff --git a/multigrid/examples/tsection.json b/multigrid/examples/tsection.json new file mode 100644 index 0000000..e54bf7a --- /dev/null +++ b/multigrid/examples/tsection.json @@ -0,0 +1,48 @@ +{ + "grids": { + "default": { + "operators": { + "xi": "upwind9", + "eta": "upwind9" + } + }, + "grid0": { + "x": "linspace:-5:5:101", + "y": "linspace:0:5:50", + "boundary_conditions": { + "south": "multi:grid1(0,61):grid2(0,41)", + "north": "vortex", + "east": "vortex", + "west": "vortex" + } + }, + "grid1": { + "x": "linspace:-5:1:61", + "y": "linspace:-5:0:50", + "boundary_conditions": { + "south": "vortex", + "north": "multi:grid0(0,61)", + "east": "grid2", + "west": "vortex" + } + }, + "grid2": { + "x": "linspace:1:5:41", + "y": "linspace:-5:0:50", + "boundary_conditions": { + "south": "vortex", + "north": "multi:grid0(60,101)", + "east": "vortex", + "west": "grid1" + } + } + }, + "integration_time": 2.0, + "vortex": { + "x0": 0.0, + "y0": 0.0, + "mach": 0.5, + "rstar": 0.5, + "eps": 1.0 + } +} diff --git a/multigrid/src/parsing.rs b/multigrid/src/parsing.rs index bf402ea..b3689cb 100644 --- a/multigrid/src/parsing.rs +++ b/multigrid/src/parsing.rs @@ -143,6 +143,27 @@ pub fn json_to_grids( names.iter().position(|other| other == grid).unwrap(), int_op, ) + } else if let Some(multigrid) = dir.strip_prefix("multi:") { + let grids = multigrid.split(":"); + sbp::euler::BoundaryCharacteristic::MultiGrid( + grids + .map(|g| { + let rparen = g.find('(').unwrap(); + let gridname = &g[..rparen]; + + let gridnumber = + names.iter().position(|other| other == gridname).unwrap(); + + let paren = &g[rparen + 1..]; + let paren = &paren[..paren.len() - 1]; + let mut pareni = paren.split(','); + let start = pareni.next().unwrap().parse::().unwrap(); + let end = pareni.next().unwrap().parse::().unwrap(); + + (gridnumber, start, end) + }) + .collect::>(), + ) } else { sbp::euler::BoundaryCharacteristic::Grid( names.iter().position(|other| other == dir).unwrap(), diff --git a/sbp/src/euler.rs b/sbp/src/euler.rs index 309afc6..ac55c35 100644 --- a/sbp/src/euler.rs +++ b/sbp/src/euler.rs @@ -614,6 +614,7 @@ pub enum BoundaryCharacteristic { Vortex(VortexParameters), // Vortices(Vec), Interpolate(usize, Box), + MultiGrid(Vec<(usize, usize, usize)>), } pub type BoundaryTerms<'a> = Direction>; @@ -628,30 +629,30 @@ fn boundary_extractor<'a>( north: match bc.north { BoundaryCharacteristic::This => field.south(), BoundaryCharacteristic::Vortex(_params) => todo!(), - BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_, _) => { - panic!("Only working on self grid") - } + BoundaryCharacteristic::Grid(_) + | BoundaryCharacteristic::Interpolate(_, _) + | BoundaryCharacteristic::MultiGrid(_) => panic!("Only working on self grid"), }, south: match bc.south { BoundaryCharacteristic::This => field.north(), BoundaryCharacteristic::Vortex(_params) => todo!(), - BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_, _) => { - panic!("Only working on self grid") - } + BoundaryCharacteristic::Grid(_) + | BoundaryCharacteristic::Interpolate(_, _) + | BoundaryCharacteristic::MultiGrid(_) => panic!("Only working on self grid"), }, west: match bc.west { BoundaryCharacteristic::This => field.east(), BoundaryCharacteristic::Vortex(_params) => todo!(), - BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_, _) => { - panic!("Only working on self grid") - } + BoundaryCharacteristic::Grid(_) + | BoundaryCharacteristic::Interpolate(_, _) + | BoundaryCharacteristic::MultiGrid(_) => panic!("Only working on self grid"), }, east: match bc.east { BoundaryCharacteristic::This => field.west(), BoundaryCharacteristic::Vortex(_params) => todo!(), - BoundaryCharacteristic::Grid(_) | BoundaryCharacteristic::Interpolate(_, _) => { - panic!("Only working on self grid") - } + BoundaryCharacteristic::Grid(_) + | BoundaryCharacteristic::Interpolate(_, _) + | BoundaryCharacteristic::MultiGrid(_) => panic!("Only working on self grid"), }, } } @@ -689,6 +690,25 @@ pub fn extract_boundaries<'a>( } to.view() } + BoundaryCharacteristic::MultiGrid(grids) => { + let to = eb.north.as_mut().unwrap(); + let mut i = 0; + let mut remaining = grids.len(); + for &(g, start, end) in grids.iter() { + let n: usize = end - start; + to.slice_mut(s![.., i..i + n]) + .assign(&fields[g].south().slice(s![.., start..end])); + remaining -= 1; + if remaining != 0 { + to.slice_mut(s![.., i]).iter_mut().for_each(|x| *x /= 2.0); + i += n - 1; + } else { + i += n; + assert_eq!(i, to.len_of(Axis(1))); + } + } + to.view() + } }, south: match &bt.south { BoundaryCharacteristic::This => field.north(), @@ -711,6 +731,25 @@ pub fn extract_boundaries<'a>( } to.view() } + BoundaryCharacteristic::MultiGrid(grids) => { + let to = eb.south.as_mut().unwrap(); + let mut i = 0; + let mut remaining = grids.len(); + for &(g, start, end) in grids.iter() { + let n: usize = end - start; + to.slice_mut(s![.., i..i + n]) + .assign(&fields[g].north().slice(s![.., start..end])); + remaining -= 1; + if remaining != 0 { + to.slice_mut(s![.., i]).iter_mut().for_each(|x| *x /= 2.0); + i += n - 1; + } else { + i += n; + assert_eq!(i, to.len_of(Axis(1))); + } + } + to.view() + } }, west: match &bt.west { BoundaryCharacteristic::This => field.east(), @@ -733,6 +772,25 @@ pub fn extract_boundaries<'a>( } to.view() } + BoundaryCharacteristic::MultiGrid(grids) => { + let to = eb.west.as_mut().unwrap(); + let mut i = 0; + let mut remaining = grids.len(); + for &(g, start, end) in grids.iter() { + let n: usize = end - start; + to.slice_mut(s![.., i..i + n]) + .assign(&fields[g].east().slice(s![.., start..end])); + remaining -= 1; + if remaining != 0 { + to.slice_mut(s![.., i]).iter_mut().for_each(|x| *x /= 2.0); + i += n - 1; + } else { + i += n; + assert_eq!(i, to.len_of(Axis(1))); + } + } + to.view() + } }, east: match &bt.east { BoundaryCharacteristic::This => field.west(), @@ -755,6 +813,25 @@ pub fn extract_boundaries<'a>( } to.view() } + BoundaryCharacteristic::MultiGrid(grids) => { + let to = eb.east.as_mut().unwrap(); + let mut i = 0; + let mut remaining = grids.len(); + for &(g, start, end) in grids.iter() { + let n: usize = end - start; + to.slice_mut(s![.., i..i + n]) + .assign(&fields[g].west().slice(s![.., start..end])); + remaining -= 1; + if remaining != 0 { + to.slice_mut(s![.., i]).iter_mut().for_each(|x| *x /= 2.0); + i += n - 1; + } else { + i += n; + assert_eq!(i, to.len_of(Axis(1))); + } + } + to.view() + } }, }) .collect() @@ -767,25 +844,33 @@ impl BoundaryStorage { pub fn new(bt: &BoundaryCharacteristics, grid: &Grid) -> Self { Self { north: match bt.north { - BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_, _) => { + BoundaryCharacteristic::Vortex(_) + | BoundaryCharacteristic::Interpolate(_, _) + | BoundaryCharacteristic::MultiGrid(_) => { Some(ndarray::Array2::zeros((4, grid.nx()))) } _ => None, }, south: match bt.south { - BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_, _) => { + BoundaryCharacteristic::Vortex(_) + | BoundaryCharacteristic::Interpolate(_, _) + | BoundaryCharacteristic::MultiGrid(_) => { Some(ndarray::Array2::zeros((4, grid.nx()))) } _ => None, }, east: match bt.east { - BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_, _) => { + BoundaryCharacteristic::Vortex(_) + | BoundaryCharacteristic::Interpolate(_, _) + | BoundaryCharacteristic::MultiGrid(_) => { Some(ndarray::Array2::zeros((4, grid.ny()))) } _ => None, }, west: match bt.west { - BoundaryCharacteristic::Vortex(_) | BoundaryCharacteristic::Interpolate(_, _) => { + BoundaryCharacteristic::Vortex(_) + | BoundaryCharacteristic::Interpolate(_, _) + | BoundaryCharacteristic::MultiGrid(_) => { Some(ndarray::Array2::zeros((4, grid.ny()))) } _ => None,