arbitrary grids
This commit is contained in:
		
							
								
								
									
										68
									
								
								src/grid.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/grid.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
use ndarray::Array2;
 | 
			
		||||
pub struct Grid<SBP>
 | 
			
		||||
where
 | 
			
		||||
    SBP: super::operators::SbpOperator,
 | 
			
		||||
{
 | 
			
		||||
    pub(crate) x: Array2<f32>,
 | 
			
		||||
    pub(crate) y: Array2<f32>,
 | 
			
		||||
 | 
			
		||||
    pub(crate) detj: Array2<f32>,
 | 
			
		||||
    pub(crate) detj_dxi_dx: Array2<f32>,
 | 
			
		||||
    pub(crate) detj_dxi_dy: Array2<f32>,
 | 
			
		||||
    pub(crate) detj_deta_dx: Array2<f32>,
 | 
			
		||||
    pub(crate) detj_deta_dy: Array2<f32>,
 | 
			
		||||
 | 
			
		||||
    operator: std::marker::PhantomData<SBP>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<SBP: super::operators::SbpOperator> Grid<SBP> {
 | 
			
		||||
    pub fn new(width: u32, height: u32, x: &[f32], y: &[f32]) -> Result<Self, ndarray::ShapeError> {
 | 
			
		||||
        let nx = width as usize;
 | 
			
		||||
        let ny = height as usize;
 | 
			
		||||
        let x = Array2::from_shape_vec((ny, nx), x.to_vec())?;
 | 
			
		||||
        let y = Array2::from_shape_vec((ny, nx), y.to_vec())?;
 | 
			
		||||
 | 
			
		||||
        let mut dx_dxi = Array2::zeros((ny, nx));
 | 
			
		||||
        SBP::diffxi(x.view(), dx_dxi.view_mut());
 | 
			
		||||
        let mut dx_deta = Array2::zeros((ny, nx));
 | 
			
		||||
        SBP::diffeta(x.view(), dx_deta.view_mut());
 | 
			
		||||
        let mut dy_dxi = Array2::zeros((ny, nx));
 | 
			
		||||
        SBP::diffxi(y.view(), dy_dxi.view_mut());
 | 
			
		||||
        let mut dy_deta = Array2::zeros((ny, nx));
 | 
			
		||||
        SBP::diffeta(y.view(), dy_deta.view_mut());
 | 
			
		||||
 | 
			
		||||
        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 {
 | 
			
		||||
            x,
 | 
			
		||||
            y,
 | 
			
		||||
            detj,
 | 
			
		||||
            detj_dxi_dx,
 | 
			
		||||
            detj_dxi_dy,
 | 
			
		||||
            detj_deta_dx,
 | 
			
		||||
            detj_deta_dy,
 | 
			
		||||
            operator: std::marker::PhantomData,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										20
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/lib.rs
									
									
									
									
									
								
							@@ -1,8 +1,10 @@
 | 
			
		||||
use wasm_bindgen::prelude::*;
 | 
			
		||||
 | 
			
		||||
mod grid;
 | 
			
		||||
mod maxwell;
 | 
			
		||||
mod operators;
 | 
			
		||||
pub use crate::maxwell::{System, WorkBuffers};
 | 
			
		||||
pub(crate) use grid::Grid;
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "wee_alloc")]
 | 
			
		||||
#[global_allocator]
 | 
			
		||||
@@ -18,14 +20,22 @@ pub fn set_panic_hook() {
 | 
			
		||||
pub struct Universe {
 | 
			
		||||
    sys: (System, System),
 | 
			
		||||
    wb: WorkBuffers,
 | 
			
		||||
    grid: Grid<operators::Upwind4>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
impl Universe {
 | 
			
		||||
    #[wasm_bindgen(constructor)]
 | 
			
		||||
    pub fn new(width: u32, height: u32) -> Self {
 | 
			
		||||
    pub fn new(width: u32, height: u32, x: &[f32], y: &[f32]) -> Self {
 | 
			
		||||
        assert_eq!((width * height) as usize, x.len());
 | 
			
		||||
        assert_eq!((width * height) as usize, y.len());
 | 
			
		||||
 | 
			
		||||
        let grid = Grid::new(width, height, x, y).expect(
 | 
			
		||||
            "Could not create grid. Different number of elements compared to width*height?",
 | 
			
		||||
        );
 | 
			
		||||
        Self {
 | 
			
		||||
            sys: (System::new(width, height), System::new(width, height)),
 | 
			
		||||
            grid,
 | 
			
		||||
            wb: WorkBuffers::new(width as usize, height as usize),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -35,7 +45,13 @@ impl Universe {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn advance(&mut self, dt: f32) {
 | 
			
		||||
        System::advance::<operators::Upwind4>(&self.sys.0, &mut self.sys.1, dt, Some(&mut self.wb));
 | 
			
		||||
        System::advance::<operators::Upwind4>(
 | 
			
		||||
            &self.sys.0,
 | 
			
		||||
            &mut self.sys.1,
 | 
			
		||||
            dt,
 | 
			
		||||
            &self.grid,
 | 
			
		||||
            Some(&mut self.wb),
 | 
			
		||||
        );
 | 
			
		||||
        std::mem::swap(&mut self.sys.0, &mut self.sys.1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										234
									
								
								src/maxwell.rs
									
									
									
									
									
								
							
							
						
						
									
										234
									
								
								src/maxwell.rs
									
									
									
									
									
								
							@@ -43,18 +43,23 @@ impl System {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn advance<SBP>(&self, fut: &mut Self, dt: f32, work_buffers: Option<&mut WorkBuffers>)
 | 
			
		||||
    where
 | 
			
		||||
    pub(crate) fn advance<SBP>(
 | 
			
		||||
        &self,
 | 
			
		||||
        fut: &mut Self,
 | 
			
		||||
        dt: f32,
 | 
			
		||||
        grid: &super::Grid<SBP>,
 | 
			
		||||
        work_buffers: Option<&mut WorkBuffers>,
 | 
			
		||||
    ) where
 | 
			
		||||
        SBP: SbpOperator,
 | 
			
		||||
    {
 | 
			
		||||
        assert_eq!(self.ex.shape(), fut.ex.shape());
 | 
			
		||||
 | 
			
		||||
        let mut wb: WorkBuffers;
 | 
			
		||||
        let (y, k) = if let Some(x) = work_buffers {
 | 
			
		||||
            (&mut x.y, &mut x.buf)
 | 
			
		||||
        let (y, k, tmp) = if let Some(x) = work_buffers {
 | 
			
		||||
            (&mut x.y, &mut x.buf, &mut x.tmp)
 | 
			
		||||
        } else {
 | 
			
		||||
            wb = WorkBuffers::new(self.ex.shape()[1], self.ex.shape()[0]);
 | 
			
		||||
            (&mut wb.y, &mut wb.buf)
 | 
			
		||||
            (&mut wb.y, &mut wb.buf, &mut wb.tmp)
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        for i in 0..4 {
 | 
			
		||||
@@ -79,18 +84,86 @@ impl System {
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // hz = -ey_x + ex_y
 | 
			
		||||
            let tmp = &mut k[i].0;
 | 
			
		||||
            SBP::diffxi(y.2.view(), tmp.view_mut());
 | 
			
		||||
            SBP::diffeta(y.0.view(), k[i].1.view_mut());
 | 
			
		||||
            k[i].1.scaled_add(-1.0, tmp);
 | 
			
		||||
            // Solving (Au)_x + (Bu)_y
 | 
			
		||||
            // with:
 | 
			
		||||
            //        A               B
 | 
			
		||||
            //  [ 0,  0,  0]    [ 0,  1,  0]
 | 
			
		||||
            //  [ 0,  0, -1]    [ 1,  0,  0]
 | 
			
		||||
            //  [ 0, -1,  0]    [ 0,  0,  0]
 | 
			
		||||
 | 
			
		||||
            // This flux is rotated by the grid metrics
 | 
			
		||||
            // (Au)_x + (Bu)_y = 1/J [
 | 
			
		||||
            //          (J xi_x Au)_xi + (J eta_x Au)_eta
 | 
			
		||||
            //          (J xi_y Bu)_xi + (J eta_y Bu)_eta
 | 
			
		||||
            //      ]
 | 
			
		||||
            // where J is the grid determinant
 | 
			
		||||
 | 
			
		||||
            // ex = hz_y
 | 
			
		||||
            SBP::diffeta(y.1.view(), k[i].0.view_mut());
 | 
			
		||||
            {
 | 
			
		||||
                ndarray::azip!((a in &mut tmp.0,
 | 
			
		||||
                                &dxi_dy in &grid.detj_dxi_dy,
 | 
			
		||||
                                &hz in &y.1)
 | 
			
		||||
                    *a = dxi_dy * hz
 | 
			
		||||
                );
 | 
			
		||||
                SBP::diffxi(tmp.0.view(), tmp.1.view_mut());
 | 
			
		||||
 | 
			
		||||
                ndarray::azip!((b in &mut tmp.2,
 | 
			
		||||
                                &deta_dy in &grid.detj_deta_dy,
 | 
			
		||||
                                &hz in &y.1)
 | 
			
		||||
                    *b = deta_dy * hz
 | 
			
		||||
                );
 | 
			
		||||
                SBP::diffeta(tmp.2.view(), tmp.3.view_mut());
 | 
			
		||||
 | 
			
		||||
                ndarray::azip!((flux in &mut k[i].0, &ax in &tmp.1, &by in &tmp.3)
 | 
			
		||||
                    *flux = ax + by
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            {
 | 
			
		||||
                // hz = -ey_x + ex_y
 | 
			
		||||
                ndarray::azip!((a in &mut tmp.0,
 | 
			
		||||
                                &dxi_dx in &grid.detj_dxi_dx,
 | 
			
		||||
                                &dxi_dy in &grid.detj_dxi_dy,
 | 
			
		||||
                                &ex in &y.0,
 | 
			
		||||
                                &ey in &y.2)
 | 
			
		||||
                    *a = dxi_dx * -ey + dxi_dy * ex
 | 
			
		||||
                );
 | 
			
		||||
                SBP::diffxi(tmp.0.view(), tmp.1.view_mut());
 | 
			
		||||
 | 
			
		||||
                ndarray::azip!((b in &mut tmp.2,
 | 
			
		||||
                                &deta_dx in &grid.detj_deta_dx,
 | 
			
		||||
                                &deta_dy in &grid.detj_deta_dy,
 | 
			
		||||
                                &ex in &y.0,
 | 
			
		||||
                                &ey in &y.2)
 | 
			
		||||
                    *b = deta_dx * -ey + deta_dy * ex
 | 
			
		||||
                );
 | 
			
		||||
                SBP::diffeta(tmp.2.view(), tmp.3.view_mut());
 | 
			
		||||
 | 
			
		||||
                ndarray::azip!((flux in &mut k[i].1, &ax in &tmp.1, &by in &tmp.3)
 | 
			
		||||
                    *flux = ax + by
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // ey = -hz_x
 | 
			
		||||
            SBP::diffxi(y.1.view(), k[i].2.view_mut());
 | 
			
		||||
            k[i].2.mapv_inplace(|v| -v);
 | 
			
		||||
            {
 | 
			
		||||
                ndarray::azip!((a in &mut tmp.0,
 | 
			
		||||
                                &dxi_dx in &grid.detj_dxi_dx,
 | 
			
		||||
                                &hz in &y.1)
 | 
			
		||||
                    *a = dxi_dx * -hz
 | 
			
		||||
                );
 | 
			
		||||
                SBP::diffxi(tmp.0.view(), tmp.1.view_mut());
 | 
			
		||||
 | 
			
		||||
                ndarray::azip!((b in &mut tmp.2,
 | 
			
		||||
                                &deta_dx in &grid.detj_deta_dx,
 | 
			
		||||
                                &hz in &y.1)
 | 
			
		||||
                    *b = deta_dx * -hz
 | 
			
		||||
                );
 | 
			
		||||
                SBP::diffeta(tmp.2.view(), tmp.3.view_mut());
 | 
			
		||||
 | 
			
		||||
                ndarray::azip!((flux in &mut k[i].2, &ax in &tmp.1, &by in &tmp.3)
 | 
			
		||||
                    *flux = ax + by
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Boundary conditions (SAT)
 | 
			
		||||
            let ny = y.0.shape()[0];
 | 
			
		||||
@@ -98,48 +171,139 @@ impl System {
 | 
			
		||||
 | 
			
		||||
            let hinv = 1.0 / (SBP::h()[0] / (nx - 1) as f32);
 | 
			
		||||
 | 
			
		||||
            fn positive_flux(kx: f32, ky: f32) -> [[f32; 3]; 3] {
 | 
			
		||||
                let r = (kx * kx + ky * ky).sqrt();
 | 
			
		||||
                [
 | 
			
		||||
                    [ky * ky / r / 2.0, ky / 2.0, -kx * ky / r / 2.0],
 | 
			
		||||
                    [ky / 2.0, r / 2.0, -kx / 2.0],
 | 
			
		||||
                    [-kx * ky / r / 2.0, -kx / 2.0, kx * kx / r / 2.0],
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
            fn negative_flux(kx: f32, ky: f32) -> [[f32; 3]; 3] {
 | 
			
		||||
                let r = (kx * kx + ky * ky).sqrt();
 | 
			
		||||
                [
 | 
			
		||||
                    [-ky * ky / r / 2.0, ky / 2.0, kx * ky / r / 2.0],
 | 
			
		||||
                    [ky / 2.0, -r / 2.0, -kx / 2.0],
 | 
			
		||||
                    [kx * ky / r / 2.0, -kx / 2.0, -kx * kx / r / 2.0],
 | 
			
		||||
                ]
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for j in 0..ny {
 | 
			
		||||
                // East boundary
 | 
			
		||||
                // East boundary, positive flux
 | 
			
		||||
                let tau = -1.0;
 | 
			
		||||
                let g = (y.0[(j, 0)], y.1[(j, 0)], y.2[(j, 0)]);
 | 
			
		||||
                let v = (y.0[(j, nx - 1)], y.1[(j, nx - 1)], y.2[(j, nx - 1)]);
 | 
			
		||||
 | 
			
		||||
                // A+ = (0, 0, 0; 0, 1/2, -1/2; 0, -1/2, 1/2);
 | 
			
		||||
                // k[i].0[(j, nx - 1)] += 0.0;
 | 
			
		||||
                k[i].1[(j, nx - 1)] += tau * hinv * (0.5 * (v.1 - g.1) - 0.5 * (v.2 - g.2));
 | 
			
		||||
                k[i].2[(j, nx - 1)] += tau * hinv * (-0.5 * (v.1 - g.1) + 0.5 * (v.2 - g.2));
 | 
			
		||||
                let kx = grid.detj_dxi_dx[(j, nx - 1)];
 | 
			
		||||
                let ky = grid.detj_dxi_dy[(j, nx - 1)];
 | 
			
		||||
 | 
			
		||||
                // West boundary
 | 
			
		||||
                let plus = positive_flux(kx, ky);
 | 
			
		||||
 | 
			
		||||
                k[i].0[(j, nx - 1)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (plus[0][0] * (v.0 - g.0)
 | 
			
		||||
                        + plus[0][1] * (v.1 - g.1)
 | 
			
		||||
                        + plus[0][2] * (v.2 - g.2));
 | 
			
		||||
                k[i].1[(j, nx - 1)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (plus[1][0] * (v.0 - g.0)
 | 
			
		||||
                        + plus[1][1] * (v.1 - g.1)
 | 
			
		||||
                        + plus[1][2] * (v.2 - g.2));
 | 
			
		||||
                k[i].2[(j, nx - 1)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (plus[2][0] * (v.0 - g.0)
 | 
			
		||||
                        + plus[2][1] * (v.1 - g.1)
 | 
			
		||||
                        + plus[2][2] * (v.2 - g.2));
 | 
			
		||||
 | 
			
		||||
                // West boundary, negative flux
 | 
			
		||||
                let tau = 1.0;
 | 
			
		||||
                let (v, g) = (g, v);
 | 
			
		||||
                // A- = (0, 0, 0; 0, -1/2, -1/2; 0, -1/2, -1/2);
 | 
			
		||||
                // k[i].0[(j, 0)] += 0.0;
 | 
			
		||||
                k[i].1[(j, 0)] += tau * hinv * (-0.5 * (v.1 - g.1) - 0.5 * (v.2 - g.2));
 | 
			
		||||
                k[i].2[(j, 0)] += tau * hinv * (-0.5 * (v.1 - g.1) - 0.5 * (v.2 - g.2));
 | 
			
		||||
 | 
			
		||||
                let kx = grid.detj_dxi_dx[(j, 0)];
 | 
			
		||||
                let ky = grid.detj_dxi_dy[(j, 0)];
 | 
			
		||||
 | 
			
		||||
                let minus = negative_flux(kx, ky);
 | 
			
		||||
 | 
			
		||||
                k[i].0[(j, 0)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (minus[0][0] * (v.0 - g.0)
 | 
			
		||||
                        + minus[0][1] * (v.1 - g.1)
 | 
			
		||||
                        + minus[0][2] * (v.2 - g.2));
 | 
			
		||||
                k[i].1[(j, 0)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (minus[1][0] * (v.0 - g.0)
 | 
			
		||||
                        + minus[1][1] * (v.1 - g.1)
 | 
			
		||||
                        + minus[1][2] * (v.2 - g.2));
 | 
			
		||||
                k[i].2[(j, 0)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (minus[2][0] * (v.0 - g.0)
 | 
			
		||||
                        + minus[2][1] * (v.1 - g.1)
 | 
			
		||||
                        + minus[2][2] * (v.2 - g.2));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let hinv = 1.0 / (SBP::h()[0] / (ny - 1) as f32);
 | 
			
		||||
 | 
			
		||||
            for j in 0..nx {
 | 
			
		||||
                // North boundary
 | 
			
		||||
                // North boundary, positive flux
 | 
			
		||||
                let tau = -1.0;
 | 
			
		||||
                let g = (y.0[(0, j)], y.1[(0, j)], y.2[(0, j)]);
 | 
			
		||||
                let v = (y.0[(ny - 1, j)], y.1[(ny - 1, j)], y.2[(ny - 1, j)]);
 | 
			
		||||
 | 
			
		||||
                // B+ = (1/2, 1/2, 0; 1/2, 1/2, 0; 0, 0, 0)
 | 
			
		||||
                k[i].0[(ny - 1, j)] += tau * hinv * (0.5 * (v.0 - g.0) + 0.5 * (v.1 - g.1));
 | 
			
		||||
                k[i].1[(ny - 1, j)] += tau * hinv * (0.5 * (v.0 - g.0) + 0.5 * (v.1 - g.1));
 | 
			
		||||
                // k[i].2[(ny - 1, j)] += 0.0;
 | 
			
		||||
                let kx = grid.detj_deta_dx[(ny - 1, j)];
 | 
			
		||||
                let ky = grid.detj_deta_dy[(ny - 1, j)];
 | 
			
		||||
 | 
			
		||||
                // South boundary
 | 
			
		||||
                let plus = positive_flux(kx, ky);
 | 
			
		||||
 | 
			
		||||
                k[i].0[(ny - 1, j)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (plus[0][0] * (v.0 - g.0)
 | 
			
		||||
                        + plus[0][1] * (v.1 - g.1)
 | 
			
		||||
                        + plus[0][2] * (v.2 - g.2));
 | 
			
		||||
                k[i].1[(ny - 1, j)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (plus[1][0] * (v.0 - g.0)
 | 
			
		||||
                        + plus[1][1] * (v.1 - g.1)
 | 
			
		||||
                        + plus[1][2] * (v.2 - g.2));
 | 
			
		||||
                k[i].2[(ny - 1, j)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (plus[2][0] * (v.0 - g.0)
 | 
			
		||||
                        + plus[2][1] * (v.1 - g.1)
 | 
			
		||||
                        + plus[2][2] * (v.2 - g.2));
 | 
			
		||||
 | 
			
		||||
                // South boundary, negative flux
 | 
			
		||||
                let tau = 1.0;
 | 
			
		||||
                let (g, v) = (v, g);
 | 
			
		||||
 | 
			
		||||
                // B- = (-1/2, 1/2, 0; 1/2, -1/2, 0; 0, 0, 0);
 | 
			
		||||
                k[i].0[(0, j)] += tau * hinv * (-0.5 * (v.0 - g.0) + 0.5 * (v.1 - g.1));
 | 
			
		||||
                k[i].1[(0, j)] += tau * hinv * (0.5 * (v.0 - g.0) - 0.5 * (v.1 - g.1));
 | 
			
		||||
                // k[i].2[(0, j)] += 0.0;
 | 
			
		||||
                let kx = grid.detj_deta_dx[(0, j)];
 | 
			
		||||
                let ky = grid.detj_deta_dy[(0, j)];
 | 
			
		||||
 | 
			
		||||
                let minus = negative_flux(kx, ky);
 | 
			
		||||
 | 
			
		||||
                k[i].0[(0, j)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (minus[0][0] * (v.0 - g.0)
 | 
			
		||||
                        + minus[0][1] * (v.1 - g.1)
 | 
			
		||||
                        + minus[0][2] * (v.2 - g.2));
 | 
			
		||||
                k[i].1[(0, j)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (minus[1][0] * (v.0 - g.0)
 | 
			
		||||
                        + minus[1][1] * (v.1 - g.1)
 | 
			
		||||
                        + minus[1][2] * (v.2 - g.2));
 | 
			
		||||
                k[i].2[(0, j)] += tau
 | 
			
		||||
                    * hinv
 | 
			
		||||
                    * (minus[2][0] * (v.0 - g.0)
 | 
			
		||||
                        + minus[2][1] * (v.1 - g.1)
 | 
			
		||||
                        + minus[2][2] * (v.2 - g.2));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ndarray::azip!((k0 in &mut k[i].0,
 | 
			
		||||
                            k1 in &mut k[i].1,
 | 
			
		||||
                            k2 in &mut k[i].2,
 | 
			
		||||
                            &detj in &grid.detj) {
 | 
			
		||||
                *k0 /= detj;
 | 
			
		||||
                *k1 /= detj;
 | 
			
		||||
                *k2 /= detj;
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Zip::from(&mut fut.ex)
 | 
			
		||||
@@ -175,6 +339,7 @@ impl System {
 | 
			
		||||
pub struct WorkBuffers {
 | 
			
		||||
    y: (Array2<f32>, Array2<f32>, Array2<f32>),
 | 
			
		||||
    buf: [(Array2<f32>, Array2<f32>, Array2<f32>); 4],
 | 
			
		||||
    tmp: (Array2<f32>, Array2<f32>, Array2<f32>, Array2<f32>),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WorkBuffers {
 | 
			
		||||
@@ -186,8 +351,9 @@ impl WorkBuffers {
 | 
			
		||||
                (arr.clone(), arr.clone(), arr.clone()),
 | 
			
		||||
                (arr.clone(), arr.clone(), arr.clone()),
 | 
			
		||||
                (arr.clone(), arr.clone(), arr.clone()),
 | 
			
		||||
                (arr.clone(), arr.clone(), arr),
 | 
			
		||||
                (arr.clone(), arr.clone(), arr.clone()),
 | 
			
		||||
            ],
 | 
			
		||||
            tmp: (arr.clone(), arr.clone(), arr.clone(), arr),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user