2020-04-15 15:47:17 +00:00
|
|
|
use super::operators::SbpOperator2d;
|
2020-02-27 19:26:43 +00:00
|
|
|
use crate::Float;
|
2019-12-10 21:03:42 +00:00
|
|
|
use ndarray::Array2;
|
2020-01-28 18:31:14 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
2020-04-03 22:29:02 +00:00
|
|
|
pub struct Grid {
|
2020-02-27 19:26:43 +00:00
|
|
|
pub(crate) x: Array2<Float>,
|
|
|
|
pub(crate) y: Array2<Float>,
|
2020-04-03 22:29:02 +00:00
|
|
|
}
|
2019-12-10 21:03:42 +00:00
|
|
|
|
2020-04-03 22:29:02 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2020-04-14 19:59:02 +00:00
|
|
|
pub struct Metrics {
|
2020-02-27 19:26:43 +00:00
|
|
|
pub(crate) detj: Array2<Float>,
|
|
|
|
pub(crate) detj_dxi_dx: Array2<Float>,
|
|
|
|
pub(crate) detj_dxi_dy: Array2<Float>,
|
|
|
|
pub(crate) detj_deta_dx: Array2<Float>,
|
|
|
|
pub(crate) detj_deta_dy: Array2<Float>,
|
2019-12-10 21:03:42 +00:00
|
|
|
}
|
|
|
|
|
2020-04-03 22:29:02 +00:00
|
|
|
impl Grid {
|
2020-02-27 19:26:43 +00:00
|
|
|
pub fn new(x: Array2<Float>, y: Array2<Float>) -> Result<Self, ndarray::ShapeError> {
|
2020-01-25 19:40:55 +00:00
|
|
|
assert_eq!(x.shape(), y.shape());
|
2020-04-03 22:29:02 +00:00
|
|
|
|
|
|
|
Ok(Self { x, y })
|
|
|
|
}
|
|
|
|
pub fn nx(&self) -> usize {
|
|
|
|
self.x.shape()[1]
|
|
|
|
}
|
|
|
|
pub fn ny(&self) -> usize {
|
|
|
|
self.x.shape()[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn x(&self) -> ndarray::ArrayView2<Float> {
|
|
|
|
self.x.view()
|
|
|
|
}
|
|
|
|
pub fn y(&self) -> ndarray::ArrayView2<Float> {
|
|
|
|
self.y.view()
|
|
|
|
}
|
|
|
|
|
2020-04-15 15:47:17 +00:00
|
|
|
pub fn metrics(&self, op: &dyn SbpOperator2d) -> Result<Metrics, ndarray::ShapeError> {
|
2020-04-14 22:12:54 +00:00
|
|
|
Metrics::new(self, op)
|
2020-04-03 22:29:02 +00:00
|
|
|
}
|
2020-04-06 20:11:35 +00:00
|
|
|
|
|
|
|
pub fn north(&self) -> (ndarray::ArrayView1<Float>, ndarray::ArrayView1<Float>) {
|
|
|
|
(
|
|
|
|
self.y.slice(ndarray::s![self.ny() - 1, ..]),
|
|
|
|
self.x.slice(ndarray::s![self.ny() - 1, ..]),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
pub fn south(&self) -> (ndarray::ArrayView1<Float>, ndarray::ArrayView1<Float>) {
|
|
|
|
(
|
|
|
|
self.y.slice(ndarray::s![0, ..]),
|
|
|
|
self.x.slice(ndarray::s![0, ..]),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
pub fn west(&self) -> (ndarray::ArrayView1<Float>, ndarray::ArrayView1<Float>) {
|
|
|
|
(
|
|
|
|
self.y.slice(ndarray::s![.., 0]),
|
|
|
|
self.x.slice(ndarray::s![.., 0]),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
pub fn east(&self) -> (ndarray::ArrayView1<Float>, ndarray::ArrayView1<Float>) {
|
|
|
|
(
|
|
|
|
self.y.slice(ndarray::s![.., self.nx() - 1]),
|
|
|
|
self.x.slice(ndarray::s![.., self.nx() - 1]),
|
|
|
|
)
|
|
|
|
}
|
2020-04-03 22:29:02 +00:00
|
|
|
}
|
|
|
|
|
2020-04-14 19:59:02 +00:00
|
|
|
impl Metrics {
|
2020-04-15 15:47:17 +00:00
|
|
|
fn new(grid: &Grid, op: &dyn SbpOperator2d) -> Result<Self, ndarray::ShapeError> {
|
2020-04-03 22:29:02 +00:00
|
|
|
let ny = grid.ny();
|
|
|
|
let nx = grid.nx();
|
|
|
|
let x = &grid.x;
|
|
|
|
let y = &grid.y;
|
2019-12-10 21:03:42 +00:00
|
|
|
|
|
|
|
let mut dx_dxi = Array2::zeros((ny, nx));
|
2020-04-14 22:12:54 +00:00
|
|
|
op.diffxi(x.view(), dx_dxi.view_mut());
|
2019-12-10 21:03:42 +00:00
|
|
|
let mut dx_deta = Array2::zeros((ny, nx));
|
2020-04-14 22:12:54 +00:00
|
|
|
op.diffeta(x.view(), dx_deta.view_mut());
|
2019-12-10 21:03:42 +00:00
|
|
|
let mut dy_dxi = Array2::zeros((ny, nx));
|
2020-04-14 22:12:54 +00:00
|
|
|
op.diffxi(y.view(), dy_dxi.view_mut());
|
2019-12-10 21:03:42 +00:00
|
|
|
let mut dy_deta = Array2::zeros((ny, nx));
|
2020-04-14 22:12:54 +00:00
|
|
|
op.diffeta(y.view(), dy_deta.view_mut());
|
2019-12-10 21:03:42 +00:00
|
|
|
|
|
|
|
let mut detj = Array2::zeros((ny, nx));
|
|
|
|
ndarray::azip!((detj in &mut detj,
|
|
|
|
&dx_dxi in &dx_dxi,
|
|
|
|
&dx_deta in &dx_deta,
|
|
|
|
&dy_dxi in &dy_dxi,
|
|
|
|
&dy_deta in &dy_deta) {
|
|
|
|
*detj = dx_dxi * dy_deta - dx_deta * dy_dxi;
|
|
|
|
assert!(*detj > 0.0);
|
|
|
|
});
|
|
|
|
|
|
|
|
let detj_dxi_dx = dy_deta;
|
|
|
|
let detj_dxi_dy = {
|
|
|
|
let mut dx_deta = dx_deta;
|
|
|
|
dx_deta.mapv_inplace(|v| -v);
|
|
|
|
dx_deta
|
|
|
|
};
|
|
|
|
let detj_deta_dx = {
|
|
|
|
let mut dy_dxi = dy_dxi;
|
|
|
|
dy_dxi.mapv_inplace(|v| -v);
|
|
|
|
dy_dxi
|
|
|
|
};
|
|
|
|
let detj_deta_dy = dx_dxi;
|
|
|
|
|
|
|
|
Ok(Self {
|
|
|
|
detj,
|
|
|
|
detj_dxi_dx,
|
|
|
|
detj_dxi_dy,
|
|
|
|
detj_deta_dx,
|
|
|
|
detj_deta_dy,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|