From dc4150299fff998f397aa0d5bcf7385b93847975 Mon Sep 17 00:00:00 2001 From: Orso Meneghini Date: Fri, 27 Jan 2023 09:14:44 -0800 Subject: [PATCH 1/3] Equilibrium --> MXHEquilibrium --- Project.toml | 2 +- src/VacuumFields.jl | 2 +- src/coil_currents.jl | 20 ++++++++++---------- test/runtests.jl | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Project.toml b/Project.toml index b65889a..8a87c31 100644 --- a/Project.toml +++ b/Project.toml @@ -8,7 +8,7 @@ Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" CoordinateConventions = "7204ce3a-f536-43d2-be4a-fbed74e90d86" DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" EFIT = "cda752c5-6b03-55a3-9e33-132a441b0c17" -Equilibrium = "187daef3-cca3-527a-8725-7379bc760182" +MXHEquilibrium = "8efa4e5a-7b9a-4eec-876e-01d13d5b5d75" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" diff --git a/src/VacuumFields.jl b/src/VacuumFields.jl index 1315cf9..90d764f 100644 --- a/src/VacuumFields.jl +++ b/src/VacuumFields.jl @@ -2,7 +2,7 @@ __precompile__() module VacuumFields -using Equilibrium +using MXHEquilibrium using Plots using Trapz using Unzip diff --git a/src/coil_currents.jl b/src/coil_currents.jl index c8c3cc7..028499e 100644 --- a/src/coil_currents.jl +++ b/src/coil_currents.jl @@ -172,7 +172,7 @@ end # ========== # # Physics # # ========== # -function fixed_boundary(EQfixed::Equilibrium.AbstractEquilibrium) +function fixed_boundary(EQfixed::MXHEquilibrium.AbstractEquilibrium) Sb = boundary(EQfixed) Rb, Zb = Sb.r, Sb.z Lb = cumlength(Rb, Zb) @@ -195,7 +195,7 @@ end Calculate ψ from image currents on boundary at surface p near boundary """ function ψp_on_fixed_eq_boundary( - EQfixed::Equilibrium.AbstractEquilibrium, + EQfixed::MXHEquilibrium.AbstractEquilibrium, fixed_coils::AbstractVector{<:AbstractCoil}=AbstractCoil[], ψbound::Real=0.0; Rx::AbstractVector{<:Real}=Real[], @@ -264,7 +264,7 @@ function field_null_on_boundary(ψp_constant::Real, # add in desired boundary flux ψbound != 0.0 && (ψp_constant .+= ψbound) - Bp_fac = Equilibrium.cocos(cocos).sigma_Bp * (2π)^Equilibrium.cocos(cocos).exp_Bp + Bp_fac = MXHEquilibrium.cocos(cocos).sigma_Bp * (2π)^MXHEquilibrium.cocos(cocos).exp_Bp # Compute flux from fixed coils and subtract from ψp to match ψfixed = zeros(length(Rp)) @@ -328,7 +328,7 @@ function currents_to_match_ψp( end function fixed_eq_currents( - EQfixed::Equilibrium.AbstractEquilibrium, + EQfixed::MXHEquilibrium.AbstractEquilibrium, coils::AbstractVector{<:AbstractCoil}, fixed_coils::AbstractVector{<:AbstractCoil}=AbstractCoil[], ψbound::Real=0.0; @@ -345,7 +345,7 @@ end # *************************************************** """ fixed2free( - EQfixed::Equilibrium.AbstractEquilibrium, + EQfixed::MXHEquilibrium.AbstractEquilibrium, n_point_coils::Integer, R::AbstractVector, Z::AbstractVector) @@ -353,7 +353,7 @@ end Distribute n point coils around fixed boundary plasma to get a free boundary ψ map """ function fixed2free( - EQfixed::Equilibrium.AbstractEquilibrium, + EQfixed::MXHEquilibrium.AbstractEquilibrium, n_coils::Integer; Rx::AbstractVector{<:Real}=Real[], Zx::AbstractVector{<:Real}=Real[], @@ -367,8 +367,8 @@ function fixed2free( return transpose(fixed2free(EQfixed, coils, Rgrid, Zgrid)) end -function encircling_coils(EQfixed::Equilibrium.AbstractEquilibrium, n_coils::Integer) - bnd = Equilibrium.boundary(EQfixed) +function encircling_coils(EQfixed::MXHEquilibrium.AbstractEquilibrium, n_coils::Integer) + bnd = MXHEquilibrium.boundary(EQfixed) R0 = sum(bnd.r) / length(bnd.r) Z0 = sum(bnd.z) / length(bnd.z) t = LinRange(0, 2π, n_coils + 1)[1:n_coils] @@ -382,7 +382,7 @@ function encircling_coils(EQfixed::Equilibrium.AbstractEquilibrium, n_coils::Int end function fixed2free( - EQfixed::Equilibrium.AbstractEquilibrium, + EQfixed::MXHEquilibrium.AbstractEquilibrium, coils::AbstractVector{<:AbstractCoil}, R::AbstractVector{<:Real}, Z::AbstractVector{<:Real}; @@ -414,7 +414,7 @@ function fixed2free( end function fixed2free( - EQfixed::Equilibrium.AbstractEquilibrium, + EQfixed::MXHEquilibrium.AbstractEquilibrium, coils::AbstractVector{<:ParallelogramCoil}, R::AbstractVector{<:Real}, Z::AbstractVector{<:Real}; diff --git a/test/runtests.jl b/test/runtests.jl index 17207eb..d2541b5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,7 +1,7 @@ using VacuumFields using Test using EFIT -using Equilibrium +using MXHEquilibrium import DelimitedFiles using Plots From bc2e40f82a83dbd8e78eebf25779c56a5ae0b519 Mon Sep 17 00:00:00 2001 From: Orso Meneghini Date: Fri, 27 Jan 2023 12:15:04 -0800 Subject: [PATCH 2/3] more MXHEquilibrium compatibility --- src/coil_currents.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coil_currents.jl b/src/coil_currents.jl index 028499e..eaf660a 100644 --- a/src/coil_currents.jl +++ b/src/coil_currents.jl @@ -173,7 +173,7 @@ end # Physics # # ========== # function fixed_boundary(EQfixed::MXHEquilibrium.AbstractEquilibrium) - Sb = boundary(EQfixed) + Sb = MXHEquilibrium.plasma_boundary(EQfixed) Rb, Zb = Sb.r, Sb.z Lb = cumlength(Rb, Zb) @@ -368,7 +368,7 @@ function fixed2free( end function encircling_coils(EQfixed::MXHEquilibrium.AbstractEquilibrium, n_coils::Integer) - bnd = MXHEquilibrium.boundary(EQfixed) + bnd = MXHEquilibrium.plasma_boundary(EQfixed) R0 = sum(bnd.r) / length(bnd.r) Z0 = sum(bnd.z) / length(bnd.z) t = LinRange(0, 2π, n_coils + 1)[1:n_coils] @@ -388,10 +388,10 @@ function fixed2free( Z::AbstractVector{<:Real}; tp=Float64) - ψb = psi_boundary(EQfixed) + ψb, Sb = MXHEquilibrium.plasma_boundary_psi(EQfixed) + Bp_fac = EQfixed.cocos.sigma_Bp * (2π)^EQfixed.cocos.exp_Bp - Sb = boundary(EQfixed) ψ_f2f = [in_boundary(Sb, (r, z)) ? tp(EQfixed(r, z)) : ψb for z in Z, r in R] Rb, Zb, Lb, dψdn_R = fixed_boundary(EQfixed) From 6f8c2cb69a2b094e3e588303ddea9627e1d85937 Mon Sep 17 00:00:00 2001 From: Orso Meneghini Date: Thu, 2 Feb 2023 22:52:05 -0800 Subject: [PATCH 3/3] fix fixed2free for MXHEquilibrium --- Project.toml | 3 ++- src/VacuumFields.jl | 1 + src/coil_currents.jl | 35 ++++++++++++++--------------------- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/Project.toml b/Project.toml index 8a87c31..3000cac 100644 --- a/Project.toml +++ b/Project.toml @@ -8,8 +8,9 @@ Contour = "d38c429a-6771-53c6-b99e-75d170b6e991" CoordinateConventions = "7204ce3a-f536-43d2-be4a-fbed74e90d86" DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab" EFIT = "cda752c5-6b03-55a3-9e33-132a441b0c17" -MXHEquilibrium = "8efa4e5a-7b9a-4eec-876e-01d13d5b5d75" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MXHEquilibrium = "8efa4e5a-7b9a-4eec-876e-01d13d5b5d75" +MillerExtendedHarmonic = "c82744c2-dc08-461a-8c37-87ab04d0f9b8" Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/VacuumFields.jl b/src/VacuumFields.jl index 90d764f..c8add24 100644 --- a/src/VacuumFields.jl +++ b/src/VacuumFields.jl @@ -2,6 +2,7 @@ __precompile__() module VacuumFields +import MillerExtendedHarmonic using MXHEquilibrium using Plots using Trapz diff --git a/src/coil_currents.jl b/src/coil_currents.jl index eaf660a..dd19983 100644 --- a/src/coil_currents.jl +++ b/src/coil_currents.jl @@ -1,6 +1,6 @@ abstract type AbstractCoil end -mutable struct PointCoil{R1<:Real, R2<:Real, R3<:Real} <: AbstractCoil +mutable struct PointCoil{R1<:Real,R2<:Real,R3<:Real} <: AbstractCoil R::R1 Z::R2 current::R3 @@ -14,7 +14,7 @@ PointCoil(R, Z) = PointCoil(R, Z, 0.0) Parallelogram coil with the R, Z, ΔR, ΔZ, θ₁, θ₂ formalism (as used by EFIT, for example) Here θ₁ and θ₂ are the shear angles along the x- and y-axes, respectively, in degrees. """ -mutable struct ParallelogramCoil{R1<:Real, R2<:Real, R3<:Real, R4<:Real, R5<:Real, R6<:Real, UNR<:Union{Nothing,Real}, R7<:Real} <: AbstractCoil +mutable struct ParallelogramCoil{R1<:Real,R2<:Real,R3<:Real,R4<:Real,R5<:Real,R6<:Real,UNR<:Union{Nothing,Real},R7<:Real} <: AbstractCoil R::R1 Z::R2 ΔR::R3 @@ -31,7 +31,7 @@ function ParallelogramCoil(R::Real, Z::Real, ΔR::Real, ΔZ::Real, θ₁::Real, return ParallelogramCoil(R, Z, ΔR, ΔZ, θ₁, θ₂, spacing) end -mutable struct DistributedCoil{AVR1<:AbstractVector{<:Real}, AVR2<:AbstractVector{<:Real}, R1<:Real} <: AbstractCoil +mutable struct DistributedCoil{AVR1<:AbstractVector{<:Real},AVR2<:AbstractVector{<:Real},R1<:Real} <: AbstractCoil R::AVR1 Z::AVR2 current::R1 @@ -173,7 +173,7 @@ end # Physics # # ========== # function fixed_boundary(EQfixed::MXHEquilibrium.AbstractEquilibrium) - Sb = MXHEquilibrium.plasma_boundary(EQfixed) + Sb = MXHEquilibrium.plasma_boundary(EQfixed; precision=0.0) Rb, Zb = Sb.r, Sb.z Lb = cumlength(Rb, Zb) @@ -203,7 +203,7 @@ function ψp_on_fixed_eq_boundary( fraction_inside::Union{Nothing,Real}=0.999) ψ0, ψb = psi_limits(EQfixed) - ψb = psi_boundary(EQfixed) + ψb = psi_boundary(EQfixed; precision=0.0) # ψp is the flux from the image currents on the plasma boundary # which is equal and opposite to the flux from the plasma current @@ -363,22 +363,16 @@ function fixed2free( coils = encircling_coils(EQfixed, n_coils) Bp_fac, ψp, Rp, Zp = ψp_on_fixed_eq_boundary(EQfixed, coils; fraction_inside, Rx, Zx) - currents_to_match_ψp(Bp_fac, ψp, Rp, Zp, coils; λ_regularize=1E-15) + currents_to_match_ψp(Bp_fac, ψp, Rp, Zp, coils; λ_regularize=1E-12) return transpose(fixed2free(EQfixed, coils, Rgrid, Zgrid)) end function encircling_coils(EQfixed::MXHEquilibrium.AbstractEquilibrium, n_coils::Integer) - bnd = MXHEquilibrium.plasma_boundary(EQfixed) - R0 = sum(bnd.r) / length(bnd.r) - Z0 = sum(bnd.z) / length(bnd.z) - t = LinRange(0, 2π, n_coils + 1)[1:n_coils] - a = R0 * 0.99 - b = (maximum(bnd.z) - minimum(bnd.z)) * 1.5 - b = max(a, b) - a = min(a, b) - coils_r = a .* cos.(t) .+ R0 - coils_z = b .* sin.(t) .+ Z0 - return [PointCoil(r, z) for (r, z) in zip(coils_r, coils_z)] + bnd = MXHEquilibrium.plasma_boundary(EQfixed; precision=0.0) + mxh = MillerExtendedHarmonic.MXH(bnd.r, bnd.z, 2) + mxh.ϵ = 0.9 + Θ = LinRange(0, 2π, n_coils)[1:end-1] + return [PointCoil(r, z) for (r, z) in mxh.(Θ)] end function fixed2free( @@ -388,8 +382,7 @@ function fixed2free( Z::AbstractVector{<:Real}; tp=Float64) - ψb, Sb = MXHEquilibrium.plasma_boundary_psi(EQfixed) - + ψb, Sb = MXHEquilibrium.plasma_boundary_psi(EQfixed; precision=0.0) Bp_fac = EQfixed.cocos.sigma_Bp * (2π)^EQfixed.cocos.exp_Bp ψ_f2f = [in_boundary(Sb, (r, z)) ? tp(EQfixed(r, z)) : ψb for z in Z, r in R] @@ -456,7 +449,7 @@ function check_fixed_eq_currents( # ψ from fixed-boundary gEQDSK # make ψ at boundary zero, and very small value outside for plotting ψ0_fix, ψb_fix = psi_limits(EQfixed) - ψb_fix = psi_boundary(EQfixed) + ψb_fix = psi_boundary(EQfixed; precision=0.0) σ₀ = sign(ψ0_fix - ψb_fix) ψ_fix = [EQfixed(r, z) for z in Z, r in R] .- ψb_fix ψ_fix = ifelse.(σ₀ * ψ_fix .> 0, ψ_fix, 1e-6 * ψ_fix) @@ -487,7 +480,7 @@ function check_fixed_eq_currents( else # Heat maps for free, fix, fix->free, and difference # ψ from free-boundary gEQDSK - ψb_free = psi_boundary(EQfree) + ψb_free = psi_boundary(EQfree; precision=0.0) ψ_free = [EQfree(r, z) for z in Z, r in R] offset = ψb_free - ψb_fix