use workspaces

This commit is contained in:
Magnus Ulimoen
2020-01-30 18:28:22 +01:00
parent 4ac1ad0d2c
commit 264b483aef
23 changed files with 185 additions and 169 deletions

1
webfront/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
publish

16
webfront/Cargo.toml Normal file
View File

@@ -0,0 +1,16 @@
[package]
name = "sbp-web"
version = "0.1.1"
authors = ["Magnus Ulimoen <flymagnus@gmail.com>"]
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"

120
webfront/lib.rs Normal file
View File

@@ -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<operators::Upwind4>);
#[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<operators::Upwind4>);
impl EulerUniverse {
pub fn new(x: ndarray::Array2<f32>, y: ndarray::Array2<f32>) -> 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);
}
}

65
webfront/make_wasm.py Executable file
View File

@@ -0,0 +1,65 @@
#! /usr/bin/env python3
from argparse import ArgumentParser
from subprocess import check_call
from shutil import copyfile, copytree
import tempfile
import pathlib
if __name__ == "__main__":
parser = ArgumentParser(description="Build js and wasm")
parser.add_argument(
"-r", help="Build release type", dest="release", action="store_true"
)
parser.add_argument(
"--destdir",
default=pathlib.Path("publish"),
type=pathlib.Path,
help="Destination suitable for being copied directly to the webserver",
)
args = parser.parse_args()
publish = args.destdir
publish.mkdir(exist_ok=True)
target_triple = "wasm32-unknown-unknown"
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(
[
"wasm-bindgen",
str(target),
"--out-dir",
str(publish),
"--no-typescript",
"--target",
"web",
]
)
if args.release:
try:
with tempfile.TemporaryDirectory() as d_:
d = pathlib.Path(d_)
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)])
except FileNotFoundError:
print("wasm-opt not found, not optimising further")
pass
copytree("pages", publish, dirs_exist_ok=True)

View File

@@ -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;

View File

@@ -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;