Skip to content

Commit

Permalink
Add configurable number of tracers
Browse files Browse the repository at this point in the history
  • Loading branch information
joshburkart committed Jul 4, 2024
1 parent cbbde49 commit 0d6e5fc
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 45 deletions.
6 changes: 3 additions & 3 deletions flow/src/bases/fourier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,11 @@ impl Basis for RectangularPeriodicBasis {
[&self.axes[0], &self.axes[1]]
}

fn make_random_points(&self) -> nd::Array2<Float> {
fn make_random_points(&self, num: usize) -> nd::Array2<Float> {
let mut rng = frand::Rand::with_seed(0);
let mut points = nd::Array2::zeros((2, crate::physics::NUM_TRACER_POINTS));
let mut points = nd::Array2::zeros((2, num));
for j in 0..2 {
for i in 0..crate::physics::NUM_TRACER_POINTS {
for i in 0..num {
points[[j, i]] = rng.gen_range((0.)..self.lengths[j]);
}
}
Expand Down
2 changes: 1 addition & 1 deletion flow/src/bases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub trait Basis: Sync + Send {
fn lengths(&self) -> [Float; 2];
fn axes(&self) -> [&nd::Array1<Float>; 2];

fn make_random_points(&self) -> nd::Array2<Float>;
fn make_random_points(&self, num: usize) -> nd::Array2<Float>;

fn make_scalar<F: Fn(Float, Float) -> Float>(&self, f: F) -> nd::Array2<Float> {
let [xs, ys] = self.axes();
Expand Down
6 changes: 3 additions & 3 deletions flow/src/bases/ylm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ impl Basis for SphericalHarmonicBasis {
[&self.mu_gauss_legendre_quad.nodes, &self.phi_grid]
}

fn make_random_points(&self) -> nd::Array2<Float> {
fn make_random_points(&self, num: usize) -> nd::Array2<Float> {
let mut rng = frand::Rand::with_seed(0);
let mut points = nd::Array2::zeros((2, crate::physics::NUM_TRACER_POINTS));
for i in 0..crate::physics::NUM_TRACER_POINTS {
let mut points = nd::Array2::zeros((2, num));
for i in 0..num {
// Crazy: https://math.stackexchange.com/a/1586015/146975
let mu = rng.gen_range((-1.)..(1.));
let phi = rng.gen_range((0.)..(float_consts::TAU));
Expand Down
4 changes: 3 additions & 1 deletion flow/src/examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub fn bump_2d_spectral(

let lengths = [5., 15.];
let bump_size = 0.3;
let num_tracers = 100;

// Want to generate a power so that a periodic "bump" is generated of width
// `bump_size`. Start from FWHM definition:
Expand All @@ -31,7 +32,7 @@ pub fn bump_2d_spectral(
lengths,
));
let terrain_height = basis.scalar_to_spectral(&basis.make_scalar(|_, _| 0.));
let mut initial_fields = physics::Fields::zeros(basis.clone());
let mut initial_fields = physics::Fields::zeros(basis.clone(), num_tracers);
initial_fields.assign_height(&basis.scalar_to_spectral(&basis.make_scalar(|x, y| {
base_height
+ amplitude
Expand All @@ -46,6 +47,7 @@ pub fn bump_2d_spectral(
})));
let problem = physics::Problem {
basis,
num_tracers,
terrain_height,
kinematic_viscosity,
tidal_prefactor: 0.,
Expand Down
15 changes: 5 additions & 10 deletions flow/src/physics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use crate::{
ComplexFloat, Float, RawComplexFloatData, RawFloatData,
};

pub const NUM_TRACER_POINTS: usize = 6000;

pub struct FieldsSnapshot<B: bases::Basis> {
pub t: Float,
pub fields: Fields<nd::OwnedRepr<ComplexFloat>, B>,
Expand Down Expand Up @@ -82,20 +80,16 @@ impl<B: bases::Basis> Fields<nd::OwnedRepr<ComplexFloat>, B> {
}

impl<B: bases::Basis> Fields<nd::OwnedRepr<ComplexFloat>, B> {
pub fn zeros(basis: std::sync::Arc<B>) -> Self {
let len =
basis.scalar_spectral_size() + basis.vector_spectral_size() + 1 + NUM_TRACER_POINTS;
pub fn zeros(basis: std::sync::Arc<B>, num_tracers: usize) -> Self {
let len = basis.scalar_spectral_size() + basis.vector_spectral_size() + 1 + num_tracers;
let storage = nd::Array1::zeros([len]);
Self { basis, storage }
}
}

impl<S: RawComplexFloatData, B: bases::Basis> Fields<S, B> {
pub fn size(&self) -> usize {
self.basis.scalar_spectral_size()
+ self.basis.vector_spectral_size()
+ 1
+ NUM_TRACER_POINTS
self.storage.len()
}

pub fn height_spectral(&self) -> B::SpectralScalarField {
Expand Down Expand Up @@ -206,6 +200,7 @@ impl<S: RawComplexFloatData + nd::RawDataClone, B: bases::Basis> Clone for Field

pub struct Problem<B: bases::Basis> {
pub basis: std::sync::Arc<B>,
pub num_tracers: usize,

pub terrain_height: B::SpectralScalarField,

Expand Down Expand Up @@ -373,7 +368,7 @@ where
let mut fields = Fields::new_mut(problem.basis.clone(), storage.view_mut());
fields.assign_height(&initial_fields.height_spectral());
fields.assign_velocity(&initial_fields.velocity_spectral());
fields.assign_tracers(problem.basis.make_random_points().view());
fields.assign_tracers(problem.basis.make_random_points(problem.num_tracers).view());

let mut abs_tol_storage = nd::Array1::<Float>::zeros(size);
let mut abs_tol_fields = Fields::new_mut(problem.basis.clone(), abs_tol_storage.view_mut());
Expand Down
3 changes: 2 additions & 1 deletion pyflow/src/examples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ pub fn bump_2d_spectral(
};
let basis = std::sync::Arc::new(bases::ylm::SphericalHarmonicBasis::new(num_points));
let terrain_height = basis.scalar_to_spectral(&basis.make_scalar(|_, _| 1.));
let mut initial_fields = physics::Fields::zeros(basis.clone());
let mut initial_fields = physics::Fields::zeros(basis.clone(), 100);
let powx = pow(bump_size, 1.);
let powy = pow(bump_size, 1.);
initial_fields.assign_height(&basis.scalar_to_spectral(&basis.make_scalar(|mu, phi| {
Expand All @@ -96,6 +96,7 @@ pub fn bump_2d_spectral(
})));
let problem = physics::Problem {
basis,
num_tracers: 100,
terrain_height,
lunar_distance: 1.,
tidal_prefactor: 0.,
Expand Down
32 changes: 20 additions & 12 deletions tsunami/src/geom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ enum GeometryImpl {
}

impl Geometry {
pub fn new(geometry_type: GeometryType, resolution_level: u32) -> Self {
pub fn new(geometry_type: GeometryType, resolution_level: u32, num_tracers: usize) -> Self {
Self(match geometry_type {
GeometryType::Sphere => GeometryImpl::Sphere(SphereGeometry::new(resolution_level)),
GeometryType::Torus => GeometryImpl::Torus(TorusGeometry::new(resolution_level)),
GeometryType::Sphere => {
GeometryImpl::Sphere(SphereGeometry::new(resolution_level, num_tracers))
}
GeometryType::Torus => {
GeometryImpl::Torus(TorusGeometry::new(resolution_level, num_tracers))
}
})
}

Expand Down Expand Up @@ -159,10 +163,10 @@ pub struct SphereGeometry {
}

impl SphereGeometry {
pub fn new(resolution_level: u32) -> Self {
pub fn new(resolution_level: u32, num_tracers: usize) -> Self {
use flow::bases::Basis;

let (base_height, solver) = Self::make_solver(resolution_level);
let (base_height, solver) = Self::make_solver(resolution_level, num_tracers);
let prev_fields_snapshot = solver.fields_snapshot();
let curr_fields_snapshot = solver.fields_snapshot();

Expand Down Expand Up @@ -244,6 +248,7 @@ impl SphereGeometry {

fn make_solver(
resolution_level: u32,
num_tracers: usize,
) -> (
Float,
flow::physics::Solver<flow::bases::ylm::SphericalHarmonicBasis>,
Expand All @@ -261,12 +266,13 @@ impl SphereGeometry {

let basis = std::sync::Arc::new(flow::bases::ylm::SphericalHarmonicBasis::new(max_l));
let terrain_height = basis.scalar_to_spectral(&basis.make_scalar(|_, _| 1.));
let mut initial_fields = flow::physics::Fields::zeros(basis.clone());
let mut initial_fields = flow::physics::Fields::zeros(basis.clone(), num_tracers);
let initial_height_grid = basis.make_scalar(|_, _| base_height);
initial_fields.assign_height(&basis.scalar_to_spectral(&initial_height_grid));
initial_fields.assign_tracers(basis.make_random_points().view());
initial_fields.assign_tracers(basis.make_random_points(num_tracers).view());
let problem = flow::physics::Problem {
basis,
num_tracers,
terrain_height,
kinematic_viscosity,
rotation_angular_speed,
Expand Down Expand Up @@ -314,10 +320,10 @@ struct TorusGeometry {
}

impl TorusGeometry {
pub fn new(resolution_level: u32) -> Self {
pub fn new(resolution_level: u32, num_tracers: usize) -> Self {
use flow::bases::Basis;

let (base_height, solver) = Self::make_solver(resolution_level);
let (base_height, solver) = Self::make_solver(resolution_level, num_tracers);
let prev_fields_snapshot = solver.fields_snapshot();
let curr_fields_snapshot = prev_fields_snapshot.clone();

Expand Down Expand Up @@ -411,6 +417,7 @@ impl TorusGeometry {

fn make_solver(
resolution_level: u32,
num_tracers: usize,
) -> (
Float,
flow::physics::Solver<flow::bases::fourier::RectangularPeriodicBasis>,
Expand Down Expand Up @@ -447,7 +454,7 @@ impl TorusGeometry {
num_points, lengths,
));
let terrain_height = basis.scalar_to_spectral(&basis.make_scalar(|_, _| 0.));
let mut initial_fields = flow::physics::Fields::zeros(basis.clone());
let mut initial_fields = flow::physics::Fields::zeros(basis.clone(), num_tracers);
initial_fields.assign_height(&basis.scalar_to_spectral(&basis.make_scalar(|x, y| {
base_height
- amplitude
Expand All @@ -460,9 +467,10 @@ impl TorusGeometry {
.powi(2)
.powf(pow(bump_size, lengths[1]))
})));
initial_fields.assign_tracers(basis.make_random_points().view());
initial_fields.assign_tracers(basis.make_random_points(num_tracers).view());
let problem = flow::physics::Problem {
basis,
num_tracers,
terrain_height,
kinematic_viscosity,
rotation_angular_speed,
Expand Down Expand Up @@ -492,7 +500,7 @@ mod tests {

#[test]
fn test_sphere_no_crash() {
let mut sphere = SphereGeometry::new(6);
let mut sphere = SphereGeometry::new(6, 100);
let _: Vec<_> = sphere.make_renderables(3).collect();
for _ in 0..20 {
sphere.step();
Expand Down
23 changes: 11 additions & 12 deletions tsunami/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ fn physics_loop(
geometry = geom::Geometry::new(
new_params.physics.geometry_type,
new_params.performance.resolution_level,
2u32.pow(new_params.performance.log2_num_tracers) as usize,
);
}
params_message = new_params_message.clone();
Expand Down Expand Up @@ -128,6 +129,7 @@ pub async fn run() {
let geometry = geom::Geometry::new(
params.physics.geometry_type,
params.performance.resolution_level,
2u32.pow(params.performance.log2_num_tracers) as usize,
);
let mut renderable = geometry.make_renderables(1).pop().unwrap();
let (renderable_sender, renderable_reader) = std::sync::mpsc::sync_channel(2);
Expand Down Expand Up @@ -211,11 +213,7 @@ pub async fn run() {
AmbientLight::new_with_environment(&context, 20.0, Srgba::WHITE, skybox.texture());
let directional = DirectionalLight::new(&context, 5.0, Srgba::WHITE, &vec3(-1., 0., 0.));

let mut performance_stats = param::PerformanceStats {
wall_time_per_renderable_sec: 0.,
wall_time_per_render_sec: 0.,
sim_time_per_renderable: 0.,
};
let mut performance_stats = param::PerformanceStats::default();

let rendering_data =
renderable.make_rendering_data(params.visualization.height_exaggeration_factor);
Expand Down Expand Up @@ -525,8 +523,9 @@ pub async fn run() {
_ => {}
}
}
tsunami_hint_circle_object.set_transformation(rotation);

if let param::ShowRotation::Corotating = params.visualization.show_rotation {
tsunami_hint_circle_object.set_transformation(rotation);
}
// Set hint circle color to red if completing a double click.
double_click_detector.process_idle();
match double_click_detector.state {
Expand Down Expand Up @@ -623,18 +622,18 @@ pub async fn run() {

// We rotated the physical objects above; now we need to rotate the camera as
// well so that we are observing from a corotating frame.
let rotated_camera = match params.visualization.show_rotation {
param::ShowRotation::Corotating => {
let rotated_camera =
if let param::ShowRotation::Corotating = params.visualization.show_rotation {
let position = rotation.transform_vector(*camera.position());
let target = rotation.transform_vector(*camera.target());
let up = rotation.transform_vector(*camera.up());

let mut rotated_camera = camera.clone();
rotated_camera.set_view(position, target, up);
rotated_camera
}
_ => camera.clone(),
};
} else {
camera.clone()
};
frame_input
.screen()
.render(
Expand Down
16 changes: 15 additions & 1 deletion tsunami/src/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ impl Default for VisualizationParameters {
pub struct PerformanceParameters {
pub substeps_per_physics_step: usize,
pub resolution_level: u32,
pub log2_num_tracers: u32,
}

impl PerformanceParameters {
Expand All @@ -221,6 +222,18 @@ impl PerformanceParameters {
}
ui.label("resolution");
});
ui.horizontal(|ui| {
for n in 12..=15 {
*geom_change |= ui
.radio_value(
&mut self.log2_num_tracers,
n,
format!("{}k", 2i32.pow(n) / 1000),
)
.changed();
}
ui.label("num tracers");
});
// ui.add(
// egui::Slider::new(
// &mut params.substeps_per_physics_step,
Expand All @@ -238,6 +251,7 @@ impl Default for PerformanceParameters {
fn default() -> Self {
Self {
resolution_level: 6,
log2_num_tracers: 12,
substeps_per_physics_step: 1,
}
}
Expand Down Expand Up @@ -356,7 +370,7 @@ impl std::fmt::Display for ShowRotation {
}
}

#[derive(Clone, Copy)]
#[derive(Clone, Copy, Default)]
pub struct PerformanceStats {
pub wall_time_per_renderable_sec: Float,
pub wall_time_per_render_sec: Float,
Expand Down
2 changes: 1 addition & 1 deletion tsunami/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use tsunami;

#[test]
fn test_sphere_no_crash() {
let mut sphere = tsunami::geom::SphereGeometry::new(7);
let mut sphere = tsunami::geom::SphereGeometry::new(7, 6000);
let _: Vec<_> = sphere.make_renderables(1).collect();
for _ in 0..20 {
sphere.step();
Expand Down

0 comments on commit 0d6e5fc

Please sign in to comment.