witwin-maxwell 0.6.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- witwin_maxwell-0.7.0/CHANGELOG.md +778 -0
- witwin_maxwell-0.7.0/PKG-INFO +201 -0
- witwin_maxwell-0.7.0/README.md +170 -0
- witwin_maxwell-0.7.0/hatch_build.py +30 -0
- witwin_maxwell-0.7.0/pyproject.toml +65 -0
- witwin_maxwell-0.7.0/witwin/maxwell/__init__.py +149 -0
- witwin_maxwell-0.7.0/witwin/maxwell/_core_material_fields.py +30 -0
- witwin_maxwell-0.7.0/witwin/maxwell/_enums.py +66 -0
- witwin_maxwell-0.7.0/witwin/maxwell/_fixed_inputs.py +24 -0
- witwin_maxwell-0.7.0/witwin/maxwell/_lazy.py +43 -0
- witwin_maxwell-0.7.0/witwin/maxwell/_stability.py +151 -0
- witwin_maxwell-0.7.0/witwin/maxwell/_version.py +9 -0
- witwin_maxwell-0.7.0/witwin/maxwell/absorbers.py +162 -0
- witwin_maxwell-0.7.0/witwin/maxwell/adapters/pcb.py +196 -0
- witwin_maxwell-0.7.0/witwin/maxwell/adapters/tidy3d.py +2801 -0
- witwin_maxwell-0.7.0/witwin/maxwell/adjoint_inputs.py +435 -0
- witwin_maxwell-0.7.0/witwin/maxwell/antenna.py +363 -0
- witwin_maxwell-0.7.0/witwin/maxwell/array.py +1608 -0
- witwin_maxwell-0.7.0/witwin/maxwell/array_execution.py +66 -0
- witwin_maxwell-0.7.0/witwin/maxwell/array_gradient.py +379 -0
- witwin_maxwell-0.7.0/witwin/maxwell/breakdown.py +149 -0
- witwin_maxwell-0.7.0/witwin/maxwell/breakdown_risk.py +313 -0
- witwin_maxwell-0.7.0/witwin/maxwell/breakdown_stress.py +546 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/__init__.py +24 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/check.py +61 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/fields.py +678 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/keys.py +340 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/model.py +110 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/tables/__init__.py +23 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/tables/_shared.py +98 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/tables/capacitance.py +22 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/tables/electrostatic.py +77 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/tables/fdfd.py +101 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/tables/fdtd.py +62 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/tables/mom.py +60 -0
- witwin_maxwell-0.7.0/witwin/maxwell/capability/tables/mom_layered.py +65 -0
- witwin_maxwell-0.7.0/witwin/maxwell/circuit_devices.py +269 -0
- witwin_maxwell-0.7.0/witwin/maxwell/circuits.py +1529 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/__init__.py +116 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/build.py +11 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/coefficients.py +39 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/conductors.py +55 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/cuda/binding.cpp +74 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/cuda/bvh.cu +135 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/cuda/checks.h +20 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/cuda/coefficients.cu +67 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/cuda/mesh.cu +140 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/cuda/poles.cu +203 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/cuda/setup.cu +255 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/cuda/subpixel.cu +90 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/cuda/tables.cu +84 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/dispatch.py +184 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/geometry.py +146 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/poles.py +164 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/setup.py +131 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/accel/subpixel.py +112 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/array.py +369 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/breakdown.py +151 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/circuits.py +323 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/coaxial.py +204 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/coordinates.py +184 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/copper_foil.py +576 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/cut_surface.py +233 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/electrostatic.py +395 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/fdtd_audit.py +81 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/gyromagnetic.py +378 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/lumped.py +102 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/mass_density.py +139 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/materials.py +4136 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/networks.py +318 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/planar_pec.py +252 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/ports.py +513 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/power_loss.py +223 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/sources.py +292 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/static_cache.py +412 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/structures.py +32 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/subpixel.py +446 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/terminal_waveports.py +200 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/thin_sheet.py +1578 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/thin_wire.py +2215 -0
- witwin_maxwell-0.7.0/witwin/maxwell/compiler/waveports.py +442 -0
- witwin_maxwell-0.7.0/witwin/maxwell/coordinates.py +205 -0
- witwin_maxwell-0.7.0/witwin/maxwell/copper_foil.py +173 -0
- witwin_maxwell-0.7.0/witwin/maxwell/dispersion_fit.py +814 -0
- witwin_maxwell-0.7.0/witwin/maxwell/electrostatic/__init__.py +67 -0
- witwin_maxwell-0.7.0/witwin/maxwell/electrostatic/api.py +266 -0
- witwin_maxwell-0.7.0/witwin/maxwell/electrostatic/capacitance.py +444 -0
- witwin_maxwell-0.7.0/witwin/maxwell/electrostatic/initial_condition.py +307 -0
- witwin_maxwell-0.7.0/witwin/maxwell/electrostatic/runtime.py +864 -0
- witwin_maxwell-0.7.0/witwin/maxwell/errors.py +73 -0
- witwin_maxwell-0.7.0/witwin/maxwell/esd.py +925 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/__init__.py +91 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/adjoint.py +160 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/batch.py +348 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/batch_runtime.py +1229 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/capacity.py +177 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/ensemble.py +181 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/plan.py +270 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/pool.py +265 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/records.py +249 -0
- witwin_maxwell-0.7.0/witwin/maxwell/execution/tuning.py +197 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/__init__.py +30 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/adjoint/bridge.py +222 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/magnetic.py +110 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/materials.py +76 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/modes.py +134 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/observations.py +202 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/pml.py +84 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/response.py +618 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/results.py +88 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/solver.py +1133 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd/sweep.py +134 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdfd_response.py +149 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/__init__.py +34 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/adjoint/bridge.py +1692 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/adjoint/capabilities.py +27 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/adjoint/copper_spectra.py +134 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/adjoint/core.py +3857 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/adjoint/dispatch.py +770 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/adjoint/joint_material.py +89 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/adjoint/mapped_admission.py +302 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/adjoint/reverse_common.py +262 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/boundary/__init__.py +35 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/boundary/abc.py +412 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/boundary/bloch.py +90 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/boundary/cpml.py +594 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/boundary/runtime.py +324 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/checkpoint.py +687 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/circuits.py +1243 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/coaxial.py +358 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/coords.py +34 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/copper_foil.py +609 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/__init__.py +0 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/backend.py +2387 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/build.py +402 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/core/binding.cpp +447 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/core/build.py +37 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/core/observers.cu +53 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/core/observers.cuh +32 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/core/step.cu +341 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/core/step.cuh +74 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/core/yee.cu +378 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/core/yee.cuh +39 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/extension.cpp +1669 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/kernels/common.cu +111 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/kernels/common.cuh +228 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/kernels/electric.cu +1327 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/kernels/gyromagnetic.cu +191 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/kernels/observers.cu +642 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cuda/runtime/__init__.py +0 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/cut_surface.py +208 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/distributed/adjoint.py +1671 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/distributed/circuits.py +613 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/distributed/copper.py +307 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/distributed/monitor_merge.py +468 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/distributed/networks.py +640 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/distributed/observations.py +92 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/distributed/resume.py +196 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/distributed/shard_engine.py +497 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/distributed/solver.py +1229 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/fixed_k.py +172 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/injection.py +1656 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/modes/__init__.py +1212 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/modes/common.py +683 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/modes/conductors.py +274 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/modes/tem.py +670 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/modes/vector.py +1221 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/spatial.py +621 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/temporal.py +657 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/tfsf_common.py +451 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/excitation/tfsf_state.py +883 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/lumped.py +1041 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/material_pullback.py +508 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/networks.py +1302 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/observers.py +1835 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/plane_product.py +318 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/plotting.py +91 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/ports.py +2685 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/postprocess.py +316 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/quadrature.py +300 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/results.py +410 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/resume.py +994 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/__init__.py +113 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/batch.py +258 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/breakdown.py +537 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/core_path.py +703 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/core_tables.py +391 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/gyromagnetic.py +332 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/initialization.py +282 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/materials.py +1982 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/module_cache.py +21 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/passivity.py +351 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/precision.py +75 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/spectral.py +684 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/stepping.py +1978 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/timeplan.py +198 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/runtime/timestep.py +187 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/solver.py +376 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/thin_sheet.py +1271 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/time_flux.py +109 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/time_traces.py +274 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd/wire.py +1408 -0
- witwin_maxwell-0.7.0/witwin/maxwell/fdtd_cpml.py +92 -0
- witwin_maxwell-0.7.0/witwin/maxwell/geometry/__init__.py +31 -0
- witwin_maxwell-0.7.0/witwin/maxwell/geometry/planar_pec.py +138 -0
- witwin_maxwell-0.7.0/witwin/maxwell/geometry/polyslab.py +302 -0
- witwin_maxwell-0.7.0/witwin/maxwell/geometry/surface_mesh.py +215 -0
- witwin_maxwell-0.7.0/witwin/maxwell/geometry/terminal_support.py +545 -0
- witwin_maxwell-0.7.0/witwin/maxwell/grid.py +18 -0
- witwin_maxwell-0.7.0/witwin/maxwell/invdes/constraints.py +114 -0
- witwin_maxwell-0.7.0/witwin/maxwell/invdes/filters.py +270 -0
- witwin_maxwell-0.7.0/witwin/maxwell/invdes/optimize.py +138 -0
- witwin_maxwell-0.7.0/witwin/maxwell/invdes/parameterization.py +110 -0
- witwin_maxwell-0.7.0/witwin/maxwell/invdes/projection.py +208 -0
- witwin_maxwell-0.7.0/witwin/maxwell/invdes/symmetry.py +148 -0
- witwin_maxwell-0.7.0/witwin/maxwell/io/__init__.py +11 -0
- witwin_maxwell-0.7.0/witwin/maxwell/io/migrate.py +373 -0
- witwin_maxwell-0.7.0/witwin/maxwell/io/scene_dict.py +827 -0
- witwin_maxwell-0.7.0/witwin/maxwell/io/schema.py +308 -0
- witwin_maxwell-0.7.0/witwin/maxwell/layers.py +209 -0
- witwin_maxwell-0.7.0/witwin/maxwell/lumped.py +617 -0
- witwin_maxwell-0.7.0/witwin/maxwell/material_cache.py +301 -0
- witwin_maxwell-0.7.0/witwin/maxwell/material_library.py +288 -0
- witwin_maxwell-0.7.0/witwin/maxwell/media.py +3037 -0
- witwin_maxwell-0.7.0/witwin/maxwell/modal_sweep.py +723 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/__init__.py +116 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/accessors.py +122 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/anisotropic_fields.py +482 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/anisotropic_lifting.py +207 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/anisotropic_operator.py +333 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/complex_static_tensor_green.py +203 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/direct_capacity.py +86 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/direct_config.py +68 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/dual_action_snapshot.py +173 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/dual_current_action.py +219 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/dual_current_receipt.py +67 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/dual_current_response.py +109 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/dyadic_contrast.py +688 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/dyadic_green.py +1322 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/efie_open.py +575 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/efie_preconditioning.py +381 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/ewald_nearfield.py +134 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fields.py +617 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fixed_tangent_inverse.py +138 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_capacity.py +320 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_config.py +486 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_directional_moments.py +986 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_directional_shift.py +491 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_error.py +692 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_order.py +948 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_periodic.py +175 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_periodic_capacity.py +138 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_periodic_error.py +201 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_periodic_order.py +114 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_periodic_regional.py +200 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_periodic_system.py +184 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/fmm_system.py +406 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/h2.py +233 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/h2_basis.py +261 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/h2_capacity.py +79 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/h2_operator.py +134 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_balance.py +329 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_config.py +193 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_current.py +177 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_current_snapshot.py +249 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_dual_current.py +212 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_fields.py +201 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_jacobian_action.py +166 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_material.py +211 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_observables.py +234 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_preparation.py +244 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_recovery.py +341 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_runtime.py +481 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/harmonic_snapshot.py +485 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/hmatrix.py +405 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/implicit_surface_solve.py +145 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/interpolation_error.py +130 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/interpolation_order.py +129 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/__init__.py +12 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/adjoint.py +227 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/admittance.py +559 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/admittance_near.py +96 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/assembly.py +220 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/body_block_lu.py +73 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/body_compress.py +295 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/body_preconditioner.py +64 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/build.py +31 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/config.py +192 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/adjoint.cu +81 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/admittance.cu +554 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/assembly.cu +1035 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/binding.cpp +274 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/closed.cu +229 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/common.cuh +69 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/cudss_workspace.cpp +74 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/green_eval.cuh +301 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/hmatrix.cu +135 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/interp.cu +280 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/iterative.cu +216 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/lowfreq.cu +540 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/spectral.cu +438 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/cuda/vertical.cu +277 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/deembed.py +383 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/extraction.py +455 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/frequency_groups.py +177 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/green.py +400 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/hmatrix.py +784 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/loss.py +131 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/lowfreq.py +179 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/macromodel.py +485 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/matrix_free.py +669 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/mesh.py +399 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/network.py +672 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/operator.py +247 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/planar.py +273 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/planar_mesh.py +563 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/port_system.py +351 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/process.py +265 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/runtime.py +499 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/sweep.py +137 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/vertical.py +330 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/layered/vertical_refine.py +198 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/lifting.py +743 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/linalg.py +1546 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/linear_runtime.py +105 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/linear_volume_state.py +112 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/lowrank.py +201 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/magnetostatic.py +113 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/near_preconditioner.py +170 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/operator.py +740 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/options.py +30 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/ordered_reduction.py +69 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/packed_near.py +777 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/periodic.py +476 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/periodic_config.py +174 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/periodic_diffraction.py +233 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/periodic_dyadic.py +1172 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/periodic_fields.py +177 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/periodic_operator.py +211 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/periodic_runtime.py +451 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/pfft_config.py +176 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/pfft_coupling.py +257 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/pfft_lifting.py +221 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/pfft_operator.py +236 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/pfft_system.py +382 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/physics.py +311 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/preconditioning.py +246 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/primitive_mesh.py +769 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/results.py +62 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/runtime.py +1324 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/rwg_interpolation_error.py +197 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/rwg_refinement.py +74 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/static_current.py +400 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/static_current_projector.py +98 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/static_projector_snapshot.py +98 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/static_tensor_floating.py +214 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/static_tensor_interface.py +271 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/static_tensor_material.py +153 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/static_tensor_polarization.py +129 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/static_tensor_volume.py +264 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/surface_h_snapshot.py +243 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/surface_volume.py +337 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/tensor_harmonic_bundle.py +337 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/tensor_harmonic_preparation.py +266 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/tensor_harmonic_runtime.py +266 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/tensor_harmonic_snapshot.py +339 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/tensor_nearfield.py +126 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/topology.py +239 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/vie_operator.py +276 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/volume_mesh.py +205 -0
- witwin_maxwell-0.7.0/witwin/maxwell/mom/volume_response_matrix.py +389 -0
- witwin_maxwell-0.7.0/witwin/maxwell/monitors.py +2017 -0
- witwin_maxwell-0.7.0/witwin/maxwell/network.py +1752 -0
- witwin_maxwell-0.7.0/witwin/maxwell/network_sweep.py +330 -0
- witwin_maxwell-0.7.0/witwin/maxwell/path_integrals.py +284 -0
- witwin_maxwell-0.7.0/witwin/maxwell/ports.py +1393 -0
- witwin_maxwell-0.7.0/witwin/maxwell/ports_postprocess.py +117 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/__init__.py +109 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/antenna.py +724 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/array.py +441 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/diffraction.py +220 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/emission.py +66 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/fdtd_loss.py +206 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/gaussian_overlap.py +171 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/low_frequency.py +144 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/modal.py +360 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/plane_payload.py +74 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/resonance.py +406 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/sar.py +371 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/sar_combine.py +289 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/scattering_parameters.py +394 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/selected_query.py +292 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/stratton_chu.py +1455 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/waveports.py +433 -0
- witwin_maxwell-0.7.0/witwin/maxwell/postprocess/yee_interpolation.py +208 -0
- witwin_maxwell-0.7.0/witwin/maxwell/py.typed +0 -0
- witwin_maxwell-0.7.0/witwin/maxwell/rational.py +1411 -0
- witwin_maxwell-0.7.0/witwin/maxwell/result.py +3112 -0
- witwin_maxwell-0.7.0/witwin/maxwell/results/__init__.py +14 -0
- witwin_maxwell-0.7.0/witwin/maxwell/results/tensor_data.py +315 -0
- witwin_maxwell-0.7.0/witwin/maxwell/results/typed.py +200 -0
- witwin_maxwell-0.7.0/witwin/maxwell/rf/__init__.py +141 -0
- witwin_maxwell-0.7.0/witwin/maxwell/rf/rational.py +21 -0
- witwin_maxwell-0.7.0/witwin/maxwell/roughness.py +241 -0
- witwin_maxwell-0.7.0/witwin/maxwell/sar.py +578 -0
- witwin_maxwell-0.7.0/witwin/maxwell/scene.py +2128 -0
- witwin_maxwell-0.7.0/witwin/maxwell/schemas/VERSIONS.toml +52 -0
- witwin_maxwell-0.7.0/witwin/maxwell/schemas/__init__.py +1 -0
- witwin_maxwell-0.7.0/witwin/maxwell/schemas/distributed-result-1.json +34 -0
- witwin_maxwell-0.7.0/witwin/maxwell/schemas/fdtd-resume-6.json +34 -0
- witwin_maxwell-0.7.0/witwin/maxwell/schemas/network-data-1.json +46 -0
- witwin_maxwell-0.7.0/witwin/maxwell/schemas/port-data-1.json +70 -0
- witwin_maxwell-0.7.0/witwin/maxwell/schemas/wire-data-1.json +38 -0
- witwin_maxwell-0.7.0/witwin/maxwell/schemas/witwin.scene-2.json +7350 -0
- witwin_maxwell-0.7.0/witwin/maxwell/simulation.py +2571 -0
- witwin_maxwell-0.7.0/witwin/maxwell/sources.py +1335 -0
- witwin_maxwell-0.7.0/witwin/maxwell/terminal_waveport.py +613 -0
- witwin_maxwell-0.7.0/witwin/maxwell/thin_wire.py +499 -0
- witwin_maxwell-0.7.0/witwin/maxwell/touchstone.py +919 -0
- witwin_maxwell-0.7.0/witwin/maxwell/waveport_sweep.py +993 -0
- witwin_maxwell-0.6.0/CHANGELOG.md +0 -277
- witwin_maxwell-0.6.0/PKG-INFO +0 -192
- witwin_maxwell-0.6.0/README.md +0 -169
- witwin_maxwell-0.6.0/hatch_build.py +0 -19
- witwin_maxwell-0.6.0/pyproject.toml +0 -56
- witwin_maxwell-0.6.0/witwin/maxwell/__init__.py +0 -634
- witwin_maxwell-0.6.0/witwin/maxwell/_fixed_inputs.py +0 -21
- witwin_maxwell-0.6.0/witwin/maxwell/absorbers.py +0 -163
- witwin_maxwell-0.6.0/witwin/maxwell/adapters/pcb.py +0 -193
- witwin_maxwell-0.6.0/witwin/maxwell/adapters/tidy3d.py +0 -2712
- witwin_maxwell-0.6.0/witwin/maxwell/adjoint_inputs.py +0 -228
- witwin_maxwell-0.6.0/witwin/maxwell/antenna.py +0 -307
- witwin_maxwell-0.6.0/witwin/maxwell/array.py +0 -1599
- witwin_maxwell-0.6.0/witwin/maxwell/array_execution.py +0 -67
- witwin_maxwell-0.6.0/witwin/maxwell/array_gradient.py +0 -375
- witwin_maxwell-0.6.0/witwin/maxwell/breakdown.py +0 -104
- witwin_maxwell-0.6.0/witwin/maxwell/breakdown_risk.py +0 -310
- witwin_maxwell-0.6.0/witwin/maxwell/breakdown_stress.py +0 -542
- witwin_maxwell-0.6.0/witwin/maxwell/circuit_devices.py +0 -292
- witwin_maxwell-0.6.0/witwin/maxwell/circuits.py +0 -1481
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/__init__.py +0 -104
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/build.py +0 -30
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/coefficients.py +0 -39
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/conductors.py +0 -55
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/cuda/binding.cpp +0 -53
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/cuda/bvh.cu +0 -138
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/cuda/checks.h +0 -18
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/cuda/coefficients.cu +0 -70
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/cuda/mesh.cu +0 -143
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/cuda/poles.cu +0 -206
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/cuda/setup.cu +0 -258
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/cuda/subpixel.cu +0 -93
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/cuda/tables.cu +0 -88
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/dispatch.py +0 -182
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/geometry.py +0 -146
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/poles.py +0 -164
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/setup.py +0 -127
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/accel/subpixel.py +0 -112
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/array.py +0 -369
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/breakdown.py +0 -151
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/circuits.py +0 -320
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/coaxial.py +0 -204
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/coordinates.py +0 -168
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/copper_foil.py +0 -576
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/curved_copper.py +0 -130
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/cut_surface.py +0 -227
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/electrostatic.py +0 -384
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/fdtd_audit.py +0 -78
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/gyromagnetic.py +0 -356
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/lumped.py +0 -102
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/mass_density.py +0 -139
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/materials.py +0 -3945
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/networks.py +0 -318
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/nonlinear_devices.py +0 -916
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/planar_pec.py +0 -247
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/ports.py +0 -509
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/power_loss.py +0 -217
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/sources.py +0 -263
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/structures.py +0 -32
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/subpixel.py +0 -446
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/terminal_waveports.py +0 -205
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/thin_sheet.py +0 -1564
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/thin_wire.py +0 -2174
- witwin_maxwell-0.6.0/witwin/maxwell/compiler/waveports.py +0 -442
- witwin_maxwell-0.6.0/witwin/maxwell/coordinates.py +0 -187
- witwin_maxwell-0.6.0/witwin/maxwell/copper_foil.py +0 -171
- witwin_maxwell-0.6.0/witwin/maxwell/dispersion_fit.py +0 -801
- witwin_maxwell-0.6.0/witwin/maxwell/electrostatic/__init__.py +0 -39
- witwin_maxwell-0.6.0/witwin/maxwell/electrostatic/api.py +0 -224
- witwin_maxwell-0.6.0/witwin/maxwell/electrostatic/capacitance.py +0 -433
- witwin_maxwell-0.6.0/witwin/maxwell/electrostatic/initial_condition.py +0 -305
- witwin_maxwell-0.6.0/witwin/maxwell/electrostatic/runtime.py +0 -878
- witwin_maxwell-0.6.0/witwin/maxwell/esd.py +0 -854
- witwin_maxwell-0.6.0/witwin/maxwell/execution/__init__.py +0 -45
- witwin_maxwell-0.6.0/witwin/maxwell/execution/adjoint.py +0 -154
- witwin_maxwell-0.6.0/witwin/maxwell/execution/batch.py +0 -336
- witwin_maxwell-0.6.0/witwin/maxwell/execution/batch_runtime.py +0 -1209
- witwin_maxwell-0.6.0/witwin/maxwell/execution/capacity.py +0 -171
- witwin_maxwell-0.6.0/witwin/maxwell/execution/ensemble.py +0 -187
- witwin_maxwell-0.6.0/witwin/maxwell/execution/plan.py +0 -267
- witwin_maxwell-0.6.0/witwin/maxwell/execution/pool.py +0 -262
- witwin_maxwell-0.6.0/witwin/maxwell/execution/records.py +0 -244
- witwin_maxwell-0.6.0/witwin/maxwell/execution/tuning.py +0 -197
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/__init__.py +0 -3
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/adjoint/bridge.py +0 -197
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/magnetic.py +0 -102
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/materials.py +0 -69
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/modes.py +0 -131
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/observations.py +0 -202
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/pml.py +0 -84
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/response.py +0 -615
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/solver.py +0 -1175
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd/sweep.py +0 -134
- witwin_maxwell-0.6.0/witwin/maxwell/fdfd_response.py +0 -144
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/__init__.py +0 -10
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/adjoint/bridge.py +0 -1800
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/adjoint/capabilities.py +0 -32
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/adjoint/copper_spectra.py +0 -134
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/adjoint/core.py +0 -3854
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/adjoint/dispatch.py +0 -775
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/adjoint/joint_material.py +0 -89
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/adjoint/mapped_admission.py +0 -272
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/adjoint/reverse_common.py +0 -355
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/boundary/__init__.py +0 -37
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/boundary/abc.py +0 -407
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/boundary/bloch.py +0 -90
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/boundary/cpml.py +0 -594
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/boundary/runtime.py +0 -322
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/checkpoint.py +0 -688
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/circuits.py +0 -1241
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/coaxial.py +0 -356
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/coords.py +0 -32
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/copper_foil.py +0 -606
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cpu_profile.py +0 -45
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cpu_reference.py +0 -279
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/__init__.py +0 -11
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/backend.py +0 -3820
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/build.py +0 -368
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/core/binding.cpp +0 -325
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/core/build.py +0 -41
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/core/observers.cu +0 -45
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/core/observers.cuh +0 -31
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/core/step.cu +0 -259
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/core/step.cuh +0 -52
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/core/yee.cu +0 -345
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/core/yee.cuh +0 -31
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/extension.cpp +0 -2397
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/kernels/common.cu +0 -166
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/kernels/common.cuh +0 -243
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/kernels/electric.cu +0 -3981
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/kernels/magnetic.cu +0 -1140
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/kernels/observers.cu +0 -622
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/kernels/projection.cu +0 -211
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/runtime/__init__.py +0 -6
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cuda/runtime/dispatcher.py +0 -6
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/curved_copper.py +0 -126
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/cut_surface.py +0 -194
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/adjoint.py +0 -1667
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/circuits.py +0 -613
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/copper.py +0 -304
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/instrumentation.py +0 -199
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/monitor_merge.py +0 -470
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/networks.py +0 -638
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/observations.py +0 -91
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/resume.py +0 -194
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/shard_engine.py +0 -488
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/distributed/solver.py +0 -1430
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/evaluation.py +0 -290
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/fixed_k.py +0 -161
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/injection.py +0 -1644
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/modes/__init__.py +0 -1247
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/modes/common.py +0 -680
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/modes/conductors.py +0 -266
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/modes/tem.py +0 -667
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/modes/vector.py +0 -1218
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/spatial.py +0 -614
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/temporal.py +0 -655
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/tfsf_common.py +0 -449
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/excitation/tfsf_state.py +0 -880
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/ferrite_reference.py +0 -403
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/io.py +0 -31
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/lumped.py +0 -1037
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/material_pullback.py +0 -505
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/networks.py +0 -1269
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/observers.py +0 -1869
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/plane_product.py +0 -309
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/plotting.py +0 -121
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/ports.py +0 -2663
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/postprocess.py +0 -219
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/quadrature.py +0 -238
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/resume.py +0 -998
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/__init__.py +0 -133
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/batch.py +0 -264
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/breakdown.py +0 -533
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/core_path.py +0 -744
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/core_tables.py +0 -279
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/gyromagnetic.py +0 -469
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/initialization.py +0 -299
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/materials.py +0 -1973
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/module_cache.py +0 -35
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/passivity.py +0 -334
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/precision.py +0 -74
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/spectral.py +0 -665
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/stepping.py +0 -2733
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/timeplan.py +0 -194
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/runtime/timestep.py +0 -187
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/solver.py +0 -544
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/surface_impedance_reference.py +0 -349
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/thin_sheet.py +0 -1369
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/thin_wire_reference.py +0 -388
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/time_flux.py +0 -102
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/time_traces.py +0 -276
- witwin_maxwell-0.6.0/witwin/maxwell/fdtd/wire.py +0 -1399
- witwin_maxwell-0.6.0/witwin/maxwell/geometry/__init__.py +0 -7
- witwin_maxwell-0.6.0/witwin/maxwell/geometry/planar_pec.py +0 -125
- witwin_maxwell-0.6.0/witwin/maxwell/geometry/polyslab.py +0 -299
- witwin_maxwell-0.6.0/witwin/maxwell/geometry/surface_mesh.py +0 -209
- witwin_maxwell-0.6.0/witwin/maxwell/geometry/terminal_support.py +0 -539
- witwin_maxwell-0.6.0/witwin/maxwell/invdes/constraints.py +0 -107
- witwin_maxwell-0.6.0/witwin/maxwell/invdes/filters.py +0 -262
- witwin_maxwell-0.6.0/witwin/maxwell/invdes/optimize.py +0 -134
- witwin_maxwell-0.6.0/witwin/maxwell/invdes/parameterization.py +0 -108
- witwin_maxwell-0.6.0/witwin/maxwell/invdes/projection.py +0 -202
- witwin_maxwell-0.6.0/witwin/maxwell/invdes/symmetry.py +0 -143
- witwin_maxwell-0.6.0/witwin/maxwell/layers.py +0 -44
- witwin_maxwell-0.6.0/witwin/maxwell/lumped.py +0 -614
- witwin_maxwell-0.6.0/witwin/maxwell/material_cache.py +0 -278
- witwin_maxwell-0.6.0/witwin/maxwell/material_library.py +0 -284
- witwin_maxwell-0.6.0/witwin/maxwell/media.py +0 -2950
- witwin_maxwell-0.6.0/witwin/maxwell/modal_sweep.py +0 -727
- witwin_maxwell-0.6.0/witwin/maxwell/mom/anisotropic_fields.py +0 -480
- witwin_maxwell-0.6.0/witwin/maxwell/mom/anisotropic_lifting.py +0 -203
- witwin_maxwell-0.6.0/witwin/maxwell/mom/anisotropic_operator.py +0 -330
- witwin_maxwell-0.6.0/witwin/maxwell/mom/complex_static_tensor_green.py +0 -200
- witwin_maxwell-0.6.0/witwin/maxwell/mom/direct_capacity.py +0 -85
- witwin_maxwell-0.6.0/witwin/maxwell/mom/direct_config.py +0 -66
- witwin_maxwell-0.6.0/witwin/maxwell/mom/dual_action_snapshot.py +0 -173
- witwin_maxwell-0.6.0/witwin/maxwell/mom/dual_current_action.py +0 -218
- witwin_maxwell-0.6.0/witwin/maxwell/mom/dual_current_receipt.py +0 -67
- witwin_maxwell-0.6.0/witwin/maxwell/mom/dual_current_response.py +0 -108
- witwin_maxwell-0.6.0/witwin/maxwell/mom/dyadic_contrast.py +0 -686
- witwin_maxwell-0.6.0/witwin/maxwell/mom/dyadic_green.py +0 -1298
- witwin_maxwell-0.6.0/witwin/maxwell/mom/efie_open.py +0 -572
- witwin_maxwell-0.6.0/witwin/maxwell/mom/efie_preconditioning.py +0 -369
- witwin_maxwell-0.6.0/witwin/maxwell/mom/ewald_nearfield.py +0 -134
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fields.py +0 -615
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fixed_tangent_inverse.py +0 -137
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_capacity.py +0 -319
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_config.py +0 -424
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_directional_moments.py +0 -983
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_directional_shift.py +0 -490
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_error.py +0 -691
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_order.py +0 -947
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_periodic.py +0 -173
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_periodic_capacity.py +0 -134
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_periodic_error.py +0 -198
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_periodic_order.py +0 -110
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_periodic_regional.py +0 -195
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_periodic_system.py +0 -178
- witwin_maxwell-0.6.0/witwin/maxwell/mom/fmm_system.py +0 -406
- witwin_maxwell-0.6.0/witwin/maxwell/mom/h2.py +0 -230
- witwin_maxwell-0.6.0/witwin/maxwell/mom/h2_basis.py +0 -260
- witwin_maxwell-0.6.0/witwin/maxwell/mom/h2_capacity.py +0 -78
- witwin_maxwell-0.6.0/witwin/maxwell/mom/h2_operator.py +0 -133
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_balance.py +0 -327
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_config.py +0 -155
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_current.py +0 -176
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_current_snapshot.py +0 -249
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_dual_current.py +0 -210
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_fields.py +0 -198
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_jacobian_action.py +0 -165
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_material.py +0 -207
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_observables.py +0 -232
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_preparation.py +0 -240
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_runtime.py +0 -473
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_snapshot.py +0 -481
- witwin_maxwell-0.6.0/witwin/maxwell/mom/harmonic_state.py +0 -339
- witwin_maxwell-0.6.0/witwin/maxwell/mom/hmatrix.py +0 -395
- witwin_maxwell-0.6.0/witwin/maxwell/mom/implicit_surface_solve.py +0 -143
- witwin_maxwell-0.6.0/witwin/maxwell/mom/interpolation_error.py +0 -127
- witwin_maxwell-0.6.0/witwin/maxwell/mom/interpolation_order.py +0 -128
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/__init__.py +0 -10
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/assembly.py +0 -184
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/build.py +0 -30
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/config.py +0 -81
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/cuda/assembly.cu +0 -829
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/cuda/binding.cpp +0 -162
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/cuda/common.cuh +0 -62
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/cuda/green_eval.cuh +0 -299
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/cuda/interp.cu +0 -262
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/cuda/lowfreq.cu +0 -410
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/cuda/spectral.cu +0 -432
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/cuda/vertical.cu +0 -259
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/green.py +0 -383
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/loss.py +0 -102
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/lowfreq.py +0 -119
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/mesh.py +0 -298
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/network.py +0 -375
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/process.py +0 -231
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/runtime.py +0 -232
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/sweep.py +0 -113
- witwin_maxwell-0.6.0/witwin/maxwell/mom/layered/vertical.py +0 -317
- witwin_maxwell-0.6.0/witwin/maxwell/mom/lifting.py +0 -742
- witwin_maxwell-0.6.0/witwin/maxwell/mom/linalg.py +0 -1523
- witwin_maxwell-0.6.0/witwin/maxwell/mom/linear_runtime.py +0 -104
- witwin_maxwell-0.6.0/witwin/maxwell/mom/linear_volume_state.py +0 -110
- witwin_maxwell-0.6.0/witwin/maxwell/mom/lowrank.py +0 -200
- witwin_maxwell-0.6.0/witwin/maxwell/mom/magnetostatic.py +0 -112
- witwin_maxwell-0.6.0/witwin/maxwell/mom/near_preconditioner.py +0 -167
- witwin_maxwell-0.6.0/witwin/maxwell/mom/operator.py +0 -739
- witwin_maxwell-0.6.0/witwin/maxwell/mom/ordered_reduction.py +0 -18
- witwin_maxwell-0.6.0/witwin/maxwell/mom/packed_near.py +0 -775
- witwin_maxwell-0.6.0/witwin/maxwell/mom/periodic.py +0 -473
- witwin_maxwell-0.6.0/witwin/maxwell/mom/periodic_config.py +0 -162
- witwin_maxwell-0.6.0/witwin/maxwell/mom/periodic_diffraction.py +0 -232
- witwin_maxwell-0.6.0/witwin/maxwell/mom/periodic_dyadic.py +0 -1168
- witwin_maxwell-0.6.0/witwin/maxwell/mom/periodic_fields.py +0 -176
- witwin_maxwell-0.6.0/witwin/maxwell/mom/periodic_operator.py +0 -208
- witwin_maxwell-0.6.0/witwin/maxwell/mom/periodic_runtime.py +0 -446
- witwin_maxwell-0.6.0/witwin/maxwell/mom/pfft_config.py +0 -156
- witwin_maxwell-0.6.0/witwin/maxwell/mom/pfft_coupling.py +0 -257
- witwin_maxwell-0.6.0/witwin/maxwell/mom/pfft_lifting.py +0 -220
- witwin_maxwell-0.6.0/witwin/maxwell/mom/pfft_operator.py +0 -235
- witwin_maxwell-0.6.0/witwin/maxwell/mom/pfft_system.py +0 -381
- witwin_maxwell-0.6.0/witwin/maxwell/mom/physics.py +0 -308
- witwin_maxwell-0.6.0/witwin/maxwell/mom/preconditioning.py +0 -241
- witwin_maxwell-0.6.0/witwin/maxwell/mom/primitive_mesh.py +0 -766
- witwin_maxwell-0.6.0/witwin/maxwell/mom/runtime.py +0 -1280
- witwin_maxwell-0.6.0/witwin/maxwell/mom/rwg_interpolation_error.py +0 -196
- witwin_maxwell-0.6.0/witwin/maxwell/mom/rwg_refinement.py +0 -72
- witwin_maxwell-0.6.0/witwin/maxwell/mom/static_current.py +0 -397
- witwin_maxwell-0.6.0/witwin/maxwell/mom/static_current_projector.py +0 -96
- witwin_maxwell-0.6.0/witwin/maxwell/mom/static_projector_snapshot.py +0 -98
- witwin_maxwell-0.6.0/witwin/maxwell/mom/static_tensor_floating.py +0 -212
- witwin_maxwell-0.6.0/witwin/maxwell/mom/static_tensor_interface.py +0 -271
- witwin_maxwell-0.6.0/witwin/maxwell/mom/static_tensor_material.py +0 -150
- witwin_maxwell-0.6.0/witwin/maxwell/mom/static_tensor_polarization.py +0 -128
- witwin_maxwell-0.6.0/witwin/maxwell/mom/static_tensor_volume.py +0 -263
- witwin_maxwell-0.6.0/witwin/maxwell/mom/surface_h_snapshot.py +0 -242
- witwin_maxwell-0.6.0/witwin/maxwell/mom/surface_volume.py +0 -336
- witwin_maxwell-0.6.0/witwin/maxwell/mom/tensor_harmonic_bundle.py +0 -335
- witwin_maxwell-0.6.0/witwin/maxwell/mom/tensor_harmonic_preparation.py +0 -261
- witwin_maxwell-0.6.0/witwin/maxwell/mom/tensor_harmonic_runtime.py +0 -260
- witwin_maxwell-0.6.0/witwin/maxwell/mom/tensor_harmonic_snapshot.py +0 -339
- witwin_maxwell-0.6.0/witwin/maxwell/mom/tensor_nearfield.py +0 -124
- witwin_maxwell-0.6.0/witwin/maxwell/mom/topology.py +0 -233
- witwin_maxwell-0.6.0/witwin/maxwell/mom/vie_operator.py +0 -275
- witwin_maxwell-0.6.0/witwin/maxwell/mom/volume_mesh.py +0 -201
- witwin_maxwell-0.6.0/witwin/maxwell/mom/volume_response_matrix.py +0 -385
- witwin_maxwell-0.6.0/witwin/maxwell/monitors.py +0 -1985
- witwin_maxwell-0.6.0/witwin/maxwell/network.py +0 -1719
- witwin_maxwell-0.6.0/witwin/maxwell/network_sweep.py +0 -324
- witwin_maxwell-0.6.0/witwin/maxwell/path_integrals.py +0 -274
- witwin_maxwell-0.6.0/witwin/maxwell/ports.py +0 -1380
- witwin_maxwell-0.6.0/witwin/maxwell/ports_postprocess.py +0 -111
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/__init__.py +0 -91
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/antenna.py +0 -722
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/array.py +0 -439
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/diffraction.py +0 -219
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/emission.py +0 -67
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/fdtd_loss.py +0 -201
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/gaussian_overlap.py +0 -170
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/low_frequency.py +0 -141
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/modal.py +0 -362
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/plane_payload.py +0 -71
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/resonance.py +0 -394
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/sar.py +0 -371
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/sar_combine.py +0 -289
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/scattering_parameters.py +0 -394
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/selected_query.py +0 -283
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/stratton_chu.py +0 -1446
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/waveports.py +0 -432
- witwin_maxwell-0.6.0/witwin/maxwell/postprocess/yee_interpolation.py +0 -205
- witwin_maxwell-0.6.0/witwin/maxwell/rational.py +0 -1409
- witwin_maxwell-0.6.0/witwin/maxwell/result.py +0 -3160
- witwin_maxwell-0.6.0/witwin/maxwell/roughness.py +0 -229
- witwin_maxwell-0.6.0/witwin/maxwell/sar.py +0 -524
- witwin_maxwell-0.6.0/witwin/maxwell/scene.py +0 -2329
- witwin_maxwell-0.6.0/witwin/maxwell/scene_dict.py +0 -274
- witwin_maxwell-0.6.0/witwin/maxwell/simulation.py +0 -2568
- witwin_maxwell-0.6.0/witwin/maxwell/sources.py +0 -1307
- witwin_maxwell-0.6.0/witwin/maxwell/terminal_waveport.py +0 -601
- witwin_maxwell-0.6.0/witwin/maxwell/thin_wire.py +0 -491
- witwin_maxwell-0.6.0/witwin/maxwell/touchstone.py +0 -918
- witwin_maxwell-0.6.0/witwin/maxwell/waveport_sweep.py +0 -980
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/.gitignore +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/LICENSE +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/_gc.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/adapters/__init__.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/adapters/gds.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/_scalar_cache.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/accel/__init__.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/accel/cuda/distance.cuh +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/accel/mesh.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/accel/primitives.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/accel/tables.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/delay.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/mna.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/monitors.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/passive_fit.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/path_integrals.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/surface_impedance.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/trilinear.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/compiler/wire_impedance.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/constants.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/execution/executor.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdfd/adjoint/__init__.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdfd/ams.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdfd/krylov.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdfd/optimization.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdfd/plotting.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdfd/postprocess.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdfd/response_cache.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdfd/update_cuda.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdfd/update_solve.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/adjoint/__init__.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/adjoint/accumulation.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/adjoint/circuits.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/adjoint/copper_foil.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/adjoint/native.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/adjoint/profiler.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/adjoint/seeds.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/boundary/common.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/boundary/mur.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/copper_foil_ade.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/adjoint.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/aniso.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/boundary.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/copper.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/dispersive.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/modulation.cuh +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/sources.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/spectral.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/thin_sheet.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/trilinear.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/kernels/wire.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/launch.h +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/runtime/graph.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/source_gather.cuh +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/cuda/tensors.h +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/delay.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/dispersion.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/__init__.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/_shared.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/capacity.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/counts.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/frequency_counts.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/interpolation.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/nccl_transport.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/output.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/persistence.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/source_corrections.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/source_rebuild.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/sources.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/transport.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/distributed/wire.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/excitation/__init__.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/excitation/gather.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/excitation/incident_line_spectrum.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/excitation/modes/eigensolvers.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/excitation/modes/yee.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/excitation/tfsf_apply.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/excitation/tfsf_specs.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/meshing/__init__.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/meshing/autogrid.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/meshing/corners.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/observation_resume.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/runtime/batch_materials.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/runtime/representation.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd/wire_lossy.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/fdtd_parallel.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/invdes/__init__.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/materials.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/action_harmonic_balance.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/background_bank_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/block_preconditioner.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/carrier.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/cluster.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/compressed_background.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/compressed_harmonic_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/compressed_volume_preparation.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/conductive_static.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/coupled_field_refinement.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/coupled_original_check.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/coupled_response_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/coupled_volume_action.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/dipole.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/direct_operator.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/direct_regional.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/direct_system.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/dual_current_material.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/dual_preparation_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/dual_static_current.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/dual_static_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/ewald_refinement.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_compact.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_directional_fft.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_directional_rwg.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_ewald_fft.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_ewald_real.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_ewald_spectral.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_ewald_translation.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_expansion.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_fft.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_fft_coefficients.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_moments.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_operator.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_periodic_operator.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_regional.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_rwg_error.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_shift.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_storage.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/fmm_translation.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/harmonic_convergence.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/harmonic_cutoff_receipt.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/harmonic_dual_bridge.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/harmonic_mixed.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/harmonic_mixed_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/hierarchical_blocks.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/hierarchical_runtime.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/incident_work.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/interior_volume_hmatrix.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/interpolated_far.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/interpolation.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/interpolation_kernel.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/kernels.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/layered/cuda/bessel.cu +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/layered/cuda/triangle_static.cuh +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/lifting_fields.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/matched_spd_green.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/mesh.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/migration.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/modes.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/nearfield.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/nested_h2_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/nested_moments.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/nonlinear.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/observables.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/open_surface.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/operator_error.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/operator_protocol.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/periodic_cylindrical.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/periodic_dyadic_fields.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/periodic_dyadic_nearfield.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/periodic_dyadic_operator.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/periodic_hierarchical_runtime.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/periodic_limits.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/periodic_nearfield.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/periodic_spectral.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/pfft_efie.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/pfft_grid.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/physical_surface_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/quadrature.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/riesz.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/rwg_moments.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/scalar_moment_action.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/scalar_near_channels.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/single_layer.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/spatial.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/spectral_linalg.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_coupling.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_floating.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_magnetic.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_magnetic_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_magnetic_volume.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_mixed.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_tensor_green.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_tensor_preparation.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_tensor_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/static_volume_curl.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/streamed_dual_state_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/surface_volume_hmatrix.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/tensor_carrier.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/tensor_medium.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/tensor_volume.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/volume_basis.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/volume_h2.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/volume_h2_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/volume_h_snapshot.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/volume_hmatrix.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/mom/volume_source_refinement.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/network_math.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/RCS.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/array_factor.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/array_taper.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/directivity.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/field_projection.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/floquet.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/incident_power.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/lobes.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/nfft.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/power_loss.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/postprocess/sar_averaging.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/power_loss.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/visualization/__init__.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/visualization/interactive.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/visualization/plots.py +0 -0
- {witwin_maxwell-0.6.0 → witwin_maxwell-0.7.0}/witwin/maxwell/waveforms.py +0 -0
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable user-visible changes to WiTwin Maxwell are documented here. The project follows semantic versioning within the `0.x` development series.
|
|
4
|
+
|
|
5
|
+
## [0.7.0] - 2026-11-14
|
|
6
|
+
|
|
7
|
+
Full details and migration notes are in the [0.7.0 release notes](docs/reference/release-notes-0.7.0.md).
|
|
8
|
+
|
|
9
|
+
### Breaking changes
|
|
10
|
+
|
|
11
|
+
- **`Scene` is immutable** (a frozen dataclass with identity equality and hashing). Its collections are tuples (`scene.structures`, `sources`, `monitors`, `ports`, `thin_wires`, `networks`, `lumped_elements`, `circuits`, `material_regions`, `electrostatic_terminals`, `charge_densities`, `internal_absorbers`); assigning a field or mutating a collection raises. The twelve `Scene.add_*` methods are removed (plan Q17: removed, not turned into functional variants) and `Scene.clone(**overrides)` is replaced by `Scene.updated(**fields)`, which returns a new `Scene`, shares every unchanged object and re-validates only the replaced fields and the cross-object rules that read them (ports against `structures`/`domain`, networks against `ports`, lumped elements and coordinates against `domain`). The constructor keeps its keywords and validation, so pass collections to it, or use `scene.updated(structures=(*scene.structures, s))`. `Scene.with_*` stays forbidden.
|
|
12
|
+
|
|
13
|
+
| 0.6 | 0.7.0 |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `scene.add_structure(s)` (likewise `add_source`, `add_monitor`, `add_port`, `add_thin_wire`, `add_lumped_element`, `add_network`, `add_circuit`, `add_material_region`, `add_internal_absorber`, `add_electrostatic_terminal`, `add_charge_density`) | `Scene(..., structures=(s, ...))` or `scene = scene.updated(structures=(*scene.structures, s))` |
|
|
16
|
+
| `scene.clone(**overrides)` | `scene.updated(**fields)` |
|
|
17
|
+
| `scene.structures[i] = s`, `scene.sources.clear()`, `scene.grid = g` | `scene = scene.updated(structures=..., sources=(), grid=g)` |
|
|
18
|
+
| `Scene(subpixel_samples=...)` | `Scene(subpixel=...)` (a `SubpixelSpec`, or samples as before) |
|
|
19
|
+
|
|
20
|
+
- **`Scene(device=..., verbose=..., lazy_meshgrid=...)` are removed; the solver config owns device placement (plan Q18).** `FDTDConfig`, `FDFDConfig`, `mw.mom.MoMConfig`, `mw.electrostatic.ElectrostaticConfig` and `mw.electrostatic.CapacitanceConfig` gain `device` (default `"cuda"`; `MoMConfig.device` is placement only and does not enter its equality), and `FDTDConfig` gains `verbose` (`FDFDConfig.verbose` already existed). Preparation places the grid and compiled tensors on the config device; the declarative tensors of a scene are not copied. `lazy_meshgrid` is an internal preparation option. A non-CUDA device is refused with `requires config.device to be CUDA` (previously `requires scene.device to be CUDA`). `prepare_scene(scene, device=...)` and `compile_electrostatics(scene, ..., device=...)` take the device (default CUDA), `Result.load(..., device="cuda")` names the device of restored MoM state, and `import_pcb_scene(...)` and `ProcessStack.scene_from_gds(...)` drop their `device` argument. Migration: move `device=`/`verbose=` from `Scene(...)` to the config (`mw.FDTDConfig(device="cuda:1")`); scene-only CPU work passes `device="cpu"` to `prepare_scene` or the compile call.
|
|
21
|
+
- `mw.rf.PECFrame(length).structures(port, scene, device=...)` takes the device explicitly (no default): a declarative `scene` is prepared there, so it must be where the scene's geometry tensors live (pass `prepared.device` with a prepared scene). Before this fix 0.7.0 prepared it on the host, which failed for CUDA-resident geometry touching the PML; WavePort and TerminalWavePort runs now lay out their injection planes on `config.device` as in 0.6.
|
|
22
|
+
- **Legacy `Scene` convenience properties are removed:** `bc_type`, `boundary_type` (use `scene.boundary.kind`), `pml_thickness`, `pml_strength` (use `scene.boundary.num_layers`/`strength`), `dx`/`dy`/`dz`, `grid_spacing` (use `scene.grid.dx`/`spacing`), `domain_size`, `bloch_wavevector`, `bloch_phase_factors` (use `scene.boundary`), `subpixel_samples` (use `scene.subpixel.samples`) and `physical_positions` (use `scene.coordinates.position(...)`). `boundary_face_kind`, `pml_thickness_for_face`, `has_symmetry`, `resolved_sources()`, `resolved_monitors()`, `to_dict()` and `from_dict()` stay.
|
|
23
|
+
- **`Scene.to_tidy3d(...)` is removed (plan phase 7c).** Export through the adapter function `witwin.maxwell.adapters.tidy3d.scene_to_tidy3d(scene, frequencies=..., run_time=..., **kwargs)`, which the method only delegated to (it also takes `length_scale` and `cw_steady_state`); the exported simulation is unchanged. Adapter error messages now name `scene_to_tidy3d()`. Migration: `scene.to_tidy3d(...)` becomes `scene_to_tidy3d(scene, ...)`.
|
|
24
|
+
- Without a solver config, grid layout follows the data: `Result.prepared_scene`, `Result.fields` and the postprocessing that reads them (power loss, raw monitors, closed-surface payloads) lay out the grid on the device of the stored result tensors, or on the host when the result holds none; material pullbacks run on the device of the adjoint gradients. `FDTDConfig.verbose` is a fixed input (a trainable tensor is refused like the other execution flags).
|
|
25
|
+
- `SceneModule.to_scene()` is unchanged. Building the static part once (`self._base = mw.Scene(...)`) and returning `self._base.updated(material_regions=(...))` shares every static object, and the static parts are not recompiled (see Added).
|
|
26
|
+
- Migration for the whole phase: `python scripts/dev/codemods/070_p7a_scene_frozen.py apply <paths>`, then `check`. It folds `scene.add_*` sequences into the constructor, rewrites the remaining additions, `clone`, field and item assignments to `updated`, moves dropped constructor keywords, and lists what it cannot decide (additions to function parameters or free names, simulation-scene mutations, reads of removed members).
|
|
27
|
+
|
|
28
|
+
- **`Scene.compile_*` and the `PreparedScene` compile methods are internal functions of `witwin.maxwell.compiler`** that take the prepared scene first; `PreparedScene` is no longer a `Scene` subclass. A `PreparedScene` (from `witwin.maxwell.scene.prepare_scene(scene, device=...)`) holds the grid state, the compile caches and `prepared.scene`, the prepared declarations (the scene with the resolved grid, the PML extrusions and the coordinates on the device); read declarations there (`prepared.scene.structures`), not on the prepared scene. `witwin.maxwell.compiler` is internal and in no public `__all__`. No numerical change.
|
|
29
|
+
|
|
30
|
+
| 0.7.0 phase 7a | 0.7.0 |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `scene.compile_ports(device=d)` (likewise `compile_thin_wires`, `compile_wire_monitors`, `compile_waveports`, `compile_lumped_elements`, `compile_networks(dt=...)`, `compile_circuits`) | `compile_ports(prepare_scene(scene, device=d))` |
|
|
33
|
+
| `prepared.compile_materials(subpixel_samples=s)` (likewise `compile_material_components`, `compile_relative_materials`, `compile_material_tensors`, `compile_mass_density`, `compile_gyromagnetic_materials`, and the port/wire/network/lumped/circuit compiles) | `compile_materials(prepared, subpixel=s)` |
|
|
34
|
+
| `scene.compile_array_monitors(...)`, `scene.compile_electrostatics(...)` | `compile_array_monitors(scene, ...)`, `compile_electrostatics(scene, ...)` (from `witwin.maxwell.compiler.electrostatic`) |
|
|
35
|
+
| `prepared.structures`, `prepared.boundary`, `prepared.resolved_sources()` (any `Scene` field or method on a `PreparedScene`) | `prepared.scene.structures`, `prepared.scene.boundary`, `prepared.scene.resolved_sources()` |
|
|
36
|
+
|
|
37
|
+
Migration: `python scripts/dev/codemods/070_p7b_compiler_internal.py apply <paths>`, then `check`. It rewrites the compile method calls and adds the imports; reads of `Scene` fields on a `PreparedScene` are not rewritten (they raise `AttributeError`).
|
|
38
|
+
|
|
39
|
+
- **`fdtd_core_path` and `accelerated_setup` are removed from `Simulation.fdtd(...)` and `FDTDConfig`.** The accelerated CUDA path is the only public FDTD path: every eligible scene runs on the core path with accelerated setup, as under the 0.6.0 `"auto"` default. Passing either keyword now raises `TypeError` (unexpected keyword argument). Since W7 row 16c every FDTD scene runs on the core path and nothing falls back to the existing stepping path (see the next entry); the 0.6.0 explicit-`True` continuation of a failed whole-step capture on the per-step core loop is gone.
|
|
40
|
+
|
|
41
|
+
| 0.6.0 | 0.7.0 |
|
|
42
|
+
|---|---|
|
|
43
|
+
| `fdtd_core_path="auto"`, `accelerated_setup="auto"` (defaults) | remove the keywords; same behavior |
|
|
44
|
+
| `fdtd_core_path=True` (refuse ineligible scenes with `ValueError`) | remove the keyword; every scene runs on the core path |
|
|
45
|
+
| `fdtd_core_path=False` and/or `accelerated_setup=False` (existing path, PyTorch setup) | no replacement; the existing path is internal |
|
|
46
|
+
| `accelerated_setup=True` | remove the keyword; setup acceleration is automatic |
|
|
47
|
+
| `FDTDConfig.fdtd_core_path`, `FDTDConfig.accelerated_setup` | removed attributes |
|
|
48
|
+
|
|
49
|
+
- **`mw.fdtd.FDTDCoreFallbackWarning` and the `execution_path`/`fallback_reason` keys of `Result.stats()` and `Result.metadata` are removed; a failed core attempt raises instead of falling back (W7 row 16c, user decision 2026-11-12).** No admission blocker is left, so the automatic fallback to the existing stepping path is gone and there is no deprecation shim. A failure of the accelerated CUDA setup retries the preparation once on the core path with the PyTorch setup (the numerics of a material-cache run) and warns with `mw.MaxwellWarning`; a second failure raises. A failure to load the core-path library, to activate the core path, or to capture or replay the whole-step CUDA graph raises that error (the solver state is restored first; a fresh `prepare()` starts over). The same holds for the differentiable forward and for multi-GPU shards, which no longer rebuild bounded per-component kernels after a failed core activation. `ESDCurrentSource` scenes, which kept the existing path through the `"unsupported source type"` blocker, run on the core path (the source lowers to a `UniformCurrentSource`; results are bitwise unchanged). A wheel build with only some of the three prebuilt FDTD libraries is refused. Features no path supports still raise their own refusals, and a CPU scene still raises `ValueError` at preparation.
|
|
50
|
+
|
|
51
|
+
| 0.6.0 / earlier 0.7.0 | 0.7.0 |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `warnings.simplefilter("error", mw.fdtd.FDTDCoreFallbackWarning)` | remove the filter; failures raise |
|
|
54
|
+
| `result.stats()["execution_path"]`, `result.metadata["execution_path"]` | removed (always the core path) |
|
|
55
|
+
| `result.stats()["fallback_reason"]`, `result.metadata["fallback_reason"]` | removed; a failure raises its own exception |
|
|
56
|
+
| a failed core activation, capture or library load rebuilt the run on the existing path | the error propagates |
|
|
57
|
+
| a failed accelerated setup rebuilt the run on the existing path with PyTorch setup | the run retries on the core path with PyTorch setup and warns (`mw.MaxwellWarning`) |
|
|
58
|
+
|
|
59
|
+
- **The CPU reference FDTD profile and the kernel-selector environment variables are removed.** FDTD runs on CUDA only. `Simulation.fdtd(..., backend=...)` and `FDTDConfig.backend` are deleted (passing `backend` raises `TypeError`), and a CPU scene is refused by the existing CUDA requirement (`ValueError`). `WITWIN_MAXWELL_THIN_SHEET_KERNEL` and `WITWIN_MAXWELL_COPPER_KERNEL` are no longer read: conformal thin sheets and ordinary `CopperFoil` sheets always run their fused CUDA kernels (paired, phase and material-trace ADE foils keep their Torch copper step, as before). No CUDA result changes. Reference implementations that no production path ran moved out of the package into the test suite (`tests/oracles/`): the Torch Yee kernel subset of the CPU profile, the Torch thin-sheet arithmetic, `fdtd.ferrite_reference`, `fdtd.surface_impedance_reference`, `fdtd.thin_wire_reference`, `fdtd.curved_copper`, `compiler.curved_copper`, `compiler.nonlinear_devices` (with `NonlinearDeviceError` and `NonlinearConvergenceError`) and the pure gyromagnetic recurrence `fdtd.runtime.advance_gyromagnetic_state`/`apply_gyromagnetic_correction`. `fdtd.evaluation` (CPML tuning helpers) is deleted, and the distributed step-rate instrument `fdtd.distributed.instrumentation` moved to the test support code.
|
|
60
|
+
|
|
61
|
+
| 0.6.0 | 0.7.0 |
|
|
62
|
+
|---|---|
|
|
63
|
+
| `Simulation.fdtd(..., backend="native")` | remove the keyword; same behavior |
|
|
64
|
+
| `Simulation.fdtd(cpu_scene, backend="cpu_reference")` | no replacement; run the scene on CUDA |
|
|
65
|
+
| `WITWIN_MAXWELL_THIN_SHEET_KERNEL=torch`, `WITWIN_MAXWELL_COPPER_KERNEL=torch` | no replacement; the variables are ignored |
|
|
66
|
+
| `witwin.maxwell.fdtd.ferrite_reference`, `.surface_impedance_reference`, `.thin_wire_reference`, `.curved_copper`, `.evaluation`, `.distributed.instrumentation`; `witwin.maxwell.compiler.curved_copper`, `.nonlinear_devices` | removed modules |
|
|
67
|
+
|
|
68
|
+
- **`FDTDConfig`, `FDFDConfig` and `SpectralSampler` are frozen dataclasses.** Assigning to a field raises `dataclasses.FrozenInstanceError`. Previously the assignment succeeded and skipped the constructor's validation and normalization (for example `config.run_time = None` was accepted). Build a new record with `dataclasses.replace(...)`, which validates it again. `TimeConfig`, `GMRES` (now `FDFDSolverConfig`) and `MoMConfig` were already frozen.
|
|
69
|
+
|
|
70
|
+
| 0.6.0 | 0.7.0 |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `simulation.config.run_time = mw.TimeConfig(time_steps=n)` | `simulation.config = dataclasses.replace(simulation.config, run_time=mw.TimeConfig(time_steps=n))` |
|
|
73
|
+
| `simulation.config.spectral_sampler.window = "none"` | `simulation.config = dataclasses.replace(simulation.config, spectral_sampler=dataclasses.replace(simulation.config.spectral_sampler, window="none"))` |
|
|
74
|
+
| `simulation.config.local_response = ...` (FDFD) | `simulation.config = dataclasses.replace(simulation.config, local_response=...)` |
|
|
75
|
+
|
|
76
|
+
- **`Simulation(...)` no longer takes `reference_frequency=` or `material_cache=`, and the `Simulation.material_cache` attribute is removed.** Both settings live only in `FDTDConfig`; the new field `FDTDConfig.material_cache` holds the `FDTDMaterialCache`. `FDTDConfig(reference_frequency=..., material_cache=...)` sets them (the `Simulation.fdtd(...)` keywords of the same name moved into `config=`, see the single configuration entry below). `FDTDConfig(material_cache=...)` raises `TypeError` for a value that is not an `FDTDMaterialCache` (previously raised by `Simulation(...)`). FDFD and MoM simulations have no such fields; the former `ValueError`/`TypeError` for passing them to a non-FDTD `Simulation(...)` is gone with the keywords.
|
|
77
|
+
|
|
78
|
+
| 0.6.0 | 0.7.0 |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `mw.Simulation(..., config=cfg, reference_frequency=f)` | `mw.Simulation(..., config=dataclasses.replace(cfg, reference_frequency=f))` |
|
|
81
|
+
| `mw.Simulation(..., config=cfg, material_cache=cache)` | `mw.Simulation(..., config=dataclasses.replace(cfg, material_cache=cache))` |
|
|
82
|
+
| `simulation.material_cache` | `simulation.config.material_cache` |
|
|
83
|
+
|
|
84
|
+
- **`FDTDConfig.cpml_config` (a dict) is replaced by `FDTDConfig.cpml`, a frozen `CPMLConfig` dataclass; the dict form is removed.** `Simulation.fdtd(..., cpml_config=...)` becomes `FDTDConfig(cpml=mw.fdtd.CPMLConfig(...))` (passed as `Simulation.fdtd(..., config=...)`, see the single configuration entry below). A misspelled key such as `{"kapa_max": 5.0}` was previously ignored; an unknown field is now a `TypeError` from the dataclass constructor, and passing a dict to `FDTDConfig(cpml=...)` raises `SetupError`. `memory_mode` is the new `str` Enum `CPMLMemoryMode` (`AUTO`, `DENSE`, `SLAB`); the exact strings `"auto"`, `"dense"` and `"slab"` are still accepted and parsed, while other spellings (`"Dense"`, `" slab "`), previously normalized, raise `SetupError`. Out-of-range values (`kappa_max < 1`, negative `alpha_max` or `dense_memory_limit_mib`, `reflection` outside (0, 1), nonpositive `grading_order`, non-finite numbers) raise `SetupError` at construction. `grading_order`, `alpha_max` and `reflection` default to `None` (the solver default: 3, 0 and 1e-6, or the shifted complex fixed-k profile), replacing the "was the key passed" rule; values and fields are unchanged. `witwin.maxwell.fdtd.DEFAULT_CPML_CONFIG` is removed (`mw.fdtd.CPMLConfig()` holds the defaults), and the prepared solver's `cpml_config` dict is replaced by `solver.cpml` (the configuration) and `solver.cpml_grading` (the resolved profile).
|
|
85
|
+
|
|
86
|
+
| 0.6.0 | 0.7.0 |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `Simulation.fdtd(..., cpml_config={"memory_mode": "slab"})` | `Simulation.fdtd(..., config=mw.FDTDConfig(cpml=mw.fdtd.CPMLConfig(memory_mode=mw.fdtd.CPMLMemoryMode.SLAB)))` (or `memory_mode="slab"`) |
|
|
89
|
+
| `cpml_config={"alpha_max": 0.0, "kappa_max": 5.0}` | `cpml=mw.fdtd.CPMLConfig(alpha_max=0.0, kappa_max=5.0)` |
|
|
90
|
+
| `FDTDConfig(cpml_config={...})`, `config.cpml_config` | `FDTDConfig(cpml=mw.fdtd.CPMLConfig(...))`, `config.cpml` |
|
|
91
|
+
| `witwin.maxwell.fdtd.DEFAULT_CPML_CONFIG` | `mw.fdtd.CPMLConfig()` |
|
|
92
|
+
| `prepared.solver.cpml_config["alpha_max"]` (resolved value) | `prepared.solver.cpml_grading.alpha_max` |
|
|
93
|
+
| `cpml_config={"memory_mode": "Dense"}` (normalized) | `memory_mode="dense"` or `CPMLMemoryMode.DENSE` |
|
|
94
|
+
|
|
95
|
+
- **`Simulation.fdtd(...)` and `Simulation.fdfd(...)` take one configuration entry.** The signatures are `Simulation.fdtd(scene, *, frequencies, excitations=None, config=None)` and `Simulation.fdfd(scene, *, frequencies, config=None)`; `config` is an `FDTDConfig` / `FDFDConfig` (`None` means the defaults). Every other keyword argument of the factories is removed and is now the config field of the same name, with the same meaning and default; passing one to the factory raises `TypeError` (unexpected keyword argument). `frequency=` is removed (one entry, no alias): `frequencies` is required and takes one frequency or a sequence. The old factories turned `run_time=None`, `spectral_sampler=None`, `cpml=None` and `solver=None` into the defaults; the config fields take a value, so omit the field instead (`FDTDConfig(run_time=None)` raises `TypeError`). Numerics and every default are unchanged. `Simulation.mom(...)` follows the same frequency rule: its signature is `Simulation.mom(scene, *, frequencies=None, config=None)`, `frequency=` is removed, and `frequencies` takes one frequency or a sequence (it stays omitted for an adaptive layered sweep, `LayeredSurfaceConfig.sweep`, which defines its own frequencies). `Simulation.electrostatic(...)` and `Simulation.capacitance(...)` are unchanged here. The rewrite of in-repo call sites is `scripts/dev/codemods/070_p4c_single_entry.py` (`apply`, then `check`); it also serves as the migration aid for downstream code.
|
|
96
|
+
|
|
97
|
+
| 0.6.0 | 0.7.0 |
|
|
98
|
+
|---|---|
|
|
99
|
+
| `Simulation.fdtd(scene, frequency=f, ...)`, `Simulation.fdfd(scene, frequency=f, ...)` | `Simulation.fdtd(scene, frequencies=f, ...)`, `Simulation.fdfd(scene, frequencies=f, ...)` |
|
|
100
|
+
| `Simulation.mom(scene, frequency=f, config=c)` | `Simulation.mom(scene, frequencies=f, config=c)` |
|
|
101
|
+
| `Simulation.fdtd(scene, frequencies=fs, run_time=t, spectral_sampler=s, full_field_dft=b, cuda_graph=g)` | `Simulation.fdtd(scene, frequencies=fs, config=mw.FDTDConfig(run_time=t, spectral_sampler=s, full_field_dft=b, cuda_graph=g))` |
|
|
102
|
+
| `Simulation.fdtd(..., absorber=, reference_frequency=, cpml=, enable_plot=, field_dtype=, shutoff=, shutoff_check_interval=, parallel=, initial_condition=, material_cache=)` | the `FDTDConfig` field of the same name |
|
|
103
|
+
| `Simulation.fdtd(..., excitations=e, run_time=t)` | `Simulation.fdtd(..., excitations=e, config=mw.FDTDConfig(run_time=t))` (`excitations` stays a factory keyword) |
|
|
104
|
+
| `sim = Simulation.fdtd(...)`; `sim.config = replace(sim.config, adjoint_checkpoint_stride=k)` | `Simulation.fdtd(..., config=mw.FDTDConfig(adjoint_checkpoint_stride=k))` (the field was not a factory keyword) |
|
|
105
|
+
| `Simulation.fdfd(..., solver=s, enable_plot=, verbose=, local_response=, observations=)` | `Simulation.fdfd(..., config=mw.FDFDConfig(solver=s, ...))` |
|
|
106
|
+
| `Simulation.fdtd(..., run_time=None)`, `spectral_sampler=None`, `cpml=None`, `Simulation.fdfd(..., solver=None)` | omit the field |
|
|
107
|
+
| `kwargs = dict(frequency=f, run_time=t)`; `Simulation.fdtd(scene, **kwargs)` | `Simulation.fdtd(scene, frequencies=f, config=mw.FDTDConfig(run_time=t))`; a forwarded mapping holds either config fields (`config=mw.FDTDConfig(**kwargs)`) or the entry keywords `frequencies`/`excitations`/`config` |
|
|
108
|
+
|
|
109
|
+
- **`GMRES` is renamed `FDFDSolverConfig`.** It configures every FDFD linear solve, not only GMRES: `solver_type` selects `"gmres"`, `"cg"`, `"bicgstab"`, `"tfqmr"`, `"idr"`, `"sqmr"` or `"direct"`. Fields, defaults and validation are unchanged; `FDFDConfig.solver` holds an `FDFDSolverConfig`, and a non-`FDFDSolverConfig` value raises `TypeError`. There is no `mw.GMRES` alias.
|
|
110
|
+
|
|
111
|
+
| 0.6.0 | 0.7.0 |
|
|
112
|
+
|---|---|
|
|
113
|
+
| `mw.GMRES(max_iter=200, solver_type="direct", ...)` | `mw.fdfd.FDFDSolverConfig(max_iter=200, solver_type="direct", ...)` |
|
|
114
|
+
| `from witwin.maxwell import GMRES` | `from witwin.maxwell import FDFDSolverConfig` |
|
|
115
|
+
| `Simulation.fdfd(scene, frequency=f, solver=mw.GMRES(...))` | `Simulation.fdfd(scene, frequencies=f, config=mw.FDFDConfig(solver=mw.fdfd.FDFDSolverConfig(...)))` |
|
|
116
|
+
|
|
117
|
+
- **`Simulation.electrostatic(...)` and `Simulation.capacitance(...)` return a `Simulation` and take one configuration entry.** The signatures are `Simulation.electrostatic(scene, *, config=None)` and `Simulation.capacitance(scene, *, config=None)`; every other keyword is a field of the new frozen dataclasses `ElectrostaticConfig(boundary, solver)` and `CapacitanceConfig(terminals, reference, boundary, solver, truncation_estimate)` (exported as `mw.electrostatic.ElectrostaticConfig`, `mw.electrostatic.CapacitanceConfig` and from `mw.electrostatic`; `dataclasses.replace` re-validates). The runner classes `ElectrostaticSimulation` and `CapacitanceSimulation` are removed. Static simulations have `method` `SimulationMethod.ELECTROSTATIC`/`CAPACITANCE` (new members), no frequencies (`frequencies == ()`, `frequency is None`), `Simulation.check()` reports them against the electrostatic/capacitance capability tables, construction/`prepare()`/`run()` raise the refused items, and a `SceneModule` scene is accepted. `prepare()` returns a `PreparedSimulation` whose `solver` is the compiled electrostatic block (previously `prepare()` returned that block). Results are bitwise unchanged. A `CapacitanceConfig` with a `truncation_estimate` and no Dirichlet face raises `ValueError` at construction (previously after the base extraction in `run()`). A non-`none` `Scene.boundary` face is refused at construction and reported by `check()` (previously admitted there and refused by the compile step in `prepare()`/`run()`). Migration: `python scripts/dev/codemods/070_p4d_es_config.py apply <paths>`.
|
|
118
|
+
|
|
119
|
+
| 0.6.0 | 0.7.0 |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `Simulation.electrostatic(scene, boundary=b, solver=s)` | `Simulation.electrostatic(scene, config=mw.electrostatic.ElectrostaticConfig(boundary=b, solver=s))` |
|
|
122
|
+
| `Simulation.capacitance(scene, terminals=t, reference=r, boundary=b, solver=s, truncation_estimate=e)` | `Simulation.capacitance(scene, config=mw.electrostatic.CapacitanceConfig(terminals=t, reference=r, boundary=b, solver=s, truncation_estimate=e))` |
|
|
123
|
+
| `boundary=None`, `solver=None` | omit the field (defaults: `ElectrostaticBoundarySpec.grounded_box()`, `ElectrostaticSolverConfig()`) |
|
|
124
|
+
| `Simulation.electrostatic(scene).prepare()` (a `CompiledElectrostatics`) | `Simulation.electrostatic(scene).prepare().solver` |
|
|
125
|
+
| `runner.boundary`, `runner.solver`, `runner.terminals`, `runner.reference`, `runner.truncation_estimate` | `simulation.config.boundary`, `.solver`, `.terminals`, `.reference`, `.truncation_estimate` |
|
|
126
|
+
| `isinstance(x, mw.electrostatic.ElectrostaticSimulation)` / `CapacitanceSimulation` | `isinstance(x, mw.Simulation) and x.method is mw.SimulationMethod.ELECTROSTATIC` / `CAPACITANCE` |
|
|
127
|
+
| `Simulation(scene=..., method="electrostatic", ...)` was not available | `mw.Simulation(scene=s, method="electrostatic", frequencies=(), config=mw.electrostatic.ElectrostaticConfig())` |
|
|
128
|
+
|
|
129
|
+
- **Invalid electrostatic configuration values raise `SetupError`** (a `ValueError`, so `except ValueError` keeps working), as `CPMLConfig` and the Enum options do: `ElectrostaticSolverConfig` (`tolerance <= 0`, `max_iterations <= 0`, a dtype other than float32/float64), `TruncationEstimate(padding_cells <= 0)`, `ElectrostaticBoundarySpec` (an unknown boundary kind, an override that is neither a kind nor a `(kind, value)` pair, a non-zero value on a non-Dirichlet face) and `CapacitanceConfig(truncation_estimate=...)` without a Dirichlet face. Messages are unchanged.
|
|
130
|
+
|
|
131
|
+
- **Wave-port, terminal wave-port and modal-port sweeps, and a direct `WavePort` excitation, refuse a configured `FDTDConfig.material_cache`.** These runners build one simulation per column and never applied the cache, so the setting was silently ignored. They now raise `UnsupportedFeatureError` (`method="fdtd"`) before running any column. Migration: leave `material_cache` unset for these runs; lumped-port `PortSweep` runs still use the cache.
|
|
132
|
+
|
|
133
|
+
- Homogeneous (non-layered) `Simulation.mom(...)` refuses, at construction and in one `NotImplementedError` listing every item, scene declarations it previously ignored: `Material(pmc=True)` bodies (previously solved as vacuum), non-default core `PhysicalMaterial` surface-model fields (`dispersion`, `conductor_model`, `thickness_m`, `layers`, `geometry_mode`, roughness, gain, scattering/xpd), `Scene.internal_absorbers`, `PlaneWave(injection=TFSF(...))` and `injection_axis`, and trainable `mu_r` or `MaxwellPlaneModes` tensors (previously solved with their gradients detached). Migration: remove the declaration, or use `Simulation.fdtd(...)` for grid features.
|
|
134
|
+
- `Simulation.electrostatic(...)`, `Simulation.capacitance(...)` and `Scene.compile_electrostatics()` refuse, in one listing `NotImplementedError`, declarations the static solve previously ignored: sources, monitors, ports, lumped elements, networks, circuits, thin wires, internal absorbers, `Scene.symmetry`, `Scene.coordinates`, `LossyMetalMedium`/`SurfaceImpedanceMedium`/`CopperFoil`/`Medium2D` structures (previously solved as vacuum), `sigma_e`/`sigma_e_tensor`, non-default core surface-model fields and trainable terminal geometry. Capacitance extraction also refuses floating (`charge=`) terminals (previously grounded at 0 V) and `Scene.charge_densities` (previously ignored). Migration: a conductor must be an `ElectrostaticTerminal`; solve floating conductors and free charge with `Simulation.electrostatic(...)`; use `ElectrostaticBoundarySpec` symmetry faces instead of `Scene.symmetry`.
|
|
135
|
+
- `Simulation.electrostatic(...)`, `Simulation.capacitance(...)` and `Scene.compile_electrostatics()` also refuse three material declarations the static solve previously ignored (capacitance was bit-identical with and without them): nonlinear media (`Material(kerr_chi3=...)` or `nonlinearity=` chi2/chi3/TPA, capability key `material.nonlinear`), `Material(breakdown=DielectricBreakdown(...))` (new key `material.breakdown`) and every `PerturbationMedium` (new key `material.perturbation`; the shift field and pole sensitivities were dropped and the base permittivity solved). `Simulation.fdfd(...)` and `Simulation.mom(...)` now refuse `breakdown=` at construction through the same `material.breakdown` row (previously a `NotImplementedError` at `prepare()`/`run()`); `PerturbationMedium` admission on FDTD, FDFD and MoM is unchanged. Migration: drop `kerr_chi3`/`nonlinearity`/`breakdown` for the static solve, declare a perturbed permittivity as `Structure` materials, and run breakdown scenes with `Simulation.fdtd(...)`.
|
|
136
|
+
- `ElectrostaticTerminal(potential=, charge=)` and `ElectrostaticBoundarySpec` values refuse trainable tensors (previously converted to floats with the gradient dropped).
|
|
137
|
+
- **Scene constructors refuse trainable tensors for values they store as Python floats.** These values were previously detached without a warning, so their gradients were silently lost. A tensor with `requires_grad=True` (a leaf or any value derived from one) now raises `NotImplementedError` naming the field. Fixed inputs (Python numbers or tensors without grad) are stored exactly as before.
|
|
138
|
+
|
|
139
|
+
| Constructor | Refused trainable fields |
|
|
140
|
+
|---|---|
|
|
141
|
+
| `Material` | `kerr_chi3` |
|
|
142
|
+
| `NonlinearSusceptibility` | `chi2`, `chi3` |
|
|
143
|
+
| `TwoPhotonAbsorption` | `beta`, `n0` |
|
|
144
|
+
| `DiagonalTensor3` | `xx`, `yy`, `zz` |
|
|
145
|
+
| `Tensor3x3` | every entry of `rows` |
|
|
146
|
+
| `Medium2D` | `sigma_s` |
|
|
147
|
+
| `WireConductor.finite` | `conductivity`, `permeability` |
|
|
148
|
+
| `MaterialRegion` | `bounds`, `eps_bounds`, `mu_bounds`, `filter_radius`, `projection_beta` |
|
|
149
|
+
|
|
150
|
+
Migration: pass a fixed value (`value.detach()` or a Python number). The native chi2/chi3/TPA coefficient pullbacks are internal kernels; trainable public nonlinear coefficients are not supported in this release.
|
|
151
|
+
- **`Structure.phase_screen` and `uv`/`face_uv` are refused by every Maxwell solver.** `Simulation.fdtd/fdfd/mom(...)` (at construction and again at `prepare()`/`run()`), `Simulation.electrostatic(...)` and `Simulation.capacitance(...)` raise `NotImplementedError` for a structure that carries an optical phase screen or UV assignment. Previously these were accepted and the bare structure was solved. Migration: set `phase_screen=None` and `uv=face_uv=None` on Maxwell structures.
|
|
152
|
+
- **`MaterialRegion(symmetry=...)` raises `NotImplementedError` for any value other than `None`.** The field was accepted for any string and never consumed. Migration: impose design symmetry on the density with `witwin.maxwell.invdes.symmetrize(...)` or `DensityParameterization`, and leave `symmetry=None`.
|
|
153
|
+
- **FDFD refuses scene features it cannot represent, at `Simulation.fdfd(...)` construction.** One `NotImplementedError` lists every unsupported item with its alternative; the check runs again in `prepare()` and `run()` after a scene change. Migration: use `Simulation.fdtd(...)` for these features, or remove them from the FDFD scene.
|
|
154
|
+
|
|
155
|
+
| Scene feature | 0.6.0 FDFD behavior | Now |
|
|
156
|
+
|---|---|---|
|
|
157
|
+
| `LossyMetalMedium`, `SurfaceImpedanceMedium`, `CopperFoil` | solved as vacuum | refused |
|
|
158
|
+
| `Material(modulation=ModulationSpec(...))` | solved with the static permittivity | refused |
|
|
159
|
+
| `Scene.lumped_elements` | dropped | refused |
|
|
160
|
+
| `LumpedPort`/`TerminalPort`/`CoaxialLumpedPort` with `termination`, wire-bound ports | load or wire dropped | refused |
|
|
161
|
+
| `ModePort`, `WavePort`, `TerminalWavePort` | mode source and monitor dropped | refused |
|
|
162
|
+
| `InternalAbsorber` | dropped | refused |
|
|
163
|
+
| `SurfaceMesh` structures (PEC traces, conformal sheets) | dropped | refused |
|
|
164
|
+
| `SubpixelSpec(pec="conformal")` | staircased | refused |
|
|
165
|
+
| `CW(frequency=f0)` source solved at another frequency (relative tolerance 1e-12) | `f0` ignored | refused; set `CW.frequency` to the solve frequency, or `source_time=None` to follow every frequency of a sweep |
|
|
166
|
+
| `GyromagneticFerrite`, nonlinear and full `Tensor3x3` media | `NotImplementedError` at `prepare()` | `NotImplementedError` at construction |
|
|
167
|
+
| boundary faces other than `none`/`pml`/`pec`, `Scene(symmetry=...)` | `ValueError` at `prepare()` | `NotImplementedError` at construction |
|
|
168
|
+
| scene monitors other than `PermittivityMonitor`/`MediumMonitor` | `NotImplementedError` at construction | same, now listed together with the other items |
|
|
169
|
+
|
|
170
|
+
Unterminated lumped probe ports stay admitted for `mw.rf.port_voltage(...)`/`mw.rf.port_phasors(...)` on FDFD fields. Internal callers of the FDFD source compiler also refuse a CW frequency that differs from the solver frequency (`ValueError`), for example after `FDFD.set_frequency(...)`.
|
|
171
|
+
- **Trainable FDFD runs go through the gradient bridge on every path, or refuse.** Multi-frequency `Simulation.fdfd(...).run()` and `prepare().run()` (single- and multi-frequency) never called the adjoint bridge for trainable scenes: they failed with `RuntimeError: Can't get __cuda_array_interface__ on Variable that requires grad` when the trainable input reached the permittivity, and returned detached fields (`requires_grad=False`) when it did not (for example a trainable `sigma_e` of 0). They now run one adjoint bridge per frequency and stack the frequencies, so `loss.backward()` reaches the inputs; forward fields equal the single-frequency bridge path. A grad-carrying scene tensor outside the trainable census (for example `MaterialRegion` geometry) skipped the bridge on every path and failed the same way; it is now differentiated. Trainable inputs the FDFD adjoint cannot differentiate now raise `NotImplementedError` at `prepare()`/`run()`, before any CUDA work, naming each input by attribute path or SceneModule parameter name, instead of receiving `None` or a zero gradient: inputs that do not reach the permittivity (PEC/PMC occupancy, disabled structures, unused SceneModule parameters) and inputs that change the permeability. The Medium2D/anisotropic/dispersive adjoint refusal moves from the autograd forward to the same admission. Migration: give these inputs fixed values (`requires_grad=False` or `.detach()`), or run under `torch.no_grad()` for a forward-only solve.
|
|
172
|
+
- **FDTD refuses trainable inputs it cannot differentiate, instead of leaving their gradient at `None` or running forward-only.** This covers single-device runs, `Simulation.batch(...)`, `run_many(...)` and multi-GPU (`parallel=`) runs. Every refusal is an `UnsupportedFeatureError` (a `NotImplementedError`) with `method="fdtd"`; `.items` names each input by attribute path.
|
|
173
|
+
|
|
174
|
+
| Trainable input | 0.6.0 FDTD behavior | Now |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| a tensor no gradient channel reads, e.g. `Material(mu_r=<tensor>)` or `ModulationSpec(amplitude=<tensor>)` | forward-only run, outputs detached (or, next to another trainable input, gradient `None`) | refused at `Simulation.fdtd(...)` and again at `prepare()`/`run()` (`feature="gradient.unclaimed_tensor"`) |
|
|
177
|
+
| PEC or PMC geometry, e.g. a trainable PEC position next to a trainable dielectric | PEC: `.grad` stays `None`; PMC: refused | refused before the run (`feature="gradient.material_channel"`) |
|
|
178
|
+
| trainable geometry in a scene whose permeability or magnetic conductivity differs from the background anywhere | permeability and magnetic-loss part of the gradient dropped | refused before the run (`feature="gradient.material_channel"`) |
|
|
179
|
+
| `MaterialRegion` density or geometry with `mu_bounds` contrast | permeability part dropped (single-device and multi-GPU; Batch already refused) | refused (`feature="gradient.material_channel"`) |
|
|
180
|
+
| a declared tensor that reaches no gradient channel, e.g. on a disabled structure | `.grad` stays `None` | refused before the run (`feature="gradient.unclaimed_tensor"`) |
|
|
181
|
+
|
|
182
|
+
The checks are structural: a moving boundary in a scene with a magnetic material is refused even where the two never touch. Under `torch.no_grad()` no gradient is requested, so these scenes run forward-only as before; a `mass_density` tensor stays a post-processing input. `FieldTimeMonitor` and `FluxTimeMonitor` traces of a differentiable run (single-device and multi-GPU) now raise during `backward()` when used in an objective, like surface and auxiliary time traces, instead of contributing a zero gradient; their values are unchanged. Migration: give the listed inputs fixed values (`requires_grad=False` or `.detach()`).
|
|
183
|
+
- `Simulation.fdtd(...)` with `Scene.symmetry` now refuses, when the Simulation is built:
|
|
184
|
+
- projection monitors (`AngleProjectionMonitor`, `CartesianProjectionMonitor`, `KSpaceProjectionMonitor`): the folded domain holds only part of the Huygens surface and image currents are not expanded (a box with a face on the image plane previously failed only at `Result.monitor(...)`);
|
|
185
|
+
- a `DiffractionMonitor` whose tangential axis carries a symmetry plane: its periods came from the folded domain;
|
|
186
|
+
- a `ClosedSurfaceMonitor` (and closed-surface postprocessing built on it, such as `mw.antenna.antenna(result, surface=...)`) whose surface touches, crosses or lies within half a cell of an image plane, and every closed surface under symmetry on `GridSpec.auto`. A box around an image-plane dipole previously reported 0.296 of the full-domain power instead of 0.5.
|
|
187
|
+
|
|
188
|
+
These results were silently wrong. Migration: keep closed surfaces strictly inside the folded domain, or simulate the full domain without `Scene.symmetry` (for diffraction, without symmetry on the monitor's tangential axes). (Domain-spanning plane flux now reports the mirrored-domain power; see Fixed.)
|
|
189
|
+
|
|
190
|
+
- **FDFD results are physics-typed (`FieldData`, `FarFieldData`).** Values are unchanged (the same tensors, as views); only their container, shape and metadata change. Every FDFD value now keeps a leading `f` dimension, of length 1 for a single-frequency run, with the solve frequencies as its coordinate. Phasors carry `attrs["phasor_convention"] = "exp(-i omega t), peak"` and `attrs["normalization"] = "raw"`. `Result.E`, `Result.H` and `Result.field(...)` return the same `FieldData` (see the slim `Result` entry below; use `field(...).values` instead of `Result.tensor`).
|
|
191
|
+
|
|
192
|
+
| Access | 0.6.0 | 0.7.0 |
|
|
193
|
+
|---|---|---|
|
|
194
|
+
| `result.fields["EX"]` (also `"EY"`, `"EZ"`) | tensor `[x, y, z]` (single frequency) or `[f, x, y, z]` (sweep) | `FieldData`, dims `("f", "x", "y", "z")`, units `V/m`, coordinates on that component's Yee grid (`attrs["yee_location"]` `edge_x`/`edge_y`/`edge_z`); the components sit on different grids, so `fields` stays a mapping with one `FieldData` per component. Migration: `result.fields["EX"].values` (single frequency: `.isel(f=0).values`, or `result.E.x` as before) |
|
|
195
|
+
| `result.monitor(name)` for a `FieldProjection` in `FDFDConfig.observations` or `LocalResponseConfig.observations` | dict `{"value", "frequency" or "frequencies", "kind": "linear_projection"}`, `value` 0-d (single frequency) or `[f]` | `FieldData`, dims `("f",)`; units `V/m` (E point), `A/m` (H point), `V` (`FieldProjection.voltage`), `1` (weighted indices: the weights define the quantity); `attrs["projection"]` is `point`/`voltage`/`weighted` with `component`/`position` or `path`. Migration: `result.monitor(name).values` (single frequency: `.isel(f=0).values`) |
|
|
196
|
+
| `result.monitor(name)` for a `FarFieldProjection` | the same dict | `FarFieldData` over one direction (`FarFieldData.from_directions`, D=1), dims `("f", "direction")`, units `V` (`r*exp(-ikr)*E`); the unit vector is `attrs["ux"]`/`["uy"]`/`["uz"]` (no `attrs["direction"]`), `polarization` and `bounds` in `attrs`. Migration: `.isel(direction=0).values` for the 0.6 shape |
|
|
197
|
+
| `result.monitor(name, frequency=...)` / `freq_index=...` / `result.at(...).monitor(name)` | the dict with `value` sliced to that frequency | the typed data at that frequency, `f` dropped (0-d `.values`); a single-frequency run is selected the same way |
|
|
198
|
+
| `result.monitors` | name to dict | name to the typed data |
|
|
199
|
+
| `Result.save(...)` / `Result.load(...)` of FDFD observations | the dict, pickled | the typed data (values, dims, coordinates, units, attrs), restored as the same type; 0.6 (schema 2) snapshots are refused (see snapshot schema 3 below) |
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
- **FDTD monitors and volume fields are physics-typed.** `Result.monitor(name)` and `Result.monitors` return `FieldData`, `FluxData`, `ModeAmplitudeData` or `TensorData` instead of the solver's payload dict; values are the same tensors (stacked along `component` where components share sample points), so numbers and gradients are unchanged. Frequency-domain data keep a leading `f` dimension, of length 1 for a single-frequency monitor, unless `frequency=`/`freq_index=` (or `Result.at(...)`) selects one, which drops it, as for FDFD; time traces have a `t` dimension. Spectral data carry `attrs["phasor_convention"] = "exp(-i omega t), peak"` and `attrs["normalization"]` (`"raw"`, or `"per_unit_source_spectrum"` with `SpectralSampler(normalize_source=True)`). Components on different Yee grids come back as a dict of per-component `FieldData` (as FDFD `Result.fields`). `Result.raw_monitor(name)` still returns the payload dict, without the single-component `"data"` and `"field"` aliases. `FieldData` selections recompute `units` from `attrs["component_units"]`, and selecting one component names it in `attrs["component"]`. Component and mode-direction labels are the plain strings `"Ex"` ... `"Hz"` and `"+"`/`"-"`, the values of `mw.monitors.FieldComponent` and `mw.monitors.Direction`, so those Enums select them too. Migrate with `python scripts/dev/codemods/070_p6b_typed_monitors.py apply <paths>`.
|
|
203
|
+
|
|
204
|
+
| Access | 0.6.0 | 0.7.0 |
|
|
205
|
+
|---|---|---|
|
|
206
|
+
| `result.monitor(name)` for a `PointMonitor` | dict: `components`, one key per component, `"data"` (single component), `frequencies`, `field_indices`, ... | `FieldData`, dims `("component", "f")`, units `V/m`, `A/m` or `mixed` (`attrs["component_units"]`), `attrs["position"]`, `attrs["sample_indices"]`. Migration: `["Ez"]`, `["data"]`, `["components"]["Ez"]` -> `.sel(component="Ez").values`; one frequency without the `f` axis: `result.monitor(name, freq_index=0)` |
|
|
207
|
+
| `result.monitor(name)` for a `PlaneMonitor` / `FinitePlaneMonitor` | dict with native `components[C]["data"]` and, for several components, cell-centred top-level `C` keys | `FieldData`, dims `("component", "f", a, b)` over the two plane axes: one component on its native Yee samples (`attrs["yee_location"]` `edge_*`/`face_*`), several on the cell-centred (`cell_center`) or `sample_spacing` (`collocated`) grid the monitor aligns them on; when an alignment does not cover a component (the plane-normal H), a dict of per-component native `FieldData` |
|
|
208
|
+
| `result.monitor(name)` with `compute_flux=True`, `FluxMonitor`, `IncidentPowerDensityMonitor`, `ClosedSurfaceMonitor` | dict with `flux`/`power` and the plane fields or `faces` | `FluxData`, dims `("f",)`, units `W`. Migration: `["flux"]` -> `.values`; the fields, faces and quadrature metadata are in `result.raw_monitor(name)` |
|
|
209
|
+
| `result.monitor(name)` for a `ModeMonitor` | dict of the overlap at the first monitor frequency (`amplitude_forward`, `power_fraction_forward`, `effective_index`, ...); several frequencies needed a selection | `ModeAmplitudeData`, dims `("mode", "propagation", "f")` with `propagation` `("+", "-")`, every monitor frequency evaluated; `attrs["power"]` (W) and `attrs["power_fraction"]` follow the values' shape and selections; `mode_power`, `total_power`, `effective_index`, `beta` per frequency. Migration: `["amplitude_forward"]` -> `.isel(mode=0).sel(propagation="+").values`, `["power_fraction_forward"]` -> `.isel(mode=0).sel(propagation="+").attrs["power_fraction"]` |
|
|
210
|
+
| `result.monitor(name)` for a `GaussianOverlapMonitor` / `AstigmaticGaussianOverlapMonitor` | dict of `[f]` amplitudes, powers and fractions | `ModeAmplitudeData` as above, units `sqrt(W)` |
|
|
211
|
+
| `result.monitor(name)` for a `DipoleEmissionMonitor` | dict with `power_delivered`, `current_spectrum`, `purcell_factor: None` | `FluxData` of the delivered power, `attrs["current_spectrum"]`; `postprocess.purcell_factor` takes the `Result` or this `FluxData` |
|
|
212
|
+
| `result.monitor(name)` for a `DiffractionMonitor` | dict with an `orders` list of records | `FluxData`, dims `("order", "f")`: power per Floquet order; `m`, `n`, `kx`, `ky`, `kz`, `theta`, `phi`, `propagating`, `efficiency`, `amplitude_E`, `amplitude_H` are per-order attrs selected with `order`; totals in `attrs` |
|
|
213
|
+
| `result.monitor(name)` for a `FieldTimeMonitor` / `AuxFieldTimeMonitor` | dict with `t`, `components`, and `"data"`/`"field"` for one component | `FieldData`, dims `("component", "t", ...)`, `attrs["field_time_offsets_steps"]`; plane or volume traces of several components: a dict of per-component `FieldData`. Migration: `["field"]` -> `.sel(component="Ez").values`, `["t"]` -> `.coords["t"]`; `postprocess.find_resonances` takes this data |
|
|
214
|
+
| `result.monitor(name)` for a `FluxTimeMonitor` | dict with `t`, `flux` | `FluxData`, dims `("t",)` |
|
|
215
|
+
| `result.monitor(name)` for a `SurfaceFieldTimeMonitor` | dict with `faces` | `{face: {component: FieldData}}`, dims `("t", a, b)` |
|
|
216
|
+
| `result.monitor(name)` for a `PermittivityMonitor` / `MediumMonitor` | dict with `eps_x`, ..., `eps`, `mu`, `sigma_e`, `x`, `y`, `z` | `{"eps": TensorData, ...}` (also `"mu"`, `"sigma_e"`), dims `("component", "f", "x", "y", "z")` with component `("x", "y", "z")`; the 0.6 averages are not repeated |
|
|
217
|
+
| `result.monitors` | name to the stored payload dict | name to the typed data |
|
|
218
|
+
| `result.raw_monitor(name)` | payload with `"data"` (and, for field-time traces, `"field"`) aliasing the single component | the same payload without the aliases: read `[component]` or `["components"][component]` |
|
|
219
|
+
| `result.monitor(name, resolve_modal=False)`, `result.at(..., resolve_modal=...)` | the unresolved plane payload | removed: use `result.raw_monitor(name)` |
|
|
220
|
+
| `result.fields["EX"]` of an FDTD run with the volume DFT | tensor `[x, y, z]` (one frequency) or `[f, x, y, z]` | `FieldData`, dims `("f", "x", "y", "z")` on that component's Yee grid. Migration: `.values` (one frequency: `.isel(f=0).values`) |
|
|
221
|
+
| `result.fields` of a single-frequency FDTD run without the volume DFT (`full_field_dft=False`, the default) | the real E fields after the last step, labelled as fields | raises `ValueError`; the last-step fields are `result.time_snapshot` (`{"EX", "EY", "EZ"}` -> `FieldData`, dims `("x", "y", "z")`, `attrs["kind"] = "time_snapshot"`, `attrs["step"]`, `attrs["time"]`). Migration: `result.time_snapshot["EX"].values`. `result.E`/`result.H`/`result.field(...)` raise the same way (slim `Result` entry below) |
|
|
222
|
+
|
|
223
|
+
- **The MoM-only `Result` members move to `mw.mom` functions that take the `Result`.** Each function returns exactly what the member returned (the same objects; no value changes). `Result.query_fields` stays on `Result`, and layered MoM keeps `Result.network` (`.s_parameters` is `SParameterData`). The members are removed from `Result` (api070/p6f); no alias remains.
|
|
224
|
+
|
|
225
|
+
| 0.6.0 | 0.7.0 |
|
|
226
|
+
|---|---|
|
|
227
|
+
| `result.surface_currents` | `mw.mom.surface_currents(result)` |
|
|
228
|
+
| `result.harmonic_state` | `mw.mom.harmonic_state(result)` |
|
|
229
|
+
| `result.harmonic_power_balance(control_surface, ...)` | `mw.mom.harmonic_power_balance(result, control_surface, ...)` |
|
|
230
|
+
| `result.refine_harmonic_power(control_surface, ...)` | `mw.mom.refine_harmonic_power(result, control_surface, ...)` |
|
|
231
|
+
| `result.query_dc(points, region_id=...)` | `mw.mom.query_dc(result, points, region_id=...)` |
|
|
232
|
+
| `result.query_dc_magnetic(points, region_id=...)` | `mw.mom.query_dc_magnetic(result, points, region_id=...)` |
|
|
233
|
+
| `result.query_dc_dual(points, region_id=...)` | `mw.mom.query_dc_dual(result, points, region_id=...)` |
|
|
234
|
+
| `result.far_field(directions, harmonic=None)` | `mw.mom.far_field(result, directions, harmonic=None)` |
|
|
235
|
+
| `result.rayleigh_orders(orders, side=..., plane_offset=...)` | `mw.mom.rayleigh_orders(result, orders, side=..., plane_offset=...)` |
|
|
236
|
+
| `result.cylindrical_orders(orders, directions)` | `mw.mom.cylindrical_orders(result, orders, directions)` |
|
|
237
|
+
| `result.bloch_spectrum(orders)` | `mw.mom.bloch_spectrum(result, orders)` |
|
|
238
|
+
|
|
239
|
+
- **MoM PointMonitor and far-field results are physics-typed (`FieldData`, `FarFieldData`).** Linear (lifted, multi-body, periodic, tensor), open-sheet and coupled harmonic `Simulation.mom(...)` runs return each `PointMonitor` as one `FieldData` with dims `("component", "f")`. Values are the same queried samples (bitwise equal); only their container and metadata change. The `component` labels are the monitor's `fields` in declaration order (`"Ex"` ... `"Hz"`). `f` has length 1 at the solve frequency for a linear run and lists the retained positive harmonics `n*f0` for a harmonic run. Phasors carry `attrs["phasor_convention"] = "exp(-i omega t), peak"` and `attrs["normalization"] = "raw"`. `units` is `V/m` for E-only and `A/m` for H-only monitors, and `"mixed"` when a monitor records both; `attrs["component_units"]` always maps each component to its unit. `Result.far_field(directions)` returns `(F_E, F_H)` as two `FarFieldData` with dims `("f", "direction", "component")`; their values are views of the same amplitudes. `Result.query_fields`, `Result.query_dc*`, `Result.surface_currents` (including `surface_currents.far_field`), the periodic order observables and the power-balance records are unchanged. Layered MoM is unchanged: `Result.network.s_parameters` already returns `SParameterData` (dims `("f", "out_port", "in_port")`) over `Result.network.s`, and `Result.network.s` stays a tensor.
|
|
240
|
+
|
|
241
|
+
| Access | 0.6.0 | 0.7.0 |
|
|
242
|
+
|---|---|---|
|
|
243
|
+
| `result.monitor(name)["Ex"]`, `result.monitors[name]["Ex"]`, `result.monitor(name)["components"]["Ex"]` (linear and open-sheet) | 0-d complex tensor | `result.monitor(name).sel(component="Ex").values` is `[f]` with `f` of length 1; use `.values[0]`, or `result.monitor(name, freq_index=0).sel(component="Ex").values` for a 0-d tensor |
|
|
244
|
+
| `result.monitor(name)["components"]["Ex"]` (harmonic) | `[harmonic]` tensor | `result.monitor(name).sel(component="Ex").values` (`[f]` over the positive harmonics); one harmonic: `result.monitor(name, frequency=n*f0).sel(component="Ex").values` |
|
|
245
|
+
| `result.monitor(name)["fields"]` | tuple of component names | `result.monitor(name).coords["component"]` |
|
|
246
|
+
| `result.monitor(name)["frequency"]` / `["frequencies"]` | float / tuple (harmonic runs: positive harmonics) | `result.monitor(name).coords["f"]` (float64 tensor) |
|
|
247
|
+
| `result.monitor(name)["position"]`, `["region_id"]`, `["structure_index"]`, `["structure_name"]` (linear only), `["field_kind"]`, `["sampling"]`, `["distance_to_surface_m"]`, `["physical_qualification"]` (harmonic only) | dict keys | the same names in `result.monitor(name).attrs` |
|
|
248
|
+
| `result.monitor(name)["dc"]` (harmonic: DC `components`, `potential_V`, `magnetic_available`) | dict key | `result.monitor(name).attrs["dc"]`, with the same contents |
|
|
249
|
+
| `result.monitor(name)["phasor_convention"]` | `"exp(-i omega t)"` (harmonic: `"exp(-i*n*omega*t); positive_peak"`) | `attrs["phasor_convention"] = "exp(-i omega t), peak"`, where omega is `2*pi*f` for each `f` coordinate |
|
|
250
|
+
| `result.monitor(name)["kind"]`, `["coordinate_units"]` | `"point"`, `"m"` | removed: the type is `FieldData`, and positions are in metres |
|
|
251
|
+
| `result.monitor(name, freq_index=i)` on a harmonic run | dict, not sliced | `i` indexes the monitor's own `f` axis of positive harmonics (`Result.frequencies` starts with DC); select by `frequency=n*f0` |
|
|
252
|
+
| `Result.save(...)` / `Result.load(...)` of MoM PointMonitors | the dict, pickled | the `FieldData`, restored as the same type |
|
|
253
|
+
| `e, h = result.far_field(directions)` (linear and open-sheet; `directions` `[D, 3]` unit vectors) | two complex tensors `[D, 3]`: `F_E` [V] and `F_H` [A] with `E, H ~ exp(ikr) F / r` | two `FarFieldData`, dims `("f", "direction", "component")`, `f` of length 1 at the solve frequency, components `Ex, Ey, Ez` (units `V`) and `Hx, Hy, Hz` (units `A`); `attrs["quantity"]` is `r*exp(-ikr)*E` / `r*exp(-ikr)*H`, `attrs["phase_origin"] = (0, 0, 0)`, and the unit directions are `attrs["ux"]`, `["uy"]`, `["uz"]` (`direction` is the index `0..D-1`). Migration: `e, h = (data.values[0] for data in result.far_field(directions))`, or `result.far_field(directions)[0].values[0]` for `F_E` alone |
|
|
254
|
+
| `e, h = result.far_field(directions, harmonic=n)` (harmonic) | the same tensors for harmonic `n` | the same `FarFieldData`, with `f` = `n*f0` |
|
|
255
|
+
| `result.far_field(directions)[0][d]` (one direction) | `[3]` tensor | `result.far_field(directions)[0].isel(f=0, direction=d).values`; `attrs["ux"]` etc. are selected with it |
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
- **`Result` is slimmed to its core; domain accessors are namespace functions that take the Result** (api070/p6e). `Result` keeps `method`, `scene`, `prepared_scene`, `frequencies`, `metadata`, `stats()`, `fields`, `E`, `H`, `time_snapshot`, `field(...)`, `monitor(...)`, `monitors`, `port(...)`, `ports`, `port_drive(...)`, `network`, `material(...)`, `materials`, `at(...)`, `save(...)`, `load(...)`, `from_fields(...)`, `plot`, `release_solver()`, `raw_monitor(...)` and `query_fields(...)`. The MoM members are `mw.mom` functions (entry above). `solver_stats` and `tensor` are removed (use `stats()` and `field(...).values`), and `raw_output` is private: the solver's raw output is not part of the public `Result` (api070/p6f). Numbers and gradients are unchanged: each function returns what the member returned. No alias remains on `Result`. Migration: `python scripts/dev/codemods/070_p6e_result_slim.py apply <paths>`, then `check`.
|
|
259
|
+
|
|
260
|
+
| 0.6.0 | 0.7.0 |
|
|
261
|
+
|---|---|
|
|
262
|
+
| `result.antenna(surface=..., driven_port=..., ...)` | `mw.antenna.antenna(result, surface=..., driven_port=..., ...)` |
|
|
263
|
+
| `result.array_basis(monitor=..., ...)` | `mw.antenna.array_basis(result, monitor=..., ...)` |
|
|
264
|
+
| `result.breakdown(name)`, `result.breakdown_names()` | `mw.breakdown.breakdown(result, name)`, `mw.breakdown.breakdown_names(result)` |
|
|
265
|
+
| `result.breakdown_data`, `result.breakdown_events` | `mw.breakdown.breakdown_data(result)`, `mw.breakdown.breakdown_events(result)` |
|
|
266
|
+
| `result.component_stress(name)`, `result.component_stress_names()` | `mw.esd.component_stress(result, name)`, `mw.esd.component_stress_names(result)` |
|
|
267
|
+
| `result.esd_waveform(name)`, `result.esd_waveform_names()` | `mw.esd.esd_waveform(result, name)`, `mw.esd.esd_waveform_names(result)` |
|
|
268
|
+
| `result.esd_generator(name)`, `result.esd_generator_names()` | `mw.esd.esd_generator(result, name)`, `mw.esd.esd_generator_names(result)` |
|
|
269
|
+
| `result.capacitance`, `result.electrostatic`, `result.electrostatic_prebias` | `mw.electrostatic.capacitance(result)`, `mw.electrostatic.electrostatic(result)`, `mw.electrostatic.electrostatic_prebias(result)` |
|
|
270
|
+
| `result.chart_fields` | `mw.coordinates.chart_fields(result)` |
|
|
271
|
+
| `result.sar(monitor, ...)`, `result.incident_power_density(monitor, ...)` | `mw.sar.sar(result, monitor, ...)`, `mw.sar.incident_power_density(result, monitor, ...)` |
|
|
272
|
+
| `result.circuit(name)`, `result.circuits` | `mw.circuits.circuit(result, name)`, `mw.circuits.circuits(result)` |
|
|
273
|
+
| `result.embedded_network(name)`, `result.embedded_networks` | `mw.rf.embedded_network(result, name)`, `mw.rf.embedded_networks(result)` |
|
|
274
|
+
| `result.conductor_losses`, `result.conductor_loss_columns` | `mw.rf.conductor_losses(result)`, `mw.rf.conductor_loss_columns(result)` |
|
|
275
|
+
| `result.power_loss(name)` | `result.monitor(name)` (the `PowerLossData` of a `PowerLossMonitor`); with explicit density inputs (`electric_fields=`, `volume_channels=`, ...) `mw.postprocess.power_loss(result, name, ...)` |
|
|
276
|
+
| `result.save_sharded(directory)`, `Result.load_sharded(directory, scene=...)` | `mw.execution.save_sharded(result, directory)`, `mw.execution.load_sharded(directory, scene=...)` |
|
|
277
|
+
| `result.is_sharded`, `result.sharded_manifest`, `result.shard_paths` | `mw.execution.is_sharded(result)`, `mw.execution.sharded_manifest(result)`, `mw.execution.shard_paths(result)` |
|
|
278
|
+
| `result.solver_stats` | `result.stats()` (the solver statistics plus `method`, `frequency`, `frequencies` and the payload counts; a solver statistic named `method`, such as the MoM linear solver's, is `stats()["solver_method"]`, since `stats()["method"]` is the Result's method) |
|
|
279
|
+
| `result.select(...)` | `result.at(...)` |
|
|
280
|
+
| `result.frequency` | `result.frequencies[0]` (the first solved frequency; `result.frequencies` is the full axis, and `result.at(frequency=...)` / `freq_index=` select one). `stats()["frequency"]` and the snapshot `"frequency"` key are unchanged (api070/drop-result-frequency) |
|
|
281
|
+
| `result.tensor(name, ...)` | `result.field(name, ...).values` |
|
|
282
|
+
| `result.raw_output` | removed from the public `Result`. FDFD `prepared.solve_modes(...)`: `result.monitor("modes")["profiles"]` (with `"coordinates"`, `"axis"`, `"position"`, `"normalization"`, previously in `raw_output`); FDFD local-response projections: `result.monitor(name)` of each observation; other raw solver payloads have no public replacement |
|
|
283
|
+
| `result.compare_harmonic_cutoff(previous, ...)` | removed (no caller) |
|
|
284
|
+
| `result.field("Ex")`, `result.E.x`, `result.at(...).H.y` | `FieldData` from `result.fields` (dims `("f", "x", "y", "z")`; a frequency selection drops `f`), instead of the bare tensor: `.values` (`.isel(f=0).values` for the 0.6 shape of a single-frequency run). `result.field("E")` and `result.E.as_dict()` return dicts of `FieldData`. `expand_symmetry=True` mirrors values and coordinates. A run without phasors (single-frequency FDTD with `full_field_dft=False`) raises: its last-step fields are `result.time_snapshot["EX"].values` |
|
|
285
|
+
- **`ModeAmplitudeData`'s propagation dimension is `propagation`, not `direction`.** Labels stay `"+"`/`"-"` (`mw.monitors.Direction`). `direction` now always means unit vectors (`FarFieldData`). Migration: `.sel(direction="+")` -> `.sel(propagation="+")` (the p6e codemod rewrites it).
|
|
286
|
+
- **`Result.save` writes snapshot schema 3 with typed payloads; older snapshots are refused.** Every `TensorData` (any subclass, at any nesting depth of a monitor payload) is stored as its class path and constructor fields; the vestigial `"format_version"` key is gone. `Result.load` and `mw.execution.load_sharded` raise `SchemaError` (a `ValueError`) for any other `schema_version`, including the 0.6 schema 2: there is no reader. Re-run and save again.
|
|
287
|
+
- **Scene-feature refusals come from one capability registry and raise one `UnsupportedFeatureError` listing every item.** `Simulation.fdtd/fdfd/mom(...)`, `Simulation.electrostatic(...)`, `Simulation.capacitance(...)` and `Scene.compile_electrostatics()` collect every refused scene feature at construction (and again at `prepare()`/`run()` after a scene change) and raise `UnsupportedFeatureError` (still a `NotImplementedError`) with `.feature` (the first item's registry key), `.method`, `.alternative` (single-item refusals) and `.items` (one `Unsupported(key, method, owner, reason, alternative)` per refused feature). Previously the FDFD, homogeneous MoM and electrostatic checks each raised their own `NotImplementedError`, and the optical-assignment, `PlanarPEC`, `LayerStack`, homogeneous-background, in-simulation-monitor and `Scene.symmetry` monitor checks raised on the first hit, so a scene with several refused features reported one at a time. Each item keeps its previous text; the error message now starts `Simulation.<method>(...) cannot represent N scene feature(s):` followed by one `- <owner>: <reason>; <alternative>` line per item.
|
|
288
|
+
- **FDTD and FDFD refuse core `PhysicalMaterial` surface-model fields.** A `witwin.core.PhysicalMaterial` with a non-default `thickness_m`, `layers`, `geometry_mode`, `roughness_front`, `roughness_back`, `dispersion`, `gain`, `scattering_coefficient`, `xpd_coefficient` or `conductor_model` is refused under the `material.core_surface_fields` key, as MoM and the electrostatic solves already did. Both grid solvers used to build the body from `eps_r`, `mu_r` and `sigma_e` alone, so `conductor_model="perfect"` was solved as a dielectric. Use a Maxwell material model (`Material(pec=True)`, `LossyMetalMedium`, `CopperFoil`, ...).
|
|
289
|
+
|
|
290
|
+
| Refusal | 0.6.0 | Now |
|
|
291
|
+
|---|---|---|
|
|
292
|
+
| Homogeneous MoM declarations | `NotImplementedError("Homogeneous MoM would ignore these scene declarations, so it refuses them: ...")` | `UnsupportedFeatureError("Simulation.mom(...) cannot represent N scene feature(s): ...")`; unnamed sources are labelled `Source #i` (was `source #i`) |
|
|
293
|
+
| Electrostatic and capacitance declarations | `NotImplementedError("... would ignore these scene declarations, so it refuses them: ...")` | `UnsupportedFeatureError("Simulation.electrostatic(...)` / `Simulation.capacitance(...) cannot represent N scene feature(s): ...")`; terminals are labelled `Terminal 'name'` (was `terminal 'name'`) |
|
|
294
|
+
| `ThinWire` in `Simulation.fdfd/mom(...)` | `ValueError` | `UnsupportedFeatureError` |
|
|
295
|
+
| A scene object of a type no method table declares (for example a user-defined monitor class) | admitted at construction, refused or ignored later | refused at construction as `<category>.<Type> is not declared for <method>`; subclasses of public types inherit their base type's row |
|
|
296
|
+
| `MoMConfig` with more than one of `layered`, `linear_coupled`, `harmonic_balance` | `prepare()` ran the first in that order and ignored the others | refused at construction |
|
|
297
|
+
| FDFD `GyromagneticFerrite`, nonlinear and full-tensor media on a disabled (`enabled=False`) structure | refused | admitted (a disabled structure is not compiled) |
|
|
298
|
+
|
|
299
|
+
Migration: keep `except NotImplementedError` handlers, or catch `mw.UnsupportedFeatureError` and read `.items`; match messages on the item text rather than the removed per-solver headers.
|
|
300
|
+
|
|
301
|
+
- Layered MoM (`Simulation.mom` with a `LayerStack` background) now refuses the declared inputs it previously ignored. Those with a capability key are rows of the `mom.layered` table and raise `UnsupportedFeatureError` at construction (`Simulation.check()` reports them); the layered compiler names every item again at `prepare()`, in one `NotImplementedError`, including the inputs without a key (`material_regions` and the `LumpedPort` `reference_plane`, `voltage_aperture` and `current_surface`):
|
|
302
|
+
- Scene `lumped_elements`, `material_regions`, `electrostatic_terminals`, `charge_densities`, `internal_absorbers`, `thin_wires`, `networks` and `circuits`, plus `sources` and `monitors` (already refused, now listed in the same error);
|
|
303
|
+
- `Scene.symmetry`, boundary face kinds other than `none` (periodic, PEC, PML, ...), and `Scene.coordinates`;
|
|
304
|
+
- ports other than `LumpedPort`, and `LumpedPort.termination`, `reference_plane`, `current_surface` and `wire_binding`. A fixed `termination` previously raised `ValueError`; it now joins the list. (`LumpedPort.voltage_aperture` is applied, see Added.)
|
|
305
|
+
|
|
306
|
+
Migration: remove the input or use the alternative the message names (for example `Result.network.terminate(port, impedance=load)` for a termination).
|
|
307
|
+
- `LumpedPort.current_surface` is optional. Layered MoM ports must omit it. FDTD field ports still require it and now raise `TypeError` when their port geometry is compiled, instead of at `LumpedPort` construction. Migration: drop `current_surface` from layered ports; FDTD scenes are unchanged.
|
|
308
|
+
- Trainable `Layer` and `HalfSpace` fields (`thickness`, `eps_r`, `sigma`, `mu_r`) raise `NotImplementedError` at construction; their gradients were previously dropped.
|
|
309
|
+
- A layered MoM scene with no port raises `ValueError` ("needs at least one LumpedPort") instead of `NotImplementedError`.
|
|
310
|
+
- `PreparedSimulation.run()` on layered MoM raises `ValueError` when the Scene's compiled inputs changed after `prepare()`; previously it returned results for the stale scene. Migration: call `Simulation.prepare()` again.
|
|
311
|
+
- A `requires_grad` tensor in `LossyMetalMedium.conductivity`, a `SurfaceRoughness` field or `PlanarPEC.physical_thickness` is refused with `UnsupportedFeatureError` (capability key `structure.trainable_conductor_loss`) by `Simulation.fdtd/fdfd/mom(...)` without a `LayerStack` background and by `Simulation.electrostatic/capacitance(...)`; previously the conductivity and roughness tensors were stored as detached floats. Layered MoM differentiates these fields. Migration: pass a float or a detached tensor.
|
|
312
|
+
|
|
313
|
+
- **The top level of `witwin.maxwell` keeps only the `Scene -> Simulation -> Result` core; every other public object moves to one domain namespace, with no alias at the old location.** 274 names leave the top level. The core that stays: the errors and warnings, `Scene`, `SceneModule`, `Domain`, `GridSpec`, `BoundarySpec`, `BoundaryKind`, `SubpixelSpec`, `MaterialRegion`, `Structure`, `Box`, `Sphere`, `Cylinder`, `Mesh`, `PolySlab`, `Material`, `DebyePole`, `DrudePole`, `LorentzPole`, `DiagonalTensor3`, `CW`, `GaussianPulse`, `PointDipole`, `PlaneWave`, `GaussianBeam`, `ModeSource`, `TFSF`, `UniformCurrentSource`, `PointMonitor`, `PlaneMonitor`, `FinitePlaneMonitor`, `FluxMonitor`, `ModeMonitor`, `ModePort`, `LumpedPort`, `AxisPath`, `Simulation`, `SimulationMethod`, `FDTDConfig`, `FDFDConfig`, `TimeConfig`, `capabilities`, `Result` and the typed result data (`FieldData`, `FluxData`, `ModeAmplitudeData`, `SParameterData`, `FarFieldData`). Namespaces load on first access (`import witwin.maxwell` no longer imports the FDTD solver, the postprocessing, electrostatic and execution packages up front); a namespace's `__all__` is its contract, and the modules that implement the objects (`witwin.maxwell.network`, `.lumped`, `.array`, ...) are internal. The 35 MoM configuration objects (`MoMConfig`, `HMatrixConfig`, ..., `Layer`, `LayerStack`, `HalfSpace`, `MaxwellPlaneModes`) move to `mw.mom`. Migration: from a 0.7.0 checkout, run `python scripts/dev/codemods/070_p5b_namespaces.py apply <your paths>` (after the p4c codemod `070_p4c_single_entry.py`), then `check`; it rewrites `mw.<name>`, `witwin.maxwell.<name>`, `from witwin.maxwell import <name>`, `getattr/hasattr(mw, "<name>")` and `"<name>" in mw.__all__`, and lists what it cannot rewrite (computed names, code inside strings).
|
|
314
|
+
|
|
315
|
+
| 0.6.0 | 0.7.0 |
|
|
316
|
+
|---|---|
|
|
317
|
+
| `mw.aggregate_scene_gradient_vjp`, `mw.AggregatedSceneGradient`, `mw.AntennaData`, `mw.ArrayBasisData`, `mw.BeamCodebook`, `mw.BeamData`, `mw.BeamWeights`, `mw.EmbeddedElementPatternData`, `mw.ensemble_scene_gradient_vjp`, `mw.Ludwig3`, `mw.MaxHoldComposite`, `mw.MIMOData`, `mw.MultipathEnvironment` | `mw.antenna.<name>` |
|
|
318
|
+
| `mw.BreakdownEvent`, `mw.BreakdownResultData`, `mw.DielectricBreakdown`, `mw.SmoothBreakdownRisk`, `mw.SmoothBreakdownRiskData` | `mw.breakdown.<name>` |
|
|
319
|
+
| `mw.Circuit`, `mw.CircuitData`, `mw.CircuitDevice`, `mw.CircuitNode`, `mw.CurrentControlledCurrentSource`, `mw.CurrentControlledVoltageSource`, `mw.CurrentSource`, `mw.Diode`, `mw.MNAConfig`, `mw.MutualInductor`, `mw.NonlinearSolveConfig`, `mw.parse_spice`, `mw.PiecewiseLinearIV`, `mw.PiecewiseLinearWaveform`, `mw.PolynomialIV`, `mw.PortBinding`, `mw.PulseWaveform`, `mw.SineWaveform`, `mw.TimedSwitch`, `mw.VoltageControlledCurrentSource`, `mw.VoltageControlledVoltageSource`, `mw.VoltageDependentCapacitor`, `mw.VoltageSource` | `mw.circuits.<name>` |
|
|
320
|
+
| `mw.BendCoordinates`, `mw.FieldFrame`, `mw.FramedFieldData` | `mw.coordinates.<name>` |
|
|
321
|
+
| `mw.CapacitanceData`, `mw.ChargeDensity`, `mw.ElectrostaticBoundarySpec`, `mw.ElectrostaticInitialCondition`, `mw.ElectrostaticResultData`, `mw.ElectrostaticSolverConfig`, `mw.ElectrostaticTerminal`, `mw.TruncationEstimate`, `mw.TruncationReport` | `mw.electrostatic.<name>` |
|
|
322
|
+
| `mw.BreakdownMonitor`, `mw.BreakdownStressData`, `mw.ComponentRating`, `mw.ComponentStressData`, `mw.ComponentStressMonitor`, `mw.ESDCurrentSource`, `mw.ESDDiagnostics`, `mw.ESDPortRecord`, `mw.ESDResampledWaveform`, `mw.ESDVoltageSource`, `mw.ESDWaveform`, `mw.MeasuredWaveform` | `mw.esd.<name>` |
|
|
323
|
+
| `mw.BatchExecution`, `mw.BatchItem`, `mw.BatchOutput`, `mw.BatchParameters`, `mw.BatchPlanReport`, `mw.BatchResult`, `mw.BatchResultIterator`, `mw.BatchSimulation`, `mw.BatchVariation`, `mw.DistributedFailure`, `mw.ExecutionRecord`, `mw.FailureKind`, `mw.MultiGPUExecution`, `mw.PreparedBatch`, `mw.ResultSequence`, `mw.run_many` | `mw.execution.<name>` |
|
|
324
|
+
| `mw.FarFieldProjection`, `mw.FDFDSolverConfig`, `mw.FieldProjection`, `mw.LocalDesignRegion`, `mw.LocalResponseConfig`, `mw.LumpedCurrentSource` | `mw.fdfd.<name>` |
|
|
325
|
+
| `mw.AbsorberKind`, `mw.CPMLConfig`, `mw.CPMLMemoryMode`, `mw.FDTDCoreFallbackWarning` (then removed, see the W7 row 16c entry), `mw.FDTDMaterialCache`, `mw.FDTDParallelConfig`, `mw.FDTDPassivityError`, `mw.FDTDResumeCheckpoint`, `mw.InternalAbsorber`, `mw.ModeABC`, `mw.MurABC`, `mw.SpectralSampler`, `mw.SpectralWindowKind` | `mw.fdtd.<name>` |
|
|
326
|
+
| `mw.ComplexPolySlab`, `mw.Cone`, `mw.Difference`, `mw.Ellipsoid`, `mw.HollowBox`, `mw.Intersection`, `mw.PlanarPEC`, `mw.Prism`, `mw.Pyramid`, `mw.SurfaceMesh`, `mw.Torus`, `mw.Union` | `mw.geometry.<name>` |
|
|
327
|
+
| `mw.CornerFinderSpec`, `mw.GridRefinement`, `mw.LayerRefinementSpec`, `mw.MeshOverrideStructure` | `mw.grid.<name>` |
|
|
328
|
+
| `mw.ComplexTensor3x3`, `mw.CopperFoil`, `mw.CustomDebyePole`, `mw.CustomDrudePole`, `mw.CustomLorentzPole`, `mw.Graphene`, `mw.GroisseRoughness`, `mw.GyromagneticFerrite`, `mw.HammerstadRoughness`, `mw.HurayRoughness`, `mw.LossyMetalMedium`, `mw.Medium2D`, `mw.ModulationSpec`, `mw.NonlinearSusceptibility`, `mw.PerturbationMedium`, `mw.RationalSurfaceImpedance`, `mw.SurfaceImpedanceMedium`, `mw.SurfaceImpedanceModel`, `mw.SurfaceRoughness`, `mw.Tensor3x3`, `mw.TensorNonlinearSusceptibility`, `mw.TwoPhotonAbsorption` | `mw.media.<name>` |
|
|
329
|
+
| `mw.DispersionFit`, `mw.DispersionFitReport`, `mw.fit_dispersion`, `mw.fit_dispersion_nk`, `mw.load_dispersion_csv`, `mw.permittivity_from_nk` | `mw.media.fit.<name>` |
|
|
330
|
+
| `mw.library_material`, `mw.MATERIAL_LIBRARY`, `mw.MaterialLibraryEntry` | `mw.media.library.<name>` |
|
|
331
|
+
| `mw.AdaptiveSweep`, `mw.AdaptiveSweepResult`, `mw.CalderonPreconditioner`, `mw.DirectH2Config`, `mw.DirectionalFMMConfig`, `mw.DyadicIntegrationConfig`, `mw.EdgeGrading`, `mw.FieldQueryConfig`, `mw.FMMConfig`, `mw.FunctionRightPreconditioner`, `mw.H2Config`, `mw.HalfSpace`, `mw.HarmonicBalanceConfig`, `mw.HarmonicCutoffConfig`, `mw.HMatrixConfig`, `mw.IdentityRightPreconditioner`, `mw.KernelErrorBudget`, `mw.Layer`, `mw.LayeredSurfaceConfig`, `mw.LayerMap`, `mw.LayerStack`, `mw.LeafBlockRightPreconditioner`, `mw.LinearCoupledConfig`, `mw.MaxwellPlaneModes`, `mw.MoMConfig`, `mw.MoMDyadicPeriodicConfig`, `mw.MoMPeriodicConfig`, `mw.NearFieldRightPreconditioner`, `mw.OpenSurfaceConfig`, `mw.PFFTConfig`, `mw.PreconditionerContext`, `mw.ProcessStack`, `mw.SurfaceMeshConfig`, `mw.TetrahedralVolumeMesh`, `mw.ViaMap` | `mw.mom.<name>` |
|
|
332
|
+
| `mw.AngleProjectionMonitor`, `mw.AstigmaticGaussianOverlapMonitor`, `mw.AuxFieldTimeMonitor`, `mw.CartesianProjectionMonitor`, `mw.ClosedSurfaceMonitor`, `mw.DiffractionMonitor`, `mw.DipoleEmissionMonitor`, `mw.FieldTimeMonitor`, `mw.FluxTimeMonitor`, `mw.GaussianOverlapMonitor`, `mw.KSpaceProjectionMonitor`, `mw.MediumMonitor`, `mw.PermittivityMonitor`, `mw.PowerLossData`, `mw.PowerLossMonitor`, `mw.SurfaceFieldTimeMonitor` | `mw.monitors.<name>` |
|
|
333
|
+
| `mw.AxisSegment`, `mw.Capacitor`, `mw.CircleLoop`, `mw.CoaxialLumpedPort`, `mw.CoaxialLumpedResistor`, `mw.CompositeCurrentIntegral`, `mw.CompositeVoltageIntegral`, `mw.CustomCurrentIntegral`, `mw.CustomVoltageIntegral`, `mw.EmbeddedNetworkData`, `mw.Inductor`, `mw.LowFrequencySmoothingSpec`, `mw.ModalPortSweep`, `mw.NetworkBlock`, `mw.NetworkData`, `mw.NetworkPhysicalityReport`, `mw.ParallelRLC`, `mw.PECFrame`, `mw.PolygonLoop`, `mw.PolylinePath`, `mw.port_phasors`, `mw.port_voltage`, `mw.PortData`, `mw.PortDrive`, `mw.PortExcitation`, `mw.PortSweep`, `mw.RectangleLoop`, `mw.Resistor`, `mw.run_modal_port_sweep`, `mw.SeriesRLC`, `mw.smooth_low_frequency`, `mw.TerminalPort`, `mw.TerminalRef`, `mw.TerminalWavePort`, `mw.TerminalWavePortApertureWarning`, `mw.ThinWire`, `mw.TouchstoneNetwork`, `mw.TouchstoneParseError`, `mw.trapezoidal_impedance`, `mw.WaveModeSpec`, `mw.WavePort`, `mw.WireConductor`, `mw.WireData`, `mw.WireEnd`, `mw.WireMonitor`, `mw.WireNodeRef`, `mw.WirePortBinding` | `mw.rf.<name>` |
|
|
334
|
+
| `mw.bilinear_discretize`, `mw.check_sampled_passivity`, `mw.DiscreteStateSpaceNetwork`, `mw.fit_rational`, `mw.FitReport`, `mw.NetworkFitReport`, `mw.PassivityReport`, `mw.RationalFitConfig`, `mw.RationalModel`, `mw.StateSpaceNetwork` | `mw.rf.rational.<name>` |
|
|
335
|
+
| `mw.combine_coherent_sar`, `mw.combine_incoherent_sar`, `mw.IncidentPowerDensity`, `mw.IncidentPowerDensityMonitor`, `mw.PowerNormalization`, `mw.SARAveraging`, `mw.SARPeak`, `mw.SARResult` | `mw.sar.<name>` |
|
|
336
|
+
| `mw.AstigmaticGaussianBeam`, `mw.BasebandGaussianPulse`, `mw.BasebandRectangularPulse`, `mw.BroadbandPulse`, `mw.CurrentDataset`, `mw.CustomCurrentSource`, `mw.CustomFieldSource`, `mw.CustomSourceTime`, `mw.FieldDataset`, `mw.RickerWavelet` | `mw.sources.<name>` |
|
|
337
|
+
| `mw.run` | removed; call Simulation.run() |
|
|
338
|
+
| `mw.BJT` | removed (a reserved placeholder that always raised) |
|
|
339
|
+
| `mw.MOSFET` | removed (a reserved placeholder that always raised) |
|
|
340
|
+
| `from witwin.maxwell.fdtd import FDTD, calculate_required_steps`, `from witwin.maxwell.fdfd import FDFD` | removed exports; the solver backends are internal (inspect `Simulation.prepare().solver`) |
|
|
341
|
+
|
|
342
|
+
`witwin.maxwell.electrostatic.__all__` lists the electrostatic objects above plus `ElectrostaticConfig` and `CapacitanceConfig` (new in 0.7.0) and no longer the internal `solve_electrostatics`, `extract_capacitance` and `DEFAULT_GAUSS_TOLERANCE`; `witwin.maxwell.execution.__all__` lists the execution and batch objects above instead of its device-pool internals; `witwin.maxwell.capability.__all__` no longer repeats `capabilities`.
|
|
343
|
+
- **`mw.run(simulation)` is removed** (plan Q9); call `simulation.run()`.
|
|
344
|
+
- **The reserved `BJT` and `MOSFET` classes are removed** (plan Q10). They raised `UnsupportedFeatureError` on construction; transistor devices are not modelled.
|
|
345
|
+
- **String-valued options are `str` Enums, parsed once at construction; only the exact value strings are still accepted** (plan Q2, Q11). A constructor takes a member or exactly its value string and stores the member; members compare equal to, hash like, and format and repr as their value strings, so `spec.kind == "pml"` and `payload["Ez"]` keep working. Any other value raises `SetupError` (a `ValueError`) listing the choices. Spellings that were silently normalized now raise: other letter case (`"PML"`, `"ez"` in `polarization` or monitor `fields`/`components`, `profile="IDEAL"`, `absorber="CPML"`, `window="Hanning"`, `averaging="Polarized"`), surrounding whitespace (`direction=" -"`, `absorber=" cpml"`), and the axis aliases `"x"`/`"y"`/`"z"` for a mode polarization (use `"Ex"`/`"Ey"`/`"Ez"` or an axis-aligned vector). `BoundaryKind` changes from a `typing.Literal` alias to an Enum whose `MIXED` member is only reported (by `BoundarySpec.kind` and `axis_kind`), never accepted. Scene dictionaries, resume fingerprints and SAR payloads keep writing the plain value strings.
|
|
346
|
+
|
|
347
|
+
| Enum (home) | Members | Option it types |
|
|
348
|
+
|---|---|---|
|
|
349
|
+
| `mw.BoundaryKind` | `NONE`, `PML`, `PERIODIC`, `BLOCH`, `PEC`, `PMC`, `MUR`, `MODE_ABC`, `MIXED` (reported only) | `BoundarySpec(kind=, x=/y=/z=, x_low=...)`, `BoundarySpec.faces(default=...)`, `BoundarySpec.uses_kind` |
|
|
350
|
+
| `mw.monitors.FieldComponent` | `EX`, `EY`, `EZ`, `HX`, `HY`, `HZ` | `PointDipole`/`UniformCurrentSource` `polarization` (electric only; a vector still works), `PointMonitor`/`PlaneMonitor`/`FinitePlaneMonitor` `fields`, `FieldTimeMonitor`/`SurfaceFieldTimeMonitor` `components`, `mw.fdfd.FieldProjection.component`, `mw.fdfd.LocalDesignRegion.components` |
|
|
351
|
+
| `mw.monitors.Direction` | `PLUS` (`"+"`), `MINUS` (`"-"`) | `direction` of `ModeSource`, `ModeMonitor`, `ModePort`, `mw.rf.WavePort`, `mw.rf.TerminalWavePort`, `mw.rf.CoaxialLumpedPort`, `mw.fdtd.InternalAbsorber`, `mw.esd.ESDCurrentSource`; `normal_direction` of the plane, flux, mode, diffraction, projection and overlap monitors; `KSpaceProjectionMonitor.hemisphere` |
|
|
352
|
+
| `mw.monitors.ModePolarization` | `AUTO`, `EX`, `EY`, `EZ` | `polarization` of `ModeSource`, `ModeMonitor`, `ModePort`, `mw.rf.WaveModeSpec`, `mw.fdtd.ModeABC`; the polarization of a `mw.rf.ModalPortSweep` mode entry (`AUTO` refused there) |
|
|
353
|
+
| `mw.sources.DipoleProfile` | `GAUSSIAN`, `IDEAL` | `PointDipole.profile` |
|
|
354
|
+
| `mw.grid.SubpixelAveraging` | `ARITHMETIC`, `POLARIZED`, `POLARIZED_TENSOR`, `KOTTKE_EDGE`, `KOTTKE_SMOOTH` | `SubpixelSpec.averaging` |
|
|
355
|
+
| `mw.grid.PECTreatment` | `STAIRCASE`, `CONFORMAL` | `SubpixelSpec.pec` |
|
|
356
|
+
| `mw.fdfd.FDFDSolverType` | `GMRES`, `CG`, `BICGSTAB`, `TFQMR`, `IDR`, `SQMR`, `DIRECT` | `FDFDSolverConfig.solver_type` |
|
|
357
|
+
| `mw.fdfd.FDFDPreconditioner` | `JACOBI`, `SSOR`, `ILU`, `AMS`, `NONE` | `FDFDSolverConfig.preconditioner` |
|
|
358
|
+
| `mw.fdfd.Precision` | `SINGLE`, `DOUBLE` | `FDFDSolverConfig.precision` |
|
|
359
|
+
| `mw.sar.AveragingProfile` | `CUBICAL_PREFIX_V1` | `SARAveraging.profile`, `SARPeak.profile`; replaces the constant `mw.AVERAGING_PROFILE` (0.6.0), which is removed: use `mw.sar.AveragingProfile.CUBICAL_PREFIX_V1` |
|
|
360
|
+
| `mw.mom.MoMOperatorBackend` | `DENSE`, `HMATRIX`, `H2`, `DIRECT_H2`, `FMM`, `PFFT` | `MoMConfig.operator_backend`; an unknown value raises `SetupError` (was `NotImplementedError`) |
|
|
361
|
+
| `mw.mom.RieszStorage` | `DENSE`, `COMPACT_RWG_V1`, `LOCAL_RWG_V1` | `MoMConfig.riesz_storage`; an unknown value raises `SetupError` (a `ValueError`, as before, with the choices listed) |
|
|
362
|
+
| `mw.mom.LayeredOperatorBackend`, `mw.mom.LayeredConductorModel`, `mw.mom.PlanarMesher` | `DENSE`, `MATRIX_FREE`, `HMATRIX`; `SHEET`, `CLOSED`, `SURFACE_ADMITTANCE`; `AUTO`, `TRIANGLE` | `LayeredSurfaceConfig.operator_backend`, `.conductor_model`, `.planar_mesher` |
|
|
363
|
+
| `mw.mom.ACAPivoting` | `COMPLETE`, `ADAPTIVE` | `HMatrixConfig.pivoting` |
|
|
364
|
+
| `mw.mom.FMMTableStorage`, `mw.mom.FMMShiftStorage`, `mw.mom.FMMNearStorage`, `mw.mom.FMMKernelBoundRule`, `mw.mom.FMMExpansionCenter`, `mw.mom.LeafFactorKernel` | one member per value string (`FMMNearStorage.FULL_MATRIX` ... `SCALAR_RECIPROCAL_CACHED_DK_V1`; `LeafFactorKernel.NONE`, `ORIGINAL`, `PRIMARY`) | `FMMConfig.table_storage`, `.shift_storage`, `.near_storage`, `.kernel_bound_rule`, `.expansion_center_policy`, `.leaf_factor_kernel`; `DirectionalFMMConfig.near_storage` (refuses `FULL_MATRIX`) and `.leaf_factor_kernel` (refuses `PRIMARY`) |
|
|
365
|
+
| `mw.mom.PFFTGridPrecision`, `mw.mom.PFFTExteriorGrids` | `COMPLEX64`, `COMPLEX128`; `SINGLE`, `CLUSTERS` | `PFFTConfig.grid_precision`, `.exterior_grids` |
|
|
366
|
+
| `mw.mom.OpenEdgeRule` | `NATURAL`, `ZERO_FLUX` | `CalderonPreconditioner(open_edge_rule=)` |
|
|
367
|
+
| `mw.mom.HarmonicBalanceMethod`, `mw.mom.TensorFaceRule`, `mw.mom.HarmonicImplicitSolver`, `mw.mom.CutoffFailure` | `NEWTON`, `PICARD`, `NEWTON_KRYLOV`; `TRIANGLE`, `PROJECTED_DUFFY`, `DISTANCE_SCALED_DUFFY`; `DENSE`, `STREAMED_KRYLOV`, `STREAMED_INVERSE_KRYLOV`; `RAISE`, `RECORD` | `HarmonicBalanceConfig.method`, `.tensor_face_rule`, `.implicit_solver`; `HarmonicCutoffConfig.failure` |
|
|
368
|
+
| `mw.mom.TransverseMap`, `mw.mom.DyadicRadialMap`, `mw.mom.DyadicSpatialRule` | `LINEAR`, `SINH`; one member per radial map and spatial rule | `MoMDyadicPeriodicConfig.transverse_map`; `DyadicIntegrationConfig.radial_map`, `.spatial_rule` |
|
|
369
|
+
| `MoMSolveMethod`, `DirectStorage` (`witwin.maxwell.mom.linalg`, beside the internal `StoppingRule`) | `DIRECT`, `GMRES`, `BLOCK_GMRES`; `RESIDENT`, `SEALED_HOST_RESTORE_V1` | `StoppingRule.method`, `.direct_storage` |
|
|
370
|
+
| `mw.fdtd.AbsorberKind`, `mw.fdtd.SpectralWindowKind` (existing) | unchanged | `FDTDConfig.absorber`, `SpectralSampler.window`: now exact strings only (they were lower-cased and stripped) and `SetupError` instead of a plain `ValueError` |
|
|
371
|
+
|
|
372
|
+
The MoM rows above keep every payload, receipt, identity and solver statistic byte-identical: writers store the value strings. Their unknown-value messages change to the `SetupError` form (`HarmonicBalanceConfig.tensor_face_rule must be one of ...`).
|
|
373
|
+
|
|
374
|
+
- **Experimental public objects emit `ExperimentalWarning`.** The first time code outside the package constructs an experimental class, or calls an experimental function or the experimental solver entry points `Simulation.fdfd`, `Simulation.electrostatic`, `Simulation.capacitance`, `Simulation.batch` and `Simulation.mom`, it emits one `ExperimentalWarning` (a `MaxwellWarning`, so a `UserWarning`) per object and process. Objects the package builds itself (results, reports, defaults) do not warn, and no numerics change. Code that turns warnings into errors (`python -W error`, `warnings.simplefilter("error")`, `pytest -W error`) now fails on the first use of an experimental object; ignore the category, as `tests/conftest.py` does. `docs/reference/public-api.csv` and the FEATURE_LIST API Stability table list which objects are experimental: the whole of `mw.antenna`, `mw.breakdown`, `mw.circuits`, `mw.coordinates`, `mw.electrostatic`, `mw.esd`, `mw.invdes`, `mw.mom` (feature keys `mom` for homogeneous MoM and `mom_layered` for `Layer`, `LayerStack`, `HalfSpace`, `LayeredSurfaceConfig`, `AdaptiveSweep`, `AdaptiveSweepResult`, `LayerMap`, `ProcessStack` and `ViaMap`) and `mw.rf.rational`, the Batch tier of `mw.execution`, the PCB conductors (`PlanarPEC`, `SurfaceMesh`, `CopperFoil`), surface roughness, wave/terminal/coaxial ports and port sweeps, thin wires, custom path integrals, embedded networks and low-frequency smoothing in `mw.rf`, and `DiffractionMonitor`/`DipoleEmissionMonitor`.
|
|
375
|
+
|
|
376
|
+
| 0.6.0 | 0.7.0 |
|
|
377
|
+
|---|---|
|
|
378
|
+
| `mw.Simulation.fdfd(...)`, `mw.circuits.Circuit(...)`, `mw.rf.WavePort(...)`, ... under `warnings.simplefilter("error")` | add `warnings.filterwarnings("ignore", category=mw.ExperimentalWarning)` after it |
|
|
379
|
+
| `pytest -W error` | `pytest -W error -W ignore::witwin.maxwell.errors.ExperimentalWarning` |
|
|
380
|
+
|
|
381
|
+
- **Scene dictionaries are `witwin.scene/2` (plan phase 8a).** `Scene.to_dict()` writes every `Scene` field and every public scene type: material regions with their density values, circuits (nodes, devices, port bindings, initial conditions), networks (`NetworkData` and fitted models inline, never a file path), symmetry, coordinates, internal absorbers, electrostatic terminals and charge densities, a `LayerStack` background, tensor-valued and nonlinear media, modulation, surface-impedance models and roughness, every source, port and monitor type. Each document records `package_version`. Trainable tensors are written with their values and `"requires_grad": true`; `from_dict` rebuilds them as fresh leaves (optimizer state is not part of a scene). Documents are strict JSON (non-finite floats as `{"type": "Float", ...}`), mappings keep their key order through stores that sort keys, and structure identities (`structure_id`, `assignment_id`, `surface_id`, `material_id`, process-wide counters) are numbered per scene in document order, so the same scene writes byte-identical documents in any process. An object outside the schema (a callable such as `CustomSourceTime(fn)`, a user subclass of a scene type, a pole-perturbed `PerturbationMedium`) raises `mw.SchemaError` naming its document path instead of `TypeError("not in witwin.scene/1: ...")`; nothing is dropped. `Scene.from_dict` still reads `witwin.scene/1` documents: they are upgraded on read by `mw.io.migrate_scene_dict` (plan phase 8b, Q20), which logs every step.
|
|
382
|
+
|
|
383
|
+
| 0.6 | 0.7.0 |
|
|
384
|
+
|---|---|
|
|
385
|
+
| `Scene.from_dict(d, arrays=None, device="cuda")` | `Scene.from_dict(d, arrays=None)`; tensors come back on the CPU and the solver config places them |
|
|
386
|
+
| `"schema": "witwin.scene/1"`, `TypeError("not in witwin.scene/1: ...")` for networks, circuits, material regions, symmetry, coordinates, trainable tensors, ... | `"schema": "witwin.scene/2"`, all of these serialized; `mw.SchemaError` for what stays outside |
|
|
387
|
+
| `{"type": "Tensor", "dtype", "values"}`, `"complex"`, mappings as JSON objects, `Structure.material` as a bare material key | `{"type": "Tensor", "dtype", "shape", "values"[, "requires_grad"]}`, `"Complex"`, `{"type": "Mapping", "items": [...]}`, `{"type": "MaterialRef", "key": ...}`; the format is in `docs/reference/scene-dict-schema.md` |
|
|
388
|
+
|
|
389
|
+
### Changed
|
|
390
|
+
|
|
391
|
+
- Requires `witwin>=0.4.7,<0.5`. witwin-core 0.4.7 adds `ExtrudedPolygon` (exposed as the experimental `mw.geometry.ExtrudedPolygon`), keeps tensor dtypes in geometry dictionaries, measures short polygon edges exactly (edge-length guard at `finfo.tiny` instead of `eps`) and uses a scale-relative inside tolerance in the convex polygon signed distance. The coax-shield `pec_occupancy` change under [Numerical changes] of the release notes comes from this core release.
|
|
392
|
+
- `Result` reads its scene strictly. `Result.scene` is the declarative `Scene` of the run, or `None` for a scene-less Result (for example `Result.load(path, scene=None)`); a scene-less Result behaves exactly as before. Any other object, such as a `PreparedScene` or a stand-in, now raises `AttributeError` when the Result is constructed or loaded (`coordinates`) and on monitor lookups, `raw_monitor`/`monitors`, field, material and power-loss reads, `mw.esd` source, generator and component-stress accessors, and matched-reference queries. Before, those paths silently read such an object as "no coordinate chart", "no monitors", "no sources" or "no circuits". Pass the `Scene` (a prepared scene's declarations are `prepared.scene`).
|
|
393
|
+
- FDTD `Result.stats()["dft_window"]` reports the window the spectra were recorded with: `"none"` for every pulse (non-CW) run, which the runtime always records without a window, instead of the requested `SpectralSampler.window` (`"hanning"` by default). The requested value moved to the new key `dft_window_requested`. Numbers are unchanged. A consequence: strict native/copper `Result.query_fields` checks that require a `"none"` clock now accept pulse runs that requested the default window, whose recorded clock was always `"none"`.
|
|
394
|
+
- `Result.release_solver()` also clears the prepared scene's compiled material cache (the accelerated-setup material tensors), so an FDTD Result keeps only its phasors and small run records: on a 64^3 grid with one frequency, 38 MB stayed allocated after the call, now 7.0 MB (the E phasors, 6.5 MB, in allocator blocks). `Result.material(...)` recompiles on demand, as on a loaded Result. `release_solver()` is documented as the dataset-generation idiom.
|
|
395
|
+
- A multi-frequency FDTD volume DFT is finalised into one preallocated `(F, ...)` complex tensor per component instead of a list of per-frequency phasors stacked afterwards, which lowers the finalisation peak (8 frequencies on a 64^3 grid: 229 MB -> 198 MB; after `release_solver()` 83 MB -> 52 MB, the phasors). Values are bitwise unchanged.
|
|
396
|
+
- Package exceptions and warnings derive from the new domain bases (below) and keep their previous built-in base, so existing `except` clauses and `pytest.raises(...)` checks are unaffected:
|
|
397
|
+
|
|
398
|
+
| Class | Previous base | New bases |
|
|
399
|
+
|---|---|---|
|
|
400
|
+
| `FDTDPassivityError` | `RuntimeError` | `ConvergenceError` (`MaxwellError`, `RuntimeError`) |
|
|
401
|
+
| `NonlinearConvergenceError`, `NonlinearDeviceError` (`compiler.nonlinear_devices`) | `RuntimeError` | `ConvergenceError` (`MaxwellError`, `RuntimeError`) |
|
|
402
|
+
| `TouchstoneParseError` | `ValueError` | `SchemaError` (`MaxwellError`, `ValueError`) |
|
|
403
|
+
| `ModeTrackingError` (`postprocess.waveports`) | `RuntimeError` | `MaxwellError`, `RuntimeError` |
|
|
404
|
+
| `DistributedFailure` | `Exception` | `MaxwellError` |
|
|
405
|
+
| `FDTDCoreFallbackWarning` (later removed), `TerminalWavePortApertureWarning` | `UserWarning` | `MaxwellWarning` (`UserWarning`) |
|
|
406
|
+
|
|
407
|
+
The MoM solver exceptions keep their current bases in this release step.
|
|
408
|
+
- Capability refusals outside MoM raise `UnsupportedFeatureError` instead of a plain `NotImplementedError`: 461 raise sites in FDTD, FDFD, electrostatics, batch execution, material models, ports, results, postprocessing and the export adapters. Each error carries `.feature`, a capability-registry key when the refusal names a declared feature (`"thin_wire"`, `"material.copper_foil"`, `"port.WavePort"`, `"boundary.bloch"`, ...) and otherwise `"guard:<8 hex>"`, a stable key from the guard census; `.method` (`"fdtd"`, `"fdfd"`, `"electrostatic"`, or `None` when the refusal does not depend on the method). Messages are unchanged. `UnsupportedFeatureError` is a `NotImplementedError`, so `except NotImplementedError` handlers and `pytest.raises(NotImplementedError)` checks keep working; only code that tests the exact type (`type(error) is NotImplementedError`) sees the narrower class. `SceneModule.to_scene()` still raises `NotImplementedError` (an abstract hook); so do the four refusals inside `Material.evaluate_static`/`evaluate_at_frequency`, whose bytes the consumer-metadata bridge pins. `TerminalPort` and `TerminalWavePort` resolution errors now keep their original exception object (type and attributes) when they add the port name to the message.
|
|
409
|
+
- MoM capability refusals raise `UnsupportedFeatureError` too: 142 raise sites, 98 in homogeneous MoM (`.method == "mom"`) and 44 in layered MoM (`.method == "mom.layered"`). `.feature` is the registry key when the refusal names a declared feature (`"boundary.periodic"`, `"boundary.bloch"`, `"geometry.planar_pec"`, `"port.LumpedPort"`, `"background.homogeneous"`, `"material.nonlinear"`, `"material.surface_impedance"`) and otherwise `"guard:<8 hex>"`. Messages are unchanged, and `except NotImplementedError` keeps working.
|
|
410
|
+
- Release wheels ship prebuilt binaries for all three native libraries: the main FDTD extension, the core-path extension and the accelerated-setup extension. A machine without a CUDA toolkit now runs the default core path and accelerated setup instead of falling back to the existing path. The core-path (`core_abi_v12`) and setup (`setup_abi_v7`) extensions now use the LibTorch Stable ABI and load through the same prebuilt-first loader as the main extension, with `.abi` markers and `WITWIN_MAXWELL_FDTD_CUDA_PREBUILT=1` fail-closed loading.
|
|
411
|
+
- `postprocess.compute_diffraction_from_payload` (and `Result.monitor(...)` / `compute_diffraction_orders` for a `DiffractionMonitor`) returns per-order `power` and `efficiency`, `total_power` and `propagating_power` as 0-d float64 tensors on the monitor device (were Python floats), so trainable runs back-propagate through them. Values are identical to the former floats; use `float(...)` where a Python number is needed.
|
|
412
|
+
- `postprocess.purcell_factor` returns `purcell_factor`, `power_delivered` and `power_delivered_vacuum` as float64 tensors on the structured run's device (were NumPy arrays and, for one frequency, a Python float); a single-frequency factor is a 0-d tensor. Values are identical.
|
|
413
|
+
- Test suite tiers: plain `pytest` now runs the fast tier and deselects tests marked `slow` (measured over 60 s, listed in `tests/slow_tests.txt`); `--run-slow` includes them, `-m slow` selects only them, and a test file or node named on the command line keeps its slow tests. `--slow-budget SECONDS` fails unmarked tests that exceed the budget. The new `test` extra installs `pytest-xdist` for parallel CPU runs (`pytest -n 24`).
|
|
414
|
+
- More scenes run on the FDTD core path instead of the existing stepping path (W7 row 4): PMC faces, including PMC symmetry planes; permeability `mu_r != 1`, diagonal permeability tensors, magnetic ADE with a non-vacuum `mu_inf` and magnetic conductivity `sigma_m`; first- and second-order Mur faces, mode-matched and broadband `ModeABC` faces (also with ports and other separate physics) and `InternalAbsorber` planes; `MediumMonitor`, `AngleProjectionMonitor`, `CartesianProjectionMonitor`, `KSpaceProjectionMonitor`, `GaussianOverlapMonitor` and `AstigmaticGaussianOverlapMonitor`. These scenes no longer emit `FDTDCoreFallbackWarning` (removed since; see Breaking changes). Their fields and monitor outputs are bitwise equal to the existing path on the release GPU (A6000). The fallback reasons `"PMC boundaries"`, `"MUR boundaries"`, `"MODE_ABC boundaries"`, `"magnetic permeability"` and `"magnetic conductivity"` no longer occur. The core-path extension ABI is `core_abi_v13` (PMC faces in the fused electric kernel); prebuilt binaries with an older marker are rejected and rebuilt.
|
|
415
|
+
- Real-field closed-transverse cells (periodic, PEC or PMC transverse walls, PML on the normal axis) with an explicit `absorber="cpml"` or `"stablepml"` run on the FDTD core path (W7 row 5); they no longer emit `FDTDCoreFallbackWarning`, and the fallback reason `"closed-transverse CPML (passivity guard)"` no longer occurs. The passivity guard samples at the core path's K-step chunk boundaries at the same steps as before, so `FDTDPassivityError` trips at the same step with the same message, and the skip warning and `Result.metadata["passivity_guard"]` are unchanged. Fields and monitor outputs are bitwise equal to the existing path on the release GPU (A6000).
|
|
416
|
+
- Resumed FDTD runs (`prepared.run(resume_from=checkpoint)`) run on the CUDA core path (W7 row 7): the prepared core solver restores the checkpoint and continues from its step in whole-step graphs. Previously every resume rebuilt an existing-path solver with PyTorch material setup, emitted `FDTDCoreFallbackWarning` and reported `fallback_reason="resume_from"`; that warning and reason no longer occur. Checkpoints are unchanged and interchangeable between the paths. A split run (`run_until(n)` then resume) is bitwise equal to the uninterrupted run on the release GPU (A6000). This also fixes resumed runs with embedded-network ports: their port and network voltage/current spectra now equal the uninterrupted run (the former existing-path resume sampled them from the wrong DFT rows); every other resumed output is unchanged.
|
|
417
|
+
- The existing per-component FDTD runner is deleted (W7 row 16e): its 37 operators (per-component magnetic and electric Yee updates in standard, bounded, dense/compressed CPML and modulated forms, and the batched per-component lane updates) and `kernels/magnetic.cu` are removed, the multi-GPU solver no longer has bounded per-component launches, and the differentiable forward has a single core-path loop. Every FDTD run already took the core path (row 16c/16d), so results are unchanged. The main FDTD extension ABI is `stable_abi_v17`; prebuilt binaries with an older marker are rejected and rebuilt.
|
|
418
|
+
- The main FDTD extension ABI is `stable_abi_v16`: test-only debug and projection kernels are no longer registered, the gyromagnetic magnetization kernels (`gyromagnetic_snapshot`, `gyromagnetic_step`) are added, and the grouped and indexed point spectral observer kernels accept float64 fields. The core-path extension ABI is `core_abi_v14` (float64 fused Yee and observer-gather launches). Prebuilt binaries with an older marker are rejected and rebuilt. (Both markers moved on since: `core_abi_v15` with W7 row 13 and `stable_abi_v17` with W7 row 16e.)
|
|
419
|
+
- Full off-diagonal anisotropic `Tensor3x3` permittivity, including its conductive and dispersive combinations, runs on the CUDA core path inside the whole-step graph (previously the existing path with `FDTDCoreFallbackWarning` and `fallback_reason="full or off-diagonal anisotropy"`). The existing off-diagonal correction and conduction kernels run right after the fused electric update, in the same order as before, so fields and monitors are bitwise unchanged. Gradient runs followed with W7 row 14.
|
|
420
|
+
- Gyromagnetic ferrites (`GyromagneticFerrite`, axis-aligned, oblique and mixed bias) run on the CUDA core path inside the whole-step graph (previously the existing path with `FDTDCoreFallbackWarning` and `fallback_reason="gyromagnetic media"`, which no longer occurs). On both paths the magnetization drive snapshot and the coupled implicit-midpoint step are two CUDA kernels over the active ferrite cells instead of about 20 Torch operations over the whole grid. The kernels keep the former arithmetic, so fields, monitors and the magnetization state are bitwise unchanged on the release GPU (A6000). Gradient runs still refuse ferrites.
|
|
421
|
+
- Differentiable FDTD runs (trainable scene tensors, `SceneModule` parameters, RF inputs, or an explicit `adjoint_checkpoint_stride`) run their forward on the CUDA core path (W7 row 14): the forward is the ordinary solve in whole-step CUDA graphs, with the adjoint checkpoints captured at the checkpoint stride, and the reverse sweep is unchanged. They no longer warn `FDTDCoreFallbackWarning` with `gradient-requiring scene tensors` or `adjoint/gradient-requiring execution`. Gradient runs of real closed-transverse CPML scenes now sample the passivity guard like ordinary runs. Forward outputs, checkpoints and gradients equal the previous existing-path forward bitwise on the gradient gate scenes.
|
|
422
|
+
- Native batch lanes (`Simulation.batch(...)`) run on the CUDA core path (W7 row 15): each resident lane advances on the fused core Yee update bound to its slot storage, instead of the batched per-component kernels. Building a batch emits no `FDTDCoreFallbackWarning`, and the fallback reason `"Batch lanes"` no longer occurs. Every lane is bitwise equal to the same variant run alone and to the former batch kernels on the release GPU (A6000), including gradients through differentiable lanes.
|
|
423
|
+
- Multi-GPU FDTD (`FDTDConfig(parallel=...)`) runs on the CUDA core path (W7 row 15, distributed half): every shard advances on the fused core Yee update bound to its local storage, instead of the bounded per-component kernels (standard fields) or the per-component CPML/modulated kernels, and each shard's full-field DFT reads its weights from a precomputed device table instead of per-step host arithmetic. Multi-GPU runs no longer warn `FDTDCoreFallbackWarning` with `multi-GPU/distributed execution`. The fused launch has no interior/halo split, so `overlap=True` now runs the serialized schedule and `parallel_stats["overlap_active"]` is `False`. Distributed build or solve errors are raised without a rebuild (a failed shard core activation first rebuilt the previous distributed path once; since W7 row 16c it raises, see Breaking changes). Outputs, gradients, resumed runs and shutoff statistics equal the previous distributed path bitwise on the two-GPU gate scenes, except one fix: a point monitor inside the last owned cell of the first shard now reads the updated `Hx` at the shard's high ghost node, which the bounded launches never updated (it read 0 there in runs without CPML or modulation), so it equals the single-device result. Distributed resume checkpoints now carry the shards' DFT step counter, so a checkpoint written by the previous release does not resume a full-field-DFT run.
|
|
424
|
+
- Float64 FDTD runs (`FDTDConfig(field_dtype=torch.float64)`) run on the CUDA core path (W7 row 12): the fused Yee update has a float64 instantiation, and the run is captured in whole-step CUDA graphs. `cuda_graph=True`, the default, is now accepted with float64 fields (it previously raised `ValueError("FP64 native forward requires eager execution, ...")`); `cuda_graph=False` keeps per-step execution. The fallback reason `"non-float32 fields"` no longer occurs. The float64 admission itself is unchanged (fixed grid, direct `LumpedPort` drives, Box scalar media and two-sided `CopperFoil`, all-face dense CPML, one frequency, float64 sparse spectra). Material setup stays on PyTorch for float64, because the accelerated setup kernels are float32-only. Per-step float64 core runs are bitwise equal to the former eager execution; graph runs differ only by the device-side observer weight recurrence, within the float64 run-level bound (1e-10 of the reference maximum; measured at most 7e-16 relative on the release GPU, A6000).
|
|
425
|
+
- Complex (Bloch split) FDTD fields run on the CUDA core path inside the whole-step graph (W7 row 13): Bloch cells, oblique and broadband fixed-k TFSF slabs, discrete-CW and zero-k grating slabs, Bloch point and current sources, and their spectral monitors and full-field DFT. They no longer take the existing path with `FDTDCoreFallbackWarning` "Bloch/complex fields" (beside separate physics too since W7 row 16b, below). Results are bitwise identical to the previous existing-path run. The fixed-k incident line no longer reads its step back to the host every step, the complex running DFT and spectral monitors use device weight tables instead of per-step host weights (on both paths), and Bloch source rows (scalar, CW and time-shifted patches) are staged once for the run. The core-path extension ABI is `core_abi_v15` (Bloch source scatter launch).
|
|
426
|
+
- Runs with a material cache (`FDTDConfig(material_cache=mw.fdtd.FDTDMaterialCache(...))`) run on the CUDA core path (W7 row 11); previously every cached run took the existing path with `FDTDCoreFallbackWarning` and `fallback_reason="material_cache override"`, which no longer occurs. The cache and its keys are unchanged: it still stores the PyTorch material compilation, so cached runs keep PyTorch material setup. Fields and monitors of cache misses, hits and local recompiles are bitwise equal to the uncached run and to the existing path on the release GPU (A6000).
|
|
427
|
+
- Scenes with bent coordinate charts (`Scene(coordinates=mw.coordinates.BendCoordinates(...))`) run on the CUDA core path inside the whole-step graph (W7 row 10), in float32 and float64; previously they ran on the existing path with `FDTDCoreFallbackWarning` and `fallback_reason="coordinate charts"`, which no longer occurs. The chart metric is folded into the electric and magnetic constitutive tables (and the split-copper half-cell metric and response scaling) at compile time, so the fused Yee update reads ordinary indexed coefficient tables and no chart-specific code runs per step. Fields, monitors, port spectra and copper losses are bitwise equal to the existing path on the release GPU (A6000). Material setup for charts stays on PyTorch. Gradient runs followed with W7 row 14.
|
|
428
|
+
- Every public monitor type runs on the CUDA core path (W7 row 16a): `PowerLossMonitor` (Cartesian, beside copper foil and on bent charts), `DipoleEmissionMonitor`, `ComponentStressMonitor`, `SurfaceFieldTimeMonitor`, `AuxFieldTimeMonitor` and `WireMonitor` no longer take the existing path with `FDTDCoreFallbackWarning` and `fallback_reason="unsupported monitor type"`, which no longer occurs. Power-loss channels and component stress are reduced at export from the core run's spectra and time series, dipole emission is a core point-observer group, and the surface, auxiliary-state and wire monitors keep the per-step observer loop around the fused Yee update (no whole-step graph, as for field time monitors). Fields, monitor payloads and the exported reductions are bitwise identical to the previous existing-path run on the release GPU (A6000).
|
|
429
|
+
- Complex (Bloch split) FDTD fields beside separate physics run on the CUDA core path (W7 row 16b): passive R/L/C lumped elements, undriven `LumpedPort`s with R/L/C or `SeriesRLC`/`ParallelRLC` terminations (also over dispersive media) and `CopperFoil`, in the whole-step graph, and beside fixed-k TFSF in the per-step core loop. They no longer take the existing path with `FDTDCoreFallbackWarning` and `fallback_reason="Bloch/complex fields with separate physics"`, which no longer occurs. The other separate-physics pieces keep refusing complex fields on every path, as before: driven lumped ports, coaxial and terminal ports, lumped terminals on copper foil, circuits, embedded networks, conformal thin sheets, thin wires, PEC cut surfaces and SIBC. Fields, monitors, port spectra, copper losses and the complete lumped/copper state (both banks) are bitwise identical to the previous existing-path run on the release GPU (A6000).
|
|
430
|
+
- MoM `StoppingRule.rtol` defaults to `None` (unset) and is derived from the backend. Hierarchical H/H2, direct H2 and FMM configurations (`operator_backend="hmatrix"`, `"h2"`, `"direct_h2"`, `"fmm"`) resolve it to `0.1 * solve_dual_tolerance` (1e-9 with the default `solve_dual_tolerance=1e-8`). Every other configuration and every standalone rule (dense and pFFT `MoMConfig`, harmonic-balance and DC tangent rules, fixed inverses, direct solves) resolves it to 1e-8, as before. A hierarchical or FMM `MoMConfig` with a `StoppingRule` that leaves `rtol` unset, which previously raised `ValueError("Hierarchical/FMM stopping.rtol must be <= 0.1 * solve_dual_tolerance ...")`, is now admitted. An explicit `rtol` keeps its value and is still refused above `0.1 * solve_dual_tolerance`. Configuration payloads and identities store the resolved number, so explicit-`rtol` and dense results are unchanged.
|
|
431
|
+
- `cpml_config["memory_mode"]="auto"` (the default) no longer reads the card's free memory. It keeps dense CPML `psi` storage whenever that storage is at most `dense_memory_limit_mib` (64 MiB by default) and uses slab storage above it, on single-device runs and on every distributed shard. A card too full for the dense storage now raises the CUDA out-of-memory error instead of switching to slab storage. Migration: pass `cpml_config={"memory_mode": "slab"}` (or a smaller `dense_memory_limit_mib`) to keep the low-memory layout on a nearly full card.
|
|
432
|
+
|
|
433
|
+
### Fixed
|
|
434
|
+
|
|
435
|
+
- Coupled harmonic MoM snapshot archives (`Result.save` and the harmonic snapshot payload) load again with `torch.load(weights_only=True)`. Since the MoM options became Enums, the snapshot's `numerical` and `stopping` records stored `RieszStorage`, `MoMSolveMethod` and `DirectStorage` members, which the safe unpickler refuses; they are now written as their plain string values. Values and restored configurations are unchanged, and archives written in between still load through `Result.load`.
|
|
436
|
+
|
|
437
|
+
- `Simulation.prepare().run()` of a `WavePort` `PortSweep` or `PortExcitation` and of a `TerminalWavePort` `PortSweep` returned a `Result` whose `scene` was the internal prepared scene (a regression of the `PreparedScene` composition above): `result.scene.domain` and the other `Scene` fields raised `AttributeError`, and the `Result` monitor lookups found no declared monitor. `result.scene` is now a `Scene` (the prepared declarations), as for the lumped `PortSweep`; `Simulation.run()` is unchanged. No numerical change.
|
|
438
|
+
- `Simulation.prepare()` of a `WavePort` sweep or excitation with trainable materials raised `AttributeError: 'PreparedScene' object has no attribute 'structures'` in the fixed port cross-section check; the check reads the prepared declarations again. No numerical change.
|
|
439
|
+
- **`Scene.symmetry` scenes reproduce their explicit mirrored domain.** A folded scene stands for the kept part plus its mirror images, and three quantities were computed over the folded domain instead:
|
|
440
|
+
- a soft `PlaneWave` was normalized to unit power over the folded aperture, which also drops the absorber cells on the folded face, so its field was too large by `sqrt(2)` per folded axis against the mirrored domain (and by `sqrt((N + 2L)/(N + L))` against the same bounds without symmetry). It is now normalized over the mirrored-domain aperture: the folded run equals the unfolded run on the kept part (bitwise on the tested uniform grids), and a unit plane wave carries one watt in the mirrored domain;
|
|
441
|
+
- a `GaussianBeam`/`AstigmaticGaussianBeam` took its launch-plane reference delay at the center of the folded plane, a global time shift (about 90 degrees at the carrier on a quarter domain); it now uses the mirrored-domain center;
|
|
442
|
+
- domain-spanning plane flux (`FluxMonitor`, flux-enabled `PlaneMonitor`, `IncidentPowerDensityMonitor` flux, `FluxTimeMonitor`) integrated the kept part only. It now reports the mirrored-domain power, twice the kept integral per folded axis tangential to the plane (the raw payload lists the image-plane axes in `symmetry_image_planes`). A flux-enabled `FinitePlaneMonitor` symmetric about an image plane counts twice per plane, one on the kept side once, and one crossing an image plane asymmetrically is refused at construction (`symmetry.finite_plane_image_plane`).
|
|
443
|
+
|
|
444
|
+
- a `ModeSource`, `ModeMonitor`, `ModePort`, `WavePort` or `TerminalWavePort` whose mode plane touches an image plane was solved on the folded aperture with a zero-field edge at the plane and normalized to unit power there: under a PEC plane the effective index was off by 0.6 % and the mirrored domain carried 2 W; under a PMC plane the solver returned a different mode. Such mode planes are now refused at construction (`symmetry.mode_plane_image_plane`); keep the mode plane more than half a cell from every image plane or simulate the full domain. PEC/PMC-aware transverse mode operators are a follow-up.
|
|
445
|
+
|
|
446
|
+
Behavior change for every symmetry scene with a soft plane wave or a Gaussian beam: fields fall by `1/sqrt(2)` per folded axis (plane wave) or change phase (beam). Plane-wave flux totals are unchanged (the two corrections cancel); flux of other sources under symmetry doubles per folded tangential axis. The reference-solver export of a face-symmetric scene is now its mirrored domain with center symmetry planes (structures and regions must be boxes symmetric about the image plane there). Benchmark rows `symmetry_center`, `symmetry_pec_center` and `symmetry_pmc_center` are now defined as the kept part of the scene their reference describes.
|
|
447
|
+
|
|
448
|
+
- **`Scene.from_dict(scene.to_dict())` rebuilds every geometry tensor bit for bit, dtype included.** In 0.6 geometry fields (Box/Sphere/... position, size, radius, rotation, boolean smoothness, PolySlab/PlanarPEC/SurfaceMesh vertices, Mesh vertices and faces, and geometry nested in ports such as `LumpedPort`/`TerminalPort` `current_surface` and `voltage_aperture`) were written as bare JSON lists and rebuilt as float32, so float64 geometry drifted by about 1e-8 relative on the first save/load, int32 Mesh faces came back int64, and a scene whose float32-rounded port aperture failed validation (benchmark `printed_dipole_scene`) could not be rebuilt at all. `witwin.scene/2` keeps every tensor dtype (see Breaking changes); a 0.6 document is read through `mw.io.migrate_scene_dict`, which reads a bare geometry value float32 cannot represent as float64 (the old writers stored full-precision values) and every other bare value as before. `geometry.ComplexPolySlab`, on which 0.6 raised `AttributeError`, is serialized.
|
|
449
|
+
|
|
450
|
+
- A resumed FDTD run on the existing runner (scenes a blocker keeps off the core path) with embedded-network or terminal ports reports the same port and network voltage, current and power as its uninterrupted run. Its embedded-terminal observer graph read the port DFT rows from step 0 after the resume, so those spectra were wrong (up to 89 % of the peak on a one-port network fixture). Fields were unaffected.
|
|
451
|
+
|
|
452
|
+
- Thin-wire ports bound with `WirePortBinding.nodes(...)` converge under grid refinement. The port voltage was the difference of the terminal node potentials `q/C_node` alone; that potential carries only the wire's quasi-static self term, so the Yee field between the two terminals was missing from the port voltage and drive, which left a grid-dependent series reactance (input reactance and S11 diverged under refinement, 0.6.0 known limitation). The node binding now adds the conservative Yee line integral along the straight chord between its terminals, sampled exactly like a removed feed gap: a node-bound feed between two arm ends is the same port model as the `gap` binding of the joined wire, and a node binding across a physical wire segment reads that segment's EMF. Results of every scene with a node-bound port change (intended); gap-bound ports and wires without ports are unchanged (`torch.equal` compiled networks). Known limitation that remains (it applies equally to the `gap` binding): R converges; X carries a placement-dependent bias. Input resistance matches a qualified thin-wire integral-equation reference within a few percent, while the input reactance of short and near-resonant dipoles depends on where the wire runs in the Yee cell (up to about 15-25 % high in |X| on or near a grid node line, within about 5 % in mid-cell or oblique runs).
|
|
453
|
+
|
|
454
|
+
- **Dispersive media under `SubpixelSpec(averaging="polarized")`, `"polarized_tensor"` and `"kottke_smooth"` now follow the interface rule of the static medium.** Interface Yee edges blended the high-frequency permittivity with the window rule (normal projection or Kottke window) but scaled the Debye/Lorentz/Sellmeier pole strengths by the node volume fraction, averaged node to edge, so the dispersive part of the medium was blended arithmetically and curved dispersive interfaces did not converge (a Sellmeier sphere stalled near 3.3% extinction error against Mie; with the fix 1.2% at the same grid). Each pole weight is now the edge-native volume fraction scaled so the edge reproduces the window rule exactly in the static and high-frequency limits (pole frequencies keep their bulk values; Drude poles keep the edge volume fraction). Results of every such scene with partially filled dispersive cells change; bulk cells, the default `kottke_edge` and `arithmetic` are unchanged.
|
|
455
|
+
|
|
456
|
+
- FDTD differentiates a trainable `MaterialRegion` geometry (for example its position) through the gradient bridge. It was missing from the trainable census, so the run went forward-only and returned outputs detached from it. Forward values are unchanged. Batch and multi-GPU runs refuse it, as they refuse other trainable geometry (multi-GPU previously ran it forward-only).
|
|
457
|
+
|
|
458
|
+
- Multi-frequency FDFD Results and local-response Results (`prepare().run()`, `trial(...).result()`, `accept(...)`) keep `Simulation.metadata`, as single-frequency `run()` does; they previously returned an empty `Result.metadata`.
|
|
459
|
+
|
|
460
|
+
- FDFD differentiates a trainable `Material(sigma_e=<tensor>)` at exactly 0: the conductivity was folded into the complex permittivity only when nonzero, so its gradient came back as zero. Forward values are unchanged. A SceneModule FDFD run under `torch.no_grad()` now runs the detached solve; it previously raised `NotImplementedError` from the gradient bridge.
|
|
461
|
+
|
|
462
|
+
- Differentiable `Simulation.batch(...)` lanes now return `Result.embedded_networks` / `Result.embedded_network(name)`, bound to the adjoint port outputs, and their `PortData`, `CircuitData` and `EmbeddedNetworkData` tensors keep the autograd graph. Differentiable lanes previously returned no embedded networks and exported port and circuit records detached, so objectives built from them silently had no gradient.
|
|
463
|
+
|
|
464
|
+
- Electrostatics and capacitance are differentiable in a trainable isotropic `Material(eps_r=<tensor>)`, as the capacitance docstring states. The permittivity was converted to a float and the result was detached; forward values are unchanged (`torch.equal`). Under an anisotropic (tensor) dielectric such a permittivity now fails closed instead of being detached.
|
|
465
|
+
|
|
466
|
+
- Identical FDTD runs with CPML boundaries are bitwise repeatable regardless of what other processes hold on the GPU. The default `"auto"` CPML memory mode chose dense or slab `psi` storage from the card's free memory at prepare time, and the two layouts round differently, so a scene whose dense storage is at most 64 MiB gave different bits whenever the card had less than eight times that storage free (at most 512 MiB). The choice now depends only on the scene (see Changed).
|
|
467
|
+
|
|
468
|
+
- Layered MoM vertical Green tables over a stack PEC ground (for example a microstrip with vertical edge ports at 1 GHz and above) were refused by the z/rho interpolation admission even though they were accurate: rows whose source or observer lies on the PEC plane hold a horizontal kernel that cancels against its image to denormal noise, and the horizontal admission divided by that row's own magnitude. Horizontal admission rows now use the vertical rule, a floor of 1e-6 times the per-frequency family maximum. Table values are unchanged; only the admission verdict changes.
|
|
469
|
+
|
|
470
|
+
- Layered MoM horizontal Green tables with a plane on a stack PEC ground and further planes above it (for example the planes {0, 100, 110} um of a PEC / 100 um / 10 um via stack, needed by grounded vertical ports in multi-plane stacks) were refused by their own interpolation admission (6e4 at 1 GHz) although every row interpolates to about 1e-8: a tangential row with one end on the PEC plane cancels against its image to roundoff and was normalized only by its own maximum. The admission now floors every row at 1e-6 of the maximum over all plane pairs of its frequency and component. Table values are unchanged (every tensor of 12 previously admitted tables is bitwise identical); the admission verdict can only decrease.
|
|
471
|
+
|
|
472
|
+
### Added
|
|
473
|
+
|
|
474
|
+
- SceneModule structural sharing is reused by the material compiler (0.7.0 phase 7d). A preparation with material regions and only static structures reuses the structure prefix of every node and Yee-edge material sample while the very same structure objects reappear on the same grid, device and dtype, and the PML-interface census of a static geometry is reused on the same grid (at most 4096 entries and 64 MiB of geometry snapshots, a geometry above 8 MiB is not memoized, and an entry is released when its geometry is garbage collected). Compiled tables are `torch.equal` to a full compile; an in-place edit of a geometry tensor, a trainable or modulated structure, or a payload above the 512 MiB frame budget compiles in full. At most two frames are kept, least recently used first, and a frame is released when its structures are garbage collected; on CUDA its tensors are device memory held between runs (up to 2 x 512 MiB; release with `witwin.maxwell.compiler.static_cache.STATIC_PREFIX_CACHE.clear()`). With 1,000 static boxes on CPU a density-loop iteration compiles its materials in about 0.1 s instead of 12-23 s and prepares in about 35 ms instead of 0.35-0.5 s. `examples/invdes/waveguide_bend_topology.py` uses the pattern. `FDTDConfig.material_cache` (content-keyed, opt-in, static scenes without material regions) is unchanged.
|
|
475
|
+
- JSON Schemas of the versioned payloads are published under `witwin/maxwell/schemas/` (plan phase 8c): `witwin.scene-2.json` (JSON Schema 2020-12 generated from the scene type registry: one `$defs` entry per type with its constructor fields and their annotations; `mw.io.scene_json_schema()` returns it) and field schemas of `PortData`, `NetworkData`, `WireData`, the FDTD resume checkpoint and the distributed result manifest. `VERSIONS.toml` records every versioned payload (also the result snapshot and `pcb-import`) with its version, revision and the sha256 of its generated schema. An additive schema change (new types, new optional fields, new enum members) keeps the version and bumps the revision; a breaking one (removal, rename, change of meaning) needs a new major version and a migrator (user decision 2026-11-13); a CI test fails on any change VERSIONS.toml does not record. Regenerate with `python scripts/dev/scene_schema.py --write`.
|
|
476
|
+
- Scene dictionaries keep tensor sharing: a tensor object reached more than once (one trainable parameter used by two structures) is written once in a `tensors` table and referenced by `{"type": "TensorRef", "key": ...}`; `Scene.from_dict` gives every use the same tensor, one shared leaf when trainable (user decision 2026-11-13).
|
|
477
|
+
- Scene dictionaries write a run of 64 or more consecutive same-type records (for example the 16,384 point monitors of a datagen F1 scene) as one `Records` block of per-field columns: constant fields once, consecutive names as a pattern, float vectors as one float64 array in the arrays table. The F1 document goes from 2.6 MB to 4.9 KB plus a 393 KB array (1.0 MB without an arrays table); the scene reads back identically.
|
|
478
|
+
- `mw.io.migrate_scene_dict(d)` upgrades a `witwin.scene/1` scene dictionary to `witwin.scene/2` (a `/2` one is returned as a copy); `Scene.from_dict` calls it for `/1` input. It is a data migrator, not an API shim (plan Q20). Every step and every value the `/1` document did not store is logged at INFO on the `witwin.maxwell.io.migrate` logger with its document path: process-wide structure identities numbered per scene (a structure inheriting its material's id inherits it again), the authored base kind of a mixed `BoundarySpec` (`/1` wrote all six faces resolved and the kind as `"none"`; the base becomes the most common uncovered face kind, ties preferring `"pml"` then `"none"`, so the face kinds are unchanged), rotations stored as quaternions (an Euler-angle tensor rotation comes back as its quaternion), metadata arrays read as lists, and bare-list geometry of documents written before tensor dtypes (float64 where float32 cannot hold the value). The 230 gate, benchmark and datagen scenes `/1` could write rebuild to the same scene fingerprints except the six mixed boundaries authored with a non-`"none"` base kind whose override form differs (same face kinds).
|
|
479
|
+
- `witwin.scene/2` scene dictionaries cover every `Scene` field and public scene type, trainable tensors (values plus `requires_grad`) and strict JSON; see the breaking-change entry for the format changes.
|
|
480
|
+
- `benchmark/datagen/scheduler.py --format emfc` (opt-in, needs emfc >= 0.2.0): one EMFC record per task (readouts, provenance and `maxwell-datagen-record/1` metadata, domain-cropped volume E of every DFT frequency at `--field-tolerance`, with a deterministic `--audit-fraction` lossless subset) in `emfc.shard` shards under `<output-dir>/shards`, indexed at the end of the run and resumable. Samples that must also store H (CopperFoil F3 boards, graded grids) and symmetry scenes are refused for now. The `--format pt` default is unchanged.
|
|
481
|
+
- Opt-in FDTD magnetic volume DFT: `FDTDConfig(full_field_dft=True, volume_dft_components=("Ex", "Ey", "Ez", "Hx", "Hy", "Hz"))` also records the H phasors, and `Result.fields` (with `Result.H`, `Result.field("Hx")`) then holds `HX`, `HY`, `HZ` `FieldData` on the full H Yee grids (`HX` is `(F, Nx, Ny - 1, Nz - 1)`, absorber layers and the periodic/Bloch wrap plane included, float64 coordinates), raw Yee phasors like E. H is accumulated in the same step as E but is the field half a step earlier, so its `FieldData` carry `attrs["field_time_offset_steps"] = -0.5` (the phasor at H's own time is the stored value times `exp(-i omega dt / 2)`). `volume_dft_components` defaults to `("Ex", "Ey", "Ez")` (unchanged, bitwise identical runs), must contain E, and needs an explicit `full_field_dft=True` to add H. Multi-GPU runs and differentiable (trainable) runs refuse the H volume DFT with `UnsupportedFeatureError`, and `Simulation.batch` keeps refusing magnetic `BatchOutput.fields`. `Result.field(..., expand_symmetry=True)` mirrors H with the pseudovector parity (opposite to E). Memory: the H phasors and accumulators double the volume-DFT storage.
|
|
482
|
+
- FDTD run records for consumers of the volume fields: `Result.stats()` gains `dft_window_requested`, `last_step_field_ratio` (per DFT frequency, the end-of-record term of the volume E phasor relative to the phasor; a decay metric for pulse records), `bloch_wavevector` (resolved, rad/m, also for `bloch_wavevector="auto"`), `bloch_phase` (per-axis wrap phase `exp(i k L)`) and `tfsf` (snapped TFSF node indices and the H blocks the update corrects). `mw.fdtd.tfsf_h_mask(result)` returns per-H-component boolean masks that are `False` at the TFSF-corrected H samples. FDTD `Result.fields` `FieldData` carry `attrs["field_time_offset_steps"] = 0.0` (the field after step `m` is weighted at `t = m*dt`). `docs/reference/fdtd-typed-results.md` states the `Result.fields` guarantee: raw Yee volume-DFT phasors on the full computational grid (absorber layers included), float64 coordinates, values that are views of the stored phasors, and the periodic/Bloch wrap plane.
|
|
483
|
+
- Physics-typed result data in the new `witwin.maxwell.results` package: the base `TensorData` and `FieldData`, `FluxData`, `ModeAmplitudeData`, `SParameterData` and `FarFieldData` (exported at the top level). Each wraps one torch tensor with named `dims`, per-dimension `coords` (1-D SI tensors moved to the values' device, or unique string labels such as field components and port names), `units` and read-only `attrs`. `sel(...)` (by coordinate value or label, exact or `method="nearest"`), `isel(...)` (by position) and `to(device)` are torch indexing and transfer operations, so gradients flow through them; `to_xarray()` returns a detached host `xarray.DataArray` and needs the optional `xarray` package (new extra `witwin-maxwell[xarray]`). Each type fixes its dimension order (`FieldData` `("component", "f", "x", "y", "z")`, `FluxData` `("f",)`, `ModeAmplitudeData` `("mode", "propagation", "f")`, `SParameterData` `("f", "out_port", "in_port")`, `FarFieldData` `("f", "theta", "phi", "component")` or `("f", "ux", "uy", "component")`) and admits any order-preserving subset. Solver results do not return these types yet.
|
|
484
|
+
- `FarFieldData` admits a third layout, `("f", "direction", "component")`, for far fields over an arbitrary list of unit directions: the `direction` coordinate is the index `0..D-1` and `attrs["ux"]`, `attrs["uy"]`, `attrs["uz"]` hold the unit vectors (1-D, one entry per direction, on the values' device, checked to be unit length within `64*eps(float32)` when constructed; selections and transfers of validated data skip the check and never synchronise with the device). `isel`/`sel` on `direction` select the vectors with the values (an integer leaves 0-d tensors), `to(device)` moves them and `to_xarray()` exports them as non-dimension coordinates along `direction`. `FarFieldData.from_directions(values, directions, f, components, units, attrs=None)` builds it from a `[D, 3]` direction tensor.
|
|
485
|
+
- `witwin.maxwell.results.field_component_units(components)` returns `(units, component_units)` for field component labels (`E*` in V/m, `H*` in A/m): `units` is the shared unit or `"mixed"` when E and H components mix, and producers store `component_units` (`{label: unit}`) in `attrs["component_units"]` in both cases; a `FieldData` with `units="mixed"` requires it. FDFD `Result.fields` and point `FieldProjection` observations now carry `attrs["component_units"]` (values and `units` unchanged).
|
|
486
|
+
- `NetworkData.s_parameters` returns the scattering matrix as `SParameterData` (the `s` tensor itself, `out_port`/`in_port` labelled by `port_names`, `z0` and the conventions in `attrs`). `NetworkData.s` stays the `[frequency, out, in]` tensor.
|
|
487
|
+
- `mw.capabilities(method)` returns the read-only capability table of a method (`"fdtd"`, `"fdfd"`, `"mom"`, `"mom.layered"`, `"electrostatic"`, `"capacitance"` or a `SimulationMethod`): feature key -> `Capability(key, support, reason, alternative, negative_tests)` with `support` one of `Support.SUPPORTED`, `UNSUPPORTED`, `INHERENT`. `Simulation.check()` and `check()` on the electrostatic/capacitance runners return a `CapabilityReport` (`supported` keys, `unsupported` items, `raise_if_unsupported()`) without raising.
|
|
488
|
+
- Field-consumption manifest (`witwin.maxwell.capability.fields`): every public scene class and constructor field declares how each method treats it, in the registry vocabulary: read (`SUPPORTED`), refused through a registry row (`UNSUPPORTED`/`INHERENT` with the deciding key), deliberately not read where it has no meaning (`INHERENT` with a reason), or neutral (names, tags, metadata, device). `consumption(cls)` resolves the per-method cells through owner keys and containing fields. A test fails on any public class or field without an entry, and pins the open gaps (fields a method admits and drops: the layered-MoM inputs that api070/p2c refuses, and Kerr/chi2/TPA, `DielectricBreakdown` and `PerturbationMedium` shifts in the electrostatic and capacitance solves).
|
|
489
|
+
- The capability vocabulary is public in `witwin.maxwell.capability`: `METHODS` (the method names `capabilities()` accepts), `SCENE_KEYS`, `CONFIG_KEYS` and `FEATURE_KEYS` (every key a table decides). `scripts/dev/capability_tables.py` generates `docs/reference/capability-registry.md` (every row of every method table), `docs/reference/scene-field-consumption.md` (the field manifest) and the registry tables in the FEATURE_LIST FDFD, Known Limitations, MoM and electrostatics sections, the gradient capability matrix (registry trainable-input rows and the native adjoint inventory) and the guard census (registry rows of the moved refusals); `--write` regenerates them, and a test fails when any of them drifts from the registry.
|
|
490
|
+
- Domain exception hierarchy in `witwin.maxwell.errors`, exported at the top level: `MaxwellError` (the common base), `UnsupportedFeatureError` (also a `NotImplementedError`; carries `.feature`, `.method`, `.alternative` and `.items`), `SetupError` (also a `ValueError`), `ConvergenceError` (also a `RuntimeError`), `SchemaError` (also a `ValueError`) and `CapacityError` (also a `MemoryError`); and the warning bases `MaxwellWarning` (a `UserWarning`) and `ExperimentalWarning` (a `MaxwellWarning`). `except mw.MaxwellError` catches every family; `warnings.filterwarnings(..., category=mw.MaxwellWarning)` selects every package warning.
|
|
491
|
+
- `mw.__version__` reports the package version (`"0.6.0"` until the 0.7.0 release bump); it is a static string in `witwin/maxwell/_version.py`, so source checkouts without installed metadata report it too. A test keeps it equal to `pyproject.toml` `version`, so a release bump edits both files.
|
|
492
|
+
- The package ships a PEP 561 `py.typed` marker (`witwin/maxwell/py.typed`) in the wheel and the sdist, so type checkers read the inline annotations of `witwin.maxwell`.
|
|
493
|
+
- Layered MoM `Result.metadata` and `Result.network.metadata` gain `thickness_modelled_geometrically` (`False` for `conductor_model="sheet"`, `True` for `"closed"` and `"surface_admittance"`).
|
|
494
|
+
- Stability markers (`witwin/maxwell/_stability.py`): every public object is stable unless marked experimental; an experimental object carries `__stability__ == "experimental"` and warns once per process on first outside use (see Breaking changes). `docs/reference/public-api.csv` lists every public object with its namespace, kind, stability and the first release that exported its name (`since`); `scripts/dev/public_api.py` generates it and the FEATURE_LIST API Stability table from the live namespace `__all__`s, and a test fails when either drifts. `ModeSource`, `ModeMonitor`, `ModePort`, `TFSF`, `LumpedPort` and `AxisPath`, labelled experimental in 0.6.0, are stable.
|
|
495
|
+
- Layered MoM frequency-dependent layer dielectrics: `Layer`/`HalfSpace` `eps_r` accepts a causal model, `mw.media.WidebandDebye(eps_inf, delta_eps, f1, f2)` (wideband Debye, also `WidebandDebye.from_loss_tangent(eps_r, tan_delta, frequency)`) or `mw.media.PolePermittivity(eps_inf, poles)` over the existing Debye/Drude/Lorentz poles (`PolePermittivity.from_material(...)` adapts a fitted `Material`). The layered Green tables evaluate the model per frequency; non-passive parameters are refused. Constant layers are unchanged.
|
|
496
|
+
- Layered MoM edge ports: `LumpedPort.voltage_aperture` is applied by layered MoM. The delta-gap bridge spans the aperture's transverse width instead of `bridge_width_m`, so the port voltage is the same on every parallel path and the port current is the total current over the full edge. This matches the FDTD meaning of `voltage_aperture` (voltage distributed over parallel paths, one port current); FDTD behaviour is unchanged. `witwin.maxwell.mom.layered.port_system.edge_port(scene, name, signal=, side=, reference=)` builds full-width edge ports with an explicit ground reference: a named coplanar conductor (horizontal), the stack PEC plane (`"pec_bottom"`/`"pec_top"`, vertical) or a conductor on the adjacent metal plane (vertical inter-layer). `conductor_model="closed"` refuses aperture ports. `Result.metadata["ports"]` and `Result.network.metadata["ports"]` record each port's type, orientation, positive conductor, reference, width, length and voltage/current definitions. `PortPair` and `mixed_mode(network, pairs)` give differential/common-mode pairs.
|
|
497
|
+
- Layered MoM device-parameter extraction (`witwin.maxwell.mom.layered.extraction`): L, R, Q (one-port and differential), M, k, self-resonance, peak Q, per-frequency pi/T models, a closed-form T fit and a nine-element pi fit, all PyTorch-native and differentiable through the layered network gradients.
|
|
498
|
+
- Layered two-line transmission-line characterization (`witwin.maxwell.mom.layered.deembed.line_parameters`): propagation constant, effective permittivity and two-line impedance from two line lengths.
|
|
499
|
+
- Layered MoM H-matrix backend: `LayeredSurfaceConfig(operator_backend="hmatrix")` is the matrix-free backend with the far interactions compressed once per frequency (per-plane cluster trees, lateral admissibility that keeps every near pair exact, adaptive cross approximation sampled with the dense kernels, symmetric storage, deterministic native action). An a-posteriori compression bound on the admittances must stay below 1e-5 and is recorded in `Result.network.metadata` with rank and storage statistics; `hmatrix_exact_check=True` adds one exact far action per solve. Measured |dY|/|Y| against dense <= 1.7e-6 (F-A, F-B, closed F-A, 1 kHz-100 GHz); the 27k/37k/44k-RWG F-B meshes solve with 2.2/3.1/3.8 GB of compressed storage.
|
|
500
|
+
- Layered MoM body-aware preconditioner: on closed conductor bodies the matrix_free and hmatrix backends add every same-body face pair within three cells to the near-field sparse-LU preconditioner, so thin conductors are preconditioned across their thickness (closed F-A fine: 30/39/60/77 -> 16/22/30/36 GMRES steps); the admittances are unchanged.
|
|
501
|
+
- Layered MoM polygon layouts: non-Manhattan `PlanarPEC` polygons with holes, z-axis `Prism` vias and vias that pass or land on an intermediate metal plane mesh with a deterministic conforming planar triangle mesher (`LayeredSurfaceConfig(planar_mesher="auto"|"triangle")`); Manhattan layouts keep the rectangle mesher bit for bit. `Result.network.metadata` records the mesher, its quality report and a sha256 mesh hash. Polygon layouts run on the dense, matrix_free and hmatrix backends and accept `voltage_aperture` edge ports (the C1 edge-port rules applied to the polygon metal union); the body-aware preconditioner keeps the plain near pattern on them. GDS import (`ProcessStack.scene_from_gds`) accepts 45-degree polygons and multi-plane vias.
|
|
502
|
+
- New optional extra `rfic` (`pip install witwin-maxwell[rfic]`: `shapely>=2.1`, `gdstk>=1.0.1`) for the layered MoM polygon layouts and the layered GDS import. Without it those paths raise an `ImportError` that names the extra; Manhattan layouts and every other path need neither package.
|
|
503
|
+
- Layered MoM `conductor_model="surface_admittance"` (experimental): each lossy body becomes its differential surface admittance, with a uniform-current low-frequency regime below t/delta = 0.3, the surface-admittance block above 0.6 and a smooth blend between, so the DC resistance is exact and weak and strong skin effect are covered; port bridges are ideal PEC blocks, and a `voltage_aperture` edge port is an aperture-wide PEC block flush with the terminal sidewalls. The inductance of the 20/2 um strip loop agrees with a true-corner reference to 0.45% from 1 MHz to 10 GHz. The matrix_free and hmatrix backends fold each body's admittance block into their near operator and preconditioner (memory grows with the square of the largest body's exterior basis count). Roughness, different-conductivity contacts, bodies crossing dielectric interfaces and gradients are refused.
|
|
504
|
+
- Layered MoM mm-wave vertical Green tables: a vertical table that misses the 1e-6 z gate is rebuilt with graded z segments toward each dielectric interface (one adaptive loop; a table that admits ungraded is unchanged bit for bit), so vertical ports, vias and grounded bridges admit up to 200 GHz. Wall meshes follow the graded segments; `Result.network.metadata["vertical_z_grading"]` records the grading. A table that still fails after five grading levels raises `ConvergenceError`.
|
|
505
|
+
|
|
506
|
+
## [0.6.0] - 2026-11-08
|
|
507
|
+
|
|
508
|
+
Full details, evidence and migration notes are in the [0.6.0 release notes](docs/reference/release-notes-0.6.0.md).
|
|
509
|
+
|
|
510
|
+
### Breaking changes
|
|
511
|
+
|
|
512
|
+
- **The surface-integral solver is renamed from SIE to MoM.** The old names are removed; there are no deprecated aliases.
|
|
513
|
+
|
|
514
|
+
| 0.5.1 | 0.6.0 |
|
|
515
|
+
|---|---|
|
|
516
|
+
| `Simulation.sie(...)` | `Simulation.mom(...)` |
|
|
517
|
+
| `SimulationMethod.SIE` (value `"sie"`) | `SimulationMethod.MOM` (value `"mom"`) |
|
|
518
|
+
| `SIEConfig` | `MoMConfig` |
|
|
519
|
+
| `SIEPeriodicConfig` | `MoMPeriodicConfig` |
|
|
520
|
+
| `SIEDyadicPeriodicConfig` | `MoMDyadicPeriodicConfig` |
|
|
521
|
+
| `witwin.maxwell.sie.*` (including `SIERuntime`) | `witwin.maxwell.mom.*` (`MoMRuntime`) |
|
|
522
|
+
| `Result.method == "sie"` | `Result.method == "mom"` |
|
|
523
|
+
| native op namespace `witwin_maxwell_sie_layered` | `witwin_maxwell_mom_layered` |
|
|
524
|
+
| `WITWIN_MAXWELL_SIE_LAYERED_BUILD_DIR` | `WITWIN_MAXWELL_MOM_LAYERED_BUILD_DIR` |
|
|
525
|
+
| periodic payload ids `sie_bravais_ewald_config_v1`, `sie_bravais_dyadic_config_v1` | `mom_bravais_ewald_config_v1`, `mom_bravais_dyadic_config_v1`; periodic results saved under the old ids do not restore |
|
|
526
|
+
|
|
527
|
+
- Result snapshots and metadata written with the old method name, layered ABI tag or other renamed schema strings are not restored. The surface-integral formulation identifiers (`pmchwt_scalar_sie`, `anisotropic_dgf_sie`, `coupled_sie_vie_*`) are unchanged.
|
|
528
|
+
- Downstream consumers importing `witwin.maxwell.sie` must move to `witwin.maxwell.mom`.
|
|
529
|
+
|
|
530
|
+
### Changed (defaults and behavior; recompute affected cached results)
|
|
531
|
+
|
|
532
|
+
- **FDTD execution defaults to `fdtd_core_path="auto"` and `accelerated_setup="auto"`.** In 0.5.1 both were off.
|
|
533
|
+
- Eligible single-GPU float32 forward scenes now run on the fused CUDA core path, with CUDA material and coefficient setup.
|
|
534
|
+
- Scenes with an admission blocker keep the existing stepping. So do resume, non-initializing preparation and material-cache runs. The first automatic fallback in a `Simulation` warns once with the public `FDTDCoreFallbackWarning`.
|
|
535
|
+
- If core activation or graph capture fails under `"auto"`, the run is rebuilt on the existing path.
|
|
536
|
+
- `Result.stats` and `Result.metadata` report `execution_path` (`"core"` or `"existing"`) and `fallback_reason`.
|
|
537
|
+
- Explicit `True` stays fail-closed: it raises for an ineligible scene. Explicit `False` keeps the existing path and does not warn.
|
|
538
|
+
- PMC boundaries keep the existing path, including PMC symmetry planes. So does closed-transverse CPML, which runs under the passivity guard.
|
|
539
|
+
- On the 121-scene release census, every FDTD scene's monitors are bitwise equal to the run with both controls `False`.
|
|
540
|
+
- Validated on A6000 (sm_86) only. Other architectures may differ at rounding level.
|
|
541
|
+
- Migration: pass `fdtd_core_path=False, accelerated_setup=False` to reproduce the 0.5.1 execution path. Use the `warnings` filters to silence or escalate `FDTDCoreFallbackWarning`. Code that inspects `prepared.solver` internals should check `execution_path` first.
|
|
542
|
+
- Default material sampling is `SubpixelSpec(samples=4, averaging="kottke_edge", pec="staircase")` (was one arithmetic sample). Trainable geometry requires `averaging="kottke_smooth"` (experimental) or `"polarized"`; trainable `MaterialRegion` densities require `samples=1, averaging="arithmetic"`; both fail closed otherwise. Pass `SubpixelSpec(samples=1, averaging="arithmetic", pec="staircase")` to recover 0.5.1 sampling.
|
|
543
|
+
- Structures that reach a PML interface and are prismatic there are continued through the PML along the face normal at preparation (FDTD and FDFD). The public `Scene` is not modified, and the extrusions are recorded as `pml_extrusions` in the prepared metadata and solver statistics. Mesh volumes, non-prismatic contacts and surface-impedance conductors (`LossyMetalMedium`, `SurfaceImpedanceMedium`, `CopperFoil`) are not extruded and warn; zero-volume sheets are only recorded. Results move only for scenes with such contacts. In the benchmark suite, 10 rows moved and none got worse; for example, `dielectric_slab` field L2 against the reference fell from 0.569 to 0.041. All other scenes are bitwise unchanged. Nonlinear structures flush with the PML now behave as infinite structures: for example, a Kerr slab's nonlinear phase shift went from 2.63e-3, an edge artefact, to 8.56e-4, which matches the infinite-slab prediction. A PEC structure and a surface-impedance conductor declared on the same face still fail closed.
|
|
544
|
+
- FDTD phasors use physical Yee time labels: post-step E at (n+1)Δt and H at (n+1/2)Δt.
|
|
545
|
+
- Compared with 0.5.1, raw field and port phasors rotate by exp(iωΔt). Source-normalised additive-current and direct-drive phasors rotate by exp(iωΔt/2), and uncompensated magnetic, sheet and analytic-pulse phasors by exp(iωΔt). Auxiliary-line and CW references are unchanged to rounding.
|
|
546
|
+
- Same-frequency S/Z/Γ, flux, matched field/port powers and directivity are unchanged.
|
|
547
|
+
- Field-time monitor `t` advances by one Δt; the values are unchanged.
|
|
548
|
+
- Resume checkpoints use format 6. Checkpoints with the earlier spectral convention need a fresh run.
|
|
549
|
+
- Additive electric currents (`PointDipole`, `UniformCurrentSource`, electric `CustomCurrentSource`) are injected at (n+1/2)Δt and normalised at their own injection instant. Raw port V/I and Z/Γ are unchanged; source-normalised spectra carry the half-step phase. Checkpoints with additive electric currents written before this change are refused on resume.
|
|
550
|
+
- Raw (non-source-normalised) pulsed absolute spectra are scaled per reference period instead of averaged over the record length, including single-frequency runs; with `reference_frequency=None` the period is taken per output frequency, so multi-frequency raw outputs also move off the centre frequency. Source-normalised results and all ratios (S, Z, Γ, power closure) are unchanged. Migration: absolute pulsed powers from 0.5.x differ by (f·T_record)²-type factors; compare ratios or recompute. Pass an explicit `reference_frequency` for the fixed-period convention. Absolute spectral reads that mix ongoing and transient drives without source normalisation are refused.
|
|
551
|
+
- Explicit `full_field_dft=False` is honoured for multi-frequency runs; volume-field reads and automatic electric power-loss channels then raise.
|
|
552
|
+
- Pulsed TFSF incident waves are referenced at the physical upstream entry plane, so absolute incident phase no longer depends on absorbing-layer padding. Older pulsed-TFSF checkpoints are refused on resume.
|
|
553
|
+
- Raw TFSF incident timing is exact on the Yee clock: auxiliary-line entry E uses the waveform at (n+1)Δt and analytic/discrete CW faces keep their physical J/M instants; normalisation references follow each provider. Migration: finite-record source-normalised TFSF values shift by up to ~1e-3 for pulses and ~1e-2 for real CW on short records; recompute affected cached results. TFSF checkpoints written before this change are refused on resume.
|
|
554
|
+
- The pulsed TFSF auxiliary line keeps its whole sampled extent lossless and ends in a 320-cell absorber appended beyond it. Previously its last 20 sampled cells formed a graded ramp, which reflected near-band-edge content and trapped a slowly decaying mode. In-band benchmark results agree with the old termination to 3–4 digits. Checkpoints with an auxiliary TFSF line written before this change are refused on resume.
|
|
555
|
+
- Complex fixed-k Bloch runs use a complex-frequency-shifted CPML by default; `cpml_config={"alpha_max": 0.0}` pins legacy coefficients for short runs. Real-field, k=0 and non-Bloch paths are unchanged.
|
|
556
|
+
- Fixed-k Bloch runs accept pulsed TFSF-slab plane waves (see Added). They still refuse pulsed beams, mode and custom-field sources and soft plane waves; use one CW source per frequency for those. Point and current sources may be pulsed.
|
|
557
|
+
- FDFD: PML now absorbs (frequency-domain form of the FDTD CPML); `PointDipole` uses the FDTD unit control-volume current moment; Yee-edge material components and exp(-iωt) loss sign are aligned with FDTD; FDFD refuses scene monitors it cannot populate and propagates solver failures.
|
|
558
|
+
- Other default-path numerics: high-side magnetic CPML grading at physical half points; CopperFoil free-edge impedance on by default (`edge_model="none"` for the legacy rim) and compressed passive diffusion fits; node-consistent staircase PEC; second-order multi-sample averaging on resolved Yee spacing; full-moment narrow Gaussian dipoles; periodic dipole image folding; watertight closed-surface monitors; `TwoPhotonAbsorption` conductivity factor 2/3; Yee-edge bulk conduction loss.
|
|
559
|
+
- Trainable fixed controls (frequencies, time/grid/sampling controls, monitor geometry, topology) and port probe gaps fully covered by PEC are rejected up front.
|
|
560
|
+
- Native CUDA extension ABI is `stable_abi_v13`; older prebuilt binaries are rejected and rebuilt. `WITWIN_MAXWELL_FDTD_CUDA_PREBUILT=1` now requires a matching ABI marker. The core-path extension (`core_abi_v11`) and the setup extension (`setup_abi_v6`) are compiled on first use.
|
|
561
|
+
- Requires `witwin>=0.4.6,<0.5`. In earlier witwin-core releases, micrometre-scale geometries were over-smoothed by about 3 cells, because the geometry smoothing width was clamped to 1.19e-7 m whatever the cell size. Optimisation results and forward fluxes change materially for µm-scale scenes (bend example: +37.7% initial flux, gradient cosine 0.85). Scenes whose smallest cell is ≥ ~2.4 µm are unchanged bit for bit. Point-like occupancy queries without coordinate spacing must now pass an explicit beta in metres (ValueError otherwise).
|
|
562
|
+
- `Simulation.fdtd(absorber="auto")` is the default.
|
|
563
|
+
- Real-field cells with closed transverse walls (periodic, PEC or PMC) and PML on the normal axis select the graded `absorber`. It needs at least 40 layers on every PML face; thinner layers raise a `ValueError` that names the closed axes, the deficient faces and both remedies.
|
|
564
|
+
- Open scenes and complex fixed-k scenes keep CPML.
|
|
565
|
+
- Explicit `absorber="cpml"` in a closed-transverse real-field cell runs under a fail-closed passivity guard (`FDTDPassivityError`). In a complex fixed-k cell the guard only warns: it emits a `RuntimeWarning` and records the measured slope in `passivity_guard` metadata. Non-finite energy fails closed everywhere.
|
|
566
|
+
- Results record `absorber`, `absorber_resolution_reason` and `passivity_guard`.
|
|
567
|
+
- FP64 native forward resolves `"auto"` the way preparation does. It runs when `"auto"` resolves to CPML, and keeps its CPML-only refusal otherwise.
|
|
568
|
+
- Closed-transverse CPML stays on the existing execution path, where the guard runs.
|
|
569
|
+
- Migration: scenes that relied on the CPML default in such cells have two options. Pass `absorber="cpml"`: the numerics are unchanged and the run is now guarded. Or configure at least 40 layers: the results then come from the graded absorber.
|
|
570
|
+
|
|
571
|
+
### Fixed
|
|
572
|
+
|
|
573
|
+
- Soft equivalent-sheet plane waves launch +E_inc (absolute fields of soft plane-wave scenes previously had the wrong sign).
|
|
574
|
+
- Soft plane-wave and beam launch currents are no longer written into inactive electric wall rows (transverse none/PML/PEC walls), which removes a linear late-time growth of the corner H field.
|
|
575
|
+
- Conformal thin-sheet rims split faces only for chords inside the outline (removes a 4-7% low resonance bias).
|
|
576
|
+
- Custom J/M sources deposit over the Yee control-cell overlap with the declared dataset volume; custom-field sources deposit on bracketing Yee sheets with fractional aperture.
|
|
577
|
+
- Time modulation uses a device integer step counter with FP64 phase and an effective-medium partial-cell coefficient.
|
|
578
|
+
- Fixed-k Bloch: Floquet TE/TM readout with power-normalised r/t, consistent complex CW conventions with the adjoint, single deposition of periodic TFSF faces, PEC-face clamping of imaginary fields.
|
|
579
|
+
- Finite thin wires are stable through a passive RL impedance; long RF clocks and TEM phases use float64; lumped/terminal magnetic observers use current into the field; same-step polarization current enters direct lumped/network sampling.
|
|
580
|
+
- Forward source injection is run-to-run deterministic for oblique and interpolated TFSF faces, periodic and Bloch wraps, batched lanes and the core-path periodic wrap (shared cells were previously accumulated with float32 atomics, so repeated runs could differ at about 1e-6 relative). No pinned result moved; oblique TFSF scenes step about 4% slower.
|
|
581
|
+
- Adjoint gradients are run-to-run deterministic for TFSF auxiliary samples, collocated-monitor objectives and coincident point seeds (fixed-order gathers replace float atomics). Density and Box parameter-field material gradients are run-to-run deterministic too: their trilinear sampling uses native kernels whose forward and coordinate gradient are bitwise equal to the previous path, with an ordered texture pullback.
|
|
582
|
+
- Multi-GPU distributed FDTD with periodic or Bloch boundaries: a source term cropped to one GPU's owned x range kept the gather built for the uncropped patch. The injection read past the cropped data, so results depended on leftover device memory, and it routed the remaining planes one cell low. The gathers are now rebuilt after the crop. For example, a uniform current source straddling the seam between GPUs was off by 4.84 and now matches the single-device result. Distributed path only; the single-GPU default path is unaffected.
|
|
583
|
+
- Micrometre-scale `ModeSource`/`ModePort` launches were refused at prepare ("zero integrated Poynting power"): the zero-power check compared watts with machine epsilon. It and other absolute floors on dimensional quantities (modal power fractions, scattering/diffraction/antenna normalisation, network and port impedance normalisation, observers, TFSF power, source-term pruning, DC port-current admission) are now relative to the same-unit reference, so results do not depend on the length unit.
|
|
584
|
+
- Gradients through trainable material on a `ModeSource`/`ModePort` launch plane are now correct. The adjoint previously differentiated a different (scalar) mode than the one launched and lost the 1/ε injection-coefficient derivative, giving gradients wrong by up to ~7.6× (reference guide, central finite differences on each tree: before, adjoint −18334 vs FD −2417; now, adjoint −2418 vs FD −2425). Trainable lossless launch planes now differentiate via a torch dense vector eigen-solve shared by the forward launch and the adjoint replay (operator n ≤ 4096). Lossy or conductive, near-degenerate and above-cap trainable planes refuse with a named `NotImplementedError`.
|
|
585
|
+
- Dispersive interfaces under the `kottke_edge` default: each Yee component edge takes one constituent's complete pole set (binary ownership) for piecewise-constant pole media, including exactly uniform custom pole fields; spatially graded pole media and the gradient subpixel modes keep fractional pole weights; float32-declared box faces snap to grid planes within their declaration rounding. Replaces the fractional-ADE interface error in dispersive scatterers; sphere cross sections converge toward the analytic Mie solution under refinement.
|
|
586
|
+
|
|
587
|
+
### Added
|
|
588
|
+
|
|
589
|
+
- Broadband fixed-k TFSF: pulsed oblique TFSF-slab plane waves under fixed-k Bloch boundaries. They are driven by a complex 1D Yee incident line with the grid's discrete transverse wavenumber, normal spacing and time step. `Result.metadata["tfsf_incident_reference"]` exports the incident electric spectrum at the lower TFSF plane, so `reflection_transmission(result, ...)` needs no separate incident run. Checkpoint/resume is supported.
|
|
590
|
+
- Prepare-time warnings for TFSF and fixed-k incident lines and for source waveforms. They report the share of a non-CW waveform near the incident line's Yee band edge and its DC content, once per hazard above max(1e-6, ε32·√N). Fixed-k lines use their own band edge and drive clock. Waveforms and compiled sources are never altered.
|
|
591
|
+
- Complex fixed-k Bloch lumped loads and ports (R/L/C, series/parallel RLC terminations, checkpoint/resume).
|
|
592
|
+
- Conformal two-sided thin-sheet runtime for tilted and faceted `SurfaceMesh` sheets; experimental conformal-sheet gap feeds.
|
|
593
|
+
- `mw.port_voltage`, `mw.port_phasors`, `Result.port_drive`, `mw.trapezoidal_impedance`; `Result.from_fields`, public `Result.metadata`, `mw.postprocess.plane_payload`, FDFD solver memory limits and `Result.release_solver()`.
|
|
594
|
+
- `Scene.to_dict()` / `Scene.from_dict()` (`witwin.scene/1`).
|
|
595
|
+
- Opt-in `averaging="kottke_smooth"` differentiable subpixel mode (experimental) and FDTD-only `averaging="polarized_tensor"`.
|
|
596
|
+
- Experimental `BendCoordinates`, inverse-design toolkit `witwin.maxwell.invdes`, PCB/printed-line workflows (`CopperFoil`, `PlanarPEC`, `TerminalPort`, PCB scene import, good-conductor and quasi-TEM modes), experimental coaxial/terminal-wave ports and modal port sweeps, Mur/`ModeABC`/`InternalAbsorber`, PMC, dispersion fitting and a material library, opt-in surface roughness, boolean geometry and STL meshes, grid refinement specs, broadband/table source times, projection and time monitors, `FieldProjector`, resonance finder and array-factor tools, FDFD multifrequency/graded grids/GPU local responses.
|
|
597
|
+
- Batch material reuse: density templates reuse a fixed material bank and recompile only changed patches.
|
|
598
|
+
- Surface integral equations (`Simulation.mom(...)`, PMCHWT with dense/hierarchical/FMM/pFFT backends, open-sheet PEC EFIE, preconditioners). Experimental; development is paused.
|
|
599
|
+
- Experimental layered-media MPIE MoM network solver for planar RF/IC passives: `Scene(background=LayerStack(...))` with `PlanarPEC` sheets and `LumpedPort` terminals, `Simulation.mom(scene, frequencies=[...], config=MoMConfig(layered=...))` returns `Result.network`. It includes vias and vertical ports, thin-sheet conductor loss, a low-frequency loop-tree solve, GDS import and an adaptive rational sweep. Its inductance and Q-peak accuracy targets are strict expected failures.
|
|
600
|
+
|
|
601
|
+
### Performance
|
|
602
|
+
|
|
603
|
+
All timings are on an A6000 (sm_86).
|
|
604
|
+
|
|
605
|
+
- **Default core path.** 96 of the 121 release-census scenes take the core path under `"auto"`.
|
|
606
|
+
- On those scenes, whole-call time (prepare and run, cold processes) fell from 670.5 s to 318.9 s (−52.4%). The run-only median speedup is 1.37×.
|
|
607
|
+
- On the FDTD scenes that keep the existing path, whole-call time fell from 296.4 s to 236.6 s through accelerated setup.
|
|
608
|
+
- Fused single-GPU float32 stepping has one magnetic and one electric launch per step and graph capture in 32-step chunks. It covers absorbing, PEC and periodic boundaries, generic sources and monitors, RF ports, lumped elements, wires, networks, CopperFoil, thin sheets, SIBC, and dispersive, nonlinear and modulated media.
|
|
609
|
+
- On slab-CPML and no-PML cubes from 128³ to 384³, step time is within 1.025–1.107× of the Yee memory-traffic floor.
|
|
610
|
+
- Core TFSF auxiliary-line corrections are fused with their auxiliary updates (core ABI v11). On the 256³ TFSF row this cuts launches from 42 to 8 per step. Step time falls by 39.8% at 64³, 11.5% at 128³ and 1.9% at 256³.
|
|
611
|
+
- Further core-path cuts:
|
|
612
|
+
- Redundant PEC clamp launches are omitted: −7.2% at 128³ and −4.2% at 256³ on PEC rows.
|
|
613
|
+
- Observer gathers use one launch per batch of up to 16 groups.
|
|
614
|
+
- The Yee block order is L2-aware: the 384³ slab row went from 1.148× to 1.085× of the byte floor.
|
|
615
|
+
- Each auxiliary TFSF step is evaluated once during setup.
|
|
616
|
+
- Point-monitor setup and readout are batched, and run with cyclic garbage collection paused. On a 16,384-point sample, warm end-to-end core-path time fell from 2.95 s to 1.55 s, then by a further 25–28% with the pause.
|
|
617
|
+
- Accelerated setup admits float64 primitive declarations (Box, Sphere, Cylinder, Pyramid, PolySlab and boolean trees).
|
|
618
|
+
- Fused CopperFoil and conformal thin-sheet CUDA kernels on by default (validated against the torch reference within declared tolerances; the torch path remains the reference and adjoint path); cached, vectorised thin-wire compilation; graph-captured grouped spectral monitors.
|
|
619
|
+
|
|
620
|
+
### Validation
|
|
621
|
+
|
|
622
|
+
- Final integration batch on the release candidate `b6d9e1aa`: all 1291 of 1291 units, 0 infrastructure failures, 33.9 GPU-hours on A6000.
|
|
623
|
+
- 1146 units pass and 74 are incomplete by design.
|
|
624
|
+
- 0 failures are new and unexplained. 19 cases are fixed after the candidate head (one was a default-path wrong result: the surface ownership guard). 111 are pre-existing at the base and 36 are environment or harness cases.
|
|
625
|
+
- Bit identity is T0, and the determinism gates pass: source patch 7 of 7, adjoint 19 of 19, nonlinear 4 of 4.
|
|
626
|
+
- Details are in the release notes.
|
|
627
|
+
- Two-device tier, both RTX A6000s:
|
|
628
|
+
- The full multi_gpu suite gave 401 passed and 1 failed on the release candidate. The failure was an order-dependent distributed periodic-source parity case, the distributed source-crop bug fixed above.
|
|
629
|
+
- With the fix, the full suite passes 405 of 405 (402 existing tests plus 3 new regression tests). The failing case also passes in the suite order that used to trigger it.
|
|
630
|
+
- Bit-identity pin files are unchanged (33 of 33 in each of 8 files).
|
|
631
|
+
- Determinism gates pass.
|
|
632
|
+
- The layered RFIC MoM solver merged after the batch. It was validated by its own gates, not by the integration batch.
|
|
633
|
+
|
|
634
|
+
### Deprecated / planned
|
|
635
|
+
|
|
636
|
+
- 0.6.0 is intended to be the last release that keeps the slower runtime paths as execution options. In 0.6.0, the existing stepping path is the fallback for `"auto"` and the path for explicit `False`.
|
|
637
|
+
- After 0.6.0, the CUDA core path and accelerated setup are intended to become the only execution path.
|
|
638
|
+
- The CPU backend and the torch reference kernels are intended to remain only as test oracles.
|
|
639
|
+
- Torch autograd paths remain until CUDA gradients are qualified.
|
|
640
|
+
|
|
641
|
+
### Limitations
|
|
642
|
+
|
|
643
|
+
Known defects are documented with magnitude, scope and workaround in the release notes; they do not block the release.
|
|
644
|
+
|
|
645
|
+
- The automatic core default and its performance figures are validated on A6000 (sm_86) only. The L2-based Yee block-order threshold is calibrated only there. Pass `fdtd_core_path=False` on other architectures if you need the existing path.
|
|
646
|
+
- Second-order nonlinear (chi2) media run on the core path under `"auto"` and pass their physics tests there (second-harmonic scaling and phase matching), but have no core-vs-existing equality check. Dispersive (electric and magnetic), Kerr, two-photon absorption, time modulation, their compositions and deterministic breakdown are bitwise equal to the existing path. Pass `fdtd_core_path=False` for chi2 scenes that need the qualified existing path.
|
|
647
|
+
- Without a CUDA toolkit (a pip install with no `nvcc`/`CUDA_HOME`), `"auto"` runs complete on the existing path with one `FDTDCoreFallbackWarning`. The first warning names the missing toolkit. Later `Simulation`s in the same process, and the recorded `fallback_reason`, instead report a missing setup-extension shared object. This is cosmetic and is fixed in 0.6.1.
|
|
648
|
+
- The core path does not run these, which keep the existing path under `"auto"`:
|
|
649
|
+
- Bloch or complex fields;
|
|
650
|
+
- PMC (including symmetry planes), Mur and mode-ABC boundaries;
|
|
651
|
+
- closed-transverse CPML;
|
|
652
|
+
- gyromagnetic media, full anisotropy, magnetic permeability or magnetic conductivity;
|
|
653
|
+
- coordinate charts;
|
|
654
|
+
- gradient-requiring scenes;
|
|
655
|
+
- batch lanes, multi-GPU and non-float32 fields.
|
|
656
|
+
- Thin-wire port Z_in/S11 does not converge under refinement (Richardson ratio median 0.75); do not use it for quantitative results. Fix targeted for 0.6.1.
|
|
657
|
+
- Curved or tilted thin copper: finite-edge response low by about 4–7% (no qualified workaround; validate against a refined grid); driven conformal-sheet antennas on tilted/curved sheets follow the rim staircase (about 2% at λ/40).
|
|
658
|
+
- Oblique TE under fixed k: 35° transmission within 4.43% against a 3% gate with the default CFS-CPML profile; no qualified workaround (a smaller α is not passive at steep angles).
|
|
659
|
+
- Under fixed k, beams, mode and custom-field sources and soft plane waves are CW only. The pulsed `bloch_oblique` benchmark rows stay quarantined in this release's validation suite.
|
|
660
|
+
- Fixed-k TFSF reports incident phase relative to its incident-line reference; absolute phase is planned for 0.6.1.
|
|
661
|
+
- MoM: hierarchical and FMM configurations with `stopping.rtol` above 0.1 × `solve_dual_tolerance` raise `ValueError` (unchanged from the previous release base); set `stopping.rtol` at or below that bound.
|
|
662
|
+
- MoM FMM and dense-reference solves are not yet bitwise run-to-run reproducible (repeated runs differ by up to about 1e-14 relative in dense-reference currents and about 1e-10 relative in FMM currents); a tolerance-sensitive test can fail intermittently.
|
|
663
|
+
- Benchmark rows with a reference-convention difference also fail against the external reference: nine sign or absolute-phase rows (field L2 near 2, shape L2 ≤ 0.15), three source-gauge rows, custom_grid_slab (L2 0.120 against 0.1) and ricker_axis_x_anisotropic (reference waveform export). See the release notes.
|
|
664
|
+
- Ten benchmark scenarios keep an unresolved residual against the external reference solver and are reported on every run, including custom_field_source, modulated_slab(_phase) and mode_port_straight_wg (see release notes).
|
|
665
|
+
- Real-field periodic or closed-transverse cells can show late-time CPML growth; `absorber="auto"` therefore selects the graded absorber there (at least 40 layers), and explicit `absorber="cpml"` in these topologies runs under the passivity guard.
|
|
666
|
+
- The CPML passivity guard does not detect growth slower than 4e-7 per step (about 1.5× energy over 1e6 steps). Complex fixed-k (oblique Bloch) CPML can grow both inside and well above that band. Measured at 160 cells per wavelength, f0 = 1 GHz, k0 = 2π f0 / c:
|
|
667
|
+
- Below the band: 2.1e-7 per step (about 1.23× per 1e6 steps) in a point-dipole εr = 4 slab cell.
|
|
668
|
+
- Near the band: 3.5e-7 to 5.0e-7 per step in εr = 4 TM CW records at 1.1 f0 and at 20° incidence. 7.0e-7 to 7.5e-7 per step in the vacuum TM CW arm at k_par = 0.25 k0, 0.9 f0.
|
|
669
|
+
- Slab-guided mode: 8.2e-7 per step late in a CW record of an εr = 4 TM slab at k_par = 0.25 k0, 0.9 f0. Here a slab-guided TM mode below the light line grows in the CPML.
|
|
670
|
+
- About 10× larger, in vacuum TM records:
|
|
671
|
+
- 7.7e-6 per step in the CW arm at k_par = 0.55 k0, 0.9 f0, late in a 136,854-step record.
|
|
672
|
+
- 8.2e-6 per step in a CW record at 20° incidence, 0.9 f0, run with 600 transient cycles. The same case with 300 cycles fits 5.0e-7 per step, so the rate rises late in long CW records.
|
|
673
|
+
- 7.7e-6 ± 1.9e-6 per step in an early window of a 320,000-step pulsed record at k_par = 0.55 k0.
|
|
674
|
+
- The reported acceptance results are unaffected at their existing bounds: pulse/CW parity ≤ 2.5e-4, CW r/t continuity ≤ 1.2e-4, cutoff κ ≤ 8.6e-4.
|
|
675
|
+
- Long fixed-k runs, especially TM runs at larger k_par, should check their energy. Prefer CW per frequency with the default transient, or short pulsed records.
|
|
676
|
+
- For complex fixed-k cells the guard warns once, records the measured slope, standard error and window in `passivity_guard_warning`, and lets the run finish. It is fail-closed only for real-field closed-transverse cells; non-finite energy fails closed everywhere.
|
|
677
|
+
- The passivity guard does not run on closed-transverse CPML scenes that contain CopperFoil or thin sheets.
|
|
678
|
+
- These scenes report `passivity_guard = "skipped: energy storage not counted (CopperFoil, thin sheets)"` and warn.
|
|
679
|
+
- Sampling their counted energy every 32 steps costs 39–133% of a step, and sparser sampling false-trips.
|
|
680
|
+
- Counting is planned for 0.6.1. See `docs/reference/fdtd-cpml.md`.
|
|
681
|
+
- Scenes with dispersive (ADE) or gyromagnetic media, lumped networks, SIBC, thin wires or coaxial elements are also skipped with a `RuntimeWarning`.
|
|
682
|
+
- Conformal PEC (`pec="conformal"`) keeps a curved-body bias and warns at construction; `kottke_edge` is not geometry-differentiable.
|
|
683
|
+
- Resolved volumetric conductors at 2–4 cells per skin depth under the default `kottke_edge` material policy show ±4–8% non-monotone tier sensitivity in absorbed power; use SIBC (`LossyMetalMedium`) for good conductors.
|
|
684
|
+
|
|
685
|
+
## [0.5.1] - 2026-09-08
|
|
686
|
+
|
|
687
|
+
### Added
|
|
688
|
+
|
|
689
|
+
- Experimental `Simulation.batch(...)` execution with reusable capacity-limited CUDA slots, batched field/CPML/source/observer updates, and ordinary owned `Result` objects.
|
|
690
|
+
- Local material compilation reuse, automatic resident capacity, private per-device CUDA allocation budgets, multi-GPU and dual-slot scheduling, and opt-in measured throughput tuning.
|
|
691
|
+
- PyTorch-native Batch checkpoint adjoints for supported density, dielectric geometry, and named source-scale inputs, including delayed backward after slot reuse or close.
|
|
692
|
+
- Reproducible Batch performance, memory, material-compilation, and device-scaling audits with numerical controls and process-contention records.
|
|
693
|
+
|
|
694
|
+
### Fixed
|
|
695
|
+
|
|
696
|
+
- Material-aware time-step stability, source timing, complex CPML and Mur boundary histories, and capture/resume state consistency in FDTD.
|
|
697
|
+
- Batch parameter cache identity, iterator ownership, result scene snapshots, selected electric spectra, and redundant spectral allocations in retained adjoint state.
|
|
698
|
+
- Automatic worker capacity distribution and isolation of tuning RNG, module state, and cross-device tensor copies.
|
|
699
|
+
- Corrected the base dependency range to `witwin>=0.4,<0.5`, matching the published `PhysicalMaterial` contract instead of an unavailable version range.
|
|
700
|
+
- Preserved local compilation reuse when declared design replacements acquire new base-package structure/material identity tokens.
|
|
701
|
+
- Declared plotting/progress/notebook display import dependencies and extended release checks to installed-package imports and native Batch allocator exports.
|
|
702
|
+
|
|
703
|
+
### Limitations
|
|
704
|
+
|
|
705
|
+
- Batch remains experimental with a narrower capability set than ordinary FDTD. Fused batch reverse kernels, exact preplanning of all retained outputs, and exclusive multi-GPU throughput acceptance remain pending.
|
|
706
|
+
- See [0.5.1 release notes](docs/reference/release-notes-0.5.1.md) for validation evidence and the supported execution contract.
|
|
707
|
+
|
|
708
|
+
## [0.5.0] - Unpublished
|
|
709
|
+
|
|
710
|
+
- The version tag built CUDA wheels but failed the installed-package import gate because `IPython` was undeclared. No distributions were uploaded to PyPI.
|
|
711
|
+
|
|
712
|
+
## [0.4.0] - 2026-07-23
|
|
713
|
+
|
|
714
|
+
### Added
|
|
715
|
+
|
|
716
|
+
- RF port, network, antenna, phased-array, thin-wire, electrostatic, capacitance, SAR, exposure, ESD, dielectric-breakdown, gyromagnetic, and generalized surface-impedance workflows.
|
|
717
|
+
- Distributed forward and adjoint execution, including CPML-trainable reverse paths and deterministic multi-device scene-gradient aggregation.
|
|
718
|
+
|
|
719
|
+
### Changed
|
|
720
|
+
|
|
721
|
+
- Moved material sampling to native Yee-component locations, improving the geometry validation cluster while changing geometry-resolved numerical baselines.
|
|
722
|
+
- Published one PyTorch Stable ABI CUDA binary per platform for PyTorch 2.10 and newer, load-tested through PyTorch 2.13 and CPython 3.10-3.14.
|
|
723
|
+
- Built Linux wheels against `manylinux_2_28`; Linux and Windows CUDA fat binaries include native SM87 SASS.
|
|
724
|
+
- Made version tags drive the gated package publication and release-artifact workflow.
|
|
725
|
+
|
|
726
|
+
### Fixed
|
|
727
|
+
|
|
728
|
+
- Closed release-blocking CUDA graph, distributed checkpoint, conformal PEC, observer staggering, near-to-far quadrature, modal selection, and surface-impedance correctness gaps.
|
|
729
|
+
|
|
730
|
+
Complete capability boundaries, validation evidence, behavior changes, and known limitations are documented in the [0.4.0 release notes](docs/reference/release-notes-0.4.0.md).
|
|
731
|
+
|
|
732
|
+
## [0.3.0] - 2026-07-13
|
|
733
|
+
|
|
734
|
+
### Added
|
|
735
|
+
|
|
736
|
+
- Native CUDA FDTD adjoint reverse paths for standard and CPML fields, complex Bloch fields, full electric anisotropy, electric conductivity and dispersion, Kerr nonlinearity, TFSF sources, and multi-source workflows.
|
|
737
|
+
- Broadband and arbitrary-normal-axis grating `TFSF.slab(...)`, including pulsed Bloch injection and mixed Bloch/CPML axis permutations.
|
|
738
|
+
- `Medium2D`, `Graphene`, `LossyMetalMedium`, `PerturbationMedium`, custom spatial dispersion, Sellmeier and gain media, nonlinear susceptibility, two-photon absorption, space-time modulation, magnetic conductivity/dispersion, and full `Tensor3x3` electric anisotropy.
|
|
739
|
+
- Composition of supported anisotropic, conductive, dispersive, nonlinear, modulated, and CPML material effects in the same compiled FDTD scene.
|
|
740
|
+
- Broadband, lossy, diagonal-anisotropic, and bent-waveguide mode-source/port workflows.
|
|
741
|
+
- Background-aware and curved-surface equivalent-current near-to-far propagation, directivity, bistatic RCS, and expanded S-parameter/modal-overlap processing.
|
|
742
|
+
- Tidy3D export for nonuniform grids, mixed boundaries, expanded geometry, material, source, and monitor families.
|
|
743
|
+
- CUDA graph capture coverage for standard, Bloch, dispersive, nonlinear, and TFSF stepping paths.
|
|
744
|
+
- Native CUDA SIBC updates, full-anisotropic conductive-current capture, and a device-resident modulation clock, all compatible with CUDA Graph replay.
|
|
745
|
+
- Python 3.10-3.14 and PyTorch 2.10-2.12 validation for the packaged LibTorch Stable ABI CUDA extension.
|
|
746
|
+
|
|
747
|
+
### Changed
|
|
748
|
+
|
|
749
|
+
- Consolidated the public architecture around the declarative `Scene -> Simulation -> Result` workflow. FDTD is the primary full-featured runtime; FDFD uses the same public model but remains a limited/experimental CUDA-only single-frequency path.
|
|
750
|
+
- Moved FDTD adjoint hot paths from Python/Torch replay to native CUDA kernels while keeping PyTorch autograd as the public differentiation interface.
|
|
751
|
+
- Generalized automatic/custom nonuniform grids, subpixel averaging, conformal PEC placement, and source phase correction to use local physical grid spacing.
|
|
752
|
+
- Standardized physical-domain handling so PML cells are appended outside `Domain.bounds`; material/source/monitor validation and cross-solver comparisons use the unchanged physical bounds.
|
|
753
|
+
- Adopted the WiTwin dual-license model and release wheels with CUDA 12.8 fat binaries for Linux and Windows.
|
|
754
|
+
|
|
755
|
+
### Fixed
|
|
756
|
+
|
|
757
|
+
- Aligned Maxwell and Tidy3D plane-wave and TFSF amplitudes using their physical power/field definitions instead of fitted dimensionless factors.
|
|
758
|
+
- Converted explicit Bloch vectors from Maxwell radians/metre to Tidy3D's dimensionless `k * period / (2*pi)` convention.
|
|
759
|
+
- Preserved requested field-monitor components during Tidy3D export and validation-cache loading, preventing undeclared near-zero components from being selected as scalar observables.
|
|
760
|
+
- Corrected external-PML SIBC half-space detection and low-side Yee surface-node placement for `LossyMetalMedium`.
|
|
761
|
+
- Corrected Gaussian-pulse phase/reference handling, CW export ramp bandwidth, source-spectrum normalization, flux-aperture integration, and coordinate-aligned complex-field comparison.
|
|
762
|
+
- Replaced invalid validation scenarios with physically supported TFSF, diffraction-monitor, cavity-probe, and closed-surface near-to-far workflows.
|
|
763
|
+
- Added visual slice/phase diagnostics and solver-independent scalar comparisons for resonances, diffraction orders, directivity/beamwidth, RCS, and S-parameters.
|
|
764
|
+
- Corrected symmetry-face PML removal, high-face grid anchoring, and Yee-control-volume point-dipole image scaling.
|
|
765
|
+
- Corrected singleton custom-current datasets on staggered Yee components so magnetic current samples compile to the nearest component location.
|
|
766
|
+
- Kept the stable-ABI CUDA extension source portable across MSVC and Linux NVCC by using explicit typed input tables in native anisotropic-current validation.
|
|
767
|
+
|
|
768
|
+
Detailed numerical conventions, pitfalls, final comparison values, and intentionally unresolved operator-level residuals are documented in [the 0.3.0 Tidy3D numerical-alignment notes](docs/validation/tidy3d-numerical-alignment-0.3.0.md).
|
|
769
|
+
|
|
770
|
+
## [0.2.0] - 2026-07-08
|
|
771
|
+
|
|
772
|
+
- Previous public release.
|
|
773
|
+
|
|
774
|
+
[0.6.0]: https://github.com/witwin-ai/witwin-maxwell/compare/witwin-maxwell-v0.5.1...witwin-maxwell-v0.6.0
|
|
775
|
+
[0.5.1]: https://github.com/witwin-ai/witwin-maxwell/compare/witwin-maxwell-v0.4.0...witwin-maxwell-v0.5.1
|
|
776
|
+
[0.4.0]: https://github.com/witwin-ai/witwin-maxwell/compare/witwin-maxwell-v0.3.0...witwin-maxwell-v0.4.0
|
|
777
|
+
[0.3.0]: https://github.com/witwin-ai/witwin-maxwell/compare/witwin-maxwell-v0.2.0...witwin-maxwell-v0.3.0
|
|
778
|
+
[0.2.0]: https://github.com/witwin-ai/witwin-maxwell/releases/tag/witwin-maxwell-v0.2.0
|