add vortex bc
This commit is contained in:
		| @@ -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) => { | ||||||
|             jgrids |             if dir == "vortex" { | ||||||
|                 .iter() |                 euler::BoundaryCharacteristic::Vortex(vortexparams) | ||||||
|                 .position(|other| other.name.as_ref().map_or(false, |name| name == dir)) |             } else { | ||||||
|                 .unwrap(), |                 euler::BoundaryCharacteristic::Grid( | ||||||
|         ), |                     jgrids | ||||||
|  |                         .iter() | ||||||
|  |                         .position(|other| other.name.as_ref().map_or(false, |name| name == dir)) | ||||||
|  |                         .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> { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Magnus Ulimoen
					Magnus Ulimoen