2020-02-25 18:44:13 +00:00
|
|
|
#![cfg(feature = "expensive_tests")]
|
2020-05-01 22:22:59 +00:00
|
|
|
use euler::*;
|
2020-02-24 19:10:59 +00:00
|
|
|
use ndarray::prelude::*;
|
2021-03-30 17:09:11 +00:00
|
|
|
use sbp::{
|
|
|
|
operators::{SbpOperator2d, UpwindOperator2d},
|
|
|
|
Float,
|
|
|
|
};
|
2020-02-24 19:10:59 +00:00
|
|
|
|
2021-03-30 17:09:11 +00:00
|
|
|
fn run_with_size(size: usize, op: impl SbpOperator2d + UpwindOperator2d + Copy) -> Float {
|
2020-02-25 18:44:13 +00:00
|
|
|
let nx = size;
|
|
|
|
let ny = size;
|
2020-02-24 19:10:59 +00:00
|
|
|
let x = Array1::linspace(-5.0, 5.0, nx);
|
|
|
|
let y = Array1::linspace(-5.0, 5.0, ny);
|
|
|
|
|
|
|
|
let x = x.broadcast((ny, nx)).unwrap().to_owned();
|
|
|
|
let y = y
|
|
|
|
.reversed_axes()
|
|
|
|
.broadcast((nx, ny))
|
|
|
|
.unwrap()
|
|
|
|
.reversed_axes()
|
|
|
|
.to_owned();
|
|
|
|
|
|
|
|
let vortex_params = VortexParameters {
|
2020-04-23 15:49:31 +00:00
|
|
|
vortices: {
|
|
|
|
let mut v = ArrayVec::new();
|
|
|
|
v.push(Vortice {
|
|
|
|
x0: -1.0,
|
|
|
|
y0: 0.0,
|
|
|
|
rstar: 0.5,
|
|
|
|
eps: 1.0,
|
|
|
|
});
|
|
|
|
v
|
|
|
|
},
|
2020-02-24 19:10:59 +00:00
|
|
|
mach: 0.5,
|
|
|
|
};
|
|
|
|
|
2020-04-23 15:49:31 +00:00
|
|
|
let mut sys = System::new(x, y, op);
|
|
|
|
sys.vortex(0.0, vortex_params.clone());
|
2020-02-24 19:10:59 +00:00
|
|
|
|
2020-02-25 18:44:13 +00:00
|
|
|
let time = 0.2;
|
2020-02-27 19:26:43 +00:00
|
|
|
let dt = 0.2 * Float::min(1.0 / (nx - 1) as Float, 1.0 / (ny - 1) as Float);
|
2020-02-24 19:10:59 +00:00
|
|
|
|
|
|
|
let nsteps = (time / dt) as usize;
|
|
|
|
for _ in 0..nsteps {
|
|
|
|
sys.advance_upwind(dt);
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut verifield = Field::new(ny, nx);
|
2020-04-23 15:49:31 +00:00
|
|
|
verifield.vortex(sys.x(), sys.y(), nsteps as Float * dt, &vortex_params);
|
2020-02-24 19:10:59 +00:00
|
|
|
|
2020-04-23 15:49:31 +00:00
|
|
|
verifield.h2_err(sys.field(), &op)
|
2020-02-24 19:10:59 +00:00
|
|
|
}
|
|
|
|
|
2021-03-30 17:09:11 +00:00
|
|
|
fn convergence(op: impl SbpOperator2d + UpwindOperator2d + Copy, expected_q: Float) {
|
2020-02-27 19:26:43 +00:00
|
|
|
let sizes = [25, 35, 50, 71, 100, 150, 200];
|
|
|
|
let mut prev: Option<(usize, Float)> = None;
|
2021-03-30 17:09:11 +00:00
|
|
|
let mut q_last = None;
|
2020-02-25 18:44:13 +00:00
|
|
|
println!("Size\tError(h2)\tq");
|
2020-02-24 19:10:59 +00:00
|
|
|
for size in &sizes {
|
2020-02-25 18:44:13 +00:00
|
|
|
print!("{:3}x{:3}", size, size);
|
2020-04-23 15:49:31 +00:00
|
|
|
let e = run_with_size(*size, op);
|
2020-02-25 18:44:13 +00:00
|
|
|
print!("\t{:.10}", e);
|
|
|
|
if let Some(prev) = prev.take() {
|
|
|
|
let m0 = size * size;
|
|
|
|
let e0 = e;
|
|
|
|
|
|
|
|
let (size1, e1) = prev;
|
|
|
|
let m1 = size1 * size1;
|
|
|
|
|
2020-02-27 19:26:43 +00:00
|
|
|
let q =
|
|
|
|
Float::log10(e0 / e1) / Float::log10((m0 as Float / m1 as Float).powf(1.0 / 2.0));
|
2020-02-25 18:44:13 +00:00
|
|
|
print!("\t{}", q);
|
2021-03-30 17:09:11 +00:00
|
|
|
q_last = Some(q);
|
2020-02-25 18:44:13 +00:00
|
|
|
}
|
|
|
|
println!();
|
|
|
|
prev = Some((*size, e));
|
2020-02-24 19:10:59 +00:00
|
|
|
}
|
2021-03-30 17:09:11 +00:00
|
|
|
let actual_q = q_last.unwrap();
|
|
|
|
assert!(actual_q < expected_q);
|
2020-03-30 21:15:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn convergence_upwind4() {
|
2021-03-30 17:09:11 +00:00
|
|
|
convergence(sbp::operators::Upwind4, -4.0);
|
2020-03-30 21:15:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn convergence_upwind9() {
|
2021-03-30 17:09:11 +00:00
|
|
|
convergence(sbp::operators::Upwind9, -8.5);
|
2020-02-24 19:10:59 +00:00
|
|
|
}
|