wave equation with periodic BC
This commit is contained in:
		
							
								
								
									
										86
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								src/lib.rs
									
									
									
									
									
								
							@@ -1,24 +1,27 @@
 | 
			
		||||
use ndarray::Array2;
 | 
			
		||||
use ndarray::{Array2, ArrayView2, ArrayViewMut2};
 | 
			
		||||
use wasm_bindgen::prelude::*;
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "wee_alloc")]
 | 
			
		||||
#[global_allocator]
 | 
			
		||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
 | 
			
		||||
 | 
			
		||||
pub fn set_panic_hook() {
 | 
			
		||||
    #[cfg(feature = "console_error_panic_hook")]
 | 
			
		||||
    console_error_panic_hook::set_once();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
pub struct Universe {
 | 
			
		||||
    width: u32,
 | 
			
		||||
    height: u32,
 | 
			
		||||
    field: Array2<f32>,
 | 
			
		||||
    e_x: Array2<f32>,
 | 
			
		||||
    // e_y: Array2<f32>,
 | 
			
		||||
    // h_z: Array2<f32>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const WAVESPEED: f32 = 1.0;
 | 
			
		||||
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
pub fn set_panic_hook() {
 | 
			
		||||
    #[cfg(feature = "console_error_panic_hook")]
 | 
			
		||||
    console_error_panic_hook::set_once();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn func(x: f32, y: f32, t: f32) -> f32 {
 | 
			
		||||
    use std::f32;
 | 
			
		||||
    (2.0 * f32::consts::PI * (x + y) - WAVESPEED * t).sin()
 | 
			
		||||
@@ -27,14 +30,17 @@ fn func(x: f32, y: f32, t: f32) -> f32 {
 | 
			
		||||
#[wasm_bindgen]
 | 
			
		||||
impl Universe {
 | 
			
		||||
    pub fn new(width: u32, height: u32) -> Self {
 | 
			
		||||
        set_panic_hook();
 | 
			
		||||
 | 
			
		||||
        let field = Array2::zeros((height as usize, width as usize));
 | 
			
		||||
        let e_x = field.clone();
 | 
			
		||||
        // let e_y = field.clone();
 | 
			
		||||
        // let h_z = field.clone();
 | 
			
		||||
 | 
			
		||||
        Universe {
 | 
			
		||||
            width,
 | 
			
		||||
            height,
 | 
			
		||||
            field,
 | 
			
		||||
            e_x,
 | 
			
		||||
            // e_y,
 | 
			
		||||
            // h_z,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -43,12 +49,68 @@ impl Universe {
 | 
			
		||||
            for i in 0..self.width {
 | 
			
		||||
                let x = i as f32 / self.width as f32;
 | 
			
		||||
                let y = j as f32 / self.height as f32;
 | 
			
		||||
                self.field[(j as usize, i as usize)] = func(x, y, t);
 | 
			
		||||
                self.e_x[(j as usize, i as usize)] = func(x, y, t);
 | 
			
		||||
                // self.e_y[(j as usize, i as usize)] = func(x, y, t);
 | 
			
		||||
                // self.h_z[(j as usize, i as usize)] = func(x, y, t);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn advance(&self, fut: &mut Universe, dt: f32) {
 | 
			
		||||
        assert_eq!(self.width, fut.width);
 | 
			
		||||
        assert_eq!(self.height, fut.height);
 | 
			
		||||
 | 
			
		||||
        fut.e_x.assign(&self.e_x);
 | 
			
		||||
 | 
			
		||||
        traditional4(self.e_x.view(), fut.e_x.view_mut(), dt);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_ptr(&mut self) -> *mut u8 {
 | 
			
		||||
        self.field.as_mut_ptr() as *mut u8
 | 
			
		||||
        self.e_x.as_mut_ptr() as *mut u8
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn traditional4(prev: ArrayView2<f32>, mut fut: ArrayViewMut2<f32>, dt: f32) {
 | 
			
		||||
    assert_eq!(prev.shape(), fut.shape());
 | 
			
		||||
    let nx = prev.shape()[1];
 | 
			
		||||
    let ny = prev.shape()[0];
 | 
			
		||||
 | 
			
		||||
    let dx = 1.0 / (nx - 1) as f32;
 | 
			
		||||
 | 
			
		||||
    let diag = [1.0 / 12.0, -2.0 / 3.0, 0.0, 2.0 / 3.0, -1.0 / 12.0];
 | 
			
		||||
 | 
			
		||||
    for j in 0..ny {
 | 
			
		||||
        let diff = diag[0] * prev[(j, nx - 2)]
 | 
			
		||||
            + diag[1] * prev[(j, nx - 1)]
 | 
			
		||||
            + diag[2] * prev[(j, 0)]
 | 
			
		||||
            + diag[3] * prev[(j, 1)]
 | 
			
		||||
            + diag[4] * prev[(j, 2)];
 | 
			
		||||
        fut[(j, 0)] += dt / dx * diff;
 | 
			
		||||
        let diff = diag[0] * prev[(j, nx - 1)]
 | 
			
		||||
            + diag[1] * prev[(j, 0)]
 | 
			
		||||
            + diag[2] * prev[(j, 1)]
 | 
			
		||||
            + diag[3] * prev[(j, 2)]
 | 
			
		||||
            + diag[4] * prev[(j, 3)];
 | 
			
		||||
        fut[(j, 1)] += dt / dx * diff;
 | 
			
		||||
        for i in 2..nx - 2 {
 | 
			
		||||
            let diff = diag[0] * prev[(j, i - 2)]
 | 
			
		||||
                + diag[1] * prev[(j, i - 1)]
 | 
			
		||||
                + diag[2] * prev[(j, i)]
 | 
			
		||||
                + diag[3] * prev[(j, i + 1)]
 | 
			
		||||
                + diag[4] * prev[(j, i + 2)];
 | 
			
		||||
            fut[(j, i)] += dt / dx * diff;
 | 
			
		||||
        }
 | 
			
		||||
        let diff = diag[0] * prev[(j, nx - 4)]
 | 
			
		||||
            + diag[1] * prev[(j, nx - 3)]
 | 
			
		||||
            + diag[2] * prev[(j, nx - 2)]
 | 
			
		||||
            + diag[3] * prev[(j, nx - 1)]
 | 
			
		||||
            + diag[4] * prev[(j, 0)];
 | 
			
		||||
        fut[(j, nx - 2)] += dt / dx * diff;
 | 
			
		||||
        let diff = diag[0] * prev[(j, nx - 3)]
 | 
			
		||||
            + diag[1] * prev[(j, nx - 2)]
 | 
			
		||||
            + diag[2] * prev[(j, nx - 1)]
 | 
			
		||||
            + diag[3] * prev[(j, 0)]
 | 
			
		||||
            + diag[4] * prev[(j, 1)];
 | 
			
		||||
        fut[(j, nx - 1)] += dt / dx * diff;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user