Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b62568e
VACUUM - MINOR - standardizing vacuum inputs to exclude the endpoint
jhalpern30 Jun 24, 2026
ad91fcb
VACUUM - FEATURE - accepting only one field period of points, nzeta i…
jhalpern30 Jun 25, 2026
f07a817
VACUUM - MINOR - updating vacuum code to accept a vector of modes ins…
jhalpern30 Jun 25, 2026
172ad76
VACUUM - WIP - Claude's first attempt at adding nfp symmetry to the k…
jhalpern30 Jun 25, 2026
447aab9
Merge branch 'develop' into feature/3Dvac_nfp
jhalpern30 Jun 25, 2026
a4b78ef
GPEC - MINOR - small cleanups
jhalpern30 Jun 25, 2026
16f4649
Merge branch 'feature/3Dvac_nfp' of github.com:OpenFUSIONToolkit/GPEC…
jhalpern30 Jun 26, 2026
2268899
Benchmark script
jhalpern30 Jun 29, 2026
d92f8d9
VACUUM - IMPROVEMENT - Claude cleanup separating 2D and 3D vacuum res…
jhalpern30 Jun 29, 2026
aca4d23
UTILITIES - MINOR - multiple dispatching compute_fourier_coefficients…
jhalpern30 Jun 29, 2026
91832e5
VACUUM - IMPROVEMENT - block-circulant + wall implementation working …
jhalpern30 Jun 29, 2026
20ce6f3
VACUUM - MINOR - small cleanups after the Claude refactoring
jhalpern30 Jun 29, 2026
29dc476
VACUUM - MINOR - more cleanups/renaming
jhalpern30 Jun 29, 2026
ece3e44
FOURIER - IMPROVEMENT - overhaul of the code to just work with comple…
jhalpern30 Jun 30, 2026
1c95504
FOURIER - IMPROVEMENT - tranposing the coefficients for more straight…
jhalpern30 Jun 30, 2026
f4ce143
VACUUM - MINOR - consolidating assemble_vacuum_response into the 2d f…
jhalpern30 Jun 30, 2026
62f0f76
VACUUM - IMPROVEMENT - cleaning up the 3d code and having it default …
jhalpern30 Jun 30, 2026
3db7cee
VACUUM - IMPROVEMENT - cleaning up the 3d code and having it default …
jhalpern30 Jun 30, 2026
b05c242
Merge branch 'feature/3Dvac_nfp' of github.com:OpenFUSIONToolkit/GPEC…
jhalpern30 Jun 30, 2026
7a62ba1
Merge branch 'feature/3Dvac_nfp' of github.com:OpenFUSIONToolkit/GPEC…
jhalpern30 Jun 30, 2026
ce08e89
Merge branch 'feature/3Dvac_nfp' of github.com:OpenFUSIONToolkit/GPEC…
jhalpern30 Jun 30, 2026
c8aec3a
VACUUM - MINOR - some small cleanups
jhalpern30 Jun 30, 2026
7eeefa7
BENCHMARKS - MINOR - removing an intermediate testing script for this…
jhalpern30 Jun 30, 2026
13e1467
Merge branch 'develop' into feature/3Dvac_nfp
jhalpern30 Jun 30, 2026
b7c8b1e
last cleanups
jhalpern30 Jun 30, 2026
3a542d7
Merge branch 'feature/3Dvac_nfp' of github.com:OpenFUSIONToolkit/GPEC…
jhalpern30 Jun 30, 2026
2d388f1
VACUUM - MINOR - claude review comments
jhalpern30 Jun 30, 2026
55b4a94
GPEC - BUGFIX - missed a notation change on the FourierTransforms
jhalpern30 Jun 30, 2026
73fd6d9
fixing unit tests
jhalpern30 Jun 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
237 changes: 0 additions & 237 deletions benchmarks/benchmark_fourier_transforms.jl

This file was deleted.

11 changes: 3 additions & 8 deletions src/Equilibrium/CoordinateInvariant.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ w(θ) = √(J·|∇ψ|).

Operationally, sqrtamat is the mode-space √weight operator: for a field b with
Fourier coefficients b_fft, it satisfies the identity
`‖sqrtamat·b_fft‖² = N² · ∫ |b|² · J|∇ψ| dθ`
`‖sqrtamat·b_fft‖² = N² · ∫ |b|² · J|∇ψ| dθ`
which is Jacobian-invariant on a given flux surface (see
`scripts/test_power_norm_invariance.jl`).

Expand All @@ -78,13 +78,8 @@ function compute_sqrtamat(
e_k .= 0.0
e_k[k] = 1.0 + 0.0im

# Standard backward FT: f(θ_j) = (1/N) Σ_m c_m exp(-imθ_j)
# exp(-imθ) = cos(mθ) - i·sin(mθ), so:
# Re(f) = (1/N)(cslth·Re(c) + snlth·Im(c))
# Im(f) = (1/N)(cslth·Im(c) - snlth·Re(c))
real_part = (ft.cslth * real.(e_k) .+ ft.snlth * imag.(e_k)) ./ mtheta
imag_part = (ft.cslth * imag.(e_k) .- ft.snlth * real.(e_k)) ./ mtheta
theta_vec = complex.(real_part, imag_part)
# Standard backward FT: f(θ_j) = (1/N) Σ_m c_m exp(-imθ_j) = (transpose(basis) * c) / N
theta_vec = (transpose(ft.basis) * e_k) ./ mtheta

# Multiply pointwise by √(J·|∇ψ|) in theta-space
theta_vec .*= sqrt_jdp
Expand Down
16 changes: 8 additions & 8 deletions src/ForceFreeStates/ForceFreeStatesStructs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ A mutable struct holding data related to the singular surfaces in the equilibriu
- `n::Vector{Int}` - Toroidal mode number(s)
- `q::Float64` - Safety factor (= m/n)
- `q1::Float64` - Derivative of safety factor with respect to ψ
- `grri::Array{Float64,2}` - Interior Green's function at this surface [2*mthvac, 2*mpert]
- `grre::Array{Float64,2}` - Exterior Green's function at this surface [2*mthvac, 2*mpert]
- `grri::Array{ComplexF64,2}` - Interior Green's function at this surface [mthvac, mpert]
- `grre::Array{ComplexF64,2}` - Exterior Green's function at this surface [mthvac, mpert]
- `delta_prime::Vector{ComplexF64}` - **STUB (not physically valid)**. Per-surface ca-based Δ' estimate retained for future work / debugging only. The physically valid Δ' is `ForceFreeStatesInternal.delta_prime_matrix`, computed via the STRIDE global BVP (Glasser 2018 PoP 25, 032501). Do not use this field for tearing-stability analysis; do not expect agreement with `delta_prime_matrix`.
- `delta_prime_col::Matrix{ComplexF64}` - **STUB (not physically valid)**. Per-surface ca-based Δ' column retained for future work / debugging only. Shape (numpert_total × n_res_modes); `delta_prime_col[j, i] = (ca_r[j,ipert_res_i,2] - ca_l[j,ipert_res_i,2]) / (4π²·psio)`. The diagonal element matches the (also stubbed) `delta_prime[i]`. Only populated for the Riccati/parallel FM paths. The physically valid Δ' is `ForceFreeStatesInternal.delta_prime_matrix`; this field exists for future development on intra-surface coupling diagnostics, not for production use.
"""
Expand All @@ -23,8 +23,8 @@ A mutable struct holding data related to the singular surfaces in the equilibriu
n::Vector{Int} = Int[]
q::Float64 = 0.0
q1::Float64 = 0.0
grri::Array{Float64,2} = Array{Float64}(undef, 0, 0)
grre::Array{Float64,2} = Array{Float64}(undef, 0, 0)
grri::Array{ComplexF64,2} = Array{ComplexF64}(undef, 0, 0)
grre::Array{ComplexF64,2} = Array{ComplexF64}(undef, 0, 0)
delta_prime::Vector{ComplexF64} = ComplexF64[]
delta_prime_col::Matrix{ComplexF64} = Matrix{ComplexF64}(undef, 0, 0)
ua_left::Array{ComplexF64,3} = Array{ComplexF64}(undef, 0, 0, 0) # asymptotic basis at left inner-layer boundary
Expand Down Expand Up @@ -413,8 +413,8 @@ Populated in `Free.jl`.
- `et::Vector{ComplexF64}` - Total eigenvalues of plasma + vacuum
- `n_tor_idx::Vector{Int}` - 0-based toroidal mode number index of each sorted eigenvalue (numpert_total). Needed in `write_imas`
- `vacuum_eigenvalue::Float64` - Least stable (minimum) eigenvalue of the vacuum matrix wv, clamped to zero
- `grri::Array{Float64, 2}` - Interior Green's function matrices (2 * mthvac * nzvac × 2 * numpert_total)
- `grre::Array{Float64, 2}` - Exterior Green's function matrices (2 * mthvac * nzvac × 2 * numpert_total)
- `grri::Array{ComplexF64, 2}` - Interior Green's function matrices (2 * mthvac * nzvac × numpert_total)
- `grre::Array{ComplexF64, 2}` - Exterior Green's function matrices (2 * mthvac * nzvac × numpert_total)
- `plasma_pts::Array{Float64, 3}` - Cartesian coordinates of plasma points, shape (mthvac * nzvac) × 3 for (x, y, z)
- `wall_pts::Array{Float64, 3}` - Cartesian coordinates of wall points, shape (mthvac * nzvac) × 3 for (x, y, z)
"""
Expand Down Expand Up @@ -444,8 +444,8 @@ Populated in `Free.jl`.
rootA_wv::Array{ComplexF64,2} = fill(complex(NaN), numpert_total, numpert_total)
rootA_wt::Array{ComplexF64,2} = fill(complex(NaN), numpert_total, numpert_total)

grri::Array{Float64,2} = Array{Float64}(undef, 2 * numpoints, 2 * numpert_total)
grre::Array{Float64,2} = Array{Float64}(undef, 2 * numpoints, 2 * numpert_total)
grri::Array{ComplexF64,2} = Array{ComplexF64}(undef, 2 * numpoints, numpert_total)
grre::Array{ComplexF64,2} = Array{ComplexF64}(undef, 2 * numpoints, numpert_total)
plasma_pts::Array{Float64,2} = Array{Float64}(undef, numpoints, 3)
wall_pts::Array{Float64,2} = Array{Float64}(undef, numpoints, 3)
end
Expand Down
4 changes: 2 additions & 2 deletions src/ForceFreeStates/Free.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ and data dumping.
end

# Compute vacuum response matrix in-place (handles 2D single-n, 2D multi-n block-diagonal, and 3D)
vac_inputs = Vacuum.VacuumInput(equil, psilim, ctrl.mthvac, ctrl.nzvac, mpert, mlow, npert, nlow; force_wv_symmetry=ctrl.force_wv_symmetry)
vac_inputs = Vacuum.VacuumInput(equil, psilim, ctrl.mthvac, ctrl.nzvac, mlow:mhigh, nlow:nhigh; force_wv_symmetry=ctrl.force_wv_symmetry)
Vacuum.compute_vacuum_response!(vac_data, vac_inputs, wall_settings)

# Scale by (m - n*q)(m' - n'*q) [Chance Phys. Plasmas 1997 2161 eq. 126]
Expand Down Expand Up @@ -159,7 +159,7 @@ q-window minimum.
)

# Compute raw vacuum matrix at the actual scan psi (singfac NOT applied; free_compute_total applies it analytically)
vac_inputs = Vacuum.VacuumInput(equil, psi_array[i], ctrl.mthvac, ctrl.nzvac, intr.mpert, intr.mlow, intr.npert, intr.nlow; force_wv_symmetry=ctrl.force_wv_symmetry)
vac_inputs = Vacuum.VacuumInput(equil, psi_array[i], ctrl.mthvac, ctrl.nzvac, intr.mlow:intr.mhigh, intr.nlow:intr.nhigh; force_wv_symmetry=ctrl.force_wv_symmetry)
wv, _, _, _, _ = Vacuum.compute_vacuum_response(vac_inputs, intr.wall_settings)
@views wv_array[i, :, :] .= wv
end
Expand Down
Loading
Loading