diff --git a/Cargo.toml b/Cargo.toml index 4dd035f..2283b6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,38 +1,15 @@ [package] -name = "sbp" +name = "diffsolver" version = "0.1.1" authors = ["Magnus Ulimoen "] edition = "2018" -[lib] -crate-type = ["cdylib", "rlib"] -[features] -default = ["console_error_panic_hook", "wee_alloc"] - -[dependencies] -wasm-bindgen = "0.2.54" -console_error_panic_hook = { version = "0.1.6", optional = true } -wee_alloc = { version = "0.4.5", optional = true } -ndarray = { version = "0.13.0", features = ["approx"] } -approx = "0.3.2" -packed_simd = "0.3.3" - -[profile.release] -opt-level = 3 -lto = "thin" -debug = true - -[dev-dependencies] -criterion = "0.3.0" - -[[bench]] -name = "maxwell" -harness = false - -[[bench]] -name = "euler" -harness = false +[workspace] +members = [ + "sbp", + "webfront", +] [profile.bench] debug = true diff --git a/sbp/Cargo.toml b/sbp/Cargo.toml new file mode 100644 index 0000000..baf1545 --- /dev/null +++ b/sbp/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "sbp" +version = "0.1.1" +authors = ["Magnus Ulimoen "] +edition = "2018" + +[dependencies] +ndarray = { version = "0.13.0", features = ["approx"] } +approx = "0.3.2" +packed_simd = "0.3.3" + +[dev-dependencies] +criterion = "0.3.0" + +[[bench]] +name = "maxwell" +harness = false + +[[bench]] +name = "euler" +harness = false diff --git a/benches/euler.rs b/sbp/benches/euler.rs similarity index 100% rename from benches/euler.rs rename to sbp/benches/euler.rs diff --git a/benches/maxwell.rs b/sbp/benches/maxwell.rs similarity index 100% rename from benches/maxwell.rs rename to sbp/benches/maxwell.rs diff --git a/src/euler.rs b/sbp/src/euler.rs similarity index 99% rename from src/euler.rs rename to sbp/src/euler.rs index 86b0614..44c38d4 100644 --- a/src/euler.rs +++ b/sbp/src/euler.rs @@ -1,6 +1,6 @@ +use super::grid::Grid; use super::integrate; use super::operators::{SbpOperator, UpwindOperator}; -use super::Grid; use ndarray::azip; use ndarray::prelude::*; diff --git a/src/grid.rs b/sbp/src/grid.rs similarity index 100% rename from src/grid.rs rename to sbp/src/grid.rs diff --git a/src/integrate.rs b/sbp/src/integrate.rs similarity index 100% rename from src/integrate.rs rename to sbp/src/integrate.rs diff --git a/sbp/src/lib.rs b/sbp/src/lib.rs new file mode 100644 index 0000000..b1b7b8a --- /dev/null +++ b/sbp/src/lib.rs @@ -0,0 +1,5 @@ +pub mod euler; +pub mod grid; +pub mod integrate; +pub mod maxwell; +pub mod operators; diff --git a/src/maxwell.rs b/sbp/src/maxwell.rs similarity index 99% rename from src/maxwell.rs rename to sbp/src/maxwell.rs index e021d99..3e98063 100644 --- a/src/maxwell.rs +++ b/sbp/src/maxwell.rs @@ -1,6 +1,6 @@ +use super::grid::Grid; use super::integrate; use super::operators::{SbpOperator, UpwindOperator}; -use super::Grid; use ndarray::azip; use ndarray::prelude::*; diff --git a/src/operators.rs b/sbp/src/operators.rs similarity index 100% rename from src/operators.rs rename to sbp/src/operators.rs diff --git a/src/operators/traditional4.rs b/sbp/src/operators/traditional4.rs similarity index 100% rename from src/operators/traditional4.rs rename to sbp/src/operators/traditional4.rs diff --git a/src/operators/traditional8.rs b/sbp/src/operators/traditional8.rs similarity index 100% rename from src/operators/traditional8.rs rename to sbp/src/operators/traditional8.rs diff --git a/src/operators/upwind4.rs b/sbp/src/operators/upwind4.rs similarity index 100% rename from src/operators/upwind4.rs rename to sbp/src/operators/upwind4.rs diff --git a/src/operators/upwind9.rs b/sbp/src/operators/upwind9.rs similarity index 100% rename from src/operators/upwind9.rs rename to sbp/src/operators/upwind9.rs diff --git a/src/lib.rs b/src/lib.rs index 6a1ed01..e69de29 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,125 +0,0 @@ -use wasm_bindgen::prelude::*; - -pub mod euler; -mod grid; -pub(crate) mod integrate; -pub mod maxwell; -pub mod operators; -pub(crate) use grid::Grid; - -#[cfg(feature = "wee_alloc")] -#[global_allocator] -static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; - -#[wasm_bindgen] -pub fn set_panic_hook() { - #[cfg(feature = "console_error_panic_hook")] - console_error_panic_hook::set_once(); -} - -#[wasm_bindgen] -pub struct MaxwellUniverse(maxwell::System); - -#[wasm_bindgen] -impl MaxwellUniverse { - #[wasm_bindgen(constructor)] - pub fn new(height: usize, width: usize, x: &[f32], y: &[f32]) -> Self { - let x = ndarray::Array2::from_shape_vec((height, width), x.to_vec()).unwrap(); - let y = ndarray::Array2::from_shape_vec((height, width), y.to_vec()).unwrap(); - Self(maxwell::System::new(x, y)) - } - - pub fn init(&mut self, x0: f32, y0: f32) { - self.0.set_gaussian(x0, y0); - } - - pub fn advance(&mut self, dt: f32) { - self.0.advance(dt) - } - - pub fn advance_upwind(&mut self, dt: f32) { - self.0.advance_upwind(dt) - } - - pub fn get_ex_ptr(&self) -> *const u8 { - self.0.field().ex().as_ptr() as *const u8 - } - - pub fn get_ey_ptr(&self) -> *const u8 { - self.0.field().ey().as_ptr() as *const u8 - } - - pub fn get_hz_ptr(&self) -> *const u8 { - self.0.field().hz().as_ptr() as *const u8 - } -} - -#[wasm_bindgen] -pub struct EulerUniverse(euler::System); - -impl EulerUniverse { - pub fn new(x: ndarray::Array2, y: ndarray::Array2) -> Self { - Self(euler::System::new(x, y)) - } -} - -#[wasm_bindgen] -impl EulerUniverse { - #[wasm_bindgen(constructor)] - pub fn new_with_slice(height: usize, width: usize, x: &[f32], y: &[f32]) -> Self { - let x = ndarray::Array2::from_shape_vec((height, width), x.to_vec()).unwrap(); - let y = ndarray::Array2::from_shape_vec((height, width), y.to_vec()).unwrap(); - Self(euler::System::new(x, y)) - } - - pub fn init(&mut self, x0: f32, y0: f32) { - self.0.init_with_vortex(x0, y0) - } - - pub fn advance(&mut self, dt: f32) { - self.0.advance(dt) - } - - pub fn advance_upwind(&mut self, dt: f32) { - self.0.advance_upwind(dt) - } - - pub fn get_rho_ptr(&self) -> *const u8 { - self.0.field().rho().as_ptr() as *const u8 - } - pub fn get_rhou_ptr(&self) -> *const u8 { - self.0.field().rhou().as_ptr() as *const u8 - } - pub fn get_rhov_ptr(&self) -> *const u8 { - self.0.field().rhov().as_ptr() as *const u8 - } - pub fn get_e_ptr(&self) -> *const u8 { - self.0.field().e().as_ptr() as *const u8 - } -} - -#[test] -fn start_and_advance_euler() { - let x = ndarray::Array2::from_shape_fn((20, 20), |(_j, i)| { - 5.0 * 2.0 * ((i as f32 / (20 - 1) as f32) - 0.5) - }); - let y = ndarray::Array2::from_shape_fn((20, 20), |(j, _i)| { - 5.0 * 2.0 * ((j as f32 / (20 - 1) as f32) - 0.5) - }); - let mut universe = EulerUniverse::new(x, y); - universe.init(-1.0, 0.0); - for _ in 0..50 { - universe.advance(0.01); - } -} - -#[test] -fn start_and_advance_upwind_euler() { - let x = ndarray::Array2::from_shape_fn((20, 10), |(_j, i)| i as f32 / (10 - 1) as f32); - let y = ndarray::Array2::from_shape_fn((20, 10), |(j, _i)| j as f32 / (20 - 1) as f32); - let mut universe = EulerUniverse::new(x, y); - universe.init(0.5, 0.5); - for _ in 0..50 { - universe.advance_upwind(0.01); - } -} diff --git a/webfront/.gitignore b/webfront/.gitignore new file mode 100644 index 0000000..06d09f4 --- /dev/null +++ b/webfront/.gitignore @@ -0,0 +1 @@ +publish diff --git a/webfront/Cargo.toml b/webfront/Cargo.toml new file mode 100644 index 0000000..91b5984 --- /dev/null +++ b/webfront/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "sbp-web" +version = "0.1.1" +authors = ["Magnus Ulimoen "] +edition = "2018" + +[lib] +crate-type = ["cdylib"] +path = "lib.rs" + +[dependencies] +wasm-bindgen = "0.2.54" +console_error_panic_hook = { version = "0.1.6" } +wee_alloc = { version = "0.4.5" } +sbp = { path = "../sbp" } +ndarray = "0.13.0" diff --git a/webfront/lib.rs b/webfront/lib.rs new file mode 100644 index 0000000..edeba8f --- /dev/null +++ b/webfront/lib.rs @@ -0,0 +1,120 @@ +use wasm_bindgen::prelude::*; + +use sbp::{euler, maxwell, operators}; + +#[cfg(feature = "wee_alloc")] +#[global_allocator] +static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; + +#[wasm_bindgen] +pub fn set_panic_hook() { + #[cfg(feature = "console_error_panic_hook")] + console_error_panic_hook::set_once(); +} + +#[wasm_bindgen] +pub struct MaxwellUniverse(maxwell::System); + +#[wasm_bindgen] +impl MaxwellUniverse { + #[wasm_bindgen(constructor)] + pub fn new(height: usize, width: usize, x: &[f32], y: &[f32]) -> Self { + let x = ndarray::Array2::from_shape_vec((height, width), x.to_vec()).unwrap(); + let y = ndarray::Array2::from_shape_vec((height, width), y.to_vec()).unwrap(); + Self(maxwell::System::new(x, y)) + } + + pub fn init(&mut self, x0: f32, y0: f32) { + self.0.set_gaussian(x0, y0); + } + + pub fn advance(&mut self, dt: f32) { + self.0.advance(dt) + } + + pub fn advance_upwind(&mut self, dt: f32) { + self.0.advance_upwind(dt) + } + + pub fn get_ex_ptr(&self) -> *const u8 { + self.0.field().ex().as_ptr() as *const u8 + } + + pub fn get_ey_ptr(&self) -> *const u8 { + self.0.field().ey().as_ptr() as *const u8 + } + + pub fn get_hz_ptr(&self) -> *const u8 { + self.0.field().hz().as_ptr() as *const u8 + } +} + +#[wasm_bindgen] +pub struct EulerUniverse(euler::System); + +impl EulerUniverse { + pub fn new(x: ndarray::Array2, y: ndarray::Array2) -> Self { + Self(euler::System::new(x, y)) + } +} + +#[wasm_bindgen] +impl EulerUniverse { + #[wasm_bindgen(constructor)] + pub fn new_with_slice(height: usize, width: usize, x: &[f32], y: &[f32]) -> Self { + let x = ndarray::Array2::from_shape_vec((height, width), x.to_vec()).unwrap(); + let y = ndarray::Array2::from_shape_vec((height, width), y.to_vec()).unwrap(); + Self(euler::System::new(x, y)) + } + + pub fn init(&mut self, x0: f32, y0: f32) { + self.0.init_with_vortex(x0, y0) + } + + pub fn advance(&mut self, dt: f32) { + self.0.advance(dt) + } + + pub fn advance_upwind(&mut self, dt: f32) { + self.0.advance_upwind(dt) + } + + pub fn get_rho_ptr(&self) -> *const u8 { + self.0.field().rho().as_ptr() as *const u8 + } + pub fn get_rhou_ptr(&self) -> *const u8 { + self.0.field().rhou().as_ptr() as *const u8 + } + pub fn get_rhov_ptr(&self) -> *const u8 { + self.0.field().rhov().as_ptr() as *const u8 + } + pub fn get_e_ptr(&self) -> *const u8 { + self.0.field().e().as_ptr() as *const u8 + } +} + +#[test] +fn start_and_advance_euler() { + let x = ndarray::Array2::from_shape_fn((20, 20), |(_j, i)| { + 5.0 * 2.0 * ((i as f32 / (20 - 1) as f32) - 0.5) + }); + let y = ndarray::Array2::from_shape_fn((20, 20), |(j, _i)| { + 5.0 * 2.0 * ((j as f32 / (20 - 1) as f32) - 0.5) + }); + let mut universe = EulerUniverse::new(x, y); + universe.init(-1.0, 0.0); + for _ in 0..50 { + universe.advance(0.01); + } +} + +#[test] +fn start_and_advance_upwind_euler() { + let x = ndarray::Array2::from_shape_fn((20, 10), |(_j, i)| i as f32 / (10 - 1) as f32); + let y = ndarray::Array2::from_shape_fn((20, 10), |(j, _i)| j as f32 / (20 - 1) as f32); + let mut universe = EulerUniverse::new(x, y); + universe.init(0.5, 0.5); + for _ in 0..50 { + universe.advance_upwind(0.01); + } +} diff --git a/make_wasm.py b/webfront/make_wasm.py similarity index 85% rename from make_wasm.py rename to webfront/make_wasm.py index 209c31a..c1235c7 100755 --- a/make_wasm.py +++ b/webfront/make_wasm.py @@ -24,17 +24,18 @@ if __name__ == "__main__": publish.mkdir(exist_ok=True) target_triple = "wasm32-unknown-unknown" - command = ["cargo", "build", "--target", target_triple] - target = ( - pathlib.Path("target") - .joinpath(target_triple) - .joinpath("release" if args.release else "debug") - .joinpath("sbp.wasm") - ) + command = ["env", "RUSTFLAGS=-Clto=thin", "cargo", "build", "--target", target_triple] if args.release: command.append("--release") check_call(command) + + target = ( + pathlib.Path("../target") + .joinpath(target_triple) + .joinpath("release" if args.release else "debug") + .joinpath("sbp_web.wasm") + ) assert target.exists() check_call( @@ -53,7 +54,7 @@ if __name__ == "__main__": try: with tempfile.TemporaryDirectory() as d_: d = pathlib.Path(d_) - wasm_bg = publish.joinpath("sbp_bg.wasm") + wasm_bg = publish.joinpath("sbp_web_bg.wasm") wasm_to_opt = d.joinpath("before-wasm-opt.wasm") copyfile(wasm_bg, wasm_to_opt) check_call(["wasm-opt", "-O4", str(wasm_to_opt), "-o", str(wasm_bg)]) @@ -61,4 +62,4 @@ if __name__ == "__main__": print("wasm-opt not found, not optimising further") pass - copytree("webfront", publish, dirs_exist_ok=True) + copytree("pages", publish, dirs_exist_ok=True) diff --git a/webfront/euler/euler.js b/webfront/pages/euler/euler.js similarity index 99% rename from webfront/euler/euler.js rename to webfront/pages/euler/euler.js index 8f63af0..8e326c8 100644 --- a/webfront/euler/euler.js +++ b/webfront/pages/euler/euler.js @@ -1,11 +1,11 @@ -import { EulerUniverse, default as init, set_panic_hook as setPanicHook } from "../sbp.js"; +import { EulerUniverse, default as init, set_panic_hook as setPanicHook } from "../sbp_web.js"; /** * Initialises and runs the Euler solver, * plotting the solution to a canvas using webgl */ (async function run() { - const wasm = await init("../sbp_bg.wasm"); + const wasm = await init("../sbp_web_bg.wasm"); setPanicHook(); const DIAMOND = false; const UPWIND = true; diff --git a/webfront/euler/index.html b/webfront/pages/euler/index.html similarity index 100% rename from webfront/euler/index.html rename to webfront/pages/euler/index.html diff --git a/webfront/maxwell/index.html b/webfront/pages/maxwell/index.html similarity index 100% rename from webfront/maxwell/index.html rename to webfront/pages/maxwell/index.html diff --git a/webfront/maxwell/main.js b/webfront/pages/maxwell/main.js similarity index 99% rename from webfront/maxwell/main.js rename to webfront/pages/maxwell/main.js index 15941f0..25639d3 100644 --- a/webfront/maxwell/main.js +++ b/webfront/pages/maxwell/main.js @@ -1,11 +1,11 @@ -import { MaxwellUniverse, default as init, set_panic_hook as setPanicHook } from "../sbp.js"; +import { MaxwellUniverse, default as init, set_panic_hook as setPanicHook } from "../sbp_web.js"; /** * Initialises and runs the Maxwell solver, * plotting the solution to a canvas using webgl */ (async function run() { - const wasm = await init("../sbp_bg.wasm"); + const wasm = await init("../sbp_web_bg.wasm"); setPanicHook(); const DIAMOND = false;