Conversation
Parse the Superconductor boundary block into SuperconductorData (London penetration depth and film thickness, or a direct kinetic sheet inductance), nondimensionalize its lengths in mesh units, extend the config schema, and warn when it is used outside a Magnetostatic simulation.
Model a thin-film superconductor as a 2D sheet contributing the London kinetic sheet inductance L_ksq = mu0 * lambda^2 / d. The operator supplies the tangential surface-mass coefficient (1/L_ksq) A_t . v_t, with per-attribute area scaling for cracked interior boundaries.
Assemble the superconductor kinetic sheet term into both the base and screened stiffness matrices so the magnetostatic solve carries the London kinetic inductance alongside the geometric contribution.
Add the kinetic sheet term to the magnetostatic energy operator M_mag so that A^T M_mag A = 2 E_mag captures the London kinetic energy, yielding the total (geometric + kinetic) inductance from the energy-based extraction.
A parallel-plate microstrip loop validating the superconductor sheet against the closed-form London limits: the PEC baseline gives the geometric inductance, and the superconductor config recovers L = L_geom + L_kin with L_kin linear in lambda^2 and the correct lambda -> 0 geometric limit.
…nvergence The range-space two-solve for London flux loops reused scratch vectors A_p_london/A_h_london across flux steps without zeroing them. Magnetostatics defaults to a nonzero initial guess, so a stale gradient/near-null-space component intermittently stalled CG on the gauge-singular operator K = K_cc + M_sheet (the fluxoid RHS c = Curlᵀf is marginally conditioned), producing a garbage A_h whose bad energy was injected via α·A_h -> wildly wrong extracted inductance on some MPI partitions. - Zero A_p_london/A_h_london before each solve for a clean, partition- and roundoff-independent start. - Expose KspSolver::GetConverged() and MFEM_VERIFY convergence after both London solves, turning a previously silent wrong answer into a hard error. - Bump ring_disk_mixed_current_flux rtol to 3e-4: its tiny off-diagonal mutual is a difference of large self-scale terms, so normal ~1e-6 partition FP jitter amplifies to ~1.2e-4 via cancellation (not a partitioning bug).
square_hole_flux_loop and ring_disk_mixed_current_flux declare a FluxLoopPEC film with no Boundaries.Superconductor block, so they took the whole-film Dirichlet clamp rather than the range-space two-solve, and both FAIL against their committed references at the current branch tip (those references encode the two-solve result). The clamp pins A over the entire film, which is not a gauge-invariant way to impose the fluxoid. - Auto-register any magnetostatic FluxLoopPEC attribute that is not already a Superconductor as the lambda -> 0 London limit: lambda = d = pec_lperp, so L_ksq = mu_0 lambda^2/d = mu_0 pec_lperp. Runs before the ams_singular_op default so the film is seen as a London film. - Add FluxLoop.PecPenetrationDepth to set that effective lambda_perp (default 1e-4 mesh units). - Raise the london_pc_shift default 1e-2 -> 1e-1. On finer meshes 1e-2 leaves the harmonic range-space solve intermittently divergent in parallel. The shift is preconditioner-only, so the extracted inductance is unchanged.
The hole flux functional c = Curl^T P_RT^T lf was assembled with VectorFEBoundaryFluxLFIntegrator(1.0), whose sign follows the raw mesh boundary-face orientation. A hole aperture is an *internal* boundary surface, and nothing makes those orientations consistent: some generators emit them mixed, and EnsureNCMesh reorients a subset. c then measured the signed sum of sub-apertures instead of the whole aperture, so the fluxoid constraint c^T A = Phi imposed the wrong linear functional. Fix with a FluxOrientationCoefficient returning sign(CalcOrtho(T.Jacobian()) . direction), matching the DIRECTION_BASED convention ComputeFluxThroughSurface already uses. Verified by Stokes: for A = (-y/2, x/2, 0) (curl A = z_hat), c^T A must equal the projected aperture area exactly. Measured before the PEC zeroing, the ratio c^T A / area was ring_disk (conformal) 0.101515230 -> 1.000000000 circular_hole (nonconformal) 0.873673 -> 1.000000000 Note two signals that mask this and should not be trusted alone: the VerifyFluxThroughHoles printout read 0.99965 for ring_disk despite c being 10x wrong, and c^T A = Phi always prints exactly Phi, because the two-solve enforces it by construction. ring_disk was the affected case, so its references are regenerated (np=2; mutual 7.973e-12 -> 8.807e-12). The other three London cases were already at ratio 1.0 and their references are unchanged, which is the useful check: the fix is a no-op wherever internal faces were already consistently oriented.
The guard rejected *any* flux loop under nonconformal AMR. A London loop's drive a_h is built directly on the 3D ND space, so it needs no global edge indexing; only the legacy 2D submesh cohomology path does, via mesh::MatchBoundaryEdges -> GetGlobalEdgeIndices, which nonconformal meshes lack. Narrow the guard to non-London loops. This also unblocks AMR on hex/wedge/pyramid meshes, where geodata forces nonconformal refinement and the old guard therefore rejected AMR outright. Nonconformal iteration 1 now reproduces the conformal result to round-off (c^T A_p 1.158692e-01 vs 1.158693e-01) with the fluxoid exact to ~1e-15 at every iteration. Known limitation, not addressed here: the +/-Phi cut cochain is written to local ND_1 DOFs, and slaves are rebuilt as P.(masters), which deforms the effective cut near hanging faces (iteration 2: 26 DOFs altered, ||delta||/||a_h|| = 9%). Since L depends on a_h restricted to Sigma beyond its cohomology class, that shifts L non-variationally. Near-uniform nonconformal refinement agrees with conformal to 0.52%, but highly localized error-driven nonconformal AMR drives L the wrong way (5.157e-12 -> 4.074e-12 where conformal gives 5.157 -> 5.648 -> 6.051e-12), because refinement concentrates on the hole perimeter that the cut crosses. Prefer conformal adaptation for error-driven AMR until the generator is built on the coarse ancestor and prolonged through the nested-space ND transfer operator.
Selects the smooth representative a_h = (Phi/2pi) grad(theta), theta = atan2(y-cy, x-cx), whose exact ND_1 DOF is the angle subtended at the flux line. It carries the fluxoid exactly (to 4e-15), is bounded, and is nonconformal-safe, so it is a useful independent cross-check of the default cut cochain and a one-variable bisection when a result looks wrong. It is NOT physically interchangeable with the cut cochain, and the comment now records why so the substitution is not attempted again: the two differ by grad(psi) with psi = (Phi/2pi) theta_branch, which does not vanish on the PEC outer walls, so A -> A + grad(psi) is not an admissible gauge transformation of the Dirichlet-constrained problem and L is not invariant. The large smooth a_h on Sigma lets the film phase gradient absorb the fluxoid at near-zero kinetic cost, collapsing the screening current: square_hole comes out 109x low, circular_hole_london 38x low. Diagnostic use only; default remains the cut cochain. Also guards the degenerate case where the flux line meets a hole vertex, where theta is undefined, by offsetting the line deterministically within the hole.
…gle) The topological ±Φ step cochain is not a conforming ND field on a non-conformal mesh: the true-DOF round trip rebuilds slave edges as P·(masters), deforming the O(1) step near hanging faces and injecting a large spurious curl on the film Σ. Decompose the generator instead as a_h = Grad ψ − a_angle, where ψ = (Φ/2π)·atan2(d,−s) is a conformed nodal H1 branch potential. Grad ψ is a discrete gradient of a conformed function, so it is exactly conforming and exactly curl-free and survives the round trip untouched; only the small smooth a_angle term is re-interpolated. On a conformal mesh this reproduces the exact integer step (all four flux/London regression cases unchanged); on a non-conformal mesh any residual curl is confined to a_angle at graded refinement and is absorbed by the range-space two-solve (verified not to affect L: PEC washer exact and London rect/high-λ track the conformal reference at matched DOF). Add circular_hole_london_nc_amr regression case locking the NC generator path through one non-conformal AMR refinement.
Avoids a reference-root collision with the new circular_hole_london_nc_amr case: the harness lists reference files recursively, so the flat flux case picked up the sibling nc_amr/ tree. Isolate each case in its own subdir.
The fluxoid-mode solve A_h = K⁻¹c needs progressively more PCG iterations as the mesh refines (p-multigrid+AMS is not h-independent on the gauge-singular operator), so deep AMR eventually hits the Linear.MaxIts cap and the fail-loud MFEM_VERIFY aborted the whole run. Instead, signal non-convergence via solve_converged_ and have SolveEstimateMarkRefine stop adaptation, retaining the last converged iteration's output. The initial solve still fails loud (no fallback), and non-AMR runs are unaffected.
A pure-PEC (λ→0) flux loop is modeled as a stiff tiny-λ London penalty. On a deeply refined mesh the linear solve cannot resolve A_t = a_h tightly enough, so the kinetic penalty energy S(A_t − a_h) = (A − a_h)ᵀ M_sheet (A − a_h) — which should vanish — becomes large and collapses the extracted inductance (compounded by catastrophic cancellation in the expanded S(A,A) form). Form S(A_t − a_h) directly (ApplySheetMass) and, if it jumps by more than 20× between adaptation iterations, flag the solve so SolveEstimateMarkRefine halts and keeps the last converged iteration. A converging solve grows this energy only mildly, so finite-λ films (circular, double, high-λ rect) are unaffected; verified the PEC square washer now stops at the geometric value (~3.02 pH) instead of collapsing.
…ctance-magnetostatics
…ctance-magnetostatics
… schema Drop PALACE_LONDON_AH (incl. the physically-wrong 'angle' mode) and PALACE_CUT_DIR env switches; the cut cochain a_h = Grad ψ − a_angle is now the sole generator (cut shape is L-invariant). Add the parsed FluxLoop.PecPenetrationDepth key to the JSON schema so setting it validates.
Holed PEC sheets always route through the London two-solve (auto-synth), so the legacy submesh/PEC-clamp path was unreachable. Remove the harmonic_generator flag, K_orig_ lift, IoData solver copy, and orphaned geodata edge-matching helpers.
dnpham23
marked this pull request as ready for review
September 10, 2026 22:57
… schema/comment fixes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds magnetostatic extraction of the total loop inductance (geometric plus London kinetic) for thin-film superconducting structures with holes and current terminals. Flux is imposed as a gauge-invariant fluxoid constraint on each hole, and finite-penetration-depth films carry a London sheet penalty, so the extracted inductance matrix includes the kinetic contribution. Also adds non-conformal AMR support for this path, worked examples, documentation, and regression coverage.
Motivation
Palace's magnetostatics previously produced only geometric inductance. Thin-film superconducting circuits have$d\lesssim\lambda$ , where the kinetic inductance is a first-class circuit element. This PR makes Palace extract L = L_geom + L_kin directly.
Examples & docs
examples/circular_hole/(square washer, single/double circular holes) andexamples/microstrip/(kinetic-inductance validation vs the analytic parallel-plateValidation
square_hole_flux_loop,circular_hole_london_flux,double_hole_london_flux,circular_hole_london_nc_amr,ring_disk_mixed_current_flux; rank-invariant at np=1/2/4/8.