fdtd-coremem/crates/applications/wavefront/src/main.rs

66 lines
2.6 KiB
Rust

//! this example runs a *2-dimensional* simulation.
//! it places a dissipative material (i.e. a conductor) on the left edge of the simulation
//! and then radiates a vertical wavefront from the center of the simulation.
//! it's about the bare-minimum simulation which still does something interesting.
//!
//! note that any practical simulation should probably terminate the simulation space
//! with something that absorbs energy. since this example doesn't, it lets you see what
//! happens when you just use the default boundary conditions.
use coremem::{mat, Driver};
use coremem::geom::{Coord as _, Cube, Index};
use coremem::units::Seconds;
use coremem::sim::spirv::{self, SpirvSim};
use coremem::stim::{Fields, ModulatedVectorField, Pulse, RegionGated};
use coremem::cross::vec::Vec3;
type Mat = mat::GenericMaterial<f32>;
fn main() {
coremem::init_logging();
// create a 2d simulation with so many grid cells
let width = 401;
let height = 401;
let size = Index::new(width, height, 1 /* depth */);
// each cell represents 1um x 1um x 1um volume
let feature_size = 1e-6;
// create the simulation "driver".
// the first parameter is the float type to use: f32 for unchecked math, coremem::real::R32
// to guard against NaN/Inf (useful for debugging).
// to run this on the gpu instead of the gpu, replace `CpuBackend` with `WgpuBackend`.
let mut driver = Driver::new(SpirvSim::<f32, Mat, spirv::CpuBackend>::new(
size, feature_size
));
// create a conductor on the left side.
let conductor = Cube::new(
Index::new(0, 0, 0).to_meters(feature_size),
Index::new(width/10, height, 1).to_meters(feature_size),
);
driver.fill_region(&conductor, mat::IsomorphicConductor::new(200f32));
// create a vertical strip in the center of the simulation which emits a wave.
let center_region = Cube::new(
Index::new(200, height/4, 0).to_meters(feature_size),
Index::new(201, height*3/4, 1).to_meters(feature_size),
);
// emit a constant E/H delta over this region for 100 femtoseconds
let stim = ModulatedVectorField::new(
RegionGated::new(center_region, Fields::new_eh(
Vec3::new(2e19, 0.0, 0.0),
Vec3::new(0.0, 0.0, 2e19/376.730),
)),
Pulse::new(0.0, 100e-15),
);
driver.add_stimulus(stim);
// render the output to a video and to the terminal (low-res)
let _ = std::fs::create_dir_all("out/applications/wavefront");
driver.add_y4m_renderer("out/applications/wavefront/rendered.y4m", 1, None);
driver.add_term_renderer(4, None);
// finally, run the simulation:
driver.step_until(Seconds(100e-12));
}