read config from json

This commit is contained in:
Magnus Ulimoen 2020-04-02 21:36:56 +02:00
parent c1895a6c33
commit d80a9bfa6d
5 changed files with 126 additions and 83 deletions

View File

@ -19,6 +19,7 @@ f32 = []
[dev-dependencies] [dev-dependencies]
criterion = "0.3.0" criterion = "0.3.0"
structopt = "0.3.12"
[[bench]] [[bench]]
name = "maxwell" name = "maxwell"

View File

@ -1,22 +1,6 @@
use ndarray::prelude::*; use sbp::utils::json_to_grids;
use sbp::*; use sbp::*;
use structopt::StructOpt;
/*
* A 2D grid divided in four parts, spanning the rectangle [-5, 5] x [-5, 5]
*
* / \ y
* |
* | 5.0 000 333
* | 000 333
* | 000 333
* | 0.0
* | 111 222
* | 111 222
* |-5.0 111 222
* |
* | -5.0 0.0 5.0 x
* ------------------------->
*/
struct System<T: operators::UpwindOperator> { struct System<T: operators::UpwindOperator> {
fnow: Vec<euler::Field>, fnow: Vec<euler::Field>,
@ -31,10 +15,11 @@ struct System<T: operators::UpwindOperator> {
)>, )>,
k: [Vec<euler::Field>; 4], k: [Vec<euler::Field>; 4],
grids: Vec<grid::Grid<T>>, grids: Vec<grid::Grid<T>>,
bt: Vec<euler::BoundaryCharacteristics>,
} }
impl<T: operators::UpwindOperator> System<T> { impl<T: operators::UpwindOperator> System<T> {
fn new(grids: Vec<grid::Grid<T>>) -> Self { fn new(grids: Vec<grid::Grid<T>>, bt: Vec<euler::BoundaryCharacteristics>) -> Self {
let fnow = grids let fnow = grids
.iter() .iter()
.map(|g| euler::Field::new(g.ny(), g.nx())) .map(|g| euler::Field::new(g.ny(), g.nx()))
@ -55,6 +40,7 @@ impl<T: operators::UpwindOperator> System<T> {
k, k,
wb, wb,
grids, grids,
bt,
} }
} }
@ -126,35 +112,37 @@ impl<T: operators::UpwindOperator> System<T> {
} }
} }
let bt = vec![ let fields = &self.fnext;
euler::BoundaryTerms {
north: self.fnext[1].south(),
south: self.fnext[1].north(),
east: self.fnext[3].west(),
west: self.fnext[3].east(),
},
euler::BoundaryTerms {
north: self.fnext[0].south(),
south: self.fnext[0].north(),
east: self.fnext[2].west(),
west: self.fnext[2].east(),
},
euler::BoundaryTerms {
north: self.fnext[3].south(),
south: self.fnext[3].north(),
east: self.fnext[1].west(),
west: self.fnext[1].east(),
},
euler::BoundaryTerms {
north: self.fnext[2].south(),
south: self.fnext[2].north(),
east: self.fnext[0].west(),
west: self.fnext[0].east(),
},
];
for ((((prev, fut), grid), wb), bt) in self let bt = self
.fnext .bt
.iter()
.enumerate()
.map(|(i, bt)| euler::BoundaryTerms {
north: match bt.north {
euler::BoundaryCharacteristic::This => fields[i].south(),
euler::BoundaryCharacteristic::Grid(g) => fields[g].south(),
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
},
south: match bt.south {
euler::BoundaryCharacteristic::This => fields[i].north(),
euler::BoundaryCharacteristic::Grid(g) => fields[g].north(),
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
},
west: match bt.west {
euler::BoundaryCharacteristic::This => fields[i].east(),
euler::BoundaryCharacteristic::Grid(g) => fields[g].east(),
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
},
east: match bt.east {
euler::BoundaryCharacteristic::This => fields[i].west(),
euler::BoundaryCharacteristic::Grid(g) => fields[g].west(),
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
},
})
.collect::<Vec<_>>();
for ((((prev, fut), grid), wb), bt) in fields
.iter() .iter()
.zip(fnext) .zip(fnext)
.zip(&self.grids) .zip(&self.grids)
@ -167,36 +155,42 @@ impl<T: operators::UpwindOperator> System<T> {
} }
} }
fn mesh(y: (f64, f64, usize), x: (f64, f64, usize)) -> (Array2<f64>, Array2<f64>) { #[derive(Debug, StructOpt)]
let arrx = Array1::linspace(x.0, x.1, x.2); struct Options {
let arry = Array1::linspace(y.0, y.1, y.2); json: std::path::PathBuf,
let gx = arrx.broadcast((y.2, x.2)).unwrap();
let mut gy = arry.broadcast((x.2, y.2)).unwrap();
gy.swap_axes(0, 1);
(gy.into_owned(), gx.into_owned())
} }
fn main() { fn main() {
let nx = 32; let opt = Options::from_args();
let ny = 31; let filecontents = std::fs::read_to_string(&opt.json).unwrap();
let mut grids = Vec::with_capacity(4); let json = json::parse(&filecontents).unwrap();
let jgrids = json_to_grids(json["grids"].clone()).unwrap();
let (y0, x0) = mesh((0.0, 5.0, ny), (-5.0, 0.0, nx)); let mut bt = Vec::with_capacity(jgrids.len());
grids.push(grid::Grid::<operators::Upwind9>::new(x0, y0).unwrap()); let determine_bc = |dir| match dir {
Some(dir) => euler::BoundaryCharacteristic::Grid(
jgrids
.iter()
.position(|other| other.name.as_ref().map_or(false, |name| name == dir))
.unwrap(),
),
None => euler::BoundaryCharacteristic::This,
};
for grid in &jgrids {
bt.push(euler::BoundaryCharacteristics {
north: determine_bc(grid.dirn.as_ref()),
south: determine_bc(grid.dirs.as_ref()),
east: determine_bc(grid.dire.as_ref()),
west: determine_bc(grid.dirw.as_ref()),
});
}
let mut grids: Vec<grid::Grid<operators::Upwind4>> = Vec::with_capacity(jgrids.len());
for grid in jgrids {
grids.push(grid::Grid::new(grid.x, grid.y).unwrap());
}
let (y1, x1) = mesh((-5.0, 0.0, ny), (-5.0, 0.0, nx)); let mut sys = System::new(grids, bt);
grids.push(grid::Grid::<operators::Upwind9>::new(x1, y1).unwrap());
let (y2, x2) = mesh((-5.0, 0.0, ny), (0.0, 5.0, nx));
grids.push(grid::Grid::<operators::Upwind9>::new(x2, y2).unwrap());
let (y3, x3) = mesh((0.0, 5.0, ny), (0.0, 5.0, nx));
grids.push(grid::Grid::<operators::Upwind9>::new(x3, y3).unwrap());
let mut sys = System::new(grids);
sys.vortex( sys.vortex(
0.0, 0.0,
euler::VortexParameters { euler::VortexParameters {
@ -207,13 +201,18 @@ fn main() {
eps: 1.0, eps: 1.0,
}, },
); );
let t = 0.2;
let dt = 0.1 / (std::cmp::max(nx, ny) as Float); let max_n = {
let max_nx = sys.grids.iter().map(|g| g.nx()).max().unwrap();
let max_ny = sys.grids.iter().map(|g| g.ny()).max().unwrap();
std::cmp::max(max_nx, max_ny)
};
let t: f64 = json["integration_time"].as_number().unwrap().into();
let dt = 0.2 / (max_n as Float);
for _ in 0..(t / dt) as _ { for _ in 0..(t / dt) as _ {
sys.advance(dt); sys.advance(dt);
} }
println!("{}", sys.fnow[0].e()[(0, 0)]);
dump_to_file(&sys); dump_to_file(&sys);
} }

41
sbp/examples/quad.json Normal file
View File

@ -0,0 +1,41 @@
{
"grids": [
{
"name": "grid0",
"x": "linspace:-5:0:50",
"y": "linspace:0:5:50",
"dirS": "grid1",
"dirN": "grid1",
"dirE": "grid3",
"dirW": "grid3"
},
{
"name": "grid1",
"x": "linspace:-5:0:50",
"y": "linspace:-5:0:50",
"dirS": "grid0",
"dirN": "grid0",
"dirE": "grid2",
"dirW": "grid2"
},
{
"name": "grid2",
"x": "linspace:0:5:50",
"y": "linspace:-5:0:50",
"dirS": "grid3",
"dirN": "grid3",
"dirE": "grid1",
"dirW": "grid1"
},
{
"name": "grid3",
"x": "linspace:0:5:50",
"y": "linspace:0:5:50",
"dirS": "grid2",
"dirN": "grid2",
"dirE": "grid0",
"dirW": "grid0"
}
],
"integration_time": 2.0
}

View File

@ -577,17 +577,17 @@ pub struct BoundaryTerms<'a> {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum BoundaryCharacteristic { pub enum BoundaryCharacteristic {
This, This,
// Grid(usize), Grid(usize),
Vortex(VortexParameters), Vortex(VortexParameters),
// Vortices(Vec<VortexParameters>), // Vortices(Vec<VortexParameters>),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct BoundaryCharacteristics { pub struct BoundaryCharacteristics {
north: BoundaryCharacteristic, pub north: BoundaryCharacteristic,
south: BoundaryCharacteristic, pub south: BoundaryCharacteristic,
east: BoundaryCharacteristic, pub east: BoundaryCharacteristic,
west: BoundaryCharacteristic, pub west: BoundaryCharacteristic,
} }
fn boundary_extractor<'a, SBP: SbpOperator>( fn boundary_extractor<'a, SBP: SbpOperator>(
@ -599,18 +599,22 @@ fn boundary_extractor<'a, SBP: SbpOperator>(
north: match bc.north { north: match bc.north {
BoundaryCharacteristic::This => field.south(), BoundaryCharacteristic::This => field.south(),
BoundaryCharacteristic::Vortex(_params) => todo!(), BoundaryCharacteristic::Vortex(_params) => todo!(),
BoundaryCharacteristic::Grid(_) => panic!("Only working on self grid"),
}, },
south: match bc.south { south: match bc.south {
BoundaryCharacteristic::This => field.north(), BoundaryCharacteristic::This => field.north(),
BoundaryCharacteristic::Vortex(_params) => todo!(), BoundaryCharacteristic::Vortex(_params) => todo!(),
BoundaryCharacteristic::Grid(_) => panic!("Only working on self grid"),
}, },
west: match bc.west { west: match bc.west {
BoundaryCharacteristic::This => field.east(), BoundaryCharacteristic::This => field.east(),
BoundaryCharacteristic::Vortex(_params) => todo!(), BoundaryCharacteristic::Vortex(_params) => todo!(),
BoundaryCharacteristic::Grid(_) => panic!("Only working on self grid"),
}, },
east: match bc.east { east: match bc.east {
BoundaryCharacteristic::This => field.west(), BoundaryCharacteristic::This => field.west(),
BoundaryCharacteristic::Vortex(_params) => todo!(), BoundaryCharacteristic::Vortex(_params) => todo!(),
BoundaryCharacteristic::Grid(_) => panic!("Only working on self grid"),
}, },
} }
} }

View File

@ -27,7 +27,7 @@ pub struct SimpleGrid {
/// Optional parameters: /// Optional parameters:
/// * name (for relating boundaries) /// * name (for relating boundaries)
/// * dir{e,w,n,s} (for boundary terms) /// * dir{e,w,n,s} (for boundary terms)
pub fn json_to_grids(json: &str) -> Result<Vec<SimpleGrid>, String> { pub fn json_to_grids(json: json::JsonValue) -> Result<Vec<SimpleGrid>, String> {
use json::JsonValue; use json::JsonValue;
fn json_to_grid(mut grid: JsonValue) -> Result<SimpleGrid, String> { fn json_to_grid(mut grid: JsonValue) -> Result<SimpleGrid, String> {
#[derive(Debug)] #[derive(Debug)]
@ -184,9 +184,7 @@ pub fn json_to_grids(json: &str) -> Result<Vec<SimpleGrid>, String> {
}) })
} }
let js = json::parse(&json).map_err(|e| format!("{}", e))?; match json {
match js {
JsonValue::Array(a) => a JsonValue::Array(a) => a
.into_iter() .into_iter()
.map(|g| json_to_grid(g)) .map(|g| json_to_grid(g))