use coremem::{Driver, Flt, mat, meas}; use coremem::geom::{Index, Meters, Torus}; use coremem::stim::{CurlStimulus, Sinusoid1, TimeVarying1 as _}; fn main() { coremem::init_logging(); let feat_size = 10e-6; // feature size let duration = 3e-9; let width = 2200e-6; let depth = 1800e-6; let buffer = 200e-6; let ferro_major = 320e-6; let ferro_minor = 60e-6; let wire_minor = 40e-6; let wire_major = 160e-6; let peak_current = 5e4; let current_duration = 1.0e-9; // half-wavelength of the sine wave let current_break = 0.5e-9; // time between 'set' pulse and 'clear' pulse let conductivity = 1.0e9; let from_m = |m: Flt| (m/feat_size).round() as u32; let m_to_um = |m: Flt| (m * 1e6).round() as u32; let half_width = width * 0.5; let half_depth = depth * 0.5; let width_px = from_m(width); let depth_px = from_m(depth); let size_px = Index((width_px, width_px, depth_px).into()); let mut driver: Driver = Driver::new(size_px, feat_size); driver.set_steps_per_frame(1000); let base = "wrapped_torus-12"; let ferro_region = Torus::new_xy(Meters((half_width, half_width, half_depth).into()), ferro_major, ferro_minor); let drive_region = Torus::new_xz(Meters((half_width - ferro_major, half_width, half_depth).into()), wire_major, wire_minor); let sense_region = Torus::new_xz(Meters((half_width + ferro_major, half_width, half_depth).into()), wire_major, wire_minor); driver.fill_region(&ferro_region, mat::db::ferroxcube_3r1().into()); driver.fill_region(&drive_region, mat::db::conductor(conductivity).into()); driver.fill_region(&sense_region, mat::db::conductor(conductivity).into()); let boundary_xy = half_width - ferro_major - ferro_minor - buffer; let boundary_z = half_depth - wire_major - wire_minor - buffer; println!("boundary: {}um; {}um", m_to_um(boundary_xy), m_to_um(boundary_z)); driver.add_upml_boundary(Meters((boundary_xy, boundary_xy, boundary_z).into())); let pos_wave = Sinusoid1::from_wavelength(peak_current, current_duration * 2.0) .half_cycle(); let neg_wave = Sinusoid1::from_wavelength(-4.0*peak_current, current_duration * 2.0) .half_cycle() .shifted(current_duration + current_break); driver.add_stimulus(CurlStimulus::new( drive_region.clone(), pos_wave, drive_region.center(), drive_region.axis() )); driver.add_stimulus(CurlStimulus::new( drive_region.clone(), neg_wave, drive_region.center(), drive_region.axis() )); driver.add_measurement(meas::CurrentLoop::new("sense", sense_region.clone())); driver.add_measurement(meas::Current::new("sense", sense_region.clone())); driver.add_measurement(meas::MagneticLoop::new("mem", ferro_region.clone())); driver.add_measurement(meas::Magnetization::new("mem", ferro_region.clone())); driver.add_measurement(meas::MagneticFlux::new("mem", ferro_region.clone())); driver.add_measurement(meas::CurrentLoop::new("drive", drive_region.clone())); driver.add_measurement(meas::Current::new("drive", drive_region.clone())); let prefix = format!("out/{}/{}-flt{}-{}-feat{}um-{}mA-{}ps--radii{}um-{}um-{}um-{}um", base, base, std::mem::size_of::() * 8, *size_px, m_to_um(feat_size), (peak_current * 1e3).round() as i64, (current_duration * 1e12).round() as i64, m_to_um(ferro_major), m_to_um(ferro_minor), m_to_um(wire_major), m_to_um(wire_minor), ); let _ = std::fs::create_dir_all(&prefix); driver.add_serializer_renderer(&*format!("{}/frame-", prefix)); driver.step_until(duration); }