Use serde for json configuration file
This commit is contained in:
parent
f90618be42
commit
d0e6727ac3
|
@ -8,11 +8,13 @@ edition = "2018"
|
|||
# Internal feature flag to gate the expensive tests
|
||||
# which should be run only in release builds
|
||||
expensive_tests = []
|
||||
serde1 = ["serde", "arrayvec/serde"]
|
||||
|
||||
[dependencies]
|
||||
ndarray = "0.13.1"
|
||||
sbp = { path = "../sbp" }
|
||||
arrayvec = "0.5.1"
|
||||
serde = { version = "1.0.115", default-features = false, optional = true, features = ["derive"] }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3.2"
|
||||
|
|
|
@ -402,6 +402,7 @@ fn h2_diff() {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub struct Vortice {
|
||||
pub x0: Float,
|
||||
pub y0: Float,
|
||||
|
@ -409,7 +410,11 @@ pub struct Vortice {
|
|||
pub eps: Float,
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde1")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
|
||||
pub struct VortexParameters {
|
||||
pub vortices: ArrayVec<[Vortice; 5]>,
|
||||
pub mach: Float,
|
||||
|
|
|
@ -6,12 +6,15 @@ edition = "2018"
|
|||
|
||||
|
||||
[dependencies]
|
||||
sbp = { path = "../sbp", features = ["rayon"] }
|
||||
euler = { path = "../euler" }
|
||||
sbp = { path = "../sbp", features = ["rayon", "serde"] }
|
||||
euler = { path = "../euler", features = ["serde1"] }
|
||||
hdf5 = "0.7.0"
|
||||
rayon = "1.3.0"
|
||||
indicatif = "0.14.0"
|
||||
structopt = "0.3.14"
|
||||
ndarray = "0.13.1"
|
||||
ndarray = { version = "0.13.1", features = ["serde"] }
|
||||
json = "0.12.4"
|
||||
either = "1.5.3"
|
||||
serde = { version = "1.0.115", features = ["derive"] }
|
||||
json5 = "0.2.8"
|
||||
indexmap = { version = "1.5.2", features = ["serde-1"] }
|
||||
|
|
|
@ -1,10 +1,127 @@
|
|||
use super::DiffOp;
|
||||
use either::*;
|
||||
use json::JsonValue;
|
||||
use sbp::grid::Grid;
|
||||
use sbp::utils::h2linspace;
|
||||
use sbp::Float;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum Operator {
|
||||
Upwind4,
|
||||
Upwind9,
|
||||
Upwind4h2,
|
||||
Upwind9h2,
|
||||
Sbp4,
|
||||
Sbp8,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Operators {
|
||||
pub xi: Operator,
|
||||
pub eta: Operator,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Linspace {
|
||||
pub start: Float,
|
||||
pub end: Float,
|
||||
pub steps: usize,
|
||||
#[serde(default)]
|
||||
pub h2: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum GridLike {
|
||||
Linspace(Linspace),
|
||||
Array(ArrayForm),
|
||||
}
|
||||
|
||||
impl From<Linspace> for GridLike {
|
||||
fn from(t: Linspace) -> Self {
|
||||
Self::Linspace(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ArrayForm> for GridLike {
|
||||
fn from(t: ArrayForm) -> Self {
|
||||
Self::Array(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ndarray::Array1<Float>> for GridLike {
|
||||
fn from(t: ndarray::Array1<Float>) -> Self {
|
||||
Self::Array(t.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ndarray::Array2<Float>> for GridLike {
|
||||
fn from(t: ndarray::Array2<Float>) -> Self {
|
||||
Self::Array(t.into())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum InterpolationOperator {
|
||||
#[serde(rename = "4")]
|
||||
Four,
|
||||
#[serde(rename = "8")]
|
||||
Eight,
|
||||
#[serde(rename = "9")]
|
||||
Nine,
|
||||
#[serde(rename = "9h2")]
|
||||
NineH2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Interpolate {
|
||||
operator: Option<InterpolationOperator>,
|
||||
neighbour: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum BoundaryType {
|
||||
This,
|
||||
Interpolate(Interpolate),
|
||||
Neighbour(String),
|
||||
Vortex,
|
||||
}
|
||||
|
||||
pub type BoundaryDescriptors = sbp::utils::Direction<Option<BoundaryType>>;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct GridConfig {
|
||||
pub operators: Option<Operators>,
|
||||
pub x: Option<GridLike>,
|
||||
pub y: Option<GridLike>,
|
||||
pub boundary_conditions: Option<BoundaryDescriptors>,
|
||||
}
|
||||
|
||||
type Grids = indexmap::IndexMap<String, GridConfig>;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Configuration {
|
||||
pub grids: Grids,
|
||||
pub integration_time: Float,
|
||||
pub vortex: euler::VortexParameters,
|
||||
}
|
||||
|
||||
pub struct RuntimeConfiguration {
|
||||
names: Vec<String>,
|
||||
grids: Vec<sbp::grid::Grid>,
|
||||
bc: Vec<euler::BoundaryCharacteristics>,
|
||||
op: Vec<DiffOp>,
|
||||
}
|
||||
|
||||
impl Configuration {
|
||||
fn to_runtime(self) -> RuntimeConfiguration {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn json_to_grids(
|
||||
mut jsongrids: JsonValue,
|
||||
vortexparams: euler::VortexParameters,
|
||||
|
@ -191,8 +308,9 @@ pub fn json_to_grids(
|
|||
|
||||
(names, grids, bcs, operators)
|
||||
}
|
||||
#[derive(Debug)]
|
||||
enum ArrayForm {
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ArrayForm {
|
||||
/// Only know the one dimension, will broadcast to
|
||||
/// two dimensions once we know about both dims
|
||||
Array1(ndarray::Array1<Float>),
|
||||
|
@ -200,6 +318,18 @@ enum ArrayForm {
|
|||
Array2(ndarray::Array2<Float>),
|
||||
}
|
||||
|
||||
impl From<ndarray::Array1<Float>> for ArrayForm {
|
||||
fn from(t: ndarray::Array1<Float>) -> Self {
|
||||
Self::Array1(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ndarray::Array2<Float>> for ArrayForm {
|
||||
fn from(t: ndarray::Array2<Float>) -> Self {
|
||||
Self::Array2(t)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parsing json strings to some gridlike form
|
||||
///
|
||||
/// Each grid should be an object with the descriptors on the form
|
||||
|
@ -217,7 +347,7 @@ enum ArrayForm {
|
|||
/// Optional parameters:
|
||||
/// * name (for relating boundaries)
|
||||
/// * dir{e,w,n,s} (for boundary terms)
|
||||
fn json2grid(x: JsonValue, y: JsonValue) -> Result<Grid, String> {
|
||||
fn json2grid(x: JsonValue, y: JsonValue) -> Result<sbp::grid::Grid, String> {
|
||||
let to_array_form = |mut x: JsonValue| {
|
||||
if let Some(s) = x.take_string() {
|
||||
if let Some(s) = s.strip_prefix("linspace:") {
|
||||
|
@ -346,7 +476,7 @@ fn json2grid(x: JsonValue, y: JsonValue) -> Result<Grid, String> {
|
|||
};
|
||||
assert_eq!(x.shape(), y.shape());
|
||||
|
||||
Ok(Grid::new(x, y).unwrap())
|
||||
Ok(sbp::grid::Grid::new(x, y).unwrap())
|
||||
}
|
||||
|
||||
pub fn json_to_vortex(mut json: JsonValue) -> euler::VortexParameters {
|
||||
|
@ -391,3 +521,154 @@ pub fn json_to_vortex(mut json: JsonValue) -> euler::VortexParameters {
|
|||
|
||||
euler::VortexParameters { vortices, mach }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn output_configuration() {
|
||||
let mut grids = Grids::new();
|
||||
grids.insert(
|
||||
"default".to_string(),
|
||||
GridConfig {
|
||||
boundary_conditions: None,
|
||||
x: None,
|
||||
y: None,
|
||||
operators: None,
|
||||
},
|
||||
);
|
||||
grids.insert(
|
||||
"operators1".to_string(),
|
||||
GridConfig {
|
||||
boundary_conditions: None,
|
||||
x: None,
|
||||
y: None,
|
||||
operators: Some(Operators {
|
||||
xi: Operator::Upwind4,
|
||||
eta: Operator::Upwind9,
|
||||
}),
|
||||
},
|
||||
);
|
||||
grids.insert(
|
||||
"operators2".to_string(),
|
||||
GridConfig {
|
||||
boundary_conditions: None,
|
||||
x: None,
|
||||
y: None,
|
||||
operators: Some(Operators {
|
||||
xi: Operator::Upwind4h2,
|
||||
eta: Operator::Upwind9h2,
|
||||
}),
|
||||
},
|
||||
);
|
||||
grids.insert(
|
||||
"operators3".to_string(),
|
||||
GridConfig {
|
||||
boundary_conditions: None,
|
||||
x: None,
|
||||
y: None,
|
||||
operators: Some(Operators {
|
||||
xi: Operator::Sbp4,
|
||||
eta: Operator::Sbp8,
|
||||
}),
|
||||
},
|
||||
);
|
||||
grids.insert(
|
||||
"linspaced".to_string(),
|
||||
GridConfig {
|
||||
boundary_conditions: None,
|
||||
x: Some(
|
||||
Linspace {
|
||||
start: 0.0,
|
||||
end: 1.0,
|
||||
steps: 32,
|
||||
h2: false,
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
y: Some(
|
||||
Linspace {
|
||||
start: -1.0,
|
||||
end: 1.0,
|
||||
steps: 35,
|
||||
h2: true,
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
operators: None,
|
||||
},
|
||||
);
|
||||
grids.insert(
|
||||
"array1".to_string(),
|
||||
GridConfig {
|
||||
boundary_conditions: None,
|
||||
x: Some(ndarray::arr1(&[1.0, 2.0, 3.0, 4.0]).into()),
|
||||
y: Some(ndarray::arr1(&[-4.0, -3.0, -2.0, -1.0, 0.0]).into()),
|
||||
operators: None,
|
||||
},
|
||||
);
|
||||
grids.insert(
|
||||
"array2".to_string(),
|
||||
GridConfig {
|
||||
boundary_conditions: None,
|
||||
x: Some(ndarray::arr2(&[[1.0, 2.0, 3.0, 4.0], [2.0, 3.0, 4.0, 5.0]]).into()),
|
||||
y: Some(ndarray::arr2(&[[0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]]).into()),
|
||||
operators: None,
|
||||
},
|
||||
);
|
||||
grids.insert(
|
||||
"boundary_conditions".to_string(),
|
||||
GridConfig {
|
||||
boundary_conditions: Some(BoundaryDescriptors {
|
||||
north: None,
|
||||
south: Some(BoundaryType::This),
|
||||
east: Some(BoundaryType::Neighbour("name_of_grid".to_string())),
|
||||
west: Some(BoundaryType::Vortex),
|
||||
}),
|
||||
x: None,
|
||||
y: None,
|
||||
operators: None,
|
||||
},
|
||||
);
|
||||
grids.insert(
|
||||
"boundary_conditions_interpolation".to_string(),
|
||||
GridConfig {
|
||||
boundary_conditions: Some(BoundaryDescriptors {
|
||||
north: Some(BoundaryType::Interpolate(Interpolate {
|
||||
neighbour: "name_of_grid".to_string(),
|
||||
operator: Some(InterpolationOperator::Four),
|
||||
})),
|
||||
south: Some(BoundaryType::Interpolate(Interpolate {
|
||||
neighbour: "name_of_grid".to_string(),
|
||||
operator: Some(InterpolationOperator::Nine),
|
||||
})),
|
||||
west: Some(BoundaryType::Interpolate(Interpolate {
|
||||
neighbour: "name_of_grid".to_string(),
|
||||
operator: Some(InterpolationOperator::Eight),
|
||||
})),
|
||||
east: Some(BoundaryType::Interpolate(Interpolate {
|
||||
neighbour: "name_of_grid".to_string(),
|
||||
operator: Some(InterpolationOperator::NineH2),
|
||||
})),
|
||||
}),
|
||||
x: None,
|
||||
y: None,
|
||||
operators: None,
|
||||
},
|
||||
);
|
||||
let configuration = Configuration {
|
||||
grids,
|
||||
integration_time: 2.0,
|
||||
vortex: euler::VortexParameters {
|
||||
mach: 0.5,
|
||||
vortices: {
|
||||
let mut arr = euler::ArrayVec::new();
|
||||
arr.push(euler::Vortice {
|
||||
eps: 1.0,
|
||||
x0: -1.0,
|
||||
y0: 0.0,
|
||||
rstar: 0.5,
|
||||
});
|
||||
arr
|
||||
},
|
||||
},
|
||||
};
|
||||
println!("{}", json5::to_string(&configuration).unwrap());
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ packed_simd = "0.3.3"
|
|||
rayon = { version = "1.3.0", optional = true }
|
||||
sprs = { version = "0.7.1", optional = true }
|
||||
num-traits = "0.2.11"
|
||||
serde = { version = "1.0.115", optional = true, default-features = false, features = ["derive"] }
|
||||
|
||||
[features]
|
||||
# Use f32 as precision, default is f64
|
||||
|
|
|
@ -8,7 +8,11 @@ pub use jacobi::*;
|
|||
mod kronecker_product;
|
||||
#[cfg(feature = "sparse")]
|
||||
pub use kronecker_product::kronecker_product;
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Direction<T> {
|
||||
pub north: T,
|
||||
pub south: T,
|
||||
|
|
Loading…
Reference in New Issue