126 lines
3.2 KiB
Rust
126 lines
3.2 KiB
Rust
|
use ndarray::Array2;
|
||
|
|
||
|
pub use sbp::{consts::*, grid::Grid, Float};
|
||
|
|
||
|
pub fn unit(ny: usize, nx: usize) -> Grid {
|
||
|
let x = Array2::from_shape_fn((ny, nx), |(_j, i)| i as Float / (nx - 1) as Float);
|
||
|
let y = Array2::from_shape_fn((ny, nx), |(j, _i)| j as Float / (ny - 1) as Float);
|
||
|
Grid::new(x, y).unwrap()
|
||
|
}
|
||
|
|
||
|
pub fn shell(ny: usize, nx: usize, mut inner: Float, mut outer: Float) -> Grid {
|
||
|
let mut unit = unit(ny, nx);
|
||
|
|
||
|
#[allow(unused)]
|
||
|
enum Mode {
|
||
|
Log,
|
||
|
Exp,
|
||
|
Normal,
|
||
|
}
|
||
|
|
||
|
let mode = Mode::Log;
|
||
|
match mode {
|
||
|
Mode::Exp => {
|
||
|
inner = inner.exp();
|
||
|
outer = outer.exp();
|
||
|
}
|
||
|
Mode::Log => {
|
||
|
inner = inner.ln();
|
||
|
outer = outer.ln();
|
||
|
}
|
||
|
_ => {}
|
||
|
}
|
||
|
|
||
|
let (mut gx, mut gy) = unit.components();
|
||
|
gx.iter_mut().zip(gy.iter_mut()).for_each(|(x, y)| {
|
||
|
let mut r = (*x) * (outer - inner) + inner;
|
||
|
match mode {
|
||
|
Mode::Exp => {
|
||
|
r = r.ln();
|
||
|
}
|
||
|
Mode::Log => {
|
||
|
r = r.exp();
|
||
|
}
|
||
|
_ => {}
|
||
|
}
|
||
|
let theta = *y * 2.0 * PI;
|
||
|
|
||
|
*x = r * theta.cos();
|
||
|
*y = r * theta.sin();
|
||
|
});
|
||
|
|
||
|
unit
|
||
|
}
|
||
|
|
||
|
pub fn vertical_interpolation(jlen: usize, north: &[Float], south: &[Float]) -> Grid {
|
||
|
let ilen = north.len();
|
||
|
assert_eq!(north.len(), south.len());
|
||
|
let mut grid = unit(jlen, ilen);
|
||
|
|
||
|
for j in 0..jlen {
|
||
|
for i in 0..ilen {
|
||
|
let y = grid.y()[(j, i)];
|
||
|
grid.y_mut()[(j, i)] = (north[i] - south[i]) * y + south[i];
|
||
|
}
|
||
|
}
|
||
|
grid
|
||
|
}
|
||
|
|
||
|
pub fn horizontal_interpolation(ilen: usize, east: &[Float], west: &[Float]) -> Grid {
|
||
|
let jlen = east.len();
|
||
|
assert_eq!(east.len(), west.len());
|
||
|
let mut grid = unit(jlen, ilen);
|
||
|
|
||
|
for j in 0..jlen {
|
||
|
for i in 0..ilen {
|
||
|
let x = grid.x()[(j, i)];
|
||
|
grid.x_mut()[(j, i)] = (east[j] - west[j]) * x + west[j];
|
||
|
}
|
||
|
}
|
||
|
grid
|
||
|
}
|
||
|
|
||
|
pub fn horizontal_interpolation_dual(
|
||
|
ilen: usize,
|
||
|
east: (&[Float], &[Float]),
|
||
|
west: (&[Float], &[Float]),
|
||
|
) -> Grid {
|
||
|
let jlen = east.0.len();
|
||
|
assert_eq!(east.0.len(), east.1.len());
|
||
|
assert_eq!(east.0.len(), west.0.len());
|
||
|
assert_eq!(east.0.len(), west.1.len());
|
||
|
let mut grid = unit(jlen, ilen);
|
||
|
|
||
|
for j in 0..jlen {
|
||
|
for i in 0..ilen {
|
||
|
let x = grid.x()[(j, i)];
|
||
|
grid.x_mut()[(j, i)] = (east.1[j] - west.1[j]) * x + west.1[j];
|
||
|
grid.y_mut()[(j, i)] = (east.0[j] - west.0[j]) * x + west.0[j];
|
||
|
}
|
||
|
}
|
||
|
grid
|
||
|
}
|
||
|
|
||
|
/// [east] : fn([0, 1]) -> (y, x)
|
||
|
/// [west] : fn([0, 1]) -> (y, x)
|
||
|
pub fn horizontal_interpolation_dual2(
|
||
|
ilen: usize,
|
||
|
jlen: usize,
|
||
|
east: impl Fn(Float) -> (Float, Float),
|
||
|
west: impl Fn(Float) -> (Float, Float),
|
||
|
) -> Grid {
|
||
|
let mut grid = unit(jlen, ilen);
|
||
|
|
||
|
for j in 0..jlen {
|
||
|
for i in 0..ilen {
|
||
|
let x = grid.x()[(j, i)];
|
||
|
let y = grid.y()[(j, i)];
|
||
|
let east = east(y);
|
||
|
let west = west(y);
|
||
|
grid.x_mut()[(j, i)] = (east.1 - west.1) * x + west.1;
|
||
|
grid.y_mut()[(j, i)] = (east.0 - west.0) * x + west.0;
|
||
|
}
|
||
|
}
|
||
|
grid
|
||
|
}
|