wave equation with periodic BC
This commit is contained in:
parent
4304c3e59d
commit
87ca45cbb8
29
main.js
29
main.js
|
@ -1,4 +1,4 @@
|
||||||
import { Universe, default as init } from "./webgl.js";
|
import { Universe, set_panic_hook, default as init } from "./webgl.js";
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
let wasm = await init("./webgl_bg.wasm");
|
let wasm = await init("./webgl_bg.wasm");
|
||||||
|
@ -84,21 +84,22 @@ async function run() {
|
||||||
|
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
|
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
|
||||||
|
|
||||||
|
set_panic_hook();
|
||||||
const width = 40;
|
const width = 40;
|
||||||
const height = 50;
|
const height = 50;
|
||||||
const universe = Universe.new(width, height);
|
let universes = [Universe.new(width, height), Universe.new(width, height)];
|
||||||
|
|
||||||
const t = performance.now();
|
let t = performance.now()/1000.0;
|
||||||
universe.set_initial(t/1000.0);
|
universes[0].set_initial(t);
|
||||||
|
|
||||||
|
|
||||||
const field = new Float32Array(wasm.memory.buffer,
|
const field = new Float32Array(wasm.memory.buffer,
|
||||||
universe.get_ptr(),
|
universes[0].get_ptr(),
|
||||||
width*height);
|
width*height);
|
||||||
|
|
||||||
const texture = gl.createTexture();
|
const texture = gl.createTexture();
|
||||||
{
|
{
|
||||||
|
gl.activeTexture(gl.TEXTURE0);
|
||||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||||
const level = 0;
|
const level = 0;
|
||||||
const internalFormat = gl.ALPHA;
|
const internalFormat = gl.ALPHA;
|
||||||
|
@ -132,15 +133,24 @@ async function run() {
|
||||||
gl.vertexAttribPointer(programInfo.attribLocations.vertexPosition, numComponents, type, normalise, stride, offset);
|
gl.vertexAttribPointer(programInfo.attribLocations.vertexPosition, numComponents, type, normalise, stride, offset);
|
||||||
gl.enableVertexAttribArray(programInfo.attribLocations.vertexPositions);
|
gl.enableVertexAttribArray(programInfo.attribLocations.vertexPositions);
|
||||||
}
|
}
|
||||||
|
{ // Binding uniforms
|
||||||
|
gl.uniform1i(programInfo.uniformLocation.sampler, 0);
|
||||||
|
}
|
||||||
|
|
||||||
function drawMe(t) {
|
|
||||||
|
function drawMe(t_draw) {
|
||||||
|
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
universe.set_initial(t/1000.0);
|
let dt = t_draw/1000.0 - t;
|
||||||
|
if (dt > 1.0) {
|
||||||
|
dt = 0.01;
|
||||||
|
}
|
||||||
|
t += dt;
|
||||||
|
universes[0].advance(universes[1], dt);
|
||||||
|
|
||||||
const field = new Float32Array(wasm.memory.buffer,
|
const field = new Float32Array(wasm.memory.buffer,
|
||||||
universe.get_ptr(),
|
universes[0].get_ptr(),
|
||||||
width*height);
|
width*height);
|
||||||
{
|
{
|
||||||
const level = 0;
|
const level = 0;
|
||||||
|
@ -155,6 +165,7 @@ async function run() {
|
||||||
const vertexCount = 4;
|
const vertexCount = 4;
|
||||||
gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount);
|
gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount);
|
||||||
|
|
||||||
|
universes = [universes[1], universes[0]];
|
||||||
window.requestAnimationFrame(drawMe);
|
window.requestAnimationFrame(drawMe);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
86
src/lib.rs
86
src/lib.rs
|
@ -1,24 +1,27 @@
|
||||||
use ndarray::Array2;
|
use ndarray::{Array2, ArrayView2, ArrayViewMut2};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
#[cfg(feature = "wee_alloc")]
|
#[cfg(feature = "wee_alloc")]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
|
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]
|
#[wasm_bindgen]
|
||||||
pub struct Universe {
|
pub struct Universe {
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
field: Array2<f32>,
|
e_x: Array2<f32>,
|
||||||
|
// e_y: Array2<f32>,
|
||||||
|
// h_z: Array2<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const WAVESPEED: f32 = 1.0;
|
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 {
|
fn func(x: f32, y: f32, t: f32) -> f32 {
|
||||||
use std::f32;
|
use std::f32;
|
||||||
(2.0 * f32::consts::PI * (x + y) - WAVESPEED * t).sin()
|
(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]
|
#[wasm_bindgen]
|
||||||
impl Universe {
|
impl Universe {
|
||||||
pub fn new(width: u32, height: u32) -> Self {
|
pub fn new(width: u32, height: u32) -> Self {
|
||||||
set_panic_hook();
|
|
||||||
|
|
||||||
let field = Array2::zeros((height as usize, width as usize));
|
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 {
|
Universe {
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
field,
|
e_x,
|
||||||
|
// e_y,
|
||||||
|
// h_z,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,12 +49,68 @@ impl Universe {
|
||||||
for i in 0..self.width {
|
for i in 0..self.width {
|
||||||
let x = i as f32 / self.width as f32;
|
let x = i as f32 / self.width as f32;
|
||||||
let y = j as f32 / self.height 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 {
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue