add vortex bc

This commit is contained in:
Magnus Ulimoen 2020-04-06 22:11:35 +02:00
parent 85a8c92cd5
commit de03fb6889
2 changed files with 152 additions and 18 deletions

View File

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

View File

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