Move json config to separate file
This commit is contained in:
parent
3ceeeb8ca1
commit
b64bace750
|
@ -0,0 +1,420 @@
|
||||||
|
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, Default, Serialize, Deserialize)]
|
||||||
|
pub struct Operators {
|
||||||
|
pub xi: Option<Operator>,
|
||||||
|
pub eta: Option<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),
|
||||||
|
/*
|
||||||
|
#[serde(rename = "initial_conditions")]
|
||||||
|
InitialConditions,
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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>),
|
||||||
|
/// The usize is the inner dimension (nx)
|
||||||
|
Array2(ndarray::Array2<Float>),
|
||||||
|
/*
|
||||||
|
/// A still unknown array, will be filled out by later
|
||||||
|
/// pass when initial_conditions file is known
|
||||||
|
Unknown,
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<GridLike> for ArrayForm {
|
||||||
|
fn from(t: GridLike) -> Self {
|
||||||
|
match t {
|
||||||
|
GridLike::Linspace(lin) => Self::Array1(if lin.h2 {
|
||||||
|
h2linspace(lin.start, lin.end, lin.steps)
|
||||||
|
} else {
|
||||||
|
ndarray::Array::linspace(lin.start, lin.end, lin.steps)
|
||||||
|
}),
|
||||||
|
GridLike::Array(arr) => arr,
|
||||||
|
// GridLike::InitialConditions => Self::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub enum InterpolationOperator {
|
||||||
|
#[serde(rename = "4")]
|
||||||
|
Four,
|
||||||
|
#[serde(rename = "8")]
|
||||||
|
Eight,
|
||||||
|
#[serde(rename = "9")]
|
||||||
|
Nine,
|
||||||
|
#[serde(rename = "9h2")]
|
||||||
|
NineH2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Box<dyn sbp::operators::InterpolationOperator>> for InterpolationOperator {
|
||||||
|
fn into(self) -> Box<dyn sbp::operators::InterpolationOperator> {
|
||||||
|
use sbp::operators::{Interpolation4, Interpolation8, Interpolation9, Interpolation9h2};
|
||||||
|
match self {
|
||||||
|
InterpolationOperator::Four => Box::new(Interpolation4),
|
||||||
|
InterpolationOperator::Eight => Box::new(Interpolation8),
|
||||||
|
InterpolationOperator::Nine => Box::new(Interpolation9),
|
||||||
|
InterpolationOperator::NineH2 => Box::new(Interpolation9h2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Interpolate {
|
||||||
|
pub operator: Option<InterpolationOperator>,
|
||||||
|
#[serde(alias = "neighbor")]
|
||||||
|
pub neighbour: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Multi {
|
||||||
|
#[serde(alias = "neighbor")]
|
||||||
|
pub neighbour: String,
|
||||||
|
pub start: usize,
|
||||||
|
pub end: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum BoundaryType {
|
||||||
|
This,
|
||||||
|
Interpolate(Interpolate),
|
||||||
|
#[serde(alias = "neighbor")]
|
||||||
|
Neighbour(String),
|
||||||
|
Vortex,
|
||||||
|
Multi(Vec<Multi>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type BoundaryDescriptors = sbp::utils::Direction<Option<BoundaryType>>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
|
||||||
|
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)]
|
||||||
|
/// Will be evaluated by evalexpr
|
||||||
|
pub struct ExpressionsConservation {
|
||||||
|
pub globals: Option<String>,
|
||||||
|
pub rho: String,
|
||||||
|
pub rhou: String,
|
||||||
|
pub rhov: String,
|
||||||
|
pub e: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
/// Will be evaluated by evalexpr
|
||||||
|
pub struct ExpressionsPressure {
|
||||||
|
pub globals: Option<String>,
|
||||||
|
pub rho: String,
|
||||||
|
pub u: String,
|
||||||
|
pub v: String,
|
||||||
|
pub p: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum Expressions {
|
||||||
|
Conservation(ExpressionsConservation),
|
||||||
|
Pressure(ExpressionsPressure),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum InitialConditions {
|
||||||
|
Vortex(euler::VortexParameters),
|
||||||
|
// File(String),
|
||||||
|
Expressions(Expressions),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum BoundaryConditions {
|
||||||
|
/// Initial conditions also contain the bc
|
||||||
|
#[serde(rename = "initial_conditions")]
|
||||||
|
InputInitialConditions,
|
||||||
|
Vortex(euler::VortexParameters),
|
||||||
|
Expressions(Expressions),
|
||||||
|
#[serde(rename = "not_needed")]
|
||||||
|
NotNeeded,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BoundaryConditions {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::NotNeeded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_gamma() -> Float {
|
||||||
|
1.4
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
/// Input configuration (json)
|
||||||
|
pub struct Configuration {
|
||||||
|
pub grids: Grids,
|
||||||
|
pub integration_time: Float,
|
||||||
|
pub initial_conditions: InitialConditions,
|
||||||
|
#[serde(default)]
|
||||||
|
pub boundary_conditions: BoundaryConditions,
|
||||||
|
#[serde(default = "default_gamma")]
|
||||||
|
pub gamma: Float,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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: Some(Operator::Upwind4),
|
||||||
|
eta: Some(Operator::Upwind9),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
grids.insert(
|
||||||
|
"operators2".to_string(),
|
||||||
|
GridConfig {
|
||||||
|
boundary_conditions: None,
|
||||||
|
x: None,
|
||||||
|
y: None,
|
||||||
|
operators: Some(Operators {
|
||||||
|
xi: Some(Operator::Upwind4h2),
|
||||||
|
eta: Some(Operator::Upwind9h2),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
grids.insert(
|
||||||
|
"operators3".to_string(),
|
||||||
|
GridConfig {
|
||||||
|
boundary_conditions: None,
|
||||||
|
x: None,
|
||||||
|
y: None,
|
||||||
|
operators: Some(Operators {
|
||||||
|
xi: Some(Operator::Sbp4),
|
||||||
|
eta: Some(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,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
grids.insert(
|
||||||
|
"boundary_conditions_multigrid".to_string(),
|
||||||
|
GridConfig {
|
||||||
|
boundary_conditions: Some(BoundaryDescriptors {
|
||||||
|
north: Some(BoundaryType::Multi(vec![Multi {
|
||||||
|
neighbour: "name_of_grid".to_string(),
|
||||||
|
start: 4,
|
||||||
|
end: 7,
|
||||||
|
}])),
|
||||||
|
south: Some(BoundaryType::Multi(vec![
|
||||||
|
Multi {
|
||||||
|
neighbour: "name_of_grid".to_string(),
|
||||||
|
start: 4,
|
||||||
|
end: 7,
|
||||||
|
},
|
||||||
|
Multi {
|
||||||
|
neighbour: "name_of_grid".to_string(),
|
||||||
|
start: 41,
|
||||||
|
end: 912,
|
||||||
|
},
|
||||||
|
])),
|
||||||
|
east: None,
|
||||||
|
west: None,
|
||||||
|
}),
|
||||||
|
x: None,
|
||||||
|
y: None,
|
||||||
|
operators: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let configuration = Configuration {
|
||||||
|
grids,
|
||||||
|
integration_time: 2.0,
|
||||||
|
initial_conditions: InitialConditions::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
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
boundary_conditions: BoundaryConditions::default(),
|
||||||
|
gamma: 1.4,
|
||||||
|
};
|
||||||
|
println!("{}", json5::to_string(&configuration).unwrap());
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ use sbp::operators::SbpOperator2d;
|
||||||
use sbp::*;
|
use sbp::*;
|
||||||
|
|
||||||
mod file;
|
mod file;
|
||||||
|
mod input;
|
||||||
mod parsing;
|
mod parsing;
|
||||||
use file::*;
|
use file::*;
|
||||||
mod eval;
|
mod eval;
|
||||||
|
@ -267,7 +268,7 @@ fn main() {
|
||||||
let opt: CliOptions = argh::from_env();
|
let opt: CliOptions = argh::from_env();
|
||||||
let filecontents = std::fs::read_to_string(&opt.json).unwrap();
|
let filecontents = std::fs::read_to_string(&opt.json).unwrap();
|
||||||
|
|
||||||
let config: parsing::Configuration = match json5::from_str(&filecontents) {
|
let config: input::Configuration = match json5::from_str(&filecontents) {
|
||||||
Ok(config) => config,
|
Ok(config) => config,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Configuration could not be read: {}", e);
|
eprintln!("Configuration could not be read: {}", e);
|
||||||
|
|
|
@ -1,199 +1,17 @@
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
|
|
||||||
use sbp::operators::SbpOperator2d;
|
use sbp::operators::SbpOperator2d;
|
||||||
use sbp::utils::h2linspace;
|
|
||||||
use sbp::Float;
|
use sbp::Float;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::eval;
|
use crate::eval;
|
||||||
|
use crate::input;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
impl TryFrom<input::Expressions> for eval::Evaluator {
|
||||||
#[serde(rename_all = "lowercase")]
|
|
||||||
pub enum Operator {
|
|
||||||
Upwind4,
|
|
||||||
Upwind9,
|
|
||||||
Upwind4h2,
|
|
||||||
Upwind9h2,
|
|
||||||
Sbp4,
|
|
||||||
Sbp8,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)]
|
|
||||||
pub struct Operators {
|
|
||||||
pub xi: Option<Operator>,
|
|
||||||
pub eta: Option<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),
|
|
||||||
/*
|
|
||||||
#[serde(rename = "initial_conditions")]
|
|
||||||
InitialConditions,
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<GridLike> for ArrayForm {
|
|
||||||
fn from(t: GridLike) -> Self {
|
|
||||||
match t {
|
|
||||||
GridLike::Linspace(lin) => Self::Array1(if lin.h2 {
|
|
||||||
h2linspace(lin.start, lin.end, lin.steps)
|
|
||||||
} else {
|
|
||||||
ndarray::Array::linspace(lin.start, lin.end, lin.steps)
|
|
||||||
}),
|
|
||||||
GridLike::Array(arr) => arr,
|
|
||||||
// GridLike::InitialConditions => Self::Unknown,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(Copy, Clone, Debug, Serialize, Deserialize)]
|
|
||||||
pub enum InterpolationOperator {
|
|
||||||
#[serde(rename = "4")]
|
|
||||||
Four,
|
|
||||||
#[serde(rename = "8")]
|
|
||||||
Eight,
|
|
||||||
#[serde(rename = "9")]
|
|
||||||
Nine,
|
|
||||||
#[serde(rename = "9h2")]
|
|
||||||
NineH2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<Box<dyn sbp::operators::InterpolationOperator>> for InterpolationOperator {
|
|
||||||
fn into(self) -> Box<dyn sbp::operators::InterpolationOperator> {
|
|
||||||
use sbp::operators::{Interpolation4, Interpolation8, Interpolation9, Interpolation9h2};
|
|
||||||
match self {
|
|
||||||
InterpolationOperator::Four => Box::new(Interpolation4),
|
|
||||||
InterpolationOperator::Eight => Box::new(Interpolation8),
|
|
||||||
InterpolationOperator::Nine => Box::new(Interpolation9),
|
|
||||||
InterpolationOperator::NineH2 => Box::new(Interpolation9h2),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
pub struct Interpolate {
|
|
||||||
operator: Option<InterpolationOperator>,
|
|
||||||
#[serde(alias = "neighbor")]
|
|
||||||
neighbour: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
pub struct Multi {
|
|
||||||
#[serde(alias = "neighbor")]
|
|
||||||
neighbour: String,
|
|
||||||
start: usize,
|
|
||||||
end: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "lowercase")]
|
|
||||||
pub enum BoundaryType {
|
|
||||||
This,
|
|
||||||
Interpolate(Interpolate),
|
|
||||||
#[serde(alias = "neighbor")]
|
|
||||||
Neighbour(String),
|
|
||||||
Vortex,
|
|
||||||
Multi(Vec<Multi>),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type BoundaryDescriptors = sbp::utils::Direction<Option<BoundaryType>>;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
|
|
||||||
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)]
|
|
||||||
/// Will be evaluated by evalexpr
|
|
||||||
pub struct ExpressionsConservation {
|
|
||||||
pub globals: Option<String>,
|
|
||||||
pub rho: String,
|
|
||||||
pub rhou: String,
|
|
||||||
pub rhov: String,
|
|
||||||
pub e: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
/// Will be evaluated by evalexpr
|
|
||||||
pub struct ExpressionsPressure {
|
|
||||||
pub globals: Option<String>,
|
|
||||||
pub rho: String,
|
|
||||||
pub u: String,
|
|
||||||
pub v: String,
|
|
||||||
pub p: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "lowercase")]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum Expressions {
|
|
||||||
Conservation(ExpressionsConservation),
|
|
||||||
Pressure(ExpressionsPressure),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
#[serde(rename_all = "lowercase")]
|
|
||||||
pub enum InputInitialConditions {
|
|
||||||
Vortex(euler::VortexParameters),
|
|
||||||
// File(String),
|
|
||||||
Expressions(Expressions),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum InitialConditions {
|
|
||||||
Vortex(euler::VortexParameters),
|
|
||||||
// File(hdf5::File),
|
|
||||||
Expressions(std::sync::Arc<eval::Evaluator>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Expressions> for eval::Evaluator {
|
|
||||||
type Error = ();
|
type Error = ();
|
||||||
fn try_from(expr: Expressions) -> Result<Self, Self::Error> {
|
fn try_from(expr: input::Expressions) -> Result<Self, Self::Error> {
|
||||||
let mut context = eval::default_context();
|
let mut context = eval::default_context();
|
||||||
match expr {
|
match expr {
|
||||||
Expressions::Pressure(ExpressionsPressure {
|
input::Expressions::Pressure(input::ExpressionsPressure {
|
||||||
globals,
|
globals,
|
||||||
rho,
|
rho,
|
||||||
u,
|
u,
|
||||||
|
@ -217,7 +35,7 @@ impl TryFrom<Expressions> for eval::Evaluator {
|
||||||
p,
|
p,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Expressions::Conservation(ExpressionsConservation {
|
input::Expressions::Conservation(input::ExpressionsConservation {
|
||||||
globals,
|
globals,
|
||||||
rho,
|
rho,
|
||||||
rhou,
|
rhou,
|
||||||
|
@ -245,35 +63,24 @@ impl TryFrom<Expressions> for eval::Evaluator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<InputInitialConditions> for InitialConditions {
|
impl TryFrom<input::InitialConditions> for InitialConditions {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
fn try_from(v: InputInitialConditions) -> Result<Self, Self::Error> {
|
fn try_from(v: input::InitialConditions) -> Result<Self, Self::Error> {
|
||||||
Ok(match v {
|
Ok(match v {
|
||||||
InputInitialConditions::Vortex(v) => Self::Vortex(v),
|
input::InitialConditions::Vortex(v) => Self::Vortex(v),
|
||||||
// InputInitialConditions::File(file) => Self::File(hdf5::File::open(file).unwrap()),
|
// InputInitialConditions::File(file) => Self::File(hdf5::File::open(file).unwrap()),
|
||||||
InputInitialConditions::Expressions(expr) => {
|
input::InitialConditions::Expressions(expr) => {
|
||||||
Self::Expressions(std::sync::Arc::new(expr.try_into()?))
|
Self::Expressions(std::sync::Arc::new(expr.try_into()?))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug)]
|
||||||
#[serde(rename_all = "lowercase")]
|
pub enum InitialConditions {
|
||||||
pub enum InputBoundaryConditions {
|
|
||||||
/// Initial conditions also contain the bc
|
|
||||||
#[serde(rename = "initial_conditions")]
|
|
||||||
InputInitialConditions,
|
|
||||||
Vortex(euler::VortexParameters),
|
Vortex(euler::VortexParameters),
|
||||||
Expressions(Expressions),
|
// File(hdf5::File),
|
||||||
#[serde(rename = "not_needed")]
|
Expressions(std::sync::Arc<eval::Evaluator>),
|
||||||
NotNeeded,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for InputBoundaryConditions {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::NotNeeded
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -283,22 +90,6 @@ pub enum BoundaryConditions {
|
||||||
NotNeeded,
|
NotNeeded,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_gamma() -> Float {
|
|
||||||
1.4
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
||||||
/// Input configuration (json)
|
|
||||||
pub struct Configuration {
|
|
||||||
pub grids: Grids,
|
|
||||||
pub integration_time: Float,
|
|
||||||
pub initial_conditions: InputInitialConditions,
|
|
||||||
#[serde(default)]
|
|
||||||
pub boundary_conditions: InputBoundaryConditions,
|
|
||||||
#[serde(default = "default_gamma")]
|
|
||||||
pub gamma: Float,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RuntimeConfiguration {
|
pub struct RuntimeConfiguration {
|
||||||
pub names: Vec<String>,
|
pub names: Vec<String>,
|
||||||
pub grids: Vec<sbp::grid::Grid>,
|
pub grids: Vec<sbp::grid::Grid>,
|
||||||
|
@ -309,7 +100,7 @@ pub struct RuntimeConfiguration {
|
||||||
pub boundary_conditions: BoundaryConditions,
|
pub boundary_conditions: BoundaryConditions,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Configuration {
|
impl input::Configuration {
|
||||||
pub fn into_runtime(mut self) -> RuntimeConfiguration {
|
pub fn into_runtime(mut self) -> RuntimeConfiguration {
|
||||||
let gamma = self.gamma;
|
let gamma = self.gamma;
|
||||||
let _ = euler::GAMMA.set(gamma);
|
let _ = euler::GAMMA.set(gamma);
|
||||||
|
@ -320,12 +111,12 @@ impl Configuration {
|
||||||
self.initial_conditions.clone().try_into().unwrap();
|
self.initial_conditions.clone().try_into().unwrap();
|
||||||
|
|
||||||
let boundary_conditions = match &self.boundary_conditions {
|
let boundary_conditions = match &self.boundary_conditions {
|
||||||
InputBoundaryConditions::NotNeeded => BoundaryConditions::NotNeeded,
|
input::BoundaryConditions::NotNeeded => BoundaryConditions::NotNeeded,
|
||||||
InputBoundaryConditions::Vortex(vp) => BoundaryConditions::Vortex(vp.clone()),
|
input::BoundaryConditions::Vortex(vp) => BoundaryConditions::Vortex(vp.clone()),
|
||||||
InputBoundaryConditions::Expressions(expr) => BoundaryConditions::Expressions(
|
input::BoundaryConditions::Expressions(expr) => BoundaryConditions::Expressions(
|
||||||
std::sync::Arc::new(expr.clone().try_into().unwrap()),
|
std::sync::Arc::new(expr.clone().try_into().unwrap()),
|
||||||
),
|
),
|
||||||
InputBoundaryConditions::InputInitialConditions => match &initial_conditions {
|
input::BoundaryConditions::InputInitialConditions => match &initial_conditions {
|
||||||
InitialConditions::Vortex(vp) => BoundaryConditions::Vortex(vp.clone()),
|
InitialConditions::Vortex(vp) => BoundaryConditions::Vortex(vp.clone()),
|
||||||
InitialConditions::Expressions(expr) => {
|
InitialConditions::Expressions(expr) => {
|
||||||
BoundaryConditions::Expressions(expr.clone())
|
BoundaryConditions::Expressions(expr.clone())
|
||||||
|
@ -337,6 +128,7 @@ impl Configuration {
|
||||||
.grids
|
.grids
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_name, g)| {
|
.map(|(_name, g)| {
|
||||||
|
use input::ArrayForm;
|
||||||
let x: ArrayForm =
|
let x: ArrayForm =
|
||||||
g.x.clone()
|
g.x.clone()
|
||||||
.unwrap_or_else(|| default.x.as_ref().unwrap().clone())
|
.unwrap_or_else(|| default.x.as_ref().unwrap().clone())
|
||||||
|
@ -413,8 +205,8 @@ impl Configuration {
|
||||||
.unwrap_or_else(|| panic!("No eta operator found for grid: {}", name))
|
.unwrap_or_else(|| panic!("No eta operator found for grid: {}", name))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
use input::Operator as op;
|
||||||
use sbp::operators::*;
|
use sbp::operators::*;
|
||||||
use Operator as op;
|
|
||||||
|
|
||||||
let matcher = |op| -> Box<dyn SbpOperator2d> {
|
let matcher = |op| -> Box<dyn SbpOperator2d> {
|
||||||
match op {
|
match op {
|
||||||
|
@ -436,6 +228,7 @@ impl Configuration {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, (name, g))| {
|
.map(|(i, (name, g))| {
|
||||||
let default_bc = default.boundary_conditions.clone().unwrap_or_default();
|
let default_bc = default.boundary_conditions.clone().unwrap_or_default();
|
||||||
|
use input::BoundaryType;
|
||||||
g.boundary_conditions
|
g.boundary_conditions
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
|
@ -499,211 +292,3 @@ impl Configuration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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>),
|
|
||||||
/// The usize is the inner dimension (nx)
|
|
||||||
Array2(ndarray::Array2<Float>),
|
|
||||||
/*
|
|
||||||
/// A still unknown array, will be filled out by later
|
|
||||||
/// pass when initial_conditions file is known
|
|
||||||
Unknown,
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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: Some(Operator::Upwind4),
|
|
||||||
eta: Some(Operator::Upwind9),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
grids.insert(
|
|
||||||
"operators2".to_string(),
|
|
||||||
GridConfig {
|
|
||||||
boundary_conditions: None,
|
|
||||||
x: None,
|
|
||||||
y: None,
|
|
||||||
operators: Some(Operators {
|
|
||||||
xi: Some(Operator::Upwind4h2),
|
|
||||||
eta: Some(Operator::Upwind9h2),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
grids.insert(
|
|
||||||
"operators3".to_string(),
|
|
||||||
GridConfig {
|
|
||||||
boundary_conditions: None,
|
|
||||||
x: None,
|
|
||||||
y: None,
|
|
||||||
operators: Some(Operators {
|
|
||||||
xi: Some(Operator::Sbp4),
|
|
||||||
eta: Some(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,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
grids.insert(
|
|
||||||
"boundary_conditions_multigrid".to_string(),
|
|
||||||
GridConfig {
|
|
||||||
boundary_conditions: Some(BoundaryDescriptors {
|
|
||||||
north: Some(BoundaryType::Multi(vec![Multi {
|
|
||||||
neighbour: "name_of_grid".to_string(),
|
|
||||||
start: 4,
|
|
||||||
end: 7,
|
|
||||||
}])),
|
|
||||||
south: Some(BoundaryType::Multi(vec![
|
|
||||||
Multi {
|
|
||||||
neighbour: "name_of_grid".to_string(),
|
|
||||||
start: 4,
|
|
||||||
end: 7,
|
|
||||||
},
|
|
||||||
Multi {
|
|
||||||
neighbour: "name_of_grid".to_string(),
|
|
||||||
start: 41,
|
|
||||||
end: 912,
|
|
||||||
},
|
|
||||||
])),
|
|
||||||
east: None,
|
|
||||||
west: None,
|
|
||||||
}),
|
|
||||||
x: None,
|
|
||||||
y: None,
|
|
||||||
operators: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
let configuration = Configuration {
|
|
||||||
grids,
|
|
||||||
integration_time: 2.0,
|
|
||||||
initial_conditions: InputInitialConditions::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
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
boundary_conditions: InputBoundaryConditions::default(),
|
|
||||||
};
|
|
||||||
println!("{}", json5::to_string(&configuration).unwrap());
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue