API¶
JAX surface operators matching BIEST conventions.
- virtual_casing_jax.surface_ops.complete_vec_field(Y, is_surf: bool, half_period: bool, nfp: int, nt: int, npol: int, dtheta: float)[source]¶
Match BIEST SurfaceOp::CompleteVecField.
Y shape: (dof, nt, npol) Returns X shape: (dof, nfp*nt, npol)
- virtual_casing_jax.surface_ops.cross_prod(A, B)[source]¶
SoA cross product: A,B shape (3, nt, npol) -> (3, nt, npol).
- virtual_casing_jax.surface_ops.dot_prod(A, B)[source]¶
SoA dot product: A,B shape (3, nt, npol) -> (nt, npol).
- virtual_casing_jax.surface_ops.fft_c2r(y, nt: int, npol: int)[source]¶
Unitary c2r FFT over (nt, npol) axes.
- virtual_casing_jax.surface_ops.fft_r2c(x, nt: int, npol: int)[source]¶
Unitary r2c FFT over (nt, npol) axes.
- virtual_casing_jax.surface_ops.grad2d(X, nt: int, npol: int)[source]¶
Spectral surface derivatives (BIEST SurfaceOp::Grad2D).
Returns dX with shape (dof * 2, nt, npol) where entries are ordered as [dX_t, dX_p] per component.
- virtual_casing_jax.surface_ops.normal_orientation(X, normal)[source]¶
Return +1 or -1 orientation used by BIEST for normals.
- virtual_casing_jax.surface_ops.resample(X0, nt0: int, np0: int, nt1: int, np1: int)[source]¶
Resample using upsample + decimation (BIEST SurfaceOp::Resample).
- virtual_casing_jax.surface_ops.rotate_toroidal(X, nt: int, npol: int, dtheta)[source]¶
Rotate field in toroidal angle by dtheta.
X shape: (dof, nt, npol)
- virtual_casing_jax.surface_ops.surf_normal_area_elem(dX, X=None, *, return_orientation: bool = False)[source]¶
Compute unit normal and area element (BIEST SurfNormalAreaElem).
dX: (6, nt, npol) for 3D surfaces (dX_t, dX_p per component). X: optional (3, nt, npol) coordinates for orientation. Returns (normal, area_elem) or (normal, area_elem, orient) when
return_orientation=True.
- virtual_casing_jax.surface_ops.upsample(X0, nt0: int, np0: int, nt1: int, np1: int)[source]¶
Upsample using Fourier zero-padding (BIEST SurfaceOp::Upsample).
Kernel functions matching BIEST scaling and conventions.
- virtual_casing_jax.kernels.biotsavart_fx_u(dx, fvec)[source]¶
Biot-Savart kernel: (f x dx) / (4*pi*r^3).
dx: (…, 3) fvec: (…, 3) returns (…, 3)
- virtual_casing_jax.kernels.biotsavart_fxd_u(dx, fvec)[source]¶
Derivative of Biot-Savart kernel (matches BIEST FxdU).
Returns (…, 3, 3) tensor. The explicit formula matches the uker_FxdU in BIEST (see kernel.hpp).
- virtual_casing_jax.kernels.laplace_dx_u(dx, n, f)[source]¶
Laplace double-layer kernel:
(n·dx) f / (4 pi r^3).This is the outward-normal convention used by SCTL and BIEST since BIEST commit
0bf9ddc. For a closed surface,D[1]is-1inside,0outside, and-1/2on the surface.
- virtual_casing_jax.kernels.laplace_fx_u(dx, f)[source]¶
Laplace single-layer potential: f / (4*pi*r).
dx: (…, 3) f: (…,) returns (…,)
- virtual_casing_jax.kernels.laplace_fxd2_u(dx, f)[source]¶
Second derivatives of Laplace single-layer.
Returns a (…, 3, 3) tensor with entries: (-delta_ij * r^-3 + 3 r_i r_j r^-5) * f / (4*pi)
- virtual_casing_jax.kernels.laplace_fxd_u(dx, f)[source]¶
Gradient of Laplace single-layer: -(dx * f) / (4*pi*r^3).
dx: (…, 3) f: (…,) returns (…, 3)
Boundary integral evaluation (baseline direct-sum).
- exception virtual_casing_jax.integrals.OffsurfaceConvergenceError(*, tolerance: float, achieved_error: float, nt: int, npol: int, levels: int)[source]¶
Bases:
RuntimeErrorRaised when eager off-surface refinement exhausts its finite budget.
- virtual_casing_jax.integrals.biotsavart_fx_u_eval(X_src, X_trg, density_vec, area_elem, *, chunk_size: int = 1024, target_chunk_size: int | None = None)[source]¶
Evaluate Biot-Savart FxU by direct quadrature.
density_vec: (3, nt, np) or (3, nsrc) Returns: (3, ntrg) or (3, nt, np) matching X_trg layout.
- virtual_casing_jax.integrals.biotsavart_fxd_u_eval(X_src, X_trg, density_vec, area_elem, *, chunk_size: int = 512, target_chunk_size: int | None = None)[source]¶
Evaluate Biot-Savart FxdU by direct quadrature.
density_vec: (3, nt, np) or (3, nsrc) Returns: (3, 3, ntrg) or (3, 3, nt, np) matching X_trg layout.
- virtual_casing_jax.integrals.computeB_offsurface_adaptive(X_src, BdotN, J, Xt, digits: int = 5, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, ext: bool = True, chunk_size: int = 1024, target_chunk_size: int | None = None)[source]¶
Adaptive off-surface evaluation matching ExtVacuumField logic.
- virtual_casing_jax.integrals.computeB_offsurface_adaptive_schedule(X_src, BdotN, J, Xt, *, levels: tuple[tuple[int, int], ...], digits: int = 5, ext: bool = True, chunk_size: int = 1024, target_chunk_size: int | None = None, return_estimate: bool = False)[source]¶
JIT-friendly adaptive off-surface evaluation with fixed refinement schedule.
The refinement schedule is provided as a static tuple of (Nt, Np) pairs. Shapes are static per-level, so this function can be JIT-compiled with
levelsmarked static. The level is chosen by the calibrated estimate of_refine_by_estimate();return_estimatealso returns that estimate, per target and dimensionless, to compare with10**-digits.
- virtual_casing_jax.integrals.computeB_offsurface_baseline(X_src, BdotN, J, Xt, upsample_factor: int = 1, chunk_size: int = 1024, target_chunk_size: int | None = None, ext: bool = True)[source]¶
Baseline off-surface evaluation using direct quadrature.
This mirrors ExtVacuumField behavior (no singular correction) with optional upsampling for improved accuracy.
- virtual_casing_jax.integrals.computeGradB_offsurface_adaptive_schedule(X_src, BdotN, J, Xt, *, levels: tuple[tuple[int, int], ...], digits: int = 5, ext: bool = True, chunk_size: int = 1024, target_chunk_size: int | None = None, return_estimate: bool = False)[source]¶
JIT-friendly adaptive off-surface GradB evaluation with fixed schedule.
The level is chosen by the calibrated estimate of
_refine_by_estimate();return_estimatealso returns that estimate, per target and dimensionless, to compare with10**-digits.
- virtual_casing_jax.integrals.curl_single_layer_gradient(grad)[source]¶
Assemble
curl(G[J])fromgrad[J_component, derivative].
- virtual_casing_jax.integrals.field_period_target_coords(X_quad, trg_nt: int, trg_np: int, nfp: int)[source]¶
Select target coordinates used by FieldPeriodBIOp.
X_quad: (3, quad_nt, quad_np) for the full NFP surface. Returns X_trg: (3, trg_nt, trg_np) for the first field period.
- virtual_casing_jax.integrals.laplace_dx_u_eval(X_src, n_src, X_trg, density, area_elem, *, chunk_size: int = 1024, target_chunk_size: int | None = None)[source]¶
Evaluate Laplace DxU (double-layer) by direct quadrature.
- virtual_casing_jax.integrals.laplace_dx_u_eval_singular(X_src, dX_src, density, trg_nt: int, trg_np: int, nfp: int, X_trg=None, digits: int = 5, patch_dim0: int | None = None, rad_dim: int | None = None, chunk_size: int = 1024, target_chunk_size: int | None = None, patch_idx=None, orient: float | None = None, pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool = False)[source]¶
Evaluate Laplace DxU with singular correction on surface targets.
- virtual_casing_jax.integrals.laplace_fxd2_u_eval(X_src, X_trg, density, area_elem, *, chunk_size: int = 1024, target_chunk_size: int | None = None)[source]¶
Evaluate Laplace Fxd2U (second derivatives) by direct quadrature.
- virtual_casing_jax.integrals.laplace_fxd2_u_eval_singular(X_src, dX_src, density, trg_nt: int, trg_np: int, nfp: int, X_trg=None, digits: int = 5, patch_dim0: int | None = None, rad_dim: int | None = None, hedgehog_order: int = 8, chunk_size: int = 1024, target_chunk_size: int | None = None, patch_idx=None, orient: float | None = None, pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool = False, scan_targets: bool = False, hedgehog_side: Literal['interior', 'exterior'] = 'interior')[source]¶
Evaluate Laplace Fxd2U with singular correction (Hedgehog).
- Args:
- scan_targets: If True, use a
lax.scanloop over targets instead of
vmapin the singular correction. This can reduce peak memory by avoiding large broadcasted temporaries, at the cost of lower parallelism per chunk.
hedgehog_side: Side from which the on-surface limit is taken.
- scan_targets: If True, use a
- virtual_casing_jax.integrals.laplace_fxd2_u_eval_vec(X_src, X_trg, density_vec, area_elem, *, chunk_size: int = 1024, target_chunk_size: int | None = None)[source]¶
Vector-density wrapper for Laplace Fxd2U.
- virtual_casing_jax.integrals.laplace_fxd2_u_eval_vec_singular(X_src, dX_src, density_vec, trg_nt: int, trg_np: int, nfp: int, X_trg=None, digits: int = 5, patch_dim0: int | None = None, rad_dim: int | None = None, hedgehog_order: int = 8, chunk_size: int = 1024, target_chunk_size: int | None = None, patch_idx=None, orient: float | None = None, pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool = False, scan_targets: bool = False, hedgehog_side: Literal['interior', 'exterior'] = 'interior')[source]¶
Vector-density wrapper for Laplace Fxd2U with singular correction.
- Args:
scan_targets: forwarded to
laplace_fxd2_u_eval_singular.hedgehog_side: forwarded to
laplace_fxd2_u_eval_singular.
- virtual_casing_jax.integrals.laplace_fxd_u_eval(X_src, X_trg, density, area_elem, *, chunk_size: int = 1024, target_chunk_size: int | None = None)[source]¶
Evaluate Laplace FxdU (grad single-layer) by direct quadrature.
X_src: (3, nt, np) or (3, nsrc) X_trg: (3, nt, np) or (3, ntrg) density: (nt, np) or (nsrc,) area_elem: (nt, np) or (nsrc,) Returns: (3, ntrg) or (3, nt, np) matching X_trg layout.
- virtual_casing_jax.integrals.laplace_fxd_u_eval_singular(X_src, dX_src, density, trg_nt: int, trg_np: int, nfp: int, X_trg=None, digits: int = 5, patch_dim0: int | None = None, rad_dim: int | None = None, chunk_size: int = 1024, target_chunk_size: int | None = None, patch_idx=None, orient: float | None = None, pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool = False)[source]¶
Evaluate Laplace FxdU with singular correction on surface targets.
- virtual_casing_jax.integrals.laplace_fxd_u_eval_vec(X_src, X_trg, density_vec, area_elem, *, chunk_size: int = 1024, target_chunk_size: int | None = None)[source]¶
Vector-density wrapper for Laplace FxdU.
density_vec: (3, nt, np) or (3, nsrc) Returns: (3, 3, ntrg) with first index over density component.
- virtual_casing_jax.integrals.laplace_fxd_u_eval_vec_singular(X_src, dX_src, density_vec, trg_nt: int, trg_np: int, nfp: int, X_trg=None, digits: int = 5, patch_dim0: int | None = None, rad_dim: int | None = None, chunk_size: int = 1024, target_chunk_size: int | None = None, patch_idx=None, orient: float | None = None, pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool = False)[source]¶
- virtual_casing_jax.integrals.source_field_scale(BdotN, J)[source]¶
RMS field magnitude on the source surface.
J = B x nandBdotN = B . nwith a unit normal, so|J|^2 + BdotN^2 = |B|^2. Off-surface field differences are divided by this to give a dimensionless error estimate comparable with10**-digits.
Functional Virtual Casing API with differentiable geometry inputs.
- class virtual_casing_jax.functional.FunctionalSetup(nfp: int, nfp_eff: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, quad_nt: int, quad_np: int, patch_dim0: int, patch_idx: Array, orient: float)[source]¶
Bases:
objectStatic quadrature setup for functional API.
- patch_idx: Array¶
- virtual_casing_jax.functional.build_patch_idx(quad_nt: int, quad_np: int, trg_nt: int, trg_np: int, nfp_eff: int, patch_dim0: int)[source]¶
Build patch indices for singular quadrature.
- virtual_casing_jax.functional.build_quad_setup(surface_coord, quad_nt: int, quad_np: int, *, orient: float | None = None)[source]¶
Compute quadrature coordinates, derivatives, and normals.
- virtual_casing_jax.functional.build_surface_coord(X, nfp: int, half_period: bool, surf_nt: int, surf_np: int, trg_nt: int)[source]¶
Build full-field-period surface coordinates from base grid.
- virtual_casing_jax.functional.compute_external_B_functional(X, B0, *, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, quad_nt: int, quad_np: int, patch_dim0: int | None = None, patch_idx=None, orient: float | None = None, X_trg=None, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None)[source]¶
Compute Bext with surface coordinates as differentiable inputs.
- virtual_casing_jax.functional.compute_external_B_jvp_columns_functional(X, B0, X_tangents, B0_tangents=None, *, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, quad_nt: int, quad_np: int, patch_dim0: int | None = None, patch_idx=None, orient: float | None = None, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None)[source]¶
Return Bext and multiple forward-mode tangent columns.
X_tangentshas shape(ncols, 3, surf_nt, surf_np).B0_tangentshas shape(ncols, 3, src_nt, src_np); when omitted the magnetic-field input is held fixed. The returned tangent array has shape(ncols, 3, trg_nt, trg_np).
- virtual_casing_jax.functional.compute_external_B_normal_functional(X, B0, *, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, quad_nt: int, quad_np: int, patch_dim0: int | None = None, patch_idx=None, orient: float | None = None, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None)[source]¶
Compute on-surface Bext dot n with differentiable geometry inputs.
- virtual_casing_jax.functional.compute_external_B_normal_jvp_columns_functional(X, B0, X_tangents, B0_tangents=None, *, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, quad_nt: int, quad_np: int, patch_dim0: int | None = None, patch_idx=None, orient: float | None = None, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None)[source]¶
Return Bext dot n and multiple forward-mode tangent columns.
X_tangentshas shape(ncols, 3, surf_nt, surf_np).B0_tangentshas shape(ncols, 3, src_nt, src_np); when omitted the magnetic-field input is held fixed. The returned tangent array has shape(ncols, trg_nt, trg_np).
- virtual_casing_jax.functional.compute_external_B_offsurf_functional(X, B0, *, X_trg, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', adaptive: bool = True)[source]¶
Compute off-surface Bext with differentiable geometry inputs.
- virtual_casing_jax.functional.compute_external_gradB_functional(X, B0, *, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, quad_nt: int, quad_np: int, patch_dim0: int | None = None, patch_idx=None, orient: float | None = None, hedgehog_order: int = 8, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None)[source]¶
Compute GradBext with surface coordinates as differentiable inputs.
- virtual_casing_jax.functional.compute_external_gradB_offsurf_functional(X, B0, *, X_trg, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', adaptive: bool = False)[source]¶
Compute off-surface GradBext with differentiable geometry inputs.
- virtual_casing_jax.functional.compute_internal_B_functional(X, B0, *, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, quad_nt: int, quad_np: int, patch_dim0: int | None = None, patch_idx=None, orient: float | None = None, X_trg=None, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None)[source]¶
Compute Bint with surface coordinates as differentiable inputs.
- virtual_casing_jax.functional.compute_internal_gradB_functional(X, B0, *, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, quad_nt: int, quad_np: int, patch_dim0: int | None = None, patch_idx=None, orient: float | None = None, hedgehog_order: int = 8, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None)[source]¶
Compute GradBint with surface coordinates as differentiable inputs.
- virtual_casing_jax.functional.prepare_functional_setup(X, *, digits: int, nfp: int, half_period: bool, surf_nt: int, surf_np: int, src_nt: int, src_np: int, trg_nt: int, trg_np: int, quad_nt: int, quad_np: int, patch_dim0: int | None = None, orient: float | None = None)[source]¶
Prepare static quadrature setup for functional API.
This helper is intended to be called outside autodiff; it uses non-differentiable logic to choose patch sizes if not provided.
- virtual_casing_jax.functional.select_patch_dim_from_geom(dX, quad_nt: int, quad_np: int, digits: int)[source]¶
Select patch_dim0 using surface condition (non-differentiable).
- virtual_casing_jax.functional.target_surface_normal(X, *, nfp: int, half_period: bool, surf_nt: int, surf_np: int, trg_nt: int, trg_np: int, orient: float | None = None)[source]¶
Return unit normals on the virtual-casing target grid.
High-level Virtual Casing routines in JAX.
- class virtual_casing_jax.virtual_casing.PrecisionPlan(quad_nt: int, quad_np: int, patch_dim0: int, patch_idx: Array)[source]¶
Bases:
objectFrozen adaptive-precision choices for a virtual-casing B evaluation.
Automatic quadrature and singular-patch selection depend on concrete surface geometry. Select them once with
plan_precision(), then pass the resulting plan tocompute_external_B()orcompute_internal_B()when differentiating with respect to the surface coordinates.- patch_idx: Array¶
- class virtual_casing_jax.virtual_casing.QuadSetup(quad_nt: 'int', quad_np: 'int', quad_coord: 'jnp.ndarray', dX: 'jnp.ndarray', normal: 'jnp.ndarray', orient: 'float', patch_idx_cache: 'dict[int, jnp.ndarray]'=<factory>)[source]¶
Bases:
object- dX: Array¶
- normal: Array¶
- quad_coord: Array¶
- class virtual_casing_jax.virtual_casing.VirtualCasingJAX[source]¶
Bases:
objectJAX mirror of VirtualCasing for external field and GradB.
- compute_external_B(B0, *, X_trg=None, quad_nt: int | None = None, quad_np: int | None = None, digits: int | None = None, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None, patch_dim0: int | None = None, patch_idx=None, precision: PrecisionPlan | None = None)[source]¶
Compute Bext from total B on the source grid.
- compute_external_B_autodiff(B0, *, X_trg, quad_nt: int | None = None, quad_np: int | None = None, digits: int | None = None, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None, hedgehog_order: int = 8)[source]¶
Compute Bext with a custom JVP that matches ComputeGradB on-surface.
- compute_external_B_batch(B0_batch, *, X_trg=None, **kwargs)[source]¶
Vectorized compute_external_B over a batch dimension.
- compute_external_B_offsurf(B0, *, X_trg, digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto')[source]¶
Compute Bext at off-surface targets using adaptive quadrature.
- compute_external_B_offsurf_schedule(B0, *, X_trg, levels: tuple[tuple[int, int], ...] | str | None, digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', return_estimate: bool = False)[source]¶
Compute Bext off-surface using a fixed adaptive refinement schedule.
- compute_external_B_offsurf_schedule_jit(B0, *, X_trg, levels: tuple[tuple[int, int], ...] | str | None = 'auto', digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', donate: bool = False)[source]¶
JIT-compiled schedule-based off-surface Bext.
- compute_external_gradB(B0, *, quad_nt: int | None = None, quad_np: int | None = None, digits: int | None = None, hedgehog_order: int = 8, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None, scan_targets: bool = False, patch_dim0: int | None = None, patch_idx=None)[source]¶
Compute GradBext from total B on the source grid.
- Args:
- scan_targets: If True, use a
lax.scanover target points inside the singular correction to reduce peak memory.
- scan_targets: If True, use a
- compute_external_gradB_batch(B0_batch, **kwargs)[source]¶
Vectorized compute_external_gradB over a batch dimension.
- compute_external_gradB_offsurf(B0, *, X_trg, digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, adaptive: bool = False, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto')[source]¶
Compute GradBext at off-surface targets using direct quadrature.
The off-surface GradB path mirrors the reference implementation and currently uses the base resampled grid (no adaptive refinement).
- compute_external_gradB_offsurf_schedule(B0, *, X_trg, levels: tuple[tuple[int, int], ...] | str | None, digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', return_estimate: bool = False)[source]¶
Compute GradBext off-surface using a fixed adaptive refinement schedule.
- compute_external_gradB_offsurf_schedule_jit(B0, *, X_trg, levels: tuple[tuple[int, int], ...] | str | None = 'auto', digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', donate: bool = False)[source]¶
JIT-compiled schedule-based off-surface GradBext.
- compute_internal_B(B0, *, X_trg=None, quad_nt: int | None = None, quad_np: int | None = None, digits: int | None = None, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None, patch_dim0: int | None = None, patch_idx=None, precision: PrecisionPlan | None = None)[source]¶
Compute Bint from total B on the source grid.
- compute_internal_B_batch(B0_batch, *, X_trg=None, **kwargs)[source]¶
Vectorized compute_internal_B over a batch dimension.
- compute_internal_B_offsurf(B0, *, X_trg, digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto')[source]¶
Compute Bint at off-surface targets using adaptive quadrature.
- compute_internal_B_offsurf_schedule(B0, *, X_trg, levels: tuple[tuple[int, int], ...] | str | None, digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', return_estimate: bool = False)[source]¶
Compute Bint off-surface using a fixed adaptive refinement schedule.
- compute_internal_B_offsurf_schedule_jit(B0, *, X_trg, levels: tuple[tuple[int, int], ...] | str | None = 'auto', digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', donate: bool = False)[source]¶
JIT-compiled schedule-based off-surface Bint.
- compute_internal_gradB(B0, *, quad_nt: int | None = None, quad_np: int | None = None, digits: int | None = None, hedgehog_order: int = 8, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', pou_dtype=None, patch_dtype=None, interp_block_size: int | str | None = 'auto', remat: bool | None = None, scan_targets: bool = False, patch_dim0: int | None = None, patch_idx=None)[source]¶
Compute GradBint from total B on the source grid.
- Args:
- scan_targets: If True, use a
lax.scanover target points inside the singular correction to reduce peak memory.
- scan_targets: If True, use a
- compute_internal_gradB_batch(B0_batch, **kwargs)[source]¶
Vectorized compute_internal_gradB over a batch dimension.
- compute_internal_gradB_offsurf(B0, *, X_trg, digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, adaptive: bool = False, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto')[source]¶
Compute GradBint at off-surface targets using direct quadrature.
- compute_internal_gradB_offsurf_schedule(B0, *, X_trg, levels: tuple[tuple[int, int], ...] | str | None, digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', return_estimate: bool = False)[source]¶
Compute GradBint off-surface using a fixed adaptive refinement schedule.
- compute_internal_gradB_offsurf_schedule_jit(B0, *, X_trg, levels: tuple[tuple[int, int], ...] | str | None = 'auto', digits: int | None = None, max_Nt: int = -1, max_Np: int = -1, max_levels: int = 6, chunk_size: int | str | None = 'auto', target_chunk_size: int | str | None = 'auto', donate: bool = False)[source]¶
JIT-compiled schedule-based off-surface GradBint.
- plan_precision(*, digits: int | None = None, quad_nt: int | None = None, quad_np: int | None = None) PrecisionPlan[source]¶
Freeze geometry-dependent precision choices for traced evaluations.
Call this on a concrete surface, then reuse the returned plan for small differentiable perturbations of that surface. The plan does not mutate the object’s stored B quadrature setup.
SIMSOPT-compatible VirtualCasing class backed by virtual_casing_jax.
- class virtual_casing_jax.simsopt_virtual_casing.VirtualCasing[source]¶
Bases:
objectSIMSOPT-compatible VirtualCasing class backed by JAX.
This class mirrors
simsopt.mhd.virtual_casing.VirtualCasingso it can be imported as:from virtual_casing_jax import VirtualCasing
High-level exterior magnetic-field wrapper for virtual casing.
- virtual_casing_jax.exterior_field.B_cyl_from_B_xyz(field_fn: Callable, R_phi_Z)[source]¶
Evaluate a Cartesian field callback and return cylindrical components.
- class virtual_casing_jax.exterior_field.ExteriorFieldConfig(digits: int = 8, src_nphi: int = 64, src_ntheta: int = 64, levels: tuple[tuple[int, int], ...] | None = None, chunk_size: int | str = 'auto', target_chunk_size: int | str = 'auto', branch: Literal['internal', 'external'] = 'internal', use_jit_schedule: bool = True, validate_orientation: bool = True, dtype: str = 'float64')[source]¶
Bases:
objectConfiguration for fixed-schedule exterior-field evaluation.
- class virtual_casing_jax.exterior_field.NearSurfaceTaylorPlan(center_rz: Array, surface_rz: Array, B_surface: Array, gradB_surface: Array, nfp: int)[source]¶
Bases:
objectReusable interpolation data for first-order near-surface continuation.
- B_surface: Array¶
- center_rz: Array¶
- gradB_surface: Array¶
- surface_rz: Array¶
- class virtual_casing_jax.exterior_field.VirtualCasingExteriorField(surface_data: VmecSurfaceFieldData, config: ExteriorFieldConfig | None = None, external_B_fn: Callable | None = None, external_gradB_fn: Callable | None = None)[source]¶
Bases:
objectJAX-native exterior field from VMEC-surface virtual-casing data.
B_plasma_xyzdefaults to theinternaloff-surface branch because VMEC plasma currents are inside the LCFS. Theexternalbranch means currents outside the VMEC surface, not targets outside the VMEC surface.- B_and_derivatives_xyz(xyz, *, order=0, level=None, source_chunk=4096)[source]¶
Band its spatial derivatives atxyz, from the closed forms.One traversal of the source sum returns every order up to
order, where nestingjacfwdoverB_plasma_xyz()costs one traversal per order and differentiates the quadrature rather than the field.Returns a tuple of
order + 1arrays, thek-th with shapexyz.shape[:-1] + (3,) * (k + 1).
- B_plasma_error_estimate(xyz, *, branch: Literal['internal', 'external'] | None = None)[source]¶
Achieved relative error of
B_plasma_xyz(), per target.Compare with
10**-config.digits. Valid on either side of the source surface. A target closer to it than about two source-grid spacings reports a large error: the periodic trapezoid rule is near-singular there and the direct schedule is not the right tool, whatever level it reaches.
- B_plasma_near_surface_xyz(xyz, plan: NearSurfaceTaylorPlan)[source]¶
Evaluate a first-order continuation of the plasma field.
This path is intended for targets close enough to the source surface that direct periodic trapezoidal quadrature would require prohibitive refinement. Returned vectors are Cartesian and batched over
xyz.
- B_plasma_on_surface(*, digits=None, chunk_size=None, quad_nt=None, quad_np=None, precision=None)[source]¶
Return the internal-current plasma field on the source surface.
This reuses the geometry prepared by the exterior field, avoiding a second quadrature setup when boundary diagnostics and off-surface evaluations are needed together.
- B_plasma_xyz(xyz, *, branch: Literal['internal', 'external'] | None = None, return_estimate: bool = False)[source]¶
Return the virtual-casing plasma-current field in Cartesian components.
With
return_estimatealso return the schedule’s achieved relative error per target, dimensionless and comparable with10**-digits, so an unconverged schedule reports what it achieved instead of silently handing back its last level. SeeB_plasma_error_estimate().
- B_xyz_sharded(xyz, *, devices=None)[source]¶
Evaluate a large
(n, 3)target batch across JAX devices.Surface data are replicated while the independent target axis is partitioned. A single-device process follows
B_xyz()directly.
- export_rphiz_grid(R, phi, Z, *, chunk_size: int | str = 'auto')[source]¶
Evaluate this field on a tensor-product cylindrical grid.
- gradB_plasma_xyz(xyz, *, branch: Literal['internal', 'external'] | None = None)[source]¶
Return
dB_i/dx_jfor the virtual-casing plasma field.
- gradB_xyz(xyz)[source]¶
Return
dB_i/dx_jfor the total field.JAX differentiates
external_B_fnpoint by point when an analyticexternal_gradB_fnwas not supplied.
- level_sources(level=None)[source]¶
Quadrature nodes and layer densities of one schedule level.
Returns
(nodes, sheet_current, charge)with shapes(m, 3),(m, 3)and(m,), the densities already carrying the quadrature weight, ready forlayer_derivatives().leveldefaults to the finest of the schedule – the one the two-level default returns unconditionally. The densities are built the way the schedule builds them: the field is recovered pointwise on the base grid and interpolated, and the products are formed on the level with the level’s own normal, so these nodes reproduceB_plasma_xyz()rather than approximating it.
- plan_near_surface(*, digits=None, precision=None, B_surface=None)[source]¶
Prepare a smooth first-order field continuation near the surface.
The singular on-surface field and gradient are computed once. Reusing the returned plan avoids increasingly fine direct quadrature for every nearby target in a field-line or grid evaluation.
- class virtual_casing_jax.exterior_field.VmecSurfaceFieldData(gamma: Array, B_total: Array, normal: Array, area_vector: Array, theta: Array, phi: Array, nfp: int, stellsym: bool, signgs: int, source_convention: str = 'vmex')[source]¶
Bases:
objectVMEC boundary data on a virtual-casing source grid.
Arrays use structure-of-arrays layout
(3, nphi, ntheta).phiis the physical toroidal angle, not the VMEC field-period coordinatezeta.- B_total: Array¶
- area_vector: Array¶
- gamma: Array¶
- normal: Array¶
- phi: Array¶
- theta: Array¶
- virtual_casing_jax.exterior_field.build_near_surface_taylor_plan(surface_data, B_surface, gradB_surface)[source]¶
Build a smooth first-order near-surface continuation plan.
Vector and gradient components are stored in the local cylindrical basis, making their Fourier representation periodic over one field period.
- virtual_casing_jax.exterior_field.cyl_to_xyz(R_phi_Z)[source]¶
Convert cylindrical point coordinates
(R, phi, Z)to Cartesian.
- virtual_casing_jax.exterior_field.default_schedule_levels(nphi: int, ntheta: int, nfp: int)[source]¶
Two-level schedule sized from the source grid, in full-torus counts.
surface_datais sampled on ONE field period, while a schedule level counts the WHOLE torus, so the toroidal entries carry thenfpfactor. Without it an nfp = 5 boundary sampled at 32 points per period was resolved by a finest level of 64 over the torus – 13 points per period – and the achieved error one minor radius off the boundary was 2.5e-02 against a requested 1e-6.Two levels are enough: the coarse level exists only to supply the Richardson term of the error estimate, and it costs a quarter of the fine one. A schedule of one level is accepted and reports the double-layer quadrature error alone.
- virtual_casing_jax.exterior_field.xyz_vec_to_cyl_vec(R_phi_Z, B_xyz)[source]¶
Convert Cartesian vector components to cylindrical components.
Cylindrical grid evaluation and lightweight NetCDF export.
- virtual_casing_jax.grid_export.evaluate_on_rphiz_grid(field, R, phi, Z, *, chunk_size: int | str = 'auto') dict[source]¶
Return
BR,Bphi,BZ, andabsBon anR, phi, Zgrid.
- virtual_casing_jax.grid_export.write_extended_field_netcdf(path, grid_data: Mapping, metadata: Mapping | None = None)[source]¶
Write an extended-field cylindrical grid to a NetCDF file.
- virtual_casing_jax.grid_export.write_mgrid_like(path, grid_data: Mapping, metadata: Mapping | None = None)[source]¶
Write a lightweight MGRID-like NetCDF file with explicit convention metadata.
Smooth objective helpers for exterior-field workflows.
- virtual_casing_jax.objectives.boundary_normal_residual(surface_data, field)[source]¶
Return
B_total . non the VMEC boundary source grid.
- virtual_casing_jax.objectives.exterior_B_magnitude_squared(field, target_xyz, weights, target_absB)[source]¶
Weighted mean-square magnetic-field magnitude objective.
- virtual_casing_jax.objectives.exterior_Bn_squared(field, target_xyz, target_normals, weights, target_Bn=0.0)[source]¶
Weighted mean-square normal-field objective on target points.
- virtual_casing_jax.objectives.grid_divergence_penalty(BR, Bphi, BZ, R, phi, Z, weights=None)[source]¶
Finite-difference cylindrical
div Bmean-square diagnostic.
Test data utilities mirroring virtual-casing VirtualCasingTestData.
- class virtual_casing_jax.testdata.Drand48(state: int = 20017429951246)[source]¶
Bases:
objectDeterministic drand48-compatible generator.
- class virtual_casing_jax.testdata.SurfType(value)[source]¶
Bases:
Enum- AxisymCircleNarrow = 1¶
- AxisymCircleWide = 0¶
- AxisymNarrow = 3¶
- AxisymWide = 2¶
- LHD = 7¶
- NoneType = 11¶
- Quas3 = 6¶
- RotatingEllipseNarrow = 5¶
- RotatingEllipseWide = 4¶
- Stell = 9¶
- W7X = 8¶
- W7X_ = 10¶
- class virtual_casing_jax.testdata.VirtualCasingTestData[source]¶
Bases:
objectJAX mirror of virtual-casing VirtualCasingTestData.
- static magnetic_field_data(nfp: int, half_period: bool, nt: int, npol: int, X, trg_nt: int, trg_np: int)[source]¶
- static magnetic_field_data_offsurf(nfp: int, half_period: bool, nt: int, npol: int, X, X_trg)[source]¶
- static magnetic_field_grad_data(nfp: int, half_period: bool, nt: int, npol: int, X, trg_nt: int, trg_np: int)[source]¶
- virtual_casing_jax.testdata.magnetic_field_data(nfp: int, half_period: bool, surf_nt: int, surf_np: int, X, trg_nt: int, trg_np: int, *, rng: Drand48 | None = None)[source]¶
Generate B field data for testing VirtualCasingJAX.
- virtual_casing_jax.testdata.magnetic_field_data_offsurf(nfp: int, half_period: bool, surf_nt: int, surf_np: int, X, X_trg, *, rng: Drand48 | None = None, chunk_size: int = 1024)[source]¶
Generate B field at arbitrary target points from synthetic loops.
- virtual_casing_jax.testdata.magnetic_field_grad_data(nfp: int, half_period: bool, surf_nt: int, surf_np: int, X, trg_nt: int, trg_np: int, *, rng: Drand48 | None = None)[source]¶
Generate GradB data for testing VirtualCasingJAX.
- virtual_casing_jax.testdata.magnetic_field_grad_data_offsurf(nfp: int, half_period: bool, surf_nt: int, surf_np: int, X, X_trg, *, rng: Drand48 | None = None, chunk_size: int = 512)[source]¶
Generate analytic GradB at arbitrary targets from synthetic loops.
- virtual_casing_jax.testdata.surface_coordinates(nfp: int, half_period: bool, nt: int, npol: int, surf_type: SurfType = SurfType.AxisymNarrow)[source]¶
Singular quadrature utilities (POU + polar correction).
- class virtual_casing_jax.singular_quadrature.SingularPrecomp(patch_dim0: 'int', hedgehog_order: 'int', rad_dim_base: 'int', rad_dim: 'int', ang_dim: 'int', patch_dim: 'int', ngrid: 'int', npolar: 'int', qx: 'jnp.ndarray', qw: 'jnp.ndarray', Gpou: 'jnp.ndarray', Ppou: 'jnp.ndarray', I_G2P: 'jnp.ndarray', M_G2P: 'jnp.ndarray', interp_idx: 'jnp.ndarray', hedgehog_wts: 'jnp.ndarray')[source]¶
Bases:
object- Gpou: Array¶
- I_G2P: Array¶
- M_G2P: Array¶
- Ppou: Array¶
- hedgehog_wts: Array¶
- interp_idx: Array¶
- qw: Array¶
- qx: Array¶
- virtual_casing_jax.singular_quadrature.precompute_singular(patch_dim0: int, rad_dim: int, hedgehog_order: int = 1, pou_dtype=None, patch_dtype=None, index_dtype=None)[source]¶
Build JAX constants from a bounded cache of host NumPy arrays.
JAX conversion is intentionally outside the cached function. Otherwise a JIT-first invocation can cache tracers globally and leak them into later eager calls.