add vortex bc
This commit is contained in:
parent
85a8c92cd5
commit
de03fb6889
|
@ -17,6 +17,8 @@ struct System<T: operators::UpwindOperator> {
|
||||||
grids: Vec<grid::Grid>,
|
grids: Vec<grid::Grid>,
|
||||||
metrics: Vec<grid::Metrics<T>>,
|
metrics: Vec<grid::Metrics<T>>,
|
||||||
bt: Vec<euler::BoundaryCharacteristics>,
|
bt: Vec<euler::BoundaryCharacteristics>,
|
||||||
|
eb: Vec<MaybeBoundary>,
|
||||||
|
time: Float,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: operators::UpwindOperator> System<T> {
|
impl<T: operators::UpwindOperator> System<T> {
|
||||||
|
@ -35,6 +37,36 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
.collect();
|
.collect();
|
||||||
let k = [fnow.clone(), fnow.clone(), fnow.clone(), fnow.clone()];
|
let k = [fnow.clone(), fnow.clone(), fnow.clone(), fnow.clone()];
|
||||||
let metrics = grids.iter().map(|g| g.metrics().unwrap()).collect();
|
let metrics = grids.iter().map(|g| g.metrics().unwrap()).collect();
|
||||||
|
let eb = bt
|
||||||
|
.iter()
|
||||||
|
.zip(&grids)
|
||||||
|
.map(|(bt, grid)| MaybeBoundary {
|
||||||
|
n: match bt.north {
|
||||||
|
euler::BoundaryCharacteristic::Vortex(_) => {
|
||||||
|
Some(ndarray::Array2::zeros((4, grid.nx())))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
s: match bt.north {
|
||||||
|
euler::BoundaryCharacteristic::Vortex(_) => {
|
||||||
|
Some(ndarray::Array2::zeros((4, grid.nx())))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
e: match bt.north {
|
||||||
|
euler::BoundaryCharacteristic::Vortex(_) => {
|
||||||
|
Some(ndarray::Array2::zeros((4, grid.ny())))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
w: match bt.north {
|
||||||
|
euler::BoundaryCharacteristic::Vortex(_) => {
|
||||||
|
Some(ndarray::Array2::zeros((4, grid.ny())))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
fnow,
|
fnow,
|
||||||
|
@ -44,6 +76,8 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
grids,
|
grids,
|
||||||
metrics,
|
metrics,
|
||||||
bt,
|
bt,
|
||||||
|
eb,
|
||||||
|
time: 0.0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +89,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
|
|
||||||
fn advance(&mut self, dt: Float) {
|
fn advance(&mut self, dt: Float) {
|
||||||
for i in 0.. {
|
for i in 0.. {
|
||||||
|
let time;
|
||||||
let fnext;
|
let fnext;
|
||||||
match i {
|
match i {
|
||||||
0 => {
|
0 => {
|
||||||
|
@ -62,6 +97,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
fut.assign(prev);
|
fut.assign(prev);
|
||||||
}
|
}
|
||||||
fnext = &mut self.k[i];
|
fnext = &mut self.k[i];
|
||||||
|
time = self.time;
|
||||||
}
|
}
|
||||||
1 | 2 => {
|
1 | 2 => {
|
||||||
for ((prev, fut), k) in self
|
for ((prev, fut), k) in self
|
||||||
|
@ -74,6 +110,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
fut.scaled_add(1.0 / 2.0 * dt, k);
|
fut.scaled_add(1.0 / 2.0 * dt, k);
|
||||||
}
|
}
|
||||||
fnext = &mut self.k[i];
|
fnext = &mut self.k[i];
|
||||||
|
time = self.time + dt / 2.0;
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
for ((prev, fut), k) in self
|
for ((prev, fut), k) in self
|
||||||
|
@ -86,6 +123,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
fut.scaled_add(dt, k);
|
fut.scaled_add(dt, k);
|
||||||
}
|
}
|
||||||
fnext = &mut self.k[i];
|
fnext = &mut self.k[i];
|
||||||
|
time = self.time + dt;
|
||||||
}
|
}
|
||||||
4 => {
|
4 => {
|
||||||
for (((((prev, fut), k0), k1), k2), k3) in self
|
for (((((prev, fut), k0), k1), k2), k3) in self
|
||||||
|
@ -108,6 +146,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
std::mem::swap(&mut self.fnext, &mut self.fnow);
|
std::mem::swap(&mut self.fnext, &mut self.fnow);
|
||||||
|
self.time += dt;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -120,27 +159,45 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
let bt = self
|
let bt = self
|
||||||
.bt
|
.bt
|
||||||
.iter()
|
.iter()
|
||||||
|
.zip(&mut self.eb)
|
||||||
|
.zip(&self.grids)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, bt)| euler::BoundaryTerms {
|
.map(|(i, ((bt, eb), grid))| euler::BoundaryTerms {
|
||||||
north: match bt.north {
|
north: match bt.north {
|
||||||
euler::BoundaryCharacteristic::This => fields[i].south(),
|
euler::BoundaryCharacteristic::This => fields[i].south(),
|
||||||
euler::BoundaryCharacteristic::Grid(g) => fields[g].south(),
|
euler::BoundaryCharacteristic::Grid(g) => fields[g].south(),
|
||||||
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
|
euler::BoundaryCharacteristic::Vortex(v) => {
|
||||||
|
let field = eb.n.as_mut().unwrap();
|
||||||
|
vortexify(field.view_mut(), grid.north(), v, time);
|
||||||
|
field.view()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
south: match bt.south {
|
south: match bt.south {
|
||||||
euler::BoundaryCharacteristic::This => fields[i].north(),
|
euler::BoundaryCharacteristic::This => fields[i].north(),
|
||||||
euler::BoundaryCharacteristic::Grid(g) => fields[g].north(),
|
euler::BoundaryCharacteristic::Grid(g) => fields[g].north(),
|
||||||
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
|
euler::BoundaryCharacteristic::Vortex(v) => {
|
||||||
|
let field = eb.s.as_mut().unwrap();
|
||||||
|
vortexify(field.view_mut(), grid.south(), v, time);
|
||||||
|
field.view()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
west: match bt.west {
|
west: match bt.west {
|
||||||
euler::BoundaryCharacteristic::This => fields[i].east(),
|
euler::BoundaryCharacteristic::This => fields[i].east(),
|
||||||
euler::BoundaryCharacteristic::Grid(g) => fields[g].east(),
|
euler::BoundaryCharacteristic::Grid(g) => fields[g].east(),
|
||||||
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
|
euler::BoundaryCharacteristic::Vortex(v) => {
|
||||||
|
let field = eb.w.as_mut().unwrap();
|
||||||
|
vortexify(field.view_mut(), grid.west(), v, time);
|
||||||
|
field.view()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
east: match bt.east {
|
east: match bt.east {
|
||||||
euler::BoundaryCharacteristic::This => fields[i].west(),
|
euler::BoundaryCharacteristic::This => fields[i].west(),
|
||||||
euler::BoundaryCharacteristic::Grid(g) => fields[g].west(),
|
euler::BoundaryCharacteristic::Grid(g) => fields[g].west(),
|
||||||
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
|
euler::BoundaryCharacteristic::Vortex(v) => {
|
||||||
|
let field = eb.e.as_mut().unwrap();
|
||||||
|
vortexify(field.view_mut(), grid.east(), v, time);
|
||||||
|
field.view()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -159,6 +216,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
|
|
||||||
fn advance_parallel(&mut self, dt: Float, s: &rayon::ThreadPool) {
|
fn advance_parallel(&mut self, dt: Float, s: &rayon::ThreadPool) {
|
||||||
for i in 0.. {
|
for i in 0.. {
|
||||||
|
let time;
|
||||||
match i {
|
match i {
|
||||||
0 => {
|
0 => {
|
||||||
s.scope(|s| {
|
s.scope(|s| {
|
||||||
|
@ -168,6 +226,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
time = self.time;
|
||||||
}
|
}
|
||||||
1 | 2 => {
|
1 | 2 => {
|
||||||
s.scope(|s| {
|
s.scope(|s| {
|
||||||
|
@ -183,6 +242,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
time = self.time + dt / 2.0;
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
s.scope(|s| {
|
s.scope(|s| {
|
||||||
|
@ -198,6 +258,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
time = self.time + dt;
|
||||||
}
|
}
|
||||||
4 => {
|
4 => {
|
||||||
s.scope(|s| {
|
s.scope(|s| {
|
||||||
|
@ -224,6 +285,7 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
std::mem::swap(&mut self.fnext, &mut self.fnow);
|
std::mem::swap(&mut self.fnext, &mut self.fnow);
|
||||||
|
self.time += dt;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -236,27 +298,45 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
let bt = self
|
let bt = self
|
||||||
.bt
|
.bt
|
||||||
.iter()
|
.iter()
|
||||||
|
.zip(&mut self.eb)
|
||||||
|
.zip(&self.grids)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, bt)| euler::BoundaryTerms {
|
.map(|(i, ((bt, eb), grid))| euler::BoundaryTerms {
|
||||||
north: match bt.north {
|
north: match bt.north {
|
||||||
euler::BoundaryCharacteristic::This => fields[i].south(),
|
euler::BoundaryCharacteristic::This => fields[i].south(),
|
||||||
euler::BoundaryCharacteristic::Grid(g) => fields[g].south(),
|
euler::BoundaryCharacteristic::Grid(g) => fields[g].south(),
|
||||||
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
|
euler::BoundaryCharacteristic::Vortex(v) => {
|
||||||
|
let field = eb.n.as_mut().unwrap();
|
||||||
|
vortexify(field.view_mut(), grid.north(), v, time);
|
||||||
|
field.view()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
south: match bt.south {
|
south: match bt.south {
|
||||||
euler::BoundaryCharacteristic::This => fields[i].north(),
|
euler::BoundaryCharacteristic::This => fields[i].north(),
|
||||||
euler::BoundaryCharacteristic::Grid(g) => fields[g].north(),
|
euler::BoundaryCharacteristic::Grid(g) => fields[g].north(),
|
||||||
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
|
euler::BoundaryCharacteristic::Vortex(v) => {
|
||||||
|
let field = eb.s.as_mut().unwrap();
|
||||||
|
vortexify(field.view_mut(), grid.south(), v, time);
|
||||||
|
field.view()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
west: match bt.west {
|
west: match bt.west {
|
||||||
euler::BoundaryCharacteristic::This => fields[i].east(),
|
euler::BoundaryCharacteristic::This => fields[i].east(),
|
||||||
euler::BoundaryCharacteristic::Grid(g) => fields[g].east(),
|
euler::BoundaryCharacteristic::Grid(g) => fields[g].east(),
|
||||||
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
|
euler::BoundaryCharacteristic::Vortex(v) => {
|
||||||
|
let field = eb.w.as_mut().unwrap();
|
||||||
|
vortexify(field.view_mut(), grid.west(), v, time);
|
||||||
|
field.view()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
east: match bt.east {
|
east: match bt.east {
|
||||||
euler::BoundaryCharacteristic::This => fields[i].west(),
|
euler::BoundaryCharacteristic::This => fields[i].west(),
|
||||||
euler::BoundaryCharacteristic::Grid(g) => fields[g].west(),
|
euler::BoundaryCharacteristic::Grid(g) => fields[g].west(),
|
||||||
euler::BoundaryCharacteristic::Vortex(_) => todo!(),
|
euler::BoundaryCharacteristic::Vortex(v) => {
|
||||||
|
let field = eb.e.as_mut().unwrap();
|
||||||
|
vortexify(field.view_mut(), grid.east(), v, time);
|
||||||
|
field.view()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -273,6 +353,30 @@ impl<T: operators::UpwindOperator> System<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct MaybeBoundary {
|
||||||
|
n: Option<ndarray::Array2<Float>>,
|
||||||
|
s: Option<ndarray::Array2<Float>>,
|
||||||
|
e: Option<ndarray::Array2<Float>>,
|
||||||
|
w: Option<ndarray::Array2<Float>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vortexify(
|
||||||
|
mut field: ndarray::ArrayViewMut2<Float>,
|
||||||
|
yx: (ndarray::ArrayView1<Float>, ndarray::ArrayView1<Float>),
|
||||||
|
v: euler::VortexParameters,
|
||||||
|
t: Float,
|
||||||
|
) {
|
||||||
|
let mut fiter = field.outer_iter_mut();
|
||||||
|
let (rho, rhou, rhov, e) = (
|
||||||
|
fiter.next().unwrap(),
|
||||||
|
fiter.next().unwrap(),
|
||||||
|
fiter.next().unwrap(),
|
||||||
|
fiter.next().unwrap(),
|
||||||
|
);
|
||||||
|
let (y, x) = yx;
|
||||||
|
euler::vortex(rho, rhou, rhov, e, x, y, t, v);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
struct Options {
|
struct Options {
|
||||||
|
@ -297,15 +401,22 @@ fn main() {
|
||||||
|
|
||||||
let json = json::parse(&filecontents).unwrap();
|
let json = json::parse(&filecontents).unwrap();
|
||||||
let jgrids = json_to_grids(json["grids"].clone()).unwrap();
|
let jgrids = json_to_grids(json["grids"].clone()).unwrap();
|
||||||
|
let vortexparams = utils::json_to_vortex(json["vortex"].clone());
|
||||||
|
|
||||||
let mut bt = Vec::with_capacity(jgrids.len());
|
let mut bt = Vec::with_capacity(jgrids.len());
|
||||||
let determine_bc = |dir| match dir {
|
let determine_bc = |dir| match dir {
|
||||||
Some(dir) => euler::BoundaryCharacteristic::Grid(
|
Some(dir) => {
|
||||||
|
if dir == "vortex" {
|
||||||
|
euler::BoundaryCharacteristic::Vortex(vortexparams)
|
||||||
|
} else {
|
||||||
|
euler::BoundaryCharacteristic::Grid(
|
||||||
jgrids
|
jgrids
|
||||||
.iter()
|
.iter()
|
||||||
.position(|other| other.name.as_ref().map_or(false, |name| name == dir))
|
.position(|other| other.name.as_ref().map_or(false, |name| name == dir))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
None => euler::BoundaryCharacteristic::This,
|
None => euler::BoundaryCharacteristic::This,
|
||||||
};
|
};
|
||||||
for grid in &jgrids {
|
for grid in &jgrids {
|
||||||
|
@ -320,8 +431,6 @@ fn main() {
|
||||||
|
|
||||||
let integration_time: Float = json["integration_time"].as_number().unwrap().into();
|
let integration_time: Float = json["integration_time"].as_number().unwrap().into();
|
||||||
|
|
||||||
let vortexparams = utils::json_to_vortex(json["vortex"].clone());
|
|
||||||
|
|
||||||
let mut sys = System::<sbp::operators::Upwind4>::new(grids, bt);
|
let mut sys = System::<sbp::operators::Upwind4>::new(grids, bt);
|
||||||
sys.vortex(0.0, vortexparams);
|
sys.vortex(0.0, vortexparams);
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,31 @@ impl Grid {
|
||||||
) -> Result<Metrics<SBP>, ndarray::ShapeError> {
|
) -> Result<Metrics<SBP>, ndarray::ShapeError> {
|
||||||
Metrics::new(self)
|
Metrics::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn north(&self) -> (ndarray::ArrayView1<Float>, ndarray::ArrayView1<Float>) {
|
||||||
|
(
|
||||||
|
self.y.slice(ndarray::s![self.ny() - 1, ..]),
|
||||||
|
self.x.slice(ndarray::s![self.ny() - 1, ..]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn south(&self) -> (ndarray::ArrayView1<Float>, ndarray::ArrayView1<Float>) {
|
||||||
|
(
|
||||||
|
self.y.slice(ndarray::s![0, ..]),
|
||||||
|
self.x.slice(ndarray::s![0, ..]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn west(&self) -> (ndarray::ArrayView1<Float>, ndarray::ArrayView1<Float>) {
|
||||||
|
(
|
||||||
|
self.y.slice(ndarray::s![.., 0]),
|
||||||
|
self.x.slice(ndarray::s![.., 0]),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
pub fn east(&self) -> (ndarray::ArrayView1<Float>, ndarray::ArrayView1<Float>) {
|
||||||
|
(
|
||||||
|
self.y.slice(ndarray::s![.., self.nx() - 1]),
|
||||||
|
self.x.slice(ndarray::s![.., self.nx() - 1]),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SBP: super::operators::SbpOperator> Metrics<SBP> {
|
impl<SBP: super::operators::SbpOperator> Metrics<SBP> {
|
||||||
|
|
Loading…
Reference in New Issue