diff --git a/README.md b/README.md index 9e212d7..cb53a35 100644 --- a/README.md +++ b/README.md @@ -14,25 +14,76 @@ as the simulation progresses or completes. ## Example Usage -simulations are defined by defining either a binary crate which links against the `coremem` library, +simulations are defined by creating either a binary crate which links against the `coremem` library, or simply inserting a top-level file to the `examples/` directory in this repo and running it. -here's the [minimal_torus](examples/minimal_torus.rs) example shipped in this library: +here's an excerpt from the [sr_latch](examples/sr_latch.rs) example shipped in this library: ```rust -# TODO: inline one of the examples/ here + // create some `Region` instances which will define our geometry + let ferro1_region = Torus::new_xy(Meters::new(ferro1_center, ferro_center_y, half_depth), ferro_major, ferro_minor); + let ferro2_region = Torus::new_xy(Meters::new(ferro2_center, ferro_center_y, half_depth), ferro_major, ferro_minor); + let set_region = Torus::new_yz(Meters::new(ferro1_center, ferro_center_y - ferro_major, half_depth), wire_major, wire_minor); + let reset_region = Torus::new_yz(Meters::new(ferro1_center, ferro_center_y + ferro_major, half_depth), wire_major, wire_minor); + let coupling_region = Torus::new_xz(Meters::new(0.5*(ferro1_center + ferro2_center), ferro_center_y, half_depth), wire_coupling_major, wire_minor); + + // create the interface through which we'll "drive" a simulation to completion: + let mut driver: SpirvDriver = Driver::new_spirv(Meters::new(width, height, depth), feat_size); + + // fill each region within the simulation with the appropriate material + driver.fill_region(&ferro1_region, mat::MHPgram::new(25.0, 881.33, 44000.0)); + driver.fill_region(&ferro2_region, mat::MHPgram::new(25.0, 881.33, 44000.0)); + driver.fill_region(&set_region, mat::IsomorphicConductor::new(drive_conductivity)); + driver.fill_region(&reset_region, mat::IsomorphicConductor::new(drive_conductivity)); + driver.fill_region(&coupling_region, mat::IsomorphicConductor::new(drive_conductivity)); + + // populate our stimuli. + // here we pulse the E field with amplitude defined by a half-sine wave w.r.t. time. + // we apply this to the "set" wire loop, everywhere directed tangential to the loop. + let wave = Sinusoid1::from_wavelength(peak_set_field, set_pulse_duration * 2.0) + .half_cycle() + .shifted(start); + driver.add_stimulus(CurlStimulus::new( + set_region.clone(), + wave, + set_region.center(), + set_region.axis() + )); + + // every 36000 "steps", render the simulation state to disk. + driver.add_serializer_renderer("out/examples/sr_latch/frame-", 36000, None); + driver.step_until(Seconds(3.0*set_pulse_duration)); ``` -you can run this with: +you can run the full example with: ``` -$ cargo run --example minimal_torus +$ cargo run --release --example sr_latch ``` +TODO: switch between CPU and GPU accel in this demo. + and then investigate the results with ``` -$ cargo run --bin viewer out/minimal_torus +$ cargo run --bin viewer out/examples/sr_latch ``` +![screencapture of Viewer for SR latch at t=2.8ns. it shows two rings spaced horizontally, with arrows circulating them](readme_images/sr_latch_ExBxy_2800ps.png "SR latch at t=2.8ns") + +the viewer shows us a single xy cross-section of the simulation at a moment in time. +it uses red-tipped arrows to show the x-y components of the B field at every point, +and the Z component of the E field is illustrated with color (bright green for positive polarization and dark blue for negative). +the light blue splotches depict the conductors (in the center, the wire coupling loops; on the edge, our energy-dissipating boundary). + +what we see here is that both ferrites (the two large circles in the above image) have a clockwise polarized B field. this is in the middle of a transition, so the E fields look a bit chaotic. advance to t=46 ns: the "reset" pulse was applied at t=24ns and had 22ns to settle: + +![screencapture of Viewer for SR latch at t=45.7ns. similar to above but with the B field polarized CCW](readme_images/sr_latch_ExBxy_45700ps.png "SR latch at t=45.7ns") + +we can see the "reset" pulse has polarized both ferrites in the CCW orientation this time. the E field is less pronounced because we gave the system 22ns instead of 3ns to settle this time. + +the graphical viewer is helpful for debugging geometries, but the CSV measurements are useful for viewing numeric system performance. peak inside "out/examples/sr-latch/meas.csv" to see a bunch of measurements over time. you can use a tool like Excel or [visidata](https://www.visidata.org/) to plot the interesting ones. + +here's a plot of `M(mem2)` over time from the SR latch simulation. we're measuring the (average) M value along the major tangent to the torus corresponding to the ferrite on the right in the images above. the notable bumps correspond to these pulses: "set", "reset", "set", "reset", "set+reset applied simultaneously", "reset", "reset". + +![plot of M(mem2) over time](readme_images/sr_latch_vd_M2.png "plot of M(mem2) over time") -TODO: include viewer screenshots ## Processing Loop @@ -73,7 +124,12 @@ TODO: document Material options, Stimulus options, Measurement options, Renderin # Performance -TODO: document how long it takes to compute select simulations. + +with my Radeon RX 5700XT, the sr\_latch example takes 125 minutes to complete 150ns of simulation time (3896500 simulation steps). that's on a grid of size 163x126x80 where the cell dimension is 20um. + +in a FDTD simulation, as we shrink the cell size the time step has to shrink too (it's an inverse affine relationship). so the scale-invariant performance metric is "grid cell steps per second" (`(163*126*80)*3896500 / (125*60)`): we get 850M. + +this is the "default" optimized version. you could introduce a new material to the simulation, and performance would remain constant. as you finalize your simulation, you can specialize it a bit and compile the GPU code to optimize for your specific material. this can squeeze another factor-of-2 gain: view to see how that's done. # Support @@ -84,6 +140,8 @@ this: i'm happy to spend the marginal extra time to help curious people make use TODO: cite the works which were useful in getting this off the ground. +TODO: consult the licenses of my dependencies. + # License i'm not a lawyer, and i don't want to be. diff --git a/readme_images/sr_latch_EzBxy_2800ps.png b/readme_images/sr_latch_EzBxy_2800ps.png new file mode 100644 index 0000000..a530e42 Binary files /dev/null and b/readme_images/sr_latch_EzBxy_2800ps.png differ diff --git a/readme_images/sr_latch_EzBxy_45700ps.png b/readme_images/sr_latch_EzBxy_45700ps.png new file mode 100644 index 0000000..15b2231 Binary files /dev/null and b/readme_images/sr_latch_EzBxy_45700ps.png differ diff --git a/readme_images/sr_latch_vd_M2.png b/readme_images/sr_latch_vd_M2.png new file mode 100644 index 0000000..293e095 Binary files /dev/null and b/readme_images/sr_latch_vd_M2.png differ