The `Cell` type in sim.rs could be further improved:
it doesn't need to be parameterized over Material. It
should actually be renamed to `Sample`, and directly encode
the magnetization, etc.
Pml uses a lot of memory: 12 floats per material
Compared against the other materials, which tend to use 3 floats.
This raises the memory-per-cell from 1 (discriminant) + 3 (material) + 6 (E/H fields) = 10 to 19.
About a doubling in memory footprint.
These new benchmarks show that compressing the Pml could gain UP TO 35%
perf.
```
Driver::step/10 time: [253.57 us 255.01 us 256.38 us]
Driver::step/20 time: [744.24 us 752.36 us 761.36 us]
Driver::step/40 time: [4.0362 ms 4.1014 ms 4.1711 ms]
Driver::step/80 time: [46.099 ms 46.290 ms 46.490 ms]
Driver::step/160 time: [300.99 ms 301.81 ms 302.70 ms]
Driver::step_no_pml/10 time: [235.28 us 237.26 us 239.09 us]
Driver::step_no_pml/20 time: [715.56 us 727.69 us 741.33 us]
Driver::step_no_pml/40 time: [2.9632 ms 2.9780 ms 2.9942 ms]
Driver::step_no_pml/80 time: [29.236 ms 29.355 ms 29.479 ms]
Driver::step_no_pml/160 time: [210.19 ms 210.54 ms 210.88 ms]
Driver::step_one_vec/10 time: [230.28 us 231.73 us 233.22 us]
Driver::step_one_vec/20 time: [679.41 us 682.16 us 685.30 us]
Driver::step_one_vec/40 time: [2.9308 ms 2.9409 ms 2.9525 ms]
Driver::step_one_vec/80 time: [29.261 ms 29.400 ms 29.540 ms]
Benchmarking Driver::step_one_vec/160:
time: [209.48 ms 209.78 ms 210.08 ms]
Driver::step_with_pml/0 time: [3.7132 ms 3.7238 ms 3.7356 ms]
Driver::step_with_pml/1 time: [3.8769 ms 3.8867 ms 3.8970 ms]
Driver::step_with_pml/2 time: [3.9985 ms 4.0122 ms 4.0276 ms]
Driver::step_with_pml/4 time: [4.2047 ms 4.2146 ms 4.2255 ms]
Driver::step_with_pml/8 time: [4.4845 ms 4.4915 ms 4.4988 ms]
Driver::step_with_pml/16
time: [4.7270 ms 4.7489 ms 4.7730 ms]
```
The splitting of e/h away from Cell is necessary to avoid
conflicting mut/immut borrows. Well, borrows even when they're
all in one Cell are still non-conflicting, but I can't prove
such a thing to rustc without splitting them like this.
```
Driver::step_with_pml/0 time: [3.7667 ms 3.7806 ms 3.7953 ms]
Driver::step_with_pml/1 time: [4.0279 ms 4.0746 ms 4.1278 ms]
Driver::step_with_pml/2 time: [4.1044 ms 4.1498 ms 4.1993 ms]
Driver::step_with_pml/4 time: [4.2738 ms 4.3023 ms 4.3330 ms]
Driver::step_with_pml/8 time: [4.6272 ms 4.6661 ms 4.7082 ms]
Driver::step_with_pml/16
time: [4.8251 ms 4.8726 ms 4.9234 ms]
```
New PML implementation doesn't require solving anything beyond linear
differential equations, so that old function is overkill.
Note that the new function isn't directly tested... but it was mostly
ripped from the old one, and withstands scrutiny so I'm not worried.
Driver::step_with_pml/0 time: [11.131 ms 11.165 ms 11.202 ms]
change: [-10.303% -9.8591% -9.3593%] (p = 0.00 < 0.05)
Driver::step_with_pml/1 time: [11.206 ms 11.243 ms 11.279 ms]
change: [-10.511% -9.9794% -9.4731%] (p = 0.00 < 0.05)
Driver::step_with_pml/2 time: [11.360 ms 11.394 ms 11.429 ms]
change: [-11.416% -10.994% -10.568%] (p = 0.00 < 0.05)
Driver::step_with_pml/4 time: [11.722 ms 11.764 ms 11.807 ms]
change: [-11.370% -10.885% -10.456%] (p = 0.00 < 0.05)
Driver::step_with_pml/8 time: [12.046 ms 12.086 ms 12.126 ms]
change: [-11.379% -10.961% -10.525%] (p = 0.00 < 0.05)
Driver::step_with_pml/16
time: [12.240 ms 12.277 ms 12.315 ms]
change: [-11.871% -11.384% -10.896%] (p = 0.00 < 0.05)
PML is actually SIGNIFICANTLY better than a conductor.
It's not apparent immediately, but even a 1-width PML beats a 50-length
conductor by about 50x :o
It still explodes in the monodirectional_{x,y,z} tests.
Explodes almost precisely the same amount as my old PML implementation
(about half).
For the normal cases, it performs just about the same as my old PML
implementation as well. So I guess that old PML impl actually was
mostly correct?
Reflections are 0.006 * that of a conductor after t=2000.
For t=400, 600, it's closer to 1e-5.
test output:
```
running 18 tests
test sim::test::pml_boundary_3d_chaotic_field ... FAILED
test sim::test::pml_boundary_3d_inneffective_monodirectional_linear ... ok
test sim::test::pml_boundary_3d_monodirectional_plane_xy ... FAILED
test sim::test::pml_boundary_3d_monodirectional_plane_xz ... FAILED
test sim::test::pml_boundary_3d_monodirectional_plane_yz ... FAILED
test sim::test::pml_boundary_3d_monodirectional_x ... FAILED
test sim::test::pml_boundary_3d_monodirectional_y ... FAILED
test sim::test::pml_boundary_3d_monodirectional_z ... FAILED
test sim::test::pml_boundary_3d_multidirectional ... FAILED
test sim::test::pml_boundary_3d_multidirectional_non_axis_aligned ... FAILED
test sim::test::pml_boundary_3d_multidirectional_off_center ... FAILED
test sim::test::pml_boundary_3d_multidirectional_off_center_multisource ... FAILED
test sim::test::pml_boundary_conditions_plane_xy ... FAILED
test sim::test::pml_boundary_conditions_plane_xz ... FAILED
test sim::test::pml_boundary_conditions_plane_yz ... FAILED
test sim::test::pml_boundary_conditions_x ... FAILED
test sim::test::pml_boundary_conditions_y ... FAILED
test sim::test::pml_boundary_conditions_z ... FAILED
failures:
---- sim::test::pml_boundary_3d_monodirectional_x stdout ----
thread 'main' panicked at 'assertion failed: `float_eq!(left, right, abs <= ε)`
left: `3374118398821788000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0`,
right: `0.0`,
abs_diff: `3374118398821788000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0`,
ulps_diff: `Some(7487140187042783038)`,
[abs] ε: `0.00002`', src/sim.rs:1561:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test
at ./src/sim.rs:1561:9
3: coremem::sim::test::pml_boundary_3d_monodirectional_x
at ./src/sim.rs:1697:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
---- sim::test::pml_boundary_3d_chaotic_field stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `2.945457365977076`,
right: `0.01`', src/sim.rs:1797:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_boundary_3d_chaotic_field
at ./src/sim.rs:1797:9
3: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_3d_monodirectional_plane_xy stdout ----
thread 'main' panicked at 'assertion failed: `float_eq!(left, right, abs <= ε)`
left: `0.0005009829175415541`,
right: `0.0`,
abs_diff: `0.0005009829175415541`,
ulps_diff: `Some(4557759975104166148)`,
[abs] ε: `0.00002`', src/sim.rs:1559:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test
at ./src/sim.rs:1559:9
3: coremem::sim::test::pml_boundary_3d_monodirectional_plane_xy
at ./src/sim.rs:1675:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_3d_monodirectional_plane_xz stdout ----
thread 'main' panicked at 'assertion failed: `float_eq!(left, right, abs <= ε)`
left: `0.0005009829175415532`,
right: `0.0`,
abs_diff: `0.0005009829175415532`,
ulps_diff: `Some(4557759975104166140)`,
[abs] ε: `0.00002`', src/sim.rs:1559:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test
at ./src/sim.rs:1559:9
3: coremem::sim::test::pml_boundary_3d_monodirectional_plane_xz
at ./src/sim.rs:1682:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_3d_monodirectional_plane_yz stdout ----
thread 'main' panicked at 'assertion failed: `float_eq!(left, right, abs <= ε)`
left: `0.0005009829175415532`,
right: `0.0`,
abs_diff: `0.0005009829175415532`,
ulps_diff: `Some(4557759975104166140)`,
[abs] ε: `0.00002`', src/sim.rs:1559:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test
at ./src/sim.rs:1559:9
3: coremem::sim::test::pml_boundary_3d_monodirectional_plane_yz
at ./src/sim.rs:1689:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_3d_multidirectional stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `1.9412470536666304`,
right: `0.001`: 0.00000032736677117707937', src/sim.rs:1569:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test_against_baseline
at ./src/sim.rs:1569:9
3: coremem::sim::test::pml_boundary_3d_multidirectional
at ./src/sim.rs:1715:13
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_3d_multidirectional_non_axis_aligned stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `1.953821151793976`,
right: `0.001`: 0.0000003324621178895135', src/sim.rs:1569:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test_against_baseline
at ./src/sim.rs:1569:9
3: coremem::sim::test::pml_boundary_3d_multidirectional_non_axis_aligned
at ./src/sim.rs:1732:13
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_3d_multidirectional_off_center stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `1.3486460410831005`,
right: `0.01`', src/sim.rs:1754:17
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_boundary_3d_multidirectional_off_center
at ./src/sim.rs:1754:17
3: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_3d_multidirectional_off_center_multisource stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `2.0802399177119555`,
right: `0.01`', src/sim.rs:1770:17
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_boundary_3d_multidirectional_off_center_multisource
at ./src/sim.rs:1770:17
3: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_conditions_plane_xy stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `0.77272749932311`,
right: `0.001`: 0.000000008487466989781884', src/sim.rs:1569:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test_against_baseline
at ./src/sim.rs:1569:9
3: coremem::sim::test::pml_boundary_conditions_plane_xy
at ./src/sim.rs:1597:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_conditions_plane_xz stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `0.7727274993229949`,
right: `0.001`: 0.000000008487466989778792', src/sim.rs:1569:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test_against_baseline
at ./src/sim.rs:1569:9
3: coremem::sim::test::pml_boundary_conditions_plane_xz
at ./src/sim.rs:1604:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_conditions_plane_yz stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `0.7727274993229949`,
right: `0.001`: 0.000000008487466989778792', src/sim.rs:1569:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test_against_baseline
at ./src/sim.rs:1569:9
3: coremem::sim::test::pml_boundary_conditions_plane_yz
at ./src/sim.rs:1611:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_conditions_x stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `0.006218022664939241`,
right: `0.001`: 0.00000001308307535275692', src/sim.rs:1569:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test_against_baseline
at ./src/sim.rs:1569:9
3: coremem::sim::test::pml_boundary_conditions_x
at ./src/sim.rs:1576:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_conditions_y stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `0.006218022664939241`,
right: `0.001`: 0.00000001308307535275692', src/sim.rs:1569:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test_against_baseline
at ./src/sim.rs:1569:9
3: coremem::sim::test::pml_boundary_conditions_y
at ./src/sim.rs:1583:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
---- sim::test::pml_boundary_conditions_z stdout ----
thread 'main' panicked at 'assertion failed: `(left < right)`
left: `0.006218022664939241`,
right: `0.001`: 0.00000001308307535275692', src/sim.rs:1569:9
stack backtrace:
0: rust_begin_unwind
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:515:5
1: std::panicking::begin_panic_fmt
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/std/src/panicking.rs:457:5
2: coremem::sim::test::pml_test_against_baseline
at ./src/sim.rs:1569:9
3: coremem::sim::test::pml_boundary_conditions_z
at ./src/sim.rs:1590:9
4: core::ops::function::FnOnce::call_once
at /rustc/f58631b4503b5cd34163cf9c3ff19dc3e0c8a09e/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
failures:
sim::test::pml_boundary_3d_chaotic_field
sim::test::pml_boundary_3d_monodirectional_plane_xy
sim::test::pml_boundary_3d_monodirectional_plane_xz
sim::test::pml_boundary_3d_monodirectional_plane_yz
sim::test::pml_boundary_3d_monodirectional_x
sim::test::pml_boundary_3d_monodirectional_y
sim::test::pml_boundary_3d_monodirectional_z
sim::test::pml_boundary_3d_multidirectional
sim::test::pml_boundary_3d_multidirectional_non_axis_aligned
sim::test::pml_boundary_3d_multidirectional_off_center
sim::test::pml_boundary_3d_multidirectional_off_center_multisource
sim::test::pml_boundary_conditions_plane_xy
sim::test::pml_boundary_conditions_plane_xz
sim::test::pml_boundary_conditions_plane_yz
sim::test::pml_boundary_conditions_x
sim::test::pml_boundary_conditions_y
sim::test::pml_boundary_conditions_z
```
There are still a few references to it, but it doesn't really exist in
the simulation proper.
The existing implementation is confusing and ineffective (broken?).
Upcoming patches will work to replace it with a more workable
implementation.
Also moves the Material::is_vacuum method to be on a helper trait.
That's just a point of hygeine. Meant to split it out to a separate
patch but messed up (-:
We don't really care what specific PML implementation it is. UPML is
kinda misleading since the implementation resembles Stretched Coordinate
PML more anyway.