From 31266b6b97b3d28fc91c59323029b5f5678acca8 Mon Sep 17 00:00:00 2001 From: ebursch <76970916+ebursch@users.noreply.github.com> Date: Sat, 15 Aug 2026 09:00:33 -0400 Subject: [PATCH 01/14] INIT WIP: Tearing Feature add for calculating b_crit --- ...r-field penetration in tokamak plasmas.pdf | Bin 0 -> 917910 bytes .../DIIID-like_SLAYER_example/slayer_ex.ipynb | 72 +++ src/GeneralizedPerturbedEquilibrium.jl | 1 + .../CriticalResonantField.jl | 21 + .../CriticalResonantField/TorqueBalance.jl | 122 +++++ .../CriticalResonantField/bcrit_dev.ipynb | 285 +++++++++++ .../CriticalResonantField/bcrit_dev_ggj.ipynb | 208 ++++++++ src/Tearing/CriticalResonantField/gslayer.txt | 466 ++++++++++++++++++ src/Tearing/Tearing.jl | 4 +- 9 files changed, 1178 insertions(+), 1 deletion(-) create mode 100644 docs/resources/2006-Cole-Drift-magnetohydrodynamical model of error-field penetration in tokamak plasmas.pdf create mode 100644 examples/DIIID-like_SLAYER_example/slayer_ex.ipynb create mode 100644 src/Tearing/CriticalResonantField/CriticalResonantField.jl create mode 100644 src/Tearing/CriticalResonantField/TorqueBalance.jl create mode 100644 src/Tearing/CriticalResonantField/bcrit_dev.ipynb create mode 100644 src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb create mode 100644 src/Tearing/CriticalResonantField/gslayer.txt diff --git a/docs/resources/2006-Cole-Drift-magnetohydrodynamical model of error-field penetration in tokamak plasmas.pdf b/docs/resources/2006-Cole-Drift-magnetohydrodynamical model of error-field penetration in tokamak plasmas.pdf new file mode 100644 index 0000000000000000000000000000000000000000..17ef612ec06a3dd2111741edb73f4be3e46cfdcb GIT binary patch literal 917910 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

V8 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

v6=UXxMSTfz%%r9%KYt&Ey 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 z

    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

    Xu`4)Vi9gH2CaBG;tvvCm7);*hdpmzb??gsWU>h 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 QNN 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

    +yBm&skM6=EH7e{2E(Cf31D_e4P4_uSr0R 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ļ=KDCq_eWQ781ocid)b9Rq$9_3`n|ATFy$YS2#s% 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 LdiCnVr}pSSZ4Wdm literal 0 HcmV?d00001 diff --git a/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb b/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb new file mode 100644 index 000000000..0fb8f9079 --- /dev/null +++ b/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb @@ -0,0 +1,72 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "using Pkg\n", + "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1", + "metadata": {}, + "outputs": [], + "source": [ + "Base.active_project()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "using GeneralizedPerturbedEquilibrium\n", + "using Plots\n", + "using GeneralizedPerturbedEquilibrium: Analysis" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "h5path = \"/Users/bursche/Documents/GitHub/JPEC_BCRIT/examples/DIIID-like_SLAYER_example/gpec.h5\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "p_eq = Analysis.Equilibrium.plot_equilibrium_summary(h5path)\n", + "p_ffs = Analysis.ForceFreeStates.plot_ffs_summary(h5path)\n", + "#p_pe = Analysis.PerturbedEquilibrium.plot_perturbed_equilibrium_summary(h5path)\n", + "\n", + "display(p_eq)\n", + "display(p_ffs)\n", + "#display(p_pe)" + ] + } + ], + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/GeneralizedPerturbedEquilibrium.jl b/src/GeneralizedPerturbedEquilibrium.jl index 96f9f4b1a..5d388d8bf 100755 --- a/src/GeneralizedPerturbedEquilibrium.jl +++ b/src/GeneralizedPerturbedEquilibrium.jl @@ -47,6 +47,7 @@ export Tearing # Backward-compat top-level aliases so callers can still reach these # directly; the canonical nested path is `Tearing.{Dispersion,Runner}`. import .Tearing.Dispersion as Dispersion +import .Tearing.CriticalResonantField as CriticalResonantField import .Tearing.Runner as Runner export Dispersion, Runner diff --git a/src/Tearing/CriticalResonantField/CriticalResonantField.jl b/src/Tearing/CriticalResonantField/CriticalResonantField.jl new file mode 100644 index 000000000..453f04b73 --- /dev/null +++ b/src/Tearing/CriticalResonantField/CriticalResonantField.jl @@ -0,0 +1,21 @@ +# CriticalResonantField.jl +# +# Uses the inner-layer delta from InnerLayer.jl to find the critical resonant field +# required for mode penetration at each rational surface. This can then be compared +# to the actual resonant field from the perturbed equilibrium to determine which modes +# are predicted to penetrate. + +module CriticalResonantField + +using LinearAlgebra +using StaticArrays + +using ..InnerLayer +using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters, + SLAYERModel, SLAYERParameters + +#include("TorqueBalance.jl") + +#export TorqueBalance, torque_balance + +end # module CriticalResonantField diff --git a/src/Tearing/CriticalResonantField/TorqueBalance.jl b/src/Tearing/CriticalResonantField/TorqueBalance.jl new file mode 100644 index 000000000..c85bff102 --- /dev/null +++ b/src/Tearing/CriticalResonantField/TorqueBalance.jl @@ -0,0 +1,122 @@ +# TorqueBalance.jl +# +# `TorqueBalance` solves the torque balance eqution for each rational surface. +# It follows the derivation found in Cole PopP 2006. For simplicity, the script +# uses equation 62 of Cole. This can be improved by incorporating the true +# outer-layer Δ' from the perturbed equilibrium and then solving equation 61. +# +# The viscous torque is: +# +# T_v = 2 · P (Q_0 - Q) / ((S kappa^hat) · (b_r(r_s)/B_phi))^2 +# +# The electromagnetic torque is: +# +# T_em = Im[Δ_inner(Q)] / |alpha + Δ_inner(Q)|^2 +# +# Now solving for critical resonant field, we have: +# +# (b_r(r_s)/B_phi))^2_crit = max(2 · P (Q_0 - Q) / ((S kappa^hat) · Im[-Δ_inner(Q)^-1]) +# +# Normalizations, definitions, and other conventions are taken from the Cole paper. +# The critical resonant field is found at each rational surface. For each, the script +# scans over a range of Q values and finds the maximum value of the right-hand side of +# the equation above. + +""" + TorqueBalance{M<:InnerLayerModel, P} + +Per-surface dispersion data: `(model, params, dp_diag, dc, scale, tauk)`. +Calling `sc(Q)` returns the complex residual + +``` +r(Q) = dp_diag - scale * solve_inner(model, params, Q).tearing - dc +``` + +A root of `sc` in the complex `Q` plane is a **tearing** eigenvalue at +this surface in the *uncoupled* approximation (only the tearing channel +of the inner-layer response appears — the interchange channel enters the +full 2m×2m dispersion via `MultiSurfaceCoupling`, not this scalar form). +Coupled multi-surface eigenvalues come from `MultiSurfaceCoupling` +evaluating the determinant of the modified Δ' matrix. +""" +struct SurfaceCoupling{M<:InnerLayerModel,P} + model::M + params::P + dp_diag::ComplexF64 + dc::Float64 + scale::Float64 + tauk::Float64 +end + +function (sc::SurfaceCoupling)(Q::Number) + Δ = solve_inner(sc.model, sc.params, ComplexF64(Q)).tearing + return sc.dp_diag - sc.scale * Δ - sc.dc +end + +""" + surface_coupling(model::SLAYERModel, params::SLAYERParameters, + dp_diag::Number; dc::Real=0.0) -> SurfaceCoupling + +SLAYER convenience constructor. `scale` is set to `params.lu^(1/3)` so that +the dimensionless Δ from `riccati_f` is mapped to outer ψ-units before +subtraction from the Δ' diagonal. `tauk` is taken from `params.tauk` for use +by `MultiSurfaceCoupling` Q rescaling. +""" +function surface_coupling(model::SLAYERModel, params::SLAYERParameters, + dp_diag::Number; dc::Real=0.0) + return SurfaceCoupling(model, params, ComplexF64(dp_diag), + Float64(dc), params.lu^(1 / 3), params.tauk) +end + +""" + surface_coupling(model::GGJModel, params::GGJParameters, + dp_diag::Number) -> SurfaceCoupling + +GGJ convenience constructor. `scale` is `1.0` because GGJ's `solve_inner` +applies its own `rescale_delta` (S^(2p₁/3)·v1^(2p₁)) internally, so the +returned Δ is already in outer units. `tauk` defaults to `1.0` (GGJ has no +direct analogue of SLAYER's per-surface time normalization, so multi-surface +Q rescaling is a no-op for GGJ surfaces unless overridden). + +**No `dc` kwarg**: GGJ's 4m×4m Pletzer-Dewar residual already includes the +interchange channel, which provides Glasser (Mercier) stabilization +natively. A Δ_crit proxy (χ_parallel-matching offset on the diagonal) is +meaningful only for tearing-only slab-layer approximations like SLAYER; +for GGJ it would double-count the interchange physics. The `SurfaceCoupling` +struct's `dc` field is hard-wired to 0 here. +""" +function surface_coupling(model::GGJModel, params::GGJParameters, + dp_diag::Number) + return SurfaceCoupling(model, params, ComplexF64(dp_diag), + 0.0, 1.0, 1.0) +end + +""" + surface_coupling(model::InnerLayerModel, params, dp_diag::Number; + dc::Real=0.0, scale::Real=1.0, tauk::Real=1.0) + -> SurfaceCoupling + +Generic fallback constructor. Use this when wiring a new inner-layer model +into the dispersion solver — pass the appropriate inner→outer-units `scale` +and per-surface `tauk` explicitly. +""" +function surface_coupling(model::InnerLayerModel, params, dp_diag::Number; + dc::Real=0.0, scale::Real=1.0, tauk::Real=1.0) + return SurfaceCoupling(model, params, ComplexF64(dp_diag), + Float64(dc), Float64(scale), Float64(tauk)) +end + +function torque_balance_value(tb::TorqueBalance, Q::Number) + Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing + jxb = -imag(1.0 / (Δ + tb.delta_n_p)) + return 2.0 * tb.P * (tb.Q0 - Q) / jxb +end + +function scan_torque_balance(tb; Qmin=-10.0, Qmax=10.0, nscan=200) + qs = range(Qmin, Qmax; length=nscan) + vals = torque_balance_value.(Ref(tb), qs) + idx = argmax(vals) + return qs[idx], vals[idx] +end + +br_th = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0)) diff --git a/src/Tearing/CriticalResonantField/bcrit_dev.ipynb b/src/Tearing/CriticalResonantField/bcrit_dev.ipynb new file mode 100644 index 000000000..a6186408f --- /dev/null +++ b/src/Tearing/CriticalResonantField/bcrit_dev.ipynb @@ -0,0 +1,285 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "using Pkg\n", + "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", + "Base.active_project()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1", + "metadata": {}, + "outputs": [], + "source": [ + "using GeneralizedPerturbedEquilibrium\n", + "using GeneralizedPerturbedEquilibrium: Analysis\n", + "using GeneralizedPerturbedEquilibrium: InnerLayer\n", + "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", + "using GeneralizedPerturbedEquilibrium: Tearing\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "using Plots\n", + "default(\n", + " fontfamily=\"Georgia\",\n", + " margin=12Plots.mm,\n", + " size=(800, 500),\n", + " dpi=150\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "struct TorqueBalance\n", + " model\n", + " params\n", + " Q0::Float64\n", + " P::Float64\n", + " delta_n_p::Float64\n", + " lu::Float64\n", + " sval::Float64\n", + "end\n", + "\n", + "function torque_balance_value(tb::TorqueBalance, Q::Number)\n", + " Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing\n", + " jxb = -imag(1.0 / (Δ + tb.delta_n_p))\n", + " return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ\n", + "end\n", + "\n", + "function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200)\n", + " Qs = range(Qmin, Qmax; length=n)\n", + " torque_out = [torque_balance_value(tb, q) for q in Qs]\n", + " bal = [x[1] for x in torque_out]\n", + " Δs = [x[2] for x in torque_out]\n", + " #bal = [torque_balance_value(tb, q) for q in Qs]\n", + " positive = isfinite.(bal) .& (bal .> 0.0)\n", + "\n", + " if !any(positive)\n", + " return Qs, bal, NaN, 0.0\n", + " end\n", + " i = argmax(bal)\n", + " Qpeak_ind = i\n", + " Qs_positive = Qs[positive]\n", + " bal_positive = bal[positive]\n", + "\n", + " i = argmax(bal_positive)\n", + " Qpeak = Qs_positive[i]\n", + " \n", + " maxbal = bal_positive[i]\n", + "\n", + " br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", + " return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "# You can substitute any valid SLAYERParameters you already have.\n", + "# This is just an example skeleton.\n", + "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", + " n_e=1e19, t_e=1e3, t_i=1e3,\n", + " omega=0.0, omega_e=4, omega_i=-2,\n", + " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", + " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", + ")\n", + "p2 = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", + " ising=p.ising,\n", + " m=p.m, n=p.n,\n", + " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", + " P_perp=p.P_perp, P_tor=p.P_tor,\n", + " Q_e=4 / p.tauk, Q_i=-10 / p.tauk, iota_e=p.iota_e,\n", + " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", + " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", + " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", + " eta=p.eta, d_beta=p.d_beta,\n", + " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", + ")\n", + "\n", + "#p = p2\n", + "\n", + "tb = TorqueBalance(\n", + " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", + " p,\n", + " 0.5,\n", + " 1.0,\n", + " 1e-2,\n", + " p.lu,\n", + " p.sval_r\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"\n", + "\n", + "tau_h=R0*(mu0*rho)**0.5/(nns*sval*bt) ! alfven time across surface\n", + "lu=tau_r/tau_h ! Lundquist number\n", + "Qconv=lu**(1.0/3.0)*tau_h ! conversion to Qs based on Cole\n", + "\n", + "! note Q depends on Qconv even if omega is fixed.\n", + "Q=Qconv*omega\n", + "Q_e=-Qconv*omega_e\n", + "Q_i=-Qconv*omega_i\n", + "\n", + "\"\"\"\n", + "2=-lu**(1.0/3.0)*tau_h *OE\n", + "2 = tauk *OE" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "Qs = range(-5.0, 5.0, length=200)\n", + "\n", + "vals = [torque_balance_value(tb, q) for q in Qs]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"\n", + "n=2000:\n", + "Qpeak = 0.24512256128064033\n", + "maxbal = 0.35873684252530247\n", + "br_crit = 4.668551985584323e-5\n", + "\n", + "n=200 (def):\n", + "Qpeak = 0.25125628140703515\n", + "maxbal = 0.3585219071071706\n", + "br_crit = 4.667153206033017e-5\n", + "\"\"\"\n", + "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb)\n", + "\n", + "println(\"Qpeak = \", Qpeak)\n", + "println(\"maxbal = \", maximum(bal_positive))\n", + "println(\"maxbal = \", maximum(bal))\n", + "println(\"br_crit = \", brcrit)\n", + "\n", + "p1 = plot(Qs, bal, lw=2, label=\"balance\")\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"balance\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "p2 = plot(Qs_positive, bal_positive, lw=2, label=\"balance (positive)\")\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"balance\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "plot(p1, p2, layout=(2,1), size=(800, 1000))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], + "source": [ + "Qpk = Qs_positive[argmax(bal_positive)]\n", + "j = findfirst(isequal(Qpk), Qs)\n", + "\n", + "lhs = 2*tb.P*(tb.Q0 - Qpk) / jxbs[j]\n", + "br_ratio = sqrt(lhs / (tb.lu * tb.sval^2 / 2))\n", + "\n", + "rhs = (tb.lu * tb.sval^2 / 2) * br_ratio^2\n", + "\n", + "println(\"lhs = \", lhs)\n", + "println(\"rhs = \", rhs)\n", + "println(\"lhs/rhs = \", lhs / rhs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": {}, + "outputs": [], + "source": [ + "#Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing for q in Qs]\n", + "jxbs = [-imag(1.0 / (d + tb.delta_n_p)) for d in Δs]\n", + "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for (q, jxb) in zip(Qs, jxbs)]\n", + "br_t = brcrit\n", + "println(tb.lu, \" \", tb.sval, \" \", br_t, \" \", p.bt, \" \", tb.delta_n_p)\n", + "T_EM = tb.lu * tb.sval^2/2 * (br_t / p.bt)^2 * jxbs\n", + "i = Qpeak_ind\n", + "println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", + "println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", + "println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", + "\n", + "#T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", + "#T_visc ∝ 2 P (Q0 − Q)\n", + "\n", + "p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", + "#plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Δ\")\n", + "title!(p1, \"Inner-layer Δ(Q)\")\n", + "\n", + "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + "plot!(p2, Qs, T_VISC, label=\"2P(Q0-Q)\", lw=2)\n", + "plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", + "xlabel!(p2, \"Q\")\n", + "ylabel!(p2, \"jxb\")\n", + "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", + "\n", + "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", + "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + "xlabel!(p3, \"Q\")\n", + "ylabel!(p3, \"balance\")\n", + "title!(p3, \"2P(Q0-Q)/jxb\")\n", + "\n", + "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" + ] + } + ], + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb b/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb new file mode 100644 index 000000000..94f04beac --- /dev/null +++ b/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb @@ -0,0 +1,208 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "using Pkg\n", + "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", + "Base.active_project()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1", + "metadata": {}, + "outputs": [], + "source": [ + "using GeneralizedPerturbedEquilibrium\n", + "using GeneralizedPerturbedEquilibrium: GGJParameters\n", + "using GeneralizedPerturbedEquilibrium\n", + "using GeneralizedPerturbedEquilibrium: InnerLayer\n", + "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", + "import GeneralizedPerturbedEquilibrium.InnerLayer.GGJ: sfac\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "using Plots\n", + "default(\n", + " fontfamily=\"Georgia\",\n", + " margin=12Plots.mm,\n", + " size=(800, 500),\n", + " dpi=150\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "struct TorqueBalance\n", + " model\n", + " params\n", + " Q0::Float64\n", + " P::Float64\n", + " delta_n_p::Float64\n", + " lu::Float64\n", + " sval::Float64\n", + "end\n", + "\n", + "function torque_balance_value(tb::TorqueBalance, Q::Number)\n", + " Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing\n", + " jxb = -imag(1.0 / (Δ + tb.delta_n_p))\n", + " return 2.0 * tb.P * (tb.Q0 - Q) / jxb\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "# You can substitute any valid SLAYERParameters you already have.\n", + "# This is just an example skeleton.\n", + "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", + " n_e=1e19, t_e=1e3, t_i=1e3,\n", + " omega=0.0, omega_e=4, omega_i=-2,\n", + " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", + " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", + ")\n", + "\n", + "tb = TorqueBalance(\n", + " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", + " p,\n", + " 0.5,\n", + " 1.0,\n", + " 1e-2,\n", + " p.lu,\n", + " p.sval_r\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "p_ggj = GeneralizedPerturbedEquilibrium.InnerLayer.glasser_wang_2020_eq55()\n", + "lu_ggj = sfac(p_ggj)\n", + "sval_ggj = 0.5\n", + "\n", + "tb = TorqueBalance(\n", + " GeneralizedPerturbedEquilibrium.InnerLayer.GGJModel(; solver=:ray),\n", + " p_ggj,\n", + " 0.5,\n", + " 1.0,\n", + " 1e-2,\n", + " lu_ggj,\n", + " sval_ggj\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "\"\"\"\n", + "\n", + "tau_h=R0*(mu0*rho)**0.5/(nns*sval*bt) ! alfven time across surface\n", + "lu=tau_r/tau_h ! Lundquist number\n", + "Qconv=lu**(1.0/3.0)*tau_h ! conversion to Qs based on Cole\n", + "\n", + "! note Q depends on Qconv even if omega is fixed.\n", + "Q=Qconv*omega\n", + "Q_e=-Qconv*omega_e\n", + "Q_i=-Qconv*omega_i\n", + "\n", + "\"\"\"\n", + "2=-lu**(1.0/3.0)*tau_h *OE\n", + "OE = -2 " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": {}, + "outputs": [], + "source": [ + "Qs = range(-5.0, 5.0, length=200)\n", + "\n", + "vals = [torque_balance_value(tb, q) for q in Qs]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], + "source": [ + "plot(Qs, real.(vals), label=\"Re(balance)\", lw=2)\n", + "plot!(Qs, imag.(vals), label=\"Im(balance)\", lw=2)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"torque balance\")\n", + "title!(\"tb(Q)\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": {}, + "outputs": [], + "source": [ + "Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing for q in Qs]\n", + "jxbs = [-imag(1.0 / (d + tb.delta_n_p)) for d in Δs]\n", + "\n", + "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Δ\")\n", + "title!(p1, \"Inner-layer Δ(Q)\")\n", + "\n", + "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + "xlabel!(p2, \"Q\")\n", + "ylabel!(p2, \"jxb\")\n", + "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", + "\n", + "p3 = plot(Qs, real.(vals), label=\"Re(balance)\", lw=2)\n", + "plot!(p3, Qs, imag.(vals), label=\"Im(balance)\", lw=2)\n", + "xlabel!(p3, \"Q\")\n", + "ylabel!(p3, \"balance\")\n", + "title!(p3, \"2P(Q0-Q)/jxb\")\n", + "\n", + "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" + ] + } + ], + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/Tearing/CriticalResonantField/gslayer.txt b/src/Tearing/CriticalResonantField/gslayer.txt new file mode 100644 index 000000000..91cc2f862 --- /dev/null +++ b/src/Tearing/CriticalResonantField/gslayer.txt @@ -0,0 +1,466 @@ + MODULE gslayer_mod + + USE sglobal_mod, ONLY: out_unit, r8, mu0, m_p, chag, lnLamb, + $ Q_e,Q_i,pr,pe,c_beta,ds,tau, + $ eta,visc,rho_s,lu,omega_e,omega_i, + $ delta_n,layfac, + $ Q + USE delta_mod, ONLY: riccati,riccati_out, + $ parflow_flag,PeOhmOnly_flag + + IMPLICIT NONE + +c----------------------------------------------------------------------- +c torque balance scan resolution. public so that gpout_singfld can +c size the netcdf dimension from the same source of truth. +c----------------------------------------------------------------------- + INTEGER, PARAMETER :: slayer_inum=200 + INTEGER, PARAMETER :: slayer_nref=4 +c----------------------------------------------------------------------- +c dedicated logarithmic sampling window bracketing Q_e, the electron +c diamagnetic frequency. (Q-Q_e) sits in the denominator of both G +c and C3 in delta.f, so the layer solve is singular there; the +c coarse scan steps over that neighbourhood with dQ=0.1 and the +c adaptive refinement only visits it when the torque-balance peak +c happens to land on it. These samples always resolve it, so the +c structure can be inspected on every surface rather than only on +c the ones that fell into it. +c +c PURELY DIAGNOSTIC: filled after br_th is computed, and tagged +c kpass=slayer_qetag so the threshold search cannot see them. +c Costs slayer_nqe extra lsode solves per surface (~40% on top of +c the 1005 the scan already does). +c----------------------------------------------------------------------- + INTEGER, PARAMETER :: slayer_nqe=400 + INTEGER, PARAMETER :: slayer_qetag=99 + REAL(r8), PARAMETER :: slayer_qefar=1.0e-1_r8 + REAL(r8), PARAMETER :: slayer_qenear=1.0e-9_r8 + INTEGER, PARAMETER :: slayer_nq=(slayer_inum+1)*(slayer_nref+1) + $ +slayer_nqe +c----------------------------------------------------------------------- +c every term of Cole & Fitzpatrick Eq. (61) on one rational +c surface, +c Im[Delta]/|alpha+Delta|**2 +c = 2*P*(Q0-Q)/(S*kappa_hat*(b_r/B_phi)**2) +c recorded so the balance can be rebuilt piece by piece and +c rescanned in post processing. every component is default +c initialized, so both ALLOCATE and INTENT(OUT) leave a well +c defined (zero) state even when the layer solve is skipped. +c +c kpass tags the scan pass that produced each sample: 0 for the +c coarse scan, 1..slayer_nref for the adaptive refinement passes. +c----------------------------------------------------------------------- + TYPE :: slayer_diag_type + REAL(r8), DIMENSION(slayer_nq) :: qs=0.0_r8 + REAL(r8), DIMENSION(slayer_nq) :: lhs=0.0_r8 + REAL(r8), DIMENSION(slayer_nq) :: rhs=0.0_r8 + REAL(r8), DIMENSION(slayer_nq) :: bal=0.0_r8 + REAL(r8), DIMENSION(slayer_nq) :: brb=0.0_r8 + COMPLEX(r8), DIMENSION(slayer_nq) :: dlt=(0.0_r8,0.0_r8) + INTEGER, DIMENSION(slayer_nq) :: kpass=0 + REAL(r8) :: alpha=0.0_r8, kaphat=0.0_r8, slun=0.0_r8 + REAL(r8) :: prnd=0.0_r8, q0v=0.0_r8, qcnv=0.0_r8 + REAL(r8) :: qev=0.0_r8, qiv=0.0_r8, dsv=0.0_r8 + REAL(r8) :: cbeta=0.0_r8, tratio=0.0_r8, pev=0.0_r8 + REAL(r8) :: lfac=0.0_r8, dnorm=0.0_r8, rhos=0.0_r8 + REAL(r8) :: etav=0.0_r8, viscv=0.0_r8, tauh=0.0_r8 + REAL(r8) :: taur=0.0_r8, tauv=0.0_r8, taui=0.0_r8 + REAL(r8) :: shr=0.0_r8, bl=0.0_r8, va=0.0_r8 + REAL(r8) :: rhom=0.0_r8, lbet=0.0_r8, omg=0.0_r8 + REAL(r8) :: qsol=0.0_r8, wsol=0.0_r8, brth=0.0_r8 + REAL(r8) :: mxbal=0.0_r8, qmn=0.0_r8, qmx=0.0_r8 + END TYPE slayer_diag_type + + CONTAINS + +c----------------------------------------------------------------------- +c subprogram 1. gpec_slayer. +c run slayer to provide b_crit(ising). +c----------------------------------------------------------------------- +c----------------------------------------------------------------------- +c declarations. +c----------------------------------------------------------------------- + SUBROUTINE gpec_slayer(n_e,t_e,n_i,t_i,zeff,omega,omega_e, + $ omega_i,qval,sval,bt,rs,R0,mu_i,inpr,mms,nns,ascii_flag, + $ delta,psi0,jxb,omega_sol,br_th,diag,inlayfac,inlayfrac) + + REAL(r8),INTENT(IN) :: n_e,t_e,n_i,t_i,omega,omega_e,omega_i, + $ qval,sval,bt,rs,R0,zeff,inpr + REAL(r8),INTENT(IN),OPTIONAL :: inlayfac,inlayfrac + REAL(r8) :: layfac_max,layfac_frac + INTEGER, INTENT(IN) :: mms,nns,mu_i + LOGICAL, INTENT(IN) :: ascii_flag + COMPLEX(r8),INTENT(OUT) :: delta,psi0 + REAL(r8),INTENT(OUT) :: jxb,omega_sol,br_th + TYPE(slayer_diag_type), INTENT(OUT), OPTIONAL :: diag + + INTEGER :: i,inum + INTEGER, DIMENSION(1) :: index + + REAL(r8) :: inQ,inQ_e,inQ_i,inpe,inc_beta,inds,intau,inlu + REAL(r8) :: mrs,nrs,rho,b_l,v_a,Qconv,Q0,delta_n_p, + $ lbeta,tau_i,tau_h,tau_r,tau_v + REAL(r8) :: inQ_min,inQ_max,Q_sol,maxbal + INTEGER :: ipass + INTEGER, PARAMETER :: nref=slayer_nref + REAL(r8) :: xpk,rlo,rhi,rdq,rdqc,xq,bloc,jloc + COMPLEX(r8) :: dloc + +c Eq. (61) term capture. cqs/cdlt/clhs/crhs/cbal/cbrb hold every +c sample of the coarse and refinement scans, cpass its pass tag, +c and iperm the permutation that sorts them by ascending Q. + INTEGER :: j,k,kk + INTEGER, DIMENSION(slayer_nq) :: iperm,cpass + REAL(r8), DIMENSION(slayer_nq) :: cqs,clhs,crhs,cbal,cbrb + COMPLEX(r8), DIMENSION(slayer_nq) :: cdlt + REAL(r8) :: kaphat,xtmp + + REAL(r8), DIMENSION(:), ALLOCATABLE :: inQs,iinQs,jxbl,bal + COMPLEX(r8), DIMENSION(:), ALLOCATABLE :: deltal + CHARACTER(3) :: sn,sm + + parflow_flag=.FALSE. + PeOhmOnly_flag=.TRUE. + riccati_out=.FALSE. + + mrs = real(mms,4) + nrs = real(nns,4) + + ! String representations of the m and n mode numbers + IF (nns<10) THEN + WRITE(UNIT=sn,FMT='(I1)') nns + sn=ADJUSTL(sn) + ELSE + WRITE(UNIT=sn,FMT='(I2)') nns + ENDIF + IF (mms<10) THEN + WRITE(UNIT=sm,FMT='(I1)') mms + sm=ADJUSTL(sm) + ELSEIF (mms<100) THEN + WRITE(UNIT=sm,FMT='(I2)') mms + sm=ADJUSTL(sm) + ELSE + WRITE(UNIT=sm,FMT='(I3)') mms + ENDIF + + inpe=0.0 ! Waybright added this + + tau= t_i/t_e ! ratio of ion to electron temperature + tau_i = 6.6e17*mu_i**0.5*(t_i/1e3)**1.5/(n_e*lnLamb) ! ion colls. + eta= 1.65e-9*lnLamb/(t_e/1e3)**1.5 ! spitzer resistivity (wesson) + rho=(mu_i*m_p)*n_e ! mass density + + b_l=(nrs/mrs)*rs*sval*bt/R0 ! characteristic magnetic field + v_a=b_l/(mu0*rho)**0.5 ! alfven velocity + rho_s=1.02e-4*(mu_i*t_e)**0.5/bt ! ion Lamour by elec. Temp. + + tau_h=R0*(mu0*rho)**0.5/(nns*sval*bt) ! alfven time across surface + tau_r=mu0*rs**2.0/eta ! resistive time scale + tau_v=tau_r/inpr ! rho*rs**2.0/visc ! viscous time scale + + ! this one must be anomalous. calculated back from pr. + visc= rho*rs**2.0/tau_v + + lu=tau_r/tau_h ! Lundquist number + + Qconv=lu**(1.0/3.0)*tau_h ! conversion to Qs based on Cole + + ! note Q depends on Qconv even if omega is fixed. + Q=Qconv*omega + Q_e=-Qconv*omega_e + Q_i=-Qconv*omega_i + + ! This is the most critical parameter + ds=lu**(1.0/3.0)*rho_s/rs ! conversion based on Cole. + + lbeta=(5.0/3.0)*mu0*n_e*chag*(t_e+t_i)/bt**2.0 + c_beta=(lbeta/(1.0+lbeta))**0.5 + + delta_n=lu**(1.0/3.0)/rs ! norm factor for delta primes + + inQ=Q + inQ_e=Q_e + inQ_i=Q_i + inc_beta=c_beta + inds=ds + intau=tau + Q0=Q +c----------------------------------------------------------------------- +c set the layer regularization width. +c +c riccati excises a disc of radius layfac around Q_e, where Im[Delta] +c has a zero and bal=2P(Q0-Q)/lhs therefore has a pole. Without it the +c coarse scan and its refinement walk into that pole and MAXVAL(bal) +c returns a threshold set by the scan spacing rather than by the +c saddle-node bifurcation. gpec_slayer never assigned layfac, so on +c this path the guard was dead. +c +c A fixed width is not safe on every surface: the disc [Q_e-layfac, +c Q_e+layfac] can be a large fraction of the physical branch, and on +c high-m surfaces it can swallow the turning point or Q0 itself -- +c quietly, since a number still comes back. So the width is scaled to +c the accessible branch |Q0-Q_e| and capped: +c +c layfac_frac > 0 : layfac = MIN(layfac_max, layfac_frac*|Q0-Q_e|) +c layfac_frac <= 0: layfac = layfac_max (fixed width) +c layfac_max <= 0: layfac = 0 (guard off) +c +c Exposed through gpec.in so the choice is auditable per run; it is a +c physics judgement, not a constant. +c----------------------------------------------------------------------- + layfac_max=0.02_r8 + IF (PRESENT(inlayfac)) layfac_max=inlayfac + layfac_frac=0.25_r8 + IF (PRESENT(inlayfrac)) layfac_frac=inlayfrac + IF (layfac_max>0.0_r8) THEN + IF (layfac_frac>0.0_r8) THEN + layfac=MIN(layfac_max,layfac_frac*ABS(Q0-inQ_e)) + ELSE + layfac=layfac_max + ENDIF + ELSE + layfac=0.0_r8 + ENDIF +c----------------------------------------------------------------------- +c calculate basic delta, torque, balance, error fields. +c----------------------------------------------------------------------- + delta_n_p=1e-2 + ! kappa_hat of Eq. (61) is implicit in the br_th expression at the + ! end of this routine: sqrt(maxbal/lu*(sval**2/2)) is identically + ! sqrt(maxbal/(lu*kappa_hat)) for kappa_hat=2/sval**2. Named here + ! for output only; it is never used in a physics expression, so + ! the threshold is unchanged. + IF (sval/=0.0_r8) THEN + kaphat=2.0_r8/sval**2.0 + ELSE + kaphat=0.0_r8 + ENDIF + delta=riccati(inQ,inQ_e,inQ_i,inpr,inc_beta,inds,intau,inpe) + psi0=1.0/ABS(delta+delta_n_p) ! a.u. + jxb=-AIMAG(1.0/(delta+delta_n_p)) ! a.u. +c---------------------------------------------------------------------- +c find solutions based on simple torque balance. +c----------------------------------------------------------------------- + IF (Q0>inQ_e) THEN + inQ_max=2.0*Q0 + inQ_min=1.05*inQ_e + ELSE + inQ_max=0.95*inQ_e + IF (Q0>0) THEN + inQ_min=0.8*inQ_i + ELSE + inQ_min=1.5*MINVAL((/Q0,inQ_i/)) + ENDIF + ENDIF + + ! Scan of rotation + inQ_max=10.0 + inQ_min=-10.0 + inum=slayer_inum + ALLOCATE(inQs(0:inum),deltal(0:inum),jxbl(0:inum),bal(0:inum)) + DO i=0,inum + inQs(i)=inQ_min+(REAL(i)/inum)*(inQ_max-inQ_min) + deltal(i)=riccati(inQs(i),inQ_e,inQ_i, + $ inpr,inc_beta,inds,intau,inpe) + jxbl(i)=-AIMAG(1.0/(deltal(i)+delta_n_p)) + bal(i)=2.0*inpr*(Q0-inQs(i))/jxbl(i) + ENDDO + + ! Capture the coarse pass (tag 0). This only reads inQs/deltal/ + ! jxbl/bal, so both the ascii dump and the refinement below are + ! bit for bit unchanged. The Eq. (61) right hand side numerator + ! is recomputed rather than harvested out of the bal expression + ! above; 2.0*inpr*(Q0-inQs(i)) is a pure product chain, so the + ! recomputed value is identical to the one formed inline. + DO i=0,inum + cqs(i+1)=inQs(i) + cdlt(i+1)=deltal(i) + clhs(i+1)=jxbl(i) + crhs(i+1)=2.0*inpr*(Q0-inQs(i)) + cbal(i+1)=bal(i) + cpass(i+1)=0 + ENDDO + + ! Write torque balance curves to file for diagnostic purposes + IF(ascii_flag)THEN + OPEN(UNIT=out_unit,FILE="gpec_slayer_torque_balance_m"// + $ TRIM(sm)//"_n"//TRIM(sn)//".out", + $ STATUS="UNKNOWN") + WRITE(out_unit,'(1x,5(a17))') "inQ","RE(delta)", + $ "IM(delta)","jxb","bal" + DO i=0,inum + WRITE(out_unit,'(1x,5(es17.8e3))') + $ inQs(i),REAL(deltal(i)),AIMAG(deltal(i)),jxbl(i),bal(i) + ENDDO + CLOSE(out_unit) + ENDIF + + ! The coarse scan above gives the overall torque-balance shape + ! and the diagnostic output. The locking "nose" (the maximum of + ! bal) can be a very narrow spike near inQ=Q0, however, and the + ! coarse grid can step right over it, leaving a spuriously + ! negative MAXVAL(bal) and hence a NaN br_th. Bracket the coarse + ! maximum and iteratively refine the scan around the running peak + ! so the nose is resolved regardless of how narrow it is. Exclude + ! non-finite entries (NaN from 0/0, Inf from a near-zero jxbl). + index=MAXLOC(bal,MASK=(bal==bal .AND. ABS(bal)maxbal) THEN + maxbal=bloc + xpk=xq + ENDIF + ENDDO + rlo=xpk-2.0*rdq + rhi=xpk+2.0*rdq + ENDDO + Q_sol=xpk + omega_sol=xpk/Qconv + ! If even the refined nose is non-positive the surface has no + ! finite penetration threshold; floor at zero and warn rather + ! than propagating a NaN into b_crit/Phi_res_crit downstream. + IF (maxbal>0.0_r8) THEN + br_th=sqrt(maxbal/lu*(sval**2.0/2.0)) + ELSE + br_th=0.0_r8 + WRITE(*,'(1x,a,i0,a,i0,a)') + $ "!! WARNING: SLAYER torque balance has no positive "// + $ "maximum at m=",mms,", n=",nns,"; br_th set to 0" + ENDIF +c----------------------------------------------------------------------- +c assemble the Eq. (61) record: b_r/B_phi implied by each balance +c point, then merge the coarse and refined samples onto one +c ascending Q grid so the narrow nose is densely resolved and the +c curve can be interpolated in post processing. +c----------------------------------------------------------------------- + ! Dedicated logarithmic sweep through the Q_e singularity, half + ! the samples on each side, |Q-Q_e| running from slayer_qefar in + ! to slayer_qenear. br_th is already fixed above and these are + ! tagged slayer_qetag, so they are invisible to the peak search. + DO i=1,slayer_nqe/2 + xq=slayer_qefar*(slayer_qenear/slayer_qefar) + $ **(REAL(i-1,r8)/REAL(slayer_nqe/2-1,r8)) + DO j=0,1 + k=(inum+1)*(nref+1)+(i-1)*2+j+1 + IF (j==0) THEN + cqs(k)=inQ_e-xq + ELSE + cqs(k)=inQ_e+xq + ENDIF + cdlt(k)=riccati(cqs(k),inQ_e,inQ_i,inpr, + $ inc_beta,inds,intau,inpe) + clhs(k)=-AIMAG(1.0/(cdlt(k)+delta_n_p)) + crhs(k)=2.0*inpr*(Q0-cqs(k)) + cbal(k)=crhs(k)/clhs(k) + cpass(k)=slayer_qetag + ENDDO + ENDDO + ! deliberately the same expression form as br_th above, so the + ! peak sample reproduces br_th exactly rather than differing in + ! the last bit. + DO k=1,slayer_nq + IF (cbal(k)==cbal(k) .AND. cbal(k)>0.0_r8 + $ .AND. ABS(cbal(k))=1) + IF (cqs(iperm(j))<=xtmp) EXIT + iperm(j+1)=iperm(j) + j=j-1 + ENDDO + iperm(j+1)=kk + ENDDO + IF (PRESENT(diag)) THEN + DO k=1,slayer_nq + kk=iperm(k) + diag%qs(k)=cqs(kk) + diag%dlt(k)=cdlt(kk) + diag%lhs(k)=clhs(kk) + diag%rhs(k)=crhs(kk) + diag%bal(k)=cbal(kk) + diag%brb(k)=cbrb(kk) + diag%kpass(k)=cpass(kk) + ENDDO + ! scalars are taken from the local copies, never from the + ! sglobal_mod globals Q/Q_e/Q_i/ds/tau/c_beta/pr/pe: riccati + ! overwrites those on every call, so by this point the module + ! Q holds the last refinement sample rather than Q0. + diag%alpha=delta_n_p + diag%kaphat=kaphat + diag%slun=lu + diag%prnd=inpr + diag%q0v=Q0 + diag%qcnv=Qconv + diag%qev=inQ_e + diag%qiv=inQ_i + diag%dsv=inds + diag%cbeta=inc_beta + diag%tratio=intau + diag%pev=inpe + diag%lfac=layfac + diag%dnorm=delta_n + diag%rhos=rho_s + diag%etav=eta + diag%viscv=visc + diag%tauh=tau_h + diag%taur=tau_r + diag%tauv=tau_v + diag%taui=tau_i + diag%shr=sval + diag%bl=b_l + diag%va=v_a + diag%rhom=rho + diag%lbet=lbeta + diag%omg=omega + diag%qsol=Q_sol + diag%wsol=omega_sol + diag%brth=br_th + diag%qmn=inQ_min + diag%qmx=inQ_max + IF (maxbal>-HUGE(maxbal)) THEN + diag%mxbal=maxbal + ELSE + diag%mxbal=0.0_r8 + ENDIF + ENDIF + DEALLOCATE(inQs,deltal,jxbl,bal) + + RETURN + END SUBROUTINE gpec_slayer + + END MODULE gslayer_mod diff --git a/src/Tearing/Tearing.jl b/src/Tearing/Tearing.jl index 745a30857..ae3ed8e3c 100644 --- a/src/Tearing/Tearing.jl +++ b/src/Tearing/Tearing.jl @@ -23,12 +23,14 @@ import ..InnerLayer as InnerLayer include("LayerInputs.jl") include("Dispersion/Dispersion.jl") +include("CriticalResonantField/CriticalResonantField.jl") include("Runner/Runner.jl") import .Dispersion as Dispersion +import .CriticalResonantField as CriticalResonantField import .Runner as Runner -export InnerLayer, Dispersion, Runner +export InnerLayer, Dispersion, CriticalResonantField, Runner export build_ggj_inputs end # module Tearing From ba740feebe21bf366d5dc69e4c07831b3bc97f73 Mon Sep 17 00:00:00 2001 From: ebursch <76970916+ebursch@users.noreply.github.com> Date: Sat, 15 Aug 2026 21:28:37 -0400 Subject: [PATCH 02/14] WIP - Testing --- .../CriticalResonantField/bcrit_dev.ipynb | 231 +++++++++++++++++- .../CriticalResonantField/bcrit_dev_ggj.ipynb | 34 ++- 2 files changed, 257 insertions(+), 8 deletions(-) diff --git a/src/Tearing/CriticalResonantField/bcrit_dev.ipynb b/src/Tearing/CriticalResonantField/bcrit_dev.ipynb index a6186408f..78490c308 100644 --- a/src/Tearing/CriticalResonantField/bcrit_dev.ipynb +++ b/src/Tearing/CriticalResonantField/bcrit_dev.ipynb @@ -97,6 +97,223 @@ "id": "4", "metadata": {}, "outputs": [], + "source": [ + "function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200)\n", + " Qs = range(Qmin, Qmax; length=n)\n", + " torque_out = [torque_balance_value(tb, q) for q in Qs]\n", + " bal = [x[1] for x in torque_out]\n", + " Δs = [x[2] for x in torque_out]\n", + "\n", + " positive = isfinite.(bal) .& (bal .> 0.0)\n", + "\n", + " if !any(positive)\n", + " return Qs, bal, Float64[], Float64[], NaN, NaN, 0, Δs\n", + " end\n", + "\n", + " i = argmax(bal)\n", + " Qpeak_ind = i\n", + " Qs_positive = Qs[positive]\n", + " bal_positive = bal[positive]\n", + "\n", + " i = argmax(bal_positive)\n", + " Qpeak = Qs_positive[i]\n", + " maxbal = bal_positive[i]\n", + "\n", + " br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", + " return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs\n", + "end\n", + "# one-cell scan: x = b_crit, y = Q_0\n", + "Q0_vals = range(-2.0, 2.0; length=60)\n", + "\n", + "bcrit_vals = Float64[]\n", + "locked_flag = Bool[]\n", + "\n", + "for Q0 in Q0_vals\n", + " tbQ = TorqueBalance(\n", + " tb.model,\n", + " tb.params,\n", + " Float64(Q0),\n", + " tb.P,\n", + " tb.delta_n_p,\n", + " tb.lu,\n", + " tb.sval\n", + " )\n", + "\n", + " Qs, bal, Qs_pos, bal_pos, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tbQ; Qmin=-10.0, Qmax=10.0, n=250)\n", + "\n", + " if isempty(bal_pos) || !all(isfinite.(bal_pos)) || maximum(bal_pos) <= 0\n", + " push!(bcrit_vals, NaN)\n", + " push!(locked_flag, false)\n", + " else\n", + " push!(bcrit_vals, brcrit)\n", + " push!(locked_flag, true)\n", + " end\n", + "end\n", + "\n", + "# keep only finite x-values for plotting\n", + "x = bcrit_vals[isfinite.(bcrit_vals)]\n", + "y = Q0_vals[isfinite.(bcrit_vals)]\n", + "locked = locked_flag[isfinite.(bcrit_vals)]\n", + "\n", + "p = scatter(\n", + " x[locked], y[locked],\n", + " label=\"locked\",\n", + " color=:green,\n", + " markersize=5,\n", + " marker=:circle,\n", + " xlabel=\"b_crit\",\n", + " ylabel=\"Q_0\",\n", + " title=\"Locked / unlocked boundary\",\n", + " legend=:topleft\n", + ")\n", + "\n", + "scatter!(\n", + " p,\n", + " x[.!locked], y[.!locked],\n", + " label=\"unlocked\",\n", + " color=:red,\n", + " markersize=5,\n", + " marker=:square\n", + ")\n", + "\n", + "display(p)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "import Pkg; Pkg.add(\"DataInterpolations\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "using Plots\n", + "using DataInterpolations\n", + "\n", + "default(\n", + " fontfamily=\"Georgia\",\n", + " grid=false,\n", + " linewidth=2,\n", + " guidefontsize=26,\n", + " tickfontsize=18,\n", + " titlefontsize=30,\n", + " legendfontsize=18,\n", + " size=(1200, 800),\n", + " dpi=150\n", + ")\n", + "\n", + "# Build the critical boundary bcrit(Q0)\n", + "Q0_scan = range(-1.0, 4.5; length=80)\n", + "bcrit_curve = Float64[]\n", + "\n", + "for Q0 in Q0_scan\n", + " tbQ = TorqueBalance(\n", + " tb.model,\n", + " tb.params,\n", + " Float64(Q0),\n", + " tb.P,\n", + " tb.delta_n_p,\n", + " tb.lu,\n", + " tb.sval\n", + " )\n", + "\n", + " Qs, bal, Qs_pos, bal_pos, Qpeak, brcrit, Qpeak_ind, Δs =\n", + " torque_balance_scan(tbQ; Qmin=-10.0, Qmax=10.0, n=250)\n", + "\n", + " if isempty(bal_pos) || !all(isfinite.(bal_pos)) || maximum(bal_pos) <= 0\n", + " push!(bcrit_curve, NaN)\n", + " else\n", + " push!(bcrit_curve, brcrit)\n", + " end\n", + "end\n", + "\n", + "ok = isfinite.(bcrit_curve)\n", + "Q0_plot = Q0_scan[ok]\n", + "bcrit_plot = bcrit_curve[ok]\n", + "\n", + "perm = sortperm(Q0_plot)\n", + "Q0_plot = Q0_plot[perm]\n", + "bcrit_plot = bcrit_plot[perm]\n", + "\n", + "# Interpolate the boundary: bcrit = f(Q0)\n", + "curve_itp = LinearInterpolation(bcrit_plot, Q0_plot)\n", + "\n", + "# Full phase-box bounds\n", + "x0 = minimum(bcrit_plot) * 0.8\n", + "x1 = maximum(bcrit_plot) * 1.2\n", + "y0 = minimum(Q0_plot)\n", + "y1 = maximum(Q0_plot)\n", + "\n", + "xvals = range(x0, x1; length=350)\n", + "yvals = range(y0, y1; length=350)\n", + "\n", + "locked_mask = zeros(Float64, length(yvals), length(xvals))\n", + "for iy in eachindex(yvals)\n", + " y = yvals[iy]\n", + " for ix in eachindex(xvals)\n", + " x = xvals[ix]\n", + " # locked when bcrit exceeds the boundary for that Q0\n", + " locked_mask[iy, ix] = x >= curve_itp(y) ? 1.0 : 0.0\n", + " end\n", + "end\n", + "\n", + "p = contourf(\n", + " xvals, yvals, locked_mask',\n", + " levels=[-0.5, 0.5, 1.5],\n", + " c=[:navy, :firebrick],\n", + " colorbar=false,\n", + " xlabel=\"b_crit\",\n", + " ylabel=\"Q_0\",\n", + " title=\"Locked / unlocked region\",\n", + " framestyle=:box,\n", + " xlims=(x0, x1),\n", + " ylims=(y0, y1),\n", + " legend=false\n", + ")\n", + "\n", + "# Critical boundary\n", + "plot!(p, bcrit_plot, Q0_plot; lw=3, color=:black, label=\"critical boundary\")\n", + "\n", + "# Critical point\n", + "cp_idx = argmax(bcrit_plot)\n", + "cp_x = bcrit_plot[cp_idx]\n", + "cp_y = Q0_plot[cp_idx]\n", + "scatter!(p, [cp_x], [cp_y]; color=:gold, marker=:star5, ms=12, label=\"critical point\")\n", + "\n", + "# Single legend block with one entry per category\n", + "plot!(p, [NaN], [NaN]; color=:firebrick, lw=4, label=\"locked\")\n", + "plot!(p, [NaN], [NaN]; color=:navy, lw=4, label=\"unlocked\")\n", + "plot!(p, [NaN], [NaN]; color=:black, lw=3, label=\"critical boundary\")\n", + "scatter!(p, [NaN], [NaN]; color=:gold, marker=:star5, ms=12, label=\"critical point\")\n", + "\n", + "plot!(p; legend=:topright)\n", + "\n", + "display(p)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], "source": [ "# You can substitute any valid SLAYERParameters you already have.\n", "# This is just an example skeleton.\n", @@ -135,7 +352,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5", + "id": "9", "metadata": {}, "outputs": [], "source": [ @@ -158,7 +375,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6", + "id": "10", "metadata": {}, "outputs": [], "source": [ @@ -170,7 +387,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7", + "id": "11", "metadata": {}, "outputs": [], "source": [ @@ -212,7 +429,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8", + "id": "12", "metadata": {}, "outputs": [], "source": [ @@ -224,6 +441,8 @@ "\n", "rhs = (tb.lu * tb.sval^2 / 2) * br_ratio^2\n", "\n", + "\n", + "\n", "println(\"lhs = \", lhs)\n", "println(\"rhs = \", rhs)\n", "println(\"lhs/rhs = \", lhs / rhs)" @@ -232,7 +451,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9", + "id": "13", "metadata": {}, "outputs": [], "source": [ @@ -241,7 +460,7 @@ "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for (q, jxb) in zip(Qs, jxbs)]\n", "br_t = brcrit\n", "println(tb.lu, \" \", tb.sval, \" \", br_t, \" \", p.bt, \" \", tb.delta_n_p)\n", - "T_EM = tb.lu * tb.sval^2/2 * (br_t / p.bt)^2 * jxbs\n", + "T_EM = tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs\n", "i = Qpeak_ind\n", "println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", "println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", diff --git a/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb b/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb index 94f04beac..a4d02d76f 100644 --- a/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb +++ b/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb @@ -146,9 +146,12 @@ "metadata": {}, "outputs": [], "source": [ - "Qs = range(-5.0, 5.0, length=200)\n", + "Qs = range(-5.0, 5.0, length=20)\n", "\n", - "vals = [torque_balance_value(tb, q) for q in Qs]" + "vals = [torque_balance_value(tb, q) for q in Qs]\n", + "\n", + "# 1m 34.7s for length = 2\n", + "# 46 m for length = 20\n" ] }, { @@ -194,6 +197,33 @@ "\n", "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": {}, + "outputs": [], + "source": [ + "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Δ\")\n", + "title!(p1, \"Inner-layer Δ(Q)\")\n", + "\n", + "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + "xlabel!(p2, \"Q\")\n", + "ylabel!(p2, \"jxb\")\n", + "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", + "\n", + "p3 = plot(Qs, real.(vals), label=\"Re(balance)\", lw=2)\n", + "plot!(p3, Qs, imag.(vals), label=\"Im(balance)\", lw=2)\n", + "xlabel!(p3, \"Q\")\n", + "ylabel!(p3, \"balance\")\n", + "title!(p3, \"2P(Q0-Q)/jxb\")\n", + "\n", + "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" + ] } ], "metadata": { From ddd54fefb2051d59e65b5e3537fc5d1ce4f91de3 Mon Sep 17 00:00:00 2001 From: ebursch <76970916+ebursch@users.noreply.github.com> Date: Sun, 16 Aug 2026 20:10:59 -0400 Subject: [PATCH 03/14] WIP - In progress bcrit full workflow --- Project.toml | 4 +- benchmarks/benchmark_against_fortran_run.jl | 24 +- ...hmark_coil_ForcingTerms_against_fortran.jl | 121 ++-- benchmarks/benchmark_delta_prime_methods.jl | 4 +- .../benchmark_diiid_ideal_ntv_torque.jl | 4 +- .../benchmark_diiid_kinetic_stability.jl | 4 +- benchmarks/benchmark_riccati_der.jl | 4 +- .../benchmark_solovev_kinetic_stability.jl | 34 +- benchmarks/benchmark_threads.jl | 4 +- benchmarks/compare_gal_vs_el.jl | 6 +- benchmarks/equil_method_comparison.jl | 20 +- benchmarks/equil_numerical_params.jl | 12 +- benchmarks/equil_psihigh_scan.jl | 31 +- benchmarks/equil_psilow_scan.jl | 8 +- benchmarks/equil_spline_comparison.jl | 342 +++++---- benchmarks/plot_xi_eigenmode.jl | 2 +- benchmarks/verify_gal_match.jl | 7 +- docs/make.jl | 4 +- docs/src/forcing_terms.md | 2 +- examples/DIIID-like_SLAYER_example/gpec.toml | 9 + .../analyze_example.jl | 2 +- .../run_imas_example.jl | 8 +- examples/LAR_beta_scan/run_scan.jl | 51 +- examples/LAR_epsilon_scan/run_scan.jl | 51 +- .../Solovev_ideal_example/analyze_example.jl | 11 +- .../analyze_example.jl | 17 +- regression-harness/src/database.jl | 70 +- regression-harness/src/env.jl | 8 +- regression-harness/src/reporter.jl | 6 +- regression-harness/src/types.jl | 5 +- regression-harness/src/utils.jl | 2 +- src/Analysis/Equilibrium.jl | 17 +- src/Analysis/PerturbedEquilibrium.jl | 52 +- src/Analysis/PerturbedEquilibriumModes.jl | 53 +- src/Equilibrium/AnalyticEquilibrium.jl | 120 ++-- src/Equilibrium/DirectEquilibriumArcLength.jl | 11 +- src/Equilibrium/Equilibrium.jl | 44 +- src/Equilibrium/EquilibriumTypes.jl | 35 +- src/Equilibrium/GeometryProfiles.jl | 4 +- src/Equilibrium/ReadEquilibrium.jl | 12 +- src/ForceFreeStates/EulerLagrange.jl | 48 +- .../Galerkin/GalerkinAssembly.jl | 19 +- src/ForceFreeStates/Galerkin/GalerkinGrid.jl | 2 +- src/ForceFreeStates/Galerkin/GalerkinSolve.jl | 4 +- src/ForceFreeStates/Resist.jl | 52 +- src/ForceFreeStates/ResistEval.jl | 85 +-- src/ForceFreeStates/Riccati.jl | 423 +++++------ src/ForceFreeStates/Sing.jl | 8 +- src/ForcingTerms/BiotSavart.jl | 63 +- src/ForcingTerms/CoilGeometry.jl | 12 +- .../coil_geometries/jet_ex_mid.dat | 338 ++++----- src/ForcingTerms/coil_geometries/jtext_l.dat | 162 ++--- src/ForcingTerms/coil_geometries/jtext_m.dat | 162 ++--- src/ForcingTerms/coil_geometries/jtext_u.dat | 162 ++--- .../coil_geometries/mastu_efcc.dat | 338 ++++----- .../coil_geometries/mastu_rmpl.dat | 674 +++++++++--------- .../coil_geometries/mastu_rmpu.dat | 338 ++++----- src/HDF5Schema.jl | 19 +- src/InnerLayer/GGJ/Ray.jl | 2 - src/InnerLayer/InnerLayerInterface.jl | 8 +- src/InnerLayer/SLAYER/LayerInputs.jl | 9 + src/InnerLayer/SLAYER/LayerParameters.jl | 50 +- src/KineticForces/BounceAveraging.jl | 155 ++-- src/KineticForces/EnergyIntegration.jl | 50 +- src/KineticForces/KineticForces.jl | 4 +- src/KineticForces/KineticForcesStructs.jl | 83 ++- src/KineticForces/Output.jl | 12 +- src/KineticForces/PitchIntegration.jl | 68 +- src/KineticForces/Torque.jl | 259 +++---- src/KineticForces/Utils.jl | 4 +- src/LocalStability/Ballooning.jl | 48 +- .../FieldReconstruction.jl | 10 +- .../PerturbedEquilibriumStructs.jl | 21 +- src/PerturbedEquilibrium/Utils.jl | 104 +-- src/Rerun.jl | 19 +- .../CriticalResonantField.jl | 4 +- .../CriticalResonantField/TorqueBalance.jl | 116 ++- .../CriticalResonantField/bcrit_dev.ipynb | 402 ++++------- src/Tearing/Dispersion/BruteForceScan.jl | 22 +- src/Tearing/Dispersion/ContourSearchAMR.jl | 4 +- src/Tearing/Dispersion/CoupledFullMatch.jl | 2 +- .../Dispersion/GrowthRateExtraction.jl | 8 +- src/Tearing/Runner/Control.jl | 41 ++ src/Tearing/Runner/HDF5Output.jl | 34 +- src/Tearing/Runner/Result.jl | 40 +- src/Tearing/Runner/Runner.jl | 9 +- src/Tearing/Runner/run_slayer.jl | 79 ++ src/Tearing/Tearing.jl | 2 + src/Utilities/GridUtilities.jl | 24 +- src/Utilities/HDF5Annotations.jl | 3 +- src/Utilities/PhysicalConstants.jl | 8 +- src/Vacuum/PnQuadCache.jl | 18 +- test/runtests_coordinate_invariant.jl | 30 +- test/runtests_dispersion_amr.jl | 74 +- test/runtests_dispersion_coupled.jl | 64 +- test/runtests_dispersion_coupled_full.jl | 2 +- test/runtests_dispersion_polish.jl | 4 +- test/runtests_dispersion_residual.jl | 24 +- test/runtests_dispersion_scan.jl | 42 +- test/runtests_equil.jl | 22 +- test/runtests_eulerlagrange.jl | 2 +- test/runtests_imas.jl | 34 +- test/runtests_kinetic.jl | 8 +- test/runtests_parallel_integration.jl | 63 +- test/runtests_rerun_from_h5.jl | 6 +- test/runtests_riccati.jl | 4 +- test/runtests_sing.jl | 16 +- test/runtests_tj_analytic.jl | 46 +- 108 files changed, 3299 insertions(+), 2998 deletions(-) diff --git a/Project.toml b/Project.toml index fe2f324d5..658824c00 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "GeneralizedPerturbedEquilibrium" uuid = "462872dd-e066-4d2e-b993-6468b5239634" license = "MIT" -authors = ["Nikolas Logan ", "Jong-Kyu Park ", "Matthew Pharr ", "Jacob Halpern ", "Rithik Banerjee ", "Jaebeom Cho ", "Daniel Burgess ", "Min-Gu Yoo "] +authors = ["Nikolas Logan ", "Jong-Kyu Park ", "Matthew Pharr ", "Jacob Halpern ", "Rithik Banerjee ", "Jaebeom Cho ", "Daniel Burgess ", "Min-Gu Yoo ","Evan Bursch "] version = "0.1.0" [deps] @@ -69,5 +69,3 @@ Statistics = "1" TOML = "1" Test = "1" julia = "1.11" - - diff --git a/benchmarks/benchmark_against_fortran_run.jl b/benchmarks/benchmark_against_fortran_run.jl index 6116a8058..42618bb47 100644 --- a/benchmarks/benchmark_against_fortran_run.jl +++ b/benchmarks/benchmark_against_fortran_run.jl @@ -109,7 +109,7 @@ end function _find_indexed2_float(text::String, name::String, i::Int, j::Int; default=nothing) m = match(Regex( - "\\b$(name)\\s*\\(\\s*$(i)\\s*,\\s*$(j)\\s*\\)\\s*=\\s*([+-]?[\\d.]+(?:[eE][+-]?\\d+)?)", "i"), + "\\b$(name)\\s*\\(\\s*$(i)\\s*,\\s*$(j)\\s*\\)\\s*=\\s*([+-]?[\\d.]+(?:[eE][+-]?\\d+)?)", "i"), text) isnothing(m) ? default : parse(Float64, m.captures[1]) end @@ -548,8 +548,8 @@ function compare_phix( grid = ForcingTerms.sample_boundary_grid(equil, p.mtheta_coil, p.nzeta_coil; psi=psilim) nobs = p.mtheta_coil * p.nzeta_coil - obs_R = zeros(nobs); - obs_phi = zeros(nobs); + obs_R = zeros(nobs) + obs_phi = zeros(nobs) obs_Z = zeros(nobs) for j in 1:p.nzeta_coil, i in 1:p.mtheta_coil idx = i + (j - 1) * p.mtheta_coil @@ -557,8 +557,8 @@ function compare_phix( obs_phi[idx] = grid.phi_grid[j] + grid.phi_offset[i] obs_Z[idx] = grid.Z[i] end - B_R = zeros(nobs); - B_phi = zeros(nobs); + B_R = zeros(nobs) + B_phi = zeros(nobs) B_Z = zeros(nobs) ForcingTerms.compute_biot_savart_boundary!(B_R, B_phi, B_Z, obs_R, obs_phi, obs_Z, coil_sets) bn = zeros(p.mtheta_coil, p.nzeta_coil) @@ -639,9 +639,9 @@ function build_comparison_table(fort, julia, fortran_dir, bench_dir, nn) push!(lines, "") push!(lines, "--- Mercier Criterion ---") - fdi = fort["di"]; + fdi = fort["di"] fdr = fort["dr"] - jdi = julia["di"]; + jdi = julia["di"] jdr = julia["dr"] if !isempty(jdi) && !isempty(fdi) jdi_on_fg = [_interp1(jq_psi, jdi, p) for p in fq_psi] @@ -857,7 +857,7 @@ function build_comparison_table(fort, julia, fortran_dir, bench_dir, nn) end function _interp1(x::AbstractVector, y::AbstractVector, xi::Real) - n = length(x); + n = length(x) n < 2 && return y[1] xi <= x[1] && return y[1] xi >= x[end] && return y[end] @@ -1451,15 +1451,15 @@ function main(argv=ARGS) println() table_lines = build_comparison_table(fort, julia, fortran_dir, bench_dir, p.nn) for line in table_lines - ; - println(line); + + println(line) end table_path = joinpath(bench_dir, "comparison_table.txt") open(table_path, "w") do io for line in table_lines - ; - println(io, line); + + println(io, line) end end println("\nComparison table saved to: ", abspath(table_path)) diff --git a/benchmarks/benchmark_coil_ForcingTerms_against_fortran.jl b/benchmarks/benchmark_coil_ForcingTerms_against_fortran.jl index 22e2b1938..e6c9b60cf 100644 --- a/benchmarks/benchmark_coil_ForcingTerms_against_fortran.jl +++ b/benchmarks/benchmark_coil_ForcingTerms_against_fortran.jl @@ -25,7 +25,7 @@ using NCDatasets using Plots using Printf -const OUTPUT_DIR = joinpath(@__DIR__, "coil_pipeline") +const OUTPUT_DIR = joinpath(@__DIR__, "coil_pipeline") const COIL_DAT_DIR = joinpath(@__DIR__, "..", "src", "ForcingTerms", "coil_geometries") # --------------------------------------------------------------------------- @@ -89,38 +89,38 @@ end function parse_fortran_run(dir::String)::FortranRunParams equil_file = joinpath(dir, "equil.in") - dcon_file = joinpath(dir, "dcon.in") - coil_file = joinpath(dir, "coil.in") + dcon_file = joinpath(dir, "dcon.in") + coil_file = joinpath(dir, "coil.in") isfile(equil_file) || error("equil.in not found in $dir") - isfile(dcon_file) || error("dcon.in not found in $dir") - isfile(coil_file) || error("coil.in not found in $dir") + isfile(dcon_file) || error("dcon.in not found in $dir") + isfile(coil_file) || error("coil.in not found in $dir") - eq_text = _strip_fortran_comments(read(equil_file, String)) - dcon_text = _strip_fortran_comments(read(dcon_file, String)) - coil_text = _strip_fortran_comments(read(coil_file, String)) + eq_text = _strip_fortran_comments(read(equil_file, String)) + dcon_text = _strip_fortran_comments(read(dcon_file, String)) + coil_text = _strip_fortran_comments(read(coil_file, String)) # Equilibrium parameters - eq_type = _find_string(eq_text, "eq_type"; default="efit") - eq_file = _find_string(eq_text, "eq_filename"; default="") - jac_type = _find_string(eq_text, "jac_type"; default="hamada") - psilow = _find_scalar(eq_text, "psilow"; default=1e-4) - psihigh = _find_scalar(eq_text, "psihigh"; default=0.99) - mtheta_eq = _find_int(eq_text, "mtheta"; default=256) + eq_type = _find_string(eq_text, "eq_type"; default="efit") + eq_file = _find_string(eq_text, "eq_filename"; default="") + jac_type = _find_string(eq_text, "jac_type"; default="hamada") + psilow = _find_scalar(eq_text, "psilow"; default=1e-4) + psihigh = _find_scalar(eq_text, "psihigh"; default=0.99) + mtheta_eq = _find_int(eq_text, "mtheta"; default=256) grid_type = _find_string(eq_text, "grid_type"; default="ldp") # Toroidal mode number and m-range expansion - nn = _find_int(dcon_text, "nn"; default=1) - delta_mlow = _find_int(dcon_text, "delta_mlow"; default=8) + nn = _find_int(dcon_text, "nn"; default=1) + delta_mlow = _find_int(dcon_text, "delta_mlow"; default=8) delta_mhigh = _find_int(dcon_text, "delta_mhigh"; default=8) # Coil grid parameters mtheta_coil = _find_int(coil_text, "cmtheta"; default=480) - nzeta_coil = _find_int(coil_text, "cmzeta"; default=40) - machine = _find_string(coil_text, "machine"; default="d3d") - coil_num = _find_int(coil_text, "coil_num"; default=1) + nzeta_coil = _find_int(coil_text, "cmzeta"; default=40) + machine = _find_string(coil_text, "machine"; default="d3d") + coil_num = _find_int(coil_text, "coil_num"; default=1) - coil_names = String[] + coil_names = String[] coil_currents = Vector{Float64}[] for ci in 1:coil_num name = _find_indexed_string(coil_text, "coil_name", ci; default="coil$ci") @@ -135,9 +135,9 @@ function parse_fortran_run(dir::String)::FortranRunParams end return FortranRunParams(eq_type, eq_file, jac_type, psilow, psihigh, mtheta_eq, - grid_type, nn, delta_mlow, delta_mhigh, - mtheta_coil, nzeta_coil, machine, - coil_names, coil_currents) + grid_type, nn, delta_mlow, delta_mhigh, + mtheta_coil, nzeta_coil, machine, + coil_names, coil_currents) end function find_output_nc(dir::String, nn::Int) @@ -177,16 +177,16 @@ end nc_path = find_output_nc(run_dir, p.nn) # Read Fortran output (psilim and Phi_x spectrum) -fortran_m = Int[] -fortran_Phix = Float64[] +fortran_m = Int[] +fortran_Phix = Float64[] fortran_psilim = NaN NCDatasets.Dataset(nc_path, "r") do ds - global fortran_m = Int.(ds["m"][:]) + global fortran_m = Int.(ds["m"][:]) global fortran_psilim = Float64(ds.attrib["psilim"]) phi_x_raw = ds["Phi_x"][:, :] # (mpert, 2); col 1=cos, col 2=sin - global fortran_Phix = sqrt.(phi_x_raw[:, 1].^2 .+ phi_x_raw[:, 2].^2) + global fortran_Phix = sqrt.(phi_x_raw[:, 1] .^ 2 .+ phi_x_raw[:, 2] .^ 2) end -mlow = minimum(fortran_m) +mlow = minimum(fortran_m) mhigh = maximum(fortran_m) @printf " Fortran psilim=%.6f, m=%d:%d\n" fortran_psilim mlow mhigh @@ -196,15 +196,15 @@ mhigh = maximum(fortran_m) println("\n[2/4] Loading equilibrium ...") t_equil = @elapsed begin eq_dict = Dict{String,Any}( - "eq_type" => p.eq_type, - "eq_filename" => p.eq_filename, - "jac_type" => p.jac_type, - "psilow" => p.psilow, - "psihigh" => p.psihigh, - "mtheta" => p.mtheta_equil, - "grid_type" => p.grid_type, + "eq_type" => p.eq_type, + "eq_filename" => p.eq_filename, + "jac_type" => p.jac_type, + "psilow" => p.psilow, + "psihigh" => p.psihigh, + "mtheta" => p.mtheta_equil, + "grid_type" => p.grid_type, "psi_accuracy" => 0.001, - "etol" => 1e-7, + "etol" => 1e-7 ) eq_config = Equilibrium.EquilibriumConfig(eq_dict, run_dir) equil = Equilibrium.setup_equilibrium(eq_config) @@ -223,7 +223,7 @@ for (name, currents) in zip(p.coil_names, p.coil_currents) isfile(dat_path) || error("Coil geometry file not found: $dat_path") raw = read_coil_dat(dat_path) push!(coil_sets, CoilSet(raw.name, raw.ncoil, raw.s, raw.nw, raw.nsec, - raw.x, raw.y, raw.z, Float64.(currents[1:raw.ncoil]))) + raw.x, raw.y, raw.z, Float64.(currents[1:raw.ncoil]))) end for cs in coil_sets @printf " %-10s %d conductors currents: %s A\n" cs.name cs.ncoil string(round.(cs.currents; digits=1)) @@ -231,18 +231,22 @@ end julia_modes = ForcingMode[] bnd_grid = nothing -bn = nothing -t_biot = @elapsed begin +bn = nothing +t_biot = @elapsed begin bnd_grid = sample_boundary_grid(equil, p.mtheta_coil, p.nzeta_coil; psi=fortran_psilim) nobs = p.mtheta_coil * p.nzeta_coil - obs_R = zeros(nobs); obs_phi = zeros(nobs); obs_Z = zeros(nobs) + obs_R = zeros(nobs) + obs_phi = zeros(nobs) + obs_Z = zeros(nobs) for j in 1:p.nzeta_coil, i in 1:p.mtheta_coil idx = i + (j - 1) * p.mtheta_coil - obs_R[idx] = bnd_grid.R[i] + obs_R[idx] = bnd_grid.R[i] obs_phi[idx] = bnd_grid.phi_grid[j] + bnd_grid.phi_offset[i] - obs_Z[idx] = bnd_grid.Z[i] + obs_Z[idx] = bnd_grid.Z[i] end - B_R = zeros(nobs); B_phi = zeros(nobs); B_Z = zeros(nobs) + B_R = zeros(nobs) + B_phi = zeros(nobs) + B_Z = zeros(nobs) compute_biot_savart_boundary!(B_R, B_phi, B_Z, obs_R, obs_phi, obs_Z, coil_sets) bn = zeros(p.mtheta_coil, p.nzeta_coil) project_normal_flux!(bn, B_R, B_Z, bnd_grid) @@ -250,7 +254,7 @@ t_biot = @elapsed begin end @printf " Done in %.1f s, max|Phi_x| = %.3e T·m²\n" t_biot maximum(abs, bn) -julia_m = [md.m for md in sort(julia_modes; by=md -> md.m)] +julia_m = [md.m for md in sort(julia_modes; by=md -> md.m)] julia_amps = abs.([md.amplitude for md in sort(julia_modes; by=md -> md.m)]) # Print comparison table @@ -259,7 +263,7 @@ println(" " * "-"^55) for (jm, ja) in zip(julia_m, julia_amps) k = findfirst(==(jm), fortran_m) if !isnothing(k) - fp = fortran_Phix[k] + fp = fortran_Phix[k] ratio = ja > 1e-40 ? fp / ja : NaN @printf " %3d %12.4e %12.4e %.4f\n" jm ja fp ratio end @@ -272,7 +276,7 @@ println(" Expected ratio ≈ 1.000 for all modes.") println("\n[4/4] Generating figure ...") function step_series(m_vals, amps) - m_ext = [m_vals[1] - 1; m_vals; m_vals[end] + 1] + m_ext = [m_vals[1] - 1; m_vals; m_vals[end] + 1] amp_ext = [0.0; amps; 0.0] return m_ext, amp_ext end @@ -286,19 +290,20 @@ p2 = plot_bn_contour(bn, p.mtheta_coil, p.nzeta_coil; n=p.nn) title!(p2, "Normal flux Φₓ(θ, ζ) at ψ=$(round(fortran_psilim; digits=4))") # Panel 3: Julia vs Fortran Phi_x spectrum -jm_ext, ja_ext = step_series(julia_m, julia_amps) -fm_ext, fa_ext = step_series(fortran_m, fortran_Phix) +jm_ext, ja_ext = step_series(julia_m, julia_amps) +fm_ext, fa_ext = step_series(fortran_m, fortran_Phix) p3 = plot(; xlabel="Poloidal mode m", ylabel="|Phi_x| [T·m²]", - title="Spectrum: Julia vs Fortran (n=$(p.nn))", - legend=:topright) + title="Spectrum: Julia vs Fortran (n=$(p.nn))", + legend=:topright) plot!(p3, jm_ext, ja_ext; seriestype=:steppre, lw=2, color=:blue, - label="Julia ψ=$(round(fortran_psilim; digits=4))") + label="Julia ψ=$(round(fortran_psilim; digits=4))") plot!(p3, fm_ext, fa_ext; seriestype=:steppre, lw=2, color=:orange, - linestyle=:dash, label="Fortran Phi_x") -ylims!(p3, (0, Inf)); xlims!(p3, mlow - 2, mhigh + 2) + linestyle=:dash, label="Fortran Phi_x") +ylims!(p3, (0, Inf)); +xlims!(p3, mlow - 2, mhigh + 2) # Panel 4: Phi_x / Julia ratio -ratio_m = Int[] +ratio_m = Int[] ratio_vals = Float64[] for (jm, ja) in zip(julia_m, julia_amps) k = findfirst(==(jm), fortran_m) @@ -308,8 +313,8 @@ for (jm, ja) in zip(julia_m, julia_amps) end end p4 = plot(; xlabel="Poloidal mode m", ylabel="Phi_x / Julia", - title="Ratio (flat at 1.0 → correct)", - legend=:topright) + title="Ratio (flat at 1.0 → correct)", + legend=:topright) if !isempty(ratio_m) scatter!(p4, ratio_m, ratio_vals; color=:blue, label="ratio", markersize=5) hline!(p4, [1.0]; color=:red, linestyle=:dash, label="expected = 1.0") @@ -318,8 +323,8 @@ xlims!(p4, mlow - 2, mhigh + 2) run_label = basename(run_dir) fig = plot(p1, p2, p3, p4; - layout=(2, 2), size=(1400, 900), - plot_title="$run_label | $(p.machine) n=$(p.nn) psilim=$(round(fortran_psilim; digits=4))") + layout=(2, 2), size=(1400, 900), + plot_title="$run_label | $(p.machine) n=$(p.nn) psilim=$(round(fortran_psilim; digits=4))") out_png = joinpath(OUTPUT_DIR, "coil_pipeline_$(run_label)_n$(p.nn).png") savefig(fig, out_png) diff --git a/benchmarks/benchmark_delta_prime_methods.jl b/benchmarks/benchmark_delta_prime_methods.jl index 917e7c9c5..d005eea7e 100644 --- a/benchmarks/benchmark_delta_prime_methods.jl +++ b/benchmarks/benchmark_delta_prime_methods.jl @@ -32,8 +32,8 @@ function setup_and_run_solovev() intr.wall_settings = GeneralizedPerturbedEquilibrium.Vacuum.WallShapeSettings(; (Symbol(k) => v for (k, v) in inputs["Wall"])...) FFS.sing_lim!(intr, ctrl, equil) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 FFS.sing_find!(intr, equil) intr.mlow = min(intr.nlow * equil.params.qmin, 0) - 4 - ctrl.delta_mlow diff --git a/benchmarks/benchmark_diiid_ideal_ntv_torque.jl b/benchmarks/benchmark_diiid_ideal_ntv_torque.jl index 7da279b91..92b788afc 100644 --- a/benchmarks/benchmark_diiid_ideal_ntv_torque.jl +++ b/benchmarks/benchmark_diiid_ideal_ntv_torque.jl @@ -35,7 +35,9 @@ const KF = GPE.KineticForces const Eq = GPE.Equilibrium const PE = GPE.PerturbedEquilibrium -"Fortran GPEC DIII-D ideal example run directory, from the environment (no on-disk default)." +""" +Fortran GPEC DIII-D ideal example run directory, from the environment (no on-disk default). +""" default_fortran_dir() = get(() -> error("Set GPEC_FORTRAN_DIIID, or pass the Fortran run directory as the first argument"), ENV, "GPEC_FORTRAN_DIIID") diff --git a/benchmarks/benchmark_diiid_kinetic_stability.jl b/benchmarks/benchmark_diiid_kinetic_stability.jl index 9ae37b6b3..91ab5b172 100644 --- a/benchmarks/benchmark_diiid_kinetic_stability.jl +++ b/benchmarks/benchmark_diiid_kinetic_stability.jl @@ -36,7 +36,9 @@ using GeneralizedPerturbedEquilibrium const GPE = GeneralizedPerturbedEquilibrium const AnalysisFFS = GPE.Analysis.ForceFreeStates -"Fortran GPEC DIII-D kinetic example run directory, from the environment (no on-disk default)." +""" +Fortran GPEC DIII-D kinetic example run directory, from the environment (no on-disk default). +""" default_fortran_dir() = get(() -> error("Set GPEC_FORTRAN_DIIID_DCON, or pass the Fortran run directory as the first argument"), ENV, "GPEC_FORTRAN_DIIID_DCON") diff --git a/benchmarks/benchmark_riccati_der.jl b/benchmarks/benchmark_riccati_der.jl index 6b23c0a81..df083891f 100644 --- a/benchmarks/benchmark_riccati_der.jl +++ b/benchmarks/benchmark_riccati_der.jl @@ -33,8 +33,8 @@ function setup_solovev() intr.wall_settings = GeneralizedPerturbedEquilibrium.Vacuum.WallShapeSettings(; (Symbol(k) => v for (k, v) in inputs["Wall"])...) FFS.sing_lim!(intr, ctrl, equil) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 FFS.sing_find!(intr, equil) intr.mlow = min(intr.nlow * equil.params.qmin, 0) - 4 - ctrl.delta_mlow diff --git a/benchmarks/benchmark_solovev_kinetic_stability.jl b/benchmarks/benchmark_solovev_kinetic_stability.jl index c942a20c6..43b3ba25d 100644 --- a/benchmarks/benchmark_solovev_kinetic_stability.jl +++ b/benchmarks/benchmark_solovev_kinetic_stability.jl @@ -43,10 +43,10 @@ using HDF5 using GeneralizedPerturbedEquilibrium const GPE = GeneralizedPerturbedEquilibrium -const REPO = normpath(joinpath(@__DIR__, "..")) -const JULIA_FIXTURE = joinpath(REPO, "test", "test_data", "regression_solovev_kinetic_calculated") -const FORTRAN_DCON = get(ENV, "GPEC_FORTRAN_DCON", "") -const FORTRAN_SOLDIR = get(ENV, "GPEC_FORTRAN_SOLDIR", "") +const REPO = normpath(joinpath(@__DIR__, "..")) +const JULIA_FIXTURE = joinpath(REPO, "test", "test_data", "regression_solovev_kinetic_calculated") +const FORTRAN_DCON = get(ENV, "GPEC_FORTRAN_DCON", "") +const FORTRAN_SOLDIR = get(ENV, "GPEC_FORTRAN_SOLDIR", "") _p(args...) = (println(stderr, args...); flush(stderr)) @@ -90,35 +90,35 @@ function build_matched_fortran_deck(workdir::String) end gpec = TOML.parsefile(joinpath(JULIA_FIXTURE, "gpec.toml")) - eq = gpec["Equilibrium"] - ffs = gpec["ForceFreeStates"] - kf = get(gpec, "KineticForces", Dict{String,Any}()) + eq = gpec["Equilibrium"] + ffs = gpec["ForceFreeStates"] + kf = get(gpec, "KineticForces", Dict{String,Any}()) # equil.in — grid + coordinate settings to match the Julia [Equilibrium] block. eqin = joinpath(workdir, "equil.in") - replace_namelist_value!(eqin, "psilow", string(eq["psilow"])) + replace_namelist_value!(eqin, "psilow", string(eq["psilow"])) replace_namelist_value!(eqin, "psihigh", string(eq["psihigh"])) - replace_namelist_value!(eqin, "mpsi", string(eq["mpsi"])) - replace_namelist_value!(eqin, "mtheta", string(eq["mtheta"])) + replace_namelist_value!(eqin, "mpsi", string(eq["mpsi"])) + replace_namelist_value!(eqin, "mtheta", string(eq["mtheta"])) # dcon.in — kinetic flags already match; align mode band, edge truncation, n. dconin = joinpath(workdir, "dcon.in") - replace_namelist_value!(dconin, "nn", string(ffs["nn_low"])) - replace_namelist_value!(dconin, "delta_mlow", string(get(ffs, "delta_mlow", 0))) + replace_namelist_value!(dconin, "nn", string(ffs["nn_low"])) + replace_namelist_value!(dconin, "delta_mlow", string(get(ffs, "delta_mlow", 0))) replace_namelist_value!(dconin, "delta_mhigh", string(get(ffs, "delta_mhigh", 0))) - replace_namelist_value!(dconin, "qlow", string(ffs["qlow"])) - replace_namelist_value!(dconin, "qhigh", string(ffs["qhigh"])) + replace_namelist_value!(dconin, "qlow", string(ffs["qlow"])) + replace_namelist_value!(dconin, "qhigh", string(ffs["qhigh"])) replace_namelist_value!(dconin, "singfac_min", string(ffs["singfac_min"])) # Julia set_psilim_via_dmlim defaults true (sas_flag) with dmlim 0.2. replace_namelist_value!(dconin, "sas_flag", "t") - replace_namelist_value!(dconin, "dmlim", "0.2") + replace_namelist_value!(dconin, "dmlim", "0.2") # pentrc.in — bounce harmonics + species; defaults mirror KineticForcesControl. pentin = joinpath(workdir, "pentrc.in") - replace_namelist_value!(pentin, "nl", string(get(kf, "nl", 1))) + replace_namelist_value!(pentin, "nl", string(get(kf, "nl", 1))) replace_namelist_value!(pentin, "nutype", "\"" * string(get(kf, "nutype", "harmonic")) * "\"") replace_namelist_value!(pentin, "f0type", "\"" * string(get(kf, "f0type", "maxwellian")) * "\"") - replace_namelist_value!(pentin, "nufac", string(get(kf, "nufac", 1))) + replace_namelist_value!(pentin, "nufac", string(get(kf, "nufac", 1))) replace_namelist_value!(pentin, "kinetic_file", "\"kinetic.txt\"") # kinetic.txt — Fortran readtable wants a title line then numeric rows; the diff --git a/benchmarks/benchmark_threads.jl b/benchmarks/benchmark_threads.jl index 96e37236a..1abd8a3d4 100644 --- a/benchmarks/benchmark_threads.jl +++ b/benchmarks/benchmark_threads.jl @@ -21,8 +21,8 @@ function run_ffs(ex; integrator) intr.wall_settings = GeneralizedPerturbedEquilibrium.Vacuum.WallShapeSettings(; (Symbol(k) => v for (k, v) in inputs["Wall"])...) GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_lim!(intr, ctrl, equil) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_find!(intr, equil) intr.mlow = min(intr.nlow * equil.params.qmin, 0) - 4 - ctrl.delta_mlow diff --git a/benchmarks/compare_gal_vs_el.jl b/benchmarks/compare_gal_vs_el.jl index 98c8e82ef..5b695fb0e 100644 --- a/benchmarks/compare_gal_vs_el.jl +++ b/benchmarks/compare_gal_vs_el.jl @@ -43,14 +43,14 @@ xiE = reduce(hcat, (u1[:, :, ip] * cEL for ip in 1:size(u1, 3))) # (mpert, nE) psiGk = psiG xiG = reduce(hcat, (gxi[:, :, ip] * w for ip in eachindex(psiG))) # (mpert, nGk) -ms = mlow .+ (0:mpert-1) +ms = mlow .+ (0:(mpert-1)) peak = [maximum(abs, @view xiE[i, :]) for i in 1:mpert] order = sortperm(peak; rev=true) ndom = min(5, mpert) # quantitative bulk agreement on the dominant harmonic (linear-interp EL onto gal grid, off rationals/edge) -lininterp(xq, x, y) = (j = clamp(searchsortedlast(x, xq), 1, length(x) - 1); -t = (xq - x[j]) / (x[j+1] - x[j]); y[j] * (1 - t) + y[j+1] * t) +lininterp(xq, x, y) = (j=clamp(searchsortedlast(x, xq), 1, length(x) - 1); + t=(xq - x[j]) / (x[j+1] - x[j]); y[j] * (1 - t) + y[j+1] * t) idom = order[1] inbulk(p) = 0.1 <= p <= 0.92 && all(abs(p - ps) > 8e-3 for ps in sing_psi) sel = [ip for ip in eachindex(psiGk) if inbulk(psiGk[ip])] diff --git a/benchmarks/equil_method_comparison.jl b/benchmarks/equil_method_comparison.jl index 450423d6a..151dadd72 100644 --- a/benchmarks/equil_method_comparison.jl +++ b/benchmarks/equil_method_comparison.jl @@ -21,7 +21,7 @@ using GeneralizedPerturbedEquilibrium.Equilibrium using TOML, Printf, Statistics example_path = length(ARGS) > 0 ? ARGS[1] : joinpath(@__DIR__, "../examples/DIIID-like_ideal_example") -config_path = joinpath(example_path, "gpec.toml") +config_path = joinpath(example_path, "gpec.toml") psihigh_override = length(ARGS) > 1 ? parse(Float64, ARGS[2]) : nothing println("=" ^ 65) @@ -58,10 +58,10 @@ for method in methods success = false end results[method] = Dict( - "success" => success, - "pe" => pe, - "runtime" => (t1 + t2) / 2.0, - "config" => cfg + "success" => success, + "pe" => pe, + "runtime" => (t1 + t2) / 2.0, + "config" => cfg ) success && @printf(" Runtime (avg 2 warm): %.3f s\n", (t1 + t2) / 2.0) end @@ -105,7 +105,7 @@ for method in methods results[method]["success"] || continue Δq = abs.([q_vals[method][i] - efit_q_interp(psi_nodes[i]) for i in 1:length(psi_nodes)]) @printf(" |q_%s - q_efit| (ψ<0.95): max=%.2e rms=%.2e\n", - method, maximum(Δq[mask_mid]), sqrt(mean(Δq[mask_mid].^2))) + method, maximum(Δq[mask_mid]), sqrt(mean(Δq[mask_mid] .^ 2))) end # ─── Roundtrip error ───────────────────────────────────────────────────────── @@ -123,15 +123,15 @@ for method in methods psio = pe.psio psi_xs = pe.rzphi_xs psi_ys = pe.rzphi_ys - mpsi = length(psi_xs) - 1 + mpsi = length(psi_xs) - 1 mtheta = length(psi_ys) - 1 errors = Float64[] - for ipsi in 1:5:mpsi+1 + for ipsi in 1:5:(mpsi+1) ψ_target = psi_xs[ipsi] - for itheta in 1:8:mtheta+1 + for itheta in 1:8:(mtheta+1) θ = psi_ys[itheta] - r2 = pe.rzphi_rsquared((ψ_target, θ)) + r2 = pe.rzphi_rsquared((ψ_target, θ)) off = pe.rzphi_offset((ψ_target, θ)) rfac = sqrt(max(r2, 0.0)) η = 2π * (θ + off) diff --git a/benchmarks/equil_numerical_params.jl b/benchmarks/equil_numerical_params.jl index f80f0f64c..f37376745 100644 --- a/benchmarks/equil_numerical_params.jl +++ b/benchmarks/equil_numerical_params.jl @@ -21,26 +21,26 @@ using GeneralizedPerturbedEquilibrium.Equilibrium using TOML, Printf, Statistics example_path = length(ARGS) > 0 ? ARGS[1] : joinpath(@__DIR__, "../examples/DIIID-like_ideal_example") -config_path = joinpath(example_path, "gpec.toml") +config_path = joinpath(example_path, "gpec.toml") function make_config(path, eq_type, mpsi, mtheta) raw = TOML.parsefile(path) raw["Equilibrium"]["eq_type"] = eq_type - raw["Equilibrium"]["mpsi"] = mpsi - raw["Equilibrium"]["mtheta"] = mtheta + raw["Equilibrium"]["mpsi"] = mpsi + raw["Equilibrium"]["mtheta"] = mtheta return Equilibrium.EquilibriumConfig(raw["Equilibrium"], dirname(path)) end function roundtrip_error(pe, raw_profile) psi_xs = pe.rzphi_xs - psio = pe.psio + psio = pe.psio mtheta = length(pe.rzphi_ys) - 1 errors = Float64[] for ipsi in 1:4:length(psi_xs) ψ = psi_xs[ipsi] - for itheta in 1:8:mtheta+1 + for itheta in 1:8:(mtheta+1) θ = pe.rzphi_ys[itheta] - r2 = pe.rzphi_rsquared((ψ, θ)) + r2 = pe.rzphi_rsquared((ψ, θ)) off = pe.rzphi_offset((ψ, θ)) rfac = sqrt(max(r2, 0.0)) η = 2π * (θ + off) diff --git a/benchmarks/equil_psihigh_scan.jl b/benchmarks/equil_psihigh_scan.jl index 56f6e9ec6..99788b281 100644 --- a/benchmarks/equil_psihigh_scan.jl +++ b/benchmarks/equil_psihigh_scan.jl @@ -29,7 +29,7 @@ using GeneralizedPerturbedEquilibrium.Equilibrium using TOML, Printf, Statistics, HDF5 example_path = length(ARGS) > 0 ? ARGS[1] : joinpath(@__DIR__, "../examples/DIIID-like_ideal_example") -config_path = joinpath(example_path, "gpec.toml") +config_path = joinpath(example_path, "gpec.toml") psihigh_values = [0.980, 0.985, 0.990, 0.993, 0.995, 0.996, 0.997, 0.998, 0.999, 0.9995, 0.9999, 1.0] methods = ["efit", "efit_arclength", "efit_by_inversion"] @@ -121,9 +121,9 @@ for method in methods for ipsi in 1:length(psi_xs) psi_xs[ipsi] < 0.90 && continue ψ = psi_xs[ipsi] - for itheta in 1:8:mtheta+1 + for itheta in 1:8:(mtheta+1) θ = pe.rzphi_ys[itheta] - r2 = pe.rzphi_rsquared((ψ, θ)) + r2 = pe.rzphi_rsquared((ψ, θ)) off = pe.rzphi_offset((ψ, θ)) rfac = sqrt(max(r2, 0.0)) η = 2π * (θ + off) @@ -161,13 +161,16 @@ for method in methods isnan(q_at_psihigh) ? -1.0 : q_at_psihigh, et1_str) - push!(rows, ( - method=method, psihigh=psihigh, success=success, runtime=runtime, - roundtrip_max_edge=roundtrip_max_edge, - q_mono_violations_edge=q_mono_violations_edge, - q_at_psihigh=q_at_psihigh, q_edge_slope=q_edge_slope, - et1=et1, error_msg=err_msg - )) + push!( + rows, + ( + method=method, psihigh=psihigh, success=success, runtime=runtime, + roundtrip_max_edge=roundtrip_max_edge, + q_mono_violations_edge=q_mono_violations_edge, + q_at_psihigh=q_at_psihigh, q_edge_slope=q_edge_slope, + et1=et1, error_msg=err_msg + ) + ) end end @@ -198,9 +201,11 @@ println("et[1] vs psihigh (free-boundary stability eigenvalue):") println(" (positive = stable, negative = unstable)") @printf(" %-22s %s\n", "psihigh", join([@sprintf("%-22s", m) for m in methods])) for psihigh in psihigh_values - vals = [let r = findfirst(x -> x.method == m && x.psihigh == psihigh, rows) - r === nothing || isnan(rows[r].et1) ? " -" : @sprintf("%+.4f", rows[r].et1) - end for m in methods] + vals = [ + let r = findfirst(x -> x.method == m && x.psihigh == psihigh, rows) + r === nothing || isnan(rows[r].et1) ? " -" : @sprintf("%+.4f", rows[r].et1) + end for m in methods + ] @printf(" %-22.4f %s\n", psihigh, join([@sprintf("%-22s", v) for v in vals])) end println() diff --git a/benchmarks/equil_psilow_scan.jl b/benchmarks/equil_psilow_scan.jl index ff5902b7b..1129d5ee1 100644 --- a/benchmarks/equil_psilow_scan.jl +++ b/benchmarks/equil_psilow_scan.jl @@ -19,7 +19,7 @@ using GeneralizedPerturbedEquilibrium.Equilibrium using TOML, Printf, Statistics example_path = length(ARGS) > 0 ? ARGS[1] : joinpath(@__DIR__, "../examples/DIIID-like_ideal_example") -config_path = joinpath(example_path, "gpec.toml") +config_path = joinpath(example_path, "gpec.toml") psilow_values = [1e-1, 5e-2, 1e-2, 5e-3, 1e-3, 5e-4, 1e-4] methods = ["efit", "efit_arclength", "efit_by_inversion"] @@ -82,7 +82,7 @@ for method in methods raw_profile = Equilibrium.read_efit(cfg) psi_xs = pe.rzphi_xs mtheta = length(pe.rzphi_ys) - 1 - psio = pe.psio + psio = pe.psio # q0 extrapolated to axis (linear from innermost two grid points) q1 = pe.profiles.q_spline.y[1] @@ -94,9 +94,9 @@ for method in methods for ipsi in 1:length(psi_xs) psi_xs[ipsi] > 0.10 && break ψ = psi_xs[ipsi] - for itheta in 1:8:mtheta+1 + for itheta in 1:8:(mtheta+1) θ = pe.rzphi_ys[itheta] - r2 = pe.rzphi_rsquared((ψ, θ)) + r2 = pe.rzphi_rsquared((ψ, θ)) off = pe.rzphi_offset((ψ, θ)) rfac = sqrt(max(r2, 0.0)) η = 2π * (θ + off) diff --git a/benchmarks/equil_spline_comparison.jl b/benchmarks/equil_spline_comparison.jl index 4cf5337e2..a0ea0bdc0 100644 --- a/benchmarks/equil_spline_comparison.jl +++ b/benchmarks/equil_spline_comparison.jl @@ -27,9 +27,9 @@ using TOML, Printf, Statistics, Plots # ─── CLI arguments ───────────────────────────────────────────────────────────── example_path = length(ARGS) > 0 ? ARGS[1] : - joinpath(@__DIR__, "../examples/DIIID-like_ideal_example") + joinpath(@__DIR__, "../examples/DIIID-like_ideal_example") psihigh_arg = length(ARGS) > 1 ? parse(Float64, ARGS[2]) : 0.997 -config_path = joinpath(example_path, "gpec.toml") +config_path = joinpath(example_path, "gpec.toml") println("=" ^ 70) println("Equilibrium Spline Comparison: efit / efit_arclength / efit_by_inversion") @@ -46,38 +46,38 @@ println("Output : $outdir\n") # ─── Config factory ──────────────────────────────────────────────────────────── function make_config(path::String, eq_type::String, psihigh::Float64) raw = TOML.parsefile(path) - raw["Equilibrium"]["eq_type"] = eq_type + raw["Equilibrium"]["eq_type"] = eq_type raw["Equilibrium"]["psihigh"] = psihigh return Equilibrium.EquilibriumConfig(raw["Equilibrium"], dirname(path)) end # ─── Load all three equilibria ───────────────────────────────────────────────── # efit is the reference; efit_arclength and efit_by_inversion are compared to it. -ref_method = "efit" -compare_methods = ["efit_arclength", "efit_by_inversion"] -all_methods = vcat(ref_method, compare_methods) +ref_method = "efit" +compare_methods = ["efit_arclength", "efit_by_inversion"] +all_methods = vcat(ref_method, compare_methods) method_color = Dict( - "efit" => :blue, - "efit_arclength" => :darkorange, - "efit_by_inversion" => :red, + "efit" => :blue, + "efit_arclength" => :darkorange, + "efit_by_inversion" => :red ) method_style = Dict( - "efit" => :solid, - "efit_arclength" => :dash, - "efit_by_inversion" => :dot, + "efit" => :solid, + "efit_arclength" => :dash, + "efit_by_inversion" => :dot ) method_label = Dict( - "efit" => "efit", - "efit_arclength" => "efit_arclength", - "efit_by_inversion" => "efit_by_inv", + "efit" => "efit", + "efit_arclength" => "efit_arclength", + "efit_by_inversion" => "efit_by_inv" ) diff_color = Dict( - "efit_arclength" => :darkorange, - "efit_by_inversion" => :red, + "efit_arclength" => :darkorange, + "efit_by_inversion" => :red ) -pes = Dict{String, Any}() +pes = Dict{String,Any}() for m in all_methods println("--- Running: $m ---") cfg = make_config(config_path, m, psihigh_arg) @@ -94,22 +94,26 @@ isempty(failed) || println("Skipping failed methods in comparisons: $(join(faile haskey(pes, ref_method) || error("Reference method '$ref_method' failed — cannot continue.") pe_ref = pes[ref_method] -all_methods = filter(m -> haskey(pes, m), all_methods) +all_methods = filter(m -> haskey(pes, m), all_methods) compare_methods_active = filter(m -> haskey(pes, m), compare_methods) # ─── Helpers ─────────────────────────────────────────────────────────────────── -"Convert (ψ, θ) straight-field-line coordinates → (R, Z) physical coordinates." +""" +Convert (ψ, θ) straight-field-line coordinates → (R, Z) physical coordinates. +""" function psi_theta_to_RZ(pe, psi, theta) - r2 = pe.rzphi_rsquared((psi, theta)) - off = pe.rzphi_offset((psi, theta)) + r2 = pe.rzphi_rsquared((psi, theta)) + off = pe.rzphi_offset((psi, theta)) rfac = sqrt(max(r2, 0.0)) - η = 2π * (theta + off) - R = pe.ro + rfac * cos(η) - Z = pe.zo + rfac * sin(η) + η = 2π * (theta + off) + R = pe.ro + rfac * cos(η) + Z = pe.zo + rfac * sin(η) return R, Z end -"Compute the full (R, Z) trace of each flux surface in psi_vals." +""" +Compute the full (R, Z) trace of each flux surface in psi_vals. +""" function flux_surface_RZ(pe, psi_vals, theta_range) R_all = [Float64[] for _ in 1:length(psi_vals)] Z_all = [Float64[] for _ in 1:length(psi_vals)] @@ -130,7 +134,7 @@ end psi_lo = pe_ref.rzphi_xs[1] psi_hi = pe_ref.rzphi_xs[end] mpsi_eval = 8 * (length(pe_ref.rzphi_xs) - 1) -psi_full = psi_lo .+ (psi_hi - psi_lo) .* sin.(range(0.0, 1.0; length=mpsi_eval+1) .* (π/2)).^2 +psi_full = psi_lo .+ (psi_hi - psi_lo) .* sin.(range(0.0, 1.0; length=mpsi_eval+1) .* (π/2)) .^ 2 mask_core = psi_full .< 0.10 mask_edge = psi_full .> 0.98 @@ -148,16 +152,16 @@ println("1. 1D Profile Comparisons") println("=" ^ 70) profile_specs = [ - ("F (2π·R·Bₜ)", pe -> pe.profiles.F_spline), - ("μ₀·P", pe -> pe.profiles.P_spline), - ("dV/dψ", pe -> pe.profiles.dVdpsi_spline), - ("q", pe -> pe.profiles.q_spline), + ("F (2π·R·Bₜ)", pe -> pe.profiles.F_spline), + ("μ₀·P", pe -> pe.profiles.P_spline), + ("dV/dψ", pe -> pe.profiles.dVdpsi_spline), + ("q", pe -> pe.profiles.q_spline) ] profile_fnames = ["profile_F", "profile_P", "profile_dVdpsi", "profile_q"] for (idx, (pname, spl_getter)) in enumerate(profile_specs) spl_ref = spl_getter(pe_ref) - y_ref = [spl_ref(ψ) for ψ in psi_full] + y_ref = [spl_ref(ψ) for ψ in psi_full] p_full = plot(psi_full, y_ref; lw=2, color=method_color[ref_method], ls=method_style[ref_method], label=method_label[ref_method], @@ -187,8 +191,8 @@ for (idx, (pname, spl_getter)) in enumerate(profile_specs) for m in compare_methods_active spl_m = spl_getter(pes[m]) - y_m = [spl_m(ψ) for ψ in psi_full] - Δy = y_ref .- y_m + y_m = [spl_m(ψ) for ψ in psi_full] + Δy = y_ref .- y_m plot!(p_full, psi_full, y_m; lw=1.5, color=method_color[m], ls=method_style[m], label=method_label[m]) @@ -227,66 +231,66 @@ z_global_grid = Float64[] r_zoom_grid_vis = Float64[] z_zoom_grid_vis = Float64[] if haskey(pes, "efit_by_inversion") -let - global r_global_grid, z_global_grid, r_zoom_grid_vis, z_zoom_grid_vis - cfg_inv = make_config(config_path, "efit_by_inversion", psihigh_arg) - raw_inv = Equilibrium.read_efit(cfg_inv) - ro_g, zo_g = pes["efit_by_inversion"].ro, pes["efit_by_inversion"].zo - psio_g = raw_inv.psio - psilow_g = cfg_inv.psilow - topology_g = Equilibrium.classify_topology(raw_inv, psio_g) - - ψ_RR = abs(raw_inv.psi_in((ro_g, zo_g); deriv=DerivOp(2, 0))) - ψ_ZZ = abs(raw_inv.psi_in((ro_g, zo_g); deriv=DerivOp(0, 2))) - a_low_g = min(sqrt(2 * psilow_g * psio_g / ψ_RR), sqrt(2 * psilow_g * psio_g / ψ_ZZ)) - - nw_g = length(raw_inv.psi_in_xs) - nh_g = length(raw_inv.psi_in_ys) - β_r_g, β_z_g = 2.0, 2.0 - refine_g = 5 - - nr_g = max(4, round(Int, refine_g * nw_g)) - nz_g = max(4, round(Int, refine_g * nh_g)) - r_g = Equilibrium.make_stretched_r_grid(raw_inv.rmin, raw_inv.rmax, ro_g, nr_g, β_r_g) - z_g = Equilibrium.make_stretched_z_grid(raw_inv.zmin, raw_inv.zmax, zo_g, nz_g, topology_g, β_z_g) - - iro_g = clamp(searchsortedfirst(r_g, ro_g), 2, length(r_g)) - izo_g = clamp(searchsortedfirst(z_g, zo_g), 2, length(z_g)) - dR_ax = r_g[iro_g] - r_g[iro_g - 1] - dZ_ax = z_g[izo_g] - z_g[izo_g - 1] - sc_r = max(1, ceil(Int, dR_ax / (0.2 * a_low_g))) - sc_z = max(1, ceil(Int, dZ_ax / (0.2 * a_low_g))) - if sc_r > 1 - nr_g = (nr_g - 1) * sc_r + 1 - r_g = Equilibrium.make_stretched_r_grid(raw_inv.rmin, raw_inv.rmax, ro_g, nr_g, β_r_g) + let + global r_global_grid, z_global_grid, r_zoom_grid_vis, z_zoom_grid_vis + cfg_inv = make_config(config_path, "efit_by_inversion", psihigh_arg) + raw_inv = Equilibrium.read_efit(cfg_inv) + ro_g, zo_g = pes["efit_by_inversion"].ro, pes["efit_by_inversion"].zo + psio_g = raw_inv.psio + psilow_g = cfg_inv.psilow + topology_g = Equilibrium.classify_topology(raw_inv, psio_g) + + ψ_RR = abs(raw_inv.psi_in((ro_g, zo_g); deriv=DerivOp(2, 0))) + ψ_ZZ = abs(raw_inv.psi_in((ro_g, zo_g); deriv=DerivOp(0, 2))) + a_low_g = min(sqrt(2 * psilow_g * psio_g / ψ_RR), sqrt(2 * psilow_g * psio_g / ψ_ZZ)) + + nw_g = length(raw_inv.psi_in_xs) + nh_g = length(raw_inv.psi_in_ys) + β_r_g, β_z_g = 2.0, 2.0 + refine_g = 5 + + nr_g = max(4, round(Int, refine_g * nw_g)) + nz_g = max(4, round(Int, refine_g * nh_g)) + r_g = Equilibrium.make_stretched_r_grid(raw_inv.rmin, raw_inv.rmax, ro_g, nr_g, β_r_g) + z_g = Equilibrium.make_stretched_z_grid(raw_inv.zmin, raw_inv.zmax, zo_g, nz_g, topology_g, β_z_g) + iro_g = clamp(searchsortedfirst(r_g, ro_g), 2, length(r_g)) - dR_ax = r_g[iro_g] - r_g[iro_g - 1] - end - if sc_z > 1 - nz_g = (nz_g - 1) * sc_z + 1 - z_g = Equilibrium.make_stretched_z_grid(raw_inv.zmin, raw_inv.zmax, zo_g, nz_g, topology_g, β_z_g) izo_g = clamp(searchsortedfirst(z_g, zo_g), 2, length(z_g)) - dZ_ax = z_g[izo_g] - z_g[izo_g - 1] + dR_ax = r_g[iro_g] - r_g[iro_g-1] + dZ_ax = z_g[izo_g] - z_g[izo_g-1] + sc_r = max(1, ceil(Int, dR_ax / (0.2 * a_low_g))) + sc_z = max(1, ceil(Int, dZ_ax / (0.2 * a_low_g))) + if sc_r > 1 + nr_g = (nr_g - 1) * sc_r + 1 + r_g = Equilibrium.make_stretched_r_grid(raw_inv.rmin, raw_inv.rmax, ro_g, nr_g, β_r_g) + iro_g = clamp(searchsortedfirst(r_g, ro_g), 2, length(r_g)) + dR_ax = r_g[iro_g] - r_g[iro_g-1] + end + if sc_z > 1 + nz_g = (nz_g - 1) * sc_z + 1 + z_g = Equilibrium.make_stretched_z_grid(raw_inv.zmin, raw_inv.zmax, zo_g, nz_g, topology_g, β_z_g) + izo_g = clamp(searchsortedfirst(z_g, zo_g), 2, length(z_g)) + dZ_ax = z_g[izo_g] - z_g[izo_g-1] + end + r_global_grid = r_g + z_global_grid = z_g + + d_max_g = max(dR_ax, dZ_ax) + threshold_g = (10 * d_max_g)^2 * max(ψ_RR, ψ_ZZ) / (2 * psio_g) + psi_zoom_max = 9 * threshold_g + a_zoom_r = sqrt(2 * psi_zoom_max * psio_g / ψ_RR) * 1.2 + a_zoom_z = sqrt(2 * psi_zoom_max * psio_g / ψ_ZZ) * 1.2 + sinh_β = sinh(β_r_g) + nr_z = max(200, ceil(Int, 8 * β_r_g * a_zoom_r * 10 / (sinh_β * a_low_g))) + nz_z = max(200, ceil(Int, 8 * β_r_g * a_zoom_z * 10 / (sinh_β * a_low_g))) + r_zoom_grid_vis = Equilibrium.make_stretched_r_grid( + max(raw_inv.rmin, ro_g - a_zoom_r), min(raw_inv.rmax, ro_g + a_zoom_r), + ro_g, nr_z, β_r_g) + z_zoom_grid_vis = Equilibrium.make_stretched_r_grid( + max(raw_inv.zmin, zo_g - a_zoom_z), min(raw_inv.zmax, zo_g + a_zoom_z), + zo_g, nz_z, β_r_g) + println(" Grid vis: global $(nr_g)×$(nz_g), zoom $(nr_z)×$(nz_z)") end - r_global_grid = r_g - z_global_grid = z_g - - d_max_g = max(dR_ax, dZ_ax) - threshold_g = (10 * d_max_g)^2 * max(ψ_RR, ψ_ZZ) / (2 * psio_g) - psi_zoom_max = 9 * threshold_g - a_zoom_r = sqrt(2 * psi_zoom_max * psio_g / ψ_RR) * 1.2 - a_zoom_z = sqrt(2 * psi_zoom_max * psio_g / ψ_ZZ) * 1.2 - sinh_β = sinh(β_r_g) - nr_z = max(200, ceil(Int, 8 * β_r_g * a_zoom_r * 10 / (sinh_β * a_low_g))) - nz_z = max(200, ceil(Int, 8 * β_r_g * a_zoom_z * 10 / (sinh_β * a_low_g))) - r_zoom_grid_vis = Equilibrium.make_stretched_r_grid( - max(raw_inv.rmin, ro_g - a_zoom_r), min(raw_inv.rmax, ro_g + a_zoom_r), - ro_g, nr_z, β_r_g) - z_zoom_grid_vis = Equilibrium.make_stretched_r_grid( - max(raw_inv.zmin, zo_g - a_zoom_z), min(raw_inv.zmax, zo_g + a_zoom_z), - zo_g, nz_z, β_r_g) - println(" Grid vis: global $(nr_g)×$(nz_g), zoom $(nr_z)×$(nz_z)") -end end # haskey(pes, "efit_by_inversion") # ═══════════════════════════════════════════════════════════════════════════════ @@ -296,7 +300,7 @@ println("\n" * "=" ^ 70) println("2. Flux Surface Contour Overlays") println("=" ^ 70) -psi_contours = collect(range(psi_lo, psi_hi; length=20)) +psi_contours = collect(range(psi_lo, psi_hi; length=20)) theta_contour = range(0.0, 1.0; length=256) R_fs = Dict(m => flux_surface_RZ(pes[m], psi_contours, theta_contour) for m in all_methods) @@ -305,7 +309,7 @@ p_ctr_full = plot(; aspect_ratio=:equal, xlabel="R [m]", ylabel="Z [m]", title="Flux surfaces: all methods (psihigh=$psihigh_arg)") p_ctr_core = plot(; aspect_ratio=:equal, xlabel="R [m]", ylabel="Z [m]", title="Deep core zoom (innermost 4 surfaces)") -p_ctr_xpt = plot(; aspect_ratio=:equal, xlabel="R [m]", ylabel="Z [m]", +p_ctr_xpt = plot(; aspect_ratio=:equal, xlabel="R [m]", ylabel="Z [m]", title="Far edge / x-point zoom (outermost 3 surfaces)") for m in all_methods @@ -322,7 +326,7 @@ for m in all_methods ls=method_style[m], lw=1.5, label=lbl) end n_outer = length(psi_contours) - for k in (n_outer - 2):n_outer + for k in (n_outer-2):n_outer lbl = k == n_outer - 2 ? method_label[m] : "" plot!(p_ctr_xpt, Rs[k], Zs[k]; color=method_color[m], ls=method_style[m], lw=1.5, label=lbl) @@ -332,45 +336,47 @@ end # Grid overplots: scatter subsampled grid points on each panel (only if efit_by_inversion ran). # Global grid: every 20th R × 12th Z (grey). Zoom grid: every 3rd R × 3rd Z (darkgrey). if !isempty(r_global_grid) -let - step_rg, step_zg = 20, 12 - Rg = [r_global_grid[ir] for ir in 1:step_rg:length(r_global_grid) - for _ in 1:step_zg:length(z_global_grid)] - Zg = [z_global_grid[iz] for _ in 1:step_rg:length(r_global_grid) - for iz in 1:step_zg:length(z_global_grid)] - scatter!(p_ctr_full, Rg, Zg; ms=0.8, color=:grey, alpha=0.25, - markerstrokewidth=0, label="global grid") - - step_rz, step_zz = 3, 3 - Rz = [r_zoom_grid_vis[ir] for ir in 1:step_rz:length(r_zoom_grid_vis) - for _ in 1:step_zz:length(z_zoom_grid_vis)] - Zz = [z_zoom_grid_vis[iz] for _ in 1:step_rz:length(r_zoom_grid_vis) - for iz in 1:step_zz:length(z_zoom_grid_vis)] - scatter!(p_ctr_full, Rz, Zz; ms=0.8, color=:darkgrey, alpha=0.4, - markerstrokewidth=0, label="zoom grid") - - # Core panel: show both grids at full density within the core zoom region - scatter!(p_ctr_core, Rg, Zg; ms=1.2, color=:grey, alpha=0.3, - markerstrokewidth=0, label="global grid") - scatter!(p_ctr_core, Rz, Zz; ms=1.2, color=:darkgrey, alpha=0.5, - markerstrokewidth=0, label="zoom grid") - - # X-point panel: global grid only (zoom doesn't extend there) - scatter!(p_ctr_xpt, Rg, Zg; ms=1.2, color=:grey, alpha=0.3, - markerstrokewidth=0, label="global grid") -end + let + step_rg, step_zg = 20, 12 + Rg = [r_global_grid[ir] for ir in 1:step_rg:length(r_global_grid) + for _ in 1:step_zg:length(z_global_grid)] + Zg = [z_global_grid[iz] for _ in 1:step_rg:length(r_global_grid) + for iz in 1:step_zg:length(z_global_grid)] + scatter!(p_ctr_full, Rg, Zg; ms=0.8, color=:grey, alpha=0.25, + markerstrokewidth=0, label="global grid") + + step_rz, step_zz = 3, 3 + Rz = [r_zoom_grid_vis[ir] for ir in 1:step_rz:length(r_zoom_grid_vis) + for _ in 1:step_zz:length(z_zoom_grid_vis)] + Zz = [z_zoom_grid_vis[iz] for _ in 1:step_rz:length(r_zoom_grid_vis) + for iz in 1:step_zz:length(z_zoom_grid_vis)] + scatter!(p_ctr_full, Rz, Zz; ms=0.8, color=:darkgrey, alpha=0.4, + markerstrokewidth=0, label="zoom grid") + + # Core panel: show both grids at full density within the core zoom region + scatter!(p_ctr_core, Rg, Zg; ms=1.2, color=:grey, alpha=0.3, + markerstrokewidth=0, label="global grid") + scatter!(p_ctr_core, Rz, Zz; ms=1.2, color=:darkgrey, alpha=0.5, + markerstrokewidth=0, label="zoom grid") + + # X-point panel: global grid only (zoom doesn't extend there) + scatter!(p_ctr_xpt, Rg, Zg; ms=1.2, color=:grey, alpha=0.3, + markerstrokewidth=0, label="global grid") + end end # !isempty(r_global_grid) # Set zoom limits for core and x-point panels using the reference method Rc, Zc = R_fs[ref_method] n_core = 4 -all_R_c = vcat(Rc[1:n_core]...); all_Z_c = vcat(Zc[1:n_core]...) +all_R_c = vcat(Rc[1:n_core]...); +all_Z_c = vcat(Zc[1:n_core]...) pad = 0.03 xlims!(p_ctr_core, minimum(all_R_c) - pad, maximum(all_R_c) + pad) ylims!(p_ctr_core, minimum(all_Z_c) - pad, maximum(all_Z_c) + pad) n_outer = length(psi_contours) -all_R_e = vcat(Rc[(n_outer-2):n_outer]...); all_Z_e = vcat(Zc[(n_outer-2):n_outer]...) +all_R_e = vcat(Rc[(n_outer-2):n_outer]...); +all_Z_e = vcat(Zc[(n_outer-2):n_outer]...) xpt_idx = argmin(all_Z_e) xlims!(p_ctr_xpt, all_R_e[xpt_idx] - 0.20, all_R_e[xpt_idx] + 0.20) ylims!(p_ctr_xpt, all_Z_e[xpt_idx] - 0.05, all_Z_e[xpt_idx] + 0.40) @@ -388,7 +394,7 @@ p_tht_full = plot(; aspect_ratio=:equal, xlabel="R [m]", ylabel="Z [m]", title="θ = const lines: all methods (psihigh=$psihigh_arg)") p_tht_core = plot(; aspect_ratio=:equal, xlabel="R [m]", ylabel="Z [m]", title="Deep core zoom") -p_tht_xpt = plot(; aspect_ratio=:equal, xlabel="R [m]", ylabel="Z [m]", +p_tht_xpt = plot(; aspect_ratio=:equal, xlabel="R [m]", ylabel="Z [m]", title="Far edge / x-point zoom") for m in all_methods @@ -402,14 +408,14 @@ for m in all_methods Zs = [psi_theta_to_RZ(pe, ψ, θ)[2] for ψ in psi_dense] plot!(p_tht_full, Rs, Zs; color=method_color[m], ls=method_style[m], lw=0.9, alpha=0.7, label=lbl) plot!(p_tht_core, Rs, Zs; color=method_color[m], ls=method_style[m], lw=1.5, label=lbl) - plot!(p_tht_xpt, Rs, Zs; color=method_color[m], ls=method_style[m], lw=1.5, label=lbl) + plot!(p_tht_xpt, Rs, Zs; color=method_color[m], ls=method_style[m], lw=1.5, label=lbl) end # Grid dots at every (ψ_i, θ_j) intersection — by construction on the lines above Rg = [psi_theta_to_RZ(pe, ψ, θ)[1] for ψ in pe.rzphi_xs for θ in θ_sub] Zg = [psi_theta_to_RZ(pe, ψ, θ)[2] for ψ in pe.rzphi_xs for θ in θ_sub] scatter!(p_tht_full, Rg, Zg; ms=1.5, color=method_color[m], alpha=0.5, markerstrokewidth=0, label="") scatter!(p_tht_core, Rg, Zg; ms=2.0, color=method_color[m], alpha=0.6, markerstrokewidth=0, label="") - scatter!(p_tht_xpt, Rg, Zg; ms=2.0, color=method_color[m], alpha=0.6, markerstrokewidth=0, label="") + scatter!(p_tht_xpt, Rg, Zg; ms=2.0, color=method_color[m], alpha=0.6, markerstrokewidth=0, label="") end xlims!(p_tht_core, minimum(all_R_c) - pad, maximum(all_R_c) + pad) @@ -430,16 +436,16 @@ println("3. 2D rzphi Geometric Spline Profiles at Select θ Values") println("=" ^ 70) rzphi_specs = [ - ("r²=(R-R₀)²+(Z-Z₀)²", pe -> ((ψ, θ) -> pe.rzphi_rsquared((ψ, θ)))), + ("r²=(R-R₀)²+(Z-Z₀)²", pe -> ((ψ, θ) -> pe.rzphi_rsquared((ψ, θ)))), ("angle offset η/2π−θ", pe -> ((ψ, θ) -> pe.rzphi_offset((ψ, θ)))), - ("ν (toroidal shift)", pe -> ((ψ, θ) -> pe.rzphi_nu((ψ, θ)))), - ("Jacobian", pe -> ((ψ, θ) -> pe.rzphi_jac((ψ, θ)))), + ("ν (toroidal shift)", pe -> ((ψ, θ) -> pe.rzphi_nu((ψ, θ)))), + ("Jacobian", pe -> ((ψ, θ) -> pe.rzphi_jac((ψ, θ)))) ] rzphi_fnames = ["rzphi_rsquared", "rzphi_angle_offset", "rzphi_nu", "rzphi_jacobian"] for (sidx, (sname, fn_getter)) in enumerate(rzphi_specs) - fn_ref = fn_getter(pe_ref) - yd_all = [[fn_ref(ψ, θ) for ψ in psi_full] for θ in theta_select] + fn_ref = fn_getter(pe_ref) + yd_all = [[fn_ref(ψ, θ) for ψ in psi_full] for θ in theta_select] p_full = plot(; xlabel="ψ", ylabel=sname, legend=:best, xlims=(0, 1), title="$sname — full domain (psihigh=$psihigh_arg)") @@ -454,20 +460,25 @@ for (sidx, (sname, fn_getter)) in enumerate(rzphi_specs) plot!(p_full, psi_full, yd; color=tc, lw=2, label="efit θ=$(θ)") plot!(p_core, psi_full[mask_core], yd[mask_core]; color=tc, lw=2, label="efit θ=$(θ)") plot!(p_edge, t_edge_full, yd[mask_edge]; color=tc, lw=2, label="efit θ=$(θ)") - xs = pe_ref.rzphi_xs; ys = [fn_ref(ψ, θ) for ψ in xs] + xs = pe_ref.rzphi_xs + ys = [fn_ref(ψ, θ) for ψ in xs] scatter!(p_full, xs, ys; ms=3, markerstrokewidth=0, color=tc, label="") - let mask = xs .< 0.10; scatter!(p_core, xs[mask], ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") end - let mask = xs .> 0.98; scatter!(p_edge, -log.(1.0 .- xs[mask]), ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") end + let mask = xs .< 0.10 + scatter!(p_core, xs[mask], ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") + end + let mask = xs .> 0.98 + scatter!(p_edge, -log.(1.0 .- xs[mask]), ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") + end end println(" $sname:") for m in compare_methods_active - fn_m = fn_getter(pes[m]) + fn_m = fn_getter(pes[m]) yi_all = [[fn_m(ψ, θ) for ψ in psi_full] for θ in theta_select] for (tidx, θ) in enumerate(theta_select) tc = theta_colors[tidx] yi = yi_all[tidx] - Δ = yd_all[tidx] .- yi + Δ = yd_all[tidx] .- yi plot!(p_full, psi_full, yi; color=tc, lw=1.2, ls=method_style[m], label="$(method_label[m]) θ=$(θ)") plot!(p_core, psi_full[mask_core], yi[mask_core]; color=tc, lw=1.2, @@ -476,10 +487,15 @@ for (sidx, (sname, fn_getter)) in enumerate(rzphi_specs) ls=method_style[m], label="$(method_label[m]) θ=$(θ)") plot!(p_diff, psi_full, Δ; color=tc, lw=1.2, ls=method_style[m], label="(efit−$(method_label[m])) θ=$(θ)") - xs = pes[m].rzphi_xs; ys = [fn_m(ψ, θ) for ψ in xs] + xs = pes[m].rzphi_xs + ys = [fn_m(ψ, θ) for ψ in xs] scatter!(p_full, xs, ys; ms=3, markerstrokewidth=0, color=tc, label="") - let mask = xs .< 0.10; scatter!(p_core, xs[mask], ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") end - let mask = xs .> 0.98; scatter!(p_edge, -log.(1.0 .- xs[mask]), ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") end + let mask = xs .< 0.10 + scatter!(p_core, xs[mask], ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") + end + let mask = xs .> 0.98 + scatter!(p_edge, -log.(1.0 .- xs[mask]), ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") + end Δc = any(mask_core) ? Δ[mask_core] : [0.0] Δe = any(mask_edge) ? Δ[mask_edge] : [0.0] @@ -501,15 +517,15 @@ println("4. Physics (eqfun) Spline Profiles at Select θ Values") println("=" ^ 70) eqfun_specs = [ - ("|B| (total field [T])", pe -> ((ψ, θ) -> pe.eqfun_B((ψ, θ)))), + ("|B| (total field [T])", pe -> ((ψ, θ) -> pe.eqfun_B((ψ, θ)))), ("metric1 (e₁·e₂+q·e₃·e₁)/JB²", pe -> ((ψ, θ) -> pe.eqfun_metric1((ψ, θ)))), - ("metric2 (e₂·e₃+q·e₃²)/JB²", pe -> ((ψ, θ) -> pe.eqfun_metric2((ψ, θ)))), + ("metric2 (e₂·e₃+q·e₃²)/JB²", pe -> ((ψ, θ) -> pe.eqfun_metric2((ψ, θ)))) ] eqfun_fnames = ["eqfun_Bmag", "eqfun_metric1", "eqfun_metric2"] for (eidx, (ename, fn_getter)) in enumerate(eqfun_specs) - fn_ref = fn_getter(pe_ref) - yd_all = [[fn_ref(ψ, θ) for ψ in psi_full] for θ in theta_select] + fn_ref = fn_getter(pe_ref) + yd_all = [[fn_ref(ψ, θ) for ψ in psi_full] for θ in theta_select] p_full = plot(; xlabel="ψ", ylabel=ename, legend=:best, xlims=(0, 1), title="$ename — full domain (psihigh=$psihigh_arg)") @@ -524,20 +540,25 @@ for (eidx, (ename, fn_getter)) in enumerate(eqfun_specs) plot!(p_full, psi_full, yd; color=tc, lw=2, label="efit θ=$(θ)") plot!(p_core, psi_full[mask_core], yd[mask_core]; color=tc, lw=2, label="efit θ=$(θ)") plot!(p_edge, t_edge_full, yd[mask_edge]; color=tc, lw=2, label="efit θ=$(θ)") - xs = pe_ref.rzphi_xs; ys = [fn_ref(ψ, θ) for ψ in xs] + xs = pe_ref.rzphi_xs + ys = [fn_ref(ψ, θ) for ψ in xs] scatter!(p_full, xs, ys; ms=3, markerstrokewidth=0, color=tc, label="") - let mask = xs .< 0.10; scatter!(p_core, xs[mask], ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") end - let mask = xs .> 0.98; scatter!(p_edge, -log.(1.0 .- xs[mask]), ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") end + let mask = xs .< 0.10 + scatter!(p_core, xs[mask], ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") + end + let mask = xs .> 0.98 + scatter!(p_edge, -log.(1.0 .- xs[mask]), ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") + end end println(" $ename:") for m in compare_methods_active - fn_m = fn_getter(pes[m]) + fn_m = fn_getter(pes[m]) yi_all = [[fn_m(ψ, θ) for ψ in psi_full] for θ in theta_select] for (tidx, θ) in enumerate(theta_select) tc = theta_colors[tidx] yi = yi_all[tidx] - Δ = yd_all[tidx] .- yi + Δ = yd_all[tidx] .- yi plot!(p_full, psi_full, yi; color=tc, lw=1.2, ls=method_style[m], label="$(method_label[m]) θ=$(θ)") plot!(p_core, psi_full[mask_core], yi[mask_core]; color=tc, lw=1.2, @@ -546,10 +567,15 @@ for (eidx, (ename, fn_getter)) in enumerate(eqfun_specs) ls=method_style[m], label="$(method_label[m]) θ=$(θ)") plot!(p_diff, psi_full, Δ; color=tc, lw=1.2, ls=method_style[m], label="(efit−$(method_label[m])) θ=$(θ)") - xs = pes[m].rzphi_xs; ys = [fn_m(ψ, θ) for ψ in xs] + xs = pes[m].rzphi_xs + ys = [fn_m(ψ, θ) for ψ in xs] scatter!(p_full, xs, ys; ms=3, markerstrokewidth=0, color=tc, label="") - let mask = xs .< 0.10; scatter!(p_core, xs[mask], ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") end - let mask = xs .> 0.98; scatter!(p_edge, -log.(1.0 .- xs[mask]), ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") end + let mask = xs .< 0.10 + scatter!(p_core, xs[mask], ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") + end + let mask = xs .> 0.98 + scatter!(p_edge, -log.(1.0 .- xs[mask]), ys[mask]; ms=3, markerstrokewidth=0, color=tc, label="") + end Δc = any(mask_core) ? Δ[mask_core] : [0.0] Δe = any(mask_edge) ? Δ[mask_edge] : [0.0] @@ -580,13 +606,13 @@ function row_int(label, vals) @printf(" %-22s %s\n", label, join([@sprintf("%18d", v) for v in vals])) end -row("ro [m]", [pes[m].ro for m in all_methods]) -row("zo [m]", [pes[m].zo for m in all_methods]) -row("psio [Wb/rad]",[pes[m].psio for m in all_methods]) -row("psilow", [pes[m].rzphi_xs[1] for m in all_methods]) -row("psihigh", [pes[m].rzphi_xs[end] for m in all_methods]) -row("q(psilow)", [pes[m].profiles.q_spline(pes[m].rzphi_xs[1]) for m in all_methods]) -row("q(psihigh)", [pes[m].profiles.q_spline(pes[m].rzphi_xs[end]) for m in all_methods]) +row("ro [m]", [pes[m].ro for m in all_methods]) +row("zo [m]", [pes[m].zo for m in all_methods]) +row("psio [Wb/rad]", [pes[m].psio for m in all_methods]) +row("psilow", [pes[m].rzphi_xs[1] for m in all_methods]) +row("psihigh", [pes[m].rzphi_xs[end] for m in all_methods]) +row("q(psilow)", [pes[m].profiles.q_spline(pes[m].rzphi_xs[1]) for m in all_methods]) +row("q(psihigh)", [pes[m].profiles.q_spline(pes[m].rzphi_xs[end]) for m in all_methods]) q_profiles = Dict(m => [pes[m].profiles.q_spline(ψ) for ψ in psi_full] for m in all_methods) row_int("q non-mono (edge)", diff --git a/benchmarks/plot_xi_eigenmode.jl b/benchmarks/plot_xi_eigenmode.jl index 78e26ee82..1d35a834e 100644 --- a/benchmarks/plot_xi_eigenmode.jl +++ b/benchmarks/plot_xi_eigenmode.jl @@ -39,7 +39,7 @@ for ip in 1:nstep @views mul!(xi[:, ip], u1[:, :, ip], c) end -ms = mlow .+ (0:mpert-1) +ms = mlow .+ (0:(mpert-1)) peak = [maximum(abs, @view xi[i, :]) for i in 1:mpert] order = sortperm(peak; rev=true) # dominant harmonics first diff --git a/benchmarks/verify_gal_match.jl b/benchmarks/verify_gal_match.jl index 51dcdd868..28ad6f2c0 100644 --- a/benchmarks/verify_gal_match.jl +++ b/benchmarks/verify_gal_match.jl @@ -19,7 +19,12 @@ xi, dxi, cout, cin, deltar, eig, resid, sing_psi = h5open(h5path) do f end # HDF5 stores ComplexF64 as a compound (re,im); convert if needed to_c(a) = eltype(a) <: Complex ? a : map(x -> ComplexF64(x.re, x.im), a) -xi = to_c(xi); dxi = to_c(dxi); cout = to_c(cout); cin = to_c(cin); deltar = to_c(deltar); eig = to_c(eig) +xi = to_c(xi); +dxi = to_c(dxi); +cout = to_c(cout); +cin = to_c(cin); +deltar = to_c(deltar); +eig = to_c(eig) mpert, mcoil, ngrid = size(xi) msing = size(deltar, 1) diff --git a/docs/make.jl b/docs/make.jl index 92b605efc..2a971d4a4 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -40,9 +40,9 @@ makedocs(; "Tearing" => "inner_layer.md", "Analysis" => "analysis.md", "Utilities" => "utilities.md" - ], + ], "Citations" => "citations.md", - "Developer Notes" => "developer_notes.md", + "Developer Notes" => "developer_notes.md" ], checkdocs=:exports ) diff --git a/docs/src/forcing_terms.md b/docs/src/forcing_terms.md index ba2f7d752..e88c11596 100644 --- a/docs/src/forcing_terms.md +++ b/docs/src/forcing_terms.md @@ -60,7 +60,7 @@ amplitudes directly — no conversion is applied. Required datasets: - `n`: integer array of toroidal mode numbers -- `m`: integer array of poloidal mode numbers +- `m`: integer array of poloidal mode numbers - `amplitude_real`: float array of real parts - `amplitude_imag`: float array of imaginary parts (optional) diff --git a/examples/DIIID-like_SLAYER_example/gpec.toml b/examples/DIIID-like_SLAYER_example/gpec.toml index 487d41f9b..d5dfe09c3 100644 --- a/examples/DIIID-like_SLAYER_example/gpec.toml +++ b/examples/DIIID-like_SLAYER_example/gpec.toml @@ -86,3 +86,12 @@ Q_re_range = [-2.0, 2.0] # Scan box in the normalized Q plane, Re(Q) axis Q_im_range = [-0.5, 3.0] # Scan box in the normalized Q plane, Im(Q) axis nre = 41 # Grid resolution along the Re(Q) axis nim = 31 # Grid resolution along the Im(Q) axis + +[CriticalResonantField] +# CriticalResonantField used to find the critical resonant field sufficent for tearing onset at each rational surface. +enabled = true # Run CriticalResonantField analysis +inner_model = "slayer_fitzpatrick" # Inner-layer Δ(Q) model: "slayer_fitzpatrick", "ggj_shooting", or "ggj_galerkin" +Qmin = -10 # Minimum rotation scanned +Qmax = 10 # Maximum rotation scanned +n = 200 # Number of rotation points scanned +profile_file = "../DIIID-like_ideal_example/TkMkr_D3Dlike_Hmode_kinetic.h5" # Kinetic-profile file (relative to the run dir), required when SLAYER is enabled diff --git a/examples/DIIID-like_ideal_example/analyze_example.jl b/examples/DIIID-like_ideal_example/analyze_example.jl index 715e3ec76..dae831848 100644 --- a/examples/DIIID-like_ideal_example/analyze_example.jl +++ b/examples/DIIID-like_ideal_example/analyze_example.jl @@ -41,7 +41,7 @@ function symmetric_clims(z) end geqdsk_cases = [ - "TkMkr_D3Dlike_Hmode.geqdsk", + "TkMkr_D3Dlike_Hmode.geqdsk" ] base_toml = TOML.parsefile(joinpath(@__DIR__, "gpec.toml")) diff --git a/examples/DIIID-like_ideal_example_IMAS/run_imas_example.jl b/examples/DIIID-like_ideal_example_IMAS/run_imas_example.jl index c4fe1637f..0e416e317 100644 --- a/examples/DIIID-like_ideal_example_IMAS/run_imas_example.jl +++ b/examples/DIIID-like_ideal_example_IMAS/run_imas_example.jl @@ -57,8 +57,8 @@ try config_imas = merge(SHARED_CONFIG, Dict("Equilibrium" => merge(EQ_COMMON, Dict("eq_type" => "imas", "eq_filename" => "from_dd", "imas_cocos" => 11)))) open(joinpath(tmpdir_imas, "gpec.toml"), "w") do io - ; - TOML.print(io, config_imas); + + TOML.print(io, config_imas) end result_imas = GPEC.main([tmpdir_imas]; dd=dd) global et_imas = real(result_imas.ffs.free_boundary.et[1]) @@ -76,8 +76,8 @@ try config_gfile = merge(SHARED_CONFIG, Dict("Equilibrium" => merge(EQ_COMMON, Dict("eq_type" => "efit", "eq_filename" => GEQDSK)))) open(joinpath(tmpdir_gfile, "gpec.toml"), "w") do io - ; - TOML.print(io, config_gfile); + + TOML.print(io, config_gfile) end result_gfile = GPEC.main([tmpdir_gfile]) global et_gfile = real(result_gfile.ffs.free_boundary.et[1]) diff --git a/examples/LAR_beta_scan/run_scan.jl b/examples/LAR_beta_scan/run_scan.jl index 6249ff30d..f6105a2ae 100644 --- a/examples/LAR_beta_scan/run_scan.jl +++ b/examples/LAR_beta_scan/run_scan.jl @@ -30,11 +30,11 @@ using Printf # is approximately uniform over most of the range and smoothly tightens as # the pole is approached, giving an even visual cadence without wasting # points on the flat-slope region far from the pole. -function _warped_grid(x_start::Float64, x_end::Float64, N::Int; p::Float64 = 2.0) - return [x_start + (x_end - x_start) * (1 - (1 - i / (N - 1))^p) for i in 0:N-1] +function _warped_grid(x_start::Float64, x_end::Float64, N::Int; p::Float64=2.0) + return [x_start + (x_end - x_start) * (1 - (1 - i / (N - 1))^p) for i in 0:(N-1)] end -const PC_FULL = _warped_grid(0.001, 0.1735, 40; p = 2.0) +const PC_FULL = _warped_grid(0.001, 0.1735, 40; p=2.0) const PC_TEST = [0.001, 0.10, 0.17] @@ -58,7 +58,9 @@ function run_single(pc::Float64) config = deepcopy(GPEC_BASE) config["TJ_ANALYTIC_INPUT"]["pc"] = pc config["ForceFreeStates"]["HDF5_filename"] = joinpath(run_dir, "gpec.h5") - open(joinpath(run_dir, "gpec.toml"), "w") do io; TOML.print(io, config); end + open(joinpath(run_dir, "gpec.toml"), "w") do io + TOML.print(io, config) + end GeneralizedPerturbedEquilibrium.main([run_dir]) return extract_results(joinpath(run_dir, "gpec.h5")) @@ -73,24 +75,32 @@ end function extract_results(h5_path::String) h5open(h5_path, "r") do f fbs = "ForceFreeStates/FreeBoundaryStability" - ep = read(f, "$fbs/eigenmode_plasma_energies"); ev = read(f, "$fbs/eigenmode_vacuum_energies"); et = read(f, "$fbs/eigenmode_energies") + ep = read(f, "$fbs/eigenmode_plasma_energies") + ev = read(f, "$fbs/eigenmode_vacuum_energies") + et = read(f, "$fbs/eigenmode_energies") msing = read(f, "SingularSurfaces/rational_count") m_sing = read(f, "SingularSurfaces/rational_m") dp_mat = haskey(f, "SingularSurfaces/Delta_prime_matrix") ? read(f, "SingularSurfaces/Delta_prime_matrix") : nothing qlim = haskey(f, "Info/qlim") ? read(f, "Info/qlim") : read(f, "Equilibrium/q_max") - q0 = read(f, "Equilibrium/q_axis"); qmax = read(f, "Equilibrium/q_max") + q0 = read(f, "Equilibrium/q_axis") + qmax = read(f, "Equilibrium/q_max") - dp_21 = NaN + NaN*im; dp_31 = NaN + NaN*im + dp_21 = NaN + NaN*im + dp_31 = NaN + NaN*im if dp_mat !== nothing && msing > 0 for s in 1:min(msing, size(dp_mat, 1)) m_val = size(m_sing, 1) == msing ? m_sing[s, 1] : m_sing[1, s] - if m_val == 2; dp_21 = dp_mat[s, s]; end - if m_val == 3; dp_31 = dp_mat[s, s]; end + if m_val == 2 + dp_21 = dp_mat[s, s] + end + if m_val == 3 + dp_31 = dp_mat[s, s] + end end end return (dp_21=dp_21, dp_31=dp_31, - dW_plasma=real(ep[1]), dW_vacuum=real(ev[1]), dW_total=real(et[1]), - q0=q0, qmax=qmax, qlim=qlim, msing=msing, dp_matrix=dp_mat) + dW_plasma=real(ep[1]), dW_vacuum=real(ev[1]), dW_total=real(et[1]), + q0=q0, qmax=qmax, qlim=qlim, msing=msing, dp_matrix=dp_mat) end end @@ -117,11 +127,20 @@ function main() haskey(f, gname) && delete_object(f, gname) g = create_group(f, gname) g["pressure_factor"] = pc - g["dp_21_real"] = real(result.dp_21); g["dp_21_imag"] = imag(result.dp_21) - g["dp_31_real"] = real(result.dp_31); g["dp_31_imag"] = imag(result.dp_31) - g["dW_plasma"] = result.dW_plasma; g["dW_vacuum"] = result.dW_vacuum; g["dW_total"] = result.dW_total - g["q0"] = result.q0; g["qmax"] = result.qmax; g["qlim"] = result.qlim; g["msing"] = result.msing - if result.dp_matrix !== nothing; g["dp_matrix"] = result.dp_matrix; end + g["dp_21_real"] = real(result.dp_21) + g["dp_21_imag"] = imag(result.dp_21) + g["dp_31_real"] = real(result.dp_31) + g["dp_31_imag"] = imag(result.dp_31) + g["dW_plasma"] = result.dW_plasma + g["dW_vacuum"] = result.dW_vacuum + g["dW_total"] = result.dW_total + g["q0"] = result.q0 + g["qmax"] = result.qmax + g["qlim"] = result.qlim + g["msing"] = result.msing + if result.dp_matrix !== nothing + g["dp_matrix"] = result.dp_matrix + end end @printf(" dp21=%+.4f%+.4fi dp31=%+.4f%+.4fi dW_t=%+.6f qa=%.3f\n", real(result.dp_21), imag(result.dp_21), real(result.dp_31), imag(result.dp_31), diff --git a/examples/LAR_epsilon_scan/run_scan.jl b/examples/LAR_epsilon_scan/run_scan.jl index e3327ab95..f487332f0 100644 --- a/examples/LAR_epsilon_scan/run_scan.jl +++ b/examples/LAR_epsilon_scan/run_scan.jl @@ -30,11 +30,11 @@ using Printf # spacing tightens smoothly as the pole is approached — the flat low-ε # region is covered with even cadence, and more points land in the final # few percent where Δ' rises by orders of magnitude. -function _warped_grid(x_start::Float64, x_end::Float64, N::Int; p::Float64 = 2.0) - return [x_start + (x_end - x_start) * (1 - (1 - i / (N - 1))^p) for i in 0:N-1] +function _warped_grid(x_start::Float64, x_end::Float64, N::Int; p::Float64=2.0) + return [x_start + (x_end - x_start) * (1 - (1 - i / (N - 1))^p) for i in 0:(N-1)] end -const EPSILONS_FULL = _warped_grid(0.125, 0.660, 56; p = 2.0) +const EPSILONS_FULL = _warped_grid(0.125, 0.660, 56; p=2.0) const EPSILONS_TEST = [0.2495, 0.4072, 0.5510] @@ -65,7 +65,9 @@ function run_single(epsilon::Float64) config["TJ_ANALYTIC_INPUT"]["lar_r0"] = GPEC_BASE["TJ_ANALYTIC_INPUT"]["lar_a"] / epsilon config["Equilibrium"]["eq_type"] = "tj_analytic_direct" config["ForceFreeStates"]["HDF5_filename"] = joinpath(run_dir, "gpec.h5") - open(joinpath(run_dir, "gpec.toml"), "w") do io; TOML.print(io, config); end + open(joinpath(run_dir, "gpec.toml"), "w") do io + TOML.print(io, config) + end GeneralizedPerturbedEquilibrium.main([run_dir]) return extract_results(joinpath(run_dir, "gpec.h5")) @@ -80,24 +82,32 @@ end function extract_results(h5_path::String) h5open(h5_path, "r") do f fbs = "ForceFreeStates/FreeBoundaryStability" - ep = read(f, "$fbs/eigenmode_plasma_energies"); ev = read(f, "$fbs/eigenmode_vacuum_energies"); et = read(f, "$fbs/eigenmode_energies") + ep = read(f, "$fbs/eigenmode_plasma_energies") + ev = read(f, "$fbs/eigenmode_vacuum_energies") + et = read(f, "$fbs/eigenmode_energies") msing = read(f, "SingularSurfaces/rational_count") m_sing = read(f, "SingularSurfaces/rational_m") dp_mat = haskey(f, "SingularSurfaces/Delta_prime_matrix") ? read(f, "SingularSurfaces/Delta_prime_matrix") : nothing qlim = haskey(f, "Info/qlim") ? read(f, "Info/qlim") : read(f, "Equilibrium/q_max") - q0 = read(f, "Equilibrium/q_axis"); qmax = read(f, "Equilibrium/q_max") + q0 = read(f, "Equilibrium/q_axis") + qmax = read(f, "Equilibrium/q_max") - dp_21 = NaN + NaN*im; dp_31 = NaN + NaN*im + dp_21 = NaN + NaN*im + dp_31 = NaN + NaN*im if dp_mat !== nothing && msing > 0 for s in 1:min(msing, size(dp_mat, 1)) m_val = size(m_sing, 1) == msing ? m_sing[s, 1] : m_sing[1, s] - if m_val == 2; dp_21 = dp_mat[s, s]; end - if m_val == 3; dp_31 = dp_mat[s, s]; end + if m_val == 2 + dp_21 = dp_mat[s, s] + end + if m_val == 3 + dp_31 = dp_mat[s, s] + end end end return (dp_21=dp_21, dp_31=dp_31, - dW_plasma=real(ep[1]), dW_vacuum=real(ev[1]), dW_total=real(et[1]), - q0=q0, qmax=qmax, qlim=qlim, msing=msing, dp_matrix=dp_mat) + dW_plasma=real(ep[1]), dW_vacuum=real(ev[1]), dW_total=real(et[1]), + q0=q0, qmax=qmax, qlim=qlim, msing=msing, dp_matrix=dp_mat) end end @@ -125,11 +135,20 @@ function main() haskey(f, gname) && delete_object(f, gname) g = create_group(f, gname) g["epsilon"] = eps - g["dp_21_real"] = real(result.dp_21); g["dp_21_imag"] = imag(result.dp_21) - g["dp_31_real"] = real(result.dp_31); g["dp_31_imag"] = imag(result.dp_31) - g["dW_plasma"] = result.dW_plasma; g["dW_vacuum"] = result.dW_vacuum; g["dW_total"] = result.dW_total - g["q0"] = result.q0; g["qmax"] = result.qmax; g["qlim"] = result.qlim; g["msing"] = result.msing - if result.dp_matrix !== nothing; g["dp_matrix"] = result.dp_matrix; end + g["dp_21_real"] = real(result.dp_21) + g["dp_21_imag"] = imag(result.dp_21) + g["dp_31_real"] = real(result.dp_31) + g["dp_31_imag"] = imag(result.dp_31) + g["dW_plasma"] = result.dW_plasma + g["dW_vacuum"] = result.dW_vacuum + g["dW_total"] = result.dW_total + g["q0"] = result.q0 + g["qmax"] = result.qmax + g["qlim"] = result.qlim + g["msing"] = result.msing + if result.dp_matrix !== nothing + g["dp_matrix"] = result.dp_matrix + end end @printf(" dp21=%+.4f%+.4fi dp31=%+.4f%+.4fi dW_t=%+.6f qa=%.3f\n", real(result.dp_21), imag(result.dp_21), real(result.dp_31), imag(result.dp_31), diff --git a/examples/Solovev_ideal_example/analyze_example.jl b/examples/Solovev_ideal_example/analyze_example.jl index 4c5a8eb7c..f3d6f0b99 100644 --- a/examples/Solovev_ideal_example/analyze_example.jl +++ b/examples/Solovev_ideal_example/analyze_example.jl @@ -9,8 +9,11 @@ h5path = joinpath(@__DIR__, "gpec.h5") # Summary plots p_eq = Analysis.Equilibrium.plot_equilibrium_summary(h5path) p_ffs = Analysis.ForceFreeStates.plot_ffs_summary(h5path) -p_pe = Analysis.PerturbedEquilibrium.plot_perturbed_equilibrium_summary(h5path) +p_pe = Analysis.PerturbedEquilibrium.plot_perturbed_equilibrium_summary(h5path) -display(p_eq); Plots.savefig(p_eq, joinpath(@__DIR__, "equilibrium_summary.png")) -display(p_ffs); Plots.savefig(p_ffs, joinpath(@__DIR__, "ffs_summary.png")) -display(p_pe); Plots.savefig(p_pe, joinpath(@__DIR__, "pe_summary.png")) \ No newline at end of file +display(p_eq); +Plots.savefig(p_eq, joinpath(@__DIR__, "equilibrium_summary.png")) +display(p_ffs); +Plots.savefig(p_ffs, joinpath(@__DIR__, "ffs_summary.png")) +display(p_pe); +Plots.savefig(p_pe, joinpath(@__DIR__, "pe_summary.png")) diff --git a/examples/Solovev_ideal_example_multi_n/analyze_example.jl b/examples/Solovev_ideal_example_multi_n/analyze_example.jl index 3a1e46134..068dd2a0d 100644 --- a/examples/Solovev_ideal_example_multi_n/analyze_example.jl +++ b/examples/Solovev_ideal_example_multi_n/analyze_example.jl @@ -9,11 +9,14 @@ h5path = joinpath(@__DIR__, "gpec.h5") # Summary plots p_eq = Analysis.Equilibrium.plot_equilibrium_summary(h5path) p_ffs = Analysis.ForceFreeStates.plot_ffs_summary(h5path) -p_pe = Analysis.PerturbedEquilibrium.plot_perturbed_equilibrium_summary(h5path) +p_pe = Analysis.PerturbedEquilibrium.plot_perturbed_equilibrium_summary(h5path) -display(p_eq); Plots.savefig(p_eq, joinpath(@__DIR__, "equilibrium_summary.png")) -display(p_ffs); Plots.savefig(p_ffs, joinpath(@__DIR__, "ffs_summary.png")) -display(p_pe); Plots.savefig(p_pe, joinpath(@__DIR__, "pe_summary.png")) +display(p_eq); +Plots.savefig(p_eq, joinpath(@__DIR__, "equilibrium_summary.png")) +display(p_ffs); +Plots.savefig(p_ffs, joinpath(@__DIR__, "ffs_summary.png")) +display(p_pe); +Plots.savefig(p_pe, joinpath(@__DIR__, "pe_summary.png")) # Analyze the single-n runs h5path_n1 = joinpath(@__DIR__, "single_n_1", "euler_n1.h5") @@ -21,5 +24,7 @@ h5path_n2 = joinpath(@__DIR__, "single_n_2", "euler_n2.h5") p_n1 = Analysis.ForceFreeStates.plot_ffs_summary(h5path_n1) p_n2 = Analysis.ForceFreeStates.plot_ffs_summary(h5path_n2) -display(p_n1); Plots.savefig(p_n1, joinpath(@__DIR__, "single_n_1", "ffs_summary.png")) -display(p_n2); Plots.savefig(p_n2, joinpath(@__DIR__, "single_n_2", "ffs_summary.png")) +display(p_n1); +Plots.savefig(p_n1, joinpath(@__DIR__, "single_n_1", "ffs_summary.png")) +display(p_n2); +Plots.savefig(p_n2, joinpath(@__DIR__, "single_n_2", "ffs_summary.png")) diff --git a/regression-harness/src/database.jl b/regression-harness/src/database.jl index c9a06b303..c7f043bc2 100644 --- a/regression-harness/src/database.jl +++ b/regression-harness/src/database.jl @@ -50,7 +50,9 @@ added by a later schema migration (NULL on every pre-existing row) need both cas """ _column(x, default) = (x === nothing || x === missing) ? default : x -"""Materialize SQLite query results as a Vector of NamedTuples.""" +""" +Materialize SQLite query results as a Vector of NamedTuples. +""" function query_rows(db::SQLite.DB, sql::String, params=()) result = DBInterface.execute(db, sql, params) ct = Tables.columntable(result) @@ -70,7 +72,9 @@ const ENV_COLUMNS = [ ("pinned", "INTEGER") ] -"""Add any `runs` columns missing from a database created by an earlier harness version.""" +""" +Add any `runs` columns missing from a database created by an earlier harness version. +""" function migrate_schema!(db::SQLite.DB) existing = Set(String[]) for row in query_rows(db, "PRAGMA table_info(runs)") @@ -107,10 +111,10 @@ environment. Rows predating fingerprinting hold NULL and therefore never match entries most likely to be misleading are exactly the ones that get re-run. """ function is_cached(db::SQLite.DB, commit_hash::String, case_name::String; - expected_key::Union{String,Nothing}=nothing)::Bool + expected_key::Union{String,Nothing}=nothing)::Bool if expected_key === nothing rows = query_rows(db, "SELECT id FROM runs WHERE commit_hash = ? AND case_name = ? AND success = 1", - (commit_hash, case_name)) + (commit_hash, case_name)) return !isempty(rows) end rows = query_rows(db, @@ -125,7 +129,7 @@ fingerprinting. Used to explain *why* a cached result was rejected. """ function cached_env_key(db::SQLite.DB, commit_hash::String, case_name::String)::Union{String,Nothing} rows = query_rows(db, "SELECT env_key FROM runs WHERE commit_hash = ? AND case_name = ?", - (commit_hash, case_name)) + (commit_hash, case_name)) isempty(rows) && return nothing key = _column(first(rows).env_key, nothing) key === nothing && return nothing @@ -135,15 +139,15 @@ end function delete_cached(db::SQLite.DB, commit_hash::String, case_name::String) # ON DELETE CASCADE handles quantities cleanup automatically DBInterface.execute(db, "DELETE FROM runs WHERE commit_hash = ? AND case_name = ?", - (commit_hash, case_name)) + (commit_hash, case_name)) end function store_run(db::SQLite.DB, commit_hash::AbstractString, commit_short::AbstractString, - commit_date::AbstractString, commit_msg::AbstractString, - case_name::AbstractString, runtime_s::Float64, - extracted::Vector{ExtractedQuantity}; - success::Bool=true, error_msg::AbstractString="", - fingerprint::EnvFingerprint=UNKNOWN_ENV) + commit_date::AbstractString, commit_msg::AbstractString, + case_name::AbstractString, runtime_s::Float64, + extracted::Vector{ExtractedQuantity}; + success::Bool=true, error_msg::AbstractString="", + fingerprint::EnvFingerprint=UNKNOWN_ENV) ran_at = Dates.format(Dates.now(), "yyyy-mm-ddTHH:MM:SS") SQLite.transaction(db) do @@ -155,10 +159,10 @@ function store_run(db::SQLite.DB, commit_hash::AbstractString, commit_short::Abs env_key, julia_version, os_arch, manifest_sha, nthreads, blas_threads, pinned) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", (String(commit_hash), String(commit_short), String(commit_date), String(commit_msg), - String(case_name), ran_at, runtime_s, success ? 1 : 0, String(error_msg), - env_key(fingerprint), fingerprint.julia_version, fingerprint.os_arch, - fingerprint.manifest_sha, fingerprint.nthreads, fingerprint.blas_threads, - fingerprint.pinned ? 1 : 0)) + String(case_name), ran_at, runtime_s, success ? 1 : 0, String(error_msg), + env_key(fingerprint), fingerprint.julia_version, fingerprint.os_arch, + fingerprint.manifest_sha, fingerprint.nthreads, fingerprint.blas_threads, + fingerprint.pinned ? 1 : 0)) run_id = SQLite.last_insert_rowid(db) @@ -168,14 +172,14 @@ function store_run(db::SQLite.DB, commit_hash::AbstractString, commit_short::Abs (run_id, qty_name, qty_label, value_real, value_int, value_text, value_type, noise_threshold) VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", (run_id, eq.name, eq.label, eq.value_real, eq.value_int, eq.value_text, - eq.value_type, eq.noise_threshold)) + eq.value_type, eq.noise_threshold)) end end end function store_failed_run(db::SQLite.DB, commit_hash::AbstractString, commit_short::AbstractString, - commit_date::AbstractString, commit_msg::AbstractString, - case_name::AbstractString, error_msg::AbstractString) + commit_date::AbstractString, commit_msg::AbstractString, + case_name::AbstractString, error_msg::AbstractString) ran_at = Dates.format(Dates.now(), "yyyy-mm-ddTHH:MM:SS") delete_cached(db, String(commit_hash), String(case_name)) DBInterface.execute(db, @@ -183,14 +187,14 @@ function store_failed_run(db::SQLite.DB, commit_hash::AbstractString, commit_sho (commit_hash, commit_short, commit_date, commit_msg, case_name, ran_at, runtime_s, success, error_msg) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""", (String(commit_hash), String(commit_short), String(commit_date), String(commit_msg), - String(case_name), ran_at, 0.0, 0, String(error_msg))) + String(case_name), ran_at, 0.0, 0, String(error_msg))) end """ Get all quantities for a (commit, case) pair. Returns Dict{qty_name => NamedTuple}. """ function get_quantities(db::SQLite.DB, commit_hash::String, case_name::String) - results = Dict{String, NamedTuple}() + results = Dict{String,NamedTuple}() rows = query_rows(db, """SELECT q.qty_name, q.qty_label, q.value_real, q.value_int, q.value_text, q.value_type, q.noise_threshold @@ -202,12 +206,12 @@ function get_quantities(db::SQLite.DB, commit_hash::String, case_name::String) for row in rows name = something(row.qty_name, "") results[name] = ( - label = something(row.qty_label, name), - value_real = row.value_real, - value_int = row.value_int, - value_text = row.value_text, - value_type = something(row.value_type, "missing"), - noise_threshold = something(row.noise_threshold, 0.0), + label=something(row.qty_label, name), + value_real=row.value_real, + value_int=row.value_int, + value_text=row.value_text, + value_type=something(row.value_type, "missing"), + noise_threshold=something(row.noise_threshold, 0.0) ) end return results @@ -233,13 +237,13 @@ function get_run_info(db::SQLite.DB, commit_hash::String, case_name::String) _column(row.pinned, 0) == 1 ) return ( - commit_short = something(row.commit_short, ""), - commit_date = something(row.commit_date, ""), - commit_msg = something(row.commit_msg, ""), - runtime_s = something(row.runtime_s, 0.0), - success = coalesce(row.success, 0) == 1, - error_msg = something(row.error_msg, ""), - fingerprint = fingerprint, + commit_short=something(row.commit_short, ""), + commit_date=something(row.commit_date, ""), + commit_msg=something(row.commit_msg, ""), + runtime_s=something(row.runtime_s, 0.0), + success=coalesce(row.success, 0) == 1, + error_msg=something(row.error_msg, ""), + fingerprint=fingerprint ) end diff --git a/regression-harness/src/env.jl b/regression-harness/src/env.jl index 20718c4cb..a7db6d339 100644 --- a/regression-harness/src/env.jl +++ b/regression-harness/src/env.jl @@ -49,7 +49,9 @@ end env_key(fp::EnvFingerprint) = env_key(fp.julia_version, fp.os_arch, fp.pinned ? fp.manifest_sha : "unpinned") -"""SHA-256 of a file, or "" when it does not exist.""" +""" +SHA-256 of a file, or "" when it does not exist. +""" function file_sha256(path::AbstractString)::String isfile(path) || return "" return bytes2hex(SHA.sha256(read(path))) @@ -108,7 +110,9 @@ function read_runinfo(path::String, pinned::Bool) return (something(runtime_s, NaN), fp) end -"""One-line human-readable summary of an environment, for report headers.""" +""" +One-line human-readable summary of an environment, for report headers. +""" function describe_env(fp::EnvFingerprint)::String isempty(fp.julia_version) && return "environment unknown (cached before fingerprinting)" mani = isempty(fp.manifest_sha) ? "no Manifest" : "manifest " * fp.manifest_sha[1:min(8, end)] diff --git a/regression-harness/src/reporter.jl b/regression-harness/src/reporter.jl index 4fdecfbe3..2fef2b990 100644 --- a/regression-harness/src/reporter.jl +++ b/regression-harness/src/reporter.jl @@ -233,7 +233,7 @@ function report_two_ref_comparison(db::SQLite.DB, case_spec::CaseSpec, println("Summary: ", join(parts, ", ")) println() return (n_ok=n_ok, n_changed=n_changed, n_missing=n_missing, - n_failed=count(identity, (failed1, failed2))) + n_failed=count(identity, (failed1, failed2))) end """ @@ -366,7 +366,7 @@ function report_multi_ref(db::SQLite.DB, case_spec::CaseSpec, end end if length(refs) >= 2 - last_two = filter(!isnothing, run_infos[(end - 1):end]) + last_two = filter(!isnothing, run_infos[(end-1):end]) length(last_two) == 2 && _warn_env_difference(last_two[1].fingerprint, last_two[2].fingerprint) end println("-"^total_w) @@ -387,7 +387,7 @@ function report_multi_ref(db::SQLite.DB, case_spec::CaseSpec, end println() return (n_ok=n_ok, n_changed=n_changed, n_missing=n_missing, - n_failed=count(identity, failed_mask)) + n_failed=count(identity, failed_mask)) end """ diff --git a/regression-harness/src/types.jl b/regression-harness/src/types.jl index 05c7159ce..bfce92ed7 100644 --- a/regression-harness/src/types.jl +++ b/regression-harness/src/types.jl @@ -19,10 +19,11 @@ end Specification for a test case: what to run and what to extract. `kind` selects the runner backend: + - "gpec_run" (default) — run GPEC end-to-end on `example_dir`, extract from `gpec.h5` - "computed" — run a self-contained Julia computation that writes a small h5 - (no `example_dir` required); used for analytic/reference cases - like the GGJ inner-layer benchmark. + (no `example_dir` required); used for analytic/reference cases + like the GGJ inner-layer benchmark. """ struct CaseSpec name::String diff --git a/regression-harness/src/utils.jl b/regression-harness/src/utils.jl index 01afbd40a..d1110f8ef 100644 --- a/regression-harness/src/utils.jl +++ b/regression-harness/src/utils.jl @@ -130,7 +130,7 @@ newest. Without it, two refs are compared across two different package sets and differences surface as physics regressions. """ function create_worktree(commit_hash::String, repo_root::String; - pin_manifest_from::Union{String,Nothing}=nothing)::String + pin_manifest_from::Union{String,Nothing}=nothing)::String short = commit_hash[1:min(8, length(commit_hash))] worktree_path = tempname() * "_gpec_$(short)" try diff --git a/src/Analysis/Equilibrium.jl b/src/Analysis/Equilibrium.jl index 6dbfede40..51b10f851 100644 --- a/src/Analysis/Equilibrium.jl +++ b/src/Analysis/Equilibrium.jl @@ -219,7 +219,7 @@ function plot_flux_surfaces(h5path; n_psi=11, n_theta=18, save_path=nothing) for s in 1:msing idx = argmin(abs.(xs_rz .- psi_sing[s])) q_label = abs(q_sing[s] - round(q_sing[s])) < 0.05 ? - "q=$(round(Int, q_sing[s]))" : "q=$(round(q_sing[s], digits=2))" + "q=$(round(Int, q_sing[s]))" : "q=$(round(q_sing[s], digits=2))" plot!(p, [R_grid[idx, :]; R_grid[idx, 1]], [Z_grid[idx, :]; Z_grid[idx, 1]]; color=:red, linewidth=1.5, label=s == 1 ? "Rational surface" : "") @@ -368,23 +368,26 @@ function plot_equilibrium_summary(h5path; save_path=nothing) title_str = "q0=$(round(q0,digits=2)) q95=$(round(q95,digits=2)) βₜ=$(round(betat,digits=3)) βₙ=$(round(betan,digits=3)) κ=$(round(kappa,digits=2)) li1=$(round(li1,digits=3))" - p_rz = plot_flux_surfaces(h5path) - p_q = plot_qprofile(h5path; show_singular=true) + p_rz = plot_flux_surfaces(h5path) + p_q = plot_qprofile(h5path; show_singular=true) p_pres = plot_pressure_profile(h5path) - p_f = plot_f_profile(h5path) - p_gse = plot_gse_by_theta(h5path) # includes integrated overplot; nothing if absent + p_f = plot_f_profile(h5path) + p_gse = plot_gse_by_theta(h5path) # includes integrated overplot; nothing if absent # Suppress x-axis labels/ticks on all but the bottom profile panel — they share the # same ψ_N axis and labeling every panel wastes vertical space. hide_xaxis!(p) = plot!(p; xlabel="", xformatter=_->"", bottom_margin=1Plots.mm) if isnothing(p_gse) - hide_xaxis!(p_q); hide_xaxis!(p_pres) + hide_xaxis!(p_q) + hide_xaxis!(p_pres) l = @layout [a{0.38w} [b; c; d]] p = plot(p_rz, p_q, p_pres, p_f; layout=l, size=(1300, 750), plot_title=title_str, plot_titlefontsize=10, top_margin=8Plots.mm) else - hide_xaxis!(p_q); hide_xaxis!(p_pres); hide_xaxis!(p_f) + hide_xaxis!(p_q) + hide_xaxis!(p_pres) + hide_xaxis!(p_f) l = @layout [a{0.38w} [b; c; d; e]] p = plot(p_rz, p_q, p_pres, p_f, p_gse; layout=l, size=(1300, 1000), plot_title=title_str, plot_titlefontsize=10, top_margin=8Plots.mm) diff --git a/src/Analysis/PerturbedEquilibrium.jl b/src/Analysis/PerturbedEquilibrium.jl index 33f8bdc0f..7c1ea2d92 100644 --- a/src/Analysis/PerturbedEquilibrium.jl +++ b/src/Analysis/PerturbedEquilibrium.jl @@ -45,10 +45,10 @@ function plot_resonant_area_weighted_field_amplitude(h5path; save_path=nothing) return plot(; title="No resonant area-weighted field data — run with perturbed equilibrium enabled", legend=false) resonant_area_weighted_field, rational_psi, rational_q, rational_n = h5open(h5path, "r") do fid - read(fid[base * "resonant_area_weighted_field"]), - read(fid[base * "rational_psi"]), - read(fid[base * "rational_q"]), - read(fid[base * "rational_n"]) + read(fid[base*"resonant_area_weighted_field"]), + read(fid[base*"rational_psi"]), + read(fid[base*"rational_q"]), + read(fid[base*"rational_n"]) end p = plot(; xlabel="Norm. Poloidal Flux", ylabel="|b^r| [T]", @@ -96,9 +96,9 @@ function plot_island_widths(h5path; save_path=nothing) return plot(; title="No island width data — run with perturbed equilibrium enabled", legend=false) island_hw, rational_psi, rational_q = h5open(h5path, "r") do fid - read(fid[base * "island_half_width"]), - read(fid[base * "rational_psi"]), - read(fid[base * "rational_q"]) + read(fid[base*"island_half_width"]), + read(fid[base*"rational_psi"]), + read(fid[base*"rational_q"]) end p = scatter( @@ -150,9 +150,9 @@ function plot_chirikov_parameter(h5path; save_path=nothing) return plot(; title="No Chirikov data — run with perturbed equilibrium enabled", legend=false) chirikov, rational_psi, rational_q = h5open(h5path, "r") do fid - read(fid[base * "chirikov_parameter"]), - read(fid[base * "rational_psi"]), - read(fid[base * "rational_q"]) + read(fid[base*"chirikov_parameter"]), + read(fid[base*"rational_psi"]), + read(fid[base*"rational_q"]) end colors = [k > 1.0 ? :red : :steelblue for k in chirikov] @@ -212,10 +212,10 @@ function plot_driven_delta_prime(h5path; save_path=nothing) return plot(; title="No PE Δ' data — run with perturbed equilibrium enabled", legend=false) delta_prime, rational_psi, rational_q, rational_n = h5open(h5path, "r") do fid - read(fid[base * "Delta_prime"]), - read(fid[base * "rational_psi"]), - read(fid[base * "rational_q"]), - read(fid[base * "rational_n"]) + read(fid[base*"Delta_prime"]), + read(fid[base*"rational_psi"]), + read(fid[base*"rational_q"]), + read(fid[base*"rational_n"]) end p = plot(; xlabel="Norm. Poloidal Flux", ylabel="Re(Δ')", @@ -298,10 +298,10 @@ function _plot_resonant_current(h5path) return plot(; title="No resonant current data", legend=false) resonant_current, rational_psi, rational_q, rational_n = h5open(h5path, "r") do fid - read(fid[base * "resonant_current"]), - read(fid[base * "rational_psi"]), - read(fid[base * "rational_q"]), - read(fid[base * "rational_n"]) + read(fid[base*"resonant_current"]), + read(fid[base*"rational_psi"]), + read(fid[base*"rational_q"]), + read(fid[base*"rational_n"]) end p = plot(; xlabel="Norm. Poloidal Flux", ylabel="|I_res|", @@ -352,10 +352,10 @@ A `Plots.jl` plot object. """ function plot_mode_spectrogram(h5path; component=:xi_psi, save_path=nothing) comp_map = Dict( - :xi_psi => "xi_psi", - :b_psi => "b_psi_area_weighted", # area-normalized b^ψ + :xi_psi => "xi_psi", + :b_psi => "b_psi_area_weighted", # area-normalized b^ψ :b_theta => "b_theta", - :b_zeta => "b_zeta", + :b_zeta => "b_zeta" ) haskey(comp_map, component) || error("component must be one of :xi_psi, :b_psi, :b_theta, :b_zeta") @@ -439,9 +439,9 @@ Three-panel composite summary of perturbed equilibrium results: A `Plots.jl` plot object. """ function plot_perturbed_equilibrium_summary(h5path; save_path=nothing) - p_islands = plot_resonant_area_weighted_field_amplitude(h5path) - p_bpsi = _plot_bpsi_edge_spectrum(h5path) - p_spectro = plot_mode_spectrogram(h5path; component=:xi_psi) + p_islands = plot_resonant_area_weighted_field_amplitude(h5path) + p_bpsi = _plot_bpsi_edge_spectrum(h5path) + p_spectro = plot_mode_spectrogram(h5path; component=:xi_psi) l = @layout [grid(1, 2){0.35h}; b] p = plot(p_islands, p_bpsi, p_spectro; layout=l, size=(1100, 1100)) @@ -457,11 +457,11 @@ function _plot_bpsi_edge_spectrum(h5path) return plot(; title="No b_psi data — run with perturbed equilibrium enabled", legend=false) data, mlow, mhigh = h5open(h5path, "r") do fid - read(fid[base * "b_psi_area_weighted"]), + read(fid[base*"b_psi_area_weighted"]), read(fid["Info/mlow"]), read(fid["Info/mhigh"]) end - mpert = mhigh - mlow + 1 + mpert = mhigh - mlow + 1 m_vals = mlow:mhigh bpsi_edge = abs.(data[end, 1:mpert]) diff --git a/src/Analysis/PerturbedEquilibriumModes.jl b/src/Analysis/PerturbedEquilibriumModes.jl index 58aacdaf9..b63ac97e2 100644 --- a/src/Analysis/PerturbedEquilibriumModes.jl +++ b/src/Analysis/PerturbedEquilibriumModes.jl @@ -20,33 +20,37 @@ Reads all required metadata (mlow, nlow, mpert, npert) and spline data (ν) from the HDF5 file. # Arguments -- `h5_file::String`: Path to gpec.h5 output file -- `variable::String`: HDF5 dataset path, e.g. `"PerturbedEquilibrium/Response/xi_R"` + + - `h5_file::String`: Path to gpec.h5 output file + - `variable::String`: HDF5 dataset path, e.g. `"PerturbedEquilibrium/Response/xi_R"` # Keyword arguments -- `mtheta::Int`: theta grid resolution (default: `max(2*(|mlow|+mpert), 512)`) -- `keep_sfl_phi::Bool`: if `true` (default), output in SFL toroidal angle; - if `false`, apply `exp(i*n*ν(ψ,θ))` to convert to machine toroidal angle - and conjugate if `helicity > 0` (matches Fortran `gpout_xbrzphifun`) + + - `mtheta::Int`: theta grid resolution (default: `max(2*(|mlow|+mpert), 512)`) + - `keep_sfl_phi::Bool`: if `true` (default), output in SFL toroidal angle; + if `false`, apply `exp(i*n*ν(ψ,θ))` to convert to machine toroidal angle + and conjugate if `helicity > 0` (matches Fortran `gpout_xbrzphifun`) # Returns -- `theta_data::Array{ComplexF64,3}`: `[npsi × mtheta × npert]` -- `theta_grid::Vector{Float64}`: `[mtheta]` SFL theta ∈ [0, 1) -- `n_vals::Vector{Int}`: `[npert]` toroidal mode numbers + + - `theta_data::Array{ComplexF64,3}`: `[npsi × mtheta × npert]` + - `theta_grid::Vector{Float64}`: `[mtheta]` SFL theta ∈ [0, 1) + - `n_vals::Vector{Int}`: `[npert]` toroidal mode numbers !!! note + When used on the cylindrical components `xi_R`, `xi_Z`, `xi_phi`, `b_R`, `b_Z`, `b_phi` these are currently in beta and show up to ~20% discrepancies vs Fortran. """ function modes_to_theta(h5_file::String, variable::String; - mtheta::Union{Int,Nothing}=nothing, - keep_sfl_phi::Bool=true) + mtheta::Union{Int,Nothing}=nothing, + keep_sfl_phi::Bool=true) h5open(h5_file, "r") do f modes = read(f, variable) # (npsi, numpert_total) npsi, numpert_total = size(modes) - mlow = read(f, "Info/mlow") - nlow = read(f, "Info/nlow") + mlow = read(f, "Info/mlow") + nlow = read(f, "Info/nlow") mpert = read(f, "Info/mpert") npert = read(f, "Info/npert") @assert numpert_total == mpert * npert "Expected numpert_total=$(mpert*npert), got $numpert_total" @@ -58,7 +62,7 @@ function modes_to_theta(h5_file::String, variable::String; theta_data = zeros(ComplexF64, npsi, mth, npert) for k in 1:npert - col_range = (k-1)*mpert+1 : k*mpert + col_range = ((k-1)*mpert+1):(k*mpert) for ipsi in 1:npsi theta_data[ipsi, :, k] .= inverse(ft, view(modes, ipsi, col_range)) end @@ -68,7 +72,7 @@ function modes_to_theta(h5_file::String, variable::String; # Reconstruct ν spline from stored grid + nodal values (FastInterpolations v0.4 API) rzphi_xs = read(f, "Equilibrium/Geometry/psi") rzphi_ys = read(f, "Equilibrium/Geometry/theta") - nu_vals = read(f, "Equilibrium/Geometry/nu") + nu_vals = read(f, "Equilibrium/Geometry/nu") nu_spline = cubic_interp( (rzphi_xs, rzphi_ys), nu_vals; bc=(CubicFit(), PeriodicBC()), @@ -77,8 +81,8 @@ function modes_to_theta(h5_file::String, variable::String; psi_grid = read(f, "ForceFreeStates/Solutions/ForwardIntegration/psi") - bt_sign = haskey(f, "Equilibrium/B_T_sign") ? read(f, "Equilibrium/B_T_sign") : 1 - crnt = haskey(f, "Equilibrium/I_p") ? read(f, "Equilibrium/I_p") : 1.0 + bt_sign = haskey(f, "Equilibrium/B_T_sign") ? read(f, "Equilibrium/B_T_sign") : 1 + crnt = haskey(f, "Equilibrium/I_p") ? read(f, "Equilibrium/I_p") : 1.0 helicity = bt_sign * Int(sign(crnt)) hint = (Ref(1), Ref(1)) @@ -110,18 +114,21 @@ Extend theta-space data to a `(θ, φ)` grid via toroidal inverse DFT. f(θ, φ) = Σₙ fₙ(θ) exp(i·n·φ) # Arguments -- `theta_data::Array{ComplexF64,3}`: `[npsi × mtheta × npert]` from `modes_to_theta` -- `n_vals::Vector{Int}`: toroidal mode numbers + + - `theta_data::Array{ComplexF64,3}`: `[npsi × mtheta × npert]` from `modes_to_theta` + - `n_vals::Vector{Int}`: toroidal mode numbers # Keyword arguments -- `nphi::Int`: toroidal grid points (default: `max(4*maximum(abs.(n_vals)), 64)`) + + - `nphi::Int`: toroidal grid points (default: `max(4*maximum(abs.(n_vals)), 64)`) # Returns -- `full_data::Array{ComplexF64,3}`: `[npsi × mtheta × nphi]` -- `phi_grid::Vector{Float64}`: `[nphi]` in radians ∈ [0, 2π) + + - `full_data::Array{ComplexF64,3}`: `[npsi × mtheta × nphi]` + - `phi_grid::Vector{Float64}`: `[nphi]` in radians ∈ [0, 2π) """ function theta_to_thetaphi(theta_data::Array{ComplexF64,3}, n_vals::Vector{Int}; - nphi::Union{Int,Nothing}=nothing) + nphi::Union{Int,Nothing}=nothing) npsi, mth, npert = size(theta_data) np = isnothing(nphi) ? max(4 * maximum(abs.(n_vals)), 64) : nphi phi_grid = [(j - 1) * 2π / np for j in 1:np] diff --git a/src/Equilibrium/AnalyticEquilibrium.jl b/src/Equilibrium/AnalyticEquilibrium.jl index 72a16a05c..7ed653867 100644 --- a/src/Equilibrium/AnalyticEquilibrium.jl +++ b/src/Equilibrium/AnalyticEquilibrium.jl @@ -243,7 +243,7 @@ function tj_analytic_f1(x::Float64, nu::Float64, qc::Float64) if x < 0.1 x2 = x * x return x2 * (1 - (nu-1)*x2/2 + (nu-1)*(nu-2)*x2*x2/6 - - (nu-1)*(nu-2)*(nu-3)*x2*x2*x2/24) / qc + (nu-1)*(nu-2)*(nu-3)*x2*x2*x2/24) / qc else return (1 - (1 - x*x)^nu) / (nu * qc) end @@ -259,10 +259,10 @@ parameterization. function tj_analytic_f1p(x::Float64, nu::Float64, qc::Float64) if x < 0.1 x2 = x * x - return 2*x * (1 - (nu-1)*x2 + (nu-1)*(nu-2)*x2*x2/2 - - (nu-1)*(nu-2)*(nu-3)*x2*x2*x2/6) / qc + return 2 * x * (1 - (nu-1)*x2 + (nu-1)*(nu-2)*x2*x2/2 - + (nu-1)*(nu-2)*(nu-3)*x2*x2*x2/6) / qc else - return 2*x * (1 - x*x)^(nu-1) / qc + return 2 * x * (1 - x*x)^(nu-1) / qc end end @@ -273,10 +273,11 @@ GPEC adaptation of the analytic shape ODE used in R. Fitzpatrick's TJ code `tj_analytic_run_direct` call so both pipelines share identical numerics. Fields: + - physical: a, R0, qc, mu, pc, B0 - derived: epsa2 = (a/R0)² - near-axis BC constants: rmin, x0 = rmin, r0 = rmin·a, f1c = 1/qc, - p2ppc = d²p₂/dx²|_0 = −2·μ·pc + p2ppc = d²p₂/dx²|_0 = −2·μ·pc """ struct TJAnalyticShapeParams a::Float64 @@ -293,15 +294,15 @@ struct TJAnalyticShapeParams p2ppc::Float64 end -function TJAnalyticShapeParams(tj::TJAnalyticConfig; rmin::Float64 = 1e-4) +function TJAnalyticShapeParams(tj::TJAnalyticConfig; rmin::Float64=1e-4) a, R0 = tj.lar_a, tj.lar_r0 - mu = max(tj.mu, 1.001) + mu = max(tj.mu, 1.001) return TJAnalyticShapeParams( a, R0, tj.qc, mu, tj.pc, tj.B0, (a / R0)^2, rmin, rmin, rmin * a, 1.0 / tj.qc, - -2.0 * mu * tj.pc, + -2.0 * mu * tj.pc ) end @@ -315,9 +316,9 @@ The params argument carries TJAnalyticShapeParams fields plus the current `nu`. """ function tj_analytic_shape_rhs!(dy, y, params, r) (; a, B0, qc, mu, pc, epsa2, nu) = params - x = r / a + x = r / a xfac = max(1 - x^2, 0.0) - f1 = tj_analytic_f1(x, nu, qc) + f1 = tj_analytic_f1(x, nu, qc) f1px = tj_analytic_f1p(x, nu, qc) p2px = -2 * mu * pc * x * xfac^(mu - 1) @@ -340,16 +341,19 @@ function tj_analytic_shape_rhs!(dy, y, params, r) # f₃'(x) for Hₙ = Vₙ = 0 (n ≥ 2 harmonics rescaled to zero, as in the # TJ-analytic benchmark configuration of Fitzpatrick's TJ code). g2, f3 = y[2], y[5] - f3p_x = -f3 * f1px / f1 - - f1 * (3 * x^2 / 2 - 2 * x * H1p + H1p^2) / x + - f1px * (g2 - 3 * x^2 / 4 + H1 + 3 * H1p^2 / 2) + - x^2 * p2px * (g2 + x^2 / 2 - 3 * x * H1p - 2 * H1) / f1 + f3p_x = + -f3 * f1px / f1 - + f1 * (3 * x^2 / 2 - 2 * x * H1p + H1p^2) / x + + f1px * (g2 - 3 * x^2 / 4 + H1 + 3 * H1p^2 / 2) + + x^2 * p2px * (g2 + x^2 / 2 - 3 * x * H1p - 2 * H1) / f1 dy[5] = f3p_x / a return nothing end -"""Initial conditions at x = x0, matching the TJ-analytic model's near-axis -expansion (cf. R. Fitzpatrick's TJ code, https://github.com/rfitzp/TJ).""" +""" +Initial conditions at x = x0, matching the TJ-analytic model's near-axis +expansion (cf. R. Fitzpatrick's TJ code, https://github.com/rfitzp/TJ). +""" function tj_analytic_shape_initial(p::TJAnalyticShapeParams, nu::Float64) f1_0 = tj_analytic_f1(p.x0, nu, p.qc) y0 = zeros(5) @@ -368,14 +372,14 @@ downstream Hₙ / ψ splines sit on uniform nodes); leave it `nothing` for the default adaptive save pattern used by `tj_analytic_run`. """ function tj_analytic_shape_solve(p::TJAnalyticShapeParams, nu::Float64; - reltol::Float64 = 1e-7, abstol::Float64 = 1e-8, - saveat = nothing) - rhs_params = (; p.a, p.B0, p.qc, p.mu, p.pc, p.epsa2, nu = nu) + reltol::Float64=1e-7, abstol::Float64=1e-8, + saveat=nothing) + rhs_params = (; p.a, p.B0, p.qc, p.mu, p.pc, p.epsa2, nu=nu) prob = ODEProblem(tj_analytic_shape_rhs!, tj_analytic_shape_initial(p, nu), (p.r0, p.a), rhs_params) if saveat === nothing - return solve(prob, Vern9(); reltol, abstol, maxiters = 10000, dense = false) + return solve(prob, Vern9(); reltol, abstol, maxiters=10000, dense=false) else - return solve(prob, Vern9(); reltol, abstol, maxiters = 10000, saveat = saveat) + return solve(prob, Vern9(); reltol, abstol, maxiters=10000, saveat=saveat) end end @@ -389,9 +393,9 @@ O(εa²) correction relative to the lowest-order guess ν = qa/qc, which matters for the TJ-analytic benchmark at large ε. Falls back to the lowest-order ν if the bracket search diverges. """ -function tj_analytic_find_nu(p::TJAnalyticShapeParams, qa_target::Float64; reltol::Float64 = 1e-7) +function tj_analytic_find_nu(p::TJAnalyticShapeParams, qa_target::Float64; reltol::Float64=1e-7) function q2_edge(nu::Float64) - sol = tj_analytic_shape_solve(p, nu; reltol) + sol = tj_analytic_shape_solve(p, nu; reltol) g2end = sol.u[end][2] f3end = sol.u[end][5] f1end = tj_analytic_f1(1.0, nu, p.qc) @@ -400,7 +404,7 @@ function tj_analytic_find_nu(p::TJAnalyticShapeParams, qa_target::Float64; relto nu_guess = qa_target / p.qc return try find_zero(nu -> q2_edge(nu) - qa_target, (0.5 * nu_guess, 2 * nu_guess); - atol = 1e-8, rtol = 1e-10) + atol=1e-8, rtol=1e-10) catch err @warn "ν root-find failed for TJ-analytic equilibrium; falling back to lowest-order ν = qa/qc" error = err nu_guess @@ -443,16 +447,16 @@ included; they are zero in the TJ-analytic benchmark scans. Reference: R. Fitzpatrick, TJ code, https://github.com/rfitzp/TJ """ function tj_analytic_run(equil_input::EquilibriumConfig, tj::TJAnalyticConfig) - a, R0 = tj.lar_a, tj.lar_r0 + a, R0 = tj.lar_a, tj.lar_r0 qc, mu = tj.qc, max(tj.mu, 1.001) pc, B0 = tj.pc, tj.B0 ma, mtau = tj.ma, tj.mtau p = TJAnalyticShapeParams(tj) - epsa2 = p.epsa2 - p00_phys = B0^2 * epsa2 * pc # μ₀P = B₀²·εa²·p₂ at axis + epsa2 = p.epsa2 + p00_phys = B0^2 * epsa2 * pc # μ₀P = B₀²·εa²·p₂ at axis - nu = tj_analytic_find_nu(p, tj.qa; reltol = equil_input.etol) - sol = tj_analytic_shape_solve(p, nu; reltol = equil_input.etol) + nu = tj_analytic_find_nu(p, tj.qa; reltol=equil_input.etol) + sol = tj_analytic_shape_solve(p, nu; reltol=equil_input.etol) r_arr = sol.t y_mat = reduce(hcat, sol.u)' @@ -468,7 +472,7 @@ function tj_analytic_run(equil_input::EquilibriumConfig, tj::TJAnalyticConfig) xfac = max(1 - x^2, 0.0) f1 = tj_analytic_f1(x, nu, qc) - ψ = y_mat[i, 1] + ψ = y_mat[i, 1] g2 = y_mat[i, 2] H1 = y_mat[i, 3] f3 = y_mat[i, 5] @@ -507,7 +511,7 @@ function tj_analytic_run(equil_input::EquilibriumConfig, tj::TJAnalyticConfig) f = spl(r; hint=hint) # f[1]=F, f[2]=P, f[3]=q, f[4]=ψ, f[5]=g₂, f[6]=H₁ - sq_xs[ia] = f[4] / psio + sq_xs[ia] = f[4] / psio sq_fs[ia, 1] = f[1] # F sq_fs[ia, 2] = f[2] # P sq_fs[ia, 3] = f[3] # q @@ -525,7 +529,7 @@ function tj_analytic_run(equil_input::EquilibriumConfig, tj::TJAnalyticConfig) for itau in 1:(mtau+1) θ = 2π * (itau - 1) / mtau rzphi_fs_nodes[ia, itau, 1] = R0 + Δ + α * r * cos(θ) - rzphi_fs_nodes[ia, itau, 2] = α * r * sin(θ) + rzphi_fs_nodes[ia, itau, 2] = α * r * sin(θ) end end @@ -579,38 +583,38 @@ ODE (g₂, H₁, H₁', f₃), the `GetPSIvac` / `GetHHvac` vacuum extension, an EFIT-writer (R, Z) → (r, w) Newton inversion that this routine adapts. """ function tj_analytic_run_direct(equil_input::EquilibriumConfig, tj::TJAnalyticConfig; - nrbox::Int = 257, nzbox::Int = 257, rc::Float64 = 1.2) - a, R0 = tj.lar_a, tj.lar_r0 + nrbox::Int=257, nzbox::Int=257, rc::Float64=1.2) + a, R0 = tj.lar_a, tj.lar_r0 qc, mu = tj.qc, max(tj.mu, 1.001) pc, B0 = tj.pc, tj.B0 p = TJAnalyticShapeParams(tj) epsa, epsa2 = p.a / p.R0, p.epsa2 - p00_phys = B0^2 * epsa2 * pc + p00_phys = B0^2 * epsa2 * pc # ν root-find (cf. Fitzpatrick TJ's Setnu): q₂(1) = qa_target. - nu = tj_analytic_find_nu(p, tj.qa; reltol = equil_input.etol) + nu = tj_analytic_find_nu(p, tj.qa; reltol=equil_input.etol) # Dense saveat so the downstream splines (H₁, g₂, f₃, ψ) are evaluated on # a fine uniform r grid rather than the ~30 adaptive Vern9 steps — otherwise # the (R, Z) → (r, w) Newton iteration hits spline interpolation artifacts. - dense_r = collect(range(p.r0, p.a; length = 1024)) - sol = tj_analytic_shape_solve(p, nu; reltol = equil_input.etol, - abstol = 1e-10, saveat = dense_r) - r_arr = sol.t - y_mat = reduce(hcat, sol.u)' + dense_r = collect(range(p.r0, p.a; length=1024)) + sol = tj_analytic_shape_solve(p, nu; reltol=equil_input.etol, + abstol=1e-10, saveat=dense_r) + r_arr = sol.t + y_mat = reduce(hcat, sol.u)' # Radial splines in the TJ-analytic dimensionless x = r/a on a clean grid for H₁ etc. x_nodes = r_arr ./ a - ψ_of_r = cubic_interp(r_arr, y_mat[:, 1]; extrap=ExtendExtrap()) - H1_of_x = cubic_interp(x_nodes, y_mat[:, 3]; extrap=ExtendExtrap()) + ψ_of_r = cubic_interp(r_arr, y_mat[:, 1]; extrap=ExtendExtrap()) + H1_of_x = cubic_interp(x_nodes, y_mat[:, 3]; extrap=ExtendExtrap()) H1p_of_x = cubic_interp(x_nodes, y_mat[:, 4]; extrap=ExtendExtrap()) - g2_of_x = cubic_interp(x_nodes, y_mat[:, 2]; extrap=ExtendExtrap()) - f3_of_x = cubic_interp(x_nodes, y_mat[:, 5]; extrap=ExtendExtrap()) + g2_of_x = cubic_interp(x_nodes, y_mat[:, 2]; extrap=ExtendExtrap()) + f3_of_x = cubic_interp(x_nodes, y_mat[:, 5]; extrap=ExtendExtrap()) # Edge values needed by GetPSIvac - f1a = tj_analytic_f1(1.0, nu, qc) - f3a = f3_of_x(1.0) - H1a = H1_of_x(1.0) + f1a = tj_analytic_f1(1.0, nu, qc) + f3a = f3_of_x(1.0) + H1a = H1_of_x(1.0) H1ap = H1p_of_x(1.0) psio = ψ_of_r(a) # ψ at r = a (boundary) @@ -644,7 +648,7 @@ function tj_analytic_run_direct(equil_input::EquilibriumConfig, tj::TJAnalyticCo return f_R_shift(rc - 1e-8, w) * r^2 / rc^2 end H1 = (r < 1.0) ? H1_of_x(r) : H1_vac(r) - L = r^3 / 8 - r * H1 / 2 + L = r^3 / 8 - r * H1 / 2 return epsa2 * H1 + epsa2 * epsa * L * cos(w) end function f_Z_shift(r::Float64, w::Float64) @@ -652,7 +656,7 @@ function tj_analytic_run_direct(equil_input::EquilibriumConfig, tj::TJAnalyticCo return f_Z_shift(rc - 1e-8, w) * r^2 / rc^2 end H1 = (r < 1.0) ? H1_of_x(r) : H1_vac(r) - L = r^3 / 8 - r * H1 / 2 + L = r^3 / 8 - r * H1 / 2 return -epsa2 * epsa * L * sin(w) end @@ -699,9 +703,9 @@ function tj_analytic_run_direct(equil_input::EquilibriumConfig, tj::TJAnalyticCo # Grid spans R₀ ± rc·a × ±rc·a (where rc is the vacuum-shell radius in # units of a), giving a comfortable margin for the separatrix finder. r_span = rc * a - psi_in_xs = collect(range(R0 - r_span, R0 + r_span; length = nrbox)) - psi_in_ys = collect(range(-r_span, r_span; length = nzbox)) - psi_rz = zeros(Float64, nrbox, nzbox) + psi_in_xs = collect(range(R0 - r_span, R0 + r_span; length=nrbox)) + psi_in_ys = collect(range(-r_span, r_span; length=nzbox)) + psi_rz = zeros(Float64, nrbox, nzbox) for i in 1:nrbox, j in 1:nzbox R_norm = psi_in_xs[i] / R0 @@ -724,8 +728,10 @@ function tj_analytic_run_direct(equil_input::EquilibriumConfig, tj::TJAnalyticCo # 1D profile spline, same layout as read_efit (4 columns). Use the # TJ-analytic q₂ on the radial grid so that the prescribed q is # consistent with the ψ(R,Z) we just constructed. - psi_norm_grid = range(0.0, 1.0; length = nrbox) - F_nodes = zeros(nrbox); P_nodes = zeros(nrbox); q_nodes = zeros(nrbox) + psi_norm_grid = range(0.0, 1.0; length=nrbox) + F_nodes = zeros(nrbox) + P_nodes = zeros(nrbox) + q_nodes = zeros(nrbox) for i in 1:nrbox ψN = psi_norm_grid[i] # Invert ψN = (ψ_plasma(r) - 0) / psio ⇒ find r such that ψ_plasma(r) = ψN·psio. @@ -746,7 +752,7 @@ function tj_analytic_run_direct(equil_input::EquilibriumConfig, tj::TJAnalyticCo F_nodes[i] = R0 * B0 * (1 + epsa2 * g2_val) P_nodes[i] = p00_phys * xfac^mu q_nodes[i] = (x > 1e-10) ? x^2 * (1 + epsa2 * g2_val) * - exp(-epsa2 * f3_val / f1) / f1 : qc + exp(-epsa2 * f3_val / f1) / f1 : qc end sq_fs_nodes = hcat(F_nodes, P_nodes, q_nodes, sqrt.(collect(psi_norm_grid))) sq_in = cubic_interp(collect(psi_norm_grid), Series(sq_fs_nodes); extrap=ExtendExtrap()) @@ -756,7 +762,7 @@ function tj_analytic_run_direct(equil_input::EquilibriumConfig, tj::TJAnalyticCo # Analytic: ingest=nothing — replay regenerates from the [TJ_ANALYTIC_INPUT] TOML section. return DirectRunInput(equil_input, sq_in, psi_in, psi_in_xs, psi_in_ys, - rmin_grid, rmax_grid, zmin_grid, zmax_grid, psio, 1, nothing) + rmin_grid, rmax_grid, zmin_grid, zmax_grid, psio, 1, nothing) end """ diff --git a/src/Equilibrium/DirectEquilibriumArcLength.jl b/src/Equilibrium/DirectEquilibriumArcLength.jl index 32b93a0ac..f247da7a1 100644 --- a/src/Equilibrium/DirectEquilibriumArcLength.jl +++ b/src/Equilibrium/DirectEquilibriumArcLength.jl @@ -64,11 +64,11 @@ end Arc-length-parameterized flux surface integration. Drop-in replacement for `direct_fieldline_int` with identical return format: -- `y_out[:, 1]`: geometric angle η ∈ 0 to 2π (CCW from outboard midplane) -- `y_out[:, 2]`: accumulated ∫dl/Bp -- `y_out[:, 3]`: rfac = √((R−ro)² + (Z−zo)²) -- `y_out[:, 4]`: accumulated ∫dl/(R²Bp) -- `y_out[:, 5]`: accumulated ∫jac·dl/Bp + - `y_out[:, 1]`: geometric angle η ∈ 0 to 2π (CCW from outboard midplane) + - `y_out[:, 2]`: accumulated ∫dl/Bp + - `y_out[:, 3]`: rfac = √((R−ro)² + (Z−zo)²) + - `y_out[:, 4]`: accumulated ∫dl/(R²Bp) + - `y_out[:, 5]`: accumulated ∫jac·dl/Bp The ODE is terminated by a `ContinuousCallback` that detects the return to the outboard midplane (Z = zo, R > ro) after a minimum arc-length guard. @@ -144,4 +144,3 @@ outboard midplane (Z = zo, R > ro) after a minimum arc-length guard. # bfield at the starting point carries F and P for the surface-averaged quantities return y_out, bfield end - diff --git a/src/Equilibrium/Equilibrium.jl b/src/Equilibrium/Equilibrium.jl index eed157812..6b55898ad 100644 --- a/src/Equilibrium/Equilibrium.jl +++ b/src/Equilibrium/Equilibrium.jl @@ -330,10 +330,10 @@ function equilibrium_global_parameters!(pe::PlasmaEquilibrium) P_vals = profiles.P_spline.y dVdpsi_vals = profiles.dVdpsi_spline.y - fsi_pdv = fsi(P_vals .* dVdpsi_vals) # ∫ p dV/dψ - fsi_dv = fsi(dVdpsi_vals) # ∫ dV/dψ + fsi_pdv = fsi(P_vals .* dVdpsi_vals) # ∫ p dV/dψ + fsi_dv = fsi(dVdpsi_vals) # ∫ dV/dψ fsi_p2dv = fsi(P_vals .^ 2 .* dVdpsi_vals) # ∫ p² dV/dψ - volume = fsi_dv # same integrand as hs col 2 in Fortran + volume = fsi_dv # same integrand as hs col 2 in Fortran # Poloidal-field surface integral hs_bp2(ψ) = ψ₀² ∮dθ |∇ψ|² / (R² J). # This is Fortran equil_out.f's hs%fs(:,3) and is the correct integrand for @@ -343,21 +343,21 @@ function equilibrium_global_parameters!(pe::PlasmaEquilibrium) for ipsi in 0:mpsi acc = 0.0 for itheta in 0:mtheta - r2 = pe.rzphi_rsquared.nodal_derivs.partials[1, ipsi+1, itheta+1] - offset = pe.rzphi_offset.nodal_derivs.partials[1, ipsi+1, itheta+1] - jac = pe.rzphi_jac.nodal_derivs.partials[1, ipsi+1, itheta+1] - r2_y = pe.rzphi_rsquared.nodal_derivs.partials[3, ipsi+1, itheta+1] - offset_y = pe.rzphi_offset.nodal_derivs.partials[3, ipsi+1, itheta+1] + r2 = pe.rzphi_rsquared.nodal_derivs.partials[1, ipsi+1, itheta+1] + offset = pe.rzphi_offset.nodal_derivs.partials[1, ipsi+1, itheta+1] + jac = pe.rzphi_jac.nodal_derivs.partials[1, ipsi+1, itheta+1] + r2_y = pe.rzphi_rsquared.nodal_derivs.partials[3, ipsi+1, itheta+1] + offset_y = pe.rzphi_offset.nodal_derivs.partials[3, ipsi+1, itheta+1] jacfac = π / jac - rfac = sqrt(r2) - eta = 2π * (pe.rzphi_ys[itheta+1] + offset) - r = pe.ro + rfac * cos(eta) - v21 = jacfac * r2_y / (2π * rfac) - v22 = jacfac * (1 + offset_y) * (2 * rfac) - v33 = jacfac * 2π * (r / π) - dvsq = (v21^2 + v22^2) * (v33 * jac^2)^2 - acc += dvsq / (r^2) / jac + rfac = sqrt(r2) + eta = 2π * (pe.rzphi_ys[itheta+1] + offset) + r = pe.ro + rfac * cos(eta) + v21 = jacfac * r2_y / (2π * rfac) + v22 = jacfac * (1 + offset_y) * (2 * rfac) + v33 = jacfac * 2π * (r / π) + dvsq = (v21^2 + v22^2) * (v33 * jac^2)^2 + acc += dvsq / (r^2) / jac end # Periodic trapezoidal rule on uniform θ grid reduces to a plain mean # because the first and last grid points coincide — matches the int1/int2 @@ -367,15 +367,15 @@ function equilibrium_global_parameters!(pe::PlasmaEquilibrium) fsi_bp2 = fsi(hs_bp2) p0 = P_vals[1] - profiles.P_deriv(profiles.xs[1]; hint=Ref(1)) * profiles.xs[1] # linear extrapolation - betat = 2 * (fsi_pdv / fsi_dv) / bt0^2 - betaj = 2 * sqrt(fsi_p2dv / fsi_dv) / bwall^2 - betan = 100 * amean * bt0 * betat / crnt + betat = 2 * (fsi_pdv / fsi_dv) / bt0^2 + betaj = 2 * sqrt(fsi_p2dv / fsi_dv) / bwall^2 + betan = 100 * amean * bt0 * betat / crnt betap1 = 2 * (fsi_pdv / fsi_dv) / bp0^2 betap2 = 4 * fsi_pdv / ((1e6 * mu0 * crnt)^2 * pe.ro) betap3 = 4 * fsi_pdv / ((1e6 * mu0 * crnt)^2 * rmean) - li1 = fsi_bp2 / fsi_dv / bp0^2 - li2 = 2 * fsi_bp2 / ((1e6 * mu0 * crnt)^2 * pe.ro) - li3 = 2 * fsi_bp2 / ((1e6 * mu0 * crnt)^2 * rmean) + li1 = fsi_bp2 / fsi_dv / bp0^2 + li2 = 2 * fsi_bp2 / ((1e6 * mu0 * crnt)^2 * pe.ro) + li3 = 2 * fsi_bp2 / ((1e6 * mu0 * crnt)^2 * rmean) pe.params.psi0 = psio pe.params.psi_axis = pe.psio diff --git a/src/Equilibrium/EquilibriumTypes.jl b/src/Equilibrium/EquilibriumTypes.jl index 344f5a60f..d6d8e16b8 100644 --- a/src/Equilibrium/EquilibriumTypes.jl +++ b/src/Equilibrium/EquilibriumTypes.jl @@ -245,7 +245,9 @@ A mutable struct holding parameters for the Large Aspect Ratio (LAR) plasma equi zeroth::Bool = false end -"Build a `LargeAspectRatioConfig` from a parsed `[LAR_INPUT]` TOML table." +""" +Build a `LargeAspectRatioConfig` from a parsed `[LAR_INPUT]` TOML table. +""" function LargeAspectRatioConfig(input_dict::Dict{String,Any}) return LargeAspectRatioConfig(; symbolize_keys(input_dict)...) end @@ -285,7 +287,9 @@ Reference: R. Fitzpatrick, TJ code, https://github.com/rfitzp/TJ zeroth::Bool = false # If true, suppress Shafranov shift end -"Build a `TJAnalyticConfig` from a parsed `[TJ_ANALYTIC_INPUT]` TOML table." +""" +Build a `TJAnalyticConfig` from a parsed `[TJ_ANALYTIC_INPUT]` TOML table. +""" function TJAnalyticConfig(input_dict::Dict{String,Any}) return TJAnalyticConfig(; symbolize_keys(input_dict)...) end @@ -321,7 +325,9 @@ A mutable struct holding parameters for the Solev'ev (SOL) plasma equilibrium mo f0fac::Float64 = 1 # scale toroidal field at constant pressure (s*f. beta,q changes. Phi,p,bp constant) end -"Build a `SolovevConfig` from a parsed `[SOL_INPUT]` TOML table." +""" +Build a `SolovevConfig` from a parsed `[SOL_INPUT]` TOML table. +""" function SolovevConfig(input_dict::Dict{String,Any}) return SolovevConfig(; symbolize_keys(input_dict)...) end @@ -419,6 +425,7 @@ raw equilibrium data and preparing the initial splines. 2. `μ₀ * Pressure` — plasma pressure (non-negative) [T²] 3. `q` — safety factor profile 4. `√ψ_norm` — square root of normalized flux + - `psi_in` 2D cubic interpolant on the (R, Z) grid [m]. The values correspond to the **poloidal flux** adjusted to be zero at the boundary [Wb/rad]. @@ -430,14 +437,23 @@ raw equilibrium data and preparing the initial splines. * 1D profiles are represented by `CubicInterpolant` or `CubicSeriesInterpolant` * 2D flux surfaces by `CubicInterpolantND` + - `psi_in_xs::Vector{Float64}` — R coordinate grid for psi_in [m] + - `psi_in_ys::Vector{Float64}` — Z coordinate grid for psi_in [m] + - `rmin::Float64` — Minimum R-coordinate of the computational grid [m] + - `rmax::Float64` — Maximum R-coordinate of the computational grid [m] + - `zmin::Float64` — Minimum Z-coordinate of the computational grid [m] + - `zmax::Float64` — Maximum Z-coordinate of the computational grid [m] + - `psio::Float64` — Total flux difference `|ψ_axis - ψ_boundary|` [Wb/rad] + - `bt_sign::Int` — Sign of the toroidal field (+1 or -1); read from fpol sign in EFIT g-files + - `ingest::EquilibriumIngest` — captured raw arrays for the `gpec.h5` rerun snapshot (a [`DirectIngest`](@ref) for file-based reads, or `nothing` for analytic equilibria) - `psihigh_resolved::Float64` — outer flux limit the equilibrium is formed on: `config.psihigh` @@ -749,7 +765,7 @@ function GeometryProfileSplines(xs::Vector{Float64}, GeometryProfileSplines{typeof(area_spline)}( xs, npts, npts - 1, - area_spline, avg_r_spline, avg_R_spline, + area_spline, avg_r_spline, avg_R_spline ) end @@ -828,7 +844,7 @@ function KineticProfileSplines(xs::Vector{Float64}, xs, npts, npts - 1, ni_spline, ne_spline, Ti_spline, Te_spline, omegaE_spline, loglam_spline, nui_spline, nue_spline, zeff_spline, - ni_deriv, ne_deriv, Ti_deriv, Te_deriv, + ni_deriv, ne_deriv, Ti_deriv, Te_deriv ) end @@ -845,17 +861,21 @@ This object provides a complete representation of the processed plasma equilibri - `params::EquilibriumParameters`: Computed equilibrium parameters and diagnostics. + - `profiles::ProfileSplines`: Named 1D profile splines (F, P, dV/dψ, q) on normalized psi grid. Access values at grid points via `profiles.F_spline.y[i]`, etc. Access derivatives via `profiles.F_deriv.y[i]` or `profiles.F_deriv(psi)`. + - `geometry::GeometryProfileSplines`: Named 1D splines for flux-surface-averaged geometry (area, ⟨r⟩, ⟨R⟩), populated automatically by `compute_geometry_profiles` during construction. + - **Grid coordinates (shared by all rzphi/eqfun interpolants):** + `rzphi_xs::Vector{Float64}`: ψ coordinates (length mpsi+1) + `rzphi_ys::Vector{Float64}`: θ coordinates (length mtheta+1) + - **Geometric quantities (rzphi, 4 interpolants):** 2D cubic interpolants for flux-coordinate mapping with periodic BC in theta. @@ -865,6 +885,7 @@ This object provides a complete representation of the processed plasma equilibri + `rzphi_offset::CubicInterpolantND`: η/(2π) - θₙₑw (angle offset) + `rzphi_nu::CubicInterpolantND`: ν in ϕ = 2πζ + ν(ψ, θ) + `rzphi_jac::CubicInterpolantND`: Jacobian + - **Physics quantities (eqfun, 3 interpolants):** 2D cubic interpolants storing local physics and geometric quantities. @@ -873,9 +894,13 @@ This object provides a complete representation of the processed plasma equilibri + `eqfun_B::CubicInterpolantND`: Total magnetic field strength [T] + `eqfun_metric1::CubicInterpolantND`: (e₁⋅e₂ + q⋅e₃⋅e₁)/(J⋅B²) + `eqfun_metric2::CubicInterpolantND`: (e₂⋅e₃ + q⋅e₃⋅e₃)/(J⋅B²) + - `ro::Float64`: R-coordinate of the magnetic axis [m] + - `zo::Float64`: Z-coordinate of the magnetic axis [m] + - `psio::Float64`: Total flux difference |Ψ_axis - Ψ_boundary| [Weber/radian] + - `ingest::EquilibriumIngest`: raw arrays forwarded from the equilibrium input for the `gpec.h5` rerun snapshot — a [`DirectIngest`](@ref)/[`InverseIngest`](@ref) for file-based equilibria, or `nothing` for analytic ones (regenerated from their TOML section on replay) diff --git a/src/Equilibrium/GeometryProfiles.jl b/src/Equilibrium/GeometryProfiles.jl index a9596c308..9b414cf83 100644 --- a/src/Equilibrium/GeometryProfiles.jl +++ b/src/Equilibrium/GeometryProfiles.jl @@ -27,7 +27,7 @@ function compute_geometry_profiles( rzphi_rsquared::FastInterpolations.CubicInterpolantND, rzphi_offset::FastInterpolations.CubicInterpolantND, rzphi_jac::FastInterpolations.CubicInterpolantND, - ro::Float64, + ro::Float64 ) npsi = length(rzphi_xs) mthsurf = length(rzphi_ys) - 1 # skip the periodic duplicate at θ = 1 @@ -78,6 +78,6 @@ function compute_geometry_profiles(pe::PlasmaEquilibrium) return compute_geometry_profiles( pe.rzphi_xs, pe.rzphi_ys, pe.rzphi_rsquared, pe.rzphi_offset, pe.rzphi_jac, - pe.ro, + pe.ro ) end diff --git a/src/Equilibrium/ReadEquilibrium.jl b/src/Equilibrium/ReadEquilibrium.jl index 8cc221b7a..068814505 100644 --- a/src/Equilibrium/ReadEquilibrium.jl +++ b/src/Equilibrium/ReadEquilibrium.jl @@ -432,15 +432,17 @@ Load an equilibrium from an IMAS data dictionary and return a `DirectRunInput`. The `dd.equilibrium.time_slice[]` is used (active time slice). Poloidal flux is converted from the IMAS COCOS convention (set by `config.imas_cocos`) to the internal COCOS 2 convention: + - `imas_cocos = 11` (default, IMAS standard): divide ψ by 2π - `imas_cocos = 2` (GPEC internal): no conversion ## Arguments -- `config`: `EquilibriumConfig` with `eq_type = "imas"` and `imas_cocos` set. -- `dd`: populated `IMASdd.dd` with `dd.equilibrium.time_slice[]` containing: - - `global_quantities.psi_axis`, `global_quantities.psi_boundary` - - `profiles_1d.psi`, `profiles_1d.f`, `profiles_1d.pressure`, `profiles_1d.q` - - `profiles_2d[1].grid.dim1` (R), `profiles_2d[1].grid.dim2` (Z), `profiles_2d[1].psi` + + - `config`: `EquilibriumConfig` with `eq_type = "imas"` and `imas_cocos` set. + - `dd`: populated `IMASdd.dd` with `dd.equilibrium.time_slice[]` containing: + + `global_quantities.psi_axis`, `global_quantities.psi_boundary` + + `profiles_1d.psi`, `profiles_1d.f`, `profiles_1d.pressure`, `profiles_1d.q` + + `profiles_2d[1].grid.dim1` (R), `profiles_2d[1].grid.dim2` (Z), `profiles_2d[1].psi` """ function read_imas(config::EquilibriumConfig, dd) @info "Processing IMAS equilibrium at global_time = $(dd.global_time) s" diff --git a/src/ForceFreeStates/EulerLagrange.jl b/src/ForceFreeStates/EulerLagrange.jl index 88c1d9e4a..3ed691261 100644 --- a/src/ForceFreeStates/EulerLagrange.jl +++ b/src/ForceFreeStates/EulerLagrange.jl @@ -37,9 +37,9 @@ end # at the interval endpoints. Coefficients are ported from STRIDE's ode_itime cost model # (Fortran reference) and unchanged here. Tune only after re-fitting against a per-chunk # step-count sweep; touching these affects parallel-chunk load balancing. -const ODE_COST_AXIS = (a = 39695.0, b = 212830.0) -const ODE_COST_RAT = (a = 17147.0, b = 470710.0) -const ODE_COST_EDGE = (a = 1646.0, b = 4683.0) +const ODE_COST_AXIS = (a=39695.0, b=212830.0) +const ODE_COST_RAT = (a=17147.0, b=470710.0) +const ODE_COST_EDGE = (a=1646.0, b=4683.0) """ ode_itime_cost(psi1, psi2, intr) -> Float64 @@ -72,7 +72,7 @@ never from `Threads.nthreads()` — so the chunk list, and hence every Riccati o identical whatever thread count `julia -t` provides. Each split finds the equal-cost midpoint ψ_mid via bisection: - ode_itime_cost(psi_start, psi_mid) ≈ ode_itime_cost(psi_start, psi_end) / 2 +ode_itime_cost(psi_start, psi_mid) ≈ ode_itime_cost(psi_start, psi_end) / 2 Sub-chunks inherit `needs_crossing=false` and `ising=0`. Only the LAST sub-chunk of each original chunk retains `needs_crossing=true` and the original `ising`, so the @@ -131,10 +131,10 @@ function balance_integration_chunks(chunks::Vector{IntegrationChunk}, ctrl::Forc psi_mid = (lo + hi) / 2.0 left = IntegrationChunk(; psi_start=chunk.psi_start, psi_end=psi_mid, - needs_crossing=false, ising=0, direction=1) + needs_crossing=false, ising=0, direction=1) right = IntegrationChunk(; psi_start=psi_mid, psi_end=chunk.psi_end, - needs_crossing=chunk.needs_crossing, ising=chunk.ising, - direction=chunk.direction) + needs_crossing=chunk.needs_crossing, ising=chunk.ising, + direction=chunk.direction) splice!(result, best_idx, [left, right]) end @@ -284,20 +284,20 @@ is identified by dominant |U₁| component, giving the physically correct consta Frobenius solution and avoiding the spurious logarithmic irregularity. """ function compute_axis_init(ffit::FourFitVars, profiles::Equilibrium.ProfileSplines, - intr::ForceFreeStatesInternal, psi_low::Float64) - N = intr.numpert_total + intr::ForceFreeStatesInternal, psi_low::Float64) + N = intr.numpert_total hint = Ref(1) # Evaluate stability matrices at psi_low F_lower = zeros(ComplexF64, N, N) - kmat = zeros(ComplexF64, N, N) - gmat = zeros(ComplexF64, N, N) + kmat = zeros(ComplexF64, N, N) + gmat = zeros(ComplexF64, N, N) ffit.fmats_lower(vec(F_lower), psi_low; hint=hint) - ffit.kmats(vec(kmat), psi_low; hint=hint) - ffit.gmats(vec(gmat), psi_low; hint=hint) + ffit.kmats(vec(kmat), psi_low; hint=hint) + ffit.gmats(vec(gmat), psi_low; hint=hint) # singfac[j] = 1 / (m_j − n_j · q) for each mode j - q0 = profiles.q_spline(psi_low; hint=hint) + q0 = profiles.q_spline(psi_low; hint=hint) singfac = vec(1.0 ./ ((intr.mlow:intr.mhigh) .- q0 .* (intr.nlow:intr.nhigh)')) # F̄⁻¹ = (F_lower · F_lower')⁻¹ via the Cholesky factor @@ -311,15 +311,15 @@ function compute_axis_init(ffit::FourFitVars, profiles::Equilibrium.ProfileSplin for j in 1:N sf = singfac[j] fi = Finv[j, j] - k = kmat[j, j] + k = kmat[j, j] kd = conj(k) # K̄†[j,j] - g = gmat[j, j] + g = gmat[j, j] # 2×2 ODE matrix block for mode j [Glasser 2016 Eq. 22-24, diagonal approximation] m11 = -sf * fi * k - m12 = sf^2 * fi - m21 = g - kd * fi * k - m22 = sf * kd * fi + m12 = sf^2 * fi + m21 = g - kd * fi * k + m22 = sf * kd * fi # Frobenius matrix A₀_j = ψ_low · M_j [Glasser 2016 Eq. 51] #! format: off @@ -346,7 +346,7 @@ function compute_axis_init(ffit::FourFitVars, profiles::Equilibrium.ProfileSplin if abs(v2) > Base.sqrt(Base.eps(Float64)) * abs(v1) U1_init[j, j] = v1 / v2 else - U1_init[j, j] = one(ComplexF64) + U1_init[j, j] = one(ComplexF64) U2_init[j, j] = zero(ComplexF64) end end @@ -365,7 +365,7 @@ Formerly `ode_axis_init!`. This now only initializes `psifac`, `ising_start`, an Move ising_start logic to chunk_el_integration_bounds? """ function initialize_el_at_axis!(odet::OdeState, ctrl::ForceFreeStatesControl, ffit::FourFitVars, - profiles::Equilibrium.ProfileSplines, intr::ForceFreeStatesInternal) + profiles::Equilibrium.ProfileSplines, intr::ForceFreeStatesInternal) # Default psifac to minimum equilibrium psi value odet.psifac = profiles.xs[1] @@ -542,7 +542,7 @@ function chunk_el_integration_bounds(odet::OdeState, ctrl::ForceFreeStatesContro psi_end=psi_end, needs_crossing=true, ising=ising_current, - direction = bidirectional ? -1 : 1 + direction=bidirectional ? -1 : 1 )) # After crossing, we jump to the other side of the singular surface @@ -975,7 +975,7 @@ function transform_u!(odet::OdeState, intr::ForceFreeStatesInternal) temp[ksol, jsol] = odet.fixfac[ksol, jsol, ifix] end end - mul!(gauss_buffer, view(gauss,:,:,ifix), temp) + mul!(gauss_buffer, view(gauss, :, :, ifix), temp) gauss[:, :, ifix] .= gauss_buffer end # Account for zeroed indices at singular surfaces in `ode_ideal_cross` @@ -992,7 +992,7 @@ function transform_u!(odet::OdeState, intr::ForceFreeStatesInternal) # and mfix + 1 is the for the region after the last fixup and before the edge transforms[:, :, end] .= identity for ifix in odet.ifix:-1:1 - mul!(view(transforms,:,:,ifix), view(gauss,:,:,ifix), view(transforms,:,:,(ifix+1))) + mul!(view(transforms, :, :, ifix), view(gauss, :, :, ifix), view(transforms, :, :, (ifix+1))) end # Now that we have the transform matrices, we can apply them to the solution vectors diff --git a/src/ForceFreeStates/Galerkin/GalerkinAssembly.jl b/src/ForceFreeStates/Galerkin/GalerkinAssembly.jl index 3032e6ef7..787305d96 100644 --- a/src/ForceFreeStates/Galerkin/GalerkinAssembly.jl +++ b/src/ForceFreeStates/Galerkin/GalerkinAssembly.jl @@ -119,11 +119,12 @@ function gal_gauss_quad!(cell::GalCell, ffit::FourFitVars, profiles, intr::Force pb = swap_edge ? (pbt[1], pbt[2], pbt[4], pbt[3]) : pbt qb = swap_edge ? (qbt[1], qbt[2], qbt[4], qbt[3]) : qbt for ip in 0:np, ipert in 1:N, jp in 0:np, jpert in 1:N - cell.mat[ipert, jpert, ip+1, jp+1] += w * ( - F[ipert, jpert] * qb[ip+1] * qb[jp+1] + - K[ipert, jpert] * qb[ip+1] * pb[jp+1] + - conj(K[jpert, ipert]) * pb[ip+1] * qb[jp+1] + - G[ipert, jpert] * pb[ip+1] * pb[jp+1]) + cell.mat[ipert, jpert, ip+1, jp+1] += + w * ( + F[ipert, jpert] * qb[ip+1] * qb[jp+1] + + K[ipert, jpert] * qb[ip+1] * pb[jp+1] + + conj(K[jpert, ipert]) * pb[ip+1] * qb[jp+1] + + G[ipert, jpert] * pb[ip+1] * pb[jp+1]) end end return cell @@ -345,8 +346,8 @@ function gal_resonant!(cell::GalCell, ising::Int, ffit::FourFitVars, profiles, if verbose @info " resonant jsing=$jsing side=$(cell.extra) qerr=$(qerr) res1=$(raw[1]) res2=$(raw[2])" end - hbig = reshape(@view(raw[3:2+N*(np+1)]), N, np + 1) - hsmall = reshape(@view(raw[3+N*(np+1):end]), N, np + 1) + hbig = reshape(@view(raw[3:(2+N*(np+1))]), N, np + 1) + hsmall = reshape(@view(raw[(3+N*(np+1)):end]), N, np + 1) # Apply the right-side negation and the gal_make_arrays signs (gal.f gal_make_arrays) cell.erhs = -sgn_u * raw[1] @@ -449,7 +450,7 @@ including its full three-way edge branch (rpec count `ncoil = ws.nsol - 2*msing` - free boundary (`wv_edge !== nothing`): add the vacuum block `wvac·psio²` at the edge value DOF (gal.f). - fixed boundary (else): identity edge (gal.f). -`wv_edge` is `nothing` for the rpec and fixed cases. + `wv_edge` is `nothing` for the rpec and fixed cases. """ function gal_set_boundary!(ws::GalWorkspace, mpert::Int, wv_edge::Union{Nothing,Matrix{ComplexF64}}) chol = ws.solver == "cholesky" @@ -474,7 +475,7 @@ function gal_set_boundary!(ws::GalWorkspace, mpert::Int, wv_edge::Union{Nothing, cell.mat[idx, idx, 4, 4] = 1 end for ipert in 1:mpert - ws.rhs[cell.map[ipert, 4], 2 * msing + ipert] = 1 + ws.rhs[cell.map[ipert, 4], 2*msing+ipert] = 1 end elseif wv_edge !== nothing # free boundary: vacuum block wvac·psio² (gal.f) diff --git a/src/ForceFreeStates/Galerkin/GalerkinGrid.jl b/src/ForceFreeStates/Galerkin/GalerkinGrid.jl index 497e26e70..49b369fba 100644 --- a/src/ForceFreeStates/Galerkin/GalerkinGrid.jl +++ b/src/ForceFreeStates/Galerkin/GalerkinGrid.jl @@ -20,7 +20,7 @@ function gal_pack(nx::Int, pfac::Float64, side::String) elseif side == "right" xi = collect(0:2nx) ./ (2nx) elseif side == "both" - xi = collect(-nx:nx) ./ nx + xi = collect((-nx):nx) ./ nx else error("gal_pack: unrecognized side = $side") end diff --git a/src/ForceFreeStates/Galerkin/GalerkinSolve.jl b/src/ForceFreeStates/Galerkin/GalerkinSolve.jl index 66dddd893..3b659e2da 100644 --- a/src/ForceFreeStates/Galerkin/GalerkinSolve.jl +++ b/src/ForceFreeStates/Galerkin/GalerkinSolve.jl @@ -39,7 +39,9 @@ function gal_make_arrays!(ws::GalWorkspace, ctrl::ForceFreeStatesControl, equil, return ws end -"""Empty `GalerkinResult` for a domain with no resonant surfaces.""" +""" +Empty `GalerkinResult` for a domain with no resonant surfaces. +""" function empty_galerkin_result() return GalerkinResult(0, Float64[], Float64[], Int[], Int[], Float64[], ComplexF64[], nothing, nothing) end diff --git a/src/ForceFreeStates/Resist.jl b/src/ForceFreeStates/Resist.jl index 3c436daa2..066d10179 100644 --- a/src/ForceFreeStates/Resist.jl +++ b/src/ForceFreeStates/Resist.jl @@ -33,11 +33,13 @@ coefficients E, F, G, H, K, M, the local time scales τ_A (`taua`), τ_R (`taur` by total volume), and the surface index `ising`. # Required keyword arguments + - `eta::Real` — plasma resistivity η at this surface [Ω·m] - `rho::Real` — mass density ρ at this surface [kg/m³] - `gamma::Real` — ratio of specific heats (enters G; physical thermodynamic value, e.g. 5/3) # Physics + The six flux-surface averages (Fortran `avg(1:6)`) are `⟨B²/|∇ψ|²⟩, ⟨1/|∇ψ|²⟩, ⟨1/B²⟩, ⟨1/(B²|∇ψ|²)⟩, ⟨B²⟩, ⟨|∇ψ|²/B²⟩`, each weighted by `J/V′` and integrated over θ ∈ [0,1) — exactly the resist.f integrands. The timescales are @@ -150,10 +152,10 @@ function resonant_match_rpec(delta_out_raw::AbstractMatrix, delta_coil_raw::Abst size(delta_coil_raw, 1) == 2msing || error("delta_coil_raw rows $(size(delta_coil_raw,1)) != 2msing") if ctrl.gal_ideal_flag # ideal limit: no inner layer, no reconnection - return ResonantMatchResult(zeros(ComplexF64,2msing,ncoil), zeros(ComplexF64,2msing,ncoil), - zeros(ComplexF64,msing,2), zeros(ComplexF64,msing), Matrix{ComplexF64}(delta_coil_raw), empty_bpen, 0.0) + return ResonantMatchResult(zeros(ComplexF64, 2msing, ncoil), zeros(ComplexF64, 2msing, ncoil), + zeros(ComplexF64, msing, 2), zeros(ComplexF64, msing), Matrix{ComplexF64}(delta_coil_raw), empty_bpen, 0.0) end - for (nm,v) in (("gal_eta",ctrl.gal_eta),("gal_rho",ctrl.gal_rho),("gal_rotation",ctrl.gal_rotation)) + for (nm, v) in (("gal_eta", ctrl.gal_eta), ("gal_rho", ctrl.gal_rho), ("gal_rotation", ctrl.gal_rotation)) length(v) == msing || error("$nm length $(length(v)) != msing $msing") end @@ -169,37 +171,47 @@ function resonant_match_rpec(delta_out_raw::AbstractMatrix, delta_coil_raw::Abst rpec_eig[i] = γ inner = InnerLayer.solve_inner_profile(InnerLayer.GGJModel(; solver=:galerkin), params, γ; xfac=ctrl.gal_inner_xfac, nx=ctrl.gal_inner_nx, nq=ctrl.gal_inner_nq, cutoff=ctrl.gal_inner_cutoff, kmax=ctrl.gal_inner_kmax) - deltar[i,1] = inner.Δ[1]; deltar[i,2] = inner.Δ[2] + deltar[i, 1] = inner.Δ[1] + deltar[i, 2] = inner.Δ[2] scale = -2π * chi1 * im * nn * sings[i].q1 * inner.dψdx # b_m = −2πi·χ₁·n·q′·dψdx·rescale·Ψ (GalerkinMatch.jl) - pen[i,1] = scale * inner.Ψ[1,1] * inner.rescale # parity 1 (Ψ(0)≠0) - pen[i,2] = scale * inner.Ψ[1,2] * inner.rescale # parity 2 (Ψ(0)=0 ⇒ ~0) + pen[i, 1] = scale * inner.Ψ[1, 1] * inner.rescale # parity 1 (Ψ(0)≠0) + pen[i, 2] = scale * inner.Ψ[1, 2] * inner.rescale # parity 2 (Ψ(0)=0 ⇒ ~0) end - mat = zeros(ComplexF64, 4msing, 4msing) + mat = zeros(ComplexF64, 4msing, 4msing) rmat = zeros(ComplexF64, 4msing, ncoil) - @views mat[2msing+1:4msing, 1:2msing] .= transpose(delta_out_raw) - @views rmat[2msing+1:4msing, :] .= .-delta_coil_raw + @views mat[(2msing+1):4msing, 1:2msing] .= transpose(delta_out_raw) + @views rmat[(2msing+1):4msing, :] .= .-delta_coil_raw for i in 1:msing - a=2i-1; b=2i; c=a+2msing; d=b+2msing - d1=deltar[i,1]; d2=deltar[i,2] - mat[a,a]=1; mat[b,b]=1 - mat[a,c]=-1; mat[a,d]=1 - mat[b,c]=-1; mat[b,d]=-1 - mat[c,c]=-d1; mat[c,d]=d2 - mat[d,c]=-d1; mat[d,d]=-d2 + a=2i-1 + b=2i + c=a+2msing + d=b+2msing + d1=deltar[i, 1] + d2=deltar[i, 2] + mat[a, a]=1 + mat[b, b]=1 + mat[a, c]=-1 + mat[a, d]=1 + mat[b, c]=-1 + mat[b, d]=-1 + mat[c, c]=-d1 + mat[c, d]=d2 + mat[d, c]=-d1 + mat[d, d]=-d2 end cof = mat \ rmat residual = norm(mat*cof - rmat) / max(norm(rmat), 1e-300) cout = cof[1:2msing, :] - cin = cof[2msing+1:4msing, :] - + cin = cof[(2msing+1):4msing, :] + reconnected_flux = delta_coil_raw .+ transpose(delta_out_raw)*cout # Inner-layer penetrated (reconnected) resonant field per surface — ONE quantity per surface, read off # the inner solution at the layer center (match.f intotsol_b; GalerkinMatch.jl): bpen[i,j] = pen₁(i)·cin[2i,j] + pen₂(i)·cin[2i-1,j]. bpen = zeros(ComplexF64, msing, ncoil) for i in 1:msing, j in 1:ncoil - bpen[i,j] = pen[i,1]*cin[2i,j] + pen[i,2]*cin[2i-1,j] + bpen[i, j] = pen[i, 1]*cin[2i, j] + pen[i, 2]*cin[2i-1, j] end return ResonantMatchResult(cout, cin, deltar, rpec_eig, reconnected_flux, bpen, residual) -end \ No newline at end of file +end diff --git a/src/ForceFreeStates/ResistEval.jl b/src/ForceFreeStates/ResistEval.jl index 04953b6c0..0f472bb38 100644 --- a/src/ForceFreeStates/ResistEval.jl +++ b/src/ForceFreeStates/ResistEval.jl @@ -33,23 +33,23 @@ Per-singular-surface Glasser-Greene-Johnson geometric coefficients and supporting flux-surface averages. -| field | meaning | -|-------------|------------------------------------------------------| -| `E`, `F` | Glasser interchange parameters (enter `D_I = E+F+H-¼`) | -| `G` | Coupling coefficient (curvature × pressure gradient) | -| `H` | Pfirsch-Schlüter coefficient | -| `K` | Glasser parameter | -| `M` | Mass factor | -| `avg_bsq_over_dpsisq` | ⟨B²/|∇ψ|²⟩ — needed for τ_R | -| `avg_bsq` | ⟨B²⟩ — needed for τ_R | -| `avg_B` | ⟨B⟩ — needed for Lin-Liu-Miller f_t | -| `B_max`, `B_min` | θ-extrema of B on the surface [T] | -| `f_trap` | Lin-Liu & Miller 1995 trapped-particle fraction | -| `R_major` | flux-surface-averaged major radius ⟨R⟩ [m] | -| `eps_local` | (R_max − R_min)/2 / R_major — local inverse aspect ratio | -| `p_local` | Plasma pressure at this surface [Pa] | -| `p1_local` | dp/dψ at this surface | -| `v1_local` | dV/dψ at this surface | +| field | meaning | +|:--------------------- |:-------------------------------------------------------- | +| `E`, `F` | Glasser interchange parameters (enter `D_I = E+F+H-¼`) | +| `G` | Coupling coefficient (curvature × pressure gradient) | +| `H` | Pfirsch-Schlüter coefficient | +| `K` | Glasser parameter | +| `M` | Mass factor | +| `avg_bsq_over_dpsisq` | ⟨B²/ | +| `avg_bsq` | ⟨B²⟩ — needed for τ_R | +| `avg_B` | ⟨B⟩ — needed for Lin-Liu-Miller f_t | +| `B_max`, `B_min` | θ-extrema of B on the surface [T] | +| `f_trap` | Lin-Liu & Miller 1995 trapped-particle fraction | +| `R_major` | flux-surface-averaged major radius ⟨R⟩ [m] | +| `eps_local` | (R_max − R_min)/2 / R_major — local inverse aspect ratio | +| `p_local` | Plasma pressure at this surface [Pa] | +| `p1_local` | dp/dψ at this surface | +| `v1_local` | dV/dψ at this surface | `H` here is identical to the `H` reported by `mercier_scan!` and stored in `LocalStability/h` — the GGJ routine recomputes it for convenience. @@ -99,6 +99,7 @@ standard GGJ formulas. - `gamma` — adiabatic index (default 5/3) !!! note "Contract" + `psifac` must be a genuine interior rational surface (`0 < ψ < 1`) with nonzero `q1`, `p1 = dp/dψ`, and `p`. The GGJ combination divides by these and by `|∇ψ|²` (which → 0 at the axis), so calling on the magnetic axis, @@ -107,47 +108,47 @@ standard GGJ formulas. rationals. """ function resist_geometry(equil::Equilibrium.PlasmaEquilibrium, - psifac::Real, q1::Real; gamma::Real=5/3) + psifac::Real, q1::Real; gamma::Real=5/3) profiles = equil.profiles - twopi = 2π - chi1 = twopi * equil.psio - psi_f = Float64(psifac) + twopi = 2π + chi1 = twopi * equil.psio + psi_f = Float64(psifac) # Surface-profile quantities (evaluate via the existing splines) twopif = profiles.F_spline(psi_f) - p = profiles.P_spline(psi_f) - p1 = profiles.P_deriv(psi_f) - v1 = profiles.dVdpsi_spline(psi_f) - v2 = profiles.dVdpsi_deriv(psi_f) - q = profiles.q_spline(psi_f) + p = profiles.P_spline(psi_f) + p1 = profiles.P_deriv(psi_f) + v1 = profiles.dVdpsi_spline(psi_f) + v2 = profiles.dVdpsi_deriv(psi_f) + q = profiles.q_spline(psi_f) # Build the 6 GGJ θ-integrands plus a 7th (B) for the neoclassical # resistivity f_t calculation, and accumulate running extrema of # (B, R) for Lin-Liu-Miller f_t and the local ε. ntheta = length(equil.rzphi_ys) - ff = zeros(Float64, ntheta, 7) - B_max = -Inf - B_min = Inf - R_max = -Inf - R_min = Inf + ff = zeros(Float64, ntheta, 7) + B_max = -Inf + B_min = Inf + R_max = -Inf + R_min = Inf for itheta in 1:ntheta theta = equil.rzphi_ys[itheta] - f1 = equil.rzphi_rsquared((psi_f, theta)) - f2 = equil.rzphi_offset((psi_f, theta)) + f1 = equil.rzphi_rsquared((psi_f, theta)) + f2 = equil.rzphi_offset((psi_f, theta)) jac = equil.rzphi_jac((psi_f, theta)) fy1 = FastInterpolations.deriv_view(equil.rzphi_rsquared, (0, 1))((psi_f, theta)) - fy2 = FastInterpolations.deriv_view(equil.rzphi_offset, (0, 1))((psi_f, theta)) - fy3 = FastInterpolations.deriv_view(equil.rzphi_nu, (0, 1))((psi_f, theta)) + fy2 = FastInterpolations.deriv_view(equil.rzphi_offset, (0, 1))((psi_f, theta)) + fy3 = FastInterpolations.deriv_view(equil.rzphi_nu, (0, 1))((psi_f, theta)) rfac = sqrt(f1) - eta = twopi * (theta + f2) - r = equil.ro + rfac * cos(eta) + eta = twopi * (theta + f2) + r = equil.ro + rfac * cos(eta) v21 = fy1 / (2 * rfac * jac) v22 = (1 + fy2) * twopi * rfac / jac v23 = fy3 * r / jac v33 = twopi * r / jac - bsq = chi1^2 * (v21^2 + v22^2 + (v23 + q*v33)^2) + bsq = chi1^2 * (v21^2 + v22^2 + (v23 + q*v33)^2) dpsisq = (twopi * r)^2 * (v21^2 + v22^2) B_here = sqrt(bsq) @@ -180,7 +181,7 @@ function resist_geometry(equil::Equilibrium.PlasmaEquilibrium, (twopif * q1 * chi1 / avg[5] - v2) F_coef = (p1 * v1 / (q1 * chi1^2))^2 * (avg[1] * avg[3] + (twopif / chi1)^2 * - (avg[1] * avg[4] - avg[2]^2)) + (avg[1] * avg[4] - avg[2]^2)) H_coef = twopif * p1 * v1 / (q1 * chi1^3) * (avg[2] - avg[1] / avg[5]) M_coef = avg[1] * (avg[6] + (twopif / chi1)^2 * (avg[3] - 1.0 / avg[5])) @@ -192,7 +193,7 @@ function resist_geometry(equil::Equilibrium.PlasmaEquilibrium, E_coef, F_coef, G_coef, H_coef, K_coef, M_coef, avg[1], avg[5], avg_B, B_max, B_min, f_trap, R_major, eps_local, - p, p1, v1, + p, p1, v1 ) end @@ -204,8 +205,8 @@ Populate `sing.restype` for every `SingType` in `intr.sing` using filled. """ function resist_eval_all!(intr::ForceFreeStatesInternal, - equil::Equilibrium.PlasmaEquilibrium; - gamma::Real=5/3) + equil::Equilibrium.PlasmaEquilibrium; + gamma::Real=5/3) for sing in intr.sing sing.restype === nothing || continue sing.restype = resist_geometry(equil, sing.psifac, sing.q1; gamma=gamma) diff --git a/src/ForceFreeStates/Riccati.jl b/src/ForceFreeStates/Riccati.jl index c1710cc12..7f9c8ee3a 100644 --- a/src/ForceFreeStates/Riccati.jl +++ b/src/ForceFreeStates/Riccati.jl @@ -97,7 +97,7 @@ This is compatible with downstream code (which uses U₁/U₂ ratio): # length chunks; the absolute floor catches short chunks where 5% of the span would be # smaller than the typical ODE step. const SAVE_NEAR_END_FRAC = 0.05 -const SAVE_NEAR_END_PSI = 1e-4 +const SAVE_NEAR_END_PSI = 1e-4 """ assemble_fm_matrix(propagators, idx_range; condition=false) -> Matrix{ComplexF64} @@ -107,6 +107,7 @@ in order for indices `idx_range`. Returns Φ_end * ... * Φ_start, so that the r maps the IC at the start of `idx_range[1]` to the state at the end of `idx_range[end]`. Each `ChunkPropagator` stores the 2N columns of Φ split into two N×N×2 blocks: + ``` block_upper_ic[:,:,1:2] ↔ Φ[:,1:N] (result from IC=(I,0)) block_lower_ic[:,:,1:2] ↔ Φ[:,N+1:2N] (result from IC=(0,I)) @@ -124,8 +125,8 @@ means only U₂ ICs are needed. Do NOT use for inter-surface segments where both and U₂ components carry physical information. """ function assemble_fm_matrix(propagators::Vector{ChunkPropagator}, idx_range; - condition::Bool=false, - T_init::Union{Nothing,Matrix{ComplexF64}}=nothing) + condition::Bool=false, + T_init::Union{Nothing,Matrix{ComplexF64}}=nothing) # Determine matrix size from T_init if provided (lets us handle empty idx_range and even # an empty propagators list, provided T_init carries the dimension). Otherwise fall back # to the first propagator that actually exists in idx_range, with a final fallback to @@ -167,7 +168,7 @@ After conditioning, only the U₂ columns carry meaningful information; the U₁ """ function condition_propagator!(Phi::Matrix{ComplexF64}, N::Int) # Work on the right half: columns N+1:2N (U₂ initial conditions) - cols = view(Phi, :, N+1:2N) + cols = view(Phi, :, (N+1):2N) # Sort columns by norm of the U₁ (upper N) block — largest first norms = [norm(view(cols, 1:N, k)) for k in 1:N] @@ -217,6 +218,7 @@ Compute the inter-surface tearing stability matrix (msing × msing) using the STRIDE global BVP formulation [Glasser 2018 Phys. Plasmas 25, 032501, Sec. III.B]. The BVP encodes the full plasma response with unknowns at each surface boundary: + ``` x_axis (N): free IC parameters at the axis (U₁ = 0 regular solutions) x_left[j] (2N): state at left inner-layer boundary of surface j @@ -229,9 +231,11 @@ The BVP encodes the full plasma response with unknowns at each surface boundary: When `wv` is provided (the vacuum response matrix, singfac-scaled), the edge BC follows the Fortran STRIDE convention: + ``` U₁ = c, U₂ = -wv·ψ₀²·c ``` + which is the free-boundary condition `wp + wv = 0` at the edge. When `wv` is `nothing`, a conducting wall BC (`U₁ = 0`) is used. @@ -248,9 +252,11 @@ keeps the BVP matrix full-rank and well-conditioned. The raw BVP solution is a 2·msing × 2·msing matrix `dp` with left/right sub-indices at each surface. The PEST3-convention Δ' matrix is the linear combination [Chance, PPPL-2527]: + ``` deltap(i,j) = dp(2i,2j) - dp(2i,2j-1) - dp(2i-1,2j) + dp(2i-1,2j-1) ``` + stored in `intr.delta_prime_matrix` (msing × msing). ## Limitations @@ -275,13 +281,13 @@ function compute_delta_prime_matrix!( intr::ForceFreeStatesInternal, propagators::Vector{ChunkPropagator}, chunks::Vector{IntegrationChunk}; - wv::Union{Nothing,Matrix{ComplexF64}} = nothing, - psio::Float64 = 0.0, - debug::Bool = false, - S_at_surface_left::Union{Nothing,Vector{Matrix{ComplexF64}}} = nothing, - ctrl::Union{Nothing,ForceFreeStatesControl} = nothing, - equil::Union{Nothing,Equilibrium.PlasmaEquilibrium} = nothing, - ffit::Union{Nothing,FourFitVars} = nothing + wv::Union{Nothing,Matrix{ComplexF64}}=nothing, + psio::Float64=0.0, + debug::Bool=false, + S_at_surface_left::Union{Nothing,Vector{Matrix{ComplexF64}}}=nothing, + ctrl::Union{Nothing,ForceFreeStatesControl}=nothing, + equil::Union{Nothing,Equilibrium.PlasmaEquilibrium}=nothing, + ffit::Union{Nothing,FourFitVars}=nothing ) intr.msing == 0 && return _has_unsupported_multi_resonance(intr) && return @@ -301,8 +307,10 @@ function compute_delta_prime_matrix!( if !use_S_axis for ic in i_crossings chunks[ic].direction == 1 || - error("compute_delta_prime_matrix!: FM-axis fallback (use_S_axis=false) requires forward crossing chunks; " * - "chunk $ic has direction=$(chunks[ic].direction). Either provide S_at_surface_left or use bidirectional=false.") + error( + "compute_delta_prime_matrix!: FM-axis fallback (use_S_axis=false) requires forward crossing chunks; " * + "chunk $ic has direction=$(chunks[ic].direction). Either provide S_at_surface_left or use bidirectional=false." + ) end end @@ -315,15 +323,15 @@ function compute_delta_prime_matrix!( _build_asymptotic_basis_matrices(sing, has_ua, N, msing) debug && _log_bvp_setup(chunks, sing, S_at_surface_left, use_S_axis, has_ua, - Phi_L_mats, Phi_R_mats, Phi_R_halves, ipert_all, wv, psio, N, msing) + Phi_L_mats, Phi_R_mats, Phi_R_halves, ipert_all, wv, psio, N, msing) if use_S_axis uShootR, uShootL, uAxis = _build_S_axis_shooting_propagators( propagators, chunks, i_crossings, sing, msing, N, T_left_mats, T_right_mats, has_ua, ctrl, equil, ffit, intr, debug) debug && _log_S_axis_shooting_propagators(uShootR, uShootL, uAxis, - S_at_surface_left, T_left_mats, - ipert_all, has_ua, msing, N) + S_at_surface_left, T_left_mats, + ipert_all, has_ua, msing, N) M, nMat, col_edge = _assemble_bvp_S_axis( uShootR, uShootL, uAxis, ipert_all, msing, N, wv, psio) else @@ -350,13 +358,13 @@ function compute_delta_prime_matrix!( # The raw matrix is consumed by `pest3_decompose` to recover (A', B', Γ', Δ') for the full # det(D' − D(γ)) = 0 eigenvalue problem; see ForceFreeStatesStructs.jl docstring. intr.delta_prime_matrix = deltap - intr.delta_prime_raw = dp_raw_persisted + intr.delta_prime_raw = dp_raw_persisted end # Column index helpers for the BVP matrix. j is the 1-based singular-surface index, # N is numpert_total. Layout: c_axis(N), c_left[1](2N), c_right[1](2N), ..., c_edge(N). -_col_left(j::Int, N::Int) = (N + 4N*(j-1) + 1):(N + 4N*(j-1) + 2N) -_col_right(j::Int, N::Int) = (N + 4N*(j-1) + 2N + 1):(N + 4N*j) +_col_left(j::Int, N::Int) = (N+4N*(j-1)+1):(N+4N*(j-1)+2N) +_col_right(j::Int, N::Int) = (N+4N*(j-1)+2N+1):(N+4N*j) # Multi-resonance surfaces (one q value satisfying multiple (m,n) tuples in a multi-n run) # are not yet handled by the inter-surface BVP. Returns true if any surface has >1 modes; @@ -395,28 +403,28 @@ end # Midpoint splitting halves each inter-surface span's condition number — STRIDE's trick: # cond(full) = 10¹⁵ → cond(half) ≈ 10⁷·⁵, an 8-digit accuracy gain. function _assemble_segment_propagators(propagators::Vector{ChunkPropagator}, - chunks::Vector{IntegrationChunk}, - i_crossings::Vector{Int}, msing::Int, N::Int, - use_S_axis::Bool) + chunks::Vector{IntegrationChunk}, + i_crossings::Vector{Int}, msing::Int, N::Int, + use_S_axis::Bool) Phi_L_mats = [assemble_fm_matrix(propagators, i_crossings[j]:i_crossings[j]) for j in 1:msing] Phi_R_mats = Vector{Matrix{ComplexF64}}(undef, msing + 1) if !use_S_axis - Phi_R_mats[1] = assemble_fm_matrix(propagators, 1:i_crossings[1]-1; condition=true) + Phi_R_mats[1] = assemble_fm_matrix(propagators, 1:(i_crossings[1]-1); condition=true) end for j in 2:msing - Phi_R_mats[j] = assemble_fm_matrix(propagators, i_crossings[j-1]+1:i_crossings[j]-1) + Phi_R_mats[j] = assemble_fm_matrix(propagators, (i_crossings[j-1]+1):(i_crossings[j]-1)) end - Phi_R_mats[msing+1] = assemble_fm_matrix(propagators, i_crossings[msing]+1:length(chunks)) + Phi_R_mats[msing+1] = assemble_fm_matrix(propagators, (i_crossings[msing]+1):length(chunks)) Phi_R_halves = Vector{Tuple{Matrix{ComplexF64},Matrix{ComplexF64}}}(undef, msing - 1) - for j in 1:msing-1 + for j in 1:(msing-1) chunk_start = i_crossings[j] + 1 - chunk_end = i_crossings[j+1] - 1 - n_chunks = chunk_end - chunk_start + 1 + chunk_end = i_crossings[j+1] - 1 + n_chunks = chunk_end - chunk_start + 1 if n_chunks >= 2 i_mid = chunk_start + div(n_chunks, 2) - 1 - Phi_left_half = assemble_fm_matrix(propagators, chunk_start:i_mid) - Phi_right_half = assemble_fm_matrix(propagators, i_mid+1:chunk_end) + Phi_left_half = assemble_fm_matrix(propagators, chunk_start:i_mid) + Phi_right_half = assemble_fm_matrix(propagators, (i_mid+1):chunk_end) Phi_R_halves[j] = (Phi_left_half, Phi_right_half) else Phi_R_halves[j] = (Matrix{ComplexF64}(I, 2N, 2N), Phi_R_mats[j+1]) @@ -430,17 +438,17 @@ end # N+1:2N = small solutions (z^{+α}, bounded). Fortran STRIDE bakes T into the shooting # propagators (uFM_sing_init); we multiply T into the BVP propagator blocks at each surface. function _build_asymptotic_basis_matrices(sing::Vector{SingType}, has_ua::Bool, N::Int, msing::Int) - T_left_mats = Vector{Matrix{ComplexF64}}(undef, msing) + T_left_mats = Vector{Matrix{ComplexF64}}(undef, msing) T_right_mats = Vector{Matrix{ComplexF64}}(undef, msing) - T_left_inv = Vector{Matrix{ComplexF64}}(undef, msing) - T_right_inv = Vector{Matrix{ComplexF64}}(undef, msing) + T_left_inv = Vector{Matrix{ComplexF64}}(undef, msing) + T_right_inv = Vector{Matrix{ComplexF64}}(undef, msing) if has_ua for j in 1:msing sp = sing[j] - T_left_mats[j] = [sp.ua_left[:,:,1]; sp.ua_left[:,:,2]] - T_right_mats[j] = [sp.ua_right[:,:,1]; sp.ua_right[:,:,2]] - T_left_inv[j] = inv(T_left_mats[j]) - T_right_inv[j] = inv(T_right_mats[j]) + T_left_mats[j] = [sp.ua_left[:, :, 1]; sp.ua_left[:, :, 2]] + T_right_mats[j] = [sp.ua_right[:, :, 1]; sp.ua_right[:, :, 2]] + T_left_inv[j] = inv(T_left_mats[j]) + T_right_inv[j] = inv(T_right_mats[j]) end end return T_left_mats, T_right_mats, T_left_inv, T_right_inv @@ -471,7 +479,7 @@ function _build_S_axis_shooting_propagators( end if can_reintegrate && !isempty(shoot_range_R) uShootR[j] = integrate_fm_with_ua_ic(chunks, shoot_range_R, sing[j].ua_right, - ctrl, equil, ffit, intr; backward=false, psi_ua=sing[j].psi_ua_right) + ctrl, equil, ffit, intr; backward=false, psi_ua=sing[j].psi_ua_right) else T_init = has_ua ? T_right_mats[j] : nothing uShootR[j] = assemble_fm_matrix(propagators, shoot_range_R; T_init=T_init) @@ -488,7 +496,7 @@ function _build_S_axis_shooting_propagators( end if can_reintegrate && !isempty(shoot_range_L) uShootL[j] = integrate_fm_with_ua_ic(chunks, shoot_range_L, sing[j].ua_left, - ctrl, equil, ffit, intr; backward=true, psi_ua=sing[j].psi_ua_left) + ctrl, equil, ffit, intr; backward=true, psi_ua=sing[j].psi_ua_left) else T_init = has_ua ? T_left_mats[j] : nothing uShootL[j] = assemble_fm_matrix(propagators, shoot_range_L; T_init=T_init) @@ -497,10 +505,10 @@ function _build_S_axis_shooting_propagators( uAxis, i_axis_mid = _build_conditioned_axis_propagator(propagators, i_crossings, N) uShootL[1] = _build_uShootL_first(propagators, chunks, i_crossings, sing, - T_left_mats, has_ua, can_reintegrate, i_axis_mid, - ctrl, equil, ffit, intr, N) + T_left_mats, has_ua, can_reintegrate, i_axis_mid, + ctrl, equil, ffit, intr, N) if debug - shoot_range_L1 = (i_axis_mid + 1):(i_crossings[1] - 1) + shoot_range_L1 = (i_axis_mid+1):(i_crossings[1]-1) @info " Axis propagator: $(i_axis_mid) chunks, cond=$(@sprintf("%.2e", cond(uAxis)))" @info " uShootL[1]: range=$(shoot_range_L1), cond=$(@sprintf("%.2e", cond(uShootL[1])))" end @@ -513,25 +521,25 @@ end # chunk+1 to chunk(i_crossings[j]-1). The ψ midpoint is used (not the chunk-index midpoint) # because chunks near singularities are packed tighter in ψ — Fortran convention. function _midpoint_shoot_range(chunks::Vector{IntegrationChunk}, i_crossings::Vector{Int}, - j::Int, msing::Int; side::Symbol) + j::Int, msing::Int; side::Symbol) if side === :right - j == msing && return (i_crossings[msing] + 1):length(chunks) + j == msing && return (i_crossings[msing]+1):length(chunks) chunk_start = i_crossings[j] + 1 - chunk_end = i_crossings[j+1] - 1 + chunk_end = i_crossings[j+1] - 1 else # :left, j >= 2 chunk_start = i_crossings[j-1] + 1 - chunk_end = i_crossings[j] - 1 + chunk_end = i_crossings[j] - 1 end psi_mid_target = (chunks[chunk_start].psi_start + chunks[chunk_end].psi_end) / 2 i_mid_inter = chunk_start - for ic in chunk_start:chunk_end-1 + for ic in chunk_start:(chunk_end-1) if chunks[ic].psi_end >= psi_mid_target i_mid_inter = ic break end i_mid_inter = ic end - return side === :right ? (chunk_start:i_mid_inter) : ((i_mid_inter + 1):chunk_end) + return side === :right ? (chunk_start:i_mid_inter) : ((i_mid_inter+1):chunk_end) end # Build a well-conditioned axis propagator by forward-propagating [0; I] through the @@ -539,7 +547,7 @@ end # midpoint is placed one chunk before the first surface so that uShootL[1] covers only the # last chunk, keeping it well-conditioned. function _build_conditioned_axis_propagator(propagators::Vector{ChunkPropagator}, - i_crossings::Vector{Int}, N::Int) + i_crossings::Vector{Int}, N::Int) n_pre_cross = i_crossings[1] - 1 i_axis_mid = max(1, n_pre_cross - 1) uAxis = zeros(ComplexF64, 2N, N) @@ -549,9 +557,9 @@ function _build_conditioned_axis_propagator(propagators::Vector{ChunkPropagator} for ic in 1:i_axis_mid prop = propagators[ic] upper_old = uAxis[1:N, :] - lower_old = uAxis[N+1:2N, :] - uAxis[1:N, :] .= prop.block_upper_ic[:,:,1] * upper_old .+ prop.block_lower_ic[:,:,1] * lower_old - uAxis[N+1:2N, :] .= prop.block_upper_ic[:,:,2] * upper_old .+ prop.block_lower_ic[:,:,2] * lower_old + lower_old = uAxis[(N+1):2N, :] + uAxis[1:N, :] .= prop.block_upper_ic[:, :, 1] * upper_old .+ prop.block_lower_ic[:, :, 1] * lower_old + uAxis[(N+1):2N, :] .= prop.block_upper_ic[:, :, 2] * upper_old .+ prop.block_lower_ic[:, :, 2] * lower_old Q, _ = qr(uAxis) uAxis .= Matrix(Q)[:, 1:N] end @@ -565,18 +573,18 @@ end # Falls back to T_left_mats[1] (or identity if no ua) when there's only 1 chunk before the # first crossing. function _build_uShootL_first(propagators::Vector{ChunkPropagator}, - chunks::Vector{IntegrationChunk}, i_crossings::Vector{Int}, - sing::Vector{SingType}, T_left_mats::Vector{Matrix{ComplexF64}}, - has_ua::Bool, can_reintegrate::Bool, i_axis_mid::Int, - ctrl, equil, ffit, intr::ForceFreeStatesInternal, N::Int) - shoot_range_L1 = (i_axis_mid + 1):(i_crossings[1] - 1) + chunks::Vector{IntegrationChunk}, i_crossings::Vector{Int}, + sing::Vector{SingType}, T_left_mats::Vector{Matrix{ComplexF64}}, + has_ua::Bool, can_reintegrate::Bool, i_axis_mid::Int, + ctrl, equil, ffit, intr::ForceFreeStatesInternal, N::Int) + shoot_range_L1 = (i_axis_mid+1):(i_crossings[1]-1) if can_reintegrate && !isempty(shoot_range_L1) return integrate_fm_with_ua_ic(chunks, shoot_range_L1, sing[1].ua_left, - ctrl, equil, ffit, intr; - backward=true, psi_ua=sing[1].psi_ua_left) + ctrl, equil, ffit, intr; + backward=true, psi_ua=sing[1].psi_ua_left) elseif !isempty(shoot_range_L1) return assemble_fm_matrix(propagators, shoot_range_L1; - T_init=has_ua ? T_left_mats[1] : nothing) + T_init=has_ua ? T_left_mats[1] : nothing) else return has_ua ? T_left_mats[1] : Matrix{ComplexF64}(I, 2N, 2N) end @@ -587,19 +595,19 @@ end # the catastrophically ill-conditioned axis FM. Fortran-matched structure with # nMat = (2 + 4·msing)·N. Returns (M, nMat, col_edge). function _assemble_bvp_S_axis(uShootR::Vector{Matrix{ComplexF64}}, - uShootL::Vector{Matrix{ComplexF64}}, - uAxis::Matrix{ComplexF64}, ipert_all::Vector{Int}, - msing::Int, N::Int, - wv::Union{Nothing,Matrix{ComplexF64}}, psio::Float64) + uShootL::Vector{Matrix{ComplexF64}}, + uAxis::Matrix{ComplexF64}, ipert_all::Vector{Int}, + msing::Int, N::Int, + wv::Union{Nothing,Matrix{ComplexF64}}, psio::Float64) # STRIDE global BVP block structure [Glasser-Kolemen 2018 PoP 25, 032501 Eq. 37]. nMat = (2 + 4 * msing) * N col_axis = 1:N - col_edge = (nMat - N + 1):nMat + col_edge = (nMat-N+1):nMat M = zeros(ComplexF64, nMat, nMat) # Axis matching: uShootL[1] · c_left[1] = uAxis · c_axis (2N equations) M[1:2N, _col_left(1, N)] .= uShootL[1] - M[1:2N, col_axis] .= -uAxis + M[1:2N, col_axis] .= -uAxis row_offset = 2N for j in 1:msing @@ -608,24 +616,24 @@ function _assemble_bvp_S_axis(uShootR::Vector{Matrix{ComplexF64}}, for i in 1:2N if i != ipert_j && i != ipert_j + N row_offset += 1 - M[row_offset, _col_left(j, N)[i]] = 1 + M[row_offset, _col_left(j, N)[i]] = 1 M[row_offset, _col_right(j, N)[i]] = -1 end end - junc_rows = (row_offset + 1):(row_offset + 2N) + junc_rows = (row_offset+1):(row_offset+2N) if j < msing # Midpoint matching between consecutive surfaces - M[junc_rows, _col_right(j, N)] .= -uShootR[j] - M[junc_rows, _col_left(j+1, N)] .= uShootL[j+1] + M[junc_rows, _col_right(j, N)] .= -uShootR[j] + M[junc_rows, _col_left(j+1, N)] .= uShootL[j+1] else # Edge junction M[junc_rows, _col_right(msing, N)] .= uShootR[msing] if wv !== nothing - M[junc_rows[1:N], col_edge] .= -I(N) - M[junc_rows[N+1:end], col_edge] .= wv .* psio^2 + M[junc_rows[1:N], col_edge] .= -I(N) + M[junc_rows[(N+1):end], col_edge] .= wv .* psio^2 else - M[junc_rows[N+1:end], col_edge] .= -I(N) + M[junc_rows[(N+1):end], col_edge] .= -I(N) end end row_offset = last(junc_rows) @@ -635,7 +643,7 @@ function _assemble_bvp_S_axis(uShootR::Vector{Matrix{ComplexF64}}, for j in 1:msing ipert_j = ipert_all[j] row_offset += 1 - M[row_offset, _col_left(j, N)[ipert_j]] = 1 + M[row_offset, _col_left(j, N)[ipert_j]] = 1 row_offset += 1 M[row_offset, _col_right(j, N)[ipert_j]] = 1 end @@ -670,18 +678,18 @@ end # Fallback BVP assembly with FM-based axis BC (used when no Riccati S matrices are available). # Uses the conditioned axis propagator Phi_R[1][:,N+1:2N] in place of S-axis matching. function _assemble_bvp_FM_axis(Phi_L_mats::Vector{Matrix{ComplexF64}}, - Phi_R_mats::Vector{Matrix{ComplexF64}}, ipert_all::Vector{Int}, - msing::Int, N::Int, - T_left_inv::Vector{Matrix{ComplexF64}}, - T_right_inv::Vector{Matrix{ComplexF64}}, has_ua::Bool, - wv::Union{Nothing,Matrix{ComplexF64}}, psio::Float64) + Phi_R_mats::Vector{Matrix{ComplexF64}}, ipert_all::Vector{Int}, + msing::Int, N::Int, + T_left_inv::Vector{Matrix{ComplexF64}}, + T_right_inv::Vector{Matrix{ComplexF64}}, has_ua::Bool, + wv::Union{Nothing,Matrix{ComplexF64}}, psio::Float64) nMat = (2 + 4 * msing) * N col_axis = 1:N - col_edge = (N + 4N*msing + 1):nMat + col_edge = (N+4N*msing+1):nMat M = zeros(ComplexF64, nMat, nMat) M[1:2N, (N+1):(N+2N)] .= Phi_L_mats[1] - M[1:2N, col_axis] .= -view(Phi_R_mats[1], :, N+1:2N) + M[1:2N, col_axis] .= -view(Phi_R_mats[1], :, (N+1):2N) row_drive_base = 2N + (4N-2)*msing for j in 1:msing @@ -692,29 +700,29 @@ function _assemble_bvp_FM_axis(Phi_L_mats::Vector{Matrix{ComplexF64}}, for i in 1:2N if i != ipert_j && i != ipert_j + N row_cont += 1 - M[row_cont, cl[i]] = 1 + M[row_cont, cl[i]] = 1 M[row_cont, cr[i]] = -1 end end - junc_rows = (row_cont + 1):(2N + (4N-2)*j) + junc_rows = (row_cont+1):(2N+(4N-2)*j) if j < msing - M[junc_rows, cr] .= Phi_R_mats[j+1] + M[junc_rows, cr] .= Phi_R_mats[j+1] M[junc_rows, _col_left(j+1, N)] .= -Phi_L_mats[j+1] else M[junc_rows, cr] .= Phi_R_mats[msing+1] if wv !== nothing - M[junc_rows[1:N], col_edge] .= -I(N) - M[junc_rows[N+1:end], col_edge] .= wv .* psio^2 + M[junc_rows[1:N], col_edge] .= -I(N) + M[junc_rows[(N+1):end], col_edge] .= wv .* psio^2 else - M[junc_rows[N+1:end], col_edge] .= -I(N) + M[junc_rows[(N+1):end], col_edge] .= -I(N) end end if has_ua - M[row_drive_base + 2j-1, cl] .= T_left_inv[j][ipert_j, :] - M[row_drive_base + 2j, cr] .= T_right_inv[j][ipert_j, :] + M[row_drive_base+2j-1, cl] .= T_left_inv[j][ipert_j, :] + M[row_drive_base+2j, cr] .= T_right_inv[j][ipert_j, :] else - M[row_drive_base + 2j-1, cl[ipert_j]] = 1 - M[row_drive_base + 2j, cr[ipert_j]] = 1 + M[row_drive_base+2j-1, cl[ipert_j]] = 1 + M[row_drive_base+2j, cr[ipert_j]] = 1 end end return M, nMat, col_edge @@ -725,8 +733,8 @@ end # combination subtracts dp_raw entries up to ~3×10⁴ larger than the result, and Float64 # precision lets the imaginary part drift 2–5× on DIIID-class equilibria. function _solve_bvp_and_combine_pest3(M::Matrix{ComplexF64}, msing::Int, N::Int, nMat::Int, - use_S_axis::Bool, ipert_all::Vector{Int}, col_edge, - ctrl, debug::Bool) + use_S_axis::Bool, ipert_all::Vector{Int}, col_edge, + ctrl, debug::Bool) s2 = 2 * msing Tc = (ctrl === nothing || ctrl.extended_precision_bvp) ? Complex{Double64} : ComplexF64 M_solve = Tc.(M) @@ -748,12 +756,12 @@ function _solve_bvp_and_combine_pest3(M::Matrix{ComplexF64}, msing::Int, N::Int, x = use_lu ? (M_lu \ b) : (M_pinv * b) debug && _log_bvp_solve(x, b, M_solve, jsing, side, dRow, msing, N, - ipert_all, col_edge, use_S_axis) + ipert_all, col_edge, use_S_axis) for ksing in 1:msing ipert_k = ipert_all[ksing] dp_raw[dRow, 2ksing-1] = x[_col_left(ksing, N)[ipert_k+N]] - dp_raw[dRow, 2ksing] = x[_col_right(ksing, N)[ipert_k+N]] + dp_raw[dRow, 2ksing] = x[_col_right(ksing, N)[ipert_k+N]] end end @@ -773,7 +781,7 @@ end # Logging helpers for `compute_delta_prime_matrix!`. Called only when debug=true. function _log_bvp_setup(chunks, sing, S_at_surface_left, use_S_axis, has_ua, - Phi_L_mats, Phi_R_mats, Phi_R_halves, ipert_all, wv, psio, N, msing) + Phi_L_mats, Phi_R_mats, Phi_R_halves, ipert_all, wv, psio, N, msing) @info "Δ' BVP: $(length(chunks)) chunks, $msing surfaces, N=$N" @info "Δ' BVP: Axis BC: $(use_S_axis ? "S-based (Riccati)" : "FM-based (conditioned)")" @info "Δ' BVP: Asymptotic basis: $(has_ua ? "available" : "NOT available (raw basis driving)")" @@ -785,8 +793,8 @@ function _log_bvp_setup(chunks, sing, S_at_surface_left, use_S_axis, has_ua, if has_ua for j in 1:msing sp = sing[j] - T_l = [sp.ua_left[:,:,1]; sp.ua_left[:,:,2]] - T_r = [sp.ua_right[:,:,1]; sp.ua_right[:,:,2]] + T_l = [sp.ua_left[:, :, 1]; sp.ua_left[:, :, 2]] + T_r = [sp.ua_right[:, :, 1]; sp.ua_right[:, :, 2]] @info " Surface $j: cond(T_left)=$(@sprintf("%.2e", cond(T_l))), cond(T_right)=$(@sprintf("%.2e", cond(T_r)))" ipert_j = ipert_all[j] @info " Surface $j ua_left (ipert=$ipert_j, psi_ua_left=$(@sprintf("%.8f", sp.psi_ua_left))):" @@ -796,7 +804,7 @@ function _log_bvp_setup(chunks, sing, S_at_surface_left, use_S_axis, has_ua, @info " small: ua(1,$(ipert_j+N),1)=$(@sprintf("%16.8e %16.8e", real(sp.ua_left[1,ipert_j+N,1]), imag(sp.ua_left[1,ipert_j+N,1])))" end end - for j in 1:msing-1 + for j in 1:(msing-1) Phi_L_h, Phi_R_h = Phi_R_halves[j] @info " Inter-surface $j→$(j+1): half_L cond=$(@sprintf("%.2e",cond(Phi_L_h))), half_R cond=$(@sprintf("%.2e",cond(Phi_R_h))), full cond=$(@sprintf("%.2e",cond(Phi_R_mats[j+1])))" end @@ -813,7 +821,7 @@ function _log_bvp_setup(chunks, sing, S_at_surface_left, use_S_axis, has_ua, end function _log_S_axis_shooting_propagators(uShootR, uShootL, uAxis, S_at_surface_left, - T_left_mats, ipert_all, has_ua, msing, N) + T_left_mats, ipert_all, has_ua, msing, N) @info " Shooting propagators (S-based axis BC, no axis unknowns):" for j in 1:msing shoot_R_str = @sprintf("%.2e", cond(uShootR[j])) @@ -823,7 +831,7 @@ function _log_S_axis_shooting_propagators(uShootR, uShootL, uAxis, S_at_surface_ S1 = S_at_surface_left[1] if has_ua T1 = T_left_mats[1] - axis_BC = T1[1:N, :] - S1 * T1[N+1:2N, :] + axis_BC = T1[1:N, :] - S1 * T1[(N+1):2N, :] @info " S-axis BC matrix: cond=$(@sprintf("%.2e", cond(axis_BC)))" end for j in 1:msing @@ -837,7 +845,7 @@ function _log_S_axis_shooting_propagators(uShootR, uShootL, uAxis, S_at_surface_ @info " uShootL[$j] col ipert=$ipert_j norm=$(@sprintf("%.2e", col_norms_L[ipert_j])), col ipert+N=$(ipert_j+N) norm=$(@sprintf("%.2e", col_norms_L[ipert_j+N]))" end end - for j in 1:msing-1 + for j in 1:(msing-1) mid_block = hcat(uShootR[j], -uShootL[j+1]) @info " Midpoint $j→$(j+1): cond([uShootR[$j] | -uShootL[$(j+1)]]) = $(@sprintf("%.2e", cond(mid_block)))" col_norms_Ljp1 = [norm(view(uShootL[j+1], :, k)) for k in 1:2N] @@ -846,7 +854,7 @@ function _log_S_axis_shooting_propagators(uShootR, uShootL, uAxis, S_at_surface_ end function _log_bvp_solve(x, b, M_solve, jsing, side, dRow, msing, N, - ipert_all, col_edge, use_S_axis) + ipert_all, col_edge, use_S_axis) residual = norm(ComplexF64.(M_solve * x - b)) side_str = side == 1 ? "left" : "right" @info " BVP solve: jsing=$jsing side=$side_str (dRow=$dRow): ||Mx-b||=$(@sprintf("%.2e", residual)), ||x||=$(@sprintf("%.2e", Float64(norm(x))))" @@ -854,9 +862,9 @@ function _log_bvp_solve(x, b, M_solve, jsing, side, dRow, msing, N, ipert_ks = ipert_all[ks] cl = _col_left(ks, N) cr = _col_right(ks, N) - xl_big = ComplexF64(x[cl[ipert_ks]]) + xl_big = ComplexF64(x[cl[ipert_ks]]) xl_small = ComplexF64(x[cl[ipert_ks+N]]) - xr_big = ComplexF64(x[cr[ipert_ks]]) + xr_big = ComplexF64(x[cr[ipert_ks]]) xr_small = ComplexF64(x[cr[ipert_ks+N]]) @info " surf $ks: x_left[big]=$(@sprintf("%+.4e%+.4ei", real(xl_big), imag(xl_big))), x_left[small]=$(@sprintf("%+.4e%+.4ei", real(xl_small), imag(xl_small)))" @info " surf $ks: x_right[big]=$(@sprintf("%+.4e%+.4ei", real(xr_big), imag(xr_big))), x_right[small]=$(@sprintf("%+.4e%+.4ei", real(xr_small), imag(xr_small)))" @@ -870,7 +878,7 @@ end function _log_bvp_pest3(dp_raw, deltap, s2, msing, Tc) @info "Δ' BVP: Full dp_raw matrix ($(s2)×$(s2)) [$(Tc)]:" for i in 1:s2 - row_str = join([@sprintf("%+.6e", Float64(real(dp_raw[i,j]))) for j in 1:s2], " ") + row_str = join([@sprintf("%+.6e", Float64(real(dp_raw[i, j]))) for j in 1:s2], " ") @info " dp_raw[$i,:] = $row_str" end @info "Δ' BVP: Raw dp diagonal = $([@sprintf("%.4f%+.4fi", Float64(real(dp_raw[i,i])), Float64(imag(dp_raw[i,i]))) for i in 1:s2])" @@ -930,8 +938,8 @@ function pest3_decompose(dp_raw::AbstractMatrix) for i in 1:m, j in 1:m LL = dp_raw[2i-1, 2j-1] LR = dp_raw[2i-1, 2j] - RL = dp_raw[2i, 2j-1] - RR = dp_raw[2i, 2j] + RL = dp_raw[2i, 2j-1] + RR = dp_raw[2i, 2j] Ap[i, j] = RR + RL + LR + LL Bp[i, j] = RR - RL + LR - LL Gp[i, j] = RR + RL - LR - LL @@ -944,7 +952,7 @@ end riccati_der!(du, u, params, psieval) Evaluate the explicit dual Riccati ODE right-hand side: - dS/dψ = w†·F̄⁻¹·w - S·Ḡ·S, w = Q - K̄·S +dS/dψ = w†·F̄⁻¹·w - S·Ḡ·S, w = Q - K̄·S where Q = diag(1/(m - n·q)) is the diagonal singular factor matrix. The identity slice u[:,:,2] = I does not evolve (du[:,:,2] = 0). @@ -968,7 +976,7 @@ See: Glasser (2018) Phys. Plasmas 25, 032507 — Eq. 19 (dual Riccati form) _, equil, ffit, intr, odet, _ = params Npert = intr.numpert_total - S = @view u[:, :, 1] + S = @view u[:, :, 1] dS = @view du[:, :, 1] @view(du[:, :, 2]) .= 0 # identity does not evolve @@ -983,9 +991,9 @@ See: Glasser (2018) Phys. Plasmas 25, 032507 — Eq. 19 (dual Riccati form) fmat_lower = acquire!(pool, ComplexF64, Npert, Npert) kmat = similar!(pool, fmat_lower) gmat = similar!(pool, fmat_lower) - w = similar!(pool, fmat_lower) # w = Q - K̄·S - v = similar!(pool, fmat_lower) # v = F̄⁻¹·w (then reused for S·Ḡ·S) - tmp = similar!(pool, fmat_lower) # scratch + w = similar!(pool, fmat_lower) # w = Q - K̄·S + v = similar!(pool, fmat_lower) # v = F̄⁻¹·w (then reused for S·Ḡ·S) + tmp = similar!(pool, fmat_lower) # scratch # Evaluate F̄ (Cholesky factor), K̄, Ḡ splines at current ψ ffit.fmats_lower(vec(fmat_lower), psieval; hint=ffit._hint) @@ -1076,7 +1084,7 @@ function riccati_integrate_chunk!( cb = DiscreteCallback((u, t, integrator) -> true, riccati_integrator_callback!) rtol = ctrl.eulerlagrange_tolerance prob = ODEProblem(sing_der!, odet.u, (chunk.psi_start, chunk.psi_end), - (ctrl, equil, ffit, intr, odet, chunk)) + (ctrl, equil, ffit, intr, odet, chunk)) sol = solve(prob, Vern9(); reltol=rtol, callback=cb, save_everystep=false, save_end=true) odet.u .= sol.u[end] odet.psifac = sol.t[end] @@ -1094,8 +1102,8 @@ end renormalize_riccati!(odet, intr) After a singular surface crossing, restore the canonical Riccati storage convention: - u[:,:,1] = S_new = U₁_new · U₂_new⁻¹ - u[:,:,2] = I +u[:,:,1] = S_new = U₁_new · U₂_new⁻¹ +u[:,:,2] = I `riccati_cross_ideal_singular_surf!` leaves u[:,:,1] = U₁_new and u[:,:,2] = U₂_new (not I), so this step is required before continuing the Riccati integration. @@ -1119,8 +1127,8 @@ end renormalize_riccati_inplace!(u, N) In-place Riccati renormalization on an arbitrary N×N×2 array: - u[:,:,1] = U₁ · U₂⁻¹ (new S) - u[:,:,2] = I +u[:,:,1] = U₁ · U₂⁻¹ (new S) +u[:,:,2] = I Used in `riccati_integrator_callback!` to renormalize the integrator's live state when column norms grow beyond `ctrl.ucrit`, analogous to Gaussian reduction in the @@ -1142,14 +1150,14 @@ end Cross a singular surface for the Riccati formulation. Replaces `cross_ideal_singular_surf!` for the Riccati integration path with two key differences: -1. **No Gaussian reduction**: `cross_ideal_singular_surf!` calls `compute_solution_norms!` - which applies Gaussian reduction to (S, I). This divides by pivot elements of S, which - can be near-zero (S = 0 at axis and grows slowly), producing NaN/Inf in U₂. For Riccati, - S is bounded so Gaussian reduction is unnecessary. + 1. **No Gaussian reduction**: `cross_ideal_singular_surf!` calls `compute_solution_norms!` + which applies Gaussian reduction to (S, I). This divides by pivot elements of S, which + can be near-zero (S = 0 at axis and grows slowly), producing NaN/Inf in U₂. For Riccati, + S is bounded so Gaussian reduction is unnecessary. -2. **Direct column zeroing**: Instead of using the GR-sorted `odet.index` to identify the - column to zero, we use `ipert_res` directly (the resonant mode index). This is valid since - without GR there is no permutation applied to the columns of S. + 2. **Direct column zeroing**: Instead of using the GR-sorted `odet.index` to identify the + column to zero, we use `ipert_res` directly (the resonant mode index). This is valid since + without GR there is no permutation applied to the columns of S. **Δ' normalization**: This function expects `odet.u` in the bounded (U₁, U₂) form produced by `riccati_integrate_chunk!` with `needs_crossing=true` (final renorm skipped). ca_l is computed @@ -1195,11 +1203,11 @@ Fortran STRIDE's separate vmatl/vmatr (sing_vmat). Alpha is taken from the right side and shared with the left. """ function _two_sided_singular_asymptotics(singp::SingType, ctrl::ForceFreeStatesControl, - equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, - intr::ForceFreeStatesInternal) + equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, + intr::ForceFreeStatesInternal) sing_asymp_right = compute_sing_asymptotics(singp, ctrl, equil, ffit, intr; sig=1.0) - sing_asymp_left = compute_sing_asymptotics(singp, ctrl, equil, ffit, intr; sig=-1.0, - alpha_override=sing_asymp_right.alpha) + sing_asymp_left = compute_sing_asymptotics(singp, ctrl, equil, ffit, intr; sig=-1.0, + alpha_override=sing_asymp_right.alpha) return sing_asymp_left, sing_asymp_right end @@ -1219,7 +1227,7 @@ end # Capture left-side asymptotic data into odet.ca_l and singp.ua_left/psi_ua_left. function _capture_left_crossing_data!(odet::OdeState, singp::SingType, sing_asymp_left, - dpsi::Float64, intr::ForceFreeStatesInternal, ising::Int) + dpsi::Float64, intr::ForceFreeStatesInternal, ising::Int) ua = sing_get_ua(sing_asymp_left, dpsi) singp.ua_left = copy(ua) singp.psi_ua_left = odet.psifac @@ -1231,9 +1239,9 @@ end # odet.psifac to the right side. The zeroed columns stay zero through the predictor # since du[:, ipert_res, :] = 0 when u[:, ipert_res, :] = 0. function _predict_across_singular_surface!(odet::OdeState, ctrl::ForceFreeStatesControl, - equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, - intr::ForceFreeStatesInternal, ising::Int, - ipert_res, dpsi::Float64, sing_asymp_right) + equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, + intr::ForceFreeStatesInternal, ising::Int, + ipert_res, dpsi::Float64, sing_asymp_right) if ctrl.kinetic_factor == 0 for i in eachindex(sing_asymp_right.r1) odet.u[:, ipert_res[i], :] .= 0 @@ -1253,8 +1261,8 @@ end # Column ipert_res of [U₁_new; U₂_new] = ua[:, ipert_res+N, :] (the introduced small asymptotic), # so ca_r[ipert_res, ipert_res, 2] = 1 regardless of other columns' normalization. function _capture_right_crossing_data!(odet::OdeState, singp::SingType, sing_asymp_right, - dpsi::Float64, intr::ForceFreeStatesInternal, ising::Int, - ipert_res, ctrl::ForceFreeStatesControl) + dpsi::Float64, intr::ForceFreeStatesInternal, ising::Int, + ipert_res, ctrl::ForceFreeStatesControl) ua = sing_get_ua(sing_asymp_right, dpsi) singp.ua_right = copy(ua) singp.psi_ua_right = odet.psifac @@ -1270,9 +1278,9 @@ end # STUB: per-surface ca-based Δ' (not physically valid; see SingType.delta_prime docstring). # The canonical Δ' is intr.delta_prime_matrix from compute_delta_prime_matrix!. function _stash_per_surface_delta_prime_stub!(odet::OdeState, intr::ForceFreeStatesInternal, - ising::Int, ipert_res, sing_asymp_right, - equil::Equilibrium.PlasmaEquilibrium, - ctrl::ForceFreeStatesControl) + ising::Int, ipert_res, sing_asymp_right, + equil::Equilibrium.PlasmaEquilibrium, + ctrl::ForceFreeStatesControl) ctrl.kinetic_factor == 0 || return denom = (2π)^2 * equil.psio n_res = length(sing_asymp_right.r1) @@ -1323,8 +1331,8 @@ function integrate_propagator_chunk!( # naturally. The resulting propagator maps state at psi_end → psi_start, which is # well-conditioned because exponentially growing solutions (forward) decay backward. tspan = chunk.direction == 1 ? - (chunk.psi_start, chunk.psi_end) : - (chunk.psi_end, chunk.psi_start) + (chunk.psi_start, chunk.psi_end) : + (chunk.psi_end, chunk.psi_start) rtol = ctrl.eulerlagrange_tolerance params = (ctrl, equil, ffit, intr, odet_proxy, chunk) @@ -1378,12 +1386,12 @@ function integrate_fm_with_ua_ic( equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, intr::ForceFreeStatesInternal; - backward::Bool = false, - psi_ua::Float64 = NaN + backward::Bool=false, + psi_ua::Float64=NaN ) N = intr.numpert_total psi_start = chunks[first(chunk_range)].psi_start - psi_end = chunks[last(chunk_range)].psi_end + psi_end = chunks[last(chunk_range)].psi_end # Use stored ua ψ location if provided; otherwise fall back to chunk boundary. # The ua is evaluated at the inner-layer boundary (exact ψ from singular crossing), # which may differ slightly from the nearest chunk boundary. @@ -1409,18 +1417,18 @@ function integrate_fm_with_ua_ic( odet_proxy.ffit_hint[] = 1 prob = ODEProblem(sing_der!, u0, tspan, params) sol = solve(prob, Vern9(); reltol=rtol, save_everystep=false, save_end=true) - result[1:N, 1:N] .= sol.u[end][:, :, 1] - result[N+1:2N, 1:N] .= sol.u[end][:, :, 2] + result[1:N, 1:N] .= sol.u[end][:, :, 1] + result[(N+1):2N, 1:N] .= sol.u[end][:, :, 2] # Batch 2: columns N+1:2N of T (small solutions) - u0[:, :, 1] .= ua[:, N+1:2N, 1] - u0[:, :, 2] .= ua[:, N+1:2N, 2] + u0[:, :, 1] .= ua[:, (N+1):2N, 1] + u0[:, :, 2] .= ua[:, (N+1):2N, 2] odet_proxy.spline_hint[] = 1 odet_proxy.ffit_hint[] = 1 prob = ODEProblem(sing_der!, u0, tspan, params) sol = solve(prob, Vern9(); reltol=rtol, save_everystep=false, save_end=true) - result[1:N, N+1:2N] .= sol.u[end][:, :, 1] - result[N+1:2N, N+1:2N] .= sol.u[end][:, :, 2] + result[1:N, (N+1):2N] .= sol.u[end][:, :, 1] + result[(N+1):2N, (N+1):2N] .= sol.u[end][:, :, 2] return result end @@ -1432,8 +1440,8 @@ Apply the chunk propagator `prop` to the current state `odet.u` in-place. The propagator acts as a linear map on the (U₁, U₂) pair: - U₁_new = block_upper_ic[:,:,1] · U₁_prev + block_lower_ic[:,:,1] · U₂_prev - U₂_new = block_upper_ic[:,:,2] · U₁_prev + block_lower_ic[:,:,2] · U₂_prev +U₁_new = block_upper_ic[:,:,1] · U₁_prev + block_lower_ic[:,:,1] · U₂_prev +U₂_new = block_upper_ic[:,:,2] · U₁_prev + block_lower_ic[:,:,2] · U₂_prev This correctly propagates any state (not just the identity), including the (S, I) form produced by Riccati-style crossings. @@ -1488,10 +1496,10 @@ function apply_propagator_inverse!(odet::OdeState, prop::ChunkPropagator) # Φ_bwd maps state at psi_end → psi_start (well-conditioned). # We want Φ_fwd = Φ_bwd⁻¹ to advance state from psi_start → psi_end. # Solving Φ_bwd · x = [U₁_old; U₂_old] gives x = Φ_bwd⁻¹ · [U₁_old; U₂_old]. - u_old = [odet.u[:,:,1]; odet.u[:,:,2]] # 2N × N + u_old = [odet.u[:, :, 1]; odet.u[:, :, 2]] # 2N × N u_new = Φ \ u_old # LU solve, 2N × N - odet.u[:,:,1] .= u_new[1:N, :] - odet.u[:,:,2] .= u_new[N+1:2N, :] + odet.u[:, :, 1] .= u_new[1:N, :] + odet.u[:, :, 2] .= u_new[(N+1):2N, :] end """ @@ -1504,33 +1512,34 @@ this is the only branch that produces them. Solves the same system as [`forward_eulerlagrange_integration`](@ref), but integrates all bulk chunks concurrently using `Threads.@threads`, then re-integrates the outer plasma serially: -1. **Chunk generation**: calls `chunk_el_integration_bounds`, then `balance_integration_chunks` - to sub-divide chunks for load balancing. The chunk count depends only on `intr.msing` and - `ctrl.nchunks`, never on the thread count, so results are thread-independent. -2. **Propagator phase**: `integrate_propagator_chunk!` integrates each chunk independently - from identity initial conditions (no accumulated state, no normalization/callback). - Each thread uses a private `OdeState` proxy for `sing_der!` side effects. -3. **Serial assembly**: propagators are applied sequentially with `apply_propagator!`. - Rational surface crossings use `riccati_cross_ideal_singular_surf!` (no Gaussian - reduction). -4. **Outer plasma re-integration**: after the last rational surface crossing, the outer - plasma (from last ψ_s to psilim) is re-integrated using `riccati_integrate_chunk!`. - FM propagation in this region is prone to precision loss for high N (exponential growth - without renormalization); Riccati integration keeps matrices bounded and provides dense - checkpoints for `findmax_dW_edge!`. + 1. **Chunk generation**: calls `chunk_el_integration_bounds`, then `balance_integration_chunks` + to sub-divide chunks for load balancing. The chunk count depends only on `intr.msing` and + `ctrl.nchunks`, never on the thread count, so results are thread-independent. + 2. **Propagator phase**: `integrate_propagator_chunk!` integrates each chunk independently + from identity initial conditions (no accumulated state, no normalization/callback). + Each thread uses a private `OdeState` proxy for `sing_der!` side effects. + 3. **Serial assembly**: propagators are applied sequentially with `apply_propagator!`. + Rational surface crossings use `riccati_cross_ideal_singular_surf!` (no Gaussian + reduction). + 4. **Outer plasma re-integration**: after the last rational surface crossing, the outer + plasma (from last ψ_s to psilim) is re-integrated using `riccati_integrate_chunk!`. + FM propagation in this region is prone to precision loss for high N (exponential growth + without renormalization); Riccati integration keeps matrices bounded and provides dense + checkpoints for `findmax_dW_edge!`. Select via `integrator = "riccati"` in `[ForceFreeStates]` of gpec.toml. Requires `singfac_min != 0`. Uses whatever threads `julia -t` provides; `ctrl.nchunks` is the only tunable. **Key differences from the forward integrator:** -- No Gaussian reduction in the propagator BVP phase (crossings use the - Riccati-style algorithm, `odet.ifix` stays 0) -- `transform_u!` is called on the odet but is a no-op (ifix=0) -- Outer plasma uses serial Riccati integration for numerical stability -- `odet.u_store` holds chunk-endpoint Riccati states, not dense Euler-Lagrange ξ, and - `odet.u_store_el_basis` stays `false`: this integrator never claims the EL basis, so - PerturbedEquilibrium and the HDF5 forward-integration ξ datasets require the forward path. + + - No Gaussian reduction in the propagator BVP phase (crossings use the + Riccati-style algorithm, `odet.ifix` stays 0) + - `transform_u!` is called on the odet but is a no-op (ifix=0) + - Outer plasma uses serial Riccati integration for numerical stability + - `odet.u_store` holds chunk-endpoint Riccati states, not dense Euler-Lagrange ξ, and + `odet.u_store_el_basis` stays `false`: this integrator never claims the EL basis, so + PerturbedEquilibrium and the HDF5 forward-integration ξ datasets require the forward path. **Bidirectional integration for large-N accuracy:** The crossing chunk (nearest to each rational surface singL[j]) is integrated *backward* @@ -1577,9 +1586,9 @@ end # Build odet and initialize at the magnetic axis. Same path as serial eulerlagrange_integration. function _initialize_parallel_odet(ctrl::ForceFreeStatesControl, - equil::Equilibrium.PlasmaEquilibrium, - ffit::FourFitVars, - intr::ForceFreeStatesInternal) + equil::Equilibrium.PlasmaEquilibrium, + ffit::FourFitVars, + intr::ForceFreeStatesInternal) odet = OdeState(intr.numpert_total, ctrl.numsteps_init, ctrl.numunorms_init, intr.msing) if ctrl.sing_start <= 0 initialize_el_at_axis!(odet, ctrl, ffit, equil.profiles, intr) @@ -1598,7 +1607,7 @@ end # per-thread proxy OdeStates sized by maxthreadid() (Julia 1.9+ may report threadid # values above nthreads() due to the interactive thread pool). function _setup_parallel_chunks_and_proxies(odet::OdeState, ctrl::ForceFreeStatesControl, - intr::ForceFreeStatesInternal) + intr::ForceFreeStatesInternal) # Bidirectional chunks: crossing chunks are assigned direction=-1 so they are # integrated backward. The resulting Φ_bwd is well-conditioned because growing EL # solutions decay backward; forward propagation is recovered via LU solve in @@ -1612,8 +1621,8 @@ function _setup_parallel_chunks_and_proxies(odet::OdeState, ctrl::ForceFreeState end function _log_parallel_start(ctrl::ForceFreeStatesControl, odet::OdeState, - equil::Equilibrium.PlasmaEquilibrium, - chunks::Vector{IntegrationChunk}) + equil::Equilibrium.PlasmaEquilibrium, + chunks::Vector{IntegrationChunk}) ctrl.verbose || return @info " ψ = $((@sprintf "%.3f" odet.psifac)), q = $((@sprintf "%.3f" equil.profiles.q_spline(odet.psifac)))" @info " Riccati FM: $(length(chunks)) chunks over $(Threads.nthreads()) thread$(Threads.nthreads() == 1 ? "" : "s")" @@ -1624,14 +1633,14 @@ end # Each chunk is independent (identity IC, no accumulated state), so the result does not # depend on how chunks are distributed across threads. function _run_parallel_bvp_phase!(propagators::Vector{ChunkPropagator}, - chunks::Vector{IntegrationChunk}, - ctrl::ForceFreeStatesControl, - equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, - intr::ForceFreeStatesInternal, - odet_proxies::Vector{OdeState}) + chunks::Vector{IntegrationChunk}, + ctrl::ForceFreeStatesControl, + equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, + intr::ForceFreeStatesInternal, + odet_proxies::Vector{OdeState}) Threads.@threads :static for i in eachindex(chunks) integrate_propagator_chunk!(propagators[i], chunks[i], ctrl, equil, ffit, intr, - odet_proxies[Threads.threadid()]) + odet_proxies[Threads.threadid()]) end end @@ -1643,10 +1652,10 @@ end # the well-conditioned Riccati S at each surface's left boundary for use as the Δ' BVP # axis BC. Returns (S_at_surface_left, last_crossing_step). function _assemble_propagators_serially!(odet::OdeState, propagators::Vector{ChunkPropagator}, - chunks::Vector{IntegrationChunk}, - ctrl::ForceFreeStatesControl, - equil::Equilibrium.PlasmaEquilibrium, - ffit::FourFitVars, intr::ForceFreeStatesInternal) + chunks::Vector{IntegrationChunk}, + ctrl::ForceFreeStatesControl, + equil::Equilibrium.PlasmaEquilibrium, + ffit::FourFitVars, intr::ForceFreeStatesInternal) N = intr.numpert_total S_at_surface_left = Matrix{ComplexF64}[] last_crossing_step = 1 @@ -1693,9 +1702,9 @@ end # entry at last_crossing_step holds (U₁_new, U₂_new) from riccati_cross_ideal_singular_surf! # before renormalization; we renorm here to (S_new, I) as the Riccati starting state. function _reintegrate_outer_plasma!(odet::OdeState, last_crossing_step::Int, - ctrl::ForceFreeStatesControl, - equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, - intr::ForceFreeStatesInternal) + ctrl::ForceFreeStatesControl, + equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, + intr::ForceFreeStatesInternal) N = intr.numpert_total odet.u .= odet.u_store[:, :, :, last_crossing_step] odet.psifac = odet.psi_store[last_crossing_step] @@ -1703,7 +1712,7 @@ function _reintegrate_outer_plasma!(odet::OdeState, last_crossing_step::Int, odet.step = last_crossing_step + 1 renormalize_riccati_inplace!(odet.u, N) outer_chunk = IntegrationChunk(; psi_start=odet.psifac, psi_end=intr.psilim * (1 - eps), - needs_crossing=false, ising=0) + needs_crossing=false, ising=0) riccati_integrate_chunk!(odet, ctrl, equil, ffit, intr, outer_chunk) # Post: odet.u is in (S, I) form; odet.step points to next empty slot. end @@ -1717,10 +1726,10 @@ end # original psilim — silently shifting the outermost rational's Δ' by tens of percent. # Returns the (possibly truncated) chunks and propagators arrays. function _handle_edge_dW_scan!(odet::OdeState, chunks::Vector{IntegrationChunk}, - propagators::Vector{ChunkPropagator}, - ctrl::ForceFreeStatesControl, - equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, - intr::ForceFreeStatesInternal) + propagators::Vector{ChunkPropagator}, + ctrl::ForceFreeStatesControl, + equil::Equilibrium.PlasmaEquilibrium, ffit::FourFitVars, + intr::ForceFreeStatesInternal) N = intr.numpert_total odet.step -= 1 trim_storage!(odet) @@ -1754,22 +1763,22 @@ function _handle_edge_dW_scan!(odet::OdeState, chunks::Vector{IntegrationChunk}, end straddling = chunks[last_chunk_idx] if straddling.psi_end > peak_psi - new_chunk = IntegrationChunk( - psi_start = straddling.psi_start, - psi_end = peak_psi, - needs_crossing = straddling.needs_crossing, - ising = straddling.ising, - direction = straddling.direction, + new_chunk = IntegrationChunk(; + psi_start=straddling.psi_start, + psi_end=peak_psi, + needs_crossing=straddling.needs_crossing, + ising=straddling.ising, + direction=straddling.direction ) chunks[last_chunk_idx] = new_chunk odet_proxy = OdeState(N, 1, 1, 0) integrate_propagator_chunk!(propagators[last_chunk_idx], new_chunk, - ctrl, equil, ffit, intr, odet_proxy) + ctrl, equil, ffit, intr, odet_proxy) end n_dropped = 0 if last_chunk_idx < length(chunks) n_dropped = length(chunks) - last_chunk_idx - chunks = chunks[1:last_chunk_idx] + chunks = chunks[1:last_chunk_idx] propagators = propagators[1:last_chunk_idx] end if ctrl.verbose diff --git a/src/ForceFreeStates/Sing.jl b/src/ForceFreeStates/Sing.jl index 960530f6a..33694477a 100644 --- a/src/ForceFreeStates/Sing.jl +++ b/src/ForceFreeStates/Sing.jl @@ -123,9 +123,11 @@ function sing_lim!(intr::ForceFreeStatesInternal, ctrl::ForceFreeStatesControl, # strategy. Multi-n runs are not supported — the "outermost rational + dmlim/n" cutoff depends # on which n is used — and fall back to qhigh / psihigh truncation with a warning. if ctrl.set_psilim_via_dmlim && intr.nlow <= 0 - error("sing_lim!: set_psilim_via_dmlim = true requires a resolved toroidal range, but got intr.nlow=$(intr.nlow). " * - "Assign intr.nlow / intr.nhigh (from ctrl.nn_low / ctrl.nn_high) before calling sing_lim!, " * - "or set set_psilim_via_dmlim = false to truncate via qhigh / psihigh instead.") + error( + "sing_lim!: set_psilim_via_dmlim = true requires a resolved toroidal range, but got intr.nlow=$(intr.nlow). " * + "Assign intr.nlow / intr.nhigh (from ctrl.nn_low / ctrl.nn_high) before calling sing_lim!, " * + "or set set_psilim_via_dmlim = false to truncate via qhigh / psihigh instead." + ) elseif ctrl.set_psilim_via_dmlim && intr.nlow != intr.nhigh @warn "set_psilim_via_dmlim = true is ignored for multi-n runs (nn_low=$(intr.nlow), nn_high=$(intr.nhigh)); falling back to qhigh / psihigh truncation." elseif ctrl.set_psilim_via_dmlim diff --git a/src/ForcingTerms/BiotSavart.jl b/src/ForcingTerms/BiotSavart.jl index c03ab07c6..cd0bbb79e 100644 --- a/src/ForcingTerms/BiotSavart.jl +++ b/src/ForcingTerms/BiotSavart.jl @@ -45,27 +45,30 @@ Build contiguous segment-vector and midpoint arrays for strand `(j,k)` of coil s function precompute_segments(cs::CoilSet, j::Int, k::Int, current_nw::Float64) nsec = cs.nsec nseg = nsec - 1 - dlx = Vector{Float64}(undef, nseg) - dly = Vector{Float64}(undef, nseg) - dlz = Vector{Float64}(undef, nseg) + dlx = Vector{Float64}(undef, nseg) + dly = Vector{Float64}(undef, nseg) + dlz = Vector{Float64}(undef, nseg) midx = Vector{Float64}(undef, nseg) midy = Vector{Float64}(undef, nseg) midz = Vector{Float64}(undef, nseg) @inbounds for l in 1:nseg - x1 = cs.x[j, k, l]; x2 = cs.x[j, k, l+1] - y1 = cs.y[j, k, l]; y2 = cs.y[j, k, l+1] - z1 = cs.z[j, k, l]; z2 = cs.z[j, k, l+1] - dlx[l] = x2 - x1 - dly[l] = y2 - y1 - dlz[l] = z2 - z1 + x1 = cs.x[j, k, l] + x2 = cs.x[j, k, l+1] + y1 = cs.y[j, k, l] + y2 = cs.y[j, k, l+1] + z1 = cs.z[j, k, l] + z2 = cs.z[j, k, l+1] + dlx[l] = x2 - x1 + dly[l] = y2 - y1 + dlz[l] = z2 - z1 midx[l] = (x1 + x2) * 0.5 midy[l] = (y1 + y2) * 0.5 midz[l] = (z1 + z2) * 0.5 end return PrecomputedSegments(dlx, dly, dlz, midx, midy, midz, - MU0_OVER_4PI * current_nw, nseg) + MU0_OVER_4PI * current_nw, nseg) end """ @@ -74,15 +77,16 @@ end Accumulate the Biot-Savart contribution from one conductor strand onto observation point `i`. Uses midpoint-rule integration: each segment from point `l` to `l+1` contributes: - dB = μ₀/(4π) × current_nw × (dl⃗ × r⃗) / |r|³ +dB = μ₀/(4π) × current_nw × (dl⃗ × r⃗) / |r|³ where `r⃗` is the displacement from the segment midpoint to the observer. ## Arguments -- `Bx`, `By`, `Bz`: pre-allocated output arrays (Cartesian field, Tesla); updated in-place -- `i`: observation point index -- `obs_x/y/z`: observer Cartesian coordinates [m] -- `xs`, `ys`, `zs`: strand point coordinates [nsec], Cartesian [m] -- `current_nw`: effective current = I × nw [A⋅turns] + + - `Bx`, `By`, `Bz`: pre-allocated output arrays (Cartesian field, Tesla); updated in-place + - `i`: observation point index + - `obs_x/y/z`: observer Cartesian coordinates [m] + - `xs`, `ys`, `zs`: strand point coordinates [nsec], Cartesian [m] + - `current_nw`: effective current = I × nw [A⋅turns] """ function accumulate_strand_field!( Bx::AbstractVector{Float64}, @@ -98,7 +102,7 @@ function accumulate_strand_field!( nsec = length(xs) prefactor = MU0_OVER_4PI * current_nw - @inbounds for l in 1:(nsec - 1) + @inbounds for l in 1:(nsec-1) # Segment vector dl⃗ dlx = xs[l+1] - xs[l] dly = ys[l+1] - ys[l] @@ -109,7 +113,7 @@ function accumulate_strand_field!( ry = obs_y - (ys[l] + ys[l+1]) * 0.5 rz = obs_z - (zs[l] + zs[l+1]) * 0.5 - r2 = rx*rx + ry*ry + rz*rz + r2 = rx*rx + ry*ry + rz*rz r2 < BIOT_SAVART_MIN_DIST_SQ && continue # avoid singularity (observer on conductor) inv_r3 = prefactor / (r2 * sqrt(r2)) @@ -146,8 +150,8 @@ cache efficiency. r2 = rx*rx + ry*ry + rz*rz # Guard: zero contribution if observer is on conductor (avoids Inf/NaN) safe_r2 = ifelse(r2 < BIOT_SAVART_MIN_DIST_SQ, one(r2), r2) - scale = ifelse(r2 < BIOT_SAVART_MIN_DIST_SQ, zero(pf), pf) - inv_r3 = scale / (safe_r2 * sqrt(safe_r2)) + scale = ifelse(r2 < BIOT_SAVART_MIN_DIST_SQ, zero(pf), pf) + inv_r3 = scale / (safe_r2 * sqrt(safe_r2)) bx_acc += (seg.dly[l]*rz - seg.dlz[l]*ry) * inv_r3 by_acc += (seg.dlz[l]*rx - seg.dlx[l]*rz) * inv_r3 @@ -172,9 +176,10 @@ Performance: segment vectors and midpoints are pre-computed once outside the observation-point loop, then accessed from contiguous arrays in the inner kernel. ## Arguments -- `B_R`, `B_phi`, `B_Z`: output field arrays [Tesla], length `nobs`; overwritten -- `obs_R`, `obs_phi`, `obs_Z`: observation point cylindrical coordinates [m, rad, m] -- `coil_sets`: conductor geometry and current data + + - `B_R`, `B_phi`, `B_Z`: output field arrays [Tesla], length `nobs`; overwritten + - `obs_R`, `obs_phi`, `obs_Z`: observation point cylindrical coordinates [m, rad, m] + - `coil_sets`: conductor geometry and current data """ function compute_biot_savart_boundary!( B_R::AbstractVector{Float64}, @@ -204,8 +209,8 @@ function compute_biot_savart_boundary!( # Pre-compute sincos for cylindrical ↔ Cartesian conversion (avoids redundant trig) cos_phi = Vector{Float64}(undef, nobs) sin_phi = Vector{Float64}(undef, nobs) - obs_x = Vector{Float64}(undef, nobs) - obs_y = Vector{Float64}(undef, nobs) + obs_x = Vector{Float64}(undef, nobs) + obs_y = Vector{Float64}(undef, nobs) @inbounds for i in 1:nobs sp, cp = sincos(obs_phi[i]) @@ -218,7 +223,9 @@ function compute_biot_savart_boundary!( # Each thread writes exclusively to its own index i — no synchronization needed Threads.@threads for i in 1:nobs @inbounds begin - ox = obs_x[i]; oy = obs_y[i]; oz = obs_Z[i] + ox = obs_x[i] + oy = obs_y[i] + oz = obs_Z[i] bx_total = 0.0 by_total = 0.0 bz_total = 0.0 @@ -233,9 +240,9 @@ function compute_biot_savart_boundary!( # Convert Cartesian → cylindrical in-place cp = cos_phi[i] sp = sin_phi[i] - B_R[i] = bx_total * cp + by_total * sp + B_R[i] = bx_total * cp + by_total * sp B_phi[i] = -bx_total * sp + by_total * cp - B_Z[i] = bz_total + B_Z[i] = bz_total end end end diff --git a/src/ForcingTerms/CoilGeometry.jl b/src/ForcingTerms/CoilGeometry.jl index b2d19ab21..477502927 100644 --- a/src/ForcingTerms/CoilGeometry.jl +++ b/src/ForcingTerms/CoilGeometry.jl @@ -265,7 +265,7 @@ function read_coil_dat(filepath::String) for l in 1:nsec # Skip blank/comment lines between data rows while row <= length(lines) && - (isempty(strip(lines[row])) || startswith(strip(lines[row]), "#")) + (isempty(strip(lines[row])) || startswith(strip(lines[row]), "#")) row += 1 end row > length(lines) && error( @@ -402,10 +402,12 @@ function make_window_pane_standoff(equil; standoff::Real, poloidal_angle::Real, # boundary along the normal is standoff - half*|sin(tilt)| — the tilt tips the legs toward the # surface, while tangential displacement leaves the normal clearance unchanged. clearance = standoff - half * abs(sin(deg2rad(poloidal_tilt))) - clearance > 0 || error("make_window_pane_standoff: coil intersects the plasma boundary " * - "(standoff=$standoff, poloidal_length=$poloidal_length, poloidal_tilt=$poloidal_tilt); " * - "an external coil must lie outside the control surface — increase standoff or reduce " * - "poloidal_length/poloidal_tilt") + clearance > 0 || error( + "make_window_pane_standoff: coil intersects the plasma boundary " * + "(standoff=$standoff, poloidal_length=$poloidal_length, poloidal_tilt=$poloidal_tilt); " * + "an external coil must lie outside the control surface — increase standoff or reduce " * + "poloidal_length/poloidal_tilt" + ) c1 = [Rc - half * uR, Zc - half * uZ] c2 = [Rc + half * uR, Zc + half * uZ] diff --git a/src/ForcingTerms/coil_geometries/jet_ex_mid.dat b/src/ForcingTerms/coil_geometries/jet_ex_mid.dat index ea2549ad3..639e8ca41 100644 --- a/src/ForcingTerms/coil_geometries/jet_ex_mid.dat +++ b/src/ForcingTerms/coil_geometries/jet_ex_mid.dat @@ -1,169 +1,169 @@ - 4 1 42 1.00 - 5.5000e+00 0.0000e+00 3.0900e+00 - 5.4795e+00 4.7404e-01 3.0900e+00 - 5.4183e+00 9.4456e-01 3.0900e+00 - 5.3167e+00 1.4080e+00 3.0900e+00 - 5.1756e+00 1.8611e+00 3.0900e+00 - 4.9959e+00 2.3002e+00 3.0900e+00 - 4.7791e+00 2.7222e+00 3.0900e+00 - 4.5266e+00 3.1240e+00 3.0900e+00 - 4.2405e+00 3.5025e+00 3.0900e+00 - 3.9229e+00 3.8550e+00 3.0900e+00 - 3.5760e+00 4.1788e+00 3.0900e+00 - 3.2025e+00 4.4714e+00 3.0900e+00 - 2.8052e+00 4.7308e+00 3.0900e+00 - 2.3870e+00 4.9550e+00 3.0900e+00 - 1.9511e+00 5.1423e+00 3.0900e+00 - 1.5006e+00 5.2913e+00 3.0900e+00 - 1.0390e+00 5.4010e+00 3.0900e+00 - 5.6960e-01 5.4704e+00 3.0900e+00 - 9.5988e-02 5.4992e+00 3.0900e+00 - 9.5988e-02 5.4992e+00 3.0900e+00 - 9.5988e-02 5.4992e+00 1.5700e+00 - 9.5988e-02 5.4992e+00 5.0000e-02 - 9.5988e-02 5.4992e+00 -1.4700e+00 - 9.5988e-02 5.4992e+00 -2.9900e+00 - 7.0430e-01 5.4547e+00 -2.9900e+00 - 1.3039e+00 5.3432e+00 -2.9900e+00 - 1.8876e+00 5.1660e+00 -2.9900e+00 - 2.4479e+00 4.9252e+00 -2.9900e+00 - 2.9782e+00 4.6239e+00 -2.9900e+00 - 3.4719e+00 4.2657e+00 -2.9900e+00 - 3.9229e+00 3.8550e+00 -2.9900e+00 - 4.3256e+00 3.3969e+00 -2.9900e+00 - 4.6751e+00 2.8971e+00 -2.9900e+00 - 4.9672e+00 2.3616e+00 -2.9900e+00 - 5.1981e+00 1.7971e+00 -2.9900e+00 - 5.3651e+00 1.2105e+00 -2.9900e+00 - 5.4662e+00 6.0899e-01 -2.9900e+00 - 5.5000e+00 0.0000e+00 -2.9900e+00 - 5.5000e+00 0.0000e+00 -1.4700e+00 - 5.5000e+00 0.0000e+00 5.0000e-02 - 5.5000e+00 0.0000e+00 1.5700e+00 - 5.5000e+00 0.0000e+00 3.0900e+00 - 3.3678e-16 5.5000e+00 3.0900e+00 - -4.7404e-01 5.4795e+00 3.0900e+00 - -9.4456e-01 5.4183e+00 3.0900e+00 - -1.4080e+00 5.3167e+00 3.0900e+00 - -1.8611e+00 5.1756e+00 3.0900e+00 - -2.3002e+00 4.9959e+00 3.0900e+00 - -2.7222e+00 4.7791e+00 3.0900e+00 - -3.1240e+00 4.5266e+00 3.0900e+00 - -3.5025e+00 4.2405e+00 3.0900e+00 - -3.8550e+00 3.9229e+00 3.0900e+00 - -4.1788e+00 3.5760e+00 3.0900e+00 - -4.4714e+00 3.2025e+00 3.0900e+00 - -4.7308e+00 2.8052e+00 3.0900e+00 - -4.9550e+00 2.3870e+00 3.0900e+00 - -5.1423e+00 1.9511e+00 3.0900e+00 - -5.2913e+00 1.5006e+00 3.0900e+00 - -5.4010e+00 1.0390e+00 3.0900e+00 - -5.4704e+00 5.6960e-01 3.0900e+00 - -5.4992e+00 9.5988e-02 3.0900e+00 - -5.4992e+00 9.5988e-02 3.0900e+00 - -5.4992e+00 9.5988e-02 1.5700e+00 - -5.4992e+00 9.5988e-02 5.0000e-02 - -5.4992e+00 9.5988e-02 -1.4700e+00 - -5.4992e+00 9.5988e-02 -2.9900e+00 - -5.4547e+00 7.0430e-01 -2.9900e+00 - -5.3432e+00 1.3039e+00 -2.9900e+00 - -5.1660e+00 1.8876e+00 -2.9900e+00 - -4.9252e+00 2.4479e+00 -2.9900e+00 - -4.6239e+00 2.9782e+00 -2.9900e+00 - -4.2657e+00 3.4719e+00 -2.9900e+00 - -3.8550e+00 3.9229e+00 -2.9900e+00 - -3.3969e+00 4.3256e+00 -2.9900e+00 - -2.8971e+00 4.6751e+00 -2.9900e+00 - -2.3616e+00 4.9672e+00 -2.9900e+00 - -1.7971e+00 5.1981e+00 -2.9900e+00 - -1.2105e+00 5.3651e+00 -2.9900e+00 - -6.0899e-01 5.4662e+00 -2.9900e+00 - 3.3678e-16 5.5000e+00 -2.9900e+00 - 3.3678e-16 5.5000e+00 -1.4700e+00 - 3.3678e-16 5.5000e+00 5.0000e-02 - 3.3678e-16 5.5000e+00 1.5700e+00 - 3.3678e-16 5.5000e+00 3.0900e+00 - -5.5000e+00 6.7356e-16 3.0900e+00 - -5.4795e+00 -4.7404e-01 3.0900e+00 - -5.4183e+00 -9.4456e-01 3.0900e+00 - -5.3167e+00 -1.4080e+00 3.0900e+00 - -5.1756e+00 -1.8611e+00 3.0900e+00 - -4.9959e+00 -2.3002e+00 3.0900e+00 - -4.7791e+00 -2.7222e+00 3.0900e+00 - -4.5266e+00 -3.1240e+00 3.0900e+00 - -4.2405e+00 -3.5025e+00 3.0900e+00 - -3.9229e+00 -3.8550e+00 3.0900e+00 - -3.5760e+00 -4.1788e+00 3.0900e+00 - -3.2025e+00 -4.4714e+00 3.0900e+00 - -2.8052e+00 -4.7308e+00 3.0900e+00 - -2.3870e+00 -4.9550e+00 3.0900e+00 - -1.9511e+00 -5.1423e+00 3.0900e+00 - -1.5006e+00 -5.2913e+00 3.0900e+00 - -1.0390e+00 -5.4010e+00 3.0900e+00 - -5.6960e-01 -5.4704e+00 3.0900e+00 - -9.5988e-02 -5.4992e+00 3.0900e+00 - -9.5988e-02 -5.4992e+00 3.0900e+00 - -9.5988e-02 -5.4992e+00 1.5700e+00 - -9.5988e-02 -5.4992e+00 5.0000e-02 - -9.5988e-02 -5.4992e+00 -1.4700e+00 - -9.5988e-02 -5.4992e+00 -2.9900e+00 - -7.0430e-01 -5.4547e+00 -2.9900e+00 - -1.3039e+00 -5.3432e+00 -2.9900e+00 - -1.8876e+00 -5.1660e+00 -2.9900e+00 - -2.4479e+00 -4.9252e+00 -2.9900e+00 - -2.9782e+00 -4.6239e+00 -2.9900e+00 - -3.4719e+00 -4.2657e+00 -2.9900e+00 - -3.9229e+00 -3.8550e+00 -2.9900e+00 - -4.3256e+00 -3.3969e+00 -2.9900e+00 - -4.6751e+00 -2.8971e+00 -2.9900e+00 - -4.9672e+00 -2.3616e+00 -2.9900e+00 - -5.1981e+00 -1.7971e+00 -2.9900e+00 - -5.3651e+00 -1.2105e+00 -2.9900e+00 - -5.4662e+00 -6.0899e-01 -2.9900e+00 - -5.5000e+00 6.7356e-16 -2.9900e+00 - -5.5000e+00 6.7356e-16 -1.4700e+00 - -5.5000e+00 6.7356e-16 5.0000e-02 - -5.5000e+00 6.7356e-16 1.5700e+00 - -5.5000e+00 6.7356e-16 3.0900e+00 - -1.0103e-15 -5.5000e+00 3.0900e+00 - 4.7404e-01 -5.4795e+00 3.0900e+00 - 9.4456e-01 -5.4183e+00 3.0900e+00 - 1.4080e+00 -5.3167e+00 3.0900e+00 - 1.8611e+00 -5.1756e+00 3.0900e+00 - 2.3002e+00 -4.9959e+00 3.0900e+00 - 2.7222e+00 -4.7791e+00 3.0900e+00 - 3.1240e+00 -4.5266e+00 3.0900e+00 - 3.5025e+00 -4.2405e+00 3.0900e+00 - 3.8550e+00 -3.9229e+00 3.0900e+00 - 4.1788e+00 -3.5760e+00 3.0900e+00 - 4.4714e+00 -3.2025e+00 3.0900e+00 - 4.7308e+00 -2.8052e+00 3.0900e+00 - 4.9550e+00 -2.3870e+00 3.0900e+00 - 5.1423e+00 -1.9511e+00 3.0900e+00 - 5.2913e+00 -1.5006e+00 3.0900e+00 - 5.4010e+00 -1.0390e+00 3.0900e+00 - 5.4704e+00 -5.6960e-01 3.0900e+00 - 5.4992e+00 -9.5988e-02 3.0900e+00 - 5.4992e+00 -9.5988e-02 3.0900e+00 - 5.4992e+00 -9.5988e-02 1.5700e+00 - 5.4992e+00 -9.5988e-02 5.0000e-02 - 5.4992e+00 -9.5988e-02 -1.4700e+00 - 5.4992e+00 -9.5988e-02 -2.9900e+00 - 5.4547e+00 -7.0430e-01 -2.9900e+00 - 5.3432e+00 -1.3039e+00 -2.9900e+00 - 5.1660e+00 -1.8876e+00 -2.9900e+00 - 4.9252e+00 -2.4479e+00 -2.9900e+00 - 4.6239e+00 -2.9782e+00 -2.9900e+00 - 4.2657e+00 -3.4719e+00 -2.9900e+00 - 3.8550e+00 -3.9229e+00 -2.9900e+00 - 3.3969e+00 -4.3256e+00 -2.9900e+00 - 2.8971e+00 -4.6751e+00 -2.9900e+00 - 2.3616e+00 -4.9672e+00 -2.9900e+00 - 1.7971e+00 -5.1981e+00 -2.9900e+00 - 1.2105e+00 -5.3651e+00 -2.9900e+00 - 6.0899e-01 -5.4662e+00 -2.9900e+00 - -1.0103e-15 -5.5000e+00 -2.9900e+00 - -1.0103e-15 -5.5000e+00 -1.4700e+00 - -1.0103e-15 -5.5000e+00 5.0000e-02 - -1.0103e-15 -5.5000e+00 1.5700e+00 - -1.0103e-15 -5.5000e+00 3.0900e+00 + 4 1 42 1.00 + 5.5000e+00 0.0000e+00 3.0900e+00 + 5.4795e+00 4.7404e-01 3.0900e+00 + 5.4183e+00 9.4456e-01 3.0900e+00 + 5.3167e+00 1.4080e+00 3.0900e+00 + 5.1756e+00 1.8611e+00 3.0900e+00 + 4.9959e+00 2.3002e+00 3.0900e+00 + 4.7791e+00 2.7222e+00 3.0900e+00 + 4.5266e+00 3.1240e+00 3.0900e+00 + 4.2405e+00 3.5025e+00 3.0900e+00 + 3.9229e+00 3.8550e+00 3.0900e+00 + 3.5760e+00 4.1788e+00 3.0900e+00 + 3.2025e+00 4.4714e+00 3.0900e+00 + 2.8052e+00 4.7308e+00 3.0900e+00 + 2.3870e+00 4.9550e+00 3.0900e+00 + 1.9511e+00 5.1423e+00 3.0900e+00 + 1.5006e+00 5.2913e+00 3.0900e+00 + 1.0390e+00 5.4010e+00 3.0900e+00 + 5.6960e-01 5.4704e+00 3.0900e+00 + 9.5988e-02 5.4992e+00 3.0900e+00 + 9.5988e-02 5.4992e+00 3.0900e+00 + 9.5988e-02 5.4992e+00 1.5700e+00 + 9.5988e-02 5.4992e+00 5.0000e-02 + 9.5988e-02 5.4992e+00 -1.4700e+00 + 9.5988e-02 5.4992e+00 -2.9900e+00 + 7.0430e-01 5.4547e+00 -2.9900e+00 + 1.3039e+00 5.3432e+00 -2.9900e+00 + 1.8876e+00 5.1660e+00 -2.9900e+00 + 2.4479e+00 4.9252e+00 -2.9900e+00 + 2.9782e+00 4.6239e+00 -2.9900e+00 + 3.4719e+00 4.2657e+00 -2.9900e+00 + 3.9229e+00 3.8550e+00 -2.9900e+00 + 4.3256e+00 3.3969e+00 -2.9900e+00 + 4.6751e+00 2.8971e+00 -2.9900e+00 + 4.9672e+00 2.3616e+00 -2.9900e+00 + 5.1981e+00 1.7971e+00 -2.9900e+00 + 5.3651e+00 1.2105e+00 -2.9900e+00 + 5.4662e+00 6.0899e-01 -2.9900e+00 + 5.5000e+00 0.0000e+00 -2.9900e+00 + 5.5000e+00 0.0000e+00 -1.4700e+00 + 5.5000e+00 0.0000e+00 5.0000e-02 + 5.5000e+00 0.0000e+00 1.5700e+00 + 5.5000e+00 0.0000e+00 3.0900e+00 + 3.3678e-16 5.5000e+00 3.0900e+00 + -4.7404e-01 5.4795e+00 3.0900e+00 + -9.4456e-01 5.4183e+00 3.0900e+00 + -1.4080e+00 5.3167e+00 3.0900e+00 + -1.8611e+00 5.1756e+00 3.0900e+00 + -2.3002e+00 4.9959e+00 3.0900e+00 + -2.7222e+00 4.7791e+00 3.0900e+00 + -3.1240e+00 4.5266e+00 3.0900e+00 + -3.5025e+00 4.2405e+00 3.0900e+00 + -3.8550e+00 3.9229e+00 3.0900e+00 + -4.1788e+00 3.5760e+00 3.0900e+00 + -4.4714e+00 3.2025e+00 3.0900e+00 + -4.7308e+00 2.8052e+00 3.0900e+00 + -4.9550e+00 2.3870e+00 3.0900e+00 + -5.1423e+00 1.9511e+00 3.0900e+00 + -5.2913e+00 1.5006e+00 3.0900e+00 + -5.4010e+00 1.0390e+00 3.0900e+00 + -5.4704e+00 5.6960e-01 3.0900e+00 + -5.4992e+00 9.5988e-02 3.0900e+00 + -5.4992e+00 9.5988e-02 3.0900e+00 + -5.4992e+00 9.5988e-02 1.5700e+00 + -5.4992e+00 9.5988e-02 5.0000e-02 + -5.4992e+00 9.5988e-02 -1.4700e+00 + -5.4992e+00 9.5988e-02 -2.9900e+00 + -5.4547e+00 7.0430e-01 -2.9900e+00 + -5.3432e+00 1.3039e+00 -2.9900e+00 + -5.1660e+00 1.8876e+00 -2.9900e+00 + -4.9252e+00 2.4479e+00 -2.9900e+00 + -4.6239e+00 2.9782e+00 -2.9900e+00 + -4.2657e+00 3.4719e+00 -2.9900e+00 + -3.8550e+00 3.9229e+00 -2.9900e+00 + -3.3969e+00 4.3256e+00 -2.9900e+00 + -2.8971e+00 4.6751e+00 -2.9900e+00 + -2.3616e+00 4.9672e+00 -2.9900e+00 + -1.7971e+00 5.1981e+00 -2.9900e+00 + -1.2105e+00 5.3651e+00 -2.9900e+00 + -6.0899e-01 5.4662e+00 -2.9900e+00 + 3.3678e-16 5.5000e+00 -2.9900e+00 + 3.3678e-16 5.5000e+00 -1.4700e+00 + 3.3678e-16 5.5000e+00 5.0000e-02 + 3.3678e-16 5.5000e+00 1.5700e+00 + 3.3678e-16 5.5000e+00 3.0900e+00 + -5.5000e+00 6.7356e-16 3.0900e+00 + -5.4795e+00 -4.7404e-01 3.0900e+00 + -5.4183e+00 -9.4456e-01 3.0900e+00 + -5.3167e+00 -1.4080e+00 3.0900e+00 + -5.1756e+00 -1.8611e+00 3.0900e+00 + -4.9959e+00 -2.3002e+00 3.0900e+00 + -4.7791e+00 -2.7222e+00 3.0900e+00 + -4.5266e+00 -3.1240e+00 3.0900e+00 + -4.2405e+00 -3.5025e+00 3.0900e+00 + -3.9229e+00 -3.8550e+00 3.0900e+00 + -3.5760e+00 -4.1788e+00 3.0900e+00 + -3.2025e+00 -4.4714e+00 3.0900e+00 + -2.8052e+00 -4.7308e+00 3.0900e+00 + -2.3870e+00 -4.9550e+00 3.0900e+00 + -1.9511e+00 -5.1423e+00 3.0900e+00 + -1.5006e+00 -5.2913e+00 3.0900e+00 + -1.0390e+00 -5.4010e+00 3.0900e+00 + -5.6960e-01 -5.4704e+00 3.0900e+00 + -9.5988e-02 -5.4992e+00 3.0900e+00 + -9.5988e-02 -5.4992e+00 3.0900e+00 + -9.5988e-02 -5.4992e+00 1.5700e+00 + -9.5988e-02 -5.4992e+00 5.0000e-02 + -9.5988e-02 -5.4992e+00 -1.4700e+00 + -9.5988e-02 -5.4992e+00 -2.9900e+00 + -7.0430e-01 -5.4547e+00 -2.9900e+00 + -1.3039e+00 -5.3432e+00 -2.9900e+00 + -1.8876e+00 -5.1660e+00 -2.9900e+00 + -2.4479e+00 -4.9252e+00 -2.9900e+00 + -2.9782e+00 -4.6239e+00 -2.9900e+00 + -3.4719e+00 -4.2657e+00 -2.9900e+00 + -3.9229e+00 -3.8550e+00 -2.9900e+00 + -4.3256e+00 -3.3969e+00 -2.9900e+00 + -4.6751e+00 -2.8971e+00 -2.9900e+00 + -4.9672e+00 -2.3616e+00 -2.9900e+00 + -5.1981e+00 -1.7971e+00 -2.9900e+00 + -5.3651e+00 -1.2105e+00 -2.9900e+00 + -5.4662e+00 -6.0899e-01 -2.9900e+00 + -5.5000e+00 6.7356e-16 -2.9900e+00 + -5.5000e+00 6.7356e-16 -1.4700e+00 + -5.5000e+00 6.7356e-16 5.0000e-02 + -5.5000e+00 6.7356e-16 1.5700e+00 + -5.5000e+00 6.7356e-16 3.0900e+00 + -1.0103e-15 -5.5000e+00 3.0900e+00 + 4.7404e-01 -5.4795e+00 3.0900e+00 + 9.4456e-01 -5.4183e+00 3.0900e+00 + 1.4080e+00 -5.3167e+00 3.0900e+00 + 1.8611e+00 -5.1756e+00 3.0900e+00 + 2.3002e+00 -4.9959e+00 3.0900e+00 + 2.7222e+00 -4.7791e+00 3.0900e+00 + 3.1240e+00 -4.5266e+00 3.0900e+00 + 3.5025e+00 -4.2405e+00 3.0900e+00 + 3.8550e+00 -3.9229e+00 3.0900e+00 + 4.1788e+00 -3.5760e+00 3.0900e+00 + 4.4714e+00 -3.2025e+00 3.0900e+00 + 4.7308e+00 -2.8052e+00 3.0900e+00 + 4.9550e+00 -2.3870e+00 3.0900e+00 + 5.1423e+00 -1.9511e+00 3.0900e+00 + 5.2913e+00 -1.5006e+00 3.0900e+00 + 5.4010e+00 -1.0390e+00 3.0900e+00 + 5.4704e+00 -5.6960e-01 3.0900e+00 + 5.4992e+00 -9.5988e-02 3.0900e+00 + 5.4992e+00 -9.5988e-02 3.0900e+00 + 5.4992e+00 -9.5988e-02 1.5700e+00 + 5.4992e+00 -9.5988e-02 5.0000e-02 + 5.4992e+00 -9.5988e-02 -1.4700e+00 + 5.4992e+00 -9.5988e-02 -2.9900e+00 + 5.4547e+00 -7.0430e-01 -2.9900e+00 + 5.3432e+00 -1.3039e+00 -2.9900e+00 + 5.1660e+00 -1.8876e+00 -2.9900e+00 + 4.9252e+00 -2.4479e+00 -2.9900e+00 + 4.6239e+00 -2.9782e+00 -2.9900e+00 + 4.2657e+00 -3.4719e+00 -2.9900e+00 + 3.8550e+00 -3.9229e+00 -2.9900e+00 + 3.3969e+00 -4.3256e+00 -2.9900e+00 + 2.8971e+00 -4.6751e+00 -2.9900e+00 + 2.3616e+00 -4.9672e+00 -2.9900e+00 + 1.7971e+00 -5.1981e+00 -2.9900e+00 + 1.2105e+00 -5.3651e+00 -2.9900e+00 + 6.0899e-01 -5.4662e+00 -2.9900e+00 + -1.0103e-15 -5.5000e+00 -2.9900e+00 + -1.0103e-15 -5.5000e+00 -1.4700e+00 + -1.0103e-15 -5.5000e+00 5.0000e-02 + -1.0103e-15 -5.5000e+00 1.5700e+00 + -1.0103e-15 -5.5000e+00 3.0900e+00 diff --git a/src/ForcingTerms/coil_geometries/jtext_l.dat b/src/ForcingTerms/coil_geometries/jtext_l.dat index b744bedd8..476b55451 100644 --- a/src/ForcingTerms/coil_geometries/jtext_l.dat +++ b/src/ForcingTerms/coil_geometries/jtext_l.dat @@ -1,81 +1,81 @@ - 4 1 20 1.00 - 1.2000e+00 1.6000e-02 -3.9800e-01 - 1.2000e+00 1.6000e-02 -3.3300e-01 - 1.2000e+00 2.5370e-02 -3.1000e-01 - 1.2000e+00 4.8000e-02 -3.0100e-01 - 1.2000e+00 1.3200e-01 -3.0100e-01 - 1.1880e+00 1.5800e-01 -3.0100e-01 - 1.1620e+00 1.6300e-01 -3.0100e-01 - 7.9400e-01 9.0000e-02 -3.0100e-01 - 7.7500e-01 7.9000e-02 -3.0100e-01 - 7.6800e-01 5.8000e-02 -3.0100e-01 - 7.6800e-01 -6.2000e-02 -3.0100e-01 - 7.7500e-01 -8.3000e-02 -3.0100e-01 - 7.9500e-01 -9.4000e-02 -3.0100e-01 - 1.1620e+00 -1.6700e-01 -3.0100e-01 - 1.1880e+00 -1.6000e-01 -3.0100e-01 - 1.2000e+00 -1.3500e-01 -3.0100e-01 - 1.2000e+00 -5.0000e-02 -3.0100e-01 - 1.2000e+00 -2.5370e-02 -3.1000e-01 - 1.2000e+00 -1.6000e-02 -3.3300e-01 - 1.2000e+00 -1.6000e-02 -3.9800e-01 - 1.6000e-02 1.2000e+00 -3.9800e-01 - 1.6000e-02 1.2000e+00 -3.3300e-01 - 2.5370e-02 1.2000e+00 -3.1000e-01 - 4.8000e-02 1.2000e+00 -3.0100e-01 - 1.3200e-01 1.2000e+00 -3.0100e-01 - 1.5800e-01 1.1880e+00 -3.0100e-01 - 1.6300e-01 1.1620e+00 -3.0100e-01 - 9.0000e-02 7.9400e-01 -3.0100e-01 - 7.9000e-02 7.7500e-01 -3.0100e-01 - 5.8000e-02 7.6800e-01 -3.0100e-01 - -6.2000e-02 7.6800e-01 -3.0100e-01 - -8.3000e-02 7.7500e-01 -3.0100e-01 - -9.4000e-02 7.9500e-01 -3.0100e-01 - -1.6700e-01 1.1620e+00 -3.0100e-01 - -1.6000e-01 1.1880e+00 -3.0100e-01 - -1.3500e-01 1.2000e+00 -3.0100e-01 - -5.0000e-02 1.2000e+00 -3.0100e-01 - -2.5370e-02 1.2000e+00 -3.1000e-01 - -1.6000e-02 1.2000e+00 -3.3300e-01 - -1.6000e-02 1.2000e+00 -3.9800e-01 - -7.7650e-01 1.6000e-02 -3.9800e-01 - -7.7650e-01 1.6000e-02 -3.3300e-01 - -7.7650e-01 2.5370e-02 -3.1000e-01 - -7.7650e-01 4.8000e-02 -3.0100e-01 - -7.7650e-01 6.1000e-02 -3.0100e-01 - -7.8350e-01 8.2000e-02 -3.0100e-01 - -8.0250e-01 9.3000e-02 -3.0100e-01 - -1.2015e+00 1.7100e-01 -3.0100e-01 - -1.2275e+00 1.6500e-01 -3.0100e-01 - -1.2395e+00 1.4100e-01 -3.0100e-01 - -1.2395e+00 -1.4100e-01 -3.0100e-01 - -1.2275e+00 -1.6600e-01 -3.0100e-01 - -1.2015e+00 -1.7200e-01 -3.0100e-01 - -8.0250e-01 -9.3000e-02 -3.0100e-01 - -7.8350e-01 -8.2000e-02 -3.0100e-01 - -7.7650e-01 -6.2000e-02 -3.0100e-01 - -7.7650e-01 -4.9000e-02 -3.0100e-01 - -7.7650e-01 -2.5370e-02 -3.1000e-01 - -7.7650e-01 -1.6000e-02 -3.3300e-01 - -7.7650e-01 -1.6000e-02 -3.9800e-01 - 1.6000e-02 -7.7650e-01 -3.9800e-01 - 1.6000e-02 -7.7650e-01 -3.3300e-01 - 2.5370e-02 -7.7650e-01 -3.1000e-01 - 4.8000e-02 -7.7650e-01 -3.0100e-01 - 6.1000e-02 -7.7650e-01 -3.0100e-01 - 8.2000e-02 -7.8350e-01 -3.0100e-01 - 9.3000e-02 -8.0250e-01 -3.0100e-01 - 1.7100e-01 -1.2015e+00 -3.0100e-01 - 1.6500e-01 -1.2275e+00 -3.0100e-01 - 1.4100e-01 -1.2395e+00 -3.0100e-01 - -1.4100e-01 -1.2395e+00 -3.0100e-01 - -1.6600e-01 -1.2275e+00 -3.0100e-01 - -1.7200e-01 -1.2015e+00 -3.0100e-01 - -9.3000e-02 -8.0250e-01 -3.0100e-01 - -8.2000e-02 -7.8350e-01 -3.0100e-01 - -6.2000e-02 -7.7650e-01 -3.0100e-01 - -4.9000e-02 -7.7650e-01 -3.0100e-01 - -2.5370e-02 -7.7650e-01 -3.1000e-01 - -1.6000e-02 -7.7650e-01 -3.3300e-01 - -1.6000e-02 -7.7650e-01 -3.9800e-01 + 4 1 20 1.00 + 1.2000e+00 1.6000e-02 -3.9800e-01 + 1.2000e+00 1.6000e-02 -3.3300e-01 + 1.2000e+00 2.5370e-02 -3.1000e-01 + 1.2000e+00 4.8000e-02 -3.0100e-01 + 1.2000e+00 1.3200e-01 -3.0100e-01 + 1.1880e+00 1.5800e-01 -3.0100e-01 + 1.1620e+00 1.6300e-01 -3.0100e-01 + 7.9400e-01 9.0000e-02 -3.0100e-01 + 7.7500e-01 7.9000e-02 -3.0100e-01 + 7.6800e-01 5.8000e-02 -3.0100e-01 + 7.6800e-01 -6.2000e-02 -3.0100e-01 + 7.7500e-01 -8.3000e-02 -3.0100e-01 + 7.9500e-01 -9.4000e-02 -3.0100e-01 + 1.1620e+00 -1.6700e-01 -3.0100e-01 + 1.1880e+00 -1.6000e-01 -3.0100e-01 + 1.2000e+00 -1.3500e-01 -3.0100e-01 + 1.2000e+00 -5.0000e-02 -3.0100e-01 + 1.2000e+00 -2.5370e-02 -3.1000e-01 + 1.2000e+00 -1.6000e-02 -3.3300e-01 + 1.2000e+00 -1.6000e-02 -3.9800e-01 + 1.6000e-02 1.2000e+00 -3.9800e-01 + 1.6000e-02 1.2000e+00 -3.3300e-01 + 2.5370e-02 1.2000e+00 -3.1000e-01 + 4.8000e-02 1.2000e+00 -3.0100e-01 + 1.3200e-01 1.2000e+00 -3.0100e-01 + 1.5800e-01 1.1880e+00 -3.0100e-01 + 1.6300e-01 1.1620e+00 -3.0100e-01 + 9.0000e-02 7.9400e-01 -3.0100e-01 + 7.9000e-02 7.7500e-01 -3.0100e-01 + 5.8000e-02 7.6800e-01 -3.0100e-01 + -6.2000e-02 7.6800e-01 -3.0100e-01 + -8.3000e-02 7.7500e-01 -3.0100e-01 + -9.4000e-02 7.9500e-01 -3.0100e-01 + -1.6700e-01 1.1620e+00 -3.0100e-01 + -1.6000e-01 1.1880e+00 -3.0100e-01 + -1.3500e-01 1.2000e+00 -3.0100e-01 + -5.0000e-02 1.2000e+00 -3.0100e-01 + -2.5370e-02 1.2000e+00 -3.1000e-01 + -1.6000e-02 1.2000e+00 -3.3300e-01 + -1.6000e-02 1.2000e+00 -3.9800e-01 + -7.7650e-01 1.6000e-02 -3.9800e-01 + -7.7650e-01 1.6000e-02 -3.3300e-01 + -7.7650e-01 2.5370e-02 -3.1000e-01 + -7.7650e-01 4.8000e-02 -3.0100e-01 + -7.7650e-01 6.1000e-02 -3.0100e-01 + -7.8350e-01 8.2000e-02 -3.0100e-01 + -8.0250e-01 9.3000e-02 -3.0100e-01 + -1.2015e+00 1.7100e-01 -3.0100e-01 + -1.2275e+00 1.6500e-01 -3.0100e-01 + -1.2395e+00 1.4100e-01 -3.0100e-01 + -1.2395e+00 -1.4100e-01 -3.0100e-01 + -1.2275e+00 -1.6600e-01 -3.0100e-01 + -1.2015e+00 -1.7200e-01 -3.0100e-01 + -8.0250e-01 -9.3000e-02 -3.0100e-01 + -7.8350e-01 -8.2000e-02 -3.0100e-01 + -7.7650e-01 -6.2000e-02 -3.0100e-01 + -7.7650e-01 -4.9000e-02 -3.0100e-01 + -7.7650e-01 -2.5370e-02 -3.1000e-01 + -7.7650e-01 -1.6000e-02 -3.3300e-01 + -7.7650e-01 -1.6000e-02 -3.9800e-01 + 1.6000e-02 -7.7650e-01 -3.9800e-01 + 1.6000e-02 -7.7650e-01 -3.3300e-01 + 2.5370e-02 -7.7650e-01 -3.1000e-01 + 4.8000e-02 -7.7650e-01 -3.0100e-01 + 6.1000e-02 -7.7650e-01 -3.0100e-01 + 8.2000e-02 -7.8350e-01 -3.0100e-01 + 9.3000e-02 -8.0250e-01 -3.0100e-01 + 1.7100e-01 -1.2015e+00 -3.0100e-01 + 1.6500e-01 -1.2275e+00 -3.0100e-01 + 1.4100e-01 -1.2395e+00 -3.0100e-01 + -1.4100e-01 -1.2395e+00 -3.0100e-01 + -1.6600e-01 -1.2275e+00 -3.0100e-01 + -1.7200e-01 -1.2015e+00 -3.0100e-01 + -9.3000e-02 -8.0250e-01 -3.0100e-01 + -8.2000e-02 -7.8350e-01 -3.0100e-01 + -6.2000e-02 -7.7650e-01 -3.0100e-01 + -4.9000e-02 -7.7650e-01 -3.0100e-01 + -2.5370e-02 -7.7650e-01 -3.1000e-01 + -1.6000e-02 -7.7650e-01 -3.3300e-01 + -1.6000e-02 -7.7650e-01 -3.9800e-01 diff --git a/src/ForcingTerms/coil_geometries/jtext_m.dat b/src/ForcingTerms/coil_geometries/jtext_m.dat index f211a2d1e..9defc821f 100644 --- a/src/ForcingTerms/coil_geometries/jtext_m.dat +++ b/src/ForcingTerms/coil_geometries/jtext_m.dat @@ -1,81 +1,81 @@ - 4 1 20 1.00 - 1.3300e+00 1.6000e-02 3.5600e-01 - 1.2830e+00 1.6000e-02 2.6500e-01 - 1.3065e+00 2.5370e-02 2.4300e-01 - 1.3300e+00 4.8000e-02 2.1100e-01 - 1.3300e+00 1.3200e-01 2.1100e-01 - 1.3300e+00 1.5800e-01 2.0200e-01 - 1.3300e+00 1.6300e-01 1.7900e-01 - 1.3300e+00 9.0000e-02 -2.0600e-01 - 1.3300e+00 7.9000e-02 -2.2900e-01 - 1.3300e+00 5.8000e-02 -2.3800e-01 - 1.3300e+00 -6.2000e-02 -2.3800e-01 - 1.3300e+00 -8.3000e-02 -2.2900e-01 - 1.3300e+00 -9.4000e-02 -2.0600e-01 - 1.3300e+00 -1.6700e-01 1.7900e-01 - 1.3300e+00 -1.6000e-01 2.0200e-01 - 1.3300e+00 -1.3500e-01 2.1100e-01 - 1.3300e+00 -5.0000e-02 2.1100e-01 - 1.3065e+00 -2.5370e-02 2.4300e-01 - 1.2830e+00 -1.6000e-02 2.6500e-01 - 1.3300e+00 -1.6000e-02 3.5600e-01 - -8.7000e-02 1.2000e+00 -3.5600e-01 - -8.7000e-02 1.2000e+00 -2.6500e-01 - -7.1000e-02 1.2000e+00 -2.4300e-01 - -5.5000e-02 1.2000e+00 -2.1100e-01 - 1.6900e-01 1.2000e+00 -2.1100e-01 - 1.9100e-01 1.1880e+00 -2.0200e-01 - 2.0100e-01 1.1620e+00 -1.7900e-01 - 2.0100e-01 7.9400e-01 2.0600e-01 - 1.9100e-01 7.7500e-01 2.2900e-01 - 1.6900e-01 7.6800e-01 2.3800e-01 - -1.6800e-01 7.6800e-01 2.3800e-01 - -1.9100e-01 7.7500e-01 2.2900e-01 - -2.0000e-01 7.9500e-01 2.0600e-01 - -2.0000e-01 1.1620e+00 -1.7900e-01 - -1.9100e-01 1.1880e+00 -2.0200e-01 - -1.6800e-01 1.2000e+00 -2.1100e-01 - -1.5100e-01 1.2000e+00 -2.1100e-01 - -1.3500e-01 1.2000e+00 -2.4300e-01 - -1.1900e-01 1.2000e+00 -2.6500e-01 - -1.1900e-01 1.2000e+00 -3.5600e-01 - -1.3300e+00 1.6000e-02 3.5600e-01 - -1.2830e+00 1.6000e-02 2.6500e-01 - -1.3065e+00 2.5370e-02 2.4300e-01 - -1.3300e+00 4.8000e-02 2.1100e-01 - -1.3300e+00 6.1000e-02 2.1100e-01 - -1.3300e+00 8.2000e-02 2.0200e-01 - -1.3300e+00 9.3000e-02 1.7900e-01 - -1.3300e+00 1.7100e-01 -2.0600e-01 - -1.3300e+00 1.6500e-01 -2.2900e-01 - -1.3300e+00 1.4100e-01 -2.3800e-01 - -1.3300e+00 -1.4100e-01 -2.3800e-01 - -1.3300e+00 -1.6600e-01 -2.2900e-01 - -1.3300e+00 -1.7200e-01 -2.0600e-01 - -1.3300e+00 -9.3000e-02 1.7900e-01 - -1.3300e+00 -8.2000e-02 2.0200e-01 - -1.3300e+00 -6.2000e-02 2.1100e-01 - -1.3300e+00 -4.9000e-02 2.1100e-01 - -1.3065e+00 -2.5370e-02 2.4300e-01 - -1.2830e+00 -1.6000e-02 2.6500e-01 - -1.3300e+00 -1.6000e-02 3.5600e-01 - 8.7000e-02 -7.7650e-01 -3.5600e-01 - 8.7000e-02 -7.7650e-01 -2.6500e-01 - 7.1000e-02 -7.7650e-01 -2.4300e-01 - 5.5000e-02 -7.7650e-01 -2.1100e-01 - 5.5000e-02 -7.7650e-01 -2.1100e-01 - 3.2600e-02 -7.8350e-01 -2.0200e-01 - 2.2600e-02 -8.0250e-01 -1.7900e-01 - 2.2600e-02 -1.2015e+00 2.0600e-01 - 3.2600e-02 -1.2275e+00 2.2900e-01 - 5.4600e-02 -1.2395e+00 2.3800e-01 - 1.6800e-01 -1.2395e+00 2.3800e-01 - 1.9100e-01 -1.2275e+00 2.2900e-01 - 2.0000e-01 -1.2015e+00 2.0600e-01 - 2.0000e-01 -8.0250e-01 -1.7900e-01 - 1.9100e-01 -7.8350e-01 -2.0200e-01 - 1.6800e-01 -7.7650e-01 -2.1100e-01 - 1.5100e-01 -7.7650e-01 -2.1100e-01 - 1.3500e-01 -7.7650e-01 -2.4300e-01 - 1.1900e-01 -7.7650e-01 -2.6500e-01 - 1.1900e-01 -7.7650e-01 -3.5600e-01 + 4 1 20 1.00 + 1.3300e+00 1.6000e-02 3.5600e-01 + 1.2830e+00 1.6000e-02 2.6500e-01 + 1.3065e+00 2.5370e-02 2.4300e-01 + 1.3300e+00 4.8000e-02 2.1100e-01 + 1.3300e+00 1.3200e-01 2.1100e-01 + 1.3300e+00 1.5800e-01 2.0200e-01 + 1.3300e+00 1.6300e-01 1.7900e-01 + 1.3300e+00 9.0000e-02 -2.0600e-01 + 1.3300e+00 7.9000e-02 -2.2900e-01 + 1.3300e+00 5.8000e-02 -2.3800e-01 + 1.3300e+00 -6.2000e-02 -2.3800e-01 + 1.3300e+00 -8.3000e-02 -2.2900e-01 + 1.3300e+00 -9.4000e-02 -2.0600e-01 + 1.3300e+00 -1.6700e-01 1.7900e-01 + 1.3300e+00 -1.6000e-01 2.0200e-01 + 1.3300e+00 -1.3500e-01 2.1100e-01 + 1.3300e+00 -5.0000e-02 2.1100e-01 + 1.3065e+00 -2.5370e-02 2.4300e-01 + 1.2830e+00 -1.6000e-02 2.6500e-01 + 1.3300e+00 -1.6000e-02 3.5600e-01 + -8.7000e-02 1.2000e+00 -3.5600e-01 + -8.7000e-02 1.2000e+00 -2.6500e-01 + -7.1000e-02 1.2000e+00 -2.4300e-01 + -5.5000e-02 1.2000e+00 -2.1100e-01 + 1.6900e-01 1.2000e+00 -2.1100e-01 + 1.9100e-01 1.1880e+00 -2.0200e-01 + 2.0100e-01 1.1620e+00 -1.7900e-01 + 2.0100e-01 7.9400e-01 2.0600e-01 + 1.9100e-01 7.7500e-01 2.2900e-01 + 1.6900e-01 7.6800e-01 2.3800e-01 + -1.6800e-01 7.6800e-01 2.3800e-01 + -1.9100e-01 7.7500e-01 2.2900e-01 + -2.0000e-01 7.9500e-01 2.0600e-01 + -2.0000e-01 1.1620e+00 -1.7900e-01 + -1.9100e-01 1.1880e+00 -2.0200e-01 + -1.6800e-01 1.2000e+00 -2.1100e-01 + -1.5100e-01 1.2000e+00 -2.1100e-01 + -1.3500e-01 1.2000e+00 -2.4300e-01 + -1.1900e-01 1.2000e+00 -2.6500e-01 + -1.1900e-01 1.2000e+00 -3.5600e-01 + -1.3300e+00 1.6000e-02 3.5600e-01 + -1.2830e+00 1.6000e-02 2.6500e-01 + -1.3065e+00 2.5370e-02 2.4300e-01 + -1.3300e+00 4.8000e-02 2.1100e-01 + -1.3300e+00 6.1000e-02 2.1100e-01 + -1.3300e+00 8.2000e-02 2.0200e-01 + -1.3300e+00 9.3000e-02 1.7900e-01 + -1.3300e+00 1.7100e-01 -2.0600e-01 + -1.3300e+00 1.6500e-01 -2.2900e-01 + -1.3300e+00 1.4100e-01 -2.3800e-01 + -1.3300e+00 -1.4100e-01 -2.3800e-01 + -1.3300e+00 -1.6600e-01 -2.2900e-01 + -1.3300e+00 -1.7200e-01 -2.0600e-01 + -1.3300e+00 -9.3000e-02 1.7900e-01 + -1.3300e+00 -8.2000e-02 2.0200e-01 + -1.3300e+00 -6.2000e-02 2.1100e-01 + -1.3300e+00 -4.9000e-02 2.1100e-01 + -1.3065e+00 -2.5370e-02 2.4300e-01 + -1.2830e+00 -1.6000e-02 2.6500e-01 + -1.3300e+00 -1.6000e-02 3.5600e-01 + 8.7000e-02 -7.7650e-01 -3.5600e-01 + 8.7000e-02 -7.7650e-01 -2.6500e-01 + 7.1000e-02 -7.7650e-01 -2.4300e-01 + 5.5000e-02 -7.7650e-01 -2.1100e-01 + 5.5000e-02 -7.7650e-01 -2.1100e-01 + 3.2600e-02 -7.8350e-01 -2.0200e-01 + 2.2600e-02 -8.0250e-01 -1.7900e-01 + 2.2600e-02 -1.2015e+00 2.0600e-01 + 3.2600e-02 -1.2275e+00 2.2900e-01 + 5.4600e-02 -1.2395e+00 2.3800e-01 + 1.6800e-01 -1.2395e+00 2.3800e-01 + 1.9100e-01 -1.2275e+00 2.2900e-01 + 2.0000e-01 -1.2015e+00 2.0600e-01 + 2.0000e-01 -8.0250e-01 -1.7900e-01 + 1.9100e-01 -7.8350e-01 -2.0200e-01 + 1.6800e-01 -7.7650e-01 -2.1100e-01 + 1.5100e-01 -7.7650e-01 -2.1100e-01 + 1.3500e-01 -7.7650e-01 -2.4300e-01 + 1.1900e-01 -7.7650e-01 -2.6500e-01 + 1.1900e-01 -7.7650e-01 -3.5600e-01 diff --git a/src/ForcingTerms/coil_geometries/jtext_u.dat b/src/ForcingTerms/coil_geometries/jtext_u.dat index 45404b00f..b70ef435f 100644 --- a/src/ForcingTerms/coil_geometries/jtext_u.dat +++ b/src/ForcingTerms/coil_geometries/jtext_u.dat @@ -1,81 +1,81 @@ - 4 1 20 1.00 - 1.2000e+00 1.6000e-02 3.9800e-01 - 1.2000e+00 1.6000e-02 3.3300e-01 - 1.2000e+00 2.5370e-02 3.1000e-01 - 1.2000e+00 4.8000e-02 3.0100e-01 - 1.2000e+00 1.3200e-01 3.0100e-01 - 1.1880e+00 1.5800e-01 3.0100e-01 - 1.1620e+00 1.6300e-01 3.0100e-01 - 7.9400e-01 9.0000e-02 3.0100e-01 - 7.7500e-01 7.9000e-02 3.0100e-01 - 7.6800e-01 5.8000e-02 3.0100e-01 - 7.6800e-01 -6.2000e-02 3.0100e-01 - 7.7500e-01 -8.3000e-02 3.0100e-01 - 7.9500e-01 -9.4000e-02 3.0100e-01 - 1.1620e+00 -1.6700e-01 3.0100e-01 - 1.1880e+00 -1.6000e-01 3.0100e-01 - 1.2000e+00 -1.3500e-01 3.0100e-01 - 1.2000e+00 -5.0000e-02 3.0100e-01 - 1.2000e+00 -2.5370e-02 3.1000e-01 - 1.2000e+00 -1.6000e-02 3.3300e-01 - 1.2000e+00 -1.6000e-02 3.9800e-01 - 1.6000e-02 1.2000e+00 3.9800e-01 - 1.6000e-02 1.2000e+00 3.3300e-01 - 2.5370e-02 1.2000e+00 3.1000e-01 - 4.8000e-02 1.2000e+00 3.0100e-01 - 1.3200e-01 1.2000e+00 3.0100e-01 - 1.5800e-01 1.1880e+00 3.0100e-01 - 1.6300e-01 1.1620e+00 3.0100e-01 - 9.0000e-02 7.9400e-01 3.0100e-01 - 7.9000e-02 7.7500e-01 3.0100e-01 - 5.8000e-02 7.6800e-01 3.0100e-01 - -6.2000e-02 7.6800e-01 3.0100e-01 - -8.3000e-02 7.7500e-01 3.0100e-01 - -9.4000e-02 7.9500e-01 3.0100e-01 - -1.6700e-01 1.1620e+00 3.0100e-01 - -1.6000e-01 1.1880e+00 3.0100e-01 - -1.3500e-01 1.2000e+00 3.0100e-01 - -5.0000e-02 1.2000e+00 3.0100e-01 - -2.5370e-02 1.2000e+00 3.1000e-01 - -1.6000e-02 1.2000e+00 3.3300e-01 - -1.6000e-02 1.2000e+00 3.9800e-01 - -7.7650e-01 1.6000e-02 3.9800e-01 - -7.7650e-01 1.6000e-02 3.3300e-01 - -7.7650e-01 2.5370e-02 3.1000e-01 - -7.7650e-01 4.8000e-02 3.0100e-01 - -7.7650e-01 6.1000e-02 3.0100e-01 - -7.8350e-01 8.2000e-02 3.0100e-01 - -8.0250e-01 9.3000e-02 3.0100e-01 - -1.2015e+00 1.7100e-01 3.0100e-01 - -1.2275e+00 1.6500e-01 3.0100e-01 - -1.2395e+00 1.4100e-01 3.0100e-01 - -1.2395e+00 -1.4100e-01 3.0100e-01 - -1.2275e+00 -1.6600e-01 3.0100e-01 - -1.2015e+00 -1.7200e-01 3.0100e-01 - -8.0250e-01 -9.3000e-02 3.0100e-01 - -7.8350e-01 -8.2000e-02 3.0100e-01 - -7.7650e-01 -6.2000e-02 3.0100e-01 - -7.7650e-01 -4.9000e-02 3.0100e-01 - -7.7650e-01 -2.5370e-02 3.1000e-01 - -7.7650e-01 -1.6000e-02 3.3300e-01 - -7.7650e-01 -1.6000e-02 3.9800e-01 - 1.6000e-02 -7.7650e-01 3.9800e-01 - 1.6000e-02 -7.7650e-01 3.3300e-01 - 2.5370e-02 -7.7650e-01 3.1000e-01 - 4.8000e-02 -7.7650e-01 3.0100e-01 - 6.1000e-02 -7.7650e-01 3.0100e-01 - 8.2000e-02 -7.8350e-01 3.0100e-01 - 9.3000e-02 -8.0250e-01 3.0100e-01 - 1.7100e-01 -1.2015e+00 3.0100e-01 - 1.6500e-01 -1.2275e+00 3.0100e-01 - 1.4100e-01 -1.2395e+00 3.0100e-01 - -1.4100e-01 -1.2395e+00 3.0100e-01 - -1.6600e-01 -1.2275e+00 3.0100e-01 - -1.7200e-01 -1.2015e+00 3.0100e-01 - -9.3000e-02 -8.0250e-01 3.0100e-01 - -8.2000e-02 -7.8350e-01 3.0100e-01 - -6.2000e-02 -7.7650e-01 3.0100e-01 - -4.9000e-02 -7.7650e-01 3.0100e-01 - -2.5370e-02 -7.7650e-01 3.1000e-01 - -1.6000e-02 -7.7650e-01 3.3300e-01 - -1.6000e-02 -7.7650e-01 3.9800e-01 + 4 1 20 1.00 + 1.2000e+00 1.6000e-02 3.9800e-01 + 1.2000e+00 1.6000e-02 3.3300e-01 + 1.2000e+00 2.5370e-02 3.1000e-01 + 1.2000e+00 4.8000e-02 3.0100e-01 + 1.2000e+00 1.3200e-01 3.0100e-01 + 1.1880e+00 1.5800e-01 3.0100e-01 + 1.1620e+00 1.6300e-01 3.0100e-01 + 7.9400e-01 9.0000e-02 3.0100e-01 + 7.7500e-01 7.9000e-02 3.0100e-01 + 7.6800e-01 5.8000e-02 3.0100e-01 + 7.6800e-01 -6.2000e-02 3.0100e-01 + 7.7500e-01 -8.3000e-02 3.0100e-01 + 7.9500e-01 -9.4000e-02 3.0100e-01 + 1.1620e+00 -1.6700e-01 3.0100e-01 + 1.1880e+00 -1.6000e-01 3.0100e-01 + 1.2000e+00 -1.3500e-01 3.0100e-01 + 1.2000e+00 -5.0000e-02 3.0100e-01 + 1.2000e+00 -2.5370e-02 3.1000e-01 + 1.2000e+00 -1.6000e-02 3.3300e-01 + 1.2000e+00 -1.6000e-02 3.9800e-01 + 1.6000e-02 1.2000e+00 3.9800e-01 + 1.6000e-02 1.2000e+00 3.3300e-01 + 2.5370e-02 1.2000e+00 3.1000e-01 + 4.8000e-02 1.2000e+00 3.0100e-01 + 1.3200e-01 1.2000e+00 3.0100e-01 + 1.5800e-01 1.1880e+00 3.0100e-01 + 1.6300e-01 1.1620e+00 3.0100e-01 + 9.0000e-02 7.9400e-01 3.0100e-01 + 7.9000e-02 7.7500e-01 3.0100e-01 + 5.8000e-02 7.6800e-01 3.0100e-01 + -6.2000e-02 7.6800e-01 3.0100e-01 + -8.3000e-02 7.7500e-01 3.0100e-01 + -9.4000e-02 7.9500e-01 3.0100e-01 + -1.6700e-01 1.1620e+00 3.0100e-01 + -1.6000e-01 1.1880e+00 3.0100e-01 + -1.3500e-01 1.2000e+00 3.0100e-01 + -5.0000e-02 1.2000e+00 3.0100e-01 + -2.5370e-02 1.2000e+00 3.1000e-01 + -1.6000e-02 1.2000e+00 3.3300e-01 + -1.6000e-02 1.2000e+00 3.9800e-01 + -7.7650e-01 1.6000e-02 3.9800e-01 + -7.7650e-01 1.6000e-02 3.3300e-01 + -7.7650e-01 2.5370e-02 3.1000e-01 + -7.7650e-01 4.8000e-02 3.0100e-01 + -7.7650e-01 6.1000e-02 3.0100e-01 + -7.8350e-01 8.2000e-02 3.0100e-01 + -8.0250e-01 9.3000e-02 3.0100e-01 + -1.2015e+00 1.7100e-01 3.0100e-01 + -1.2275e+00 1.6500e-01 3.0100e-01 + -1.2395e+00 1.4100e-01 3.0100e-01 + -1.2395e+00 -1.4100e-01 3.0100e-01 + -1.2275e+00 -1.6600e-01 3.0100e-01 + -1.2015e+00 -1.7200e-01 3.0100e-01 + -8.0250e-01 -9.3000e-02 3.0100e-01 + -7.8350e-01 -8.2000e-02 3.0100e-01 + -7.7650e-01 -6.2000e-02 3.0100e-01 + -7.7650e-01 -4.9000e-02 3.0100e-01 + -7.7650e-01 -2.5370e-02 3.1000e-01 + -7.7650e-01 -1.6000e-02 3.3300e-01 + -7.7650e-01 -1.6000e-02 3.9800e-01 + 1.6000e-02 -7.7650e-01 3.9800e-01 + 1.6000e-02 -7.7650e-01 3.3300e-01 + 2.5370e-02 -7.7650e-01 3.1000e-01 + 4.8000e-02 -7.7650e-01 3.0100e-01 + 6.1000e-02 -7.7650e-01 3.0100e-01 + 8.2000e-02 -7.8350e-01 3.0100e-01 + 9.3000e-02 -8.0250e-01 3.0100e-01 + 1.7100e-01 -1.2015e+00 3.0100e-01 + 1.6500e-01 -1.2275e+00 3.0100e-01 + 1.4100e-01 -1.2395e+00 3.0100e-01 + -1.4100e-01 -1.2395e+00 3.0100e-01 + -1.6600e-01 -1.2275e+00 3.0100e-01 + -1.7200e-01 -1.2015e+00 3.0100e-01 + -9.3000e-02 -8.0250e-01 3.0100e-01 + -8.2000e-02 -7.8350e-01 3.0100e-01 + -6.2000e-02 -7.7650e-01 3.0100e-01 + -4.9000e-02 -7.7650e-01 3.0100e-01 + -2.5370e-02 -7.7650e-01 3.1000e-01 + -1.6000e-02 -7.7650e-01 3.3300e-01 + -1.6000e-02 -7.7650e-01 3.9800e-01 diff --git a/src/ForcingTerms/coil_geometries/mastu_efcc.dat b/src/ForcingTerms/coil_geometries/mastu_efcc.dat index e94da889f..5259e11cc 100644 --- a/src/ForcingTerms/coil_geometries/mastu_efcc.dat +++ b/src/ForcingTerms/coil_geometries/mastu_efcc.dat @@ -1,169 +1,169 @@ - 4 1 42 1.00 - 2.9319e+00 0.0000e+00 1.6550e+00 - 2.9213e+00 2.4953e-01 1.6550e+00 - 2.8894e+00 4.9726e-01 1.6550e+00 - 2.8366e+00 7.4137e-01 1.6550e+00 - 2.7632e+00 9.8011e-01 1.6550e+00 - 2.6698e+00 1.2117e+00 1.6550e+00 - 2.5570e+00 1.4346e+00 1.6550e+00 - 2.4256e+00 1.6470e+00 1.6550e+00 - 2.2766e+00 1.8474e+00 1.6550e+00 - 2.1111e+00 2.0345e+00 1.6550e+00 - 1.9303e+00 2.2068e+00 1.6550e+00 - 1.7355e+00 2.3631e+00 1.6550e+00 - 1.5281e+00 2.5022e+00 1.6550e+00 - 1.3096e+00 2.6232e+00 1.6550e+00 - 1.0815e+00 2.7251e+00 1.6550e+00 - 8.4568e-01 2.8073e+00 1.6550e+00 - 6.0369e-01 2.8691e+00 1.6550e+00 - 3.5731e-01 2.9100e+00 1.6550e+00 - 3.5731e-01 2.9100e+00 1.6550e+00 - 3.5729e-01 2.9099e+00 9.1800e-01 - 3.5727e-01 2.9097e+00 1.8100e-01 - 3.5725e-01 2.9096e+00 -5.5600e-01 - 3.5723e-01 2.9094e+00 -1.2930e+00 - 3.5721e-01 2.9093e+00 -2.0300e+00 - 6.7851e-01 2.8515e+00 -2.0300e+00 - 9.9139e-01 2.7583e+00 -2.0300e+00 - 1.2920e+00 2.6310e+00 -2.0300e+00 - 1.5765e+00 2.4710e+00 -2.0300e+00 - 1.8415e+00 2.2804e+00 -2.0300e+00 - 2.0837e+00 2.0614e+00 -2.0300e+00 - 2.3000e+00 1.8169e+00 -2.0300e+00 - 2.4878e+00 1.5499e+00 -2.0300e+00 - 2.6447e+00 1.2636e+00 -2.0300e+00 - 2.7688e+00 9.6171e-01 -2.0300e+00 - 2.8586e+00 6.4785e-01 -2.0300e+00 - 2.9129e+00 3.2594e-01 -2.0300e+00 - 2.9311e+00 0.0000e+00 -2.0300e+00 - 2.9313e+00 0.0000e+00 -1.2930e+00 - 2.9314e+00 0.0000e+00 -5.5600e-01 - 2.9316e+00 0.0000e+00 1.8100e-01 - 2.9317e+00 0.0000e+00 9.1800e-01 - 2.9319e+00 0.0000e+00 1.6550e+00 - 1.7953e-16 2.9319e+00 1.6550e+00 - -2.4953e-01 2.9213e+00 1.6550e+00 - -4.9726e-01 2.8894e+00 1.6550e+00 - -7.4137e-01 2.8366e+00 1.6550e+00 - -9.8011e-01 2.7632e+00 1.6550e+00 - -1.2117e+00 2.6698e+00 1.6550e+00 - -1.4346e+00 2.5570e+00 1.6550e+00 - -1.6470e+00 2.4256e+00 1.6550e+00 - -1.8474e+00 2.2766e+00 1.6550e+00 - -2.0345e+00 2.1111e+00 1.6550e+00 - -2.2068e+00 1.9303e+00 1.6550e+00 - -2.3631e+00 1.7355e+00 1.6550e+00 - -2.5022e+00 1.5281e+00 1.6550e+00 - -2.6232e+00 1.3096e+00 1.6550e+00 - -2.7251e+00 1.0815e+00 1.6550e+00 - -2.8073e+00 8.4568e-01 1.6550e+00 - -2.8691e+00 6.0369e-01 1.6550e+00 - -2.9100e+00 3.5731e-01 1.6550e+00 - -2.9100e+00 3.5731e-01 1.6550e+00 - -2.9099e+00 3.5729e-01 9.1800e-01 - -2.9097e+00 3.5727e-01 1.8100e-01 - -2.9096e+00 3.5725e-01 -5.5600e-01 - -2.9094e+00 3.5723e-01 -1.2930e+00 - -2.9093e+00 3.5721e-01 -2.0300e+00 - -2.8515e+00 6.7851e-01 -2.0300e+00 - -2.7583e+00 9.9139e-01 -2.0300e+00 - -2.6310e+00 1.2920e+00 -2.0300e+00 - -2.4710e+00 1.5765e+00 -2.0300e+00 - -2.2804e+00 1.8415e+00 -2.0300e+00 - -2.0614e+00 2.0837e+00 -2.0300e+00 - -1.8169e+00 2.3000e+00 -2.0300e+00 - -1.5499e+00 2.4878e+00 -2.0300e+00 - -1.2636e+00 2.6447e+00 -2.0300e+00 - -9.6171e-01 2.7688e+00 -2.0300e+00 - -6.4785e-01 2.8586e+00 -2.0300e+00 - -3.2594e-01 2.9129e+00 -2.0300e+00 - 1.7948e-16 2.9311e+00 -2.0300e+00 - 1.7949e-16 2.9313e+00 -1.2930e+00 - 1.7950e-16 2.9314e+00 -5.5600e-01 - 1.7951e-16 2.9316e+00 1.8100e-01 - 1.7952e-16 2.9317e+00 9.1800e-01 - 1.7953e-16 2.9319e+00 1.6550e+00 - -2.9319e+00 3.5905e-16 1.6550e+00 - -2.9213e+00 -2.4953e-01 1.6550e+00 - -2.8894e+00 -4.9726e-01 1.6550e+00 - -2.8366e+00 -7.4137e-01 1.6550e+00 - -2.7632e+00 -9.8011e-01 1.6550e+00 - -2.6698e+00 -1.2117e+00 1.6550e+00 - -2.5570e+00 -1.4346e+00 1.6550e+00 - -2.4256e+00 -1.6470e+00 1.6550e+00 - -2.2766e+00 -1.8474e+00 1.6550e+00 - -2.1111e+00 -2.0345e+00 1.6550e+00 - -1.9303e+00 -2.2068e+00 1.6550e+00 - -1.7355e+00 -2.3631e+00 1.6550e+00 - -1.5281e+00 -2.5022e+00 1.6550e+00 - -1.3096e+00 -2.6232e+00 1.6550e+00 - -1.0815e+00 -2.7251e+00 1.6550e+00 - -8.4568e-01 -2.8073e+00 1.6550e+00 - -6.0369e-01 -2.8691e+00 1.6550e+00 - -3.5731e-01 -2.9100e+00 1.6550e+00 - -3.5731e-01 -2.9100e+00 1.6550e+00 - -3.5729e-01 -2.9099e+00 9.1800e-01 - -3.5727e-01 -2.9097e+00 1.8100e-01 - -3.5725e-01 -2.9096e+00 -5.5600e-01 - -3.5723e-01 -2.9094e+00 -1.2930e+00 - -3.5721e-01 -2.9093e+00 -2.0300e+00 - -6.7851e-01 -2.8515e+00 -2.0300e+00 - -9.9139e-01 -2.7583e+00 -2.0300e+00 - -1.2920e+00 -2.6310e+00 -2.0300e+00 - -1.5765e+00 -2.4710e+00 -2.0300e+00 - -1.8415e+00 -2.2804e+00 -2.0300e+00 - -2.0837e+00 -2.0614e+00 -2.0300e+00 - -2.3000e+00 -1.8169e+00 -2.0300e+00 - -2.4878e+00 -1.5499e+00 -2.0300e+00 - -2.6447e+00 -1.2636e+00 -2.0300e+00 - -2.7688e+00 -9.6171e-01 -2.0300e+00 - -2.8586e+00 -6.4785e-01 -2.0300e+00 - -2.9129e+00 -3.2594e-01 -2.0300e+00 - -2.9311e+00 3.5896e-16 -2.0300e+00 - -2.9313e+00 3.5898e-16 -1.2930e+00 - -2.9314e+00 3.5900e-16 -5.5600e-01 - -2.9316e+00 3.5902e-16 1.8100e-01 - -2.9317e+00 3.5903e-16 9.1800e-01 - -2.9319e+00 3.5905e-16 1.6550e+00 - -5.3858e-16 -2.9319e+00 1.6550e+00 - 2.4953e-01 -2.9213e+00 1.6550e+00 - 4.9726e-01 -2.8894e+00 1.6550e+00 - 7.4137e-01 -2.8366e+00 1.6550e+00 - 9.8011e-01 -2.7632e+00 1.6550e+00 - 1.2117e+00 -2.6698e+00 1.6550e+00 - 1.4346e+00 -2.5570e+00 1.6550e+00 - 1.6470e+00 -2.4256e+00 1.6550e+00 - 1.8474e+00 -2.2766e+00 1.6550e+00 - 2.0345e+00 -2.1111e+00 1.6550e+00 - 2.2068e+00 -1.9303e+00 1.6550e+00 - 2.3631e+00 -1.7355e+00 1.6550e+00 - 2.5022e+00 -1.5281e+00 1.6550e+00 - 2.6232e+00 -1.3096e+00 1.6550e+00 - 2.7251e+00 -1.0815e+00 1.6550e+00 - 2.8073e+00 -8.4568e-01 1.6550e+00 - 2.8691e+00 -6.0369e-01 1.6550e+00 - 2.9100e+00 -3.5731e-01 1.6550e+00 - 2.9100e+00 -3.5731e-01 1.6550e+00 - 2.9099e+00 -3.5729e-01 9.1800e-01 - 2.9097e+00 -3.5727e-01 1.8100e-01 - 2.9096e+00 -3.5725e-01 -5.5600e-01 - 2.9094e+00 -3.5723e-01 -1.2930e+00 - 2.9093e+00 -3.5721e-01 -2.0300e+00 - 2.8515e+00 -6.7851e-01 -2.0300e+00 - 2.7583e+00 -9.9139e-01 -2.0300e+00 - 2.6310e+00 -1.2920e+00 -2.0300e+00 - 2.4710e+00 -1.5765e+00 -2.0300e+00 - 2.2804e+00 -1.8415e+00 -2.0300e+00 - 2.0614e+00 -2.0837e+00 -2.0300e+00 - 1.8169e+00 -2.3000e+00 -2.0300e+00 - 1.5499e+00 -2.4878e+00 -2.0300e+00 - 1.2636e+00 -2.6447e+00 -2.0300e+00 - 9.6171e-01 -2.7688e+00 -2.0300e+00 - 6.4785e-01 -2.8586e+00 -2.0300e+00 - 3.2594e-01 -2.9129e+00 -2.0300e+00 - -5.3843e-16 -2.9311e+00 -2.0300e+00 - -5.3846e-16 -2.9313e+00 -1.2930e+00 - -5.3849e-16 -2.9314e+00 -5.5600e-01 - -5.3852e-16 -2.9316e+00 1.8100e-01 - -5.3855e-16 -2.9317e+00 9.1800e-01 - -5.3858e-16 -2.9319e+00 1.6550e+00 + 4 1 42 1.00 + 2.9319e+00 0.0000e+00 1.6550e+00 + 2.9213e+00 2.4953e-01 1.6550e+00 + 2.8894e+00 4.9726e-01 1.6550e+00 + 2.8366e+00 7.4137e-01 1.6550e+00 + 2.7632e+00 9.8011e-01 1.6550e+00 + 2.6698e+00 1.2117e+00 1.6550e+00 + 2.5570e+00 1.4346e+00 1.6550e+00 + 2.4256e+00 1.6470e+00 1.6550e+00 + 2.2766e+00 1.8474e+00 1.6550e+00 + 2.1111e+00 2.0345e+00 1.6550e+00 + 1.9303e+00 2.2068e+00 1.6550e+00 + 1.7355e+00 2.3631e+00 1.6550e+00 + 1.5281e+00 2.5022e+00 1.6550e+00 + 1.3096e+00 2.6232e+00 1.6550e+00 + 1.0815e+00 2.7251e+00 1.6550e+00 + 8.4568e-01 2.8073e+00 1.6550e+00 + 6.0369e-01 2.8691e+00 1.6550e+00 + 3.5731e-01 2.9100e+00 1.6550e+00 + 3.5731e-01 2.9100e+00 1.6550e+00 + 3.5729e-01 2.9099e+00 9.1800e-01 + 3.5727e-01 2.9097e+00 1.8100e-01 + 3.5725e-01 2.9096e+00 -5.5600e-01 + 3.5723e-01 2.9094e+00 -1.2930e+00 + 3.5721e-01 2.9093e+00 -2.0300e+00 + 6.7851e-01 2.8515e+00 -2.0300e+00 + 9.9139e-01 2.7583e+00 -2.0300e+00 + 1.2920e+00 2.6310e+00 -2.0300e+00 + 1.5765e+00 2.4710e+00 -2.0300e+00 + 1.8415e+00 2.2804e+00 -2.0300e+00 + 2.0837e+00 2.0614e+00 -2.0300e+00 + 2.3000e+00 1.8169e+00 -2.0300e+00 + 2.4878e+00 1.5499e+00 -2.0300e+00 + 2.6447e+00 1.2636e+00 -2.0300e+00 + 2.7688e+00 9.6171e-01 -2.0300e+00 + 2.8586e+00 6.4785e-01 -2.0300e+00 + 2.9129e+00 3.2594e-01 -2.0300e+00 + 2.9311e+00 0.0000e+00 -2.0300e+00 + 2.9313e+00 0.0000e+00 -1.2930e+00 + 2.9314e+00 0.0000e+00 -5.5600e-01 + 2.9316e+00 0.0000e+00 1.8100e-01 + 2.9317e+00 0.0000e+00 9.1800e-01 + 2.9319e+00 0.0000e+00 1.6550e+00 + 1.7953e-16 2.9319e+00 1.6550e+00 + -2.4953e-01 2.9213e+00 1.6550e+00 + -4.9726e-01 2.8894e+00 1.6550e+00 + -7.4137e-01 2.8366e+00 1.6550e+00 + -9.8011e-01 2.7632e+00 1.6550e+00 + -1.2117e+00 2.6698e+00 1.6550e+00 + -1.4346e+00 2.5570e+00 1.6550e+00 + -1.6470e+00 2.4256e+00 1.6550e+00 + -1.8474e+00 2.2766e+00 1.6550e+00 + -2.0345e+00 2.1111e+00 1.6550e+00 + -2.2068e+00 1.9303e+00 1.6550e+00 + -2.3631e+00 1.7355e+00 1.6550e+00 + -2.5022e+00 1.5281e+00 1.6550e+00 + -2.6232e+00 1.3096e+00 1.6550e+00 + -2.7251e+00 1.0815e+00 1.6550e+00 + -2.8073e+00 8.4568e-01 1.6550e+00 + -2.8691e+00 6.0369e-01 1.6550e+00 + -2.9100e+00 3.5731e-01 1.6550e+00 + -2.9100e+00 3.5731e-01 1.6550e+00 + -2.9099e+00 3.5729e-01 9.1800e-01 + -2.9097e+00 3.5727e-01 1.8100e-01 + -2.9096e+00 3.5725e-01 -5.5600e-01 + -2.9094e+00 3.5723e-01 -1.2930e+00 + -2.9093e+00 3.5721e-01 -2.0300e+00 + -2.8515e+00 6.7851e-01 -2.0300e+00 + -2.7583e+00 9.9139e-01 -2.0300e+00 + -2.6310e+00 1.2920e+00 -2.0300e+00 + -2.4710e+00 1.5765e+00 -2.0300e+00 + -2.2804e+00 1.8415e+00 -2.0300e+00 + -2.0614e+00 2.0837e+00 -2.0300e+00 + -1.8169e+00 2.3000e+00 -2.0300e+00 + -1.5499e+00 2.4878e+00 -2.0300e+00 + -1.2636e+00 2.6447e+00 -2.0300e+00 + -9.6171e-01 2.7688e+00 -2.0300e+00 + -6.4785e-01 2.8586e+00 -2.0300e+00 + -3.2594e-01 2.9129e+00 -2.0300e+00 + 1.7948e-16 2.9311e+00 -2.0300e+00 + 1.7949e-16 2.9313e+00 -1.2930e+00 + 1.7950e-16 2.9314e+00 -5.5600e-01 + 1.7951e-16 2.9316e+00 1.8100e-01 + 1.7952e-16 2.9317e+00 9.1800e-01 + 1.7953e-16 2.9319e+00 1.6550e+00 + -2.9319e+00 3.5905e-16 1.6550e+00 + -2.9213e+00 -2.4953e-01 1.6550e+00 + -2.8894e+00 -4.9726e-01 1.6550e+00 + -2.8366e+00 -7.4137e-01 1.6550e+00 + -2.7632e+00 -9.8011e-01 1.6550e+00 + -2.6698e+00 -1.2117e+00 1.6550e+00 + -2.5570e+00 -1.4346e+00 1.6550e+00 + -2.4256e+00 -1.6470e+00 1.6550e+00 + -2.2766e+00 -1.8474e+00 1.6550e+00 + -2.1111e+00 -2.0345e+00 1.6550e+00 + -1.9303e+00 -2.2068e+00 1.6550e+00 + -1.7355e+00 -2.3631e+00 1.6550e+00 + -1.5281e+00 -2.5022e+00 1.6550e+00 + -1.3096e+00 -2.6232e+00 1.6550e+00 + -1.0815e+00 -2.7251e+00 1.6550e+00 + -8.4568e-01 -2.8073e+00 1.6550e+00 + -6.0369e-01 -2.8691e+00 1.6550e+00 + -3.5731e-01 -2.9100e+00 1.6550e+00 + -3.5731e-01 -2.9100e+00 1.6550e+00 + -3.5729e-01 -2.9099e+00 9.1800e-01 + -3.5727e-01 -2.9097e+00 1.8100e-01 + -3.5725e-01 -2.9096e+00 -5.5600e-01 + -3.5723e-01 -2.9094e+00 -1.2930e+00 + -3.5721e-01 -2.9093e+00 -2.0300e+00 + -6.7851e-01 -2.8515e+00 -2.0300e+00 + -9.9139e-01 -2.7583e+00 -2.0300e+00 + -1.2920e+00 -2.6310e+00 -2.0300e+00 + -1.5765e+00 -2.4710e+00 -2.0300e+00 + -1.8415e+00 -2.2804e+00 -2.0300e+00 + -2.0837e+00 -2.0614e+00 -2.0300e+00 + -2.3000e+00 -1.8169e+00 -2.0300e+00 + -2.4878e+00 -1.5499e+00 -2.0300e+00 + -2.6447e+00 -1.2636e+00 -2.0300e+00 + -2.7688e+00 -9.6171e-01 -2.0300e+00 + -2.8586e+00 -6.4785e-01 -2.0300e+00 + -2.9129e+00 -3.2594e-01 -2.0300e+00 + -2.9311e+00 3.5896e-16 -2.0300e+00 + -2.9313e+00 3.5898e-16 -1.2930e+00 + -2.9314e+00 3.5900e-16 -5.5600e-01 + -2.9316e+00 3.5902e-16 1.8100e-01 + -2.9317e+00 3.5903e-16 9.1800e-01 + -2.9319e+00 3.5905e-16 1.6550e+00 + -5.3858e-16 -2.9319e+00 1.6550e+00 + 2.4953e-01 -2.9213e+00 1.6550e+00 + 4.9726e-01 -2.8894e+00 1.6550e+00 + 7.4137e-01 -2.8366e+00 1.6550e+00 + 9.8011e-01 -2.7632e+00 1.6550e+00 + 1.2117e+00 -2.6698e+00 1.6550e+00 + 1.4346e+00 -2.5570e+00 1.6550e+00 + 1.6470e+00 -2.4256e+00 1.6550e+00 + 1.8474e+00 -2.2766e+00 1.6550e+00 + 2.0345e+00 -2.1111e+00 1.6550e+00 + 2.2068e+00 -1.9303e+00 1.6550e+00 + 2.3631e+00 -1.7355e+00 1.6550e+00 + 2.5022e+00 -1.5281e+00 1.6550e+00 + 2.6232e+00 -1.3096e+00 1.6550e+00 + 2.7251e+00 -1.0815e+00 1.6550e+00 + 2.8073e+00 -8.4568e-01 1.6550e+00 + 2.8691e+00 -6.0369e-01 1.6550e+00 + 2.9100e+00 -3.5731e-01 1.6550e+00 + 2.9100e+00 -3.5731e-01 1.6550e+00 + 2.9099e+00 -3.5729e-01 9.1800e-01 + 2.9097e+00 -3.5727e-01 1.8100e-01 + 2.9096e+00 -3.5725e-01 -5.5600e-01 + 2.9094e+00 -3.5723e-01 -1.2930e+00 + 2.9093e+00 -3.5721e-01 -2.0300e+00 + 2.8515e+00 -6.7851e-01 -2.0300e+00 + 2.7583e+00 -9.9139e-01 -2.0300e+00 + 2.6310e+00 -1.2920e+00 -2.0300e+00 + 2.4710e+00 -1.5765e+00 -2.0300e+00 + 2.2804e+00 -1.8415e+00 -2.0300e+00 + 2.0614e+00 -2.0837e+00 -2.0300e+00 + 1.8169e+00 -2.3000e+00 -2.0300e+00 + 1.5499e+00 -2.4878e+00 -2.0300e+00 + 1.2636e+00 -2.6447e+00 -2.0300e+00 + 9.6171e-01 -2.7688e+00 -2.0300e+00 + 6.4785e-01 -2.8586e+00 -2.0300e+00 + 3.2594e-01 -2.9129e+00 -2.0300e+00 + -5.3843e-16 -2.9311e+00 -2.0300e+00 + -5.3846e-16 -2.9313e+00 -1.2930e+00 + -5.3849e-16 -2.9314e+00 -5.5600e-01 + -5.3852e-16 -2.9316e+00 1.8100e-01 + -5.3855e-16 -2.9317e+00 9.1800e-01 + -5.3858e-16 -2.9319e+00 1.6550e+00 diff --git a/src/ForcingTerms/coil_geometries/mastu_rmpl.dat b/src/ForcingTerms/coil_geometries/mastu_rmpl.dat index 7d3a798d3..1bb9ca785 100644 --- a/src/ForcingTerms/coil_geometries/mastu_rmpl.dat +++ b/src/ForcingTerms/coil_geometries/mastu_rmpl.dat @@ -1,337 +1,337 @@ - 8 1 42 1.00 - 1.3110e+00 0.0000e+00 -7.9100e-01 - 1.3107e+00 2.6300e-02 -7.9100e-01 - 1.3099e+00 5.2589e-02 -7.9100e-01 - 1.3086e+00 7.8857e-02 -7.9100e-01 - 1.3068e+00 1.0509e-01 -7.9100e-01 - 1.3044e+00 1.3129e-01 -7.9100e-01 - 1.3015e+00 1.5743e-01 -7.9100e-01 - 1.2981e+00 1.8351e-01 -7.9100e-01 - 1.2942e+00 2.0951e-01 -7.9100e-01 - 1.2897e+00 2.3543e-01 -7.9100e-01 - 1.2847e+00 2.6125e-01 -7.9100e-01 - 1.2792e+00 2.8697e-01 -7.9100e-01 - 1.2732e+00 3.1258e-01 -7.9100e-01 - 1.2667e+00 3.3806e-01 -7.9100e-01 - 1.2596e+00 3.6340e-01 -7.9100e-01 - 1.2521e+00 3.8859e-01 -7.9100e-01 - 1.2440e+00 4.1363e-01 -7.9100e-01 - 1.2355e+00 4.3851e-01 -7.9100e-01 - 1.2264e+00 4.6320e-01 -7.9100e-01 - 1.2169e+00 4.8771e-01 -7.9100e-01 - 1.2169e+00 4.8771e-01 -7.9100e-01 - 1.2703e+00 5.0910e-01 -6.9100e-01 - 1.3237e+00 5.3049e-01 -5.9100e-01 - 1.3352e+00 5.0068e-01 -5.9100e-01 - 1.3461e+00 4.7062e-01 -5.9100e-01 - 1.3563e+00 4.4032e-01 -5.9100e-01 - 1.3658e+00 4.0980e-01 -5.9100e-01 - 1.3747e+00 3.7908e-01 -5.9100e-01 - 1.3828e+00 3.4816e-01 -5.9100e-01 - 1.3903e+00 3.1707e-01 -5.9100e-01 - 1.3971e+00 2.8582e-01 -5.9100e-01 - 1.4031e+00 2.5442e-01 -5.9100e-01 - 1.4085e+00 2.2290e-01 -5.9100e-01 - 1.4131e+00 1.9127e-01 -5.9100e-01 - 1.4170e+00 1.5954e-01 -5.9100e-01 - 1.4203e+00 1.2773e-01 -5.9100e-01 - 1.4228e+00 9.5850e-02 -5.9100e-01 - 1.4246e+00 6.3927e-02 -5.9100e-01 - 1.4256e+00 3.1972e-02 -5.9100e-01 - 1.4260e+00 0.0000e+00 -5.9100e-01 - 1.3685e+00 0.0000e+00 -6.9100e-01 - 1.3110e+00 0.0000e+00 -7.9100e-01 - 9.2702e-01 9.2702e-01 -7.9100e-01 - 9.0823e-01 9.4543e-01 -7.9100e-01 - 8.8909e-01 9.6346e-01 -7.9100e-01 - 8.6958e-01 9.8110e-01 -7.9100e-01 - 8.4972e-01 9.9835e-01 -7.9100e-01 - 8.2952e-01 1.0152e+00 -7.9100e-01 - 8.0899e-01 1.0316e+00 -7.9100e-01 - 7.8813e-01 1.0476e+00 -7.9100e-01 - 7.6696e-01 1.0632e+00 -7.9100e-01 - 7.4547e-01 1.0784e+00 -7.9100e-01 - 7.2369e-01 1.0932e+00 -7.9100e-01 - 7.0161e-01 1.1075e+00 -7.9100e-01 - 6.7926e-01 1.1213e+00 -7.9100e-01 - 6.5663e-01 1.1347e+00 -7.9100e-01 - 6.3373e-01 1.1477e+00 -7.9100e-01 - 6.1058e-01 1.1601e+00 -7.9100e-01 - 5.8718e-01 1.1721e+00 -7.9100e-01 - 5.6355e-01 1.1837e+00 -7.9100e-01 - 5.3969e-01 1.1948e+00 -7.9100e-01 - 5.1562e-01 1.2053e+00 -7.9100e-01 - 5.1562e-01 1.2053e+00 -7.9100e-01 - 5.3823e-01 1.2582e+00 -6.9100e-01 - 5.6085e-01 1.3111e+00 -5.9100e-01 - 5.9010e-01 1.2982e+00 -5.9100e-01 - 6.1906e-01 1.2846e+00 -5.9100e-01 - 6.4770e-01 1.2704e+00 -5.9100e-01 - 6.7602e-01 1.2556e+00 -5.9100e-01 - 7.0400e-01 1.2401e+00 -5.9100e-01 - 7.3163e-01 1.2240e+00 -5.9100e-01 - 7.5889e-01 1.2073e+00 -5.9100e-01 - 7.8577e-01 1.1900e+00 -5.9100e-01 - 8.1225e-01 1.1721e+00 -5.9100e-01 - 8.3832e-01 1.1536e+00 -5.9100e-01 - 8.6398e-01 1.1345e+00 -5.9100e-01 - 8.8919e-01 1.1148e+00 -5.9100e-01 - 9.1397e-01 1.0946e+00 -5.9100e-01 - 9.3828e-01 1.0738e+00 -5.9100e-01 - 9.6212e-01 1.0525e+00 -5.9100e-01 - 9.8547e-01 1.0307e+00 -5.9100e-01 - 1.0083e+00 1.0083e+00 -5.9100e-01 - 9.6768e-01 9.6768e-01 -6.9100e-01 - 9.2702e-01 9.2702e-01 -7.9100e-01 - 8.0276e-17 1.3110e+00 -7.9100e-01 - -2.6300e-02 1.3107e+00 -7.9100e-01 - -5.2589e-02 1.3099e+00 -7.9100e-01 - -7.8857e-02 1.3086e+00 -7.9100e-01 - -1.0509e-01 1.3068e+00 -7.9100e-01 - -1.3129e-01 1.3044e+00 -7.9100e-01 - -1.5743e-01 1.3015e+00 -7.9100e-01 - -1.8351e-01 1.2981e+00 -7.9100e-01 - -2.0951e-01 1.2942e+00 -7.9100e-01 - -2.3543e-01 1.2897e+00 -7.9100e-01 - -2.6125e-01 1.2847e+00 -7.9100e-01 - -2.8697e-01 1.2792e+00 -7.9100e-01 - -3.1258e-01 1.2732e+00 -7.9100e-01 - -3.3806e-01 1.2667e+00 -7.9100e-01 - -3.6340e-01 1.2596e+00 -7.9100e-01 - -3.8859e-01 1.2521e+00 -7.9100e-01 - -4.1363e-01 1.2440e+00 -7.9100e-01 - -4.3851e-01 1.2355e+00 -7.9100e-01 - -4.6320e-01 1.2264e+00 -7.9100e-01 - -4.8771e-01 1.2169e+00 -7.9100e-01 - -4.8771e-01 1.2169e+00 -7.9100e-01 - -5.0910e-01 1.2703e+00 -6.9100e-01 - -5.3049e-01 1.3237e+00 -5.9100e-01 - -5.0068e-01 1.3352e+00 -5.9100e-01 - -4.7062e-01 1.3461e+00 -5.9100e-01 - -4.4032e-01 1.3563e+00 -5.9100e-01 - -4.0980e-01 1.3658e+00 -5.9100e-01 - -3.7908e-01 1.3747e+00 -5.9100e-01 - -3.4816e-01 1.3828e+00 -5.9100e-01 - -3.1707e-01 1.3903e+00 -5.9100e-01 - -2.8582e-01 1.3971e+00 -5.9100e-01 - -2.5442e-01 1.4031e+00 -5.9100e-01 - -2.2290e-01 1.4085e+00 -5.9100e-01 - -1.9127e-01 1.4131e+00 -5.9100e-01 - -1.5954e-01 1.4170e+00 -5.9100e-01 - -1.2773e-01 1.4203e+00 -5.9100e-01 - -9.5850e-02 1.4228e+00 -5.9100e-01 - -6.3927e-02 1.4246e+00 -5.9100e-01 - -3.1972e-02 1.4256e+00 -5.9100e-01 - 8.7317e-17 1.4260e+00 -5.9100e-01 - 8.3796e-17 1.3685e+00 -6.9100e-01 - 8.0276e-17 1.3110e+00 -7.9100e-01 - -9.2702e-01 9.2702e-01 -7.9100e-01 - -9.4543e-01 9.0823e-01 -7.9100e-01 - -9.6346e-01 8.8909e-01 -7.9100e-01 - -9.8110e-01 8.6958e-01 -7.9100e-01 - -9.9835e-01 8.4972e-01 -7.9100e-01 - -1.0152e+00 8.2952e-01 -7.9100e-01 - -1.0316e+00 8.0899e-01 -7.9100e-01 - -1.0476e+00 7.8813e-01 -7.9100e-01 - -1.0632e+00 7.6696e-01 -7.9100e-01 - -1.0784e+00 7.4547e-01 -7.9100e-01 - -1.0932e+00 7.2369e-01 -7.9100e-01 - -1.1075e+00 7.0161e-01 -7.9100e-01 - -1.1213e+00 6.7926e-01 -7.9100e-01 - -1.1347e+00 6.5663e-01 -7.9100e-01 - -1.1477e+00 6.3373e-01 -7.9100e-01 - -1.1601e+00 6.1058e-01 -7.9100e-01 - -1.1721e+00 5.8718e-01 -7.9100e-01 - -1.1837e+00 5.6355e-01 -7.9100e-01 - -1.1948e+00 5.3969e-01 -7.9100e-01 - -1.2053e+00 5.1562e-01 -7.9100e-01 - -1.2053e+00 5.1562e-01 -7.9100e-01 - -1.2582e+00 5.3823e-01 -6.9100e-01 - -1.3111e+00 5.6085e-01 -5.9100e-01 - -1.2982e+00 5.9010e-01 -5.9100e-01 - -1.2846e+00 6.1906e-01 -5.9100e-01 - -1.2704e+00 6.4770e-01 -5.9100e-01 - -1.2556e+00 6.7602e-01 -5.9100e-01 - -1.2401e+00 7.0400e-01 -5.9100e-01 - -1.2240e+00 7.3163e-01 -5.9100e-01 - -1.2073e+00 7.5889e-01 -5.9100e-01 - -1.1900e+00 7.8577e-01 -5.9100e-01 - -1.1721e+00 8.1225e-01 -5.9100e-01 - -1.1536e+00 8.3832e-01 -5.9100e-01 - -1.1345e+00 8.6398e-01 -5.9100e-01 - -1.1148e+00 8.8919e-01 -5.9100e-01 - -1.0946e+00 9.1397e-01 -5.9100e-01 - -1.0738e+00 9.3828e-01 -5.9100e-01 - -1.0525e+00 9.6212e-01 -5.9100e-01 - -1.0307e+00 9.8547e-01 -5.9100e-01 - -1.0083e+00 1.0083e+00 -5.9100e-01 - -9.6768e-01 9.6768e-01 -6.9100e-01 - -9.2702e-01 9.2702e-01 -7.9100e-01 - -1.3110e+00 1.6055e-16 -7.9100e-01 - -1.3107e+00 -2.6300e-02 -7.9100e-01 - -1.3099e+00 -5.2589e-02 -7.9100e-01 - -1.3086e+00 -7.8857e-02 -7.9100e-01 - -1.3068e+00 -1.0509e-01 -7.9100e-01 - -1.3044e+00 -1.3129e-01 -7.9100e-01 - -1.3015e+00 -1.5743e-01 -7.9100e-01 - -1.2981e+00 -1.8351e-01 -7.9100e-01 - -1.2942e+00 -2.0951e-01 -7.9100e-01 - -1.2897e+00 -2.3543e-01 -7.9100e-01 - -1.2847e+00 -2.6125e-01 -7.9100e-01 - -1.2792e+00 -2.8697e-01 -7.9100e-01 - -1.2732e+00 -3.1258e-01 -7.9100e-01 - -1.2667e+00 -3.3806e-01 -7.9100e-01 - -1.2596e+00 -3.6340e-01 -7.9100e-01 - -1.2521e+00 -3.8859e-01 -7.9100e-01 - -1.2440e+00 -4.1363e-01 -7.9100e-01 - -1.2355e+00 -4.3851e-01 -7.9100e-01 - -1.2264e+00 -4.6320e-01 -7.9100e-01 - -1.2169e+00 -4.8771e-01 -7.9100e-01 - -1.2169e+00 -4.8771e-01 -7.9100e-01 - -1.2703e+00 -5.0910e-01 -6.9100e-01 - -1.3237e+00 -5.3049e-01 -5.9100e-01 - -1.3352e+00 -5.0068e-01 -5.9100e-01 - -1.3461e+00 -4.7062e-01 -5.9100e-01 - -1.3563e+00 -4.4032e-01 -5.9100e-01 - -1.3658e+00 -4.0980e-01 -5.9100e-01 - -1.3747e+00 -3.7908e-01 -5.9100e-01 - -1.3828e+00 -3.4816e-01 -5.9100e-01 - -1.3903e+00 -3.1707e-01 -5.9100e-01 - -1.3971e+00 -2.8582e-01 -5.9100e-01 - -1.4031e+00 -2.5442e-01 -5.9100e-01 - -1.4085e+00 -2.2290e-01 -5.9100e-01 - -1.4131e+00 -1.9127e-01 -5.9100e-01 - -1.4170e+00 -1.5954e-01 -5.9100e-01 - -1.4203e+00 -1.2773e-01 -5.9100e-01 - -1.4228e+00 -9.5850e-02 -5.9100e-01 - -1.4246e+00 -6.3927e-02 -5.9100e-01 - -1.4256e+00 -3.1972e-02 -5.9100e-01 - -1.4260e+00 1.7463e-16 -5.9100e-01 - -1.3685e+00 1.6759e-16 -6.9100e-01 - -1.3110e+00 1.6055e-16 -7.9100e-01 - -9.2702e-01 -9.2702e-01 -7.9100e-01 - -9.0823e-01 -9.4543e-01 -7.9100e-01 - -8.8909e-01 -9.6346e-01 -7.9100e-01 - -8.6958e-01 -9.8110e-01 -7.9100e-01 - -8.4972e-01 -9.9835e-01 -7.9100e-01 - -8.2952e-01 -1.0152e+00 -7.9100e-01 - -8.0899e-01 -1.0316e+00 -7.9100e-01 - -7.8813e-01 -1.0476e+00 -7.9100e-01 - -7.6696e-01 -1.0632e+00 -7.9100e-01 - -7.4547e-01 -1.0784e+00 -7.9100e-01 - -7.2369e-01 -1.0932e+00 -7.9100e-01 - -7.0161e-01 -1.1075e+00 -7.9100e-01 - -6.7926e-01 -1.1213e+00 -7.9100e-01 - -6.5663e-01 -1.1347e+00 -7.9100e-01 - -6.3373e-01 -1.1477e+00 -7.9100e-01 - -6.1058e-01 -1.1601e+00 -7.9100e-01 - -5.8718e-01 -1.1721e+00 -7.9100e-01 - -5.6355e-01 -1.1837e+00 -7.9100e-01 - -5.3969e-01 -1.1948e+00 -7.9100e-01 - -5.1562e-01 -1.2053e+00 -7.9100e-01 - -5.1562e-01 -1.2053e+00 -7.9100e-01 - -5.3823e-01 -1.2582e+00 -6.9100e-01 - -5.6085e-01 -1.3111e+00 -5.9100e-01 - -5.9010e-01 -1.2982e+00 -5.9100e-01 - -6.1906e-01 -1.2846e+00 -5.9100e-01 - -6.4770e-01 -1.2704e+00 -5.9100e-01 - -6.7602e-01 -1.2556e+00 -5.9100e-01 - -7.0400e-01 -1.2401e+00 -5.9100e-01 - -7.3163e-01 -1.2240e+00 -5.9100e-01 - -7.5889e-01 -1.2073e+00 -5.9100e-01 - -7.8577e-01 -1.1900e+00 -5.9100e-01 - -8.1225e-01 -1.1721e+00 -5.9100e-01 - -8.3832e-01 -1.1536e+00 -5.9100e-01 - -8.6398e-01 -1.1345e+00 -5.9100e-01 - -8.8919e-01 -1.1148e+00 -5.9100e-01 - -9.1397e-01 -1.0946e+00 -5.9100e-01 - -9.3828e-01 -1.0738e+00 -5.9100e-01 - -9.6212e-01 -1.0525e+00 -5.9100e-01 - -9.8547e-01 -1.0307e+00 -5.9100e-01 - -1.0083e+00 -1.0083e+00 -5.9100e-01 - -9.6768e-01 -9.6768e-01 -6.9100e-01 - -9.2702e-01 -9.2702e-01 -7.9100e-01 - -2.4083e-16 -1.3110e+00 -7.9100e-01 - 2.6300e-02 -1.3107e+00 -7.9100e-01 - 5.2589e-02 -1.3099e+00 -7.9100e-01 - 7.8857e-02 -1.3086e+00 -7.9100e-01 - 1.0509e-01 -1.3068e+00 -7.9100e-01 - 1.3129e-01 -1.3044e+00 -7.9100e-01 - 1.5743e-01 -1.3015e+00 -7.9100e-01 - 1.8351e-01 -1.2981e+00 -7.9100e-01 - 2.0951e-01 -1.2942e+00 -7.9100e-01 - 2.3543e-01 -1.2897e+00 -7.9100e-01 - 2.6125e-01 -1.2847e+00 -7.9100e-01 - 2.8697e-01 -1.2792e+00 -7.9100e-01 - 3.1258e-01 -1.2732e+00 -7.9100e-01 - 3.3806e-01 -1.2667e+00 -7.9100e-01 - 3.6340e-01 -1.2596e+00 -7.9100e-01 - 3.8859e-01 -1.2521e+00 -7.9100e-01 - 4.1363e-01 -1.2440e+00 -7.9100e-01 - 4.3851e-01 -1.2355e+00 -7.9100e-01 - 4.6320e-01 -1.2264e+00 -7.9100e-01 - 4.8771e-01 -1.2169e+00 -7.9100e-01 - 4.8771e-01 -1.2169e+00 -7.9100e-01 - 5.0910e-01 -1.2703e+00 -6.9100e-01 - 5.3049e-01 -1.3237e+00 -5.9100e-01 - 5.0068e-01 -1.3352e+00 -5.9100e-01 - 4.7062e-01 -1.3461e+00 -5.9100e-01 - 4.4032e-01 -1.3563e+00 -5.9100e-01 - 4.0980e-01 -1.3658e+00 -5.9100e-01 - 3.7908e-01 -1.3747e+00 -5.9100e-01 - 3.4816e-01 -1.3828e+00 -5.9100e-01 - 3.1707e-01 -1.3903e+00 -5.9100e-01 - 2.8582e-01 -1.3971e+00 -5.9100e-01 - 2.5442e-01 -1.4031e+00 -5.9100e-01 - 2.2290e-01 -1.4085e+00 -5.9100e-01 - 1.9127e-01 -1.4131e+00 -5.9100e-01 - 1.5954e-01 -1.4170e+00 -5.9100e-01 - 1.2773e-01 -1.4203e+00 -5.9100e-01 - 9.5850e-02 -1.4228e+00 -5.9100e-01 - 6.3927e-02 -1.4246e+00 -5.9100e-01 - 3.1972e-02 -1.4256e+00 -5.9100e-01 - -2.6195e-16 -1.4260e+00 -5.9100e-01 - -2.5139e-16 -1.3685e+00 -6.9100e-01 - -2.4083e-16 -1.3110e+00 -7.9100e-01 - 9.2702e-01 -9.2702e-01 -7.9100e-01 - 9.4543e-01 -9.0823e-01 -7.9100e-01 - 9.6346e-01 -8.8909e-01 -7.9100e-01 - 9.8110e-01 -8.6958e-01 -7.9100e-01 - 9.9835e-01 -8.4972e-01 -7.9100e-01 - 1.0152e+00 -8.2952e-01 -7.9100e-01 - 1.0316e+00 -8.0899e-01 -7.9100e-01 - 1.0476e+00 -7.8813e-01 -7.9100e-01 - 1.0632e+00 -7.6696e-01 -7.9100e-01 - 1.0784e+00 -7.4547e-01 -7.9100e-01 - 1.0932e+00 -7.2369e-01 -7.9100e-01 - 1.1075e+00 -7.0161e-01 -7.9100e-01 - 1.1213e+00 -6.7926e-01 -7.9100e-01 - 1.1347e+00 -6.5663e-01 -7.9100e-01 - 1.1477e+00 -6.3373e-01 -7.9100e-01 - 1.1601e+00 -6.1058e-01 -7.9100e-01 - 1.1721e+00 -5.8718e-01 -7.9100e-01 - 1.1837e+00 -5.6355e-01 -7.9100e-01 - 1.1948e+00 -5.3969e-01 -7.9100e-01 - 1.2053e+00 -5.1562e-01 -7.9100e-01 - 1.2053e+00 -5.1562e-01 -7.9100e-01 - 1.2582e+00 -5.3823e-01 -6.9100e-01 - 1.3111e+00 -5.6085e-01 -5.9100e-01 - 1.2982e+00 -5.9010e-01 -5.9100e-01 - 1.2846e+00 -6.1906e-01 -5.9100e-01 - 1.2704e+00 -6.4770e-01 -5.9100e-01 - 1.2556e+00 -6.7602e-01 -5.9100e-01 - 1.2401e+00 -7.0400e-01 -5.9100e-01 - 1.2240e+00 -7.3163e-01 -5.9100e-01 - 1.2073e+00 -7.5889e-01 -5.9100e-01 - 1.1900e+00 -7.8577e-01 -5.9100e-01 - 1.1721e+00 -8.1225e-01 -5.9100e-01 - 1.1536e+00 -8.3832e-01 -5.9100e-01 - 1.1345e+00 -8.6398e-01 -5.9100e-01 - 1.1148e+00 -8.8919e-01 -5.9100e-01 - 1.0946e+00 -9.1397e-01 -5.9100e-01 - 1.0738e+00 -9.3828e-01 -5.9100e-01 - 1.0525e+00 -9.6212e-01 -5.9100e-01 - 1.0307e+00 -9.8547e-01 -5.9100e-01 - 1.0083e+00 -1.0083e+00 -5.9100e-01 - 9.6768e-01 -9.6768e-01 -6.9100e-01 - 9.2702e-01 -9.2702e-01 -7.9100e-01 + 8 1 42 1.00 + 1.3110e+00 0.0000e+00 -7.9100e-01 + 1.3107e+00 2.6300e-02 -7.9100e-01 + 1.3099e+00 5.2589e-02 -7.9100e-01 + 1.3086e+00 7.8857e-02 -7.9100e-01 + 1.3068e+00 1.0509e-01 -7.9100e-01 + 1.3044e+00 1.3129e-01 -7.9100e-01 + 1.3015e+00 1.5743e-01 -7.9100e-01 + 1.2981e+00 1.8351e-01 -7.9100e-01 + 1.2942e+00 2.0951e-01 -7.9100e-01 + 1.2897e+00 2.3543e-01 -7.9100e-01 + 1.2847e+00 2.6125e-01 -7.9100e-01 + 1.2792e+00 2.8697e-01 -7.9100e-01 + 1.2732e+00 3.1258e-01 -7.9100e-01 + 1.2667e+00 3.3806e-01 -7.9100e-01 + 1.2596e+00 3.6340e-01 -7.9100e-01 + 1.2521e+00 3.8859e-01 -7.9100e-01 + 1.2440e+00 4.1363e-01 -7.9100e-01 + 1.2355e+00 4.3851e-01 -7.9100e-01 + 1.2264e+00 4.6320e-01 -7.9100e-01 + 1.2169e+00 4.8771e-01 -7.9100e-01 + 1.2169e+00 4.8771e-01 -7.9100e-01 + 1.2703e+00 5.0910e-01 -6.9100e-01 + 1.3237e+00 5.3049e-01 -5.9100e-01 + 1.3352e+00 5.0068e-01 -5.9100e-01 + 1.3461e+00 4.7062e-01 -5.9100e-01 + 1.3563e+00 4.4032e-01 -5.9100e-01 + 1.3658e+00 4.0980e-01 -5.9100e-01 + 1.3747e+00 3.7908e-01 -5.9100e-01 + 1.3828e+00 3.4816e-01 -5.9100e-01 + 1.3903e+00 3.1707e-01 -5.9100e-01 + 1.3971e+00 2.8582e-01 -5.9100e-01 + 1.4031e+00 2.5442e-01 -5.9100e-01 + 1.4085e+00 2.2290e-01 -5.9100e-01 + 1.4131e+00 1.9127e-01 -5.9100e-01 + 1.4170e+00 1.5954e-01 -5.9100e-01 + 1.4203e+00 1.2773e-01 -5.9100e-01 + 1.4228e+00 9.5850e-02 -5.9100e-01 + 1.4246e+00 6.3927e-02 -5.9100e-01 + 1.4256e+00 3.1972e-02 -5.9100e-01 + 1.4260e+00 0.0000e+00 -5.9100e-01 + 1.3685e+00 0.0000e+00 -6.9100e-01 + 1.3110e+00 0.0000e+00 -7.9100e-01 + 9.2702e-01 9.2702e-01 -7.9100e-01 + 9.0823e-01 9.4543e-01 -7.9100e-01 + 8.8909e-01 9.6346e-01 -7.9100e-01 + 8.6958e-01 9.8110e-01 -7.9100e-01 + 8.4972e-01 9.9835e-01 -7.9100e-01 + 8.2952e-01 1.0152e+00 -7.9100e-01 + 8.0899e-01 1.0316e+00 -7.9100e-01 + 7.8813e-01 1.0476e+00 -7.9100e-01 + 7.6696e-01 1.0632e+00 -7.9100e-01 + 7.4547e-01 1.0784e+00 -7.9100e-01 + 7.2369e-01 1.0932e+00 -7.9100e-01 + 7.0161e-01 1.1075e+00 -7.9100e-01 + 6.7926e-01 1.1213e+00 -7.9100e-01 + 6.5663e-01 1.1347e+00 -7.9100e-01 + 6.3373e-01 1.1477e+00 -7.9100e-01 + 6.1058e-01 1.1601e+00 -7.9100e-01 + 5.8718e-01 1.1721e+00 -7.9100e-01 + 5.6355e-01 1.1837e+00 -7.9100e-01 + 5.3969e-01 1.1948e+00 -7.9100e-01 + 5.1562e-01 1.2053e+00 -7.9100e-01 + 5.1562e-01 1.2053e+00 -7.9100e-01 + 5.3823e-01 1.2582e+00 -6.9100e-01 + 5.6085e-01 1.3111e+00 -5.9100e-01 + 5.9010e-01 1.2982e+00 -5.9100e-01 + 6.1906e-01 1.2846e+00 -5.9100e-01 + 6.4770e-01 1.2704e+00 -5.9100e-01 + 6.7602e-01 1.2556e+00 -5.9100e-01 + 7.0400e-01 1.2401e+00 -5.9100e-01 + 7.3163e-01 1.2240e+00 -5.9100e-01 + 7.5889e-01 1.2073e+00 -5.9100e-01 + 7.8577e-01 1.1900e+00 -5.9100e-01 + 8.1225e-01 1.1721e+00 -5.9100e-01 + 8.3832e-01 1.1536e+00 -5.9100e-01 + 8.6398e-01 1.1345e+00 -5.9100e-01 + 8.8919e-01 1.1148e+00 -5.9100e-01 + 9.1397e-01 1.0946e+00 -5.9100e-01 + 9.3828e-01 1.0738e+00 -5.9100e-01 + 9.6212e-01 1.0525e+00 -5.9100e-01 + 9.8547e-01 1.0307e+00 -5.9100e-01 + 1.0083e+00 1.0083e+00 -5.9100e-01 + 9.6768e-01 9.6768e-01 -6.9100e-01 + 9.2702e-01 9.2702e-01 -7.9100e-01 + 8.0276e-17 1.3110e+00 -7.9100e-01 + -2.6300e-02 1.3107e+00 -7.9100e-01 + -5.2589e-02 1.3099e+00 -7.9100e-01 + -7.8857e-02 1.3086e+00 -7.9100e-01 + -1.0509e-01 1.3068e+00 -7.9100e-01 + -1.3129e-01 1.3044e+00 -7.9100e-01 + -1.5743e-01 1.3015e+00 -7.9100e-01 + -1.8351e-01 1.2981e+00 -7.9100e-01 + -2.0951e-01 1.2942e+00 -7.9100e-01 + -2.3543e-01 1.2897e+00 -7.9100e-01 + -2.6125e-01 1.2847e+00 -7.9100e-01 + -2.8697e-01 1.2792e+00 -7.9100e-01 + -3.1258e-01 1.2732e+00 -7.9100e-01 + -3.3806e-01 1.2667e+00 -7.9100e-01 + -3.6340e-01 1.2596e+00 -7.9100e-01 + -3.8859e-01 1.2521e+00 -7.9100e-01 + -4.1363e-01 1.2440e+00 -7.9100e-01 + -4.3851e-01 1.2355e+00 -7.9100e-01 + -4.6320e-01 1.2264e+00 -7.9100e-01 + -4.8771e-01 1.2169e+00 -7.9100e-01 + -4.8771e-01 1.2169e+00 -7.9100e-01 + -5.0910e-01 1.2703e+00 -6.9100e-01 + -5.3049e-01 1.3237e+00 -5.9100e-01 + -5.0068e-01 1.3352e+00 -5.9100e-01 + -4.7062e-01 1.3461e+00 -5.9100e-01 + -4.4032e-01 1.3563e+00 -5.9100e-01 + -4.0980e-01 1.3658e+00 -5.9100e-01 + -3.7908e-01 1.3747e+00 -5.9100e-01 + -3.4816e-01 1.3828e+00 -5.9100e-01 + -3.1707e-01 1.3903e+00 -5.9100e-01 + -2.8582e-01 1.3971e+00 -5.9100e-01 + -2.5442e-01 1.4031e+00 -5.9100e-01 + -2.2290e-01 1.4085e+00 -5.9100e-01 + -1.9127e-01 1.4131e+00 -5.9100e-01 + -1.5954e-01 1.4170e+00 -5.9100e-01 + -1.2773e-01 1.4203e+00 -5.9100e-01 + -9.5850e-02 1.4228e+00 -5.9100e-01 + -6.3927e-02 1.4246e+00 -5.9100e-01 + -3.1972e-02 1.4256e+00 -5.9100e-01 + 8.7317e-17 1.4260e+00 -5.9100e-01 + 8.3796e-17 1.3685e+00 -6.9100e-01 + 8.0276e-17 1.3110e+00 -7.9100e-01 + -9.2702e-01 9.2702e-01 -7.9100e-01 + -9.4543e-01 9.0823e-01 -7.9100e-01 + -9.6346e-01 8.8909e-01 -7.9100e-01 + -9.8110e-01 8.6958e-01 -7.9100e-01 + -9.9835e-01 8.4972e-01 -7.9100e-01 + -1.0152e+00 8.2952e-01 -7.9100e-01 + -1.0316e+00 8.0899e-01 -7.9100e-01 + -1.0476e+00 7.8813e-01 -7.9100e-01 + -1.0632e+00 7.6696e-01 -7.9100e-01 + -1.0784e+00 7.4547e-01 -7.9100e-01 + -1.0932e+00 7.2369e-01 -7.9100e-01 + -1.1075e+00 7.0161e-01 -7.9100e-01 + -1.1213e+00 6.7926e-01 -7.9100e-01 + -1.1347e+00 6.5663e-01 -7.9100e-01 + -1.1477e+00 6.3373e-01 -7.9100e-01 + -1.1601e+00 6.1058e-01 -7.9100e-01 + -1.1721e+00 5.8718e-01 -7.9100e-01 + -1.1837e+00 5.6355e-01 -7.9100e-01 + -1.1948e+00 5.3969e-01 -7.9100e-01 + -1.2053e+00 5.1562e-01 -7.9100e-01 + -1.2053e+00 5.1562e-01 -7.9100e-01 + -1.2582e+00 5.3823e-01 -6.9100e-01 + -1.3111e+00 5.6085e-01 -5.9100e-01 + -1.2982e+00 5.9010e-01 -5.9100e-01 + -1.2846e+00 6.1906e-01 -5.9100e-01 + -1.2704e+00 6.4770e-01 -5.9100e-01 + -1.2556e+00 6.7602e-01 -5.9100e-01 + -1.2401e+00 7.0400e-01 -5.9100e-01 + -1.2240e+00 7.3163e-01 -5.9100e-01 + -1.2073e+00 7.5889e-01 -5.9100e-01 + -1.1900e+00 7.8577e-01 -5.9100e-01 + -1.1721e+00 8.1225e-01 -5.9100e-01 + -1.1536e+00 8.3832e-01 -5.9100e-01 + -1.1345e+00 8.6398e-01 -5.9100e-01 + -1.1148e+00 8.8919e-01 -5.9100e-01 + -1.0946e+00 9.1397e-01 -5.9100e-01 + -1.0738e+00 9.3828e-01 -5.9100e-01 + -1.0525e+00 9.6212e-01 -5.9100e-01 + -1.0307e+00 9.8547e-01 -5.9100e-01 + -1.0083e+00 1.0083e+00 -5.9100e-01 + -9.6768e-01 9.6768e-01 -6.9100e-01 + -9.2702e-01 9.2702e-01 -7.9100e-01 + -1.3110e+00 1.6055e-16 -7.9100e-01 + -1.3107e+00 -2.6300e-02 -7.9100e-01 + -1.3099e+00 -5.2589e-02 -7.9100e-01 + -1.3086e+00 -7.8857e-02 -7.9100e-01 + -1.3068e+00 -1.0509e-01 -7.9100e-01 + -1.3044e+00 -1.3129e-01 -7.9100e-01 + -1.3015e+00 -1.5743e-01 -7.9100e-01 + -1.2981e+00 -1.8351e-01 -7.9100e-01 + -1.2942e+00 -2.0951e-01 -7.9100e-01 + -1.2897e+00 -2.3543e-01 -7.9100e-01 + -1.2847e+00 -2.6125e-01 -7.9100e-01 + -1.2792e+00 -2.8697e-01 -7.9100e-01 + -1.2732e+00 -3.1258e-01 -7.9100e-01 + -1.2667e+00 -3.3806e-01 -7.9100e-01 + -1.2596e+00 -3.6340e-01 -7.9100e-01 + -1.2521e+00 -3.8859e-01 -7.9100e-01 + -1.2440e+00 -4.1363e-01 -7.9100e-01 + -1.2355e+00 -4.3851e-01 -7.9100e-01 + -1.2264e+00 -4.6320e-01 -7.9100e-01 + -1.2169e+00 -4.8771e-01 -7.9100e-01 + -1.2169e+00 -4.8771e-01 -7.9100e-01 + -1.2703e+00 -5.0910e-01 -6.9100e-01 + -1.3237e+00 -5.3049e-01 -5.9100e-01 + -1.3352e+00 -5.0068e-01 -5.9100e-01 + -1.3461e+00 -4.7062e-01 -5.9100e-01 + -1.3563e+00 -4.4032e-01 -5.9100e-01 + -1.3658e+00 -4.0980e-01 -5.9100e-01 + -1.3747e+00 -3.7908e-01 -5.9100e-01 + -1.3828e+00 -3.4816e-01 -5.9100e-01 + -1.3903e+00 -3.1707e-01 -5.9100e-01 + -1.3971e+00 -2.8582e-01 -5.9100e-01 + -1.4031e+00 -2.5442e-01 -5.9100e-01 + -1.4085e+00 -2.2290e-01 -5.9100e-01 + -1.4131e+00 -1.9127e-01 -5.9100e-01 + -1.4170e+00 -1.5954e-01 -5.9100e-01 + -1.4203e+00 -1.2773e-01 -5.9100e-01 + -1.4228e+00 -9.5850e-02 -5.9100e-01 + -1.4246e+00 -6.3927e-02 -5.9100e-01 + -1.4256e+00 -3.1972e-02 -5.9100e-01 + -1.4260e+00 1.7463e-16 -5.9100e-01 + -1.3685e+00 1.6759e-16 -6.9100e-01 + -1.3110e+00 1.6055e-16 -7.9100e-01 + -9.2702e-01 -9.2702e-01 -7.9100e-01 + -9.0823e-01 -9.4543e-01 -7.9100e-01 + -8.8909e-01 -9.6346e-01 -7.9100e-01 + -8.6958e-01 -9.8110e-01 -7.9100e-01 + -8.4972e-01 -9.9835e-01 -7.9100e-01 + -8.2952e-01 -1.0152e+00 -7.9100e-01 + -8.0899e-01 -1.0316e+00 -7.9100e-01 + -7.8813e-01 -1.0476e+00 -7.9100e-01 + -7.6696e-01 -1.0632e+00 -7.9100e-01 + -7.4547e-01 -1.0784e+00 -7.9100e-01 + -7.2369e-01 -1.0932e+00 -7.9100e-01 + -7.0161e-01 -1.1075e+00 -7.9100e-01 + -6.7926e-01 -1.1213e+00 -7.9100e-01 + -6.5663e-01 -1.1347e+00 -7.9100e-01 + -6.3373e-01 -1.1477e+00 -7.9100e-01 + -6.1058e-01 -1.1601e+00 -7.9100e-01 + -5.8718e-01 -1.1721e+00 -7.9100e-01 + -5.6355e-01 -1.1837e+00 -7.9100e-01 + -5.3969e-01 -1.1948e+00 -7.9100e-01 + -5.1562e-01 -1.2053e+00 -7.9100e-01 + -5.1562e-01 -1.2053e+00 -7.9100e-01 + -5.3823e-01 -1.2582e+00 -6.9100e-01 + -5.6085e-01 -1.3111e+00 -5.9100e-01 + -5.9010e-01 -1.2982e+00 -5.9100e-01 + -6.1906e-01 -1.2846e+00 -5.9100e-01 + -6.4770e-01 -1.2704e+00 -5.9100e-01 + -6.7602e-01 -1.2556e+00 -5.9100e-01 + -7.0400e-01 -1.2401e+00 -5.9100e-01 + -7.3163e-01 -1.2240e+00 -5.9100e-01 + -7.5889e-01 -1.2073e+00 -5.9100e-01 + -7.8577e-01 -1.1900e+00 -5.9100e-01 + -8.1225e-01 -1.1721e+00 -5.9100e-01 + -8.3832e-01 -1.1536e+00 -5.9100e-01 + -8.6398e-01 -1.1345e+00 -5.9100e-01 + -8.8919e-01 -1.1148e+00 -5.9100e-01 + -9.1397e-01 -1.0946e+00 -5.9100e-01 + -9.3828e-01 -1.0738e+00 -5.9100e-01 + -9.6212e-01 -1.0525e+00 -5.9100e-01 + -9.8547e-01 -1.0307e+00 -5.9100e-01 + -1.0083e+00 -1.0083e+00 -5.9100e-01 + -9.6768e-01 -9.6768e-01 -6.9100e-01 + -9.2702e-01 -9.2702e-01 -7.9100e-01 + -2.4083e-16 -1.3110e+00 -7.9100e-01 + 2.6300e-02 -1.3107e+00 -7.9100e-01 + 5.2589e-02 -1.3099e+00 -7.9100e-01 + 7.8857e-02 -1.3086e+00 -7.9100e-01 + 1.0509e-01 -1.3068e+00 -7.9100e-01 + 1.3129e-01 -1.3044e+00 -7.9100e-01 + 1.5743e-01 -1.3015e+00 -7.9100e-01 + 1.8351e-01 -1.2981e+00 -7.9100e-01 + 2.0951e-01 -1.2942e+00 -7.9100e-01 + 2.3543e-01 -1.2897e+00 -7.9100e-01 + 2.6125e-01 -1.2847e+00 -7.9100e-01 + 2.8697e-01 -1.2792e+00 -7.9100e-01 + 3.1258e-01 -1.2732e+00 -7.9100e-01 + 3.3806e-01 -1.2667e+00 -7.9100e-01 + 3.6340e-01 -1.2596e+00 -7.9100e-01 + 3.8859e-01 -1.2521e+00 -7.9100e-01 + 4.1363e-01 -1.2440e+00 -7.9100e-01 + 4.3851e-01 -1.2355e+00 -7.9100e-01 + 4.6320e-01 -1.2264e+00 -7.9100e-01 + 4.8771e-01 -1.2169e+00 -7.9100e-01 + 4.8771e-01 -1.2169e+00 -7.9100e-01 + 5.0910e-01 -1.2703e+00 -6.9100e-01 + 5.3049e-01 -1.3237e+00 -5.9100e-01 + 5.0068e-01 -1.3352e+00 -5.9100e-01 + 4.7062e-01 -1.3461e+00 -5.9100e-01 + 4.4032e-01 -1.3563e+00 -5.9100e-01 + 4.0980e-01 -1.3658e+00 -5.9100e-01 + 3.7908e-01 -1.3747e+00 -5.9100e-01 + 3.4816e-01 -1.3828e+00 -5.9100e-01 + 3.1707e-01 -1.3903e+00 -5.9100e-01 + 2.8582e-01 -1.3971e+00 -5.9100e-01 + 2.5442e-01 -1.4031e+00 -5.9100e-01 + 2.2290e-01 -1.4085e+00 -5.9100e-01 + 1.9127e-01 -1.4131e+00 -5.9100e-01 + 1.5954e-01 -1.4170e+00 -5.9100e-01 + 1.2773e-01 -1.4203e+00 -5.9100e-01 + 9.5850e-02 -1.4228e+00 -5.9100e-01 + 6.3927e-02 -1.4246e+00 -5.9100e-01 + 3.1972e-02 -1.4256e+00 -5.9100e-01 + -2.6195e-16 -1.4260e+00 -5.9100e-01 + -2.5139e-16 -1.3685e+00 -6.9100e-01 + -2.4083e-16 -1.3110e+00 -7.9100e-01 + 9.2702e-01 -9.2702e-01 -7.9100e-01 + 9.4543e-01 -9.0823e-01 -7.9100e-01 + 9.6346e-01 -8.8909e-01 -7.9100e-01 + 9.8110e-01 -8.6958e-01 -7.9100e-01 + 9.9835e-01 -8.4972e-01 -7.9100e-01 + 1.0152e+00 -8.2952e-01 -7.9100e-01 + 1.0316e+00 -8.0899e-01 -7.9100e-01 + 1.0476e+00 -7.8813e-01 -7.9100e-01 + 1.0632e+00 -7.6696e-01 -7.9100e-01 + 1.0784e+00 -7.4547e-01 -7.9100e-01 + 1.0932e+00 -7.2369e-01 -7.9100e-01 + 1.1075e+00 -7.0161e-01 -7.9100e-01 + 1.1213e+00 -6.7926e-01 -7.9100e-01 + 1.1347e+00 -6.5663e-01 -7.9100e-01 + 1.1477e+00 -6.3373e-01 -7.9100e-01 + 1.1601e+00 -6.1058e-01 -7.9100e-01 + 1.1721e+00 -5.8718e-01 -7.9100e-01 + 1.1837e+00 -5.6355e-01 -7.9100e-01 + 1.1948e+00 -5.3969e-01 -7.9100e-01 + 1.2053e+00 -5.1562e-01 -7.9100e-01 + 1.2053e+00 -5.1562e-01 -7.9100e-01 + 1.2582e+00 -5.3823e-01 -6.9100e-01 + 1.3111e+00 -5.6085e-01 -5.9100e-01 + 1.2982e+00 -5.9010e-01 -5.9100e-01 + 1.2846e+00 -6.1906e-01 -5.9100e-01 + 1.2704e+00 -6.4770e-01 -5.9100e-01 + 1.2556e+00 -6.7602e-01 -5.9100e-01 + 1.2401e+00 -7.0400e-01 -5.9100e-01 + 1.2240e+00 -7.3163e-01 -5.9100e-01 + 1.2073e+00 -7.5889e-01 -5.9100e-01 + 1.1900e+00 -7.8577e-01 -5.9100e-01 + 1.1721e+00 -8.1225e-01 -5.9100e-01 + 1.1536e+00 -8.3832e-01 -5.9100e-01 + 1.1345e+00 -8.6398e-01 -5.9100e-01 + 1.1148e+00 -8.8919e-01 -5.9100e-01 + 1.0946e+00 -9.1397e-01 -5.9100e-01 + 1.0738e+00 -9.3828e-01 -5.9100e-01 + 1.0525e+00 -9.6212e-01 -5.9100e-01 + 1.0307e+00 -9.8547e-01 -5.9100e-01 + 1.0083e+00 -1.0083e+00 -5.9100e-01 + 9.6768e-01 -9.6768e-01 -6.9100e-01 + 9.2702e-01 -9.2702e-01 -7.9100e-01 diff --git a/src/ForcingTerms/coil_geometries/mastu_rmpu.dat b/src/ForcingTerms/coil_geometries/mastu_rmpu.dat index 59d20c96d..ba2a4e14f 100644 --- a/src/ForcingTerms/coil_geometries/mastu_rmpu.dat +++ b/src/ForcingTerms/coil_geometries/mastu_rmpu.dat @@ -1,169 +1,169 @@ - 4 1 42 1.00 - 1.4180e+00 0.0000e+00 7.6000e-01 - 1.4177e+00 3.0026e-02 7.6000e-01 - 1.4167e+00 6.0039e-02 7.6000e-01 - 1.4151e+00 9.0025e-02 7.6000e-01 - 1.4129e+00 1.1997e-01 7.6000e-01 - 1.4101e+00 1.4986e-01 7.6000e-01 - 1.4066e+00 1.7969e-01 7.6000e-01 - 1.4024e+00 2.0943e-01 7.6000e-01 - 1.3977e+00 2.3908e-01 7.6000e-01 - 1.3923e+00 2.6862e-01 7.6000e-01 - 1.3863e+00 2.9805e-01 7.6000e-01 - 1.3797e+00 3.2733e-01 7.6000e-01 - 1.3725e+00 3.5648e-01 7.6000e-01 - 1.3646e+00 3.8546e-01 7.6000e-01 - 1.3561e+00 4.1427e-01 7.6000e-01 - 1.3471e+00 4.4289e-01 7.6000e-01 - 1.3374e+00 4.7132e-01 7.6000e-01 - 1.3271e+00 4.9953e-01 7.6000e-01 - 1.3162e+00 5.2752e-01 7.6000e-01 - 1.3162e+00 5.2752e-01 7.6000e-01 - 1.3487e+00 5.4054e-01 6.2950e-01 - 1.3812e+00 5.5356e-01 4.9900e-01 - 1.3926e+00 5.2419e-01 4.9900e-01 - 1.4034e+00 4.9458e-01 4.9900e-01 - 1.4136e+00 4.6475e-01 4.9900e-01 - 1.4231e+00 4.3472e-01 4.9900e-01 - 1.4320e+00 4.0449e-01 4.9900e-01 - 1.4402e+00 3.7407e-01 4.9900e-01 - 1.4478e+00 3.4349e-01 4.9900e-01 - 1.4548e+00 3.1276e-01 4.9900e-01 - 1.4611e+00 2.8188e-01 4.9900e-01 - 1.4667e+00 2.5088e-01 4.9900e-01 - 1.4717e+00 2.1977e-01 4.9900e-01 - 1.4760e+00 1.8856e-01 4.9900e-01 - 1.4797e+00 1.5726e-01 4.9900e-01 - 1.4827e+00 1.2589e-01 4.9900e-01 - 1.4850e+00 9.4469e-02 4.9900e-01 - 1.4867e+00 6.3003e-02 4.9900e-01 - 1.4877e+00 3.1509e-02 4.9900e-01 - 1.4880e+00 0.0000e+00 4.9900e-01 - 1.4530e+00 0.0000e+00 6.2950e-01 - 1.4180e+00 0.0000e+00 7.6000e-01 - 8.6827e-17 1.4180e+00 7.6000e-01 - -3.0026e-02 1.4177e+00 7.6000e-01 - -6.0039e-02 1.4167e+00 7.6000e-01 - -9.0025e-02 1.4151e+00 7.6000e-01 - -1.1997e-01 1.4129e+00 7.6000e-01 - -1.4986e-01 1.4101e+00 7.6000e-01 - -1.7969e-01 1.4066e+00 7.6000e-01 - -2.0943e-01 1.4024e+00 7.6000e-01 - -2.3908e-01 1.3977e+00 7.6000e-01 - -2.6862e-01 1.3923e+00 7.6000e-01 - -2.9805e-01 1.3863e+00 7.6000e-01 - -3.2733e-01 1.3797e+00 7.6000e-01 - -3.5648e-01 1.3725e+00 7.6000e-01 - -3.8546e-01 1.3646e+00 7.6000e-01 - -4.1427e-01 1.3561e+00 7.6000e-01 - -4.4289e-01 1.3471e+00 7.6000e-01 - -4.7132e-01 1.3374e+00 7.6000e-01 - -4.9953e-01 1.3271e+00 7.6000e-01 - -5.2752e-01 1.3162e+00 7.6000e-01 - -5.2752e-01 1.3162e+00 7.6000e-01 - -5.4054e-01 1.3487e+00 6.2950e-01 - -5.5356e-01 1.3812e+00 4.9900e-01 - -5.2419e-01 1.3926e+00 4.9900e-01 - -4.9458e-01 1.4034e+00 4.9900e-01 - -4.6475e-01 1.4136e+00 4.9900e-01 - -4.3472e-01 1.4231e+00 4.9900e-01 - -4.0449e-01 1.4320e+00 4.9900e-01 - -3.7407e-01 1.4402e+00 4.9900e-01 - -3.4349e-01 1.4478e+00 4.9900e-01 - -3.1276e-01 1.4548e+00 4.9900e-01 - -2.8188e-01 1.4611e+00 4.9900e-01 - -2.5088e-01 1.4667e+00 4.9900e-01 - -2.1977e-01 1.4717e+00 4.9900e-01 - -1.8856e-01 1.4760e+00 4.9900e-01 - -1.5726e-01 1.4797e+00 4.9900e-01 - -1.2589e-01 1.4827e+00 4.9900e-01 - -9.4469e-02 1.4850e+00 4.9900e-01 - -6.3003e-02 1.4867e+00 4.9900e-01 - -3.1509e-02 1.4877e+00 4.9900e-01 - 9.1114e-17 1.4880e+00 4.9900e-01 - 8.8971e-17 1.4530e+00 6.2950e-01 - 8.6827e-17 1.4180e+00 7.6000e-01 - -1.4180e+00 1.7365e-16 7.6000e-01 - -1.4177e+00 -3.0026e-02 7.6000e-01 - -1.4167e+00 -6.0039e-02 7.6000e-01 - -1.4151e+00 -9.0025e-02 7.6000e-01 - -1.4129e+00 -1.1997e-01 7.6000e-01 - -1.4101e+00 -1.4986e-01 7.6000e-01 - -1.4066e+00 -1.7969e-01 7.6000e-01 - -1.4024e+00 -2.0943e-01 7.6000e-01 - -1.3977e+00 -2.3908e-01 7.6000e-01 - -1.3923e+00 -2.6862e-01 7.6000e-01 - -1.3863e+00 -2.9805e-01 7.6000e-01 - -1.3797e+00 -3.2733e-01 7.6000e-01 - -1.3725e+00 -3.5648e-01 7.6000e-01 - -1.3646e+00 -3.8546e-01 7.6000e-01 - -1.3561e+00 -4.1427e-01 7.6000e-01 - -1.3471e+00 -4.4289e-01 7.6000e-01 - -1.3374e+00 -4.7132e-01 7.6000e-01 - -1.3271e+00 -4.9953e-01 7.6000e-01 - -1.3162e+00 -5.2752e-01 7.6000e-01 - -1.3162e+00 -5.2752e-01 7.6000e-01 - -1.3487e+00 -5.4054e-01 6.2950e-01 - -1.3812e+00 -5.5356e-01 4.9900e-01 - -1.3926e+00 -5.2419e-01 4.9900e-01 - -1.4034e+00 -4.9458e-01 4.9900e-01 - -1.4136e+00 -4.6475e-01 4.9900e-01 - -1.4231e+00 -4.3472e-01 4.9900e-01 - -1.4320e+00 -4.0449e-01 4.9900e-01 - -1.4402e+00 -3.7407e-01 4.9900e-01 - -1.4478e+00 -3.4349e-01 4.9900e-01 - -1.4548e+00 -3.1276e-01 4.9900e-01 - -1.4611e+00 -2.8188e-01 4.9900e-01 - -1.4667e+00 -2.5088e-01 4.9900e-01 - -1.4717e+00 -2.1977e-01 4.9900e-01 - -1.4760e+00 -1.8856e-01 4.9900e-01 - -1.4797e+00 -1.5726e-01 4.9900e-01 - -1.4827e+00 -1.2589e-01 4.9900e-01 - -1.4850e+00 -9.4469e-02 4.9900e-01 - -1.4867e+00 -6.3003e-02 4.9900e-01 - -1.4877e+00 -3.1509e-02 4.9900e-01 - -1.4880e+00 1.8223e-16 4.9900e-01 - -1.4530e+00 1.7794e-16 6.2950e-01 - -1.4180e+00 1.7365e-16 7.6000e-01 - -2.6048e-16 -1.4180e+00 7.6000e-01 - 3.0026e-02 -1.4177e+00 7.6000e-01 - 6.0039e-02 -1.4167e+00 7.6000e-01 - 9.0025e-02 -1.4151e+00 7.6000e-01 - 1.1997e-01 -1.4129e+00 7.6000e-01 - 1.4986e-01 -1.4101e+00 7.6000e-01 - 1.7969e-01 -1.4066e+00 7.6000e-01 - 2.0943e-01 -1.4024e+00 7.6000e-01 - 2.3908e-01 -1.3977e+00 7.6000e-01 - 2.6862e-01 -1.3923e+00 7.6000e-01 - 2.9805e-01 -1.3863e+00 7.6000e-01 - 3.2733e-01 -1.3797e+00 7.6000e-01 - 3.5648e-01 -1.3725e+00 7.6000e-01 - 3.8546e-01 -1.3646e+00 7.6000e-01 - 4.1427e-01 -1.3561e+00 7.6000e-01 - 4.4289e-01 -1.3471e+00 7.6000e-01 - 4.7132e-01 -1.3374e+00 7.6000e-01 - 4.9953e-01 -1.3271e+00 7.6000e-01 - 5.2752e-01 -1.3162e+00 7.6000e-01 - 5.2752e-01 -1.3162e+00 7.6000e-01 - 5.4054e-01 -1.3487e+00 6.2950e-01 - 5.5356e-01 -1.3812e+00 4.9900e-01 - 5.2419e-01 -1.3926e+00 4.9900e-01 - 4.9458e-01 -1.4034e+00 4.9900e-01 - 4.6475e-01 -1.4136e+00 4.9900e-01 - 4.3472e-01 -1.4231e+00 4.9900e-01 - 4.0449e-01 -1.4320e+00 4.9900e-01 - 3.7407e-01 -1.4402e+00 4.9900e-01 - 3.4349e-01 -1.4478e+00 4.9900e-01 - 3.1276e-01 -1.4548e+00 4.9900e-01 - 2.8188e-01 -1.4611e+00 4.9900e-01 - 2.5088e-01 -1.4667e+00 4.9900e-01 - 2.1977e-01 -1.4717e+00 4.9900e-01 - 1.8856e-01 -1.4760e+00 4.9900e-01 - 1.5726e-01 -1.4797e+00 4.9900e-01 - 1.2589e-01 -1.4827e+00 4.9900e-01 - 9.4469e-02 -1.4850e+00 4.9900e-01 - 6.3003e-02 -1.4867e+00 4.9900e-01 - 3.1509e-02 -1.4877e+00 4.9900e-01 - -2.7334e-16 -1.4880e+00 4.9900e-01 - -2.6691e-16 -1.4530e+00 6.2950e-01 - -2.6048e-16 -1.4180e+00 7.6000e-01 + 4 1 42 1.00 + 1.4180e+00 0.0000e+00 7.6000e-01 + 1.4177e+00 3.0026e-02 7.6000e-01 + 1.4167e+00 6.0039e-02 7.6000e-01 + 1.4151e+00 9.0025e-02 7.6000e-01 + 1.4129e+00 1.1997e-01 7.6000e-01 + 1.4101e+00 1.4986e-01 7.6000e-01 + 1.4066e+00 1.7969e-01 7.6000e-01 + 1.4024e+00 2.0943e-01 7.6000e-01 + 1.3977e+00 2.3908e-01 7.6000e-01 + 1.3923e+00 2.6862e-01 7.6000e-01 + 1.3863e+00 2.9805e-01 7.6000e-01 + 1.3797e+00 3.2733e-01 7.6000e-01 + 1.3725e+00 3.5648e-01 7.6000e-01 + 1.3646e+00 3.8546e-01 7.6000e-01 + 1.3561e+00 4.1427e-01 7.6000e-01 + 1.3471e+00 4.4289e-01 7.6000e-01 + 1.3374e+00 4.7132e-01 7.6000e-01 + 1.3271e+00 4.9953e-01 7.6000e-01 + 1.3162e+00 5.2752e-01 7.6000e-01 + 1.3162e+00 5.2752e-01 7.6000e-01 + 1.3487e+00 5.4054e-01 6.2950e-01 + 1.3812e+00 5.5356e-01 4.9900e-01 + 1.3926e+00 5.2419e-01 4.9900e-01 + 1.4034e+00 4.9458e-01 4.9900e-01 + 1.4136e+00 4.6475e-01 4.9900e-01 + 1.4231e+00 4.3472e-01 4.9900e-01 + 1.4320e+00 4.0449e-01 4.9900e-01 + 1.4402e+00 3.7407e-01 4.9900e-01 + 1.4478e+00 3.4349e-01 4.9900e-01 + 1.4548e+00 3.1276e-01 4.9900e-01 + 1.4611e+00 2.8188e-01 4.9900e-01 + 1.4667e+00 2.5088e-01 4.9900e-01 + 1.4717e+00 2.1977e-01 4.9900e-01 + 1.4760e+00 1.8856e-01 4.9900e-01 + 1.4797e+00 1.5726e-01 4.9900e-01 + 1.4827e+00 1.2589e-01 4.9900e-01 + 1.4850e+00 9.4469e-02 4.9900e-01 + 1.4867e+00 6.3003e-02 4.9900e-01 + 1.4877e+00 3.1509e-02 4.9900e-01 + 1.4880e+00 0.0000e+00 4.9900e-01 + 1.4530e+00 0.0000e+00 6.2950e-01 + 1.4180e+00 0.0000e+00 7.6000e-01 + 8.6827e-17 1.4180e+00 7.6000e-01 + -3.0026e-02 1.4177e+00 7.6000e-01 + -6.0039e-02 1.4167e+00 7.6000e-01 + -9.0025e-02 1.4151e+00 7.6000e-01 + -1.1997e-01 1.4129e+00 7.6000e-01 + -1.4986e-01 1.4101e+00 7.6000e-01 + -1.7969e-01 1.4066e+00 7.6000e-01 + -2.0943e-01 1.4024e+00 7.6000e-01 + -2.3908e-01 1.3977e+00 7.6000e-01 + -2.6862e-01 1.3923e+00 7.6000e-01 + -2.9805e-01 1.3863e+00 7.6000e-01 + -3.2733e-01 1.3797e+00 7.6000e-01 + -3.5648e-01 1.3725e+00 7.6000e-01 + -3.8546e-01 1.3646e+00 7.6000e-01 + -4.1427e-01 1.3561e+00 7.6000e-01 + -4.4289e-01 1.3471e+00 7.6000e-01 + -4.7132e-01 1.3374e+00 7.6000e-01 + -4.9953e-01 1.3271e+00 7.6000e-01 + -5.2752e-01 1.3162e+00 7.6000e-01 + -5.2752e-01 1.3162e+00 7.6000e-01 + -5.4054e-01 1.3487e+00 6.2950e-01 + -5.5356e-01 1.3812e+00 4.9900e-01 + -5.2419e-01 1.3926e+00 4.9900e-01 + -4.9458e-01 1.4034e+00 4.9900e-01 + -4.6475e-01 1.4136e+00 4.9900e-01 + -4.3472e-01 1.4231e+00 4.9900e-01 + -4.0449e-01 1.4320e+00 4.9900e-01 + -3.7407e-01 1.4402e+00 4.9900e-01 + -3.4349e-01 1.4478e+00 4.9900e-01 + -3.1276e-01 1.4548e+00 4.9900e-01 + -2.8188e-01 1.4611e+00 4.9900e-01 + -2.5088e-01 1.4667e+00 4.9900e-01 + -2.1977e-01 1.4717e+00 4.9900e-01 + -1.8856e-01 1.4760e+00 4.9900e-01 + -1.5726e-01 1.4797e+00 4.9900e-01 + -1.2589e-01 1.4827e+00 4.9900e-01 + -9.4469e-02 1.4850e+00 4.9900e-01 + -6.3003e-02 1.4867e+00 4.9900e-01 + -3.1509e-02 1.4877e+00 4.9900e-01 + 9.1114e-17 1.4880e+00 4.9900e-01 + 8.8971e-17 1.4530e+00 6.2950e-01 + 8.6827e-17 1.4180e+00 7.6000e-01 + -1.4180e+00 1.7365e-16 7.6000e-01 + -1.4177e+00 -3.0026e-02 7.6000e-01 + -1.4167e+00 -6.0039e-02 7.6000e-01 + -1.4151e+00 -9.0025e-02 7.6000e-01 + -1.4129e+00 -1.1997e-01 7.6000e-01 + -1.4101e+00 -1.4986e-01 7.6000e-01 + -1.4066e+00 -1.7969e-01 7.6000e-01 + -1.4024e+00 -2.0943e-01 7.6000e-01 + -1.3977e+00 -2.3908e-01 7.6000e-01 + -1.3923e+00 -2.6862e-01 7.6000e-01 + -1.3863e+00 -2.9805e-01 7.6000e-01 + -1.3797e+00 -3.2733e-01 7.6000e-01 + -1.3725e+00 -3.5648e-01 7.6000e-01 + -1.3646e+00 -3.8546e-01 7.6000e-01 + -1.3561e+00 -4.1427e-01 7.6000e-01 + -1.3471e+00 -4.4289e-01 7.6000e-01 + -1.3374e+00 -4.7132e-01 7.6000e-01 + -1.3271e+00 -4.9953e-01 7.6000e-01 + -1.3162e+00 -5.2752e-01 7.6000e-01 + -1.3162e+00 -5.2752e-01 7.6000e-01 + -1.3487e+00 -5.4054e-01 6.2950e-01 + -1.3812e+00 -5.5356e-01 4.9900e-01 + -1.3926e+00 -5.2419e-01 4.9900e-01 + -1.4034e+00 -4.9458e-01 4.9900e-01 + -1.4136e+00 -4.6475e-01 4.9900e-01 + -1.4231e+00 -4.3472e-01 4.9900e-01 + -1.4320e+00 -4.0449e-01 4.9900e-01 + -1.4402e+00 -3.7407e-01 4.9900e-01 + -1.4478e+00 -3.4349e-01 4.9900e-01 + -1.4548e+00 -3.1276e-01 4.9900e-01 + -1.4611e+00 -2.8188e-01 4.9900e-01 + -1.4667e+00 -2.5088e-01 4.9900e-01 + -1.4717e+00 -2.1977e-01 4.9900e-01 + -1.4760e+00 -1.8856e-01 4.9900e-01 + -1.4797e+00 -1.5726e-01 4.9900e-01 + -1.4827e+00 -1.2589e-01 4.9900e-01 + -1.4850e+00 -9.4469e-02 4.9900e-01 + -1.4867e+00 -6.3003e-02 4.9900e-01 + -1.4877e+00 -3.1509e-02 4.9900e-01 + -1.4880e+00 1.8223e-16 4.9900e-01 + -1.4530e+00 1.7794e-16 6.2950e-01 + -1.4180e+00 1.7365e-16 7.6000e-01 + -2.6048e-16 -1.4180e+00 7.6000e-01 + 3.0026e-02 -1.4177e+00 7.6000e-01 + 6.0039e-02 -1.4167e+00 7.6000e-01 + 9.0025e-02 -1.4151e+00 7.6000e-01 + 1.1997e-01 -1.4129e+00 7.6000e-01 + 1.4986e-01 -1.4101e+00 7.6000e-01 + 1.7969e-01 -1.4066e+00 7.6000e-01 + 2.0943e-01 -1.4024e+00 7.6000e-01 + 2.3908e-01 -1.3977e+00 7.6000e-01 + 2.6862e-01 -1.3923e+00 7.6000e-01 + 2.9805e-01 -1.3863e+00 7.6000e-01 + 3.2733e-01 -1.3797e+00 7.6000e-01 + 3.5648e-01 -1.3725e+00 7.6000e-01 + 3.8546e-01 -1.3646e+00 7.6000e-01 + 4.1427e-01 -1.3561e+00 7.6000e-01 + 4.4289e-01 -1.3471e+00 7.6000e-01 + 4.7132e-01 -1.3374e+00 7.6000e-01 + 4.9953e-01 -1.3271e+00 7.6000e-01 + 5.2752e-01 -1.3162e+00 7.6000e-01 + 5.2752e-01 -1.3162e+00 7.6000e-01 + 5.4054e-01 -1.3487e+00 6.2950e-01 + 5.5356e-01 -1.3812e+00 4.9900e-01 + 5.2419e-01 -1.3926e+00 4.9900e-01 + 4.9458e-01 -1.4034e+00 4.9900e-01 + 4.6475e-01 -1.4136e+00 4.9900e-01 + 4.3472e-01 -1.4231e+00 4.9900e-01 + 4.0449e-01 -1.4320e+00 4.9900e-01 + 3.7407e-01 -1.4402e+00 4.9900e-01 + 3.4349e-01 -1.4478e+00 4.9900e-01 + 3.1276e-01 -1.4548e+00 4.9900e-01 + 2.8188e-01 -1.4611e+00 4.9900e-01 + 2.5088e-01 -1.4667e+00 4.9900e-01 + 2.1977e-01 -1.4717e+00 4.9900e-01 + 1.8856e-01 -1.4760e+00 4.9900e-01 + 1.5726e-01 -1.4797e+00 4.9900e-01 + 1.2589e-01 -1.4827e+00 4.9900e-01 + 9.4469e-02 -1.4850e+00 4.9900e-01 + 6.3003e-02 -1.4867e+00 4.9900e-01 + 3.1509e-02 -1.4877e+00 4.9900e-01 + -2.7334e-16 -1.4880e+00 4.9900e-01 + -2.6691e-16 -1.4530e+00 6.2950e-01 + -2.6048e-16 -1.4180e+00 7.6000e-01 diff --git a/src/HDF5Schema.jl b/src/HDF5Schema.jl index b8b0333c7..0ad15083e 100644 --- a/src/HDF5Schema.jl +++ b/src/HDF5Schema.jl @@ -243,7 +243,7 @@ const MAIN_H5_ANNOTATIONS = [ "SurfaceGeometries/Plasma/z" => (; long_name="Cartesian z of plasma-surface point cloud", units="m"), "SurfaceGeometries/Wall/x" => (; long_name="Cartesian x of wall point cloud", units="m"), "SurfaceGeometries/Wall/y" => (; long_name="Cartesian y of wall point cloud", units="m"), - "SurfaceGeometries/Wall/z" => (; long_name="Cartesian z of wall point cloud", units="m"), + "SurfaceGeometries/Wall/z" => (; long_name="Cartesian z of wall point cloud", units="m") ] # Euler-Lagrange operator matrices: same wording per letter, Ideal/ and Kinetic/ variants. @@ -256,7 +256,7 @@ const _ELM_IDEAL_LETTERS = [ ("H", "Euler-Lagrange primitive coefficient matrix H"), ("F", "Euler-Lagrange derived coefficient matrix F"), ("K", "Euler-Lagrange derived coefficient matrix K"), - ("G", "Euler-Lagrange derived coefficient matrix G"), + ("G", "Euler-Lagrange derived coefficient matrix G") ] # The kinetic branch overwrites only A, B, C, K, G and adds f0; D, E, H, F are shared # unchanged from the ideal set and are not re-emitted. @@ -266,14 +266,19 @@ const _ELM_KINETIC_LETTERS = [ ("C", "Euler-Lagrange primitive coefficient matrix C"), ("K", "Euler-Lagrange derived coefficient matrix K"), ("G", "Euler-Lagrange derived coefficient matrix G"), - ("f0", "raw kinetic component matrix f0"), + ("f0", "raw kinetic component matrix f0") ] const ELM_H5_ANNOTATIONS = vcat( ["ForceFreeStates/EulerLagrangeMatrices/psi" => (; long_name="normalized poloidal flux ψ_N grid of the operator matrices", scale="psi")], - ["ForceFreeStates/EulerLagrangeMatrices/Ideal/$l" => - (; long_name="ideal " * d, dims=("psi", "mode_row", "mode_col"), attach=(1 => "ForceFreeStates/EulerLagrangeMatrices/psi",)) for (l, d) in _ELM_IDEAL_LETTERS], - ["ForceFreeStates/EulerLagrangeMatrices/Kinetic/$l" => - (; long_name="kinetic-modified " * d, dims=("psi", "mode_row", "mode_col"), attach=(1 => "ForceFreeStates/EulerLagrangeMatrices/psi",)) for (l, d) in _ELM_KINETIC_LETTERS] + [ + "ForceFreeStates/EulerLagrangeMatrices/Ideal/$l" => + (; long_name="ideal " * d, dims=("psi", "mode_row", "mode_col"), attach=(1 => "ForceFreeStates/EulerLagrangeMatrices/psi",)) for (l, d) in _ELM_IDEAL_LETTERS + ], + [ + "ForceFreeStates/EulerLagrangeMatrices/Kinetic/$l" => + (; long_name="kinetic-modified " * d, dims=("psi", "mode_row", "mode_col"), attach=(1 => "ForceFreeStates/EulerLagrangeMatrices/psi",)) for + (l, d) in _ELM_KINETIC_LETTERS + ] ) """ diff --git a/src/InnerLayer/GGJ/Ray.jl b/src/InnerLayer/GGJ/Ray.jl index cb188f4aa..3abbc4f46 100644 --- a/src/InnerLayer/GGJ/Ray.jl +++ b/src/InnerLayer/GGJ/Ray.jl @@ -943,8 +943,6 @@ end npc=8, certify_rtol=1e-3, kwargs...) -> (; Δ, x, Ψ, Ξ, dψdx, rescale, certΔ) -Rotated-ray implementation of the [`solve_inner_profile`](@ref) interface. The -certified `Δ` comes from the optimal-contour solve at θ = arg(Q)/4 (robust for |Q| ≳ 1, where real-axis methods drift); the profiles come from a θ = 0 re-solve on the real axis, valid at physical (RPEC) |Q| since the on-axis pseudo-resonance is a regular point resolved by the BVP refinement. The diff --git a/src/InnerLayer/InnerLayerInterface.jl b/src/InnerLayer/InnerLayerInterface.jl index 52e1b36ea..5ad7dedaf 100644 --- a/src/InnerLayer/InnerLayerInterface.jl +++ b/src/InnerLayer/InnerLayerInterface.jl @@ -87,13 +87,13 @@ tuple with at least: - `Δ` — the same `(Δ_odd, Δ_even)` matching data as [`solve_inner`](@ref) - `x` — real ascending grid in the model's stretched inner coordinate, - `x ≥ 0` with the rational surface at `x = 0` + `x ≥ 0` with the rational surface at `x = 0` - `Ψ`, `Ξ` — `length(x) × 2` profiles, columns (odd, even) parity, in the - model's inner normalization: `Ψ` the normal-field - (reconnected-flux) variable, `Ξ` the displacement + model's inner normalization: `Ψ` the normal-field + (reconnected-flux) variable, `Ξ` the displacement - `dψdx` — conversion to poloidal-flux distance, `δψ = dψdx · x` - `rescale` — amplitude factor converting the inner-normalized profiles to - the outer δψ-normalized convention (companion of the Δ rescale) + the outer δψ-normalized convention (companion of the Δ rescale) Concrete models may return additional diagnostic fields (e.g. a solve-quality certificate). Solver-knob keywords are model-specific. diff --git a/src/InnerLayer/SLAYER/LayerInputs.jl b/src/InnerLayer/SLAYER/LayerInputs.jl index 96177903d..b25faa154 100644 --- a/src/InnerLayer/SLAYER/LayerInputs.jl +++ b/src/InnerLayer/SLAYER/LayerInputs.jl @@ -87,11 +87,15 @@ profiles, without an intermediate file round-trip. physical field, so passing it as a scalar is almost always wrong. - `mu_i` -- ion mass in proton-mass units (default `2.0` for D). + - `zeff` -- effective charge (default `1.0`). + - `chi_perp` -- perpendicular heat diffusivity [m²/s]. Scalar or a callable of `psi` (default `1.0`). + - `chi_tor` -- toroidal heat diffusivity [m²/s]. Scalar or a callable of `psi` (default `1.0`). + - `dr_val` -- resistive interchange index `D_R = E + F + H²` (Glasser-Greene-Johnson 1975) feeding the critical-Δ formulas (`:lar`, `:rfitzp`, `:toroidal`). When `nothing` (default), Julia @@ -106,6 +110,7 @@ profiles, without an intermediate file round-trip. NOT the Mercier index `D_I = E + F + H − 1/4`. The two differ by `(H − 1/2)²`, which is non-trivial on shaped equilibria (~factor 3 on DIII-D); this code uses the physically correct `D_R`. + - `dgeo_val` -- Connor 2015 (PPCF 57 065001) Eq. 59 geometric factor used by `dc_type=:toroidal`. When `nothing` (default), an error is raised if `dc_type=:toroidal` is also requested — the auto-derived @@ -113,15 +118,19 @@ profiles, without an intermediate file round-trip. doesn't currently expose. Pass a scalar / vector / callable to use a prescribed value. (For `dc_type=:rfitzp` and `:lar`, dgeo_val is not consulted.) + - `dc_type` -- `:none` (default), `:lar`, `:rfitzp`, or `:toroidal`. + - `theta` -- poloidal angle at which to measure minor radius (default `0.0`, outboard midplane). + - `resistivity_model` -- `SauterNeoModel()` (default), `RedlNeoModel()`, `SpitzerModel()`, or `SpitzerHarmModel()` (legacy Fitzpatrick σ_∥). Sets the η entering τ_R = μ₀r_s²/η. With a neoclassical model, `f_trap` and ν*_e are taken from the surface's `ResistGeometry` if populated (via `ForceFreeStates.resist_eval_all!`), otherwise fall back to the ε-only Lin-Liu-Miller form and `rs/R_0` aspect ratio. + - `lnLambda_form` -- Coulomb-log form passed through to `slayer_parameters` (default `:nrl`; `:wesson` + `SpitzerHarmModel()` reproduces legacy SLAYER exactly). diff --git a/src/InnerLayer/SLAYER/LayerParameters.jl b/src/InnerLayer/SLAYER/LayerParameters.jl index 5dbf9163f..8e3c17fb1 100644 --- a/src/InnerLayer/SLAYER/LayerParameters.jl +++ b/src/InnerLayer/SLAYER/LayerParameters.jl @@ -20,32 +20,32 @@ Fitzpatrick two-fluid drift-MHD SLAYER inner-layer model (Fitzpatrick de-normalization. The parametrization uses `P_perp`, `P_tor`, and `D_norm` (not the older `pr`/`pe`/`ds` set). -| field | meaning | -|:---------- |:----------------------------------------------------------------- | -| `ising` | Singular-surface index (traceability only) | -| `m`, `n` | Poloidal / toroidal mode numbers at this surface | -| `tau` | T_i / T_e | -| `lu` | Lundquist number S = τ_R / τ_H | -| `c_beta` | Compressibility √(β_local / (1 + β_local)) | -| `D_norm` | (d_β/r_s) · S^(1/3) · √(τ/(1+τ)) (Fitzpatrick normalized scale) | -| `P_perp` | Perpendicular Prandtl number τ_R / τ_⊥ | -| `P_tor` | Toroidal-direction Prandtl number τ_R / τ_‖tor | -| `Q_e` | Normalized electron diamagnetic: −tauk · ω_*e | -| `Q_i` | Normalized ion diamagnetic: −tauk · ω_*i | -| `iota_e` | Q_e / (Q_e − Q_i) | -| `tauk` | Q-conversion factor S^(1/3) · τ_H [s] — multiplies ω to get Q | -| `tau_r` | Resistive diffusion time [s] | -| `delta_n` | Δ-normalization factor S^(1/3) / r_s [m⁻¹] | -| `rs` | Minor radius at this surface [m] | -| `R0` | Major radius [m] | -| `bt` | Toroidal field [T] | -| `sval_r` | r-based magnetic shear r_s · (dq/dr) / q (Fitzpatrick convention) | +| field | meaning | +|:---------- |:--------------------------------------------------------------------------------------------------------------- | +| `ising` | Singular-surface index (traceability only) | +| `m`, `n` | Poloidal / toroidal mode numbers at this surface | +| `tau` | T_i / T_e | +| `lu` | Lundquist number S = τ_R / τ_H | +| `c_beta` | Compressibility √(β_local / (1 + β_local)) | +| `D_norm` | (d_β/r_s) · S^(1/3) · √(τ/(1+τ)) (Fitzpatrick normalized scale) | +| `P_perp` | Perpendicular Prandtl number τ_R / τ_⊥ | +| `P_tor` | Toroidal-direction Prandtl number τ_R / τ_‖tor | +| `Q_e` | Normalized electron diamagnetic: −tauk · ω_*e | +| `Q_i` | Normalized ion diamagnetic: −tauk · ω_*i | +| `iota_e` | Q_e / (Q_e − Q_i) | +| `tauk` | Q-conversion factor S^(1/3) · τ_H [s] — multiplies ω to get Q | +| `tau_r` | Resistive diffusion time [s] | +| `delta_n` | Δ-normalization factor S^(1/3) / r_s [m⁻¹] | +| `rs` | Minor radius at this surface [m] | +| `R0` | Major radius [m] | +| `bt` | Toroidal field [T] | +| `sval_r` | r-based magnetic shear r_s · (dq/dr) / q (Fitzpatrick convention) | | `dr_val` | Resistive interchange D_R = E + F + H² (critical-Δ input; auto-derived from GGJ coefficients unless overridden) | -| `dgeo_val` | Connor-Hastie-Helander 2015 Eq. 59 geometric factor (0 unless supplied) | -| `eta` | Parallel resistivity entering τ_R = μ₀r_s²/η [Ω·m] | -| `d_beta` | Beta-weighted ion length scale c_β · d_i [m] | -| `dc_tmp` | Critical-Δ offset from chi_parallel matching | -| `dc_type` | Selector for `dc_tmp` formula | +| `dgeo_val` | Connor-Hastie-Helander 2015 Eq. 59 geometric factor (0 unless supplied) | +| `eta` | Parallel resistivity entering τ_R = μ₀r_s²/η [Ω·m] | +| `d_beta` | Beta-weighted ion length scale c_β · d_i [m] | +| `dc_tmp` | Critical-Δ offset from chi_parallel matching | +| `dc_type` | Selector for `dc_tmp` formula | The complex normalized growth rate `Q = ω + iγ` is **not** stored here; it is passed as a separate argument to `solve_inner`. diff --git a/src/KineticForces/BounceAveraging.jl b/src/KineticForces/BounceAveraging.jl index 63a59aedc..5dddae01d 100644 --- a/src/KineticForces/BounceAveraging.jl +++ b/src/KineticForces/BounceAveraging.jl @@ -31,7 +31,7 @@ struct BounceData # For matrix path (nothing if scalar-only): packed layout (nlmda, nqty_matrix(mpert)). # Consumer fills into fbnce_data[:, 3:end] by direct copy. See `nqty_matrix` for # the 3-Hermitian-triangle + 3-full-block packing (Logan 2015 Eqs 7.30–7.35). - wmats_vs_lambda::Union{Nothing, Matrix{ComplexF64}} + wmats_vs_lambda::Union{Nothing,Matrix{ComplexF64}} end @@ -44,13 +44,19 @@ end # the full mpert² for the three non-Hermitian blocks. Block packing order: # A-tri, D-tri, H-tri, B-full, C-full, E-full. -"""Number of packed complex entries per λ for the 6 kinetic matrices.""" +""" +Number of packed complex entries per λ for the 6 kinetic matrices. +""" @inline nqty_matrix(mpert::Int) = 3 * (mpert * (mpert + 1)) ÷ 2 + 3 * mpert^2 -"""Upper-triangle index (1 ≤ i ≤ j ≤ mpert) within a triangular block.""" +""" +Upper-triangle index (1 ≤ i ≤ j ≤ mpert) within a triangular block. +""" @inline _tri_idx(i::Int, j::Int) = (j * (j - 1)) ÷ 2 + i -"""Full-block index (column-major) within a non-Hermitian block.""" +""" +Full-block index (column-major) within a non-Hermitian block. +""" @inline _full_idx(i::Int, j::Int, mpert::Int) = (j - 1) * mpert + i @@ -65,14 +71,16 @@ Generate a grid with power-law concentration near endpoints. Port of Fortran `powspace_sub` from equil/grid.f90. # Arguments -- `xmin, xmax`: Grid bounds -- `pow::Int`: Power of grid concentration (higher = more refined near edges) -- `num::Int`: Number of grid points -- `endpoints::String`: Where to concentrate: "lower", "upper", or "both" + + - `xmin, xmax`: Grid bounds + - `pow::Int`: Power of grid concentration (higher = more refined near edges) + - `num::Int`: Number of grid points + - `endpoints::String`: Where to concentrate: "lower", "upper", or "both" # Returns -- `points::Vector{Float64}`: Grid point locations -- `weights::Vector{Float64}`: Derivatives dx/dnorm (integration weights) + + - `points::Vector{Float64}`: Grid point locations + - `weights::Vector{Float64}`: Derivatives dx/dnorm (integration weights) """ function powspace(xmin::Float64, xmax::Float64, pow::Int, num::Int, endpoints::String) if xmax <= xmin @@ -81,11 +89,11 @@ function powspace(xmin::Float64, xmax::Float64, pow::Int, num::Int, endpoints::S # Linear base grid in [-1,1], [0,1], or [-1,0] x = if endpoints == "lower" - collect(range(-1.0, 0.0, length=num)) + collect(range(-1.0, 0.0; length=num)) elseif endpoints == "upper" - collect(range(0.0, 1.0, length=num)) + collect(range(0.0, 1.0; length=num)) elseif endpoints == "both" - collect(range(-1.0, 1.0, length=num)) + collect(range(-1.0, 1.0; length=num)) else error("powspace: invalid endpoints '$endpoints' — use lower, upper, or both") end @@ -160,31 +168,33 @@ needed by the pitch-angle quadrature. Ports Fortran torque.F90 lines 530-816 (GAR branch). # Arguments -- `psi`: Normalized poloidal flux -- `n`: Toroidal mode number -- `l`: Bounce harmonic number -- `q`: Safety factor at this ψ -- `bo`: On-axis toroidal field [T] -- `bmax, bmin`: Max/min of B(θ) at this ψ -- `theta_bmax`: θ location of Bmax (nodal knot; the passing-transit start) -- `tspl`: Periodic poloidal interpolant: tspl(θ) → [B, dB/dψ, dB/dθ, J, dJ/dψ] -- `B_extrap`: Endpoint-fit (non-periodic) cubic of B(θ) used for v_par and the - bounce-point roots (the Fortran `vspl` equivalent) -- `mfac`: Poloidal mode numbers [mlow:mhigh] -- `chi1`: 2π·ψ₀ flux normalization -- `ro`: Major radius [m] -- `dbob_m_f`: δB/B Fourier modes at this ψ (ComplexF64 vector, length mpert) -- `divx_m_f`: ∇·ξ⊥ Fourier modes at this ψ (ComplexF64 vector, length mpert) -- `divxfac, wdfac`: Scaling factors -- `mass`: Particle mass [kg] -- `chrg`: Particle charge [C] -- `T_s`: Species temperature at this ψ [J] -- `method`: Method string (first char: f/t/p determines λ range) + + - `psi`: Normalized poloidal flux + - `n`: Toroidal mode number + - `l`: Bounce harmonic number + - `q`: Safety factor at this ψ + - `bo`: On-axis toroidal field [T] + - `bmax, bmin`: Max/min of B(θ) at this ψ + - `theta_bmax`: θ location of Bmax (nodal knot; the passing-transit start) + - `tspl`: Periodic poloidal interpolant: tspl(θ) → [B, dB/dψ, dB/dθ, J, dJ/dψ] + - `B_extrap`: Endpoint-fit (non-periodic) cubic of B(θ) used for v_par and the + bounce-point roots (the Fortran `vspl` equivalent) + - `mfac`: Poloidal mode numbers [mlow:mhigh] + - `chi1`: 2π·ψ₀ flux normalization + - `ro`: Major radius [m] + - `dbob_m_f`: δB/B Fourier modes at this ψ (ComplexF64 vector, length mpert) + - `divx_m_f`: ∇·ξ⊥ Fourier modes at this ψ (ComplexF64 vector, length mpert) + - `divxfac, wdfac`: Scaling factors + - `mass`: Particle mass [kg] + - `chrg`: Particle charge [C] + - `T_s`: Species temperature at this ψ [J] + - `method`: Method string (first char: f/t/p determines λ range) # Keyword Arguments -- `nlmda`: Number of pitch angle grid points (default 128, matching Fortran pentrc nlmda) -- `ntheta`: Number of poloidal grid points per bounce (default 128) -- `smat, tmat, xmat, ymat, zmat`: Geometric matrices (mpert×mpert) for kinetic matrix path + + - `nlmda`: Number of pitch angle grid points (default 128, matching Fortran pentrc nlmda) + - `ntheta`: Number of poloidal grid points per bounce (default 128) + - `smat, tmat, xmat, ymat, zmat`: Geometric matrices (mpert×mpert) for kinetic matrix path """ function compute_bounce_data( psi::Float64, n::Int, l::Int, q::Float64, @@ -262,7 +272,7 @@ function compute_bounce_data( end return BounceData(nlmda, lambda, dlambda, sigma_arr, - wb_arr, wd_arr, dJdJ_arr, wmats_arr) + wb_arr, wd_arr, dJdJ_arr, wmats_arr) end @@ -275,23 +285,24 @@ Per-surface scratch for the bounce-averaging inner loops, allocated once in partially are `fill!`-reset per λ. ## Fields -- `g_wb::Vector{Float64}`: length `ntheta` — bounce-action integrand samples -- `g_wd::Vector{Float64}`: length `ntheta` — drift integrand samples -- `cum_wb_arr::Vector{Float64}`: length `ntheta` — cumulative bounce-action integral -- `jvtheta::Vector{ComplexF64}`: length `ntheta` — action integrand -- `bj_samples::Vector{ComplexF64}`: length `ntheta` — action bounce-integral samples -- `wsamp::Vector{ComplexF64}`: length `ntheta` — per-mode W bounce-integral samples -- `wmu_mt::Matrix{ComplexF64}`: `mpert × ntheta` — W_μ per θ -- `wen_mt::Matrix{ComplexF64}`: `mpert × ntheta` — W_E per θ -- `expm::Vector{ComplexF64}`: length `mpert` — Fourier basis at a θ -- `pl::Vector{ComplexF64}`: length `ntheta` — bounce phase factor -- `wmu_ba::Vector{ComplexF64}`: length `mpert` — bounce-averaged W_μ -- `wen_ba::Vector{ComplexF64}`: length `mpert` — bounce-averaged W_E -- `wmats_lmda::Vector{ComplexF64}`: length `nqty_matrix(mpert)` — packed W outer products -- `tspl_f::Vector{Float64}`: length 5 — in-place tspl(θ) evaluation -- `int_w::Vector{Float64}`, `cumint_W::Matrix{Float64}`: precomputed exact-cubic - quadrature weights on the fixed unit θ-grid (`∫ = int_w·y`, `cumulative = cumint_W·y`); - shared read-only across surfaces, see `_quadrature_weights` + + - `g_wb::Vector{Float64}`: length `ntheta` — bounce-action integrand samples + - `g_wd::Vector{Float64}`: length `ntheta` — drift integrand samples + - `cum_wb_arr::Vector{Float64}`: length `ntheta` — cumulative bounce-action integral + - `jvtheta::Vector{ComplexF64}`: length `ntheta` — action integrand + - `bj_samples::Vector{ComplexF64}`: length `ntheta` — action bounce-integral samples + - `wsamp::Vector{ComplexF64}`: length `ntheta` — per-mode W bounce-integral samples + - `wmu_mt::Matrix{ComplexF64}`: `mpert × ntheta` — W_μ per θ + - `wen_mt::Matrix{ComplexF64}`: `mpert × ntheta` — W_E per θ + - `expm::Vector{ComplexF64}`: length `mpert` — Fourier basis at a θ + - `pl::Vector{ComplexF64}`: length `ntheta` — bounce phase factor + - `wmu_ba::Vector{ComplexF64}`: length `mpert` — bounce-averaged W_μ + - `wen_ba::Vector{ComplexF64}`: length `mpert` — bounce-averaged W_E + - `wmats_lmda::Vector{ComplexF64}`: length `nqty_matrix(mpert)` — packed W outer products + - `tspl_f::Vector{Float64}`: length 5 — in-place tspl(θ) evaluation + - `int_w::Vector{Float64}`, `cumint_W::Matrix{Float64}`: precomputed exact-cubic + quadrature weights on the fixed unit θ-grid (`∫ = int_w·y`, `cumulative = cumint_W·y`); + shared read-only across surfaces, see `_quadrature_weights` """ struct BounceScratch g_wb::Vector{Float64} @@ -330,7 +341,7 @@ function BounceScratch(ntheta::Int, mpert::Int) Vector{ComplexF64}(undef, nqty_matrix(mpert)), Vector{Float64}(undef, 5), int_w, - cumint_W, + cumint_W ) end @@ -351,7 +362,7 @@ fitting and integrating each sample vector directly, but reducing the per-λ hot function _quadrature_weights(ntheta::Int) lock(_QUAD_WEIGHTS_LOCK) do get!(_QUAD_WEIGHTS, ntheta) do - xs = collect(range(0.0, 1.0, length=ntheta)) + xs = collect(range(0.0, 1.0; length=ntheta)) int_w = zeros(Float64, ntheta) cumint_W = zeros(Float64, ntheta, ntheta) ej = zeros(Float64, ntheta) @@ -384,12 +395,12 @@ function _build_lambda_grid(method_char::Char, lmdatpb::Float64, lmdamax::Float6 if method_char == 't' # Trapped only: λ ∈ (lmdatpb, lmdamax), exclude endpoints pts_inc, wts_inc = powspace(lmdatpb, lmdamax, 1, 2 + nlmda, "both") - return pts_inc[2:end-1], wts_inc[2:end-1] + return pts_inc[2:(end-1)], wts_inc[2:(end-1)] elseif method_char == 'p' # Passing only: λ ∈ (lmdamin, lmdatpb), exclude endpoints pts_inc, wts_inc = powspace(lmdamin, lmdatpb, 1, 2 + nlmda, "both") - return pts_inc[2:end-1], wts_inc[2:end-1] + return pts_inc[2:(end-1)], wts_inc[2:(end-1)] else # 'f' = full if lmdatpb ≈ lmdamax @@ -401,8 +412,8 @@ function _build_lambda_grid(method_char::Char, lmdatpb::Float64, lmdamax::Float6 pts_p, wts_p = powspace(lmdamin, lmdatpb, 2, 2 + nhalf_p, "upper") pts_t, wts_t = powspace(lmdatpb, lmdamax, 2, 2 + nhalf_t, "lower") # Exclude boundary points - lambda = vcat(pts_p[2:end-1], pts_t[2:end-1]) - dlambda = vcat(wts_p[2:end-1], wts_t[2:end-1]) + lambda = vcat(pts_p[2:(end-1)], pts_t[2:(end-1)]) + dlambda = vcat(wts_p[2:(end-1)], wts_t[2:(end-1)]) return lambda, dlambda end end @@ -538,7 +549,7 @@ function _bounce_integrate( tspl_f = scr.tspl_f expm = scr.expm - for i in 2:ntheta-1 # Edge weights are 0 from powspace + for i in 2:(ntheta-1) # Edge weights are 0 from powspace θ = tdt_pts[i] dt = tdt_wts[i] θmod = mod(θ, 1.0) @@ -595,8 +606,8 @@ function _bounce_integrate( # Action integrand phase = cis(-twopi * n * q * (θ - theta0)) jvtheta[i] = dt * jac * B_val * - (divx * sqrt_vpar + dbob * (1.0 - 1.5 * lmda * B_val / bo) / sqrt_vpar) * - phase + (divx * sqrt_vpar + dbob * (1.0 - 1.5 * lmda * B_val / bo) / sqrt_vpar) * + phase # W vectors for matrix path if do_matrices @@ -611,9 +622,9 @@ function _bounce_integrate( # Smooth backfill for points zeroed before a restart. Exact equality with # 0.0 is safe: the restart branch set these entries with fill!(…, 0.0). if i >= 3 && g_wb[i-1] == 0.0 - fill!(view(g_wb, 3:i-1), g_wb[i]) - fill!(view(g_wd, 3:i-1), g_wd[i]) - fill!(view(jvtheta, 2:i-1), jvtheta[i]) + fill!(view(g_wb, 3:(i-1)), g_wb[i]) + fill!(view(g_wd, 3:(i-1)), g_wd[i]) + fill!(view(jvtheta, 2:(i-1)), jvtheta[i]) end end @@ -698,32 +709,32 @@ function _bounce_integrate( # A (Hermitian): upper triangle of W_Z†W_Z, rank-1 → conj(wz[i])·wz[j]. off = 0 @inbounds for j in 1:mpert, i in 1:j - wmats_lmda[off + _tri_idx(i, j)] = conj(wz[i]) * wz[j] * scale + wmats_lmda[off+_tri_idx(i, j)] = conj(wz[i]) * wz[j] * scale end off += Mu # D (Hermitian): upper triangle of W_X†W_X. @inbounds for j in 1:mpert, i in 1:j - wmats_lmda[off + _tri_idx(i, j)] = conj(wx[i]) * wx[j] * scale + wmats_lmda[off+_tri_idx(i, j)] = conj(wx[i]) * wx[j] * scale end off += Mu # H (Hermitian): upper triangle of W_Y†W_Y. @inbounds for j in 1:mpert, i in 1:j - wmats_lmda[off + _tri_idx(i, j)] = conj(wy[i]) * wy[j] * scale + wmats_lmda[off+_tri_idx(i, j)] = conj(wy[i]) * wy[j] * scale end off += Mu # B (full): W_Z†W_X. @inbounds for j in 1:mpert, i in 1:mpert - wmats_lmda[off + _full_idx(i, j, mpert)] = conj(wz[i]) * wx[j] * scale + wmats_lmda[off+_full_idx(i, j, mpert)] = conj(wz[i]) * wx[j] * scale end off += mpert^2 # C (full): W_Z†W_Y. @inbounds for j in 1:mpert, i in 1:mpert - wmats_lmda[off + _full_idx(i, j, mpert)] = conj(wz[i]) * wy[j] * scale + wmats_lmda[off+_full_idx(i, j, mpert)] = conj(wz[i]) * wy[j] * scale end off += mpert^2 # E (full): W_X†W_Y. @inbounds for j in 1:mpert, i in 1:mpert - wmats_lmda[off + _full_idx(i, j, mpert)] = conj(wx[i]) * wy[j] * scale + wmats_lmda[off+_full_idx(i, j, mpert)] = conj(wx[i]) * wy[j] * scale end end diff --git a/src/KineticForces/EnergyIntegration.jl b/src/KineticForces/EnergyIntegration.jl index 36cc1ecef..261c403ce 100644 --- a/src/KineticForces/EnergyIntegration.jl +++ b/src/KineticForces/EnergyIntegration.jl @@ -40,10 +40,10 @@ end Collision frequency ν(x) at normalized energy x = E/T. -- `"zero"`: collisionless (ν = 0) -- `"small"`: 1e-5 * we -- `"krook"`: unmodified Krook operator -- `"harmonic"`: (1 + (l/2)²) * krook * x^(-3/2) + - `"zero"`: collisionless (ν = 0) + - `"small"`: 1e-5 * we + - `"krook"`: unmodified Krook operator + - `"harmonic"`: (1 + (l/2)²) * krook * x^(-3/2) """ @inline function _energy_collision_frequency(x::Float64, p::EnergyParams)::Float64 nux = if p.nutype == "zero" @@ -188,7 +188,7 @@ Writing `h(x) = N(x)·exp(-x)`, the limit is `Ω′ = leff·wb/(2√x) + n·wd`, `Ω″ = −leff·wb/(4·x^{3/2})`. """ @inline function _real_pole_regular_part(xr::Float64, p::EnergyParams, leff::Float64, - wb::Float64, n::Int, wd::Float64)::ComplexF64 + wb::Float64, n::Int, wd::Float64)::ComplexF64 sx = sqrt(xr) op = leff * wb / (2.0 * sx) + n * wd # Ω′(x_res) opp = -leff * wb / (4.0 * xr * sx) # Ω″(x_res) @@ -211,8 +211,8 @@ add-back below), and its on-axis `0/0` window by the analytic regular-part limit # Real x-space resonant integrand with pole subtractions # Explicit function keeps memory allocation out of the QuadGK inner loop. @inline function _resonant_integrand(x::Float64, p::EnergyParams, - residues::Vector{ComplexF64}, x_poles::Vector{ComplexF64}, npole::Int, - leff::Float64, wb::Float64, n::Int, wd::Float64)::ComplexF64 + residues::Vector{ComplexF64}, x_poles::Vector{ComplexF64}, npole::Int, + leff::Float64, wb::Float64, n::Int, wd::Float64)::ComplexF64 val = _energy_integrand_real(x, p) @inbounds for k in 1:npole val -= residues[k] / (x - x_poles[k]) @@ -234,8 +234,8 @@ add-back below), and its on-axis `0/0` window by the analytic regular-part limit end function _integrate_energy_resonant(p::EnergyParams, leff::Float64, wb::Float64, - n::Int, we::Float64, wd::Float64, - atol::Float64, rtol::Float64, segbuf=nothing)::ComplexF64 + n::Int, we::Float64, wd::Float64, + atol::Float64, rtol::Float64, segbuf=nothing)::ComplexF64 x_res_list = find_resonance_energies(leff, wb, n, we, wd) # ≤ 2 roots of a quadratic in √x x_poles = ComplexF64[] residues = ComplexF64[] @@ -308,17 +308,18 @@ Distribution function types (`f0type`): `"maxwellian"`, `"jkp"`, `"cgl"`. poles are now handled analytically rather than by contour deformation. # Returns -- `ComplexF64`: energy integral value + + - `ComplexF64`: energy integral value """ function integrate_energy(wn::Float64, wt::Float64, we::Float64, wd::Float64, - wb::Float64, nuk::Float64, ell::Int, leff::Float64, - n::Int, psi::Float64, lambda::Float64, method::String; - nutype::String="harmonic", f0type::String="maxwellian", - nufac::Float64=1.0, ximag::Float64=0.0, qt::Bool=false, - atol::Float64=1e-7, rtol::Float64=1e-5, segbuf=nothing)::ComplexF64 + wb::Float64, nuk::Float64, ell::Int, leff::Float64, + n::Int, psi::Float64, lambda::Float64, method::String; + nutype::String="harmonic", f0type::String="maxwellian", + nufac::Float64=1.0, ximag::Float64=0.0, qt::Bool=false, + atol::Float64=1e-7, rtol::Float64=1e-5, segbuf=nothing)::ComplexF64 p = EnergyParams(wn, wt, we, wd, wb, nuk, leff, n, - nutype, f0type, nufac, ximag, qt) + nutype, f0type, nufac, ximag, qt) # CGL has no resonance denominator and no pole — integrate the physical # x-space integrand directly over the half line (QuadGK maps [0,∞) itself). @@ -343,19 +344,20 @@ N(x)·exp(-x)/denom(x) at specified x = E/T values. Returns the integrand value integrand shape and verifying kinetic resonance resolution. # Example + ```julia -x = 10 .^ range(-2, stop=2, length=500) +x = 10 .^ range(-2; stop=2, length=500) f = KineticForces.evaluate_energy_integrand(x; wn=1e3, wt=2e3, we=5e4, - wd=1e2, wb=3e4, nuk=1e3, leff=1.0, n=1) -plot(x, real.(f); xscale=:log10, xlabel="x = E/T", ylabel="Re(integrand)") + wd=1e2, wb=3e4, nuk=1e3, leff=1.0, n=1) +plot(x, real.(f); xscale=:log10, xlabel=\"x = E/T\", ylabel=\"Re(integrand)\") ``` """ function evaluate_energy_integrand(x_grid::AbstractVector{Float64}; - wn::Float64, wt::Float64, we::Float64, - wd::Float64, wb::Float64, nuk::Float64, - leff::Float64, n::Int, - nutype::String="harmonic", f0type::String="maxwellian", - nufac::Float64=1.0, ximag::Float64=0.0, qt::Bool=false) + wn::Float64, wt::Float64, we::Float64, + wd::Float64, wb::Float64, nuk::Float64, + leff::Float64, n::Int, + nutype::String="harmonic", f0type::String="maxwellian", + nufac::Float64=1.0, ximag::Float64=0.0, qt::Bool=false) p = EnergyParams(wn, wt, we, wd, wb, nuk, leff, n, nutype, f0type, nufac, ximag, qt) return [energy_integrand_scalar(x, p) for x in x_grid] end diff --git a/src/KineticForces/KineticForces.jl b/src/KineticForces/KineticForces.jl index 1ac79ad22..748d19e64 100644 --- a/src/KineticForces/KineticForces.jl +++ b/src/KineticForces/KineticForces.jl @@ -59,11 +59,11 @@ include("CalculatedKineticMatrices.jl") # ============================================================================ const mp = 1.672_614e-27 # proton mass (kg) const me = 9.109_1e-31 # electron mass (kg) -const e = 1.602_191_7e-19 # elementary charge (C) +const e = 1.602_191_7e-19 # elementary charge (C) const eV = e # joules per electron-volt const twopi = 2π -const μ₀ = 4e-7 * π +const μ₀ = 4e-7 * π const rad2deg = 180 / π const deg2rad = π / 180 const iunit = 1im # equivalent to Fortran's (0,1) diff --git a/src/KineticForces/KineticForcesStructs.jl b/src/KineticForces/KineticForcesStructs.jl index e4eca2581..5d2505b69 100644 --- a/src/KineticForces/KineticForcesStructs.jl +++ b/src/KineticForces/KineticForcesStructs.jl @@ -3,12 +3,13 @@ Single source of truth for the NTV calculation methods. Each entry is a NamedTuple `(name, flag, kind, doc)`: -- `name` — short method identifier used as the HDF5 group key and in `intr.method` -- `flag` — the `KineticForcesControl` field symbol that enables the method -- `kind` — dispatch routing tag consumed by `method_kind` / `Torque.jl` - (`:gar` for the GAR/matrix family, `:fcgl`/`:rlar`/`:clar` for the - three special-cased methods) -- `doc` — one-line description printed in verbose output + + - `name` — short method identifier used as the HDF5 group key and in `intr.method` + - `flag` — the `KineticForcesControl` field symbol that enables the method + - `kind` — dispatch routing tag consumed by `method_kind` / `Torque.jl` + (`:gar` for the GAR/matrix family, `:fcgl`/`:rlar`/`:clar` for the + three special-cased methods) + - `doc` — one-line description printed in verbose output The method names/docs and the `Compute.jl` enable list are all derived from this tuple, and `Torque.jl` routes on `kind`, so the methods are enumerated in one place. @@ -77,8 +78,9 @@ User-facing control parameters from the TOML `[KineticForces]` section. Configures which NTV methods to run, species parameters, tolerances, and output options. Constructed via keyword arguments or from a TOML dict: + ```julia -ctrl = KineticForcesControl(; (Symbol(k) => v for (k, v) in inputs["KineticForces"])...) +ctrl = KineticForcesControl(; (Symbol(k) => v for (k, v) in inputs[\"KineticForces\"])...) ``` Immutable: vary a field by building a new control rather than assigning to one (the @@ -202,12 +204,13 @@ Internal working state for KineticForces calculations. Holds equilibrium-derived quantities, profile interpolants, and integration results. Fields replacing former module-level globals: -- `ro`, `bo`, `chi1`: Equilibrium geometry parameters -- `mthsurf`, `mfac`: Poloidal grid info -- `dbob_m`, `divx_m`: Perturbation mode interpolants -- `sing_psis`: Rational-surface ψ locations (sorted, from the stability analysis), used as - panel boundaries for the outer ψ torque quadrature so the resonant peaks fall on - Gauss-Kronrod interval endpoints instead of driving deep adaptive bisection + + - `ro`, `bo`, `chi1`: Equilibrium geometry parameters + - `mthsurf`, `mfac`: Poloidal grid info + - `dbob_m`, `divx_m`: Perturbation mode interpolants + - `sing_psis`: Rational-surface ψ locations (sorted, from the stability analysis), used as + panel boundaries for the outer ψ torque quadrature so the resonant peaks fall on + Gauss-Kronrod interval endpoints instead of driving deep adaptive bisection Equilibrium and kinetic profile data are read directly from the `PlasmaEquilibrium` (`equil.profiles`, `equil.geometry`) and the @@ -297,17 +300,17 @@ function KineticForcesInternal(equil; verbose::Bool=false) # Axis toroidal field F(0)/ro that normalizes λ = μ·bo/E; F_spline stores 2πF. bo_axis = abs(equil.profiles.F_spline(0.0)) / (2π * equil.ro) KineticForcesInternal(; - ro = equil.ro, - bo = bo_axis, - chi1 = 2π * equil.psio, + ro=equil.ro, + bo=bo_axis, + chi1=2π * equil.psio, mthsurf, - tpsi_xs = collect(range(0.0, 1.0, length=nth)), - tpsi_B = Vector{Float64}(undef, nth), - tpsi_dBdpsi = Vector{Float64}(undef, nth), - tpsi_dBdtheta = Vector{Float64}(undef, nth), - tpsi_jac = Vector{Float64}(undef, nth), - tpsi_djdpsi = Vector{Float64}(undef, nth), - verbose, + tpsi_xs=collect(range(0.0, 1.0; length=nth)), + tpsi_B=Vector{Float64}(undef, nth), + tpsi_dBdpsi=Vector{Float64}(undef, nth), + tpsi_dBdtheta=Vector{Float64}(undef, nth), + tpsi_jac=Vector{Float64}(undef, nth), + tpsi_djdpsi=Vector{Float64}(undef, nth), + verbose ) end @@ -317,15 +320,17 @@ end Populate perturbation data from PerturbedEquilibriumState into KineticForcesInternal. Builds three interpolant sets from PE Clebsch displacements: -1. `xs_m` — [ξ^ψ, ∂ξ^ψ/∂ψ, ξ^α] CubicSeriesInterpolants over ψ -2. `dbob_m` — δB/B Fourier modes via JBB deweighting (Fortran set_peq) -3. `divx_m` — ∇·ξ⊥ Fourier modes via JBB deweighting + + 1. `xs_m` — [ξ^ψ, ∂ξ^ψ/∂ψ, ξ^α] CubicSeriesInterpolants over ψ + 2. `dbob_m` — δB/B Fourier modes via JBB deweighting (Fortran set_peq) + 3. `divx_m` — ∇·ξ⊥ Fourier modes via JBB deweighting The JBB deweighting algorithm (Fortran pentrc/inputs.f90:828-868): -1. Apply geometric matrices S,T,X,Y,Z in m-space -2. Inverse DFT to θ-space -3. Divide by J·B² at each θ -4. Forward DFT back to m-space + + 1. Apply geometric matrices S,T,X,Y,Z in m-space + 2. Inverse DFT to θ-space + 3. Divide by J·B² at each θ + 4. Forward DFT back to m-space """ function set_perturbation_data!(kf_intr::KineticForcesInternal, pe_state::PerturbedEquilibrium.PerturbedEquilibriumState, ffs::ForceFreeStates.ForceFreeStatesResult, @@ -399,9 +404,9 @@ function set_perturbation_data!(kf_intr::KineticForcesInternal, pe_state::Pertur psi = psi_grid[ipsi] # Get Clebsch displacement vectors at this ψ - xsp = view(xi_modes.clebsch_psi, ipsi, :) # ξ^ψ [mpert] + xsp = view(xi_modes.clebsch_psi, ipsi, :) # ξ^ψ [mpert] xmp1 = view(xi_modes.clebsch_psi1, ipsi, :) # ∂ξ^ψ/∂ψ [mpert] - xms = view(clebsch_alpha_mat, ipsi, :) # ξ^α [mpert] + xms = view(clebsch_alpha_mat, ipsi, :) # ξ^α [mpert] # Evaluate geometric matrices at ψ → mpert² flat vectors, reshape to mpert×mpert geom_mats.smats(smat_flat, psi; hint=hint_s) @@ -421,8 +426,8 @@ function set_perturbation_data!(kf_intr::KineticForcesInternal, pe_state::Pertur mul!(jbb_kapx, smat, xsp) mul!(jbb_kapx, tmat, xms, 1.0 + 0.0im, 1.0 + 0.0im) # += tmat * xms mul!(jbb_divx, xmat, xmp1) - mul!(jbb_divx, ymat, xsp, 1.0 + 0.0im, 1.0 + 0.0im) # += ymat * xsp - mul!(jbb_divx, zmat, xms, 1.0 + 0.0im, 1.0 + 0.0im) # += zmat * xms + mul!(jbb_divx, ymat, xsp, 1.0 + 0.0im, 1.0 + 0.0im) # += ymat * xsp + mul!(jbb_divx, zmat, xms, 1.0 + 0.0im, 1.0 + 0.0im) # += zmat * xms @. jbb_dbob = -(jbb_divx + jbb_kapx) # Inverse DFT to θ-space, divide by J·B², forward DFT back @@ -449,9 +454,9 @@ Matches Fortran set_peq lines 859-868: transforms JBB-weighted m-space data to θ-space, removes the J·B² weighting at each poloidal angle, and transforms back. """ function _jbb_deweight!(out::AbstractVector{ComplexF64}, jbb_modes::Vector{ComplexF64}, - ft::Utilities.FourierTransforms.FourierTransform, - psi::Float64, equil::Equilibrium.PlasmaEquilibrium, - mthsurf::Int, theta_buf::Vector{ComplexF64}) + ft::Utilities.FourierTransforms.FourierTransform, + psi::Float64, equil::Equilibrium.PlasmaEquilibrium, + mthsurf::Int, theta_buf::Vector{ComplexF64}) # Inverse DFT: m-space → θ-space theta_buf .= Utilities.FourierTransforms.inverse(ft, jbb_modes) @@ -521,8 +526,8 @@ Accumulated results from all KineticForces computations. Written to gpec.h5 under the "KineticForces" group. """ @kwdef mutable struct KineticForcesState - method_results::Dict{String, MethodResult} = Dict{String, MethodResult}() + method_results::Dict{String,MethodResult} = Dict{String,MethodResult}() # Block-diagonal kinetic matrices: key=method, value=(numpert_total, numpert_total, 6) - kinetic_matrices::Dict{String, Array{ComplexF64,3}} = Dict{String, Array{ComplexF64,3}}() + kinetic_matrices::Dict{String,Array{ComplexF64,3}} = Dict{String,Array{ComplexF64,3}}() completed::Bool = false end diff --git a/src/KineticForces/Output.jl b/src/KineticForces/Output.jl index 75f527ae2..96594f06d 100644 --- a/src/KineticForces/Output.jl +++ b/src/KineticForces/Output.jl @@ -140,8 +140,9 @@ Write variable-length integration trajectory records using offset-indexed concat This is the standard HDF5 ragged array pattern for storing variable-length data. # Arguments -- `mg::HDF5.Group`: HDF5 group for this method -- `records::Vector{EnergyIntegrationResult}`: Integration records to write + + - `mg::HDF5.Group`: HDF5 group for this method + - `records::Vector{EnergyIntegrationResult}`: Integration records to write """ function write_integration_records!(mg::HDF5.Group, records::Vector{EnergyIntegrationResult}) rg = create_group(mg, "EnergyIntegrals") @@ -173,13 +174,14 @@ end Print a summary of KineticForces results to stdout. # Arguments -- `state::KineticForcesState`: Accumulated computation results -- `verbose::Bool`: Print detailed per-surface results + + - `state::KineticForcesState`: Accumulated computation results + - `verbose::Bool`: Print detailed per-surface results """ function print_summary(state::KineticForcesState; verbose::Bool=false) for (method_name, result) in state.method_results @printf("%-8s T_phi = %11.3e 2n*dW_k = %11.3e\n", - method_name, real(result.total_torque), imag(result.total_torque)) + method_name, real(result.total_torque), imag(result.total_torque)) end if verbose for (method_name, _) in state.kinetic_matrices diff --git a/src/KineticForces/PitchIntegration.jl b/src/KineticForces/PitchIntegration.jl index 845cfabc9..52fd40ec6 100644 --- a/src/KineticForces/PitchIntegration.jl +++ b/src/KineticForces/PitchIntegration.jl @@ -61,15 +61,17 @@ Gauss-Kronrod quadrature. Uses `QuadGK.quadgk!` with an in-place ComplexF64 kernel buffer. The fbnce interpolant returns [ωb, ωd, f₁, f₂, ...] at each λ, where: -- f₁ = ωb|δJ|²/ro² (scalar torque) -- f₂:end = ωb·W_outer_products/ro² (kinetic matrix elements, if present) + + - f₁ = ωb|δJ|²/ro² (scalar torque) + - f₂:end = ωb·W_outer_products/ro² (kinetic matrix elements, if present) Splits the domain at the trapped/passing boundary so Gauss-Kronrod resolves the kink in leff = ell + n*q (circulating) → ell (trapped). One `quadgk!` call writes all `nqty` complex quantities per λ-evaluation. # Returns -- `Vector{ComplexF64}` of length nqty: integrated pitch-angle results + + - `Vector{ComplexF64}` of length nqty: integrated pitch-angle results """ function integrate_pitch_gar_quadgk( wn::Float64, wt::Float64, we::Float64, nuk::Float64, @@ -129,28 +131,28 @@ function _pitch_gar_kernel_quadgk!(out::Vector{ComplexF64}, lambda, p::PitchGARP if is_circulating xint_co = integrate_energy(p.wn, p.wt, p.we, wd, wb, nueff, - p.ell, leff, p.n, p.psi, lambda, p.method; - nutype=p.nutype, f0type=p.f0type, - nufac=p.nufac, ximag=p.ximag, qt=p.qt, - atol=p.energy_atol, rtol=p.energy_rtol, segbuf=p.esegbuf) + p.ell, leff, p.n, p.psi, lambda, p.method; + nutype=p.nutype, f0type=p.f0type, + nufac=p.nufac, ximag=p.ximag, qt=p.qt, + atol=p.energy_atol, rtol=p.energy_rtol, segbuf=p.esegbuf) xint_counter = integrate_energy(p.wn, p.wt, p.we, wd, -wb, nueff, - p.ell, leff, p.n, p.psi, lambda, p.method; - nutype=p.nutype, f0type=p.f0type, - nufac=p.nufac, ximag=p.ximag, qt=p.qt, - atol=p.energy_atol, rtol=p.energy_rtol, segbuf=p.esegbuf) + p.ell, leff, p.n, p.psi, lambda, p.method; + nutype=p.nutype, f0type=p.f0type, + nufac=p.nufac, ximag=p.ximag, qt=p.qt, + atol=p.energy_atol, rtol=p.energy_rtol, segbuf=p.esegbuf) xint = xint_co + xint_counter else xint = integrate_energy(p.wn, p.wt, p.we, wd, wb, nueff, - p.ell, leff, p.n, p.psi, lambda, p.method; - nutype=p.nutype, f0type=p.f0type, - nufac=p.nufac, ximag=p.ximag, qt=p.qt, - atol=p.energy_atol, rtol=p.energy_rtol) + p.ell, leff, p.n, p.psi, lambda, p.method; + nutype=p.nutype, f0type=p.f0type, + nufac=p.nufac, ximag=p.ximag, qt=p.qt, + atol=p.energy_atol, rtol=p.energy_rtol) end xint_decomposed = complex(p.rex * real(xint), p.imx * imag(xint)) @inbounds for i in 1:p.nqty - out[i] = fvals[i + 2] * xint_decomposed + out[i] = fvals[i+2] * xint_decomposed end return nothing end @@ -212,8 +214,8 @@ end _pitch_gar_kernel_quadgk_wt!(out::Vector{ComplexF64}, lambda, p::PitchGARParams) Dual-output pitch kernel. Fills a length-`2*nqty` buffer: - out[1:nqty] — fwmm half: `fvals * complex(0, imag(xint))` - out[nqty+1:2*nqty] — ftmm half: `fvals * complex(real(xint), 0)` +out[1:nqty] — fwmm half: `fvals * complex(0, imag(xint))` +out[nqty+1:2*nqty] — ftmm half: `fvals * complex(real(xint), 0)` One energy integration per λ; both halves share it. """ @@ -229,22 +231,22 @@ function _pitch_gar_kernel_quadgk_wt!(out::Vector{ComplexF64}, lambda, p::PitchG if is_circulating xint_co = integrate_energy(p.wn, p.wt, p.we, wd, wb, nueff, - p.ell, leff, p.n, p.psi, lambda, p.method; - nutype=p.nutype, f0type=p.f0type, - nufac=p.nufac, ximag=p.ximag, qt=p.qt, - atol=p.energy_atol, rtol=p.energy_rtol, segbuf=p.esegbuf) + p.ell, leff, p.n, p.psi, lambda, p.method; + nutype=p.nutype, f0type=p.f0type, + nufac=p.nufac, ximag=p.ximag, qt=p.qt, + atol=p.energy_atol, rtol=p.energy_rtol, segbuf=p.esegbuf) xint_counter = integrate_energy(p.wn, p.wt, p.we, wd, -wb, nueff, - p.ell, leff, p.n, p.psi, lambda, p.method; - nutype=p.nutype, f0type=p.f0type, - nufac=p.nufac, ximag=p.ximag, qt=p.qt, - atol=p.energy_atol, rtol=p.energy_rtol, segbuf=p.esegbuf) + p.ell, leff, p.n, p.psi, lambda, p.method; + nutype=p.nutype, f0type=p.f0type, + nufac=p.nufac, ximag=p.ximag, qt=p.qt, + atol=p.energy_atol, rtol=p.energy_rtol, segbuf=p.esegbuf) xint = xint_co + xint_counter else xint = integrate_energy(p.wn, p.wt, p.we, wd, wb, nueff, - p.ell, leff, p.n, p.psi, lambda, p.method; - nutype=p.nutype, f0type=p.f0type, - nufac=p.nufac, ximag=p.ximag, qt=p.qt, - atol=p.energy_atol, rtol=p.energy_rtol) + p.ell, leff, p.n, p.psi, lambda, p.method; + nutype=p.nutype, f0type=p.f0type, + nufac=p.nufac, ximag=p.ximag, qt=p.qt, + atol=p.energy_atol, rtol=p.energy_rtol) end xint_w = complex(0.0, imag(xint)) # fwmm: rex=0, imx=1 @@ -252,9 +254,9 @@ function _pitch_gar_kernel_quadgk_wt!(out::Vector{ComplexF64}, lambda, p::PitchG nq = p.nqty @inbounds for i in 1:nq - f = fvals[i + 2] - out[i] = f * xint_w - out[i + nq] = f * xint_t + f = fvals[i+2] + out[i] = f * xint_w + out[i+nq] = f * xint_t end return nothing end diff --git a/src/KineticForces/Torque.jl b/src/KineticForces/Torque.jl index 1cd40285e..99949647c 100644 --- a/src/KineticForces/Torque.jl +++ b/src/KineticForces/Torque.jl @@ -6,36 +6,39 @@ Toroidal torque resulting from nonambipolar transport in perturbed equilibrium. Imaginary component is proportional to the kinetic energy Im(T) = 2*n*dW_k. # Arguments -- `tpsi_var`: Output complex torque value -- `psi::Float64`: Normalized poloidal flux -- `n::Int`: Toroidal mode number -- `l::Int`: Bounce harmonic number -- `zi::Int`: Ion charge in fundamental units (e) -- `mi::Int`: Ion mass (units of proton mass) -- `wdfac::Float64`: Drift factor -- `divxfac::Float64`: Divergence factor -- `electron::Bool`: Calculate quantities for electrons (zi,mi ignored) -- `method::String`: Integration method (RLAR, CLAR, *GAR, *TMM, *WMM, *KMM) + + - `tpsi_var`: Output complex torque value + - `psi::Float64`: Normalized poloidal flux + - `n::Int`: Toroidal mode number + - `l::Int`: Bounce harmonic number + - `zi::Int`: Ion charge in fundamental units (e) + - `mi::Int`: Ion mass (units of proton mass) + - `wdfac::Float64`: Drift factor + - `divxfac::Float64`: Divergence factor + - `electron::Bool`: Calculate quantities for electrons (zi,mi ignored) + - `method::String`: Integration method (RLAR, CLAR, *GAR, *TMM, *WMM, *KMM) where * = F,T,P for full,trapped,passing -- `equil`: PlasmaEquilibrium with 2D interpolants and named profile/geometry splines -- `intr::KineticForcesInternal`: Internal state with mode indexing and perturbation splines -- `kinetic_profiles::Equilibrium.KineticProfileSplines`: Named kinetic-profile splines + - `equil`: PlasmaEquilibrium with 2D interpolants and named profile/geometry splines + - `intr::KineticForcesInternal`: Internal state with mode indexing and perturbation splines + - `kinetic_profiles::Equilibrium.KineticProfileSplines`: Named kinetic-profile splines (n_i, n_e, T_i, T_e, ω_E, ν_i, ν_e) loaded from `kinetic.dat` # Optional Arguments -- `op_wmats::Array{ComplexF64,3}`: Store ForceFreeStates matrix elements + + - `op_wmats::Array{ComplexF64,3}`: Store ForceFreeStates matrix elements # Returns -- `ComplexF64`: Toroidal torque due to nonambipolar transport + + - `ComplexF64`: Toroidal torque due to nonambipolar transport """ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int, - zi::Int, mi::Int, wdfac::Float64, divxfac::Float64, - electron::Bool, method::String, equil, intr::KineticForcesInternal, - kinetic_profiles::Equilibrium.KineticProfileSplines; - op_wmats::Union{Nothing,Array{ComplexF64,3}}=nothing, - rex_override::Union{Nothing,Float64}=nothing, - imx_override::Union{Nothing,Float64}=nothing, - atol_xlmda::Float64=1e-9, rtol_xlmda::Float64=1e-6) + zi::Int, mi::Int, wdfac::Float64, divxfac::Float64, + electron::Bool, method::String, equil, intr::KineticForcesInternal, + kinetic_profiles::Equilibrium.KineticProfileSplines; + op_wmats::Union{Nothing,Array{ComplexF64,3}}=nothing, + rex_override::Union{Nothing,Float64}=nothing, + imx_override::Union{Nothing,Float64}=nothing, + atol_xlmda::Float64=1e-9, rtol_xlmda::Float64=1e-6) # Enforce bounds if psi > 1 @@ -72,12 +75,12 @@ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int, # Sample poloidal quantities on theta grid (buffers pre-allocated on intr). mthsurf_local = intr.mthsurf - xs = intr.tpsi_xs - B_vals = intr.tpsi_B - dBdpsi_vals = intr.tpsi_dBdpsi + xs = intr.tpsi_xs + B_vals = intr.tpsi_B + dBdpsi_vals = intr.tpsi_dBdpsi dBdtheta_vals = intr.tpsi_dBdtheta - jac_vals = intr.tpsi_jac - djdpsi_vals = intr.tpsi_djdpsi + jac_vals = intr.tpsi_jac + djdpsi_vals = intr.tpsi_djdpsi hB = intr.hint2d_eqfun_B hJ = intr.hint2d_rzphi_jac @@ -144,14 +147,14 @@ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int, # Flux-function quantities — read directly from named splines on the # PlasmaEquilibrium and the externally-loaded KineticProfileSplines. - q = equil.profiles.q_spline(psi) - dVdpsi = equil.profiles.dVdpsi_spline(psi) + q = equil.profiles.q_spline(psi) + dVdpsi = equil.profiles.dVdpsi_spline(psi) if electron - n_s = kinetic_profiles.ne_spline(psi) - T_s = kinetic_profiles.Te_spline(psi) + n_s = kinetic_profiles.ne_spline(psi) + T_s = kinetic_profiles.Te_spline(psi) dn_s_dpsi = kinetic_profiles.ne_deriv(psi) dT_s_dpsi = kinetic_profiles.Te_deriv(psi) - nu_s = kinetic_profiles.nue_spline(psi) + nu_s = kinetic_profiles.nue_spline(psi) else # ni_spline / nui_spline carry THIS species' resonant density and its # full-composition collisionality (per-species views built by the loader). @@ -159,7 +162,7 @@ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int, T_s = kinetic_profiles.Ti_spline(psi) dn_s_dpsi = kinetic_profiles.ni_deriv(psi) dT_s_dpsi = kinetic_profiles.Ti_deriv(psi) - nu_s = kinetic_profiles.nui_spline(psi) + nu_s = kinetic_profiles.nui_spline(psi) end welec = kinetic_profiles.omegaE_spline(psi) @@ -167,10 +170,10 @@ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int, # time from the kinetic-profile derivatives — no longer baked into the loader. wdian = -twopi * T_s * dn_s_dpsi / (chrg * intr.chi1 * n_s) wdiat = -twopi * dT_s_dpsi / (chrg * intr.chi1) - wphi = welec + wdian + wdiat + wphi = welec + wdian + wdiat wtran = sqrt(2 * T_s / mass) / (q * intr.ro) wgyro = chrg * intr.bo / mass - nuk = nu_s + nuk = nu_s rsquared_bmin = equil.rzphi_rsquared((psi, theta_bmin)) if rsquared_bmin <= 0 @@ -187,7 +190,7 @@ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int, avg_r = equil.geometry.avg_r_spline(psi) avg_R = equil.geometry.avg_R_spline(psi) - epsr = avg_r / avg_R + epsr = avg_r / avg_R wbhat = (π / 4) * sqrt(epsr / 2) * wtran wdhat = q^3 * wtran^2 / (4 * epsr * wgyro) * wdfac nueff = nu_s / (2 * epsr) @@ -196,17 +199,17 @@ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int, kind = method_kind(method) if kind == :fcgl tpsi_var[] = calculate_fcgl(psi, n, l, tspl, dbob_m_f, divx_m_f, divxfac, - n_s, T_s, equil, intr) + n_s, T_s, equil, intr) elseif kind == :rlar tpsi_var[] = calculate_rlar(psi, n, l, q, epsr, wdian, wdiat, welec, - wdhat, wbhat, nueff, dVdpsi, n_s, T_s, - dbob_m_f, intr.bo, bmin) + wdhat, wbhat, nueff, dVdpsi, n_s, T_s, + dbob_m_f, intr.bo, bmin) elseif kind == :clar tpsi_var[] = calculate_clar(psi, n, l, q, epsr, wdian, wdiat, welec, - nuk, intr.bo, bmax, bmin, n_s, T_s, mass, chrg, - tspl, dbob_m_f, divx_m_f, divxfac, wdfac) + nuk, intr.bo, bmax, bmin, n_s, T_s, mass, chrg, + tspl, dbob_m_f, divx_m_f, divxfac, wdfac) else # :gar — fgar/tgar/pgar + all *mm matrix methods # Evaluate geometric matrices at current ψ if matrix path @@ -223,17 +226,17 @@ function tpsi!(tpsi_var::Ref{ComplexF64}, psi::Float64, n::Int, l::Int, zmat_f = reshape(intr.zmats(psi), intr.mpert, intr.mpert) end tpsi_var[] = calculate_gar(psi, n, l, q, epsr, wdian, wdiat, welec, - nuk, intr.bo, bmax, bmin, n_s, T_s, mass, chrg, - tspl, dbob_m_f, divx_m_f, divxfac, wdfac, - method, op_wmats; - chi1=intr.chi1, ro=intr.ro, mfac=intr.mfac, - mpert=intr.mpert, theta_bmax=theta_bmax, - B_extrap=B_extrap, - smat=smat_f, tmat=tmat_f, xmat=xmat_f, - ymat=ymat_f, zmat=zmat_f, - energy_atol=atol_xlmda, energy_rtol=rtol_xlmda, - pitch_atol=atol_xlmda, pitch_rtol=rtol_xlmda, - rex_override=rex_override, imx_override=imx_override) + nuk, intr.bo, bmax, bmin, n_s, T_s, mass, chrg, + tspl, dbob_m_f, divx_m_f, divxfac, wdfac, + method, op_wmats; + chi1=intr.chi1, ro=intr.ro, mfac=intr.mfac, + mpert=intr.mpert, theta_bmax=theta_bmax, + B_extrap=B_extrap, + smat=smat_f, tmat=tmat_f, xmat=xmat_f, + ymat=ymat_f, zmat=zmat_f, + energy_atol=atol_xlmda, energy_rtol=rtol_xlmda, + pitch_atol=atol_xlmda, pitch_rtol=rtol_xlmda, + rex_override=rex_override, imx_override=imx_override) end return nothing @@ -255,8 +258,8 @@ Only valid for bounce harmonic l=0. Based on: [Logan et al., Phys. Plasmas 2013] """ function calculate_fcgl(psi, n, l, tspl, dbob_m_f, divx_m_f, divxfac::Float64, - n_s::Float64, T_s::Float64, equil, - intr::KineticForcesInternal)::ComplexF64 + n_s::Float64, T_s::Float64, equil, + intr::KineticForcesInternal)::ComplexF64 # Only implemented for l=0 if l != 0 @@ -267,7 +270,7 @@ function calculate_fcgl(psi, n, l, tspl, dbob_m_f, divx_m_f, divxfac::Float64, # Create spline for poloidal integrands cglspl = zeros(2, mthsurf_local + 1) - theta_vals = range(0, 1, length=mthsurf_local + 1) + theta_vals = range(0, 1; length=mthsurf_local + 1) # Evaluate poloidal functions and field perturbations hB = intr.hint2d_eqfun_B @@ -301,8 +304,8 @@ function calculate_fcgl(psi, n, l, tspl, dbob_m_f, divx_m_f, divxfac::Float64, # Calculate torque: T = 2*n*i*n_s*T_s * [weighted integral] result = 2.0 * n * im * n_s * T_s * - (0.5 * (5.0/3.0) * integral_1 + - 0.5 * (1.0/3.0) * integral_2) + (0.5 * (5.0/3.0) * integral_1 + + 0.5 * (1.0/3.0) * integral_2) return result end @@ -319,9 +322,9 @@ Valid for low aspect ratio tokamaks (ε << 1). Reference: [Logan et al., Phys. Plasmas, 2013] """ function calculate_rlar(psi, n, l, q, epsr, wdian, wdiat, welec, - wdhat, wbhat, nueff, dVdpsi::Float64, - n_s::Float64, T_s::Float64, - dbob_m_f, bo, bmin=0.5)::ComplexF64 + wdhat, wbhat, nueff, dVdpsi::Float64, + n_s::Float64, T_s::Float64, + dbob_m_f, bo, bmin=0.5)::ComplexF64 # Setup parameters for energy integration lnq = Float64(l) # Resonant mode for trapped particles @@ -332,11 +335,11 @@ function calculate_rlar(psi, n, l, q, epsr, wdian, wdiat, welec, # Energy-space quadrature # This computes ∫ K(x) dx where K is the resonance operator xint = integrate_energy(wdian, wdiat, welec, wdhat, wbhat, nueff, - l, lnq, n, psi, lmdamax, "rlar") + l, lnq, n, psi, lmdamax, "rlar") # Kappa/bounce averaging (effect of field perturbations) # Placeholder: simplified estimate - kappaint_val = sqrt(mean(abs.(dbob_m_f).^2)) + kappaint_val = sqrt(mean(abs.(dbob_m_f) .^ 2)) # dV/dpsi gradient term from Clebsch coordinate Jacobian psi_factor = dVdpsi @@ -363,8 +366,8 @@ Includes bounce-averaged integrals over lambda (pitch angle). Status: Partially implemented (stub for full calculation) """ function calculate_clar(psi, n, l, q, epsr, wdian, wdiat, welec, nuk, bo, - bmax, bmin, n_s::Float64, T_s::Float64, mass, chrg, tspl, - dbob_m_f, divx_m_f, divxfac, wdfac)::ComplexF64 + bmax, bmin, n_s::Float64, T_s::Float64, mass, chrg, tspl, + dbob_m_f, divx_m_f, divxfac, wdfac)::ComplexF64 @warn "CLAR method not yet fully implemented, returning zero" maxlog=1 return ComplexF64(0.0, 0.0) @@ -384,35 +387,37 @@ Can compute torque (*TMM), energy (*WMM), or matrix elements (*KMM/*RMM). Ports Fortran torque.F90 GAR branch (lines 529-932). # Steps -1. Compute bounce-averaged quantities via `compute_bounce_data()` -2. Build fbnce interpolant over λ, normalize for numerical stability -3. Integrate over pitch angle via `integrate_pitch_gar_quadgk()` -4. Apply torque normalization (Eq. 19, Logan et al. 2013) -5. If matrix path: assemble and normalize kinetic matrices + + 1. Compute bounce-averaged quantities via `compute_bounce_data()` + 2. Build fbnce interpolant over λ, normalize for numerical stability + 3. Integrate over pitch angle via `integrate_pitch_gar_quadgk()` + 4. Apply torque normalization (Eq. 19, Logan et al. 2013) + 5. If matrix path: assemble and normalize kinetic matrices # Keyword Arguments (rex/imx override) -- `rex_override::Union{Nothing,Float64}`: Override real-part multiplier for resonance - operator. When both overrides are provided, bypasses method-string derivation. -- `imx_override::Union{Nothing,Float64}`: Override imaginary-part multiplier. - Use `rex_override=1.0, imx_override=1.0` to get full complex result for - simultaneous kwmat/ktmat extraction via `compute_kinetic_matrices_at_psi!`. + + - `rex_override::Union{Nothing,Float64}`: Override real-part multiplier for resonance + operator. When both overrides are provided, bypasses method-string derivation. + - `imx_override::Union{Nothing,Float64}`: Override imaginary-part multiplier. + Use `rex_override=1.0, imx_override=1.0` to get full complex result for + simultaneous kwmat/ktmat extraction via `compute_kinetic_matrices_at_psi!`. Reference: [Logan et al., Phys. Plasmas 20, 122507 (2013)] """ function calculate_gar(psi, n, l, q, epsr, wdian, wdiat, welec, nuk, bo, - bmax, bmin, n_s::Float64, T_s::Float64, mass, chrg, tspl, - dbob_m_f, divx_m_f, divxfac, wdfac, method, op_wmats; - chi1::Float64, ro::Float64, mfac::Vector{Int}, mpert::Int, - theta_bmax::Float64, B_extrap, - smat=nothing, tmat=nothing, xmat=nothing, - ymat=nothing, zmat=nothing, - nlmda::Int=128, ntheta::Int=128, - nutype::String="harmonic", f0type::String="maxwellian", - nufac::Float64=1.0, ximag::Float64=0.0, qt::Bool=false, - energy_atol::Float64=1e-7, energy_rtol::Float64=1e-5, - pitch_atol::Float64=1e-9, pitch_rtol::Float64=1e-6, - rex_override::Union{Nothing,Float64}=nothing, - imx_override::Union{Nothing,Float64}=nothing)::ComplexF64 + bmax, bmin, n_s::Float64, T_s::Float64, mass, chrg, tspl, + dbob_m_f, divx_m_f, divxfac, wdfac, method, op_wmats; + chi1::Float64, ro::Float64, mfac::Vector{Int}, mpert::Int, + theta_bmax::Float64, B_extrap, + smat=nothing, tmat=nothing, xmat=nothing, + ymat=nothing, zmat=nothing, + nlmda::Int=128, ntheta::Int=128, + nutype::String="harmonic", f0type::String="maxwellian", + nufac::Float64=1.0, ximag::Float64=0.0, qt::Bool=false, + energy_atol::Float64=1e-7, energy_rtol::Float64=1e-5, + pitch_atol::Float64=1e-9, pitch_rtol::Float64=1e-6, + rex_override::Union{Nothing,Float64}=nothing, + imx_override::Union{Nothing,Float64}=nothing)::ComplexF64 # Bounce-averaged quantities per pitch angle bounce = compute_bounce_data( @@ -443,7 +448,7 @@ function calculate_gar(psi, n, l, q, epsr, wdian, wdiat, welec, nuk, bo, # keeps the historical OLD-path behavior (torque pipeline uses only the # real part of the outer products). @inbounds for q in 1:nqty_mat, ilmda in 1:bounce.nlmda - fbnce_data[ilmda, 3 + q] = real(bounce.wmats_vs_lambda[ilmda, q]) + fbnce_data[ilmda, 3+q] = real(bounce.wmats_vs_lambda[ilmda, q]) end end @@ -497,7 +502,7 @@ function calculate_gar(psi, n, l, q, epsr, wdian, wdiat, welec, nuk, bo, base = 1 # lxint offset after scalar-torque slot (index 1) # Helper: fetch normalized pitch integral at lxint[base+q] for q ∈ [1..nqty_mat]. - @inline elem(q) = complex(lxint[base + q] / fbnce_norm[base + q]) * energy_factor + @inline elem(q) = complex(lxint[base+q] / fbnce_norm[base+q]) * energy_factor # A (Hermitian, k=1): upper triangle stored at q ∈ [1..Mu]; mirror to lower. off = 0 @@ -586,7 +591,7 @@ without perturbing the perturbative torque pipeline. function _setup_surface_state( psi::Float64, zi::Int, mi::Int, electron::Bool, equil, intr::KineticForcesInternal, - kinetic_profiles::Equilibrium.KineticProfileSplines, + kinetic_profiles::Equilibrium.KineticProfileSplines ) if electron chrg = -1 * e @@ -597,12 +602,12 @@ function _setup_surface_state( end mthsurf_local = intr.mthsurf - xs = intr.tpsi_xs - B_vals = intr.tpsi_B - dBdpsi_vals = intr.tpsi_dBdpsi + xs = intr.tpsi_xs + B_vals = intr.tpsi_B + dBdpsi_vals = intr.tpsi_dBdpsi dBdtheta_vals = intr.tpsi_dBdtheta - jac_vals = intr.tpsi_jac - djdpsi_vals = intr.tpsi_djdpsi + jac_vals = intr.tpsi_jac + djdpsi_vals = intr.tpsi_djdpsi hB = intr.hint2d_eqfun_B hJ = intr.hint2d_rzphi_jac @@ -657,17 +662,17 @@ function _setup_surface_state( q = equil.profiles.q_spline(psi) if electron - n_s = kinetic_profiles.ne_spline(psi) - T_s = kinetic_profiles.Te_spline(psi) + n_s = kinetic_profiles.ne_spline(psi) + T_s = kinetic_profiles.Te_spline(psi) dn_s_dpsi = kinetic_profiles.ne_deriv(psi) dT_s_dpsi = kinetic_profiles.Te_deriv(psi) - nu_s = kinetic_profiles.nue_spline(psi) + nu_s = kinetic_profiles.nue_spline(psi) else - n_s = kinetic_profiles.ni_spline(psi) - T_s = kinetic_profiles.Ti_spline(psi) + n_s = kinetic_profiles.ni_spline(psi) + T_s = kinetic_profiles.Ti_spline(psi) dn_s_dpsi = kinetic_profiles.ni_deriv(psi) dT_s_dpsi = kinetic_profiles.Ti_deriv(psi) - nu_s = kinetic_profiles.nui_spline(psi) + nu_s = kinetic_profiles.nui_spline(psi) end welec = kinetic_profiles.omegaE_spline(psi) @@ -675,7 +680,7 @@ function _setup_surface_state( wdiat = -twopi * dT_s_dpsi / (chrg * intr.chi1) wtran = sqrt(2 * T_s / mass) / (q * intr.ro) wgyro = chrg * intr.bo / mass - nuk = nu_s + nuk = nu_s rsquared_bmin = equil.rzphi_rsquared((psi, theta_bmin)) rsquared_bmin > 0 || @@ -683,14 +688,14 @@ function _setup_surface_state( avg_r = equil.geometry.avg_r_spline(psi) avg_R = equil.geometry.avg_R_spline(psi) - epsr = avg_r / avg_R + epsr = avg_r / avg_R return (; chrg, mass, tspl, B_extrap, bmax, bmin, theta_bmax, q, n_s, T_s, welec, wdian, wdiat, wtran, wgyro, nuk, - epsr, + epsr ) end @@ -714,8 +719,8 @@ match against Fortran `fourfit.F:1080-1082` (`kwmat_l`, `ktmat_l`). For the Hermitian-outer-product blocks A/D/H stored as upper-triangles, the mirror rule differs between halves: - kwmat[j,i] = conj(kwmat[i,j]) — Hermitian (S_w pure imaginary) - ktmat[j,i] = -conj(ktmat[i,j]) — anti-Hermitian (S_t pure real) +kwmat[j,i] = conj(kwmat[i,j]) — Hermitian (S_w pure imaginary) +ktmat[j,i] = -conj(ktmat[i,j]) — anti-Hermitian (S_t pure real) Derivation: `conj(S_w) = -S_w` vs `conj(S_t) = S_t`, combined with `conj(factor) = -factor` (factor = -i/(2n)). These mirrors recover Fortran's independent-slot computation at the mirrored (j,i) positions. @@ -735,8 +740,8 @@ function kinetic_energy_matrices_for_euler_lagrange!( mpert = intr.mpert mfac = intr.mfac chi1 = intr.chi1 - ro = intr.ro - bo = intr.bo + ro = intr.ro + bo = intr.bo # Geometric matrices at this ψ smat_f = reshape(intr.smats(psi), mpert, mpert) @@ -805,7 +810,7 @@ function kinetic_energy_matrices_for_euler_lagrange!( Mu = (mpert * (mpert + 1)) ÷ 2 # Fetch normalized element at pitch-integral slot q, from either half. # half_offset = 0 for wmm (→kwmat), = nqty for tmm (→ktmat). - @inline elem(q, half_offset) = complex(lxint[half_offset + q] / fbnce_norm[q]) * energy_factor + @inline elem(q, half_offset) = complex(lxint[half_offset+q] / fbnce_norm[q]) * energy_factor # For A/D/H Hermitian-outer-product blocks stored as upper-triangles, the # lower-triangle reconstruction uses different mirrors per half: @@ -829,11 +834,16 @@ function kinetic_energy_matrices_for_euler_lagrange!( for (dest, half, mirror_sign) in ((kwmat, 0, 1.0), (ktmat, nqty, -1.0)) off = 0 - _assemble_hermitian!(dest, 1, off, half, mirror_sign); off += Mu # A (k=1) - _assemble_hermitian!(dest, 4, off, half, mirror_sign); off += Mu # D (k=4) - _assemble_hermitian!(dest, 6, off, half, mirror_sign); off += Mu # H (k=6) - _assemble_full!(dest, 2, off, half); off += mpert^2 # B (k=2) - _assemble_full!(dest, 3, off, half); off += mpert^2 # C (k=3) + _assemble_hermitian!(dest, 1, off, half, mirror_sign) + off += Mu # A (k=1) + _assemble_hermitian!(dest, 4, off, half, mirror_sign) + off += Mu # D (k=4) + _assemble_hermitian!(dest, 6, off, half, mirror_sign) + off += Mu # H (k=6) + _assemble_full!(dest, 2, off, half) + off += mpert^2 # B (k=2) + _assemble_full!(dest, 3, off, half) + off += mpert^2 # C (k=3) _assemble_full!(dest, 5, off, half) # E (k=5) end @@ -875,14 +885,15 @@ adjoint combinations `kwmat ± ktmat` in `ForceFreeStates/Kinetic.jl` / Fortran `dcon/sing.f:967-1075` for non-Hermitian B_k, C_k, E_k. # Arguments -- `kwmat::Array{ComplexF64,3}`: Output (mpert×mpert×6), fwmm half, zeroed on entry -- `ktmat::Array{ComplexF64,3}`: Output (mpert×mpert×6), ftmm half, zeroed on entry -- `psi, n, l, zi, mi, wdfac, divxfac, electron`: Same as `tpsi!` (divxfac unused - on the matrix path — retained for call-site compatibility) -- `equil`: PlasmaEquilibrium -- `intr::KineticForcesInternal`: Internal state with mode indexing, geometric - matrices (smats/tmats/xmats/ymats/zmats), and per-surface θ-grid buffers -- `kinetic_profiles::Equilibrium.KineticProfileSplines`: Named kinetic-profile splines + + - `kwmat::Array{ComplexF64,3}`: Output (mpert×mpert×6), fwmm half, zeroed on entry + - `ktmat::Array{ComplexF64,3}`: Output (mpert×mpert×6), ftmm half, zeroed on entry + - `psi, n, l, zi, mi, wdfac, divxfac, electron`: Same as `tpsi!` (divxfac unused + on the matrix path — retained for call-site compatibility) + - `equil`: PlasmaEquilibrium + - `intr::KineticForcesInternal`: Internal state with mode indexing, geometric + matrices (smats/tmats/xmats/ymats/zmats), and per-surface θ-grid buffers + - `kinetic_profiles::Equilibrium.KineticProfileSplines`: Named kinetic-profile splines Reference: [Logan et al., Phys. Plasmas 20, 122507 (2013)] """ @@ -904,7 +915,7 @@ function compute_kinetic_matrices_at_psi!( end state = _setup_surface_state(psi, zi, mi, electron, - equil, intr, kinetic_profiles) + equil, intr, kinetic_profiles) kinetic_energy_matrices_for_euler_lagrange!( kwmat, ktmat, state, psi, n, l, wdfac, intr; @@ -914,5 +925,3 @@ function compute_kinetic_matrices_at_psi!( return nothing end - - diff --git a/src/KineticForces/Utils.jl b/src/KineticForces/Utils.jl index 51c0cd3a8..0be9b3406 100644 --- a/src/KineticForces/Utils.jl +++ b/src/KineticForces/Utils.jl @@ -44,7 +44,7 @@ in `psi_panel_points`). function _resonance_nodes_from_frequencies(wbhat_f, welec_f, wdhat_f, grid; n::Int, nl::Int, xeval::Float64=2.5) nodes = Float64[] sx = sqrt(xeval) - for l in -nl:nl + for l in (-nl):nl append!(nodes, find_sign_change_roots(psi -> l * wbhat_f(psi) * sx + n * (welec_f(psi) + wdhat_f(psi) * xeval), grid)) end return nodes @@ -71,7 +71,7 @@ the estimate degenerates. Panel placement only needs ~peak-width accuracy, so th estimates (single spline evaluations) are sufficient and no bounce averaging is performed. """ function kinetic_resonance_psi_nodes(kinetic_profiles::Equilibrium.KineticProfileSplines, equil; - n::Int, nl::Int, zi::Int=1, mi::Int=2, electron::Bool=false, wdfac::Float64=1.0, xeval::Float64=2.5) + n::Int, nl::Int, zi::Int=1, mi::Int=2, electron::Bool=false, wdfac::Float64=1.0, xeval::Float64=2.5) chrg = electron ? -e : zi * e mass = electron ? me : mi * mp T_spline = electron ? kinetic_profiles.Te_spline : kinetic_profiles.Ti_spline diff --git a/src/LocalStability/Ballooning.jl b/src/LocalStability/Ballooning.jl index 2add47a62..5f11e9992 100644 --- a/src/LocalStability/Ballooning.jl +++ b/src/LocalStability/Ballooning.jl @@ -755,17 +755,18 @@ function ballooning_alpha_crossings( # Δ' as a function of the α scaling at fixed magnetic shear. Failed evaluations # (extreme corrections can break the coefficient assembly) count as non-stable # samples and are rejected by the crossing classification, like in scan_delta_prime_map. - delta_at(scale) = try - ballooning_delta_prime( - psi_idx, - plasma_eq; - corr_qprime=0.0, - corr_pprime=ref.pprime_norm_ref * (scale - 1.0), - theta_k=theta_k - ).delta_prime - catch - NaN - end + delta_at(scale) = + try + ballooning_delta_prime( + psi_idx, + plasma_eq; + corr_qprime=0.0, + corr_pprime=ref.pprime_norm_ref * (scale - 1.0), + theta_k=theta_k + ).delta_prime + catch + NaN + end samples = collect(range(0.0, max_alpha_scale; length=n_scan + 1)) scales = _ballooning_marginal_crossings(delta_at, samples, tol; max_crossings=max_crossings) @@ -796,7 +797,7 @@ function _ballooning_marginal_crossings(delta_at, samples, tol; pole_cap=3.0, ma k0 == 0 && return Float64[] d_anchor = abs(d_prev) locs = Float64[] - for k in k0+1:n + for k in (k0+1):n d = delta_at(samples[k]) if isfinite(d_prev) && isfinite(d) && sign(d) != sign(d_prev) && max(abs(d_prev), abs(d)) <= pole_cap * d_anchor lo, hi = samples[k-1], samples[k] @@ -981,17 +982,18 @@ function ballooning_qprime_crossings( # Δ' as a function of the q' scaling at the experimental pressure gradient. Failed # evaluations (reversed-shear corrections can break the coefficient assembly) count # as non-stable samples and are rejected by the crossing classification. - delta_at(scale) = try - ballooning_delta_prime( - psi_idx, - plasma_eq; - corr_qprime=ref.qprime_norm_ref * (scale - 1.0), - corr_pprime=0.0, - theta_k=theta_k - ).delta_prime - catch - NaN - end + delta_at(scale) = + try + ballooning_delta_prime( + psi_idx, + plasma_eq; + corr_qprime=ref.qprime_norm_ref * (scale - 1.0), + corr_pprime=0.0, + theta_k=theta_k + ).delta_prime + catch + NaN + end samples = collect(range(max_qprime_scale, min_qprime_scale; length=n_scan + 1)) scales = _ballooning_marginal_crossings(delta_at, samples, tol) diff --git a/src/PerturbedEquilibrium/FieldReconstruction.jl b/src/PerturbedEquilibrium/FieldReconstruction.jl index 65f36ee51..f4532c6ef 100644 --- a/src/PerturbedEquilibrium/FieldReconstruction.jl +++ b/src/PerturbedEquilibrium/FieldReconstruction.jl @@ -980,10 +980,12 @@ function _apply_rzphi_transform( # Per-thread scratch (the immutable `ft` functor and `geom` are shared read-only): θ-space # transform inputs/outputs (length mtheta) and mode-space forward-DFT outputs (length mpert), # so the DFTs run in place with no per-surface allocation. - bufs = [(R=zeros(ComplexF64, mtheta), Z=zeros(ComplexF64, mtheta), P=zeros(ComplexF64, mtheta), - psi=zeros(ComplexF64, mtheta), th=zeros(ComplexF64, mtheta), ze=zeros(ComplexF64, mtheta), - Ro=zeros(ComplexF64, mpert), Zo=zeros(ComplexF64, mpert), Po=zeros(ComplexF64, mpert)) - for _ in 1:Threads.maxthreadid()] + bufs = [ + (R=zeros(ComplexF64, mtheta), Z=zeros(ComplexF64, mtheta), P=zeros(ComplexF64, mtheta), + psi=zeros(ComplexF64, mtheta), th=zeros(ComplexF64, mtheta), ze=zeros(ComplexF64, mtheta), + Ro=zeros(ComplexF64, mpert), Zo=zeros(ComplexF64, mpert), Po=zeros(ComplexF64, mpert)) + for _ in 1:Threads.maxthreadid() + ] Threads.@threads :static for ipsi in 1:npsi buf = bufs[Threads.threadid()] diff --git a/src/PerturbedEquilibrium/PerturbedEquilibriumStructs.jl b/src/PerturbedEquilibrium/PerturbedEquilibriumStructs.jl index d8251de38..aa1250030 100644 --- a/src/PerturbedEquilibrium/PerturbedEquilibriumStructs.jl +++ b/src/PerturbedEquilibrium/PerturbedEquilibriumStructs.jl @@ -26,7 +26,9 @@ Medium Priority (defer for MWE): - `singular_point_method::String` - Method for singular point treatment (default: "standard") Regularization: - # High Priority (MWE) + +# High Priority (MWE) + - `reg_spot::Float64` - Regularization width for singular surface smoothing (default: 0.05). Set to 0 to disable. Must be ≥ 0. """ @kwdef struct PerturbedEquilibriumControl @@ -121,6 +123,7 @@ Metadata [n_rational] — identifies each (surface, n) row: Control-surface forcing/response spectra [numpert_total], in the three Pharr (2026) field representations (all tesla; no flux/weber is stored): + - `forcing_b`/`response_b` - bare normal field b (Σ⁻¹·b̃) - `forcing_b_rootarea`/`response_b_rootarea` - root-area-weighted field b̃ (coordinate-invariant) - `forcing_b_area`/`response_b_area` - area-weighted field b̄ (= S·b̃; flux is Φ = A·b̄) @@ -185,18 +188,18 @@ well-conditioned flux-space inductances L, Λ: rational_surface_idx::Vector{Int} = Int[] # Control-surface forcing/response spectra in the three weightings of field representations [numpert_total], tesla - forcing_b::Vector{ComplexF64} = ComplexF64[] # bare normal field b (forcing Φ_x) - forcing_b_rootarea::Vector{ComplexF64} = ComplexF64[] # root-area-weighted field b̃ (coordinate-invariant) - forcing_b_area::Vector{ComplexF64} = ComplexF64[] # area-weighted field b̄ - response_b::Vector{ComplexF64} = ComplexF64[] # bare normal field b (response Φ_tot = P·Φ_x) + forcing_b::Vector{ComplexF64} = ComplexF64[] # bare normal field b (forcing Φ_x) + forcing_b_rootarea::Vector{ComplexF64} = ComplexF64[] # root-area-weighted field b̃ (coordinate-invariant) + forcing_b_area::Vector{ComplexF64} = ComplexF64[] # area-weighted field b̄ + response_b::Vector{ComplexF64} = ComplexF64[] # bare normal field b (response Φ_tot = P·Φ_x) response_b_rootarea::Vector{ComplexF64} = ComplexF64[] # root-area-weighted field b̃ - response_b_area::Vector{ComplexF64} = ComplexF64[] # area-weighted field b̄ + response_b_area::Vector{ComplexF64} = ComplexF64[] # area-weighted field b̄ # Control surface matrices [numpert_total × numpert_total], root-area-weighted field (b̃) space - plasma_inductance::Matrix{ComplexF64} = zeros(ComplexF64, 0, 0) # Λ̃ (field space) + plasma_inductance::Matrix{ComplexF64} = zeros(ComplexF64, 0, 0) # Λ̃ (field space) surface_inductance::Matrix{ComplexF64} = zeros(ComplexF64, 0, 0) # L̃ (field space) - permeability::Matrix{ComplexF64} = zeros(ComplexF64, 0, 0) # P̃ = R⁻¹·Λ·L⁻¹·R - reluctance::Matrix{ComplexF64} = zeros(ComplexF64, 0, 0) # ϱ̃ = R†·L⁻¹·(Λ−L)·L⁻¹·R + permeability::Matrix{ComplexF64} = zeros(ComplexF64, 0, 0) # P̃ = R⁻¹·Λ·L⁻¹·R + reluctance::Matrix{ComplexF64} = zeros(ComplexF64, 0, 0) # ϱ̃ = R†·L⁻¹·(Λ−L)·L⁻¹·R rootarea_to_area_weight::Matrix{ComplexF64} = zeros(ComplexF64, 0, 0) # S = Σ/√A at psilim: b̃→b̄ recovery operator surface_area::Float64 = 0.0 # scalar control-surface area A = ∫J|∇ψ|dθ (flux: Φ = A·b̄; conform R = S·A) diff --git a/src/PerturbedEquilibrium/Utils.jl b/src/PerturbedEquilibrium/Utils.jl index fc1eb9c0a..38be26f87 100644 --- a/src/PerturbedEquilibrium/Utils.jl +++ b/src/PerturbedEquilibrium/Utils.jl @@ -12,8 +12,9 @@ avoiding repeated index arithmetic throughout the code. ## Mode Indexing Convention For linear index i ∈ [1, numpert_total]: -- m_modes[i] = (i-1) % mpert + mlow -- n_modes[i] = (i-1) ÷ mpert + nlow + + - m_modes[i] = (i-1) % mpert + mlow + - n_modes[i] = (i-1) ÷ mpert + nlow This matches the convention used in ForceFreeStates where modes are ordered as: (m1,n1), (m2,n1), ..., (mpert,n1), (m1,n2), (m2,n2), ..., (mpert,npert) @@ -110,47 +111,47 @@ function write_outputs_to_HDF5( # Forcing modes forcing_group = haskey(pe_group, "ForcingModes") ? pe_group["ForcingModes"] : create_group(pe_group, "ForcingModes") - forcing_group["n"] = [mode.n for mode in intr.forcing_modes] - forcing_group["m"] = [mode.m for mode in intr.forcing_modes] + forcing_group["n"] = [mode.n for mode in intr.forcing_modes] + forcing_group["m"] = [mode.m for mode in intr.forcing_modes] forcing_group["amplitude"] = [mode.amplitude for mode in intr.forcing_modes] # Control-surface forcing/response spectra in the three Pharr field representations # (all tesla; flux/weber is never stored). b̃ = root-area-weighted (coordinate-invariant). - !isempty(state.forcing_b) && (pe_group["forcing_b"] = state.forcing_b) - !isempty(state.forcing_b_rootarea) && (pe_group["forcing_b_root_area"] = state.forcing_b_rootarea) - !isempty(state.forcing_b_area) && (pe_group["forcing_b_area"] = state.forcing_b_area) - !isempty(state.response_b) && (pe_group["response_b"] = state.response_b) + !isempty(state.forcing_b) && (pe_group["forcing_b"] = state.forcing_b) + !isempty(state.forcing_b_rootarea) && (pe_group["forcing_b_root_area"] = state.forcing_b_rootarea) + !isempty(state.forcing_b_area) && (pe_group["forcing_b_area"] = state.forcing_b_area) + !isempty(state.response_b) && (pe_group["response_b"] = state.response_b) !isempty(state.response_b_rootarea) && (pe_group["response_b_root_area"] = state.response_b_rootarea) - !isempty(state.response_b_area) && (pe_group["response_b_area"] = state.response_b_area) + !isempty(state.response_b_area) && (pe_group["response_b_area"] = state.response_b_area) # Control surface matrices [numpert_total × numpert_total], in coordinate-invariant # root-area-weighted field (b̃) space. Recover the area-weighted field b̄ with the stored # operator S ≡ rootarea_to_area_weight (b̄ = S·b̃): e.g. L_b̄ = S·L̃·S†; recover flux with the # scalar surface_area A: Φ = A·b̄ (internally R = S·A, Φ = R·b̃). [Pharr 2026] mat_group = haskey(pe_group, "ResponseMatrices") ? pe_group["ResponseMatrices"] : create_group(pe_group, "ResponseMatrices") - !isempty(state.plasma_inductance) && (mat_group["plasma_inductance"] = state.plasma_inductance) + !isempty(state.plasma_inductance) && (mat_group["plasma_inductance"] = state.plasma_inductance) !isempty(state.surface_inductance) && (mat_group["surface_inductance"] = state.surface_inductance) - !isempty(state.permeability) && (mat_group["permeability"] = state.permeability) - !isempty(state.reluctance) && (mat_group["reluctance"] = state.reluctance) + !isempty(state.permeability) && (mat_group["permeability"] = state.permeability) + !isempty(state.reluctance) && (mat_group["reluctance"] = state.reluctance) !isempty(state.rootarea_to_area_weight) && (mat_group["rootarea_to_area_weight_operator"] = state.rootarea_to_area_weight) - (state.surface_area != 0.0) && (mat_group["surface_area"] = state.surface_area) + (state.surface_area != 0.0) && (mat_group["surface_area"] = state.surface_area) # Response fields (ComplexF64 directly) response_group = haskey(pe_group, "Response") ? pe_group["Response"] : create_group(pe_group, "Response") !isempty(state.psi_grid) && (response_group["psi"] = state.psi_grid) have_xi = !isnothing(state.xi_modes) - have_b = have_xi && !isnothing(state.b_modes) - response_group["xi_psi"] = have_xi ? state.xi_modes.psi : ComplexF64[] - response_group["b_psi_area_weighted"] = have_b ? state.b_modes.b_psi_area_weighted : ComplexF64[] - response_group["Jb_theta"] = have_b ? state.b_modes.theta : ComplexF64[] - response_group["Jb_zeta"] = have_b ? state.b_modes.zeta : ComplexF64[] - response_group["b_n"] = !isnothing(state.b_n_modes) ? state.b_n_modes : ComplexF64[] - response_group["xi_n"] = !isnothing(state.xi_n_modes) ? state.xi_n_modes : ComplexF64[] + have_b = have_xi && !isnothing(state.b_modes) + response_group["xi_psi"] = have_xi ? state.xi_modes.psi : ComplexF64[] + response_group["b_psi_area_weighted"] = have_b ? state.b_modes.b_psi_area_weighted : ComplexF64[] + response_group["Jb_theta"] = have_b ? state.b_modes.theta : ComplexF64[] + response_group["Jb_zeta"] = have_b ? state.b_modes.zeta : ComplexF64[] + response_group["b_n"] = !isnothing(state.b_n_modes) ? state.b_n_modes : ComplexF64[] + response_group["xi_n"] = !isnothing(state.xi_n_modes) ? state.xi_n_modes : ComplexF64[] # Clebsch displacements for PENTRC (matches Fortran gpout_xclebsch) if have_xi - response_group["xi_clebsch_psi"] = state.xi_modes.clebsch_psi - response_group["dxi_clebsch_psidpsi"] = state.xi_modes.clebsch_psi1 + response_group["xi_clebsch_psi"] = state.xi_modes.clebsch_psi + response_group["dxi_clebsch_psidpsi"] = state.xi_modes.clebsch_psi1 response_group["xi_clebsch_alpha"] = state.xi_modes.clebsch_alpha end @@ -158,36 +159,36 @@ function write_outputs_to_HDF5( if have_xi response_group["Jxi_psi"] = state.xi_modes.psi_J response_group["Jxi_theta"] = state.xi_modes.theta - response_group["Jxi_zeta"] = state.xi_modes.zeta + response_group["Jxi_zeta"] = state.xi_modes.zeta end # Covariant components (from gpeq_cova) if have_xi - response_group["xi_cov_psi"] = state.xi_modes.cova_psi + response_group["xi_cov_psi"] = state.xi_modes.cova_psi response_group["xi_cov_theta"] = state.xi_modes.cova_theta - response_group["xi_cov_zeta"] = state.xi_modes.cova_zeta + response_group["xi_cov_zeta"] = state.xi_modes.cova_zeta end if have_xi response_group["Jxi_theta_reg"] = state.xi_modes.theta_reg - response_group["Jxi_zeta_reg"] = state.xi_modes.zeta_reg + response_group["Jxi_zeta_reg"] = state.xi_modes.zeta_reg end if have_b response_group["Jb_theta_reg"] = state.b_modes.theta_reg - response_group["Jb_zeta_reg"] = state.b_modes.zeta_reg - response_group["b_cov_psi"] = state.b_modes.cova_psi + response_group["Jb_zeta_reg"] = state.b_modes.zeta_reg + response_group["b_cov_psi"] = state.b_modes.cova_psi response_group["b_cov_theta"] = state.b_modes.cova_theta - response_group["b_cov_zeta"] = state.b_modes.cova_zeta + response_group["b_cov_zeta"] = state.b_modes.cova_zeta end # R,Z,φ cylindrical components in mode-space (from gpeq_rzphi) if have_xi - response_group["xi_R"] = state.xi_modes.R - response_group["xi_Z"] = state.xi_modes.Z + response_group["xi_R"] = state.xi_modes.R + response_group["xi_Z"] = state.xi_modes.Z response_group["xi_phi"] = state.xi_modes.phi end if have_b - response_group["b_R"] = state.b_modes.R - response_group["b_Z"] = state.b_modes.Z + response_group["b_R"] = state.b_modes.R + response_group["b_Z"] = state.b_modes.Z response_group["b_phi"] = state.b_modes.phi end @@ -195,34 +196,34 @@ function write_outputs_to_HDF5( coupling_group = haskey(pe_group, "SingularCoupling") ? pe_group["SingularCoupling"] : create_group(pe_group, "SingularCoupling") # Coupling matrices [n_rational × numpert_total] - !isempty(state.C_resonant_area_weighted_field) && (coupling_group["C_resonant_area_weighted_field"] = state.C_resonant_area_weighted_field) + !isempty(state.C_resonant_area_weighted_field) && (coupling_group["C_resonant_area_weighted_field"] = state.C_resonant_area_weighted_field) !isempty(state.C_resonant_current) && (coupling_group["C_resonant_current"] = state.C_resonant_current) - !isempty(state.C_island_width_sq) && (coupling_group["C_island_width_sq"] = state.C_island_width_sq) + !isempty(state.C_island_width_sq) && (coupling_group["C_island_width_sq"] = state.C_island_width_sq) !isempty(state.C_penetrated_area_weighted_field) && (coupling_group["C_penetrated_area_weighted_field"] = state.C_penetrated_area_weighted_field) - !isempty(state.C_delta_prime) && (coupling_group["C_Delta_prime"] = state.C_delta_prime) + !isempty(state.C_delta_prime) && (coupling_group["C_Delta_prime"] = state.C_delta_prime) # Applied resonant vectors [n_rational] - !isempty(state.resonant_area_weighted_field) && (coupling_group["resonant_area_weighted_field"] = state.resonant_area_weighted_field) - !isempty(state.resonant_current) && (coupling_group["resonant_current"] = state.resonant_current) - !isempty(state.island_width_sq) && (coupling_group["island_width_sq"] = state.island_width_sq) - !isempty(state.penetrated_area_weighted_field) && (coupling_group["penetrated_area_weighted_field"] = state.penetrated_area_weighted_field) - !isempty(state.delta_prime) && (coupling_group["Delta_prime"] = state.delta_prime) - !isempty(state.forcing_solution_weights) && (coupling_group["forcing_solution_weights"] = state.forcing_solution_weights) + !isempty(state.resonant_area_weighted_field) && (coupling_group["resonant_area_weighted_field"] = state.resonant_area_weighted_field) + !isempty(state.resonant_current) && (coupling_group["resonant_current"] = state.resonant_current) + !isempty(state.island_width_sq) && (coupling_group["island_width_sq"] = state.island_width_sq) + !isempty(state.penetrated_area_weighted_field) && (coupling_group["penetrated_area_weighted_field"] = state.penetrated_area_weighted_field) + !isempty(state.delta_prime) && (coupling_group["Delta_prime"] = state.delta_prime) + !isempty(state.forcing_solution_weights) && (coupling_group["forcing_solution_weights"] = state.forcing_solution_weights) !isempty(state.rational_area) && (coupling_group["rational_area"] = state.rational_area) - !isempty(state.island_half_width) && (coupling_group["island_half_width"] = state.island_half_width) + !isempty(state.island_half_width) && (coupling_group["island_half_width"] = state.island_half_width) !isempty(state.chirikov_parameter) && (coupling_group["chirikov_parameter"] = state.chirikov_parameter) # Metadata [n_rational] - !isempty(state.rational_psi) && (coupling_group["rational_psi"] = state.rational_psi) - !isempty(state.rational_q) && (coupling_group["rational_q"] = state.rational_q) - !isempty(state.rational_m_res) && (coupling_group["rational_m"] = state.rational_m_res) - !isempty(state.rational_n) && (coupling_group["rational_n"] = state.rational_n) + !isempty(state.rational_psi) && (coupling_group["rational_psi"] = state.rational_psi) + !isempty(state.rational_q) && (coupling_group["rational_q"] = state.rational_q) + !isempty(state.rational_m_res) && (coupling_group["rational_m"] = state.rational_m_res) + !isempty(state.rational_n) && (coupling_group["rational_n"] = state.rational_n) # Energies energy_group = haskey(pe_group, "Energies") ? pe_group["Energies"] : create_group(pe_group, "Energies") - energy_group["vacuum_energy"] = state.vacuum_energy - energy_group["surface_energy"] = state.surface_energy - energy_group["plasma_energy"] = state.plasma_energy + energy_group["vacuum_energy"] = state.vacuum_energy + energy_group["surface_energy"] = state.surface_energy + energy_group["plasma_energy"] = state.plasma_energy energy_group["toroidal_torque"] = state.toroidal_torque annotate_pe!(pe_group) @@ -261,7 +262,8 @@ const PE_H5_ANNOTATIONS = [ "Response/xi_cov_psi" => (; long_name="covariant radial displacement ξ_ψ = ξ·e_ψ", units="m^2", dims=("psi", "mode"), attach=(1 => "Response/psi",)), "Response/xi_cov_theta" => (; long_name="covariant poloidal displacement ξ_θ = ξ·e_θ", units="m^2", dims=("psi", "mode"), attach=(1 => "Response/psi",)), "Response/xi_cov_zeta" => (; long_name="covariant toroidal displacement ξ_ζ = ξ·e_ζ", units="m^2", dims=("psi", "mode"), attach=(1 => "Response/psi",)), - "Response/xi_clebsch_psi" => (; long_name="Clebsch displacement component ξ^ψ (PENTRC input, gpout_xclebsch convention)", dims=("psi", "mode"), attach=(1 => "Response/psi",)), + "Response/xi_clebsch_psi" => + (; long_name="Clebsch displacement component ξ^ψ (PENTRC input, gpout_xclebsch convention)", dims=("psi", "mode"), attach=(1 => "Response/psi",)), "Response/dxi_clebsch_psidpsi" => (; long_name="regularized ψ_N derivative of ξ^ψ (× singfac²/(singfac²+reg_spot²))", dims=("psi", "mode"), attach=(1 => "Response/psi",)), "Response/xi_clebsch_alpha" => diff --git a/src/Rerun.jl b/src/Rerun.jl index 03c19bea6..a71401637 100644 --- a/src/Rerun.jl +++ b/src/Rerun.jl @@ -37,7 +37,8 @@ function read_equilibrium_ingest(in_h5) haskey(in_h5, group_path) || return nothing group = in_h5[group_path] kind = read(group, "ingest_kind") - T = kind == "direct" ? Equilibrium.DirectIngest : + T = + kind == "direct" ? Equilibrium.DirectIngest : kind == "inverse" ? Equilibrium.InverseIngest : error("Unknown equilibrium ingest_kind in gpec.h5: $kind (expected \"direct\" or \"inverse\")") # Positional reconstruction: relies on the default constructor, so `fieldnames(T)` order @@ -75,8 +76,8 @@ numbers, booleans, and quoted strings without worrying about shell quoting. function parse_override_flag(expr::AbstractString) eqidx = findfirst(==('='), expr) eqidx === nothing && error("--override expects key=value, got: $expr") - lhs = String(strip(expr[1:eqidx-1])) - rhs = String(strip(expr[eqidx+1:end])) + lhs = String(strip(expr[1:(eqidx-1)])) + rhs = String(strip(expr[(eqidx+1):end])) isempty(lhs) && error("--override key cannot be empty: $expr") parts = split(lhs, '.') @@ -97,7 +98,7 @@ function parse_override_flag(expr::AbstractString) # Build nested dict from dotted path. root = Dict{String,Any}() cursor = root - for p in parts[1:end-1] + for p in parts[1:(end-1)] cursor[String(p)] = Dict{String,Any}() cursor = cursor[String(p)] end @@ -176,7 +177,7 @@ function resolve_rerun_output_path(source_h5::String, output_dir::String, output source_abs = abspath(source_h5) if output_name === nothing base = basename(source_abs) - stem = endswith(lowercase(base), ".h5") ? base[1:end-3] : base + stem = endswith(lowercase(base), ".h5") ? base[1:(end-3)] : base output_name = string(stem, "_rerun.h5") end if abspath(joinpath(output_dir, output_name)) == source_abs @@ -281,9 +282,11 @@ function build_inputs_from_h5(args::Vector{String}) elseif ingest isa Equilibrium.InverseIngest Equilibrium.build_inverse_from_ingest(eq_config, ingest) else - error("gpec.h5 has no equilibrium ingest and eq_type=$(eq_config.eq_type) is not analytic — cannot replay. " * - "A file-based eq_type needs a stored ingest (pre-ingest snapshots lack one); a new analytic kind must be " * - "registered in Equilibrium.ANALYTIC_EQ.") + error( + "gpec.h5 has no equilibrium ingest and eq_type=$(eq_config.eq_type) is not analytic — cannot replay. " * + "A file-based eq_type needs a stored ingest (pre-ingest snapshots lack one); a new analytic kind must be " * + "registered in Equilibrium.ANALYTIC_EQ." + ) end return inputs, eq_config, additional_input, output_dir, current_git, preloaded_forcing, preloaded_coils diff --git a/src/Tearing/CriticalResonantField/CriticalResonantField.jl b/src/Tearing/CriticalResonantField/CriticalResonantField.jl index 453f04b73..1fe90461a 100644 --- a/src/Tearing/CriticalResonantField/CriticalResonantField.jl +++ b/src/Tearing/CriticalResonantField/CriticalResonantField.jl @@ -14,8 +14,8 @@ using ..InnerLayer using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters, SLAYERModel, SLAYERParameters -#include("TorqueBalance.jl") +include("TorqueBalance.jl") -#export TorqueBalance, torque_balance +export TorqueBalance, torque_balance_value, torque_balance_scan end # module CriticalResonantField diff --git a/src/Tearing/CriticalResonantField/TorqueBalance.jl b/src/Tearing/CriticalResonantField/TorqueBalance.jl index c85bff102..517737c57 100644 --- a/src/Tearing/CriticalResonantField/TorqueBalance.jl +++ b/src/Tearing/CriticalResonantField/TorqueBalance.jl @@ -25,98 +25,62 @@ """ TorqueBalance{M<:InnerLayerModel, P} -Per-surface dispersion data: `(model, params, dp_diag, dc, scale, tauk)`. -Calling `sc(Q)` returns the complex residual +Per-surface torque balance data: `(model, params, Q0, P, lu, sval)`. -``` -r(Q) = dp_diag - scale * solve_inner(model, params, Q).tearing - dc -``` - -A root of `sc` in the complex `Q` plane is a **tearing** eigenvalue at -this surface in the *uncoupled* approximation (only the tearing channel -of the inner-layer response appears — the interchange channel enters the -full 2m×2m dispersion via `MultiSurfaceCoupling`, not this scalar form). -Coupled multi-surface eigenvalues come from `MultiSurfaceCoupling` -evaluating the determinant of the modified Δ' matrix. """ -struct SurfaceCoupling{M<:InnerLayerModel,P} + +struct TorqueBalance{M<:InnerLayerModel,P} model::M params::P - dp_diag::ComplexF64 - dc::Float64 - scale::Float64 - tauk::Float64 + Q0::Float64 + P::Float64 + lu::Float64 + sval::Float64 end -function (sc::SurfaceCoupling)(Q::Number) - Δ = solve_inner(sc.model, sc.params, ComplexF64(Q)).tearing - return sc.dp_diag - sc.scale * Δ - sc.dc +function torque_balance_value(tb::TorqueBalance, Q::Number) + Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing + delta_n_p = 1e-2 # JK hack to avoid singularity at Δ=0.0. Need to fix this in the future. + jxb = -imag(1.0 / (Δ + delta_n_p)) + return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ end """ - surface_coupling(model::SLAYERModel, params::SLAYERParameters, - dp_diag::Number; dc::Real=0.0) -> SurfaceCoupling + torque_balance_scan(model::InnerLayerModel, params::InnerLayerParameters, Q0::Real, P::Real, + lu::Real, sval::Real;Qmin=-10.0, Qmax=10.0, n=200) -> (Qs, bal, Qs_positive, bal_positive, + Qpeak, br_crit, Qpeak_ind, Δs) -SLAYER convenience constructor. `scale` is set to `params.lu^(1/3)` so that -the dimensionless Δ from `riccati_f` is mapped to outer ψ-units before -subtraction from the Δ' diagonal. `tauk` is taken from `params.tauk` for use -by `MultiSurfaceCoupling` Q rescaling. +Scan over a range of Q values to find the maximum of the torque balance equation. +Returns the Q values, torque balance values, positive Q values, positive torque balance values, +the Q value at the peak, the critical resonant field, the index of the peak Q value, and the Δ values for each Q. """ -function surface_coupling(model::SLAYERModel, params::SLAYERParameters, - dp_diag::Number; dc::Real=0.0) - return SurfaceCoupling(model, params, ComplexF64(dp_diag), - Float64(dc), params.lu^(1 / 3), params.tauk) -end -""" - surface_coupling(model::GGJModel, params::GGJParameters, - dp_diag::Number) -> SurfaceCoupling +function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200) + Qs = range(Qmin, Qmax; length=n) + torque_out = [torque_balance_value(tb, q) for q in Qs] + bal = [x[1] for x in torque_out] + Δs = [x[2] for x in torque_out] + positive = isfinite.(bal) .& (bal .> 0.0) -GGJ convenience constructor. `scale` is `1.0` because GGJ's `solve_inner` -applies its own `rescale_delta` (S^(2p₁/3)·v1^(2p₁)) internally, so the -returned Δ is already in outer units. `tauk` defaults to `1.0` (GGJ has no -direct analogue of SLAYER's per-surface time normalization, so multi-surface -Q rescaling is a no-op for GGJ surfaces unless overridden). + if !any(positive) + return Qs, bal, [0.0], [0.0], 0.0, 0.0, NaN, Δs + end + i = argmax(bal) + Qpeak_ind = i + Qpeak = Qs[i] + maxbal = bal[i] -**No `dc` kwarg**: GGJ's 4m×4m Pletzer-Dewar residual already includes the -interchange channel, which provides Glasser (Mercier) stabilization -natively. A Δ_crit proxy (χ_parallel-matching offset on the diagonal) is -meaningful only for tearing-only slab-layer approximations like SLAYER; -for GGJ it would double-count the interchange physics. The `SurfaceCoupling` -struct's `dc` field is hard-wired to 0 here. -""" -function surface_coupling(model::GGJModel, params::GGJParameters, - dp_diag::Number) - return SurfaceCoupling(model, params, ComplexF64(dp_diag), - 0.0, 1.0, 1.0) -end + Qs_positive = Qs[positive] + bal_positive = bal[positive] -""" - surface_coupling(model::InnerLayerModel, params, dp_diag::Number; - dc::Real=0.0, scale::Real=1.0, tauk::Real=1.0) - -> SurfaceCoupling - -Generic fallback constructor. Use this when wiring a new inner-layer model -into the dispersion solver — pass the appropriate inner→outer-units `scale` -and per-surface `tauk` explicitly. -""" -function surface_coupling(model::InnerLayerModel, params, dp_diag::Number; - dc::Real=0.0, scale::Real=1.0, tauk::Real=1.0) - return SurfaceCoupling(model, params, ComplexF64(dp_diag), - Float64(dc), Float64(scale), Float64(tauk)) -end + i = argmax(bal_positive) + #Qpeak = Qs_positive[i] -function torque_balance_value(tb::TorqueBalance, Q::Number) - Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing - jxb = -imag(1.0 / (Δ + tb.delta_n_p)) - return 2.0 * tb.P * (tb.Q0 - Q) / jxb -end + #maxbal = bal_positive[i] -function scan_torque_balance(tb; Qmin=-10.0, Qmax=10.0, nscan=200) - qs = range(Qmin, Qmax; length=nscan) - vals = torque_balance_value.(Ref(tb), qs) - idx = argmax(vals) - return qs[idx], vals[idx] + br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0)) + return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs end -br_th = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0)) +# Need to fix and improve this function. The positive masking is not helpful. +# Need to avoid poles from Q_e and Q_i. diff --git a/src/Tearing/CriticalResonantField/bcrit_dev.ipynb b/src/Tearing/CriticalResonantField/bcrit_dev.ipynb index 78490c308..4af00e1f0 100644 --- a/src/Tearing/CriticalResonantField/bcrit_dev.ipynb +++ b/src/Tearing/CriticalResonantField/bcrit_dev.ipynb @@ -23,16 +23,11 @@ "using GeneralizedPerturbedEquilibrium: Analysis\n", "using GeneralizedPerturbedEquilibrium: InnerLayer\n", "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", - "using GeneralizedPerturbedEquilibrium: Tearing\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2", - "metadata": {}, - "outputs": [], - "source": [ + "using GeneralizedPerturbedEquilibrium: Tearing\n", + "using ..InnerLayer\n", + "using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters,\n", + " SLAYERModel, SLAYERParameters\n", + "\n", "using Plots\n", "default(\n", " fontfamily=\"Georgia\",\n", @@ -45,23 +40,23 @@ { "cell_type": "code", "execution_count": null, - "id": "3", + "id": "2", "metadata": {}, "outputs": [], "source": [ - "struct TorqueBalance\n", - " model\n", - " params\n", + "struct TorqueBalance{M<:InnerLayerModel,P}\n", + " model::M\n", + " params::P\n", " Q0::Float64\n", " P::Float64\n", - " delta_n_p::Float64\n", " lu::Float64\n", " sval::Float64\n", "end\n", "\n", "function torque_balance_value(tb::TorqueBalance, Q::Number)\n", " Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing\n", - " jxb = -imag(1.0 / (Δ + tb.delta_n_p))\n", + " delta_n_p = 1e-2\n", + " jxb = -imag(1.0 / (Δ + delta_n_p))\n", " return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ\n", "end\n", "\n", @@ -94,108 +89,162 @@ { "cell_type": "code", "execution_count": null, - "id": "4", + "id": "3", "metadata": {}, "outputs": [], "source": [ - "function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200)\n", - " Qs = range(Qmin, Qmax; length=n)\n", - " torque_out = [torque_balance_value(tb, q) for q in Qs]\n", - " bal = [x[1] for x in torque_out]\n", - " Δs = [x[2] for x in torque_out]\n", + "# You can substitute any valid SLAYERParameters you already have.\n", + "# This is just an example skeleton.\n", + "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", + " n_e=1e19, t_e=1e3, t_i=1e3,\n", + " omega=0.0, omega_e=4, omega_i=-2,\n", + " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", + " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", + ")\n", + "p2 = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", + " ising=p.ising,\n", + " m=p.m, n=p.n,\n", + " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", + " P_perp=p.P_perp, P_tor=p.P_tor,\n", + " Q_e=4 / p.tauk, Q_i=-10 / p.tauk, iota_e=p.iota_e,\n", + " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", + " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", + " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", + " eta=p.eta, d_beta=p.d_beta,\n", + " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", + ")\n", "\n", - " positive = isfinite.(bal) .& (bal .> 0.0)\n", + "#p = p2\n", "\n", - " if !any(positive)\n", - " return Qs, bal, Float64[], Float64[], NaN, NaN, 0, Δs\n", - " end\n", + "tb = TorqueBalance(\n", + " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", + " p,\n", + " 0.5,\n", + " 1.0,\n", + " p.lu,\n", + " p.sval_r\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "#Qs = range(-5.0, 5.0, length=200)\n", "\n", - " i = argmax(bal)\n", - " Qpeak_ind = i\n", - " Qs_positive = Qs[positive]\n", - " bal_positive = bal[positive]\n", + "#vals = [torque_balance_value(tb, q) for q in Qs]\n", + "\"\"\"\n", + "n=2000:\n", + "Qpeak = 0.24512256128064033\n", + "maxbal = 0.35873684252530247\n", + "br_crit = 4.668551985584323e-5\n", "\n", - " i = argmax(bal_positive)\n", - " Qpeak = Qs_positive[i]\n", - " maxbal = bal_positive[i]\n", + "n=200 (def):\n", + "Qpeak = 0.25125628140703515\n", + "maxbal = 0.3585219071071706\n", + "br_crit = 4.667153206033017e-5\n", + "\"\"\"\n", + "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb)\n", "\n", - " br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", - " return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs\n", - "end\n", - "# one-cell scan: x = b_crit, y = Q_0\n", - "Q0_vals = range(-2.0, 2.0; length=60)\n", + "println(\"Qpeak = \", Qpeak)\n", + "println(\"maxbal = \", maximum(bal_positive))\n", + "println(\"maxbal = \", maximum(bal))\n", + "println(\"br_crit = \", brcrit)\n", "\n", - "bcrit_vals = Float64[]\n", - "locked_flag = Bool[]\n", + "p1 = plot(Qs, bal, lw=2, label=\"balance\")\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"balance\")\n", + "title!(\"Torque-balance scan\")\n", "\n", - "for Q0 in Q0_vals\n", - " tbQ = TorqueBalance(\n", - " tb.model,\n", - " tb.params,\n", - " Float64(Q0),\n", - " tb.P,\n", - " tb.delta_n_p,\n", - " tb.lu,\n", - " tb.sval\n", - " )\n", + "p2 = plot(Qs_positive, bal_positive, lw=2, label=\"balance (positive)\")\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"balance\")\n", + "title!(\"Torque-balance scan\")\n", "\n", - " Qs, bal, Qs_pos, bal_pos, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tbQ; Qmin=-10.0, Qmax=10.0, n=250)\n", + "plot(p1, p2, layout=(2,1), size=(800, 1000))\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "Qpk = Qs_positive[argmax(bal_positive)]\n", + "j = findfirst(isequal(Qpk), Qs)\n", "\n", - " if isempty(bal_pos) || !all(isfinite.(bal_pos)) || maximum(bal_pos) <= 0\n", - " push!(bcrit_vals, NaN)\n", - " push!(locked_flag, false)\n", - " else\n", - " push!(bcrit_vals, brcrit)\n", - " push!(locked_flag, true)\n", - " end\n", - "end\n", + "lhs = 2*tb.P*(tb.Q0 - Qpk) / jxbs[j]\n", + "br_ratio = sqrt(lhs / (tb.lu * tb.sval^2 / 2))\n", "\n", - "# keep only finite x-values for plotting\n", - "x = bcrit_vals[isfinite.(bcrit_vals)]\n", - "y = Q0_vals[isfinite.(bcrit_vals)]\n", - "locked = locked_flag[isfinite.(bcrit_vals)]\n", - "\n", - "p = scatter(\n", - " x[locked], y[locked],\n", - " label=\"locked\",\n", - " color=:green,\n", - " markersize=5,\n", - " marker=:circle,\n", - " xlabel=\"b_crit\",\n", - " ylabel=\"Q_0\",\n", - " title=\"Locked / unlocked boundary\",\n", - " legend=:topleft\n", - ")\n", + "rhs = (tb.lu * tb.sval^2 / 2) * br_ratio^2\n", "\n", - "scatter!(\n", - " p,\n", - " x[.!locked], y[.!locked],\n", - " label=\"unlocked\",\n", - " color=:red,\n", - " markersize=5,\n", - " marker=:square\n", - ")\n", "\n", - "display(p)" + "\n", + "println(\"lhs = \", lhs)\n", + "println(\"rhs = \", rhs)\n", + "println(\"lhs/rhs = \", lhs / rhs)" ] }, { "cell_type": "code", "execution_count": null, - "id": "5", + "id": "6", "metadata": {}, "outputs": [], "source": [ - "import Pkg; Pkg.add(\"DataInterpolations\")" + "#Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing for q in Qs]\n", + "jxbs = [-imag(1.0 / (d + tb.delta_n_p)) for d in Δs]\n", + "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for (q, jxb) in zip(Qs, jxbs)]\n", + "br_t = brcrit\n", + "println(tb.lu, \" \", tb.sval, \" \", br_t, \" \", p.bt, \" \", tb.delta_n_p)\n", + "T_EM = tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs\n", + "i = Qpeak_ind\n", + "println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", + "println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", + "println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", + "\n", + "#T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", + "#T_visc ∝ 2 P (Q0 − Q)\n", + "\n", + "p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", + "#plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Δ\")\n", + "title!(p1, \"Inner-layer Δ(Q)\")\n", + "\n", + "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + "plot!(p2, Qs, T_VISC, label=\"2P(Q0-Q)\", lw=2)\n", + "plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", + "xlabel!(p2, \"Q\")\n", + "ylabel!(p2, \"jxb\")\n", + "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", + "\n", + "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", + "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + "xlabel!(p3, \"Q\")\n", + "ylabel!(p3, \"balance\")\n", + "title!(p3, \"2P(Q0-Q)/jxb\")\n", + "\n", + "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" ] }, { "cell_type": "code", "execution_count": null, - "id": "6", + "id": "7", "metadata": {}, "outputs": [], "source": [ + "# Recreate Cihan's plot:\n", + "\n", "using Plots\n", "using DataInterpolations\n", "\n", @@ -300,54 +349,13 @@ "display(p)" ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "7", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": null, "id": "8", "metadata": {}, "outputs": [], - "source": [ - "# You can substitute any valid SLAYERParameters you already have.\n", - "# This is just an example skeleton.\n", - "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", - " n_e=1e19, t_e=1e3, t_i=1e3,\n", - " omega=0.0, omega_e=4, omega_i=-2,\n", - " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", - " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", - ")\n", - "p2 = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", - " ising=p.ising,\n", - " m=p.m, n=p.n,\n", - " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", - " P_perp=p.P_perp, P_tor=p.P_tor,\n", - " Q_e=4 / p.tauk, Q_i=-10 / p.tauk, iota_e=p.iota_e,\n", - " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", - " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", - " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", - " eta=p.eta, d_beta=p.d_beta,\n", - " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", - ")\n", - "\n", - "#p = p2\n", - "\n", - "tb = TorqueBalance(\n", - " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", - " p,\n", - " 0.5,\n", - " 1.0,\n", - " 1e-2,\n", - " p.lu,\n", - " p.sval_r\n", - ")" - ] + "source": [] }, { "cell_type": "code", @@ -355,141 +363,7 @@ "id": "9", "metadata": {}, "outputs": [], - "source": [ - "\"\"\"\n", - "\n", - "tau_h=R0*(mu0*rho)**0.5/(nns*sval*bt) ! alfven time across surface\n", - "lu=tau_r/tau_h ! Lundquist number\n", - "Qconv=lu**(1.0/3.0)*tau_h ! conversion to Qs based on Cole\n", - "\n", - "! note Q depends on Qconv even if omega is fixed.\n", - "Q=Qconv*omega\n", - "Q_e=-Qconv*omega_e\n", - "Q_i=-Qconv*omega_i\n", - "\n", - "\"\"\"\n", - "2=-lu**(1.0/3.0)*tau_h *OE\n", - "2 = tauk *OE" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10", - "metadata": {}, - "outputs": [], - "source": [ - "Qs = range(-5.0, 5.0, length=200)\n", - "\n", - "vals = [torque_balance_value(tb, q) for q in Qs]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11", - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "n=2000:\n", - "Qpeak = 0.24512256128064033\n", - "maxbal = 0.35873684252530247\n", - "br_crit = 4.668551985584323e-5\n", - "\n", - "n=200 (def):\n", - "Qpeak = 0.25125628140703515\n", - "maxbal = 0.3585219071071706\n", - "br_crit = 4.667153206033017e-5\n", - "\"\"\"\n", - "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb)\n", - "\n", - "println(\"Qpeak = \", Qpeak)\n", - "println(\"maxbal = \", maximum(bal_positive))\n", - "println(\"maxbal = \", maximum(bal))\n", - "println(\"br_crit = \", brcrit)\n", - "\n", - "p1 = plot(Qs, bal, lw=2, label=\"balance\")\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"balance\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "p2 = plot(Qs_positive, bal_positive, lw=2, label=\"balance (positive)\")\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"balance\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "plot(p1, p2, layout=(2,1), size=(800, 1000))\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "12", - "metadata": {}, - "outputs": [], - "source": [ - "Qpk = Qs_positive[argmax(bal_positive)]\n", - "j = findfirst(isequal(Qpk), Qs)\n", - "\n", - "lhs = 2*tb.P*(tb.Q0 - Qpk) / jxbs[j]\n", - "br_ratio = sqrt(lhs / (tb.lu * tb.sval^2 / 2))\n", - "\n", - "rhs = (tb.lu * tb.sval^2 / 2) * br_ratio^2\n", - "\n", - "\n", - "\n", - "println(\"lhs = \", lhs)\n", - "println(\"rhs = \", rhs)\n", - "println(\"lhs/rhs = \", lhs / rhs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "13", - "metadata": {}, - "outputs": [], - "source": [ - "#Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing for q in Qs]\n", - "jxbs = [-imag(1.0 / (d + tb.delta_n_p)) for d in Δs]\n", - "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for (q, jxb) in zip(Qs, jxbs)]\n", - "br_t = brcrit\n", - "println(tb.lu, \" \", tb.sval, \" \", br_t, \" \", p.bt, \" \", tb.delta_n_p)\n", - "T_EM = tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs\n", - "i = Qpeak_ind\n", - "println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", - "println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", - "println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", - "\n", - "#T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", - "#T_visc ∝ 2 P (Q0 − Q)\n", - "\n", - "p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", - "#plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Δ\")\n", - "title!(p1, \"Inner-layer Δ(Q)\")\n", - "\n", - "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - "plot!(p2, Qs, T_VISC, label=\"2P(Q0-Q)\", lw=2)\n", - "plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", - "xlabel!(p2, \"Q\")\n", - "ylabel!(p2, \"jxb\")\n", - "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", - "\n", - "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", - "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - "xlabel!(p3, \"Q\")\n", - "ylabel!(p3, \"balance\")\n", - "title!(p3, \"2P(Q0-Q)/jxb\")\n", - "\n", - "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" - ] + "source": [] } ], "metadata": { diff --git a/src/Tearing/Dispersion/BruteForceScan.jl b/src/Tearing/Dispersion/BruteForceScan.jl index 6e7b8aead..c1f2b55fb 100644 --- a/src/Tearing/Dispersion/BruteForceScan.jl +++ b/src/Tearing/Dispersion/BruteForceScan.jl @@ -15,12 +15,12 @@ Output of a brute-force or AMR Q-plane scan. -| field | meaning | -|------------|---------------------------------------------------| -| `Q` | Complex Q values (`Matrix` for grid, `Vector` for AMR) | -| `Δ` | Residual values, same shape as `Q` | -| `re_axis` | Real-axis grid (only for regular-grid `ScanResult`) | -| `im_axis` | Imaginary-axis grid (only for regular-grid `ScanResult`) | +| field | meaning | +|:--------- |:-------------------------------------------------------- | +| `Q` | Complex Q values (`Matrix` for grid, `Vector` for AMR) | +| `Δ` | Residual values, same shape as `Q` | +| `re_axis` | Real-axis grid (only for regular-grid `ScanResult`) | +| `im_axis` | Imaginary-axis grid (only for regular-grid `ScanResult`) | """ struct ScanResult Q::Matrix{ComplexF64} @@ -53,15 +53,15 @@ from the result. - `threaded` -- distribute Q evaluations across `Threads.@threads` """ function brute_force_scan(f, Q_re_range::NTuple{2,<:Real}, - Q_im_range::NTuple{2,<:Real}; - nre::Integer, nim::Integer, - threaded::Bool=true) + Q_im_range::NTuple{2,<:Real}; + nre::Integer, nim::Integer, + threaded::Bool=true) nre >= 2 || throw(ArgumentError("brute_force_scan: nre must be ≥ 2")) nim >= 2 || throw(ArgumentError("brute_force_scan: nim must be ≥ 2")) re_axis = collect(range(Float64(Q_re_range[1]); stop=Float64(Q_re_range[2]), - length=nre)) + length=nre)) im_axis = collect(range(Float64(Q_im_range[1]); stop=Float64(Q_im_range[2]), - length=nim)) + length=nim)) Q = ComplexF64[(qr + qi*im) for qr in re_axis, qi in im_axis] Δ = Matrix{ComplexF64}(undef, nre, nim) if threaded diff --git a/src/Tearing/Dispersion/ContourSearchAMR.jl b/src/Tearing/Dispersion/ContourSearchAMR.jl index 3533a1773..5cf369eda 100644 --- a/src/Tearing/Dispersion/ContourSearchAMR.jl +++ b/src/Tearing/Dispersion/ContourSearchAMR.jl @@ -243,7 +243,7 @@ function amr_scan(f, Q_re_range::NTuple{2,<:Real}, _bulk_eval_into_cache!(cache, f, corners; parallel=parallel) cells = Vector{AMRCell}(undef, nre0 * nim0) - @inbounds for j in 0:nim0-1, i in 0:nre0-1 + @inbounds for j in 0:(nim0-1), i in 0:(nre0-1) # Read corner Q values from the same `corners` array used to populate # the cache. Recomputing them with `x + re_step` here would differ in # the last floating-point bit from the cache keys, causing spurious @@ -573,7 +573,7 @@ function multi_box_amr_scan(f, # Build pre-screen cells ps_cells = Vector{AMRCell}(undef, prescreen_nre * prescreen_nim) - @inbounds for j in 0:prescreen_nim-1, i in 0:prescreen_nre-1 + @inbounds for j in 0:(prescreen_nim-1), i in 0:(prescreen_nre-1) q_bl = corners[j*ncorners_x+i+1] q_br = corners[j*ncorners_x+(i+1)+1] q_tl = corners[(j+1)*ncorners_x+i+1] diff --git a/src/Tearing/Dispersion/CoupledFullMatch.jl b/src/Tearing/Dispersion/CoupledFullMatch.jl index 9b0f136c9..ed68c4445 100644 --- a/src/Tearing/Dispersion/CoupledFullMatch.jl +++ b/src/Tearing/Dispersion/CoupledFullMatch.jl @@ -155,7 +155,7 @@ function (mc::MultiSurfaceCouplingFull)(Q::Number) # Allocate the matching matrix and fill the lower-left 2m × 2m block # with transpose(dp_raw[1:s2, 1:s2]). mat = zeros(ComplexF64, s4, s4) - @views mat[s2+1:s4, 1:s2] .= transpose(mc.dp_raw[1:s2, 1:s2]) + @views mat[(s2+1):s4, 1:s2] .= transpose(mc.dp_raw[1:s2, 1:s2]) # Per-surface inner-layer assembly @inbounds for k in 1:m diff --git a/src/Tearing/Dispersion/GrowthRateExtraction.jl b/src/Tearing/Dispersion/GrowthRateExtraction.jl index 42c2c9681..796e67633 100644 --- a/src/Tearing/Dispersion/GrowthRateExtraction.jl +++ b/src/Tearing/Dispersion/GrowthRateExtraction.jl @@ -253,10 +253,10 @@ function _all_intersections(re_paths::Vector{Vector{ComplexF64}}, im_paths::Vector{Vector{ComplexF64}}) out = ComplexF64[] for re_path in re_paths - for i in 1:length(re_path)-1 + for i in 1:(length(re_path)-1) a, b = re_path[i], re_path[i+1] for im_path in im_paths - for j in 1:length(im_path)-1 + for j in 1:(length(im_path)-1) c, d = im_path[j], im_path[j+1] pt = _segment_intersection(a, b, c, d) pt !== nothing && push!(out, pt) @@ -468,7 +468,7 @@ function _median_segment_length(re_paths::Vector{Vector{ComplexF64}}, im_paths::Vector{Vector{ComplexF64}}) lens = Float64[] for paths in (re_paths, im_paths), p in paths - @inbounds for i in 1:length(p)-1 + @inbounds for i in 1:(length(p)-1) push!(lens, abs(p[i+1] - p[i])) end end @@ -811,7 +811,7 @@ function _march_triangle(p1::ComplexF64, p2::ComplexF64, p3::ComplexF64, v1::ComplexF64, v2::ComplexF64, v3::ComplexF64, re_target::Float64, im_target::Float64) return (_march_single(p1, p2, p3, real(v1), real(v2), real(v3), - imag(v1), imag(v2), imag(v3), re_target), + imag(v1), imag(v2), imag(v3), re_target), _march_single(p1, p2, p3, imag(v1), imag(v2), imag(v3), real(v1), real(v2), real(v3), im_target)) end diff --git a/src/Tearing/Runner/Control.jl b/src/Tearing/Runner/Control.jl index 1a12ff7e6..88e8fe091 100644 --- a/src/Tearing/Runner/Control.jl +++ b/src/Tearing/Runner/Control.jl @@ -4,6 +4,9 @@ # growth-rate analysis. Populated either directly via the `@kwdef` # constructor or by parsing the `[SLAYER]` (and nested `[SLAYER.*]`) # section(s) of a `gpec.toml`. +# +# `CriticalResonantFieldControl` holds the user-facing knobs that drive the critical resonant field +# analysis. Populated either directly via the `@kwdef` constructor or by parsing the `[CriticalResonantField]` section of a `gpec.toml`. """ SLAYERControl @@ -268,3 +271,41 @@ function slayer_control_from_toml(section::AbstractDict) end return validate(SLAYERControl(; kwargs...)) end + +""" + CriticalResonantFieldControl + +Configuration for the critical resonant field analysis. All fields are +user-facing: read from the `[CriticalResonantField]` TOML section of a `gpec.toml` via +`critical_resonant_field_control_from_toml`, or built directly via the `@kwdef` keyword +constructor. +""" +@kwdef struct CriticalResonantFieldControl + enabled::Bool = false + inner_model::Symbol = :slayer_fitzpatrick + Qmin::Float64 = -10.0 + Qmax::Float64 = 10.0 + n::Int = 200 + profile_file::String = "" + profile_group::String = "/" + store_scan::Bool = false +end + +function critical_resonant_field_control_from_toml(section::AbstractDict) + flat = Dict{String,Any}() + for (k, v) in section + flat[k] = v + end + + kwargs = Dict{Symbol,Any}() + for (k, v) in flat + sym = Symbol(k) + if sym in (:inner_model,) + kwargs[sym] = v isa Symbol ? v : Symbol(String(v)) + else + kwargs[sym] = v + end + end + + return CriticalResonantFieldControl(; kwargs...) +end diff --git a/src/Tearing/Runner/HDF5Output.jl b/src/Tearing/Runner/HDF5Output.jl index ca4287147..02c3f5da9 100644 --- a/src/Tearing/Runner/HDF5Output.jl +++ b/src/Tearing/Runner/HDF5Output.jl @@ -1,6 +1,6 @@ # HDF5Output.jl # -# Write a `SLAYERResult` into an HDF5 group. Designed to be called by the +# Write a `SLAYERResult` or `CriticalResonantFieldResult` into an HDF5 group. Designed to be called by the # existing `PerturbedEquilibrium.write_outputs_to_HDF5` path — the # top-level GPEC runner wires that up; this file only defines the pure # writer. @@ -57,6 +57,38 @@ function write_slayer_hdf5!(parent::Union{HDF5.File,HDF5.Group}, return g end +function write_critical_resonant_field_hdf5!(parent::Union{HDF5.File,HDF5.Group}, + result::CriticalResonantFieldResult) + + if !haskey(parent, "Tearing") + create_group(parent, "Tearing") + end + g = create_group(parent["Tearing"], "CriticalResonantField") + + g["surface_index"] = result.surface_index + g["Qpeak"] = result.Qpeak + g["br_crit"] = result.br_crit + g["Q0"] = result.Q0 + g["P"] = result.P + + if !isempty(result.scan_data) + scan_group = create_group(g, "Scan") + for d in result.scan_data + sg = create_group(scan_group, "surface_$(d.surface)") + sg["Q"] = d.Q + sg["balance"] = d.balance + sg["delta"] = d.delta + sg["Q_positive"] = d.Q_positive + sg["balance_positive"] = d.balance_positive + sg["Qpeak"] = d.Qpeak + sg["br_crit"] = d.br_crit + end + end + + attrs(g)["kind"] = "critical_resonant_field" + return g +end + # Token recorded in the Tearing group's layer_model attribute; keyed by the # per-surface parameter type since the SLAYER and GGJ branches write disjoint fields. _layer_model_token(::Type{SLAYERParameters}) = "slayer" diff --git a/src/Tearing/Runner/Result.jl b/src/Tearing/Runner/Result.jl index 0cffc21c9..9132e8421 100644 --- a/src/Tearing/Runner/Result.jl +++ b/src/Tearing/Runner/Result.jl @@ -3,6 +3,10 @@ # `SLAYERResult` packages the output of a full SLAYER analysis run: # per-surface layer parameters, the extracted tearing eigenvalues, and (if # `control.store_scan`) the full Q-plane scan data for plotting. +# +# `CriticalResonantFieldResult` packages the output of the critical resonant field analysis run: +# per-surface critical resoant field. If `control.store_scan` is true, the full Q scan data, +# viscous torque, and electromagnetic torque are also stored for plotting. """ SLAYERResult @@ -22,9 +26,9 @@ downstream inspection and HDF5 output. the surface list), in which case the HDF5 writer skips them. - `dp_matrix` -- outer-region Δ' matrix used in the analysis - `Q_root` -- tearing eigenvalue(s) in normalized Q - * length `nsurfaces` in `:uncoupled` mode - * length `1` in `:coupled` mode (global eigenvalue normalized by - `params[1].tauk`) + + length `nsurfaces` in `:uncoupled` mode + + length `1` in `:coupled` mode (global eigenvalue normalized by + `params[1].tauk`) - `omega_Hz`, `gamma_Hz` -- physical rotation frequency / growth rate - `per_surface_extraction` -- `Vector{GrowthRateResult}` of length `nsurfaces` in uncoupled mode (each includes polelines, pole list, @@ -64,3 +68,33 @@ function empty_slayer_result(control::SLAYERControl) LayerWidths[], Union{ScanResult,AMRResult}[]) end + +""" + CriticalResonantFieldResult + +Output of `run_critical_resonant_field`. Carries both summary critical resonant field values and if `control.store_scan` is true, the full Q scan data, viscous torque, and electromagnetic torque for plotting. +""" + +struct CriticalResonantFieldResult + enabled::Bool + params::AbstractVector{<:InnerLayerParameters} + surface_index::Vector{Int} + Qpeak::Vector{Float64} + br_crit::Vector{Float64} + Q0::Vector{Float64} + P::Vector{Float64} + scan_data::Vector{NamedTuple} +end + +function empty_critical_resonant_field_result() + return CriticalResonantFieldResult( + false, + InnerLayerParameters[], + Int[], + Float64[], + Float64[], + Float64[], + Float64[], + NamedTuple[] + ) +end diff --git a/src/Tearing/Runner/Runner.jl b/src/Tearing/Runner/Runner.jl index 919088065..df3293b2f 100644 --- a/src/Tearing/Runner/Runner.jl +++ b/src/Tearing/Runner/Runner.jl @@ -32,11 +32,14 @@ using ..Utilities using ..Utilities: KineticProfiles using ...Equilibrium: read_kinetic_file, KineticProfileData using ..InnerLayer -using ..InnerLayer: InnerLayerParameters, InnerLayerResponse, solve_inner, +using ..InnerLayer: + InnerLayerParameters, InnerLayerResponse, solve_inner, SLAYERModel, SLAYERParameters, build_slayer_inputs, GGJModel, GGJParameters, LayerWidths, slayer_layer_thickness import ..build_ggj_inputs # defined at the Tearing level (needs ForceFreeStates) +import ...Equilibrium as Equilibrium +using ...Equilibrium: read_kinetic_file, KineticProfileData, load_kinetic_profiles using ..Dispersion using ..Dispersion: SurfaceCoupling, surface_coupling, MultiSurfaceCoupling, multi_surface_coupling, @@ -54,5 +57,9 @@ export SLAYERControl, slayer_control_from_toml, validate export SLAYERResult, empty_slayer_result export run_slayer, run_slayer_from_inputs, ggj_inner_deltas export write_slayer_hdf5! +export CriticalResonantFieldControl, critical_resonant_field_control_from_toml +export CriticalResonantFieldResult, empty_critical_resonant_field_result +export run_critical_resonant_field +export write_critical_resonant_field_hdf5! end # module Runner diff --git a/src/Tearing/Runner/run_slayer.jl b/src/Tearing/Runner/run_slayer.jl index 2a29c63a8..3dca41bbc 100644 --- a/src/Tearing/Runner/run_slayer.jl +++ b/src/Tearing/Runner/run_slayer.jl @@ -455,3 +455,82 @@ function run_slayer(equil, surfaces::AbstractVector, delta_prime_matrix::Abstrac rational_q = Float64[surfaces[p.ising].q for p in params] return run_slayer_from_inputs(params, dp, control; rational_psi=rational_psi, rational_q=rational_q) end + +# --------------------------------------------------------------------- +# Critical Resonant Field (Torque-Balance) Workflow +# --------------------------------------------------------------------- +""" + Critical Resonant Field (Torque-Balance) Workflow + + The critical resonant field is the minimum resonant magnetic perturbation + amplitude that can drive a tearing mode unstable. + + Returns a `CriticalResonantFieldResult` containing the critical resonant field + and the corresponding critical resoannt field values for each rational surface. +""" + +function run_critical_resonant_field(equil, intr, ctrl; dir_path="./") + ctrl.enabled || return empty_critical_resonant_field_result() + + # Use the same per-surface params already built for SLAYER + profiles = Equilibrium.load_kinetic_profiles(joinpath(dir_path, ctrl.profile_file)) + params = build_slayer_inputs(equil, intr.sing, profiles) + + surface_index = Int[] + Qpeak_vec = Float64[] + br_vec = Float64[] + Q0_vec = Float64[] + P_vec = Float64[] + scan_data = NamedTuple[] + + for (isurf, p) in enumerate(params) + # Fill in the actual per-surface drive from your model + Q0_here = 0.5 + P_here = 1.0 + + tb = TorqueBalance( + SLAYERModel{:fitzpatrick}(), + p, + Q0_here, + P_here, + p.lu, + p.sval_r + ) + + Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs = + torque_balance_scan(tb; Qmin=ctrl.Qmin, Qmax=ctrl.Qmax, n=ctrl.n) + + push!(surface_index, isurf) + push!(Qpeak_vec, Qpeak) + push!(br_vec, br_crit) + push!(Q0_vec, Q0_here) + push!(P_vec, P_here) + + if ctrl.store_scan + push!( + scan_data, + ( + surface=isurf, + Q=collect(Qs), + balance=collect(bal), + delta=collect(Δs), + Q_positive=collect(Qs_positive), + balance_positive=collect(bal_positive), + Qpeak=Qpeak, + br_crit=br_crit + ) + ) + end + end + + return CriticalResonantFieldResult( + true, + params, + surface_index, + Qpeak_vec, + br_vec, + Q0_vec, + P_vec, + scan_data + ) +end diff --git a/src/Tearing/Tearing.jl b/src/Tearing/Tearing.jl index ae3ed8e3c..3ebd35996 100644 --- a/src/Tearing/Tearing.jl +++ b/src/Tearing/Tearing.jl @@ -6,6 +6,8 @@ # InnerLayer -- pure physics: Δ_inner(Q) for GGJ or SLAYER models # Dispersion -- physics-agnostic scan + contour-intersection root # extraction (consumes any InnerLayerModel) +# CriticalResonantField -- physics-agnostic scan + torque-balance root +# extraction (consumes any InnerLayerModel) # Runner -- user-facing orchestration: TOML config, profile # loading, HDF5 output, workflow hooks # diff --git a/src/Utilities/GridUtilities.jl b/src/Utilities/GridUtilities.jl index a02bf0d08..71e255699 100644 --- a/src/Utilities/GridUtilities.jl +++ b/src/Utilities/GridUtilities.jl @@ -11,25 +11,27 @@ Power-law spaced grid with analytic derivative calculation. Creates a grid with more points concentrated near boundaries. # Arguments -- `x_min, x_max`: Grid boundaries -- `npower::Int`: Power law exponent (1=linear, higher=more concentration at edges) -- `nx::Int`: Number of grid points -- `spacing::String`: "lower" (concentrate at x_min), "upper" (at x_max), or "both" + + - `x_min, x_max`: Grid boundaries + - `npower::Int`: Power law exponent (1=linear, higher=more concentration at edges) + - `nx::Int`: Number of grid points + - `spacing::String`: "lower" (concentrate at x_min), "upper" (at x_max), or "both" # Returns -- `Matrix{Float64}`: (2, nx) where row 1 = positions, row 2 = dr/d(norm) derivatives + + - `Matrix{Float64}`: (2, nx) where row 1 = positions, row 2 = dr/d(norm) derivatives """ function powspace(x_min::Float64, x_max::Float64, npower::Int, nx::Int, - spacing::String)::Matrix{Float64} + spacing::String)::Matrix{Float64} result = zeros(Float64, 2, nx) y = if spacing == "lower" - collect(range(-1.0, 0.0, length=nx)) + collect(range(-1.0, 0.0; length=nx)) elseif spacing == "upper" - collect(range(0.0, 1.0, length=nx)) + collect(range(0.0, 1.0; length=nx)) elseif spacing == "both" - collect(range(-1.0, 1.0, length=nx)) + collect(range(-1.0, 1.0; length=nx)) else error("Unknown spacing type: $spacing. Use \"lower\", \"upper\", or \"both\".") end @@ -78,10 +80,10 @@ end function _powspace_numeric_integral(y::Float64, npower::Int)::Float64 y == 0.0 && return 0.0 npts = 100 - y_int = range(0.0, y, length=npts) + y_int = range(0.0, y; length=npts) f_int = abs.((y_int .- 1) .* (y_int .+ 1)) .^ npower integral = (f_int[1] + f_int[npts]) / 2 - for i in 2:(npts - 1) + for i in 2:(npts-1) integral += f_int[i] end return integral * (y / (npts - 1)) diff --git a/src/Utilities/HDF5Annotations.jl b/src/Utilities/HDF5Annotations.jl index 1fff44e62..33e055b4f 100644 --- a/src/Utilities/HDF5Annotations.jl +++ b/src/Utilities/HDF5Annotations.jl @@ -7,8 +7,7 @@ Self-describing metadata for `gpec.h5` (the contract in datasets are marked as HDF5 Dimension Scales (netCDF-4 coordinate variables) attached to the arrays that share their axis, so h5py/xarray/HDFView read the file unaided. -Writers stay table-driven: each writer keeps a table of `path => (; long_name, units, -dims)` entries next to it and calls [`annotate!`](@ref) once after its datasets are +Writers stay table-driven: each writer keeps a table of `path => (; long_name, units, dims)` entries next to it and calls [`annotate!`](@ref) once after its datasets are written. Paths absent from the file are skipped silently (many writes are conditional). """ module HDF5Annotations diff --git a/src/Utilities/PhysicalConstants.jl b/src/Utilities/PhysicalConstants.jl index a9668b611..6511e6df2 100644 --- a/src/Utilities/PhysicalConstants.jl +++ b/src/Utilities/PhysicalConstants.jl @@ -10,11 +10,11 @@ All quantities in SI units. module PhysicalConstants # Match the Fortran GPEC/SLAYER sglobal_mod values exactly so cross-code numerical comparison is meaningful. -const MU_0 = 4.0e-7 * π # vacuum permeability [H/m] -const M_E = 9.1094e-31 # electron mass [kg] -const M_P = 1.6726e-27 # proton mass [kg] +const MU_0 = 4.0e-7 * π # vacuum permeability [H/m] +const M_E = 9.1094e-31 # electron mass [kg] +const M_P = 1.6726e-27 # proton mass [kg] const E_CHG = 1.6021917e-19 # elementary charge [C] -const K_B = 1.3807e-23 # Boltzmann constant [J/K] +const K_B = 1.3807e-23 # Boltzmann constant [J/K] const EPS_0 = 8.8542e-12 # vacuum permittivity [F/m] export MU_0, M_E, M_P, E_CHG, K_B, EPS_0 diff --git a/src/Vacuum/PnQuadCache.jl b/src/Vacuum/PnQuadCache.jl index 6e0b8b719..4d6de9850 100644 --- a/src/Vacuum/PnQuadCache.jl +++ b/src/Vacuum/PnQuadCache.jl @@ -26,7 +26,7 @@ const _PN_BGAUS = 2.5 const (_PN_TG02, _PN_WANUMR) = let x32, w32 = gausslegendre(32) tg0 = [_PN_AGAUS + x32[i] * _PN_BGAUS for i in 1:32] - tg02 = NTuple{32,Float64}(t * t for t in tg0) + tg02 = NTuple{32,Float64}(t * t for t in tg0) wanumr = NTuple{32,Float64}(w32[i] * tg0[i] * exp(-tg0[i]^2) for i in 1:32) (tg02, wanumr) end @@ -94,17 +94,19 @@ end function _make_pn_quad_entry(n::Int) @assert n >= 1 "PnQuadEntry is only defined for n ≥ 1 (Γ(1/2 - n) diverges at n = 0)" - inv_2n = 1.0 / (2.0 * n) + inv_2n = 1.0 / (2.0 * n) inv_2np2 = 1.0 / (2.0 * n + 2.0) - sh = Vector{Float64}(undef, 32) - ch = Vector{Float64}(undef, 32) + sh = Vector{Float64}(undef, 32) + ch = Vector{Float64}(undef, 32) shp = Vector{Float64}(undef, 32) chp = Vector{Float64}(undef, 32) @inbounds for ig in 1:32 - x = _PN_TG02[ig] * inv_2n + x = _PN_TG02[ig] * inv_2n xp = _PN_TG02[ig] * inv_2np2 - sh[ig] = sinh(x); ch[ig] = cosh(x) - shp[ig] = sinh(xp); chp[ig] = cosh(xp) + sh[ig] = sinh(x) + ch[ig] = cosh(x) + shp[ig] = sinh(xp) + chp[ig] = cosh(xp) end # Compute the Gamma function Γ(1/2 - n) via the product formula. @@ -117,7 +119,7 @@ function _make_pn_quad_entry(n::Int) # Combine into scale factors used in the final Legendre function assembly. # Pre-computing these once per n avoids repeating the Gamma product on every s-call. sqtwo = sqrt(2.0) - gauss_norm_n = sqtwo / (n * sqpi * gamn) + gauss_norm_n = sqtwo / (n * sqpi * gamn) gauss_norm_np1 = sqtwo / ((n + 1.0) * sqpi * gamp) return PnQuadEntry(sh, ch, shp, chp, gauss_norm_n, gauss_norm_np1) diff --git a/test/runtests_coordinate_invariant.jl b/test/runtests_coordinate_invariant.jl index 39b20330a..63fe773e3 100644 --- a/test/runtests_coordinate_invariant.jl +++ b/test/runtests_coordinate_invariant.jl @@ -43,31 +43,31 @@ end fm = PE.field_space_response_matrices(Λ, L, P, ϱ, S, jarea) @testset "Flux recovery contract (round-trip via R = S·A)" begin - @test R * fm.permeability / R ≈ P rtol = 1e-10 - @test R * fm.surface_inductance * R' ≈ L rtol = 1e-10 - @test R * fm.plasma_inductance * R' ≈ Λ rtol = 1e-10 - @test (R') \ fm.reluctance / R ≈ ϱ rtol = 1e-10 + @test R * fm.permeability / R ≈ P rtol = 1e-10 + @test R * fm.surface_inductance * R' ≈ L rtol = 1e-10 + @test R * fm.plasma_inductance * R' ≈ Λ rtol = 1e-10 + @test (R') \ fm.reluctance / R ≈ ϱ rtol = 1e-10 end @testset "Area-weighted (b̄) recovery via S (= flux/A²)" begin # b̄-space inductance L_b̄ = S·L̃·S† = L/A² since S·R⁻¹ = A⁻¹·I. - @test S * fm.surface_inductance * S' ≈ L ./ jarea^2 rtol = 1e-10 - @test S * fm.plasma_inductance * S' ≈ Λ ./ jarea^2 rtol = 1e-10 - @test S * fm.permeability / S ≈ P rtol = 1e-10 # similarity: A cancels + @test S * fm.surface_inductance * S' ≈ L ./ jarea^2 rtol = 1e-10 + @test S * fm.plasma_inductance * S' ≈ Λ ./ jarea^2 rtol = 1e-10 + @test S * fm.permeability / S ≈ P rtol = 1e-10 # similarity: A cancels end @testset "Internal consistency of the b̃ transform rules" begin - @test fm.permeability ≈ fm.plasma_inductance / fm.surface_inductance rtol = 1e-10 + @test fm.permeability ≈ fm.plasma_inductance / fm.surface_inductance rtol = 1e-10 L̃inv = inv(fm.surface_inductance) - @test fm.reluctance ≈ L̃inv * (fm.plasma_inductance - fm.surface_inductance) * L̃inv rtol = 1e-10 + @test fm.reluctance ≈ L̃inv * (fm.plasma_inductance - fm.surface_inductance) * L̃inv rtol = 1e-10 end @testset "Energy-scalar invariance (flux ↔ b̃)" begin Φ = ComplexF64[cis(0.3k) / k for k in 1:n] b̃ = R \ Φ # root-area-weighted field - @test dot(Φ, L \ Φ) ≈ dot(b̃, fm.surface_inductance \ b̃) rtol = 1e-10 - @test dot(Φ, Λ \ Φ) ≈ dot(b̃, fm.plasma_inductance \ b̃) rtol = 1e-10 - @test dot(Φ, ϱ * Φ) ≈ dot(b̃, fm.reluctance * b̃) rtol = 1e-10 + @test dot(Φ, L \ Φ) ≈ dot(b̃, fm.surface_inductance \ b̃) rtol = 1e-10 + @test dot(Φ, Λ \ Φ) ≈ dot(b̃, fm.plasma_inductance \ b̃) rtol = 1e-10 + @test dot(Φ, ϱ * Φ) ≈ dot(b̃, fm.reluctance * b̃) rtol = 1e-10 end @testset "Three-field vector relations (b, b̃, b̄; flux = A·b̄)" begin @@ -75,9 +75,9 @@ end b̄ = S * b̃ # area-weighted field b = (S .* sqrt(jarea)) \ b̃ # bare field b = Σ⁻¹·b̃ Φ = R * b̃ # poloidal flux - @test Φ ≈ jarea .* b̄ rtol = 1e-12 # Φ = A·b̄ - @test b̄ ≈ Φ ./ jarea rtol = 1e-12 - @test (S .* sqrt(jarea)) * b ≈ b̃ rtol = 1e-12 # Σ·b = b̃ + @test Φ ≈ jarea .* b̄ rtol = 1e-12 # Φ = A·b̄ + @test b̄ ≈ Φ ./ jarea rtol = 1e-12 + @test (S .* sqrt(jarea)) * b ≈ b̃ rtol = 1e-12 # Σ·b = b̃ end end diff --git a/test/runtests_dispersion_amr.jl b/test/runtests_dispersion_amr.jl index 014f3d019..86ed61653 100644 --- a/test/runtests_dispersion_amr.jl +++ b/test/runtests_dispersion_amr.jl @@ -13,7 +13,7 @@ # Small 2×2 initial grid → 9 unique corners amr = amr_scan(counting_f, (-1.0, 1.0), (-1.0, 1.0); - nre0=2, nim0=2, passes=0) + nre0=2, nim0=2, passes=0) @test amr isa AMRResult @test length(amr.cells) == 4 # 2×2 cells # Dedup: 9 unique corners (3×3) @@ -27,7 +27,7 @@ amr0 = amr_scan(f, (-1.0, 1.0), (-1.0, 1.0); nre0=4, nim0=4, passes=0) amr3 = amr_scan(f, (-1.0, 1.0), (-1.0, 1.0); nre0=4, nim0=4, passes=3) @test length(amr3.cells) > length(amr0.cells) - @test length(amr3.Q) > length(amr0.Q) + @test length(amr3.Q) > length(amr0.Q) # A 4×4 coarse grid is 16 cells; adding 3 refinement passes must # leave the total bounded by exponential growth of only the cells # bracketing the root (roughly linear in the path length). @@ -36,26 +36,26 @@ @testset "amr_scan: argument validation" begin @test_throws ArgumentError amr_scan(identity, (0.0, 1.0), (0.0, 1.0); - nre0=0, nim0=2, passes=1) + nre0=0, nim0=2, passes=1) @test_throws ArgumentError amr_scan(identity, (0.0, 1.0), (0.0, 1.0); - nre0=2, nim0=0, passes=1) + nre0=2, nim0=0, passes=1) @test_throws ArgumentError amr_scan(identity, (0.0, 1.0), (0.0, 1.0); - nre0=2, nim0=2, passes=-1) + nre0=2, nim0=2, passes=-1) end @testset "amr_scan: max_cells safety cap fires" begin # A pathological f that forces every cell to subdivide every pass f(Q) = 0.0 + 0.0im # identically zero → every cell crosses @test_throws ErrorException amr_scan(f, (-1.0, 1.0), (-1.0, 1.0); - nre0=4, nim0=4, passes=10, - max_cells=100) + nre0=4, nim0=4, passes=10, + max_cells=100) end @testset "find_growth_rates(AMR): single isolated root" begin Q_root = 0.42 + 0.27im f(Q) = ComplexF64(Q) - Q_root amr = amr_scan(f, (-1.0, 1.5), (-0.5, 1.0); - nre0=8, nim0=6, passes=4) + nre0=8, nim0=6, passes=4) result = find_growth_rates(amr, 1.0) @test result isa GrowthRateResult @test abs(result.Q_root - Q_root) < 1e-3 # AMR-resolution limited @@ -68,7 +68,7 @@ Q2 = -0.4 + 0.1im f(Q) = (ComplexF64(Q) - Q1) * (ComplexF64(Q) - Q2) amr = amr_scan(f, (-1.0, 1.0), (-0.3, 0.8); - nre0=10, nim0=8, passes=4) + nre0=10, nim0=8, passes=4) result = find_growth_rates(amr, 1.0) @test length(result.valid_roots) == 2 @test abs(result.Q_root - Q1) < 1e-2 @@ -79,7 +79,7 @@ Q_p = -0.5 + 0.6im f(Q) = (ComplexF64(Q) - Q_r) / (ComplexF64(Q) - Q_p) amr = amr_scan(f, (-1.5, 1.5), (-0.5, 1.5); - nre0=10, nim0=8, passes=5) + nre0=10, nim0=8, passes=5) result = find_growth_rates(amr, 1.0; pole_threshold=10.0) @test length(result.poles) >= 1 @test any(p -> abs(p - Q_p) < 0.05, result.poles) @@ -90,7 +90,7 @@ Q_root = 1.0 + 2.0im f(Q) = ComplexF64(Q) - Q_root amr = amr_scan(f, (-2.0, 3.0), (-1.0, 4.0); - nre0=8, nim0=8, passes=4) + nre0=8, nim0=8, passes=4) tauk = 5e-5 result = find_growth_rates(amr, tauk) @test result.omega_Hz ≈ real(result.Q_root) / tauk @@ -119,13 +119,13 @@ Q_root = 0.5 + 0.3im f(Q) = ComplexF64(Q) - Q_root scan = brute_force_scan(f, (-1.0, 1.0), (-0.5, 1.0); - nre=80, nim=60, threaded=false) - amr = amr_scan(f, (-1.0, 1.0), (-0.5, 1.0); - nre0=8, nim0=6, passes=4) + nre=80, nim=60, threaded=false) + amr = amr_scan(f, (-1.0, 1.0), (-0.5, 1.0); + nre0=8, nim0=6, passes=4) r_grid = find_growth_rates(scan, 1.0) - r_amr = find_growth_rates(amr, 1.0) + r_amr = find_growth_rates(amr, 1.0) @test abs(r_grid.Q_root - Q_root) < 1e-3 - @test abs(r_amr.Q_root - Q_root) < 1e-3 + @test abs(r_amr.Q_root - Q_root) < 1e-3 @test abs(r_grid.Q_root - r_amr.Q_root) < 5e-3 end @@ -140,22 +140,22 @@ Q_pin = 0.7 - 0.3im sc = surface_coupling(LinModel(0.0im, 1.0+0im), nothing, - Q_pin; scale=1.0, tauk=1.0) + Q_pin; scale=1.0, tauk=1.0) amr = amr_scan(sc, (-0.5, 1.5), (-1.0, 0.5); - nre0=8, nim0=6, passes=4) + nre0=8, nim0=6, passes=4) r = find_growth_rates(amr, sc.tauk) @test abs(r.Q_root - Q_pin) < 1e-2 # Multi-surface coupled scan through AMR Q_a, Q_b = 0.7 - 0.3im, -0.4 + 0.5im sc1 = surface_coupling(LinModel(0.0im, 1.0+0im), nothing, - ComplexF64(0); scale=1.0, tauk=1.0) + ComplexF64(0); scale=1.0, tauk=1.0) sc2 = surface_coupling(LinModel(0.0im, 1.0+0im), nothing, - ComplexF64(0); scale=1.0, tauk=1.0) + ComplexF64(0); scale=1.0, tauk=1.0) dp = ComplexF64[Q_a 0.0; 0.0 Q_b] mc = multi_surface_coupling([sc1, sc2], dp) amr_c = amr_scan(mc, (-1.0, 1.5), (-1.0, 1.0); - nre0=10, nim0=8, passes=4) + nre0=10, nim0=8, passes=4) r_c = find_growth_rates(amr_c, mc.surfaces[mc.ref_idx].tauk) @test abs(r_c.Q_root - Q_b) < 1e-2 # higher-γ root end @@ -175,15 +175,15 @@ # otherwise crosses the entire real axis). f(Q) = (ComplexF64(Q) - 0.0) / (ComplexF64(Q) - (-50.0)) + (1.0 + 1.0im) boxes = [((-75.0, -25.0), (-25.0, 25.0)), - ((-25.0, 25.0), (-25.0, 25.0)), - (( 25.0, 75.0), (-25.0, 25.0))] + ((-25.0, 25.0), (-25.0, 25.0)), + ((25.0, 75.0), (-25.0, 25.0))] result = multi_box_amr_scan(f, boxes; - pole_magnitude_threshold=10.0, - prescreen_nre=25, prescreen_nim=25, - nre0=25, nim0=25, passes=2, - max_cells=100_000, - max_cells_action=:warn_truncate, - parallel=false) + pole_magnitude_threshold=10.0, + prescreen_nre=25, prescreen_nim=25, + nre0=25, nim0=25, passes=2, + max_cells=100_000, + max_cells_action=:warn_truncate, + parallel=false) @test result isa MultiBoxAMRResult @test length(result.box_results) == 3 @test length(result.box_activity) == 3 @@ -212,15 +212,15 @@ # independent of sign-change tests. g(Q) = 1000.0 / (ComplexF64(Q) - (-50.0))^2 + (5.0 + 5.0im) boxes = [((-75.0, -25.0), (-25.0, 25.0)), - ((-25.0, 25.0), (-25.0, 25.0)), - (( 25.0, 75.0), (-25.0, 25.0))] + ((-25.0, 25.0), (-25.0, 25.0)), + ((25.0, 75.0), (-25.0, 25.0))] result = multi_box_amr_scan(g, boxes; - pole_magnitude_threshold=50.0, - prescreen_nre=25, prescreen_nim=25, - nre0=25, nim0=25, passes=1, - max_cells=100_000, - max_cells_action=:warn_truncate, - parallel=false) + pole_magnitude_threshold=50.0, + prescreen_nre=25, prescreen_nim=25, + nre0=25, nim0=25, passes=1, + max_cells=100_000, + max_cells_action=:warn_truncate, + parallel=false) @test result.box_activity[1] != NoActivity @test result.box_activity[2] == NoActivity @test result.box_activity[3] == NoActivity diff --git a/test/runtests_dispersion_coupled.jl b/test/runtests_dispersion_coupled.jl index 5a65539ff..d29745479 100644 --- a/test/runtests_dispersion_coupled.jl +++ b/test/runtests_dispersion_coupled.jl @@ -29,9 +29,9 @@ @testset "Constructor validation" begin sc1 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 1.0+0im; scale=1.0, tauk=1.0) + 1.0+0im; scale=1.0, tauk=1.0) sc2 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 2.0+0im; scale=1.0, tauk=1.0) + 2.0+0im; scale=1.0, tauk=1.0) good_dp = ComplexF64[1.0 0.1; 0.1 2.0] mc = multi_surface_coupling([sc1, sc2], good_dp) @@ -41,7 +41,7 @@ # 3-surface default also caps at 3 (min(3, 3) = 3) sc3 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 3.0+0im; scale=1.0, tauk=1.0) + 3.0+0im; scale=1.0, tauk=1.0) good_dp3 = ComplexF64[1.0 0.1 0.0; 0.1 2.0 0.0; 0.0 0.0 3.0] mc3 = multi_surface_coupling([sc1, sc2, sc3], good_dp3) @test mc3.msing_max == 3 @@ -49,16 +49,16 @@ # 4-surface case caps at 3 (the design default — Δ' beyond 3 surfaces # tends to be erratic in practice) sc4 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 4.0+0im; scale=1.0, tauk=1.0) + 4.0+0im; scale=1.0, tauk=1.0) good_dp4 = ComplexF64[1.0 0.0 0.0 0.0; - 0.0 2.0 0.0 0.0; - 0.0 0.0 3.0 0.0; - 0.0 0.0 0.0 4.0] + 0.0 2.0 0.0 0.0; + 0.0 0.0 3.0 0.0; + 0.0 0.0 0.0 4.0] mc4 = multi_surface_coupling([sc1, sc2, sc3, sc4], good_dp4) @test mc4.msing_max == 3 # default capped at 3 # Caller can opt in to all 4 mc4_full = multi_surface_coupling([sc1, sc2, sc3, sc4], good_dp4; - msing_max=4) + msing_max=4) @test mc4_full.msing_max == 4 # Mismatched dp size @@ -69,15 +69,15 @@ # Out-of-range ref_idx @test_throws ArgumentError multi_surface_coupling([sc1, sc2], good_dp; - ref_idx=3) + ref_idx=3) @test_throws ArgumentError multi_surface_coupling([sc1, sc2], good_dp; - ref_idx=0) + ref_idx=0) # Out-of-range msing_max @test_throws ArgumentError multi_surface_coupling([sc1, sc2], good_dp; - msing_max=3) + msing_max=3) @test_throws ArgumentError multi_surface_coupling([sc1, sc2], good_dp; - msing_max=0) + msing_max=0) end @testset "Diagonal Δ' factorizes (det = ∏ per-surface residuals)" begin @@ -85,14 +85,14 @@ # the coupled determinant should reduce exactly to the product of # per-surface residuals. sc1 = surface_coupling(LinTestModel(1.0+0im, 1.0+0im), nothing, - 5.0+0im; scale=1.0, tauk=1.0) + 5.0+0im; scale=1.0, tauk=1.0) sc2 = surface_coupling(LinTestModel(2.0+0im, 1.0+0im), nothing, - 7.0+0im; scale=1.0, tauk=1.0) + 7.0+0im; scale=1.0, tauk=1.0) sc3 = surface_coupling(LinTestModel(0.5+0im, 0.5+0im), nothing, - 3.0+0im; scale=1.0, tauk=1.0) + 3.0+0im; scale=1.0, tauk=1.0) dp = ComplexF64[5.0 0.0 0.0; - 0.0 7.0 0.0; - 0.0 0.0 3.0] + 0.0 7.0 0.0; + 0.0 0.0 3.0] mc = multi_surface_coupling([sc1, sc2, sc3], dp) for Q in (0.5+0im, 2.0+0.3im, -1.0-0.5im, 4.5+1.0im) @test mc(Q) ≈ sc1(Q) * sc2(Q) * sc3(Q) rtol = 1e-12 @@ -105,9 +105,9 @@ # single-surface roots. Q1, Q2 = 0.5+0.0im, 2.0+0.0im sc1 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - Q1; scale=1.0, tauk=1.0) + Q1; scale=1.0, tauk=1.0) sc2 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - Q2; scale=1.0, tauk=1.0) + Q2; scale=1.0, tauk=1.0) dp = ComplexF64[real(Q1) 0.0; 0.0 real(Q2)] mc = multi_surface_coupling([sc1, sc2], dp) @test abs(mc(Q1)) < 1e-12 @@ -117,9 +117,9 @@ @testset "Off-diagonal coupling shifts the roots away from the diagonal" begin sc1 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 0.5+0im; scale=1.0, tauk=1.0) + 0.5+0im; scale=1.0, tauk=1.0) sc2 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 2.0+0im; scale=1.0, tauk=1.0) + 2.0+0im; scale=1.0, tauk=1.0) # Coupling-free baseline dp_diag = ComplexF64[0.5 0.0; 0.0 2.0] mc_diag = multi_surface_coupling([sc1, sc2], dp_diag) @@ -138,14 +138,14 @@ @testset "msing_max truncation uses upper-left submatrix" begin sc1 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 1.0+0im; scale=1.0, tauk=1.0) + 1.0+0im; scale=1.0, tauk=1.0) sc2 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 2.0+0im; scale=1.0, tauk=1.0) + 2.0+0im; scale=1.0, tauk=1.0) sc3 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 3.0+0im; scale=1.0, tauk=1.0) + 3.0+0im; scale=1.0, tauk=1.0) dp = ComplexF64[1.0 0.0 0.0; - 0.0 2.0 0.0; - 0.0 0.0 3.0] + 0.0 2.0 0.0; + 0.0 0.0 3.0] # msing_max = 1 reduces to sc1(Q) alone mc1 = multi_surface_coupling([sc1, sc2, sc3], dp; msing_max=1) @@ -173,9 +173,9 @@ # M[k,k] = dp_diag_k - scale·Q·(tauk_ref/tauk_k) # Verify against an explicit closed form with mismatched tauks. sc1 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 0.0+0im; scale=1.0, tauk=2.0) # ref tauk + 0.0+0im; scale=1.0, tauk=2.0) # ref tauk sc2 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 0.0+0im; scale=1.0, tauk=4.0) # half rate + 0.0+0im; scale=1.0, tauk=4.0) # half rate dp = ComplexF64[0.0 0.0; 0.0 0.0] mc = multi_surface_coupling([sc1, sc2], dp; ref_idx=1) for Q in (1.0+0im, 0.5+0.3im) @@ -219,8 +219,8 @@ # Pick M[1,1] arbitrarily, solve for M[2,2]: M11 = 0.7 + 0.0im M22 = (c12 * c21) / M11 - dp = ComplexF64[M11+Δ1 c12; - c21 M22+Δ2] + dp = ComplexF64[M11+Δ1 c12; + c21 M22+Δ2] mc = multi_surface_coupling([sc1, sc2], dp) # The constructed M(Q_pin) is exactly singular by construction @@ -244,9 +244,9 @@ @testset "Broadcast over a 2D Q grid" begin # Coupled residual must be broadcast-compatible for PR 5/6 scans. sc1 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 0.0+0im; scale=1.0, tauk=1.0) + 0.0+0im; scale=1.0, tauk=1.0) sc2 = surface_coupling(LinTestModel(0.0im, 1.0+0im), nothing, - 0.0+0im; scale=1.0, tauk=1.0) + 0.0+0im; scale=1.0, tauk=1.0) dp = ComplexF64[0.0 0.0; 0.0 0.0] mc = multi_surface_coupling([sc1, sc2], dp) diff --git a/test/runtests_dispersion_coupled_full.jl b/test/runtests_dispersion_coupled_full.jl index d471650f8..65eec71c8 100644 --- a/test/runtests_dispersion_coupled_full.jl +++ b/test/runtests_dispersion_coupled_full.jl @@ -255,7 +255,7 @@ 0.2 0.1 0.05 0.1 0.3 -6.5] # Non-trivial Q dependence: Δ_t(Q) = a + 0.5·Q, Δ_i(Q) = b + 0.2·Q scs = [surface_coupling(_LinearInnerF(0.3 + 0.01k * im, 0.5 + 0im, - 0.7 + 0.02k * im, 0.2 + 0im), + 0.7 + 0.02k * im, 0.2 + 0im), nothing, 0 + 0im; scale=1.0, tauk=1.0) for k in 1:m] mc = multi_surface_coupling_full(scs, Random_dp) diff --git a/test/runtests_dispersion_polish.jl b/test/runtests_dispersion_polish.jl index 8bc4c9702..8e7ae2e7b 100644 --- a/test/runtests_dispersion_polish.jl +++ b/test/runtests_dispersion_polish.jl @@ -106,7 +106,7 @@ r1 = 0.30 + 0.20im r2 = r1 + 0.002 # second root 0.002 away f(Q) = (ComplexF64(Q) - r1) * (ComplexF64(Q) - r2) - pts = ComplexF64[r1 + 0.0003, r2 - 0.0003] # coarse contour estimates + pts = ComplexF64[r1+0.0003, r2-0.0003] # coarse contour estimates R1 = D._polish_trust_radius(pts, 1, 0.001) R2 = D._polish_trust_radius(pts, 2, 0.001) p1 = D._polish_root(f, pts[1], R1)[1] @@ -124,7 +124,7 @@ im_paths = [ComplexF64[0+0im, 0+0.1im]] # segment length 0.1 @test D._median_segment_length(re_paths, im_paths) ≈ 0.1 # median of [0.1,0.2,0.1] @test D._median_segment_length(Vector{Vector{ComplexF64}}(), - Vector{Vector{ComplexF64}}()) == 0.0 + Vector{Vector{ComplexF64}}()) == 0.0 end # ---------------------------------------------------------------- diff --git a/test/runtests_dispersion_residual.jl b/test/runtests_dispersion_residual.jl index d0235a0da..40cdbfd5d 100644 --- a/test/runtests_dispersion_residual.jl +++ b/test/runtests_dispersion_residual.jl @@ -30,35 +30,35 @@ @testset "Constructor scale defaults" begin # SLAYER: scale = lu^(1/3) so the dimensionless Δ from riccati_f # is mapped to outer ψ-units (Fortran SLAYER growthrates routine) - p_sl = _slayer_ref() + p_sl = _slayer_ref() sc_sl = surface_coupling(SLAYERModel(), p_sl, -1.0 + 0.0im) @test sc_sl.scale ≈ p_sl.lu^(1/3) @test sc_sl.dc == 0.0 @test sc_sl.dp_diag == ComplexF64(-1.0) # GGJ: scale = 1 because rescale_delta is applied inside solve_inner - p_ggj = glasser_wang_2020_eq55() + p_ggj = glasser_wang_2020_eq55() sc_ggj = surface_coupling(GGJModel(solver=:shooting), p_ggj, - -1.0 + 0.0im) + -1.0 + 0.0im) @test sc_ggj.scale == 1.0 # Generic fallback honors explicit scale + dc kwargs sc_lin = surface_coupling(LinearTestModel(0.0im, 1.0+0im), nothing, - 3.0 + 0.0im; dc=0.5, scale=2.0) + 3.0 + 0.0im; dc=0.5, scale=2.0) @test sc_lin.scale == 2.0 @test sc_lin.dc == 0.5 end @testset "Residual arithmetic on synthetic linear model" begin # r(Q) = dp_diag - scale·(a + b·Q) - dc - a, b = 1.0 + 2.0im, -0.5 + 1.0im - scale = 3.0 - dc = 0.25 + a, b = 1.0 + 2.0im, -0.5 + 1.0im + scale = 3.0 + dc = 0.25 Q_root = -0.7 + 0.3im dp_diag = (a + b * Q_root) * scale + dc # construct a known root sc = surface_coupling(LinearTestModel(a, b), nothing, dp_diag; - dc=dc, scale=scale) + dc=dc, scale=scale) @test sc(Q_root) ≈ 0 atol = 1e-12 # Off-root residual matches the closed form @@ -89,14 +89,14 @@ # Both inner-layer models flow through the same SurfaceCoupling # API. Numerical agreement is *not* asserted (different physics) — # only that both pipelines construct and evaluate. - p_sl = _slayer_ref() + p_sl = _slayer_ref() sc_sl = surface_coupling(SLAYERModel(), p_sl, -100.0 + 0.0im) @test sc_sl isa SurfaceCoupling{SLAYERModel{:fitzpatrick},SLAYERParameters} @test sc_sl(0.0 + 0.5im) isa ComplexF64 - p_ggj = glasser_wang_2020_eq55() + p_ggj = glasser_wang_2020_eq55() sc_ggj = surface_coupling(GGJModel(solver=:shooting), p_ggj, - -1.0 + 0.0im) + -1.0 + 0.0im) @test sc_ggj isa SurfaceCoupling{GGJModel{:shooting},GGJParameters} @test sc_ggj(1e-3 + 0.0im) isa ComplexF64 end @@ -106,7 +106,7 @@ # complex-Q grid; verify that broadcasting works element-wise. a, b = 0.0+0im, 1.0+0im sc = surface_coupling(LinearTestModel(a, b), nothing, 2.0+0im; - dc=0.0, scale=1.0) + dc=0.0, scale=1.0) Q_grid = [(qr + qi*im) for qr in -1.0:0.5:1.0, qi in -1.0:0.5:1.0] Δ_grid = sc.(Q_grid) @test size(Δ_grid) == size(Q_grid) diff --git a/test/runtests_dispersion_scan.jl b/test/runtests_dispersion_scan.jl index f50b449fc..00145ad63 100644 --- a/test/runtests_dispersion_scan.jl +++ b/test/runtests_dispersion_scan.jl @@ -7,16 +7,16 @@ @testset "brute_force_scan: regular grid evaluation" begin f(Q) = ComplexF64(Q)^2 - 1 scan = brute_force_scan(f, (-2.0, 2.0), (-1.0, 1.0); - nre=21, nim=11, threaded=false) + nre=21, nim=11, threaded=false) @test scan isa ScanResult @test size(scan.Q) == (21, 11) @test size(scan.Δ) == (21, 11) @test length(scan.re_axis) == 21 @test length(scan.im_axis) == 11 - @test scan.re_axis[1] == -2.0 - @test scan.re_axis[end] == 2.0 - @test scan.im_axis[1] == -1.0 - @test scan.im_axis[end] == 1.0 + @test scan.re_axis[1] == -2.0 + @test scan.re_axis[end] == 2.0 + @test scan.im_axis[1] == -1.0 + @test scan.im_axis[end] == 1.0 # Spot-check a grid value i, j = 11, 6 @test scan.Q[i, j] ≈ scan.re_axis[i] + scan.im_axis[j]*im @@ -26,17 +26,17 @@ @testset "brute_force_scan: threaded vs non-threaded agree" begin f(Q) = sin(ComplexF64(Q)) s_t = brute_force_scan(f, (-1.0, 1.0), (-0.5, 0.5); - nre=15, nim=10, threaded=true) + nre=15, nim=10, threaded=true) s_n = brute_force_scan(f, (-1.0, 1.0), (-0.5, 0.5); - nre=15, nim=10, threaded=false) + nre=15, nim=10, threaded=false) @test s_t.Δ == s_n.Δ end @testset "brute_force_scan: argument validation" begin @test_throws ArgumentError brute_force_scan(identity, (0.0, 1.0), - (0.0, 1.0); nre=1, nim=10) + (0.0, 1.0); nre=1, nim=10) @test_throws ArgumentError brute_force_scan(identity, (0.0, 1.0), - (0.0, 1.0); nre=10, nim=1) + (0.0, 1.0); nre=10, nim=1) end @testset "find_growth_rates: single isolated root" begin @@ -44,7 +44,7 @@ Q_root = 0.42 + 0.27im f(Q) = ComplexF64(Q) - Q_root scan = brute_force_scan(f, (-1.0, 1.5), (-0.5, 1.0); - nre=80, nim=60, threaded=false) + nre=80, nim=60, threaded=false) result = find_growth_rates(scan, 1.0) @test result isa GrowthRateResult @test isempty(result.poles) @@ -60,7 +60,7 @@ Q2 = -0.4 + 0.1im # lower γ f(Q) = (ComplexF64(Q) - Q1) * (ComplexF64(Q) - Q2) scan = brute_force_scan(f, (-1.0, 1.0), (-0.3, 0.8); - nre=100, nim=80, threaded=false) + nre=100, nim=80, threaded=false) result = find_growth_rates(scan, 1.0) @test length(result.valid_roots) == 2 @test abs(result.Q_root - Q1) < 1e-3 # higher-γ root chosen @@ -73,7 +73,7 @@ Q_p = -0.5 + 0.6im # pole at higher γ f(Q) = (ComplexF64(Q) - Q_r) / (ComplexF64(Q) - Q_p) scan = brute_force_scan(f, (-1.5, 1.5), (-0.5, 1.5); - nre=120, nim=100, threaded=false) + nre=120, nim=100, threaded=false) result = find_growth_rates(scan, 1.0; pole_threshold=10.0) # Pole correctly classified — but the root is at lower γ than the # pole, so even with filter_above_poles=true the root must survive. @@ -86,14 +86,14 @@ Q_root = 1.0 + 2.0im f(Q) = ComplexF64(Q) - Q_root scan = brute_force_scan(f, (-2.0, 3.0), (-1.0, 4.0); - nre=80, nim=80, threaded=false) + nre=80, nim=80, threaded=false) tauk = 5.0e-5 result = find_growth_rates(scan, tauk) @test result.omega_Hz ≈ real(result.Q_root) / tauk @test result.gamma_Hz ≈ imag(result.Q_root) / tauk # Check sensible orders of magnitude (Q_root ≈ 1+2im, tauk ≈ 5e-5) - @test result.omega_Hz ≈ 1 / tauk atol = 1 / tauk * 5e-3 - @test result.gamma_Hz ≈ 2 / tauk atol = 2 / tauk * 5e-3 + @test result.omega_Hz ≈ 1 / tauk atol = 1 / tauk * 5e-3 + @test result.gamma_Hz ≈ 2 / tauk atol = 2 / tauk * 5e-3 end @testset "find_growth_rates: empty result when no contour intersections" begin @@ -102,7 +102,7 @@ f(Q) = 1.0 + ComplexF64(Q) # Choose a box where Δ has no zeros — far above the real axis scan = brute_force_scan(f, (1.0, 2.0), (1.0, 2.0); - nre=30, nim=30, threaded=false) + nre=30, nim=30, threaded=false) result = find_growth_rates(scan, 1.0) # Either no valid roots, or a NaN Q_root @test isempty(result.valid_roots) || isnan(real(result.Q_root)) @@ -122,9 +122,9 @@ # Single-surface scan via SurfaceCoupling (Q_root by construction = 0.7-0.3im) Q_pin = 0.7 - 0.3im sc = surface_coupling(LinModel(0.0im, 1.0+0im), nothing, - Q_pin; scale=1.0, tauk=1.0) + Q_pin; scale=1.0, tauk=1.0) scan = brute_force_scan(sc, (-0.5, 1.5), (-1.0, 0.5); - nre=80, nim=80, threaded=false) + nre=80, nim=80, threaded=false) res = find_growth_rates(scan, sc.tauk) @test abs(res.Q_root - Q_pin) < 1e-3 @@ -136,13 +136,13 @@ # full complex value, not just its real part). Q_a, Q_b = 0.7 - 0.3im, -0.4 + 0.5im sc1 = surface_coupling(LinModel(0.0im, 1.0+0im), nothing, - ComplexF64(0); scale=1.0, tauk=1.0) + ComplexF64(0); scale=1.0, tauk=1.0) sc2 = surface_coupling(LinModel(0.0im, 1.0+0im), nothing, - ComplexF64(0); scale=1.0, tauk=1.0) + ComplexF64(0); scale=1.0, tauk=1.0) dp = ComplexF64[Q_a 0.0; 0.0 Q_b] # diagonal Δ' mc = multi_surface_coupling([sc1, sc2], dp) scan_c = brute_force_scan(mc, (-1.0, 1.5), (-1.0, 1.0); - nre=120, nim=100, threaded=false) + nre=120, nim=100, threaded=false) res_c = find_growth_rates(scan_c, mc.surfaces[mc.ref_idx].tauk) # With diagonal Δ', det = (Q_a - Q)·(Q_b - Q) → roots at Q_a, Q_b. # The higher-γ root is Q_b (γ = 0.5). diff --git a/test/runtests_equil.jl b/test/runtests_equil.jl index af3cd5743..782ae6120 100644 --- a/test/runtests_equil.jl +++ b/test/runtests_equil.jl @@ -143,7 +143,7 @@ @testset "EFIT Method Consistency" begin # All three methods solve the same equilibrium — q-profiles should broadly agree. # Tolerance is 10% to allow for method-specific discretisation differences. - q_efit = plasma_eq_efit.profiles.q_spline.y + q_efit = plasma_eq_efit.profiles.q_spline.y q_arclength = plasma_eq_arclength.profiles.q_spline.y q_inversion = plasma_eq_inversion.profiles.q_spline.y @@ -242,7 +242,7 @@ b0exp = 7.4 # CHEASE normalization field [T] B_nodes_binary = plasma_eq_binary.eqfun_B.nodal_derivs.partials[1, :, :] - B_nodes_ascii = plasma_eq_ascii.eqfun_B.nodal_derivs.partials[1, :, :] + B_nodes_ascii = plasma_eq_ascii.eqfun_B.nodal_derivs.partials[1, :, :] # B field must be finite and positive everywhere @test all(isfinite, B_nodes_binary) @@ -258,7 +258,7 @@ # q must be finite, positive, and in a physically reasonable range q_binary = plasma_eq_binary.profiles.q_spline.y - q_ascii = plasma_eq_ascii.profiles.q_spline.y + q_ascii = plasma_eq_ascii.profiles.q_spline.y @test all(isfinite, q_binary) @test all(isfinite, q_ascii) @test all(>(0), q_binary) @@ -436,7 +436,7 @@ Eq = GeneralizedPerturbedEquilibrium.Equilibrium function build_solovev_equilibrium(; e=1.6, a=0.33, r0=1.0, q0=1.9, - mpsi=64, mtheta=128) + mpsi=64, mtheta=128) eq_config = Eq.EquilibriumConfig(; eq_type="sol", eq_filename="unused", jac_type="pest", grid_type="ldp", @@ -515,24 +515,24 @@ @test pe.params.zsep[1] > pe.params.zsep[2] # Shape parameters — all physically positive quantities. - @test pe.params.amean > 0 - @test pe.params.rmean > 0 + @test pe.params.amean > 0 + @test pe.params.rmean > 0 @test pe.params.aratio > 0 - @test pe.params.kappa > 0 - @test pe.params.kappa ≈ 1.6 rtol=0.02 + @test pe.params.kappa > 0 + @test pe.params.kappa ≈ 1.6 rtol=0.02 # For Solovev (e=1.6, a=0.33, r0=1.0) the shape is approximately # recovered (Shafranov shift loosens the match). @test pe.params.amean ≈ 0.33 rtol=0.15 - @test pe.params.rmean ≈ 1.0 rtol=0.15 + @test pe.params.rmean ≈ 1.0 rtol=0.15 # Consistency with separatrix formulae. @test pe.params.rmean ≈ (pe.params.rsep[1] + pe.params.rsep[2]) / 2 @test pe.params.amean ≈ (pe.params.rsep[1] - pe.params.rsep[2]) / 2 # Beta and field quantities — all physically positive. - @test pe.params.bt0 > 0 - @test pe.params.crnt > 0 + @test pe.params.bt0 > 0 + @test pe.params.crnt > 0 @test pe.params.bwall > 0 @test pe.params.betat > 0 @test pe.params.betan > 0 diff --git a/test/runtests_eulerlagrange.jl b/test/runtests_eulerlagrange.jl index 6547352e6..6794ec296 100644 --- a/test/runtests_eulerlagrange.jl +++ b/test/runtests_eulerlagrange.jl @@ -494,7 +494,7 @@ end # materialize after the Gaussian fixups and free-boundary normalization rather than # transforming stored derivatives alongside u_store. npert = intr.numpert_total - T = Matrix{ComplexF64}(I, npert, npert) .+ 0.25 .* ComplexF64.(reshape(sin.(1:npert^2), npert, npert)) + T = Matrix{ComplexF64}(I, npert, npert) .+ 0.25 .* ComplexF64.(reshape(sin.(1:(npert^2)), npert, npert)) odet_t = deepcopy(odet_pristine) for istep in 1:odet_t.step odet_t.u_store[:, :, 1, istep] = odet_t.u_store[:, :, 1, istep] * T diff --git a/test/runtests_imas.jl b/test/runtests_imas.jl index 2d82d5b0e..f261cc45a 100644 --- a/test/runtests_imas.jl +++ b/test/runtests_imas.jl @@ -20,31 +20,31 @@ using GeneralizedPerturbedEquilibrium.Equilibrium # COCOS 11: ψ_IMAS = 2π × ψ_internal psi_axis_int = 0.0 - psi_bnd_int = 1.5 # Wb/rad + psi_bnd_int = 1.5 # Wb/rad cf = cocos == 11 ? 2π : 1.0 - eqt.global_quantities.psi_axis = psi_axis_int * cf - eqt.global_quantities.psi_boundary = psi_bnd_int * cf + eqt.global_quantities.psi_axis = psi_axis_int * cf + eqt.global_quantities.psi_boundary = psi_bnd_int * cf nw = 64 psi_1d = collect(LinRange(psi_axis_int, psi_bnd_int, nw)) - eqt.profiles_1d.psi = psi_1d .* cf - eqt.profiles_1d.f = fill(5.0, nw) + eqt.profiles_1d.psi = psi_1d .* cf + eqt.profiles_1d.f = fill(5.0, nw) eqt.profiles_1d.pressure = collect(LinRange(1e4, 0.0, nw)) - eqt.profiles_1d.q = collect(LinRange(1.0, 3.0, nw)) + eqt.profiles_1d.q = collect(LinRange(1.0, 3.0, nw)) # Minimal 2D ψ(R,Z) — rough circular flux surfaces nR, nZ = 32, 40 R_grid = collect(LinRange(1.0, 2.5, nR)) Z_grid = collect(LinRange(-0.8, 0.8, nZ)) - Rmag = 1.75 + Rmag = 1.75 psi_rz = [min((R - Rmag)^2 / 0.6 + Z^2 / 0.7, psi_bnd_int * 1.4) for R in R_grid, Z in Z_grid] resize!(eqt.profiles_2d, 1; wipe=true) - prof2d = eqt.profiles_2d[1] - prof2d.grid.dim1 = R_grid - prof2d.grid.dim2 = Z_grid - prof2d.psi = psi_rz .* cf + prof2d = eqt.profiles_2d[1] + prof2d.grid.dim1 = R_grid + prof2d.grid.dim2 = Z_grid + prof2d.psi = psi_rz .* cf return dd, psi_bnd_int end @@ -58,8 +58,8 @@ using GeneralizedPerturbedEquilibrium.Equilibrium # psio should equal |psi_boundary - psi_axis| in internal (COCOS 2) units @test isapprox(result.psio, psi_bnd_int; rtol=1e-6) - @test result.rmin ≈ 1.0 atol=1e-9 - @test result.rmax ≈ 2.5 atol=1e-9 + @test result.rmin ≈ 1.0 atol=1e-9 + @test result.rmax ≈ 2.5 atol=1e-9 end # Test 2: read_imas — COCOS 2 input requires no conversion @@ -121,7 +121,7 @@ using GeneralizedPerturbedEquilibrium.Equilibrium GeneralizedPerturbedEquilibrium.write_imas(dd, mock_result) - @test dd.mhd_linear.code.name == "GPEC" + @test dd.mhd_linear.code.name == "GPEC" @test dd.mhd_linear.ideal_flag == 1 @test length(dd.mhd_linear.time_slice) == 1 @@ -142,7 +142,7 @@ using GeneralizedPerturbedEquilibrium.Equilibrium # et sorted ascending (least stable globally first). # n=1 (j=0) has eigenvalues: real=0.3 (idx 1) and real=0.6 (idx 3) # n=2 (j=1) has eigenvalues: real=0.5 (idx 2) and real=0.7 (idx 4) - mock_et = [0.3+0im, 0.5+0im, 0.6+0im, 0.7+0im] + mock_et = [0.3+0im, 0.5+0im, 0.6+0im, 0.7+0im] mock_n_idx = [0, 1, 0, 1] mock_result = ( ffs = (integrator=:forward, free_boundary=(et=mock_et, n_tor_idx=mock_n_idx), @@ -190,9 +190,9 @@ using GeneralizedPerturbedEquilibrium.Equilibrium ) GeneralizedPerturbedEquilibrium.write_imas(dd_multi, result_multi) - ts_single = dd_single.mhd_linear.time_slice[1] + ts_single = dd_single.mhd_linear.time_slice[1] ts_single2 = dd_single2.mhd_linear.time_slice[1] - ts_multi = dd_multi.mhd_linear.time_slice[1] + ts_multi = dd_multi.mhd_linear.time_slice[1] # n=1 energy from combined run must match the standalone n=1 run @test ts_multi.toroidal_mode[1].energy_perturbed == ts_single.toroidal_mode[1].energy_perturbed diff --git a/test/runtests_kinetic.jl b/test/runtests_kinetic.jl index 29955c2c7..7f1ac8fcf 100644 --- a/test/runtests_kinetic.jl +++ b/test/runtests_kinetic.jl @@ -26,7 +26,7 @@ @testset "endpoint modes" begin pts_lower, _ = KF.powspace(0.0, 1.0, 2, 50, "lower") pts_upper, _ = KF.powspace(0.0, 1.0, 2, 50, "upper") - pts_both, _ = KF.powspace(0.0, 1.0, 2, 50, "both") + pts_both, _ = KF.powspace(0.0, 1.0, 2, 50, "both") # All modes should span the full range for pts in [pts_lower, pts_upper, pts_both] @@ -194,11 +194,11 @@ # independent reference for the u-substitution + pole-extraction result. wn, wt, we, wd, wb, nuk, leff, n = 0.5, 0.8, -2.0, 0.5, 1.0, 0.3, 1.0, 1 p = KF.EnergyParams(wn, wt, we, wd, wb, nuk, leff, n, - "harmonic", "maxwellian", 1.0, 0.0, false) + "harmonic", "maxwellian", 1.0, 0.0, false) x_res = KF.find_resonance_energies(leff, wb, n, we, wd) @test length(x_res) == 1 # this case has exactly one resonance reference, _ = KF.quadgk(x -> KF.energy_integrand_scalar(x, p), - 0.0, x_res[1], Inf; rtol=1e-12, atol=1e-14) + 0.0, x_res[1], Inf; rtol=1e-12, atol=1e-14) result = KF.integrate_energy( wn, wt, we, wd, wb, nuk, 0, leff, n, 0.5, 0.5, "fgar"; nutype="harmonic", f0type="maxwellian", atol=1e-12, rtol=1e-10 @@ -317,7 +317,7 @@ @test all(isfinite, vals) # Element-wise match against the scalar form documented in the docstring. p = KF.EnergyParams(0.5, 0.8, -2.0, 0.5, 1.0, 0.3, 1.0, 1, - "harmonic", "maxwellian", 1.0, 0.0, false) + "harmonic", "maxwellian", 1.0, 0.0, false) @test vals ≈ [KF.energy_integrand_scalar(x, p) for x in x_grid] end diff --git a/test/runtests_parallel_integration.jl b/test/runtests_parallel_integration.jl index 7e7737e06..616cc28d6 100644 --- a/test/runtests_parallel_integration.jl +++ b/test/runtests_parallel_integration.jl @@ -114,9 +114,12 @@ using TOML ctrl = GeneralizedPerturbedEquilibrium.ForceFreeStates.ForceFreeStatesControl(; (Symbol(k) => v for (k, v) in inputs["ForceFreeStates"])...) eq_config = GeneralizedPerturbedEquilibrium.Equilibrium.EquilibriumConfig(inputs["Equilibrium"], ex) - equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium(eq_config, haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium( + eq_config, + haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing + ) + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_lim!(intr, ctrl, equil) GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_find!(intr, equil) @@ -201,9 +204,12 @@ using TOML ctrl = GeneralizedPerturbedEquilibrium.ForceFreeStates.ForceFreeStatesControl(; (Symbol(k) => v for (k, v) in inputs["ForceFreeStates"])...) eq_config = GeneralizedPerturbedEquilibrium.Equilibrium.EquilibriumConfig(inputs["Equilibrium"], ex) - equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium(eq_config, haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium( + eq_config, + haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing + ) + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_lim!(intr, ctrl, equil) GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_find!(intr, equil) @@ -262,11 +268,14 @@ using TOML ctrl = GeneralizedPerturbedEquilibrium.ForceFreeStates.ForceFreeStatesControl(; (Symbol(k) => v for (k, v) in inputs["ForceFreeStates"])...) eq_config = GeneralizedPerturbedEquilibrium.Equilibrium.EquilibriumConfig(inputs["Equilibrium"], ex) - equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium(eq_config, haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing) + equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium( + eq_config, + haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing + ) intr.wall_settings = GeneralizedPerturbedEquilibrium.Vacuum.WallShapeSettings(; (Symbol(k) => v for (k, v) in inputs["Wall"])...) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_lim!(intr, ctrl, equil) GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_find!(intr, equil) @@ -311,7 +320,10 @@ using TOML ctrl = GeneralizedPerturbedEquilibrium.ForceFreeStates.ForceFreeStatesControl(; (Symbol(k) => v for (k, v) in inputs["ForceFreeStates"])...) eq_config = GeneralizedPerturbedEquilibrium.Equilibrium.EquilibriumConfig(inputs["Equilibrium"], ex) - equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium(eq_config, haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing) + equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium( + eq_config, + haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing + ) # Apply the two-pass auto grid exactly as the main driver does (the example ships # grid_type="auto", mpsi=0): measured-curvature refinement with rational surfaces # pinned as mandatory knots, re-formed from the captured ingest. The pinned values @@ -324,8 +336,8 @@ using TOML end intr.wall_settings = GeneralizedPerturbedEquilibrium.Vacuum.WallShapeSettings(; (Symbol(k) => v for (k, v) in inputs["Wall"])...) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_lim!(intr, ctrl, equil) GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_find!(intr, equil) @@ -372,9 +384,12 @@ using TOML ctrl = GeneralizedPerturbedEquilibrium.ForceFreeStates.ForceFreeStatesControl(; (Symbol(k) => v for (k, v) in inputs["ForceFreeStates"])...) eq_config = GeneralizedPerturbedEquilibrium.Equilibrium.EquilibriumConfig(inputs["Equilibrium"], ex) - equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium(eq_config, haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium( + eq_config, + haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing + ) + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_lim!(intr, ctrl, equil) GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_find!(intr, equil) @@ -423,11 +438,14 @@ using TOML ctrl = GeneralizedPerturbedEquilibrium.ForceFreeStates.ForceFreeStatesControl(; (Symbol(k) => v for (k, v) in inputs["ForceFreeStates"])...) eq_config = GeneralizedPerturbedEquilibrium.Equilibrium.EquilibriumConfig(inputs["Equilibrium"], example_dir) - equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium(eq_config, haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing) + equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium( + eq_config, + haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing + ) intr.wall_settings = GeneralizedPerturbedEquilibrium.Vacuum.WallShapeSettings(; (Symbol(k) => v for (k, v) in inputs["Wall"])...) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_lim!(intr, ctrl, equil) GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_find!(intr, equil) @@ -476,7 +494,10 @@ using TOML ctrl = GeneralizedPerturbedEquilibrium.ForceFreeStates.ForceFreeStatesControl(; (Symbol(k) => v for (k, v) in inputs["ForceFreeStates"])...) eq_config = GeneralizedPerturbedEquilibrium.Equilibrium.EquilibriumConfig(inputs["Equilibrium"], ex) - equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium(eq_config, haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing) + equil = GeneralizedPerturbedEquilibrium.Equilibrium.setup_equilibrium( + eq_config, + haskey(inputs, "SOL_INPUT") ? GeneralizedPerturbedEquilibrium.Equilibrium.SolovevConfig(inputs["SOL_INPUT"]) : nothing + ) # Apply the two-pass auto grid (measured-curvature refinement, rational surfaces pinned # as mandatory knots) exactly as the main driver does (see the FM testset above); the # pinned values below are for this grid, the production default. @@ -488,8 +509,8 @@ using TOML end intr.wall_settings = GeneralizedPerturbedEquilibrium.Vacuum.WallShapeSettings(; (Symbol(k) => v for (k, v) in inputs["Wall"])...) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_lim!(intr, ctrl, equil) GeneralizedPerturbedEquilibrium.ForceFreeStates.sing_find!(intr, equil) diff --git a/test/runtests_rerun_from_h5.jl b/test/runtests_rerun_from_h5.jl index dc242426f..db10e3c9d 100644 --- a/test/runtests_rerun_from_h5.jl +++ b/test/runtests_rerun_from_h5.jl @@ -102,7 +102,11 @@ end inputs, = GeneralizedPerturbedEquilibrium.build_inputs_from_h5([source_h5, "--output-dir", out_dir, "--override", "ForceFreeStates.use_parallel=true"]) @test inputs["ForceFreeStates"]["use_parallel"] == true - @test_logs (:warn,) GeneralizedPerturbedEquilibrium._drop_deprecated_keys!(inputs["ForceFreeStates"], GeneralizedPerturbedEquilibrium._DEPRECATED_FFS_KEYS, "ForceFreeStates") + @test_logs (:warn,) GeneralizedPerturbedEquilibrium._drop_deprecated_keys!( + inputs["ForceFreeStates"], + GeneralizedPerturbedEquilibrium._DEPRECATED_FFS_KEYS, + "ForceFreeStates" + ) @test !haskey(inputs["ForceFreeStates"], "use_parallel") # With the key gone the control struct builds again, on the default integrator. diff --git a/test/runtests_riccati.jl b/test/runtests_riccati.jl index afd084056..69edfb972 100644 --- a/test/runtests_riccati.jl +++ b/test/runtests_riccati.jl @@ -9,8 +9,8 @@ function make_solovev_intr(inputs, ctrl, equil, ex) intr = FFS.ForceFreeStatesInternal(; dir_path=ex) intr.wall_settings = GeneralizedPerturbedEquilibrium.Vacuum.WallShapeSettings(; (Symbol(k) => v for (k, v) in inputs["Wall"])...) - intr.nlow = ctrl.nn_low; - intr.nhigh = ctrl.nn_high; + intr.nlow = ctrl.nn_low + intr.nhigh = ctrl.nn_high intr.npert = 1 FFS.sing_lim!(intr, ctrl, equil) FFS.sing_find!(intr, equil) diff --git a/test/runtests_sing.jl b/test/runtests_sing.jl index 83b85a765..18ce06c59 100644 --- a/test/runtests_sing.jl +++ b/test/runtests_sing.jl @@ -41,14 +41,14 @@ using FastInterpolations: cubic_interp, CubicFit, LinearBinarySearch, Series, Ex function read_solutions_3d(fname::String) lines = readlines(fname) - blocks = Vector{Vector{Vector{Float64}}}(); + blocks = Vector{Vector{Vector{Float64}}}() current = Vector{Vector{Float64}}() for s in lines - t = strip(s); + t = strip(s) isempty(t) && continue if occursin("Solution index", t) if !isempty(current) - push!(blocks, current); + push!(blocks, current) current = Vector{Vector{Float64}}() end continue @@ -62,11 +62,11 @@ using FastInterpolations: cubic_interp, CubicFit, LinearBinarySearch, Series, Ex if !isempty(current) push!(blocks, current) end - mpert = length(blocks[1]); + mpert = length(blocks[1]) nsol = length(blocks) result = Array{ComplexF64}(undef, mpert, nsol, 2) for (j, block) in enumerate(blocks), (i, row) in enumerate(block) - result[i, j, 1] = complex(row[2], row[3]); + result[i, j, 1] = complex(row[2], row[3]) result[i, j, 2] = complex(row[4], row[5]) end return result @@ -105,7 +105,7 @@ using FastInterpolations: cubic_interp, CubicFit, LinearBinarySearch, Series, Ex odet = GeneralizedPerturbedEquilibrium.ForceFreeStates.OdeState(; numpert_total=intr.numpert_total, numsteps_init=ctrl.numsteps_init, numunorms_init=ctrl.numunorms_init, msing=intr.msing) - psifac_dummy = collect(range(0, 1, 10)); + psifac_dummy = collect(range(0, 1, 10)) points = length(psifac_dummy) amat = read_complex_fortran(joinpath(@__DIR__, "test_data/sing_der_testing/mat_dat/amat.dat")) amats = copyForSplines(amat, psifac_dummy) @@ -115,7 +115,7 @@ using FastInterpolations: cubic_interp, CubicFit, LinearBinarySearch, Series, Ex cmats = copyForSplines(cmat, psifac_dummy) fmat = read_complex_fortran(joinpath(@__DIR__, "test_data/sing_der_testing/mat_dat/fmat.dat")) - fmat .= cholesky(Hermitian(fmat)).L; + fmat .= cholesky(Hermitian(fmat)).L fmats = copyForSplines(fmat, psifac_dummy) kmat = read_complex_fortran(joinpath(@__DIR__, "test_data/sing_der_testing/mat_dat/kmat.dat")) kmats = copyForSplines(kmat, psifac_dummy) @@ -125,7 +125,7 @@ using FastInterpolations: cubic_interp, CubicFit, LinearBinarySearch, Series, Ex umat_p1 = read_complex_fortran(joinpath(@__DIR__, "test_data/sing_der_testing/mat_dat/umat_p1.dat")) umat_p2 = read_complex_fortran(joinpath(@__DIR__, "test_data/sing_der_testing/mat_dat/umat_p2.dat")) odet.psifac = extract_value(joinpath(@__DIR__, "test_data/sing_der_testing/mat_dat/sing_der_output_normal.dat"), "psifac") - odet.u[:, :, 1] .= umat_p1; + odet.u[:, :, 1] .= umat_p1 odet.u[:, :, 2] .= umat_p2 ffit = GeneralizedPerturbedEquilibrium.ForceFreeStates.FourFitVars(; mpert=intr.numpert_total, numpert_total=intr.numpert_total) diff --git a/test/runtests_tj_analytic.jl b/test/runtests_tj_analytic.jl index 5bbcb25d2..b36702001 100644 --- a/test/runtests_tj_analytic.jl +++ b/test/runtests_tj_analytic.jl @@ -19,12 +19,12 @@ using GeneralizedPerturbedEquilibrium.Equilibrium: TJAnalyticConfig, Equilibrium @testset "TJ-analytic model" begin @testset "tj_analytic_run (inverse) — basic invariants at ε = 0.25" begin # Keep ε, mpsi, mtheta modest so the whole block runs in ~1 s. - tj = TJAnalyticConfig(lar_r0 = 1.0 / 0.25, lar_a = 1.0, - qc = 1.5, qa = 3.6, pc = 0.001, mu = 2.0, B0 = 12.0, - ma = 64, mtau = 64) - eq = EquilibriumConfig(eq_type = "tj_analytic", - psilow = 0.01, psihigh = 0.995, - mpsi = 64, mtheta = 128, etol = 1e-7) + tj = TJAnalyticConfig(lar_r0=1.0 / 0.25, lar_a=1.0, + qc=1.5, qa=3.6, pc=0.001, mu=2.0, B0=12.0, + ma=64, mtau=64) + eq = EquilibriumConfig(eq_type="tj_analytic", + psilow=0.01, psihigh=0.995, + mpsi=64, mtheta=128, etol=1e-7) pe = setup_equilibrium(eq, tj) # psio is a physical-scale ψ; regressions in the a→a² normalization @@ -33,12 +33,12 @@ using GeneralizedPerturbedEquilibrium.Equilibrium: TJAnalyticConfig, Equilibrium @test isfinite(pe.psio) # ν root-find pins q₂(x=1) = qa; qmax at psihigh=0.995 lands ~0.04 below. - @test pe.params.q0 ≈ 1.5 rtol = 1e-3 + @test pe.params.q0 ≈ 1.5 rtol = 1e-3 @test pe.params.qmax > 3.5 @test pe.params.qmax < 3.7 # Magnetic axis at R = R0, Z = 0 for the shifted-circle benchmark. - @test pe.ro ≈ 4.0 rtol = 1e-3 + @test pe.ro ≈ 4.0 rtol = 1e-3 @test abs(pe.zo) < 1e-8 end @@ -46,12 +46,12 @@ using GeneralizedPerturbedEquilibrium.Equilibrium: TJAnalyticConfig, Equilibrium # ε = 0.60 sits on the stable side of the ideal-external-kink pole at # ε ≈ 0.665 for this (qc, qa, pc, μ) combination. Pole-approach shape # (δW_t small, Δ' > 0 and growing) is the Option B success criterion. - tj = TJAnalyticConfig(lar_r0 = 1.0 / 0.60, lar_a = 1.0, - qc = 1.5, qa = 3.6, pc = 0.001, mu = 2.0, B0 = 12.0, - ma = 64, mtau = 64) - eq = EquilibriumConfig(eq_type = "tj_analytic_direct", - psilow = 0.01, psihigh = 0.995, - mpsi = 64, mtheta = 128, etol = 1e-7) + tj = TJAnalyticConfig(lar_r0=1.0 / 0.60, lar_a=1.0, + qc=1.5, qa=3.6, pc=0.001, mu=2.0, B0=12.0, + ma=64, mtau=64) + eq = EquilibriumConfig(eq_type="tj_analytic_direct", + psilow=0.01, psihigh=0.995, + mpsi=64, mtheta=128, etol=1e-7) pe = setup_equilibrium(eq, tj) @test pe.psio > 0 @@ -59,13 +59,13 @@ using GeneralizedPerturbedEquilibrium.Equilibrium: TJAnalyticConfig, Equilibrium # Direct-GS line integration at ε=0.60 gives qmax between 3.8 and 4.0. # If the εa³·L shape terms in f_R / f_Z regress, qmax jumps above 5. - @test pe.params.q0 ≈ 1.5 rtol = 1e-2 + @test pe.params.q0 ≈ 1.5 rtol = 1e-2 @test pe.params.qmax > 3.75 @test pe.params.qmax < 4.1 # Magnetic axis at R = R0. Shafranov shift of the O-point itself is # zero by construction (H₁(0) = 0). - @test pe.ro ≈ (1.0 / 0.60) rtol = 1e-3 + @test pe.ro ≈ (1.0 / 0.60) rtol = 1e-3 @test abs(pe.zo) < 1e-4 end @@ -73,18 +73,18 @@ using GeneralizedPerturbedEquilibrium.Equilibrium: TJAnalyticConfig, Equilibrium # At the magnetic axis ψ_in should equal psio (axis convention: ψ # positive at axis, zero at LCFS); sampling well outside the LCFS should # give a negative value (the vacuum branch of psi_rz). - tj = TJAnalyticConfig(lar_r0 = 1.0 / 0.25, lar_a = 1.0, - qc = 1.5, qa = 3.6, pc = 0.001, mu = 2.0, B0 = 12.0, - ma = 64, mtau = 64) - eq = EquilibriumConfig(eq_type = "tj_analytic_direct", - psilow = 0.01, psihigh = 0.995, - mpsi = 64, mtheta = 128, etol = 1e-7) + tj = TJAnalyticConfig(lar_r0=1.0 / 0.25, lar_a=1.0, + qc=1.5, qa=3.6, pc=0.001, mu=2.0, B0=12.0, + ma=64, mtau=64) + eq = EquilibriumConfig(eq_type="tj_analytic_direct", + psilow=0.01, psihigh=0.995, + mpsi=64, mtheta=128, etol=1e-7) inp = tj_analytic_run_direct(eq, tj) # ψ at the geometric axis matches psio (see DirectRunInput docstring for # the sign convention: psi_in is positive at axis, zero at LCFS). R0 = 1.0 / 0.25 - @test inp.psi_in((R0, 0.0)) ≈ inp.psio rtol = 1e-3 + @test inp.psi_in((R0, 0.0)) ≈ inp.psio rtol = 1e-3 # Well outside the LCFS → negative ψ_in (vacuum branch of the grid). R_out = R0 + 1.05 # plasma LCFS is at R ≈ R0 + 0.94 From 46c648dba59e537d0c9e2d4280e5cbc7c09cfa8b Mon Sep 17 00:00:00 2001 From: ebursch <76970916+ebursch@users.noreply.github.com> Date: Mon, 17 Aug 2026 11:54:48 -0400 Subject: [PATCH 04/14] WIP - Bcrit runs through, need to add true Q0, P, etc. and validate --- .../DIIID-like_SLAYER_example/slayer_ex.ipynb | 60 ++++++++++++++++++- .../CriticalResonantField/bcrit_dev.ipynb | 37 ++++++++++-- .../CriticalResonantField/bcrit_dev_ggj.ipynb | 43 ++++++++++++- src/Tearing/Runner/Runner.jl | 2 +- src/Tearing/Runner/run_slayer.jl | 14 +++-- 5 files changed, 145 insertions(+), 11 deletions(-) diff --git a/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb b/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb index 0fb8f9079..72901743a 100644 --- a/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb +++ b/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb @@ -30,7 +30,8 @@ "source": [ "using GeneralizedPerturbedEquilibrium\n", "using Plots\n", - "using GeneralizedPerturbedEquilibrium: Analysis" + "using GeneralizedPerturbedEquilibrium: Analysis\n", + "using Printf" ] }, { @@ -49,6 +50,63 @@ "id": "4", "metadata": {}, "outputs": [], + "source": [ + "using HDF5\n", + "\n", + "h5open(h5path, \"r\") do file\n", + " println(\"Top-level keys:\")\n", + " println(collect(keys(file)))\n", + "\n", + " if haskey(file, \"Tearing\")\n", + " println(\"\\nKeys in Tearing:\")\n", + " println(collect(keys(file[\"Tearing\"])))\n", + "\n", + " if haskey(file[\"Tearing\"], \"CriticalResonantField\")\n", + " println(\"\\nKeys in Tearing/CriticalResonantField:\")\n", + " println(collect(keys(file[\"Tearing\"][\"CriticalResonantField\"])))\n", + " end\n", + " else\n", + " println(\"No Tearing group found.\")\n", + " end\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "# Print the contents of the Tearing/CriticalResonantField group\n", + "h5open(h5path, \"r\") do file\n", + " if haskey(file, \"Tearing\") && haskey(file[\"Tearing\"], \"CriticalResonantField\")\n", + " println(\"\\nContents of Tearing/CriticalResonantField:\")\n", + " # Iterate over the keys in the Tearing/CriticalResonantField group and print their names and types\n", + " for key in keys(file[\"Tearing\"][\"CriticalResonantField\"])\n", + " dataset = file[\"Tearing\"][\"CriticalResonantField\"][key]\n", + " println(\"Key: $key, Type: $(typeof(dataset))\")\n", + " # print data \n", + " if isa(dataset, HDF5.Dataset)\n", + " data = read(dataset)\n", + " println(\"Data: $data\")\n", + " end\n", + " end\n", + " else\n", + " println(\"No Tearing/CriticalResonantField group found.\")\n", + " end\n", + " # Print bcrit data as .2e (in one line)\n", + " println(\"\\nBcrit data: $(join([@sprintf(\"%.2e\", x) for x in read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"])], \" \"))\")\n", + "end\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], "source": [ "p_eq = Analysis.Equilibrium.plot_equilibrium_summary(h5path)\n", "p_ffs = Analysis.ForceFreeStates.plot_ffs_summary(h5path)\n", diff --git a/src/Tearing/CriticalResonantField/bcrit_dev.ipynb b/src/Tearing/CriticalResonantField/bcrit_dev.ipynb index 4af00e1f0..9269f6ab4 100644 --- a/src/Tearing/CriticalResonantField/bcrit_dev.ipynb +++ b/src/Tearing/CriticalResonantField/bcrit_dev.ipynb @@ -177,6 +177,35 @@ "id": "5", "metadata": {}, "outputs": [], + "source": [ + "jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", + "\n", + "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Δ\")\n", + "title!(p1, \"Inner-layer Δ(Q)\")\n", + "\n", + "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + "xlabel!(p2, \"Q\")\n", + "ylabel!(p2, \"jxb\")\n", + "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", + "\n", + "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", + "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + "xlabel!(p3, \"Q\")\n", + "ylabel!(p3, \"balance\")\n", + "title!(p3, \"2P(Q0-Q)/jxb\")\n", + "\n", + "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], "source": [ "Qpk = Qs_positive[argmax(bal_positive)]\n", "j = findfirst(isequal(Qpk), Qs)\n", @@ -196,7 +225,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6", + "id": "7", "metadata": {}, "outputs": [], "source": [ @@ -239,7 +268,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7", + "id": "8", "metadata": {}, "outputs": [], "source": [ @@ -352,7 +381,7 @@ { "cell_type": "code", "execution_count": null, - "id": "8", + "id": "9", "metadata": {}, "outputs": [], "source": [] @@ -360,7 +389,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9", + "id": "10", "metadata": {}, "outputs": [], "source": [] diff --git a/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb b/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb index a4d02d76f..ca4f3df48 100644 --- a/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb +++ b/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb @@ -106,7 +106,7 @@ "sval_ggj = 0.5\n", "\n", "tb = TorqueBalance(\n", - " GeneralizedPerturbedEquilibrium.InnerLayer.GGJModel(; solver=:ray),\n", + " GeneralizedPerturbedEquilibrium.InnerLayer.GGJModel(; solver=:galerkin),\n", " p_ggj,\n", " 0.5,\n", " 1.0,\n", @@ -204,6 +204,47 @@ "id": "10", "metadata": {}, "outputs": [], + "source": [ + "println(p.lu^(1/3))\n", + "println(p.tauk)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": {}, + "outputs": [], + "source": [ + "Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing/p.lu^(1 / 3) for q in Qs]\n", + "jxbs = [-imag(1.0 / (d + tb.delta_n_p)) for d in Δs]\n", + "\n", + "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Δ\")\n", + "title!(p1, \"Inner-layer Δ(Q)\")\n", + "\n", + "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + "xlabel!(p2, \"Q\")\n", + "ylabel!(p2, \"jxb\")\n", + "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", + "\n", + "p3 = plot(Qs, real.(vals), label=\"Re(balance)\", lw=2)\n", + "plot!(p3, Qs, imag.(vals), label=\"Im(balance)\", lw=2)\n", + "xlabel!(p3, \"Q\")\n", + "ylabel!(p3, \"balance\")\n", + "title!(p3, \"2P(Q0-Q)/jxb\")\n", + "\n", + "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": {}, + "outputs": [], "source": [ "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", diff --git a/src/Tearing/Runner/Runner.jl b/src/Tearing/Runner/Runner.jl index df3293b2f..6f11208a7 100644 --- a/src/Tearing/Runner/Runner.jl +++ b/src/Tearing/Runner/Runner.jl @@ -30,7 +30,6 @@ using HDF5 using FastInterpolations: cubic_interp using ..Utilities using ..Utilities: KineticProfiles -using ...Equilibrium: read_kinetic_file, KineticProfileData using ..InnerLayer using ..InnerLayer: InnerLayerParameters, InnerLayerResponse, solve_inner, @@ -47,6 +46,7 @@ using ..Dispersion: SurfaceCoupling, surface_coupling, AMRResult, amr_scan, MultiBoxAMRResult, multi_box_amr_scan, as_amr_result, GrowthRateResult, find_growth_rates +using ..CriticalResonantField: TorqueBalance, torque_balance_scan include("Control.jl") include("Result.jl") diff --git a/src/Tearing/Runner/run_slayer.jl b/src/Tearing/Runner/run_slayer.jl index 3dca41bbc..5c92691f5 100644 --- a/src/Tearing/Runner/run_slayer.jl +++ b/src/Tearing/Runner/run_slayer.jl @@ -469,12 +469,18 @@ end and the corresponding critical resoannt field values for each rational surface. """ -function run_critical_resonant_field(equil, intr, ctrl; dir_path="./") +function run_critical_resonant_field(equil, intr, ctrl; dir_path="./", slayer_result=nothing) ctrl.enabled || return empty_critical_resonant_field_result() - # Use the same per-surface params already built for SLAYER - profiles = Equilibrium.load_kinetic_profiles(joinpath(dir_path, ctrl.profile_file)) - params = build_slayer_inputs(equil, intr.sing, profiles) + params = if slayer_result !== nothing && slayer_result.enabled && !isempty(slayer_result.params) + slayer_result.params + else + profiles = load_kinetic_profiles(joinpath(dir_path, ctrl.profile_file)) + build_slayer_inputs(equil, intr.sing, profiles) + end + + all(p -> p isa SLAYERParameters, params) || + throw(ArgumentError("CriticalResonantField requires SLAYERParameters; run SLAYER first or provide compatible params.")) surface_index = Int[] Qpeak_vec = Float64[] From 522312261253a0a8d0c81ca6d8e80938cb64bb49 Mon Sep 17 00:00:00 2001 From: ebursch <76970916+ebursch@users.noreply.github.com> Date: Tue, 18 Aug 2026 16:07:46 -0400 Subject: [PATCH 05/14] WIP - Rebasing with develop --- .../DIIID-like_SLAYER_example/slayer_ex.ipynb | 102 ++- .../CriticalResonantField/CRF Dev/b_crit.jls | Bin 0 -> 74 bytes .../CRF Dev/bcrit_dev.ipynb | 724 ++++++++++++++++++ .../{ => CRF Dev}/bcrit_dev_ggj.ipynb | 23 +- .../CRF Dev/bcrit_numerics.ipynb | 122 +++ .../{ => CRF Dev}/gslayer.txt | 0 .../CRF Dev/pole_testing.ipynb | 234 ++++++ .../CRF Dev/sample_number.jls | Bin 0 -> 68 bytes .../CriticalResonantField/TorqueBalance.jl | 4 +- .../CriticalResonantField/bcrit_dev.ipynb | 407 ---------- src/Tearing/Runner/HDF5Output.jl | 7 + src/Tearing/Runner/run_slayer.jl | 42 +- 12 files changed, 1211 insertions(+), 454 deletions(-) create mode 100644 src/Tearing/CriticalResonantField/CRF Dev/b_crit.jls create mode 100644 src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb rename src/Tearing/CriticalResonantField/{ => CRF Dev}/bcrit_dev_ggj.ipynb (91%) create mode 100644 src/Tearing/CriticalResonantField/CRF Dev/bcrit_numerics.ipynb rename src/Tearing/CriticalResonantField/{ => CRF Dev}/gslayer.txt (100%) create mode 100644 src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb create mode 100644 src/Tearing/CriticalResonantField/CRF Dev/sample_number.jls delete mode 100644 src/Tearing/CriticalResonantField/bcrit_dev.ipynb diff --git a/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb b/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb index 72901743a..709891273 100644 --- a/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb +++ b/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb @@ -8,36 +8,26 @@ "outputs": [], "source": [ "using Pkg\n", - "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1", - "metadata": {}, - "outputs": [], - "source": [ - "Base.active_project()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2", - "metadata": {}, - "outputs": [], - "source": [ + "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", + "Base.active_project()\n", + "\n", "using GeneralizedPerturbedEquilibrium\n", - "using Plots\n", "using GeneralizedPerturbedEquilibrium: Analysis\n", - "using Printf" + "using Printf\n", + "\n", + "using Plots\n", + "default(\n", + " fontfamily=\"Georgia\",\n", + " margin=12Plots.mm,\n", + " size=(800, 500),\n", + " dpi=150\n", + ")" ] }, { "cell_type": "code", "execution_count": null, - "id": "3", + "id": "1", "metadata": {}, "outputs": [], "source": [ @@ -47,7 +37,7 @@ { "cell_type": "code", "execution_count": null, - "id": "4", + "id": "2", "metadata": {}, "outputs": [], "source": [ @@ -74,7 +64,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5", + "id": "3", "metadata": {}, "outputs": [], "source": [ @@ -101,12 +91,74 @@ "\n" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "println(keys(h5open(h5path, \"r\")[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_1\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "function bcrit_diag_plots(Δs, Qs, bal,name)\n", + "\n", + " p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", + " #plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + " xlabel!(p1, \"Q\")\n", + " ylabel!(p1, \"Δ\")\n", + " title!(p1, \"Inner-layer Δ(Q) - $name\")\n", + "\n", + " p2 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", + " plot!(p2, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + " xlabel!(p2, \"Q\")\n", + " ylabel!(p2, \"balance\")\n", + " title!(p2, \"2P(Q0-Q)/jxb - $name\")\n", + "\n", + " plot(p1, p2, layout=(2,1), size=(800, 1000))\n", + "\n", + "\n", + "end" + ] + }, { "cell_type": "code", "execution_count": null, "id": "6", "metadata": {}, "outputs": [], + "source": [ + "# Plot bcrit vs q surface\n", + "\n", + "# print all contents of bcrit /scan /surface 1/\n", + "h5open(h5path, \"r\") do file\n", + " bcrit = file[\"Tearing\"][\"CriticalResonantField\"]\n", + "\n", + " for i in 1:6\n", + " ss = \"surface_$i\"\n", + "\n", + " delta = read(bcrit[\"Scan\"][ss][\"delta\"])\n", + " Q = read(bcrit[\"Scan\"][ss][\"Q\"])\n", + " balance = read(bcrit[\"Scan\"][ss][\"balance\"])\n", + "\n", + " display(bcrit_diag_plots(delta, Q, balance, \"surface_$i\"))\n", + " end\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": {}, + "outputs": [], "source": [ "p_eq = Analysis.Equilibrium.plot_equilibrium_summary(h5path)\n", "p_ffs = Analysis.ForceFreeStates.plot_ffs_summary(h5path)\n", diff --git a/src/Tearing/CriticalResonantField/CRF Dev/b_crit.jls b/src/Tearing/CriticalResonantField/CRF Dev/b_crit.jls new file mode 100644 index 0000000000000000000000000000000000000000..dcd8e2611787cf2ae06b76a1ee64426e4009ac8a GIT binary patch literal 74 zcmXr_@{waLoNTscITzal0AxrQ1ONa4 literal 0 HcmV?d00001 diff --git a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb new file mode 100644 index 000000000..528ca4934 --- /dev/null +++ b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb @@ -0,0 +1,724 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "using Pkg\n", + "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", + "Base.active_project()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1", + "metadata": {}, + "outputs": [], + "source": [ + "using GeneralizedPerturbedEquilibrium\n", + "using GeneralizedPerturbedEquilibrium: Analysis\n", + "using GeneralizedPerturbedEquilibrium: InnerLayer\n", + "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", + "using GeneralizedPerturbedEquilibrium: Tearing\n", + "using ..InnerLayer\n", + "using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters,\n", + " SLAYERModel, SLAYERParameters\n", + "\n", + "using Plots\n", + "using Printf\n", + "default(\n", + " fontfamily=\"Georgia\",\n", + " margin=12Plots.mm,\n", + " size=(800, 500),\n", + " dpi=150\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "struct TorqueBalance{M<:InnerLayerModel,P}\n", + " model::M\n", + " params::P\n", + " Q0::Float64\n", + " P::Float64\n", + " lu::Float64\n", + " sval::Float64\n", + "end\n", + "\n", + "function torque_balance_value(tb::TorqueBalance, Q::Number)\n", + " Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing\n", + " alpha = 1e-2\n", + " jxb = -imag(1.0 / (Δ+ alpha))\n", + " return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ\n", + "end\n", + "\n", + "function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200)\n", + " Qs = range(Qmin, Qmax; length=n)\n", + " torque_out = [torque_balance_value(tb, q) for q in Qs]\n", + " bal = [x[1] for x in torque_out]\n", + " Δs = [x[2] for x in torque_out]\n", + " #bal = [torque_balance_value(tb, q) for q in Qs]\n", + " positive = isfinite.(bal) .& (bal .> 0.0)\n", + "\n", + " if !any(positive)\n", + " return Qs, bal, NaN, NaN, 0.0, NaN, NaN, Δs\n", + " end\n", + " i = argmax(bal)\n", + " Qpeak_ind = i\n", + " Qs_positive = Qs[positive]\n", + " bal_positive = bal[positive]\n", + "\n", + " i = argmax(bal_positive)\n", + " Qpeak = Qs_positive[i]\n", + " \n", + " maxbal = bal_positive[i]\n", + "\n", + " br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", + " return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", + " n_e=1e19, t_e=1e3, t_i=1e3,\n", + " omega=0.0, omega_e=4, omega_i=-2,\n", + " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", + " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", + ")\n", + "p2 = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", + " ising=p.ising,\n", + " m=p.m, n=p.n,\n", + " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", + " P_perp=p.P_perp, P_tor=p.P_tor,\n", + " Q_e=0.818, Q_i=-0.543, iota_e=p.iota_e,\n", + " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", + " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", + " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", + " eta=p.eta, d_beta=p.d_beta,\n", + " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", + ")\n", + "\n", + "p2 = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", + " ising=p.ising,\n", + " m=p.m, n=p.n,\n", + " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", + " P_perp=p.P_perp, P_tor=p.P_tor,\n", + " Q_e=2, Q_i=3, iota_e=p.iota_e,\n", + " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", + " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", + " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", + " eta=p.eta, d_beta=p.d_beta,\n", + " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", + ")\n", + "\n", + "p = p2\n", + "\n", + "tb = TorqueBalance(\n", + " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", + " p,\n", + " 0.5,\n", + " 61.0, #1.0\n", + " p.lu,\n", + " p.sval_r\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "#Qs = range(-5.0, 5.0, length=200)\n", + "\n", + "#vals = [torque_balance_value(tb, q) for q in Qs]\n", + "\"\"\"\n", + "n=2000:\n", + "Qpeak = 0.24512256128064033\n", + "maxbal = 0.35873684252530247\n", + "br_crit = 4.668551985584323e-5\n", + "\n", + "n=200 (def):\n", + "Qpeak = 0.25125628140703515\n", + "maxbal = 0.3585219071071706\n", + "br_crit = 4.667153206033017e-5\n", + "\"\"\"\n", + "Qmi = -10\n", + "Qma = 10\n", + "\n", + "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qmi, Qmax=Qma, n=10000)\n", + "\n", + "println(\"Qpeak = \", Qpeak)\n", + "println(\"maxbal = \", maximum(bal_positive))\n", + "println(\"maxbal = \", maximum(bal))\n", + "println(\"br_crit = \", brcrit)\n", + "\n", + "p1 = plot(Qs, bal, lw=2, label=\"balance\")#,ylim=(-40, 40))\n", + "z_inds = findall(i -> bal[i]*bal[i+1] < 0, 1:length(bal)-1)\n", + "println(\"zero crossings at Q = \", Qs[z_inds])\n", + "for i in z_inds\n", + " vline!([Qs[i]], label=\"0\", linestyle=:dot, color=:gray)\n", + "end\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"balance\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "\n", + "\n", + "p5 = plot(Qs, bal, lw=2, label=\"balance\",xlim=(Qs[z_inds[1]],Qs[z_inds[2]]))#,ylim=(-40, 40))#, xlim = (-.11,-.09))\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"balance\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "p2 = plot(Qs, -imag(Δs), lw=2, label=\"Im(Δ)\",ylim=(-5,2))#,xlim=(-.11,-.09))\n", + "plot!(p2, Qs, real(Δs), lw=2, label=\"Re(Δ)\")\n", + "#vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "#hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "vline!([-3], linestyle=:dashdot)\n", + "vline!([-2], linestyle=:dashdot)\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "vline!([0.499], linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"Δ\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "jxb = -imag(1.0 ./ (Δs .+ 1e-2))\n", + "jxb0 = -imag(1.0 ./ (Δs))\n", + "p3 = plot(Qs, jxb, lw=2, label=\"-Im(1 / (Δs + 1e-2))\",color=:blue)#, xlim = (-.11,-.09),ylim=(-500,500))\n", + "plot!(p3, Qs, jxb0, lw=2, label=\"-Im(1 / Δs)\",color=:red,linestyle=:dash)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"~ jxb\")\n", + "\n", + "p4 = plot(Qs, jxb, lw=2, label=\"-Im(1 / Δs)\",color=:blue)#, xlim = (-.11,-.09))\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"~ jxb\")\n", + "\"\"\"\n", + "#remake plot 1 but of derivative of balance with respect to Q\n", + "dQ = Qs[2] - Qs[1]\n", + "dbal_dQ = diff(bal) ./ dQ\n", + "p3 = plot(Qs[1:end-1], dbal_dQ, lw=2, label=\"d(balance)/dQ\",ylim=(-1000, 1000))\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"d(balance)/dQ\")\n", + "\"\"\"\n", + "\n", + "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qs[], Qmax=Qs[zin], n=10000)\n", + "\n", + "\n", + "plo = plot(p1, p2,p3,p4,p5, p6, layout=(6,1), size=(1000, 2000))\n", + "display(plo)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "Qlow = -0.1005100510051005\n", + "Qhigh = 0.49954995499549953\n", + "\n", + "#Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qlow, Qmax=Qhigh, n=10000)\n", + "\n", + "println(\"Qpeak = \", Qpeak)\n", + "println(\"maxbal = \", maximum(bal_positive))\n", + "println(\"maxbal = \", maximum(bal))\n", + "println(\"br_crit = \", brcrit)\n", + "\n", + "p1 = plot(Qs, bal, lw=2, label=\"balance\")#,ylim=(-40, 40))\n", + "z_inds = findall(i -> bal[i]*bal[i+1] < 0, 1:length(bal)-1)\n", + "println(\"zero crossings at Q = \", Qs[z_inds])\n", + "for i in z_inds\n", + " vline!([Qs[i]], label=\"0\", linestyle=:dot, color=:gray)\n", + "end\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"balance\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "\n", + "p5 = plot(Qs, bal, lw=2, label=\"balance\",ylim=(-40, 40), xlim = (-.11,-.09))\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"balance\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "p2 = plot(Qs, -imag(Δs), lw=2, label=\"Im(Δ)\",ylim=(-2,2))#,xlim=(-.11,-.09))\n", + "plot!(p2, Qs, real(Δs), lw=2, label=\"Re(Δ)\")\n", + "#vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "#hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"Δ\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "jxb = -imag(1.0 ./ (Δs .+ 1e-2))\n", + "jxb0 = -imag(1.0 ./ (Δs))\n", + "p3 = plot(Qs, jxb, lw=2, label=\"-Im(1 / (Δs + 1e-2))\",color=:blue, xlim = (-.11,-.09),ylim=(-500,500))\n", + "plot!(p3, Qs, jxb0, lw=2, label=\"-Im(1 / Δs)\",color=:red,linestyle=:dash)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"~ jxb\")\n", + "\n", + "p4 = plot(Qs, jxb, lw=2, label=\"-Im(1 / Δs)\",color=:blue, xlim = (-.11,-.09))\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"~ jxb\")\n", + "\"\"\"\n", + "#remake plot 1 but of derivative of balance with respect to Q\n", + "dQ = Qs[2] - Qs[1]\n", + "dbal_dQ = diff(bal) ./ dQ\n", + "p3 = plot(Qs[1:end-1], dbal_dQ, lw=2, label=\"d(balance)/dQ\",ylim=(-1000, 1000))\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"d(balance)/dQ\")\n", + "\"\"\"\n", + "plo = plot(p1, p2,p3,p4,p5, layout=(5,1), size=(1000, 2000))\n", + "display(plo)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "#Qs = range(-5.0, 5.0, length=200)\n", + "\n", + "#vals = [torque_balance_value(tb, q) for q in Qs]\n", + "\"\"\"\n", + "n=2000:\n", + "Qpeak = 0.24512256128064033\n", + "maxbal = 0.35873684252530247\n", + "br_crit = 4.668551985584323e-5\n", + "\n", + "n=200 (def):\n", + "Qpeak = 0.25125628140703515\n", + "maxbal = 0.3585219071071706\n", + "br_crit = 4.667153206033017e-5\n", + "\"\"\"\n", + "\n", + "#Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=-.2, Qmax=0.5, n=10000)\n", + "\n", + "println(\"Qpeak = \", Qpeak)\n", + "println(\"maxbal = \", maximum(bal_positive))\n", + "println(\"maxbal = \", maximum(bal))\n", + "println(\"br_crit = \", brcrit)\n", + "\n", + "p1 = plot(Qs, bal, lw=2, label=\"balance\")#,ylim=(-40, 40))\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"balance\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "p2 = plot(Qs, -imag(Δs), lw=2, label=\"Im(Δs)\")#,ylim=(-.2,.05))#,xlim=(-.11,-.09))\n", + "plot!(p2, Qs, real(Δs), lw=2, label=\"Re(Δs)\")\n", + "#vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "#hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"Δs\")\n", + "title!(\"Torque-balance scan\")\n", + "\n", + "\"\"\"\n", + "#remake plot 1 but of derivative of balance with respect to Q\n", + "dQ = Qs[2] - Qs[1]\n", + "dbal_dQ = diff(bal) ./ dQ\n", + "p3 = plot(Qs[1:end-1], dbal_dQ, lw=2, label=\"d(balance)/dQ\",ylim=(-1000, 1000))\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", + "xlabel!(\"Q\")\n", + "ylabel!(\"d(balance)/dQ\")\n", + "\"\"\"\n", + "plo = plot(p1, p2, layout=(2,1), size=(800, 1000))\n", + "display(plo)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": {}, + "outputs": [], + "source": [ + "jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", + "\n", + "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Δ\")\n", + "title!(p1, \"Inner-layer Δ(Q)\")\n", + "\n", + "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + "xlabel!(p2, \"Q\")\n", + "ylabel!(p2, \"jxb\")\n", + "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", + "\n", + "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", + "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + "xlabel!(p3, \"Q\")\n", + "ylabel!(p3, \"balance\")\n", + "title!(p3, \"2P(Q0-Q)/jxb\")\n", + "\n", + "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], + "source": [ + "# Check torque is balanced\n", + "\n", + "viscous_torque = 2*tb.P*(tb.Q0 - Qpeak)\n", + "electromagnetic_torque = -imag(1.0 / (Δs[Qpeak_ind] + 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", + "\n", + "# delta_n_p = 1e-2\n", + "# jxb = -imag(1.0 / (Δ + delta_n_p))\n", + "# bal = 2.0 * tb.P * (tb.Q0 - Q) / jxb\n", + "# br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", + "\n", + "@printf(\"br_crit = %.5e\\n\", brcrit)\n", + "@printf(\"viscous_torque = %.5e\\n\", viscous_torque)\n", + "@printf(\"electromagnetic_torque = %.5e\\n\", electromagnetic_torque)\n", + "@printf(\"ratio = %.10f\\n\", viscous_torque / electromagnetic_torque)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": {}, + "outputs": [], + "source": [ + "Qs_n, bal_n, Qs_positive_n, bal_positive_n, Qpeak_n, brcrit_n, Qpeak_ind_n, Δs_n = torque_balance_scan(tb,Qmin=-3, Qmax=3, n=2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": {}, + "outputs": [], + "source": [ + "sample_number = [2, 3, 4, 5, 10,100,1000]#,10000,100000]#,1000000]\n", + "b_crit = []\n", + "# make dicts to store Qs_n and Δs_n arrays for each sample number\n", + "Qs_n_dict = Dict{Int, Vector{Float64}}()\n", + "bal_n_dict = Dict{Int, Vector{Float64}}()\n", + "for i in sample_number\n", + " Qs_n, bal_n, Qs_positive_n, bal_positive_n, Qpeak_n, brcrit_n, Qpeak_ind_n, Δs_n = torque_balance_scan(tb,Qmin=-3, Qmax=3, n=i)\n", + " push!(b_crit, brcrit_n)\n", + " push!(Qs_n_dict, i => Qs_n)\n", + " push!(bal_n_dict, i => bal_n)\n", + " println(bal_n)\n", + "end\n", + "\n", + "# add bcrit = 3.50601e-03 for n=100000 to b_crit\n", + "#push!(b_crit, 3.50601e-03)\n", + "\n", + "# make a plot of b_crit vs sample_number \n", + "p1 = plot(sample_number, b_crit,\n", + " lw=2,\n", + " label=\"b_crit\",\n", + " #xscale=:log10,\n", + " #yscale=:log10,\n", + " xlabel=\"Sample Number\",\n", + " ylabel=\"b_crit\")\n", + "\n", + "p2 = plot(\n", + " xlabel=\"Q\",\n", + " ylabel=\"balance\",\n", + " title=\"Torque balance vs Q\"\n", + ")\n", + "\n", + "for i in sample_number[1:end-1]\n", + " plot!(p2, Qs_n_dict[i], bal_n_dict[i],\n", + " lw=2,\n", + " label=\"n=$i\")\n", + "end\n", + "\n", + "p3 = plot(layout=(3, 2), size=(1000, 800))\n", + "\n", + "for (k, i) in enumerate(sample_number[1:end-1])\n", + " plot!(\n", + " p3[k],\n", + " Qs_n_dict[i],\n", + " bal_n_dict[i],\n", + " lw=2,\n", + " label=\"n=$i\",\n", + " xlabel=\"Q\",\n", + " ylabel=\"balance\",\n", + " title=\"n = $i\"\n", + " )\n", + "end\n", + "\n", + "display(p1)\n", + "display(p2)\n", + "display(p3)\n", + "\n", + "\n", + "println(\"b_crit = \", b_crit)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": {}, + "outputs": [], + "source": [ + "println(b_crit)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": {}, + "outputs": [], + "source": [ + "bcrit = Any[0.0014075170156654356, 0.0015190532807794722, 0.0015297173529485084, 0.0015297510027746748, 0.0015297613496804952, 0.0015297692159317363, 0.004702965572292843]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "13", + "metadata": {}, + "outputs": [], + "source": [ + "using Serialization\n", + "\n", + "# serialize(\"Qs_n_dict.jls\", Qs_n_dict)\n", + "# serialize(\"bal_n_dict.jls\", bal_n_dict)\n", + "# serialize(\"b_crit.jls\", b_crit)\n", + "# serialize(\"sample_number.jls\", sample_number)\n", + "#my_dict = deserialize(\"my_dict.jls\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=-2.5, Qmax=0, n=20000)\n", + "\n", + "jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", + "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for q in Qs] #(q, jxb) in zip(Qs, jxbs)]\n", + "br_t = brcrit\n", + "println(tb.lu, \" \", tb.sval, \" \", br_t, \" \", p.bt, \" \", 1e-2)\n", + "@printf(\"br_crit = %.5e\\n\", brcrit)\n", + "#T_EM = tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs\n", + "T_EM = -imag(1.0 ./ (Δs .+ 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", + "i = Qpeak_ind\n", + "println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", + "println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", + "println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", + "\n", + "#T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", + "#T_visc ∝ 2 P (Q0 − Q)\n", + "\n", + "xmi = -2.5\n", + "xma = 0\n", + "\n", + "\"\"\"\n", + "p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2, xlim=(xmi, xma))\n", + "#plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Δ\")\n", + "#title!(p1, \"Inner-layer Δ(Q)\")\n", + "\"\"\"\n", + "\n", + "p1 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(-1000,1000))\n", + "plot!(p1, Qs, T_EM, label=\"T_EM\", lw=2)\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Torque\")\n", + "\n", + "#p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + "p2 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(0,500))\n", + "plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "xlabel!(p2, \"Q\")\n", + "ylabel!(p2, \"Torque\")\n", + "#title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", + "\n", + "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2, xlim=(xmi, xma))\n", + "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + "ylabel!(p3, \"Torque Balance\")\n", + "#title!(p3, \"2P(Q0-Q)/jxb\")\n", + "xlabel!(p3, \"Q\")\n", + "vline!([Qpeak], label=\"Max Balance\", linestyle=:dash)\n", + "\n", + "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "15", + "metadata": {}, + "outputs": [], + "source": [ + "# Recreate Cihan's plot:\n", + "\n", + "using Plots\n", + "using DataInterpolations\n", + "\n", + "default(\n", + " fontfamily=\"Georgia\",\n", + " grid=false,\n", + " linewidth=2,\n", + " guidefontsize=26,\n", + " tickfontsize=18,\n", + " titlefontsize=30,\n", + " legendfontsize=18,\n", + " size=(1200, 800),\n", + " dpi=150\n", + ")\n", + "\n", + "# Build the critical boundary bcrit(Q0)\n", + "Q0_scan = range(-1.0, 4.5; length=80)\n", + "bcrit_curve = Float64[]\n", + "\n", + "for Q0 in Q0_scan\n", + " tbQ = TorqueBalance(\n", + " tb.model,\n", + " tb.params,\n", + " Float64(Q0),\n", + " tb.P,\n", + " tb.delta_n_p,\n", + " tb.lu,\n", + " tb.sval\n", + " )\n", + "\n", + " Qs, bal, Qs_pos, bal_pos, Qpeak, brcrit, Qpeak_ind, Δs =\n", + " torque_balance_scan(tbQ; Qmin=-10.0, Qmax=10.0, n=250)\n", + "\n", + " if isempty(bal_pos) || !all(isfinite.(bal_pos)) || maximum(bal_pos) <= 0\n", + " push!(bcrit_curve, NaN)\n", + " else\n", + " push!(bcrit_curve, brcrit)\n", + " end\n", + "end\n", + "\n", + "ok = isfinite.(bcrit_curve)\n", + "Q0_plot = Q0_scan[ok]\n", + "bcrit_plot = bcrit_curve[ok]\n", + "\n", + "perm = sortperm(Q0_plot)\n", + "Q0_plot = Q0_plot[perm]\n", + "bcrit_plot = bcrit_plot[perm]\n", + "\n", + "# Interpolate the boundary: bcrit = f(Q0)\n", + "curve_itp = LinearInterpolation(bcrit_plot, Q0_plot)\n", + "\n", + "# Full phase-box bounds\n", + "x0 = minimum(bcrit_plot) * 0.8\n", + "x1 = maximum(bcrit_plot) * 1.2\n", + "y0 = minimum(Q0_plot)\n", + "y1 = maximum(Q0_plot)\n", + "\n", + "xvals = range(x0, x1; length=350)\n", + "yvals = range(y0, y1; length=350)\n", + "\n", + "locked_mask = zeros(Float64, length(yvals), length(xvals))\n", + "for iy in eachindex(yvals)\n", + " y = yvals[iy]\n", + " for ix in eachindex(xvals)\n", + " x = xvals[ix]\n", + " # locked when bcrit exceeds the boundary for that Q0\n", + " locked_mask[iy, ix] = x >= curve_itp(y) ? 1.0 : 0.0\n", + " end\n", + "end\n", + "\n", + "p = contourf(\n", + " xvals, yvals, locked_mask',\n", + " levels=[-0.5, 0.5, 1.5],\n", + " c=[:navy, :firebrick],\n", + " colorbar=false,\n", + " xlabel=\"b_crit\",\n", + " ylabel=\"Q_0\",\n", + " title=\"Locked / unlocked region\",\n", + " framestyle=:box,\n", + " xlims=(x0, x1),\n", + " ylims=(y0, y1),\n", + " legend=false\n", + ")\n", + "\n", + "# Critical boundary\n", + "plot!(p, bcrit_plot, Q0_plot; lw=3, color=:black, label=\"critical boundary\")\n", + "\n", + "# Critical point\n", + "cp_idx = argmax(bcrit_plot)\n", + "cp_x = bcrit_plot[cp_idx]\n", + "cp_y = Q0_plot[cp_idx]\n", + "scatter!(p, [cp_x], [cp_y]; color=:gold, marker=:star5, ms=12, label=\"critical point\")\n", + "\n", + "# Single legend block with one entry per category\n", + "plot!(p, [NaN], [NaN]; color=:firebrick, lw=4, label=\"locked\")\n", + "plot!(p, [NaN], [NaN]; color=:navy, lw=4, label=\"unlocked\")\n", + "plot!(p, [NaN], [NaN]; color=:black, lw=3, label=\"critical boundary\")\n", + "scatter!(p, [NaN], [NaN]; color=:gold, marker=:star5, ms=12, label=\"critical point\")\n", + "\n", + "plot!(p; legend=:topright)\n", + "\n", + "display(p)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "17", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev_ggj.ipynb similarity index 91% rename from src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb rename to src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev_ggj.ipynb index ca4f3df48..617d61585 100644 --- a/src/Tearing/CriticalResonantField/bcrit_dev_ggj.ipynb +++ b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev_ggj.ipynb @@ -216,7 +216,26 @@ "metadata": {}, "outputs": [], "source": [ - "Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing/p.lu^(1 / 3) for q in Qs]\n", + "plt.figure()\n", + "for i in OMFIT['GPEC']['OUTPUTS'].keys():\n", + " try:\n", + " print(OMFIT['GPEC']['OUTPUTS'][i]['DATA'][0]['gpec_slayer_torque_balance_m2_n1_out']['bal'].values)\n", + " plt.plot(OMFIT['GPEC']['OUTPUTS'][i]['DATA'][0]['gpec_slayer_torque_balance_m2_n1_out']['inQ'].values, OMFIT['GPEC']['OUTPUTS'][i]['DATA'][0]['gpec_slayer_torque_balance_m2_n1_out']['bal'].values,label=i)\n", + " except:\n", + " continue\n", + "plt.axhline(0)\n", + "plt.legend()\n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "12", + "metadata": {}, + "outputs": [], + "source": [ + "Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing/p.lu^(1 / 3)/p.rs for q in Qs]\n", "jxbs = [-imag(1.0 / (d + tb.delta_n_p)) for d in Δs]\n", "\n", "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", @@ -242,7 +261,7 @@ { "cell_type": "code", "execution_count": null, - "id": "12", + "id": "13", "metadata": {}, "outputs": [], "source": [ diff --git a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_numerics.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_numerics.ipynb new file mode 100644 index 000000000..71ed79d9e --- /dev/null +++ b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_numerics.ipynb @@ -0,0 +1,122 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "using Pkg\n", + "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", + "Base.active_project()\n", + "using GeneralizedPerturbedEquilibrium\n", + "using GeneralizedPerturbedEquilibrium: Analysis\n", + "using GeneralizedPerturbedEquilibrium: InnerLayer\n", + "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", + "using GeneralizedPerturbedEquilibrium: Tearing\n", + "using ..InnerLayer\n", + "using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters,\n", + " SLAYERModel, SLAYERParameters\n", + "using Serialization\n", + "using Plots\n", + "using Printf\n", + "default(\n", + " fontfamily=\"Georgia\",\n", + " margin=12Plots.mm,\n", + " size=(800, 500),\n", + " dpi=150\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1", + "metadata": {}, + "outputs": [], + "source": [ + "bal_n_dict = deserialize(\"bal_n_dict.jls\")\n", + "Qs_n_dict = deserialize(\"Qs_n_dict.jls\")\n", + "sample_number = deserialize(\"sample_number.jls\")\n", + "bcrit = deserialize(\"b_crit.jls\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "# make a plot of b_crit vs sample_number \n", + "p1 = plot(\n", + " sample_number,\n", + " b_crit,\n", + " lw=2,\n", + " marker=:circle,\n", + " label=\"b_crit\",\n", + " xscale=:log10,\n", + " #yscale=:log10,\n", + " xlabel=\"Sample Number\",\n", + " ylabel=\"b_crit\"\n", + ")\n", + "\n", + "xticks!(p1,\n", + " [5, 10, 100, 1000, 10000, 100000, 1000000],\n", + " [\"5\", \"10\", \"100\", \"1k\", \"10k\", \"100k\", \"1M\"]\n", + ")\n", + "\n", + "p2 = plot(\n", + " xlabel=\"Q\",\n", + " ylabel=\"balance\",\n", + " title=\"Torque balance vs Q\"\n", + ")\n", + "\n", + "for i in sample_number\n", + " plot!(p2, Qs_n_dict[i], bal_n_dict[i],\n", + " lw=2,\n", + " label=\"n=$i\")\n", + "end\n", + "\n", + "p3 = plot(layout=(4, 2), size=(1000, 800))\n", + "\n", + "for (k, i) in enumerate(sample_number)\n", + " plot!(\n", + " p3[k],\n", + " Qs_n_dict[i],\n", + " bal_n_dict[i],\n", + " lw=2,\n", + " label=\"n=$i\",\n", + " xlabel=\"Q\",\n", + " ylabel=\"balance\",\n", + " title=\"n = $i\"\n", + " )\n", + "end\n", + "\n", + "display(p1)\n", + "display(p2)\n", + "display(p3)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "println(\"bcrit = $bcrit\")" + ] + } + ], + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/Tearing/CriticalResonantField/gslayer.txt b/src/Tearing/CriticalResonantField/CRF Dev/gslayer.txt similarity index 100% rename from src/Tearing/CriticalResonantField/gslayer.txt rename to src/Tearing/CriticalResonantField/CRF Dev/gslayer.txt diff --git a/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb new file mode 100644 index 000000000..329e9dd53 --- /dev/null +++ b/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb @@ -0,0 +1,234 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "using Pkg\n", + "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", + "Base.active_project()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1", + "metadata": {}, + "outputs": [], + "source": [ + "using GeneralizedPerturbedEquilibrium\n", + "using GeneralizedPerturbedEquilibrium: Analysis\n", + "using GeneralizedPerturbedEquilibrium: InnerLayer\n", + "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", + "using GeneralizedPerturbedEquilibrium: Tearing\n", + "using ..InnerLayer\n", + "using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters,\n", + " SLAYERModel, SLAYERParameters\n", + "\n", + "using Plots\n", + "using Printf\n", + "default(\n", + " fontfamily=\"Georgia\",\n", + " margin=12Plots.mm,\n", + " size=(800, 500),\n", + " dpi=150\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "struct TorqueBalance{M<:InnerLayerModel,P}\n", + " model::M\n", + " params::P\n", + " Q0::Float64\n", + " P::Float64\n", + " lu::Float64\n", + " sval::Float64\n", + "end\n", + "\n", + "function torque_balance_value(tb::TorqueBalance, Q::Number)\n", + " Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing\n", + " alpha = 1e-2\n", + " jxb = -imag(1.0 / (Δ + alpha))\n", + " return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ\n", + "end\n", + "\n", + "function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200)\n", + " Qs = range(Qmin, Qmax; length=n)\n", + " torque_out = [torque_balance_value(tb, q) for q in Qs]\n", + " bal = [x[1] for x in torque_out]\n", + " Δs = [x[2] for x in torque_out]\n", + " #bal = [torque_balance_value(tb, q) for q in Qs]\n", + " positive = isfinite.(bal) .& (bal .> 0.0)\n", + "\n", + " if !any(positive)\n", + " return Qs, bal, NaN, NaN, 0.0, NaN, NaN, Δs\n", + " end\n", + "\n", + " i = argmax(bal)\n", + " Qpeak_ind = i\n", + " Qs_positive = Qs[positive]\n", + " bal_positive = bal[positive]\n", + "\n", + "\n", + " \n", + " Qpeak = Qs_positive[i]\n", + " maxbal = bal_positive[i]\n", + "\n", + " br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", + " return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", + " n_e=1e19, t_e=1e3, t_i=1e3,\n", + " omega=0.0, omega_e=40, omega_i=-20,\n", + " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", + " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", + ")\n", + "p = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", + " ising=p.ising,\n", + " m=p.m, n=p.n,\n", + " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", + " P_perp=p.P_perp, P_tor=p.P_tor,\n", + " Q_e=2, Q_i=3, iota_e=p.iota_e,\n", + " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", + " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", + " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", + " eta=p.eta, d_beta=p.d_beta,\n", + " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", + ")\n", + "\n", + "tb = TorqueBalance(\n", + " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", + " p,\n", + " 0.5,\n", + " 61.0, #1.0\n", + " p.lu,\n", + " p.sval_r\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=-2.5, Qmax=0, n=20000)\n", + "\n", + "jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", + "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for q in Qs] #(q, jxb) in zip(Qs, jxbs)]\n", + "#br_t = brcrit\n", + "#println(tb.lu, \" \", tb.sval, \" \", br_t, \" \", p.bt, \" \", 1e-2)\n", + "#@printf(\"br_crit = %.5e\\n\", brcrit)\n", + "#T_EM = tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs\n", + "T_EM = -imag(1.0 ./ (Δs .+ 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", + "i = Qpeak_ind\n", + "println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", + "println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", + "println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", + "\n", + "#T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", + "#T_visc ∝ 2 P (Q0 − Q)\n", + "\n", + "xmi = -2.5\n", + "xma = 0\n", + "\n", + "\"\"\"\n", + "p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2, xlim=(xmi, xma))\n", + "#plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Δ\")\n", + "#title!(p1, \"Inner-layer Δ(Q)\")\n", + "\"\"\"\n", + "\n", + "p1 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(-1000,1000))\n", + "plot!(p1, Qs, T_EM, label=\"T_EM\", lw=2)\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "xlabel!(p1, \"Q\")\n", + "ylabel!(p1, \"Torque\")\n", + "\n", + "#p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + "p2 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(0,500))\n", + "plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", + "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + "xlabel!(p2, \"Q\")\n", + "ylabel!(p2, \"Torque\")\n", + "#title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", + "\n", + "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2, xlim=(xmi, xma))\n", + "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + "ylabel!(p3, \"Torque Balance\")\n", + "#title!(p3, \"2P(Q0-Q)/jxb\")\n", + "xlabel!(p3, \"Q\")\n", + "vline!([Qpeak], label=\"Max Balance\", linestyle=:dash)\n", + "\n", + "#plot(p1, p2, p3, layout=(3,1), size=(800, 1000))\n", + "plot(p3, layout=(1,1), size=(800, 1000))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "# compare Q_e to Q of max(bal)\n", + "println(\"-Q_e = \", -p.Q_e, \" Q_i = \", p.Q_i, \" Q_peak = \", Qpeak, \" br_crit = \", brcrit)\n", + "# check if |Qpeak+Q_e| < 1e-2\n", + "println(\"|Qpeak + Q_e| = \", abs(Qpeak + p.Q_e))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ + "# Check torque is balanced\n", + "\n", + "viscous_torque = 2*tb.P*(tb.Q0 - Qpeak)\n", + "electromagnetic_torque = -imag(1.0 / (Δs[Qpeak_ind] + 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", + "\n", + "# delta_n_p = 1e-2\n", + "# jxb = -imag(1.0 / (Δ + delta_n_p))\n", + "# bal = 2.0 * tb.P * (tb.Q0 - Q) / jxb\n", + "# br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", + "\n", + "@printf(\"br_crit = %.5e\\n\", brcrit)\n", + "@printf(\"viscous_torque = %.5e\\n\", viscous_torque)\n", + "@printf(\"electromagnetic_torque = %.5e\\n\", electromagnetic_torque)\n", + "@printf(\"ratio = %.10f\\n\", viscous_torque / electromagnetic_torque)" + ] + } + ], + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/Tearing/CriticalResonantField/CRF Dev/sample_number.jls b/src/Tearing/CriticalResonantField/CRF Dev/sample_number.jls new file mode 100644 index 0000000000000000000000000000000000000000..c320ccaa9d62b84e8037da421fd24ccf2da49346 GIT binary patch literal 68 ucmXr_@{wa 0.0)\n", - "\n", - " if !any(positive)\n", - " return Qs, bal, NaN, 0.0\n", - " end\n", - " i = argmax(bal)\n", - " Qpeak_ind = i\n", - " Qs_positive = Qs[positive]\n", - " bal_positive = bal[positive]\n", - "\n", - " i = argmax(bal_positive)\n", - " Qpeak = Qs_positive[i]\n", - " \n", - " maxbal = bal_positive[i]\n", - "\n", - " br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", - " return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3", - "metadata": {}, - "outputs": [], - "source": [ - "# You can substitute any valid SLAYERParameters you already have.\n", - "# This is just an example skeleton.\n", - "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", - " n_e=1e19, t_e=1e3, t_i=1e3,\n", - " omega=0.0, omega_e=4, omega_i=-2,\n", - " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", - " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", - ")\n", - "p2 = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", - " ising=p.ising,\n", - " m=p.m, n=p.n,\n", - " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", - " P_perp=p.P_perp, P_tor=p.P_tor,\n", - " Q_e=4 / p.tauk, Q_i=-10 / p.tauk, iota_e=p.iota_e,\n", - " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", - " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", - " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", - " eta=p.eta, d_beta=p.d_beta,\n", - " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", - ")\n", - "\n", - "#p = p2\n", - "\n", - "tb = TorqueBalance(\n", - " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", - " p,\n", - " 0.5,\n", - " 1.0,\n", - " p.lu,\n", - " p.sval_r\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4", - "metadata": {}, - "outputs": [], - "source": [ - "#Qs = range(-5.0, 5.0, length=200)\n", - "\n", - "#vals = [torque_balance_value(tb, q) for q in Qs]\n", - "\"\"\"\n", - "n=2000:\n", - "Qpeak = 0.24512256128064033\n", - "maxbal = 0.35873684252530247\n", - "br_crit = 4.668551985584323e-5\n", - "\n", - "n=200 (def):\n", - "Qpeak = 0.25125628140703515\n", - "maxbal = 0.3585219071071706\n", - "br_crit = 4.667153206033017e-5\n", - "\"\"\"\n", - "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb)\n", - "\n", - "println(\"Qpeak = \", Qpeak)\n", - "println(\"maxbal = \", maximum(bal_positive))\n", - "println(\"maxbal = \", maximum(bal))\n", - "println(\"br_crit = \", brcrit)\n", - "\n", - "p1 = plot(Qs, bal, lw=2, label=\"balance\")\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"balance\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "p2 = plot(Qs_positive, bal_positive, lw=2, label=\"balance (positive)\")\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"balance\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "plot(p1, p2, layout=(2,1), size=(800, 1000))\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5", - "metadata": {}, - "outputs": [], - "source": [ - "jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", - "\n", - "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Δ\")\n", - "title!(p1, \"Inner-layer Δ(Q)\")\n", - "\n", - "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - "xlabel!(p2, \"Q\")\n", - "ylabel!(p2, \"jxb\")\n", - "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", - "\n", - "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", - "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - "xlabel!(p3, \"Q\")\n", - "ylabel!(p3, \"balance\")\n", - "title!(p3, \"2P(Q0-Q)/jxb\")\n", - "\n", - "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6", - "metadata": {}, - "outputs": [], - "source": [ - "Qpk = Qs_positive[argmax(bal_positive)]\n", - "j = findfirst(isequal(Qpk), Qs)\n", - "\n", - "lhs = 2*tb.P*(tb.Q0 - Qpk) / jxbs[j]\n", - "br_ratio = sqrt(lhs / (tb.lu * tb.sval^2 / 2))\n", - "\n", - "rhs = (tb.lu * tb.sval^2 / 2) * br_ratio^2\n", - "\n", - "\n", - "\n", - "println(\"lhs = \", lhs)\n", - "println(\"rhs = \", rhs)\n", - "println(\"lhs/rhs = \", lhs / rhs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7", - "metadata": {}, - "outputs": [], - "source": [ - "#Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing for q in Qs]\n", - "jxbs = [-imag(1.0 / (d + tb.delta_n_p)) for d in Δs]\n", - "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for (q, jxb) in zip(Qs, jxbs)]\n", - "br_t = brcrit\n", - "println(tb.lu, \" \", tb.sval, \" \", br_t, \" \", p.bt, \" \", tb.delta_n_p)\n", - "T_EM = tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs\n", - "i = Qpeak_ind\n", - "println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", - "println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", - "println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", - "\n", - "#T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", - "#T_visc ∝ 2 P (Q0 − Q)\n", - "\n", - "p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", - "#plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Δ\")\n", - "title!(p1, \"Inner-layer Δ(Q)\")\n", - "\n", - "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - "plot!(p2, Qs, T_VISC, label=\"2P(Q0-Q)\", lw=2)\n", - "plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", - "xlabel!(p2, \"Q\")\n", - "ylabel!(p2, \"jxb\")\n", - "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", - "\n", - "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", - "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - "xlabel!(p3, \"Q\")\n", - "ylabel!(p3, \"balance\")\n", - "title!(p3, \"2P(Q0-Q)/jxb\")\n", - "\n", - "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8", - "metadata": {}, - "outputs": [], - "source": [ - "# Recreate Cihan's plot:\n", - "\n", - "using Plots\n", - "using DataInterpolations\n", - "\n", - "default(\n", - " fontfamily=\"Georgia\",\n", - " grid=false,\n", - " linewidth=2,\n", - " guidefontsize=26,\n", - " tickfontsize=18,\n", - " titlefontsize=30,\n", - " legendfontsize=18,\n", - " size=(1200, 800),\n", - " dpi=150\n", - ")\n", - "\n", - "# Build the critical boundary bcrit(Q0)\n", - "Q0_scan = range(-1.0, 4.5; length=80)\n", - "bcrit_curve = Float64[]\n", - "\n", - "for Q0 in Q0_scan\n", - " tbQ = TorqueBalance(\n", - " tb.model,\n", - " tb.params,\n", - " Float64(Q0),\n", - " tb.P,\n", - " tb.delta_n_p,\n", - " tb.lu,\n", - " tb.sval\n", - " )\n", - "\n", - " Qs, bal, Qs_pos, bal_pos, Qpeak, brcrit, Qpeak_ind, Δs =\n", - " torque_balance_scan(tbQ; Qmin=-10.0, Qmax=10.0, n=250)\n", - "\n", - " if isempty(bal_pos) || !all(isfinite.(bal_pos)) || maximum(bal_pos) <= 0\n", - " push!(bcrit_curve, NaN)\n", - " else\n", - " push!(bcrit_curve, brcrit)\n", - " end\n", - "end\n", - "\n", - "ok = isfinite.(bcrit_curve)\n", - "Q0_plot = Q0_scan[ok]\n", - "bcrit_plot = bcrit_curve[ok]\n", - "\n", - "perm = sortperm(Q0_plot)\n", - "Q0_plot = Q0_plot[perm]\n", - "bcrit_plot = bcrit_plot[perm]\n", - "\n", - "# Interpolate the boundary: bcrit = f(Q0)\n", - "curve_itp = LinearInterpolation(bcrit_plot, Q0_plot)\n", - "\n", - "# Full phase-box bounds\n", - "x0 = minimum(bcrit_plot) * 0.8\n", - "x1 = maximum(bcrit_plot) * 1.2\n", - "y0 = minimum(Q0_plot)\n", - "y1 = maximum(Q0_plot)\n", - "\n", - "xvals = range(x0, x1; length=350)\n", - "yvals = range(y0, y1; length=350)\n", - "\n", - "locked_mask = zeros(Float64, length(yvals), length(xvals))\n", - "for iy in eachindex(yvals)\n", - " y = yvals[iy]\n", - " for ix in eachindex(xvals)\n", - " x = xvals[ix]\n", - " # locked when bcrit exceeds the boundary for that Q0\n", - " locked_mask[iy, ix] = x >= curve_itp(y) ? 1.0 : 0.0\n", - " end\n", - "end\n", - "\n", - "p = contourf(\n", - " xvals, yvals, locked_mask',\n", - " levels=[-0.5, 0.5, 1.5],\n", - " c=[:navy, :firebrick],\n", - " colorbar=false,\n", - " xlabel=\"b_crit\",\n", - " ylabel=\"Q_0\",\n", - " title=\"Locked / unlocked region\",\n", - " framestyle=:box,\n", - " xlims=(x0, x1),\n", - " ylims=(y0, y1),\n", - " legend=false\n", - ")\n", - "\n", - "# Critical boundary\n", - "plot!(p, bcrit_plot, Q0_plot; lw=3, color=:black, label=\"critical boundary\")\n", - "\n", - "# Critical point\n", - "cp_idx = argmax(bcrit_plot)\n", - "cp_x = bcrit_plot[cp_idx]\n", - "cp_y = Q0_plot[cp_idx]\n", - "scatter!(p, [cp_x], [cp_y]; color=:gold, marker=:star5, ms=12, label=\"critical point\")\n", - "\n", - "# Single legend block with one entry per category\n", - "plot!(p, [NaN], [NaN]; color=:firebrick, lw=4, label=\"locked\")\n", - "plot!(p, [NaN], [NaN]; color=:navy, lw=4, label=\"unlocked\")\n", - "plot!(p, [NaN], [NaN]; color=:black, lw=3, label=\"critical boundary\")\n", - "scatter!(p, [NaN], [NaN]; color=:gold, marker=:star5, ms=12, label=\"critical point\")\n", - "\n", - "plot!(p; legend=:topright)\n", - "\n", - "display(p)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/src/Tearing/Runner/HDF5Output.jl b/src/Tearing/Runner/HDF5Output.jl index 02c3f5da9..006f2d079 100644 --- a/src/Tearing/Runner/HDF5Output.jl +++ b/src/Tearing/Runner/HDF5Output.jl @@ -82,6 +82,13 @@ function write_critical_resonant_field_hdf5!(parent::Union{HDF5.File,HDF5.Group} sg["balance_positive"] = d.balance_positive sg["Qpeak"] = d.Qpeak sg["br_crit"] = d.br_crit + + # Save inputs for analysis in post + for field in (:Q0, :P, :lu, :sval, :m, :n) + if field in keys(d) + sg[String(field)] = getfield(d, field) + end + end end end diff --git a/src/Tearing/Runner/run_slayer.jl b/src/Tearing/Runner/run_slayer.jl index 5c92691f5..3d51d4a11 100644 --- a/src/Tearing/Runner/run_slayer.jl +++ b/src/Tearing/Runner/run_slayer.jl @@ -472,10 +472,11 @@ end function run_critical_resonant_field(equil, intr, ctrl; dir_path="./", slayer_result=nothing) ctrl.enabled || return empty_critical_resonant_field_result() + profiles = load_kinetic_profiles(joinpath(dir_path, ctrl.profile_file)) + params = if slayer_result !== nothing && slayer_result.enabled && !isempty(slayer_result.params) slayer_result.params else - profiles = load_kinetic_profiles(joinpath(dir_path, ctrl.profile_file)) build_slayer_inputs(equil, intr.sing, profiles) end @@ -490,8 +491,9 @@ function run_critical_resonant_field(equil, intr, ctrl; dir_path="./", slayer_re scan_data = NamedTuple[] for (isurf, p) in enumerate(params) - # Fill in the actual per-surface drive from your model - Q0_here = 0.5 + psi_here = intr.sing[isurf].psifac + omega_here = profiles(psi_here).omega + Q0_here = p.tauk * omega_here P_here = 1.0 tb = TorqueBalance( @@ -512,21 +514,25 @@ function run_critical_resonant_field(equil, intr, ctrl; dir_path="./", slayer_re push!(Q0_vec, Q0_here) push!(P_vec, P_here) - if ctrl.store_scan - push!( - scan_data, - ( - surface=isurf, - Q=collect(Qs), - balance=collect(bal), - delta=collect(Δs), - Q_positive=collect(Qs_positive), - balance_positive=collect(bal_positive), - Qpeak=Qpeak, - br_crit=br_crit - ) - ) - end + scan_entry = ( + surface=isurf, + Q=collect(Qs), + balance=collect(bal), + delta=collect(Δs), + Q_positive=collect(Qs_positive), + balance_positive=collect(bal_positive), + Qpeak=Qpeak, + br_crit=br_crit, + Q0=Q0_here, + P=P_here, + lu=p.lu, + sval=p.sval_r, + m=p.m, + n=p.n, + params=p + ) + push!(scan_data, scan_entry) + end return CriticalResonantFieldResult( From 6f4a356483082f90baed0df5f3c45cd2bd9b08af Mon Sep 17 00:00:00 2001 From: ebursch <76970916+ebursch@users.noreply.github.com> Date: Wed, 19 Aug 2026 22:04:23 -0400 Subject: [PATCH 06/14] WIP - Minimal working version --- examples/DIIID-like_SLAYER_example/gpec.toml | 8 +- .../DIIID-like_SLAYER_example/slayer_ex.ipynb | 86 +++++- .../CRF Dev/P_eta_calc.ipynb | 279 ++++++++++++++++++ .../CRF Dev/bcrit_dev.ipynb | 4 +- .../CRF Dev/pole_testing.ipynb | 193 +++++++++++- .../CriticalResonantField/TorqueBalance.jl | 86 +++++- src/Tearing/Runner/Control.jl | 80 ++--- src/Tearing/Runner/HDF5Output.jl | 11 +- src/Tearing/Runner/Result.jl | 77 ++--- src/Tearing/Runner/Runner.jl | 1 + src/Tearing/Runner/run_slayer.jl | 225 ++++++++------ 11 files changed, 839 insertions(+), 211 deletions(-) create mode 100644 src/Tearing/CriticalResonantField/CRF Dev/P_eta_calc.ipynb diff --git a/examples/DIIID-like_SLAYER_example/gpec.toml b/examples/DIIID-like_SLAYER_example/gpec.toml index d5dfe09c3..618372d02 100644 --- a/examples/DIIID-like_SLAYER_example/gpec.toml +++ b/examples/DIIID-like_SLAYER_example/gpec.toml @@ -30,7 +30,7 @@ equal_arc_wall = true # Equal arc length distribution of nodes on wall [ForceFreeStates] force_termination = true # Run FFS + SLAYER, skip PerturbedEquilibrium -local_stability_flag = true # Perform local stability analysis (Mercier and ballooning) across the ψ profile +local_stability_flag = false # Perform local stability analysis (Mercier and ballooning) across the ψ profile vac_flag = true # Compute plasma, vacuum, and total energies for free-boundary modes psiedge = 0.99 # Edge dW scan band: diagnostic dW(ψ) computed for ψ ∈ [psiedge, psilim]; integration domain set by qhigh / psihigh / dmlim @@ -87,11 +87,11 @@ Q_im_range = [-0.5, 3.0] # Scan box in the normalized Q plane, Im(Q) axis nre = 41 # Grid resolution along the Re(Q) axis nim = 31 # Grid resolution along the Im(Q) axis -[CriticalResonantField] +[SLAYER.CriticalResonantField] # CriticalResonantField used to find the critical resonant field sufficent for tearing onset at each rational surface. enabled = true # Run CriticalResonantField analysis -inner_model = "slayer_fitzpatrick" # Inner-layer Δ(Q) model: "slayer_fitzpatrick", "ggj_shooting", or "ggj_galerkin" Qmin = -10 # Minimum rotation scanned Qmax = 10 # Maximum rotation scanned n = 200 # Number of rotation points scanned -profile_file = "../DIIID-like_ideal_example/TkMkr_D3Dlike_Hmode_kinetic.h5" # Kinetic-profile file (relative to the run dir), required when SLAYER is enabled +angular_momentum_diffusivity = [1.0,1.0,1.0,1.0,1.0,1.0] # Toroidal momentum diffusivity (if nothing, falls back on chi_perp ~ chi_e, electron thermal diffusivity) +store_scan = true # Per surface torque and inner layer quantities diff --git a/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb b/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb index 709891273..710608340 100644 --- a/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb +++ b/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb @@ -134,6 +134,90 @@ "id": "6", "metadata": {}, "outputs": [], + "source": [ + "# print all P values\n", + "println(\"\\nP values for each surface in the scan:\")\n", + "h5open(h5path, \"r\") do file\n", + " for i in 1:6\n", + " ss = \"surface_$i\"\n", + " if haskey(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"], ss)\n", + " P = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][ss][\"P\"])\n", + " println(\"Surface $i: P = $(join([@sprintf(\"%.2e\", x) for x in P], \" \"))\")\n", + " else\n", + " println(\"Surface $i: No data found.\")\n", + " end\n", + " end\n", + "end\n", + "# want to print chi_tor for each surface in the scan, need to use P = (4π * 1e-7) .* abs.(chi_sel) ./ η_neo, so chi_sel = P * η_neo / (4π * 1e-7)\n", + "println(\"\\nchi_tor values for each surface in the scan:\")\n", + "h5open(h5path, \"r\") do file\n", + " for i in 1:6\n", + " ss = \"surface_$i\"\n", + " if haskey(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"], ss)\n", + " P = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][ss][\"P\"])\n", + " η_neo = read(file[\"Tearing\"][\"PerSurface\"][\"eta\"])\n", + " chi_tor = P .* η_neo[i] ./ (4π * 1e-7)\n", + " println(\"Surface $i: chi_tor = $(join([@sprintf(\"%.2e\", x) for x in chi_tor], \" \"))\") \n", + " else\n", + " println(\"Surface $i: No data found.\")\n", + " end\n", + " end\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": {}, + "outputs": [], + "source": [ + "# plot jxb vs Qs for surface 1\n", + "# jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", + "surface_num = 2\n", + "h5open(h5path, \"r\") do file\n", + " Δs = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"delta\"])\n", + " Qs = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"Q\"])\n", + " bal = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"balance\"])\n", + " jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", + " aplot = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + " xlabel!(\"Q\")\n", + " ylabel!(\"jxb\")\n", + " title!(\"jxb vs Q for surface $(surface_num)\")\n", + " println(\"max of balance: \", maximum(bal))\n", + " println(\"max of jxb: \", maximum(jxbs))\n", + " println(\"bcrit: \", read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"]))\n", + " println(\"Qpeak: \", read(file[\"Tearing\"][\"CriticalResonantField\"][\"Qpeak\"]))\n", + " println(\"Q_e: \", read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"]))\n", + " # plot balance vs q with bcrit as vertical line\n", + " p2 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", + " plot!(p2, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + " xlabel!(p2, \"Q\")\n", + " ylabel!(p2, \"balance\")\n", + " title!(p2, \"2P(Q0-Q)/jxb - surface $(surface_num)\")\n", + " vline!(p2, [read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"])], label=\"bcrit\", lw=2, lc=:red)\n", + " # add Q_e as vertical line\n", + " vline!(p2, [read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"])[surface_num]], label=\"Q_e\", lw=2, lc=:green)\n", + " vline!(p2, [read(file[\"Tearing\"][\"PerSurface\"][\"Q_i\"])[surface_num]], label=\"Q_i\", lw=2, lc=:blue)\n", + "\n", + " display(aplot)\n", + " display(p2)\n", + "\n", + "end\n", + "\n", + "\"\"\"\n", + "Local maxima indices: [104, 103] with values: [80.15320925995013, 79.66428209429431] and corresponding Qs: [0.35175879396984927, 0.25125628140703515] closest Q to Q_e: -0.35175879396984927 closest Q to Q_i: 0.35175879396984927\n", + "Warning: The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead.\n", + "Selected local maximum index: 103 with value: 79.66428209429431 and corresponding Q: 0.25125628140703515\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], "source": [ "# Plot bcrit vs q surface\n", "\n", @@ -156,7 +240,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7", + "id": "9", "metadata": {}, "outputs": [], "source": [ diff --git a/src/Tearing/CriticalResonantField/CRF Dev/P_eta_calc.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/P_eta_calc.ipynb new file mode 100644 index 000000000..0639317bd --- /dev/null +++ b/src/Tearing/CriticalResonantField/CRF Dev/P_eta_calc.ipynb @@ -0,0 +1,279 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "using Pkg\n", + "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", + "Base.active_project()\n", + "\n", + "using Plots\n", + "using Printf" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1", + "metadata": {}, + "outputs": [], + "source": [ + "# Minimal Julia implementation of the `neo_2021` branch.\n", + "\n", + "# Inputs:\n", + "# Te : electron temperature [eV]\n", + "# ne : electron density [m^-3]\n", + "# Ti : ion temperature [eV]\n", + "# q : safety factor\n", + "# eps : inverse aspect ratio\n", + "# R : major radius [m]\n", + "# fT : trapped-particle fraction\n", + "# Zeff : effective charge\n", + "\n", + "# Output:\n", + "# σ_spitzer : Spitzer conductivity [1/(Ω m)]\n", + "# σ_neo : Redl 2021 neoclassical conductivity [1/(Ω m)]\n", + "\n", + "# All inputs can be scalars or arrays of the same size.\n", + "\n", + "function neoclassical_conductivity(\n", + " Te, ne, Ti, q, eps, R, fT, Zeff;\n", + " version = :neo_2021,\n", + ")\n", + "\n", + " # Coulomb logarithms\n", + " lnΛe = 23.5 .-\n", + " log.(sqrt.(ne ./ 1e6) .* Te.^(-5/4)) .-\n", + " sqrt.(1e-5 .+ (log.(Te) .- 2).^2 ./ 16)\n", + "\n", + " # Ion density.\n", + " #\n", + " # For the simple D + C model used in the original code:\n", + " # n_i = n_main + n_imp\n", + " #\n", + " # If only Zeff is supplied, the original function uses\n", + " # n_i = ne / Zeff\n", + " ni = ne ./ Zeff\n", + "\n", + " # With only Zeff available, Zdom = 1, giving\n", + " Zdom = 1.0\n", + "\n", + " # Average ion charge\n", + " Zavg = ne ./ ni\n", + "\n", + " # Koh effective ion charge\n", + " Zion = (Zdom^2 .* Zavg .* Zeff).^(1/4)\n", + "\n", + " # Ion Coulomb logarithm\n", + " lnΛi = 30.0 .-\n", + " log.(Zion.^3 .* sqrt.(ni) ./ Ti.^1.5)\n", + "\n", + " # Prevent pathological negative electron Coulomb logarithms\n", + " lnΛe_min = minimum(lnΛe[lnΛe .> 0])\n", + " lnΛe = max.(lnΛe, lnΛe_min)\n", + "\n", + " # Avoid eps = 0\n", + " eps_nz = copy(eps)\n", + " if any(eps .== 0)\n", + " eps_nz[eps .== 0] .= minimum(eps[eps .!= 0])\n", + " end\n", + "\n", + " # Electron collisionality, Eq. 18b\n", + " νe_star = 6.921e-18 .* abs.(q) .* R .* ne .* Zeff .* lnΛe ./\n", + " (Te.^2 .* eps_nz.^1.5)\n", + "\n", + " # Ion collisionality, Eq. 18c\n", + " νi_star = 4.90e-18 .* abs.(q) .* R .* ni .* Zion.^4 .* lnΛi ./\n", + " (Ti.^2 .* eps_nz.^1.5)\n", + "\n", + " # Sauter Eq. 18a\n", + " NZ(Z) = 0.58 + 0.74 ./ (0.76 + Z)\n", + "\n", + " σ_spitzer = 1.9012e4 .* Te.^1.5 ./\n", + " (Zeff .* NZ(Zeff) .* lnΛe)\n", + "\n", + " # Redl 2021, Eq. 18\n", + " f33teff = fT ./ (\n", + " 1 .+\n", + " 0.25 .* (1 .- 0.7 .* fT) .* sqrt.(νe_star) .*\n", + " (1 .+ 0.45 .* sqrt.(Zeff .- 1)) .+\n", + " 0.61 .* (1 .- 0.41 .* fT) .* νe_star ./ sqrt.(Zeff)\n", + " )\n", + "\n", + " # Redl 2021, Eq. 17\n", + " F33 = 1 .-\n", + " (1 .+ 0.21 ./ Zeff) .* f33teff .+\n", + " 0.54 ./ Zeff .* f33teff.^2 .-\n", + " 0.33 ./ Zeff .* f33teff.^3\n", + "\n", + " σ_neo = σ_spitzer .* F33\n", + "\n", + " return σ_neo, σ_spitzer\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "function calc_resistivity_P(chi, ne, Te, Zeff, q, eps, R, fT, volume;\n", + " model=:neoclassical)\n", + " cond = neoclassical_conductivity(\n", + " Te=Te,\n", + " ne=ne,\n", + " Ti=Te,\n", + " Zeff=Zeff,\n", + " q=q,\n", + " eps=eps,\n", + " R=R,\n", + " fT=fT,\n", + " volume=volume,\n", + " version=:neo_2021,\n", + " )\n", + "\n", + " σ = model == :neoclassical ?\n", + " cond.neoclassical_conductivity :\n", + " cond.spitzer_conductivity\n", + "\n", + " η = 1 ./ σ\n", + " P = (4π * 1e-7) .* abs.(chi) ./ η\n", + "\n", + " return η, P\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "σ_neo, σ_spitzer = neoclassical_conductivity(\n", + " Te_eV,\n", + " ne_sel,\n", + " Te_eV, # Ti = Te\n", + " qsing,\n", + " eps_sel,\n", + " R_sel,\n", + " fT_sel;\n", + " Zeff=zeff_sel,\n", + ")\n", + "\n", + "η_neo = 1.0 ./ σ_neo\n", + "η_spitzer = 1.0 ./ σ_spitzer\n", + "\n", + "P = (4π * 1e-7) .* abs.(chi_sel) ./ η_neo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "σ_neo, σ_spitzer = neoclassical_conductivity(\n", + " 106.211805100300, # Te [eV]\n", + " 1.005827348013049e19, # ne [m^-3]\n", + " 106.211805100300, # Ti [eV]\n", + " 6.00000000000048, # q\n", + " 0.771873939341347 / 1.74333594120074, # eps = rs / R0\n", + " 1.74333594120074, # R [m]\n", + " 1, #fT; # trapped fraction\n", + " 1.80427095488192, # Zeff\n", + ")\n", + "\n", + "η_neo = 1.0 ./ σ_neo\n", + "η_spitzer = 1.0 ./ σ_spitzer\n", + "\n", + "chi_sel = 1\n", + "\n", + "P = (4π * 1e-7) .* abs.(chi_sel) ./ η_neo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "using LinearAlgebra # or relevant module providing neoclassical_conductivity\n", + "\n", + "# --- Set 1 Inputs (5 radial points) ---\n", + "Te_eV = [718.04269217, 342.58020426, 188.39435197, 95.70267912, 44.04668565] # Te and Ti [eV]\n", + "ne_sel = [1.98796958e19, 1.80371630e19, 1.55527262e19, 1.23649097e19, 8.97867646e18] # ne [m^-3]\n", + "zeff_sel = [1.65619282, 1.64427584, 1.58198407, 1.55990923, 1.68572562] # Zeff\n", + "qsing = [2.0, 3.0, 4.0, 5.0, 6.0] # q\n", + "eps_sel = [0.22284171, 0.28956909, 0.32302672, 0.34432513, 0.35141583] # eps = r/R\n", + "R_sel = [1.72151657, 1.70693349, 1.69832026, 1.69192129, 1.68947514] # R [m]\n", + "fT_sel = [0.6127298, 0.66890766, 0.68553652, 0.68355803, 0.67414449] # Trapped fraction fT\n", + "\n", + "# Reference values from Python NCLASS run (for validation)\n", + "py_neo = [7683580.66632273, 3011088.07938057, 1644303.89021149, 782055.27991453, 274193.4323623]\n", + "py_spitzer = [16324797.88300323, 5666135.22162908, 2468477.31865855, 941040.7938515, 290205.76181926]\n", + "\n", + "# --- Run Neoclassical Conductivity in Julia ---\n", + "# Broadcasting across all 5 radial positions:\n", + "σ_neo, σ_spitzer = neoclassical_conductivity.(\n", + " Te_eV, # Te [eV]\n", + " ne_sel, # ne [m^-3]\n", + " Te_eV, # Ti [eV] (assumed Ti = Te)\n", + " qsing, # q\n", + " eps_sel, # eps\n", + " R_sel, # R [m]\n", + " fT_sel, # trapped fraction fT\n", + " zeff_sel # Zeff\n", + ")\n", + "\n", + "# Collect tuple outputs into a vector of tuples\n", + "results = [\n", + " neoclassical_conductivity(\n", + " Te_eV[i], ne_sel[i], Te_eV[i], qsing[i], \n", + " eps_sel[i], R_sel[i], fT_sel[i], zeff_sel[i]\n", + " ) for i in 1:length(Te_eV)\n", + "]\n", + "\n", + "# Extract σ_neo (1st element) and σ_spitzer (2nd element)\n", + "σ_neo = getindex.(results, 1)\n", + "σ_spitzer = getindex.(results, 2)\n", + "\n", + "η_neo = 1.0 ./ σ_neo\n", + "η_spitzer = 1.0 ./ σ_spitzer\n", + "\n", + "chi_sel = 1\n", + "P = (4π * 1e-7) .* abs.(chi_sel) ./ η_neo\n", + "\n", + "\n", + "# --- Comparison Printouts ---\n", + "println(\"=== Neoclassical Conductivity Comparison ===\")\n", + "for i in 1:length(Te_eV)\n", + " println(\"Point $i (q=$(qsing[i])):\")\n", + " println(\" Julia σ_neo : \", σ_neo[i])\n", + " println(\" Python σ_neo : \", py_neo[i])\n", + " println(\" Julia σ_spitzer : \", σ_spitzer[i])\n", + " println(\" Python σ_spitzer: \", py_spitzer[i])\n", + " println(\" P (magnetic diff): \", P[i])\n", + " println()\n", + "end" + ] + } + ], + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb index 528ca4934..5f9dfac2a 100644 --- a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb +++ b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb @@ -132,7 +132,7 @@ " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", " p,\n", " 0.5,\n", - " 61.0, #1.0\n", + " p.P_tor,\n", " p.lu,\n", " p.sval_r\n", ")" @@ -162,7 +162,7 @@ "Qmi = -10\n", "Qma = 10\n", "\n", - "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qmi, Qmax=Qma, n=10000)\n", + "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qmi, Qmax=Qma, n=100)\n", "\n", "println(\"Qpeak = \", Qpeak)\n", "println(\"maxbal = \", maximum(bal_positive))\n", diff --git a/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb index 329e9dd53..d7f16a2b4 100644 --- a/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb +++ b/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb @@ -61,30 +61,81 @@ " return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ\n", "end\n", "\n", - "function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200)\n", + "function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=20000)\n", " Qs = range(Qmin, Qmax; length=n)\n", " torque_out = [torque_balance_value(tb, q) for q in Qs]\n", " bal = [x[1] for x in torque_out]\n", " Δs = [x[2] for x in torque_out]\n", - " #bal = [torque_balance_value(tb, q) for q in Qs]\n", " positive = isfinite.(bal) .& (bal .> 0.0)\n", "\n", " if !any(positive)\n", - " return Qs, bal, NaN, NaN, 0.0, NaN, NaN, Δs\n", + " @warn \"No positive torque balance found in the specified range. Try increasing the number of Q samples scanned or adjusting the range.\"\n", + " return Qs, bal, NaN, NaN, NaN, Δs\n", " end\n", "\n", - " i = argmax(bal)\n", - " Qpeak_ind = i\n", - " Qs_positive = Qs[positive]\n", - " bal_positive = bal[positive]\n", + " # Find the highest point, then remove candidates within ΔQ of it.\n", "\n", + " idx_maxima = findall(isfinite.(bal) .& (bal .> 0))\n", + " sort!(idx_maxima, by=i -> bal[i], rev=true)\n", + " selected = Int[]\n", + " min_ΔQ = 0.001 * abs(Qmax - Qmin)\n", "\n", + " for i in idx_maxima\n", + " if all(abs(Qs[i] - Qs[j]) > min_ΔQ for j in selected)\n", + " push!(selected, i)\n", + " end\n", + " length(selected) == 2 && break\n", + " end\n", + "\n", + " if isempty(selected)\n", + " @warn \"No usable positive torque-balance maximum found. Try increasing the number of Q samples scanned or adjusting the range.\"\n", + " return Qs, bal, NaN, NaN, NaN, Δs\n", + " end\n", + "\n", + " idx_maxima = selected\n", + "\n", + "\n", + " # Find all local maxima in the positive region\n", + " #idx_positive = findall(positive)\n", + " #idx_maxima = idx_positive[partialsortperm(bal[idx_positive], 1:min(2, length(idx_positive)); rev=true)]\n", + " maxima = bal[idx_maxima]\n", + " Qs_maxima = Qs[idx_maxima]\n", + " # find index, q val and bal val of the q closest to Q_e\n", + " idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e)) # + Q_e since Q_e = -omega_e * Qconv\n", + " q_closest_Q_e = Qs[idx_closest_Q_e]\n", + " bal_closest_Q_e = bal[idx_closest_Q_e]\n", + "\n", + " # find index, q val and bal val of the q closest to Q_i\n", + " idx_closest_Q_i = argmin(abs.(Qs .+ tb.params.Q_i)) # + Q_i since Q_i = -omega_i * Qconv\n", + " q_closest_Q_i = Qs[idx_closest_Q_i]\n", + " bal_closest_Q_i = bal[idx_closest_Q_i]\n", " \n", - " Qpeak = Qs_positive[i]\n", - " maxbal = bal_positive[i]\n", + " println(\"Local maxima indices: \", idx_maxima, \" with values: \", maxima, \" and corresponding Qs: \", Qs_maxima, \" closest Q to Q_e: \", q_closest_Q_e, \" closest Q to Q_i: \", q_closest_Q_i)\n", + " # check if 1st q_maxima is same as Q_e or Q_i from p\n", + " if idx_maxima[1] == idx_closest_Q_e || idx_maxima[1] == idx_closest_Q_i\n", + " if length(idx_maxima) < 2\n", + " @warn \"The first local maximum corresponds to a pole from Q_e or Q_i, but there is no second local maximum to select. Try increasing the number of Q samples scanned or adjusting the range.\"\n", + " return Qs, bal, NaN, NaN, NaN, Δs\n", + " end\n", + " println(\"Warning: The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead.\")\n", + " if idx_maxima[2] == idx_closest_Q_e || idx_maxima[2] == idx_closest_Q_i\n", + " @warn \"Both the first and second local maxima correspond to poles from Q_e or Q_i. Unable to select a valid local maximum. Try increasing the number of Q samples scanned or adjusting the range.\"\n", + " return Qs, bal, NaN, NaN, NaN, Δs\n", + " end\n", + " idx_maximum = idx_maxima[2]\n", + " maximum = bal[idx_maximum]\n", + " Qmaximum = Qs[idx_maximum]\n", + " else\n", + " idx_maximum = idx_maxima[1]\n", + " maximum = bal[idx_maximum]\n", + " Qmaximum = Qs[idx_maximum]\n", + " end\n", + "\n", + " println(\"Selected local maximum index: \", idx_maximum, \" with value: \", maximum, \" and corresponding Q: \", Qmaximum)\n", "\n", - " br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", - " return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs\n", + " br_crit = sqrt(maximum / tb.lu * (tb.sval^2 / 2.0))\n", + "\n", + " return Qs, bal, Qmaximum, br_crit, idx_maximum, Δs\n", "end" ] }, @@ -131,9 +182,97 @@ "metadata": {}, "outputs": [], "source": [ + "Qs, bal, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=-2.5, Qmax=0, n=200000)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "Qmax = 10\n", + "Qmin = -10\n", + "positive = isfinite.(bal) .& (bal .> 0.0)\n", + "\n", + "if !any(positive)\n", + " @warn \"No positive torque balance found in the specified range. Try increasing the number of Q samples scanned or adjusting the range.\"\n", + " return Qs, bal, NaN, NaN, NaN, Δs\n", + "end\n", + "\n", + "# Find the highest point, then remove candidates within ΔQ of it.\n", + "\n", + "idx_maxima = findall(isfinite.(bal) .& (bal .> 0))\n", + "sort!(idx_maxima, by=i -> bal[i], rev=true)\n", + "selected = Int[]\n", + "min_ΔQ = 0.001 * abs(Qmax - Qmin)\n", + "\n", + "for i in idx_maxima\n", + " if all(abs(Qs[i] - Qs[j]) > min_ΔQ for j in selected)\n", + " push!(selected, i)\n", + " end\n", + " length(selected) == 2 && break\n", + "end\n", + "\n", + "if isempty(selected)\n", + " @warn \"No usable positive torque-balance maximum found. Try increasing the number of Q samples scanned or adjusting the range.\"\n", + " return Qs, bal, NaN, NaN, NaN, Δs\n", + "end\n", "\n", - "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=-2.5, Qmax=0, n=20000)\n", + "idx_maxima = selected\n", "\n", + "\n", + "# Find all local maxima in the positive region\n", + "#idx_positive = findall(positive)\n", + "#idx_maxima = idx_positive[partialsortperm(bal[idx_positive], 1:min(2, length(idx_positive)); rev=true)]\n", + "maxima = bal[idx_maxima]\n", + "Qs_maxima = Qs[idx_maxima]\n", + "# find index, q val and bal val of the q closest to Q_e\n", + "idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e)) # + Q_e since Q_e = -omega_e * Qconv\n", + "q_closest_Q_e = Qs[idx_closest_Q_e]\n", + "bal_closest_Q_e = bal[idx_closest_Q_e]\n", + "\n", + "# find index, q val and bal val of the q closest to Q_i\n", + "idx_closest_Q_i = argmin(abs.(Qs .+ tb.params.Q_i)) # + Q_i since Q_i = -omega_i * Qconv\n", + "q_closest_Q_i = Qs[idx_closest_Q_i]\n", + "bal_closest_Q_i = bal[idx_closest_Q_i]\n", + "\n", + "println(\"Local maxima indices: \", idx_maxima, \" with values: \", maxima, \" and corresponding Qs: \", Qs_maxima, \" closest Q to Q_e: \", q_closest_Q_e, \" closest Q to Q_i: \", q_closest_Q_i)\n", + "# check if 1st q_maxima is same as Q_e or Q_i from p\n", + "if idx_maxima[1] == idx_closest_Q_e || idx_maxima[1] == idx_closest_Q_i\n", + " if length(idx_maxima) < 2\n", + " @warn \"The first local maximum corresponds to a pole from Q_e or Q_i, but there is no second local maximum to select. Try increasing the number of Q samples scanned or adjusting the range.\"\n", + " return Qs, bal, NaN, NaN, NaN, Δs\n", + " end\n", + " println(\"Warning: The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead.\")\n", + " if idx_maxima[2] == idx_closest_Q_e || idx_maxima[2] == idx_closest_Q_i\n", + " @warn \"Both the first and second local maxima correspond to poles from Q_e or Q_i. Unable to select a valid local maximum. Try increasing the number of Q samples scanned or adjusting the range.\"\n", + " return Qs, bal, NaN, NaN, NaN, Δs\n", + " end\n", + " idx_maximum = idx_maxima[2]\n", + " maximum = bal[idx_maximum]\n", + " Qmaximum = Qs[idx_maximum]\n", + "else\n", + " idx_maximum = idx_maxima[1]\n", + " maximum = bal[idx_maximum]\n", + " Qmaximum = Qs[idx_maximum]\n", + "end\n", + "\n", + "println(\"Selected local maximum index: \", idx_maximum, \" with value: \", maximum, \" and corresponding Q: \", Qmaximum)\n", + "\n", + "br_crit = sqrt(maximum / tb.lu * (tb.sval^2 / 2.0))\n", + "\n", + "println(Qmaximum, br_crit, idx_maximum)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [ "jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for q in Qs] #(q, jxb) in zip(Qs, jxbs)]\n", "#br_t = brcrit\n", @@ -174,13 +313,27 @@ "ylabel!(p2, \"Torque\")\n", "#title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", "\n", - "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2, xlim=(xmi, xma))\n", + "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2, xlim=(xmi, xma)) #xlim=(-1.3,-.8),ylim=(375,389))#\n", "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + "loc_max_ind= [4001, 10050, 10094, 10186, 10195, 10213, 10258, 10272, 10340, 10355, 10365, 10376, 10385, 10387, 10392, 10405, 10412, 10421, 10430, 10443, 10450, 10457, 10470, 10473, 10494, 10498, 10512, 10520, 10537, 10544, 10552, 10557, 10573, 10576, 10578, 10586, 10588, 10596, 10606, 10610, 10632, 10637, 10648, 10655, 10659, 10665, 10670, 10676, 10679, 10691, 10695, 10697, 10705, 10707, 10719, 10730, 10742, 10746, 10751, 10755, 10761, 10765, 10770, 10776, 10778, 10783, 10786, 10788, 10793, 10798, 10810, 10814, 10821, 10824, 10829, 10834, 10837, 10841, 10843, 10847, 10849, 10856, 10858, 10861, 10863, 10868, 10871, 10877, 10881, 10887, 10892, 10895, 10897, 10900, 10904, 10906, 10909, 10911, 10916, 10918, 10923, 10929, 10931, 10933, 10937, 10942, 10945, 10950, 10955, 10959, 10963, 10969, 10971, 10974, 10976, 10981, 10984, 10988, 10991, 10994, 10997, 11001, 11003, 11005, 11012, 11015, 11018, 11021, 11024, 11027, 11029, 11031, 11033, 11036, 11039, 11042, 11044, 11048, 11053, 11056, 11058, 11060, 11062, 11064, 11068, 11078, 11080, 11083, 11085, 11096, 11098, 11100, 11102, 11104, 11106, 11109, 11111, 11116, 11119, 11121, 11128, 11131, 11133, 11139, 11145, 11148, 11150, 11152, 11155, 11157, 11162, 11165, 11169, 11174, 11180, 11183, 11186, 11188, 11205, 11218, 11220, 11222, 11224, 11228, 11233, 11235, 11243, 11249, 11254, 11257, 11259, 11276, 11281, 11294, 11299, 11303, 11306, 11312, 11316, 11319, 11322, 11335, 11341, 11358, 11369, 11376, 11381, 11386, 11391, 11394, 11396, 11399, 11406, 11410, 11417, 11420, 11422, 11428, 11437, 11446, 11448, 11453, 11457, 11469, 11473, 11486, 11497, 11513, 11540, 11542, 11544, 11552, 11554, 11565, 11570, 11573, 11578, 11587, 11594, 11597, 11602, 11614, 11620, 11633, 11654, 11660, 11662, 11669, 11677, 11682, 11687, 11711, 11764, 11804, 11806, 11821, 11848, 11860, 11882, 11901, 11928, 11991, 12108]\n", + "#plot!(p3, Qs[loc_max_ind], bal[loc_max_ind], seriestype=:scatter, label=\"Local Maxima\", color=:red)\n", + "loc_mx2 = [4001, 10963, 10955, 10950, 11005]\n", + "#plot!(p3, Qs[loc_mx2], bal[loc_mx2], seriestype=:scatter, label=\"Local Maxima 2\", color=:green)\n", "ylabel!(p3, \"Torque Balance\")\n", "#title!(p3, \"2P(Q0-Q)/jxb\")\n", "xlabel!(p3, \"Q\")\n", "vline!([Qpeak], label=\"Max Balance\", linestyle=:dash)\n", "\n", + "# find index, q val and bal val of the q closest to Q_e\n", + "println(\"Q_e: \", -tb.params.Q_e)\n", + "idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e))\n", + "q_closest_Q_e = Qs[idx_closest_Q_e]\n", + "bal_closest_Q_e = bal[idx_closest_Q_e]\n", + "println(\"Closest Q to Q_e: \", q_closest_Q_e, \" with balance value: \", bal_closest_Q_e, \" at index: \", idx_closest_Q_e)\n", + "println(\"B crit: \", brcrit)\n", + "vline!([-tb.params.Q_e], label=\"Q_e\", linestyle=:dashdot, color=:orange)\n", + "vline!([q_closest_Q_e], label=\"Closest Q to Q_e\", linestyle=:dashdot, color=:purple)\n", + "\n", "#plot(p1, p2, p3, layout=(3,1), size=(800, 1000))\n", "plot(p3, layout=(1,1), size=(800, 1000))" ] @@ -188,20 +341,28 @@ { "cell_type": "code", "execution_count": null, - "id": "5", + "id": "7", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", "metadata": {}, "outputs": [], "source": [ "# compare Q_e to Q of max(bal)\n", "println(\"-Q_e = \", -p.Q_e, \" Q_i = \", p.Q_i, \" Q_peak = \", Qpeak, \" br_crit = \", brcrit)\n", "# check if |Qpeak+Q_e| < 1e-2\n", - "println(\"|Qpeak + Q_e| = \", abs(Qpeak + p.Q_e))" + "println(\"|Qpeak + Q_e| = \", abs(Qpeak + p.Q_e))\n" ] }, { "cell_type": "code", "execution_count": null, - "id": "6", + "id": "9", "metadata": {}, "outputs": [], "source": [ diff --git a/src/Tearing/CriticalResonantField/TorqueBalance.jl b/src/Tearing/CriticalResonantField/TorqueBalance.jl index fbafddc4a..cd74535ea 100644 --- a/src/Tearing/CriticalResonantField/TorqueBalance.jl +++ b/src/Tearing/CriticalResonantField/TorqueBalance.jl @@ -55,7 +55,7 @@ Returns the Q values, torque balance values, positive Q values, positive torque the Q value at the peak, the critical resonant field, the index of the peak Q value, and the Δ values for each Q. """ -function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200) +function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=20000) Qs = range(Qmin, Qmax; length=n) torque_out = [torque_balance_value(tb, q) for q in Qs] bal = [x[1] for x in torque_out] @@ -63,24 +63,78 @@ function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200) positive = isfinite.(bal) .& (bal .> 0.0) if !any(positive) - return Qs, bal, [0.0], [0.0], 0.0, 0.0, NaN, Δs + @warn "No positive torque balance found in the specified range. Try increasing the number of Q samples scanned or adjusting the range." + return Qs, bal, NaN, NaN, NaN, Δs end - i = argmax(bal) - Qpeak_ind = i - Qpeak = Qs[i] - maxbal = bal[i] - Qs_positive = Qs[positive] - bal_positive = bal[positive] + # Find the highest point, then remove candidates within ΔQ of it. + idx_maxima = findall(isfinite.(bal) .& (bal .> 0)) + sort!(idx_maxima; by=i -> bal[i], rev=true) + selected = Int[] + min_ΔQ = 0.001 * abs(Qmax - Qmin) - i = argmax(bal_positive) - #Qpeak = Qs_positive[i] + for i in idx_maxima + if all(abs(Qs[i] - Qs[j]) > min_ΔQ for j in selected) + push!(selected, i) + end + length(selected) == 2 && break + end - #maxbal = bal_positive[i] + if isempty(selected) + @warn "No usable positive torque-balance maximum found. Try increasing the number of Q samples scanned or adjusting the range." + return Qs, bal, NaN, NaN, NaN, Δs + end - br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0)) - return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs -end + idx_maxima = selected + maxima = bal[idx_maxima] + Qs_maxima = Qs[idx_maxima] + + # find index, q val and bal val of the q closest to Q_e + idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e)) # + Q_e since Q_e = -omega_e * Qconv + q_closest_Q_e = Qs[idx_closest_Q_e] + bal_closest_Q_e = bal[idx_closest_Q_e] + + # find index, q val and bal val of the q closest to Q_i + idx_closest_Q_i = argmin(abs.(Qs .+ tb.params.Q_i)) # + Q_i since Q_i = -omega_i * Qconv + q_closest_Q_i = Qs[idx_closest_Q_i] + bal_closest_Q_i = bal[idx_closest_Q_i] + + println( + "Local maxima indices: ", + idx_maxima, + " with values: ", + maxima, + " and corresponding Qs: ", + Qs_maxima, + " closest Q to Q_e: ", + q_closest_Q_e, + " closest Q to Q_i: ", + q_closest_Q_i + ) -# Need to fix and improve this function. The positive masking is not helpful. -# Need to avoid poles from Q_e and Q_i. + # check if 1st q_maxima is same as Q_e or Q_i from p + if idx_maxima[1] == idx_closest_Q_e || idx_maxima[1] == idx_closest_Q_i + if length(idx_maxima) < 2 + @warn "The first local maximum corresponds to a pole from Q_e or Q_i, but there is no second local maximum to select. Try increasing the number of Q samples scanned or adjusting the range." + return Qs, bal, NaN, NaN, NaN, Δs + end + println("Warning: The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead.") + if idx_maxima[2] == idx_closest_Q_e || idx_maxima[2] == idx_closest_Q_i + @warn "Both the first and second local maxima correspond to poles from Q_e or Q_i. Unable to select a valid local maximum. Try increasing the number of Q samples scanned or adjusting the range." + return Qs, bal, NaN, NaN, NaN, Δs + end + idx_maximum = idx_maxima[2] + maximum = bal[idx_maximum] + Qmaximum = Qs[idx_maximum] + else + idx_maximum = idx_maxima[1] + maximum = bal[idx_maximum] + Qmaximum = Qs[idx_maximum] + end + + println("Selected local maximum index: ", idx_maximum, " with value: ", maximum, " and corresponding Q: ", Qmaximum) + + br_crit = sqrt(maximum / tb.lu * (tb.sval^2 / 2.0)) + + return Qs, bal, Qmaximum, br_crit, idx_maximum, Δs +end diff --git a/src/Tearing/Runner/Control.jl b/src/Tearing/Runner/Control.jl index 88e8fe091..bbf297975 100644 --- a/src/Tearing/Runner/Control.jl +++ b/src/Tearing/Runner/Control.jl @@ -7,6 +7,41 @@ # # `CriticalResonantFieldControl` holds the user-facing knobs that drive the critical resonant field # analysis. Populated either directly via the `@kwdef` constructor or by parsing the `[CriticalResonantField]` section of a `gpec.toml`. +""" + CriticalResonantFieldControl + +Configuration for the critical resonant field analysis. All fields are +user-facing: read from the `[CriticalResonantField]` TOML section of a `gpec.toml` via +`critical_resonant_field_control_from_toml`, or built directly via the `@kwdef` keyword +constructor. +""" +@kwdef struct CriticalResonantFieldControl + enabled::Bool = false + Qmin::Float64 = -10.0 + Qmax::Float64 = 10.0 + n::Int = 200 + angular_momentum_diffusivity::Union{Float64,Vector{Float64}} = 1.0 + store_scan::Bool = false +end + +function critical_resonant_field_control_from_toml(section::AbstractDict) + flat = Dict{String,Any}() + for (k, v) in section + flat[k] = v + end + + kwargs = Dict{Symbol,Any}() + for (k, v) in flat + sym = Symbol(k) + if sym in (:inner_model,) + kwargs[sym] = v isa Symbol ? v : Symbol(String(v)) + else + kwargs[sym] = v + end + end + + return CriticalResonantFieldControl(; kwargs...) +end """ SLAYERControl @@ -158,6 +193,9 @@ there is one consistent interface for resistive and kinetic profiles. profile_group::String = "/" store_scan::Bool = false + + # Critical resonant field analysis. Enabled via `[SLAYER.CriticalResonantField]` TOML section. + critical_resonant_field::CriticalResonantFieldControl = CriticalResonantFieldControl() end const _VALID_INNER_MODELS = (:slayer_fitzpatrick, :ggj_shooting, :ggj_galerkin) @@ -227,6 +265,10 @@ function slayer_control_from_toml(section::AbstractDict) haskey(v, "pole_threshold") && (flat["pole_threshold"] = v["pole_threshold"]) haskey(v, "filter_above_poles") && (flat["filter_above_poles"] = v["filter_above_poles"]) haskey(v, "filter_outside_re") && (flat["filter_outside_re"] = v["filter_outside_re"]) + elseif k == "CriticalResonantField" && v isa AbstractDict + flat["critical_resonant_field"] = + critical_resonant_field_control_from_toml(v) + else flat[k] = v end @@ -271,41 +313,3 @@ function slayer_control_from_toml(section::AbstractDict) end return validate(SLAYERControl(; kwargs...)) end - -""" - CriticalResonantFieldControl - -Configuration for the critical resonant field analysis. All fields are -user-facing: read from the `[CriticalResonantField]` TOML section of a `gpec.toml` via -`critical_resonant_field_control_from_toml`, or built directly via the `@kwdef` keyword -constructor. -""" -@kwdef struct CriticalResonantFieldControl - enabled::Bool = false - inner_model::Symbol = :slayer_fitzpatrick - Qmin::Float64 = -10.0 - Qmax::Float64 = 10.0 - n::Int = 200 - profile_file::String = "" - profile_group::String = "/" - store_scan::Bool = false -end - -function critical_resonant_field_control_from_toml(section::AbstractDict) - flat = Dict{String,Any}() - for (k, v) in section - flat[k] = v - end - - kwargs = Dict{Symbol,Any}() - for (k, v) in flat - sym = Symbol(k) - if sym in (:inner_model,) - kwargs[sym] = v isa Symbol ? v : Symbol(String(v)) - else - kwargs[sym] = v - end - end - - return CriticalResonantFieldControl(; kwargs...) -end diff --git a/src/Tearing/Runner/HDF5Output.jl b/src/Tearing/Runner/HDF5Output.jl index 006f2d079..2ae545211 100644 --- a/src/Tearing/Runner/HDF5Output.jl +++ b/src/Tearing/Runner/HDF5Output.jl @@ -38,6 +38,10 @@ function write_slayer_hdf5!(parent::Union{HDF5.File,HDF5.Group}, # disjoint field sets, so readers must not have to infer it from the schema. attrs(g)["layer_model"] = result.enabled ? _layer_model_token(eltype(result.params)) : "none" + if result.critical_resonant_field.enabled + write_critical_resonant_field_hdf5!(g, result.critical_resonant_field) + end + if !result.enabled # nothing else to write _annotate_tearing!(g) return g @@ -60,10 +64,7 @@ end function write_critical_resonant_field_hdf5!(parent::Union{HDF5.File,HDF5.Group}, result::CriticalResonantFieldResult) - if !haskey(parent, "Tearing") - create_group(parent, "Tearing") - end - g = create_group(parent["Tearing"], "CriticalResonantField") + g = create_group(parent, "CriticalResonantField") g["surface_index"] = result.surface_index g["Qpeak"] = result.Qpeak @@ -78,8 +79,6 @@ function write_critical_resonant_field_hdf5!(parent::Union{HDF5.File,HDF5.Group} sg["Q"] = d.Q sg["balance"] = d.balance sg["delta"] = d.delta - sg["Q_positive"] = d.Q_positive - sg["balance_positive"] = d.balance_positive sg["Qpeak"] = d.Qpeak sg["br_crit"] = d.br_crit diff --git a/src/Tearing/Runner/Result.jl b/src/Tearing/Runner/Result.jl index 9132e8421..df68bb868 100644 --- a/src/Tearing/Runner/Result.jl +++ b/src/Tearing/Runner/Result.jl @@ -8,6 +8,37 @@ # per-surface critical resoant field. If `control.store_scan` is true, the full Q scan data, # viscous torque, and electromagnetic torque are also stored for plotting. +""" + CriticalResonantFieldResult + +Output of `run_critical_resonant_field`. Carries both summary critical resonant field values and if `control.store_scan` is true, the full Q scan data, viscous torque, and electromagnetic torque for plotting. +""" + +struct CriticalResonantFieldResult + enabled::Bool + params::AbstractVector{<:InnerLayerParameters} + surface_index::Vector{Int} + Qpeak::Vector{Float64} + br_crit::Vector{Float64} + Q0::Vector{Float64} + P::Vector{Float64} + scan_data::Vector{NamedTuple} +end + +function empty_critical_resonant_field_result() + return CriticalResonantFieldResult( + false, + InnerLayerParameters[], + Int[], + Float64[], + Float64[], + Float64[], + Float64[], + NamedTuple[] + ) +end + + """ SLAYERResult @@ -55,46 +86,18 @@ struct SLAYERResult coupled_extraction::Union{Nothing,GrowthRateResult} layer_widths::Vector{LayerWidths} scan_data::Vector{Union{ScanResult,AMRResult}} + critical_resonant_field::CriticalResonantFieldResult end # Empty result (enabled=false path) function empty_slayer_result(control::SLAYERControl) return SLAYERResult(false, control, - SLAYERParameters[], - Float64[], Float64[], - zeros(ComplexF64, 0, 0), - ComplexF64[], Float64[], Float64[], - GrowthRateResult[], nothing, - LayerWidths[], - Union{ScanResult,AMRResult}[]) -end - -""" - CriticalResonantFieldResult - -Output of `run_critical_resonant_field`. Carries both summary critical resonant field values and if `control.store_scan` is true, the full Q scan data, viscous torque, and electromagnetic torque for plotting. -""" - -struct CriticalResonantFieldResult - enabled::Bool - params::AbstractVector{<:InnerLayerParameters} - surface_index::Vector{Int} - Qpeak::Vector{Float64} - br_crit::Vector{Float64} - Q0::Vector{Float64} - P::Vector{Float64} - scan_data::Vector{NamedTuple} -end - -function empty_critical_resonant_field_result() - return CriticalResonantFieldResult( - false, - InnerLayerParameters[], - Int[], - Float64[], - Float64[], - Float64[], - Float64[], - NamedTuple[] - ) + SLAYERParameters[], + Float64[], Float64[], + zeros(ComplexF64, 0, 0), + ComplexF64[], Float64[], Float64[], + GrowthRateResult[], nothing, + LayerWidths[], + Union{ScanResult,AMRResult}[], + empty_critical_resonant_field_result()) end diff --git a/src/Tearing/Runner/Runner.jl b/src/Tearing/Runner/Runner.jl index 6f11208a7..2d45b3d54 100644 --- a/src/Tearing/Runner/Runner.jl +++ b/src/Tearing/Runner/Runner.jl @@ -27,6 +27,7 @@ using LinearAlgebra using Statistics: mean, median using HDF5 + using FastInterpolations: cubic_interp using ..Utilities using ..Utilities: KineticProfiles diff --git a/src/Tearing/Runner/run_slayer.jl b/src/Tearing/Runner/run_slayer.jl index 3d51d4a11..9f1a686d1 100644 --- a/src/Tearing/Runner/run_slayer.jl +++ b/src/Tearing/Runner/run_slayer.jl @@ -314,7 +314,7 @@ function run_slayer_from_inputs(params::AbstractVector{<:InnerLayerParameters}, return SLAYERResult(true, control, params, rational_psi, rational_q, dp, Q_root, omega_Hz, gamma_Hz, per_surface_extraction, coupled_extraction, - layer_widths, scan_data_list) + layer_widths, scan_data_list, empty_critical_resonant_field_result()) end # --------------------------------------------------------------------- @@ -346,6 +346,115 @@ function ggj_inner_deltas(params::AbstractVector{GGJParameters}, Q::Number; end return out end +# --------------------------------------------------------------------- +# Critical Resonant Field (Torque-Balance) Workflow +# --------------------------------------------------------------------- +""" + Critical Resonant Field (Torque-Balance) Workflow + + The critical resonant field is the minimum resonant magnetic perturbation + amplitude that can drive a tearing mode unstable. + + Returns a `CriticalResonantFieldResult` containing the critical resonant field + and the corresponding critical resoannt field values for each rational surface. +""" + +function run_critical_resonant_field(equil, intr, ctrl; dir_path="./", slayer_result=nothing, profiles=nothing) + ctrl.enabled || return empty_critical_resonant_field_result() + + profiles === nothing && + throw(ArgumentError( + "CriticalResonantField requires kinetic profiles." + )) + + params = if slayer_result !== nothing && slayer_result.enabled && !isempty(slayer_result.params) + slayer_result.params + else + throw(ArgumentError("CriticalResonantField requires SLAYERParameters; run SLAYER first or provide compatible params.")) + end + + all(p -> p isa SLAYERParameters, params) || + throw(ArgumentError("CriticalResonantField requires SLAYERParameters; run SLAYER first or provide compatible params.")) + + surface_index = Int[] + Qpeak_vec = Float64[] + br_vec = Float64[] + Q0_vec = Float64[] + P_vec = Float64[] + scan_data = NamedTuple[] + # check if angular_momentum_diffusivity is list or value + + if isa(ctrl.angular_momentum_diffusivity, AbstractArray) + chi_vec = ctrl.angular_momentum_diffusivity + else + chi_vec = fill(ctrl.angular_momentum_diffusivity, length(params)) + end + + for (isurf, p) in enumerate(params) + psi_here = intr[isurf].psifac + omega_here = profiles(psi_here).omega + Q0_here = p.tauk * omega_here + eta_here = p.eta # resistivity at the rational surface + chi_here = chi_vec[isurf] # angular momentum diffusivity at the rational surface + + # Note, P = τ_R / τ_V (Cole PoP 2006), τ_R = μ₀ r_s² / η, τ_V = ρ r_s² / μ + # Therefore, P = τ_R / τ_V = μ₀ μ / (η ρ), and with χ_φ = μ / ρ, P = μ₀ χ_φ / η + + P_here = (4π * 1e-7) .* abs.(chi_here) ./ eta_here + + if P_here < 1 + @warn("CriticalResonantField: P < 1 at surface $isurf (P = $P_here). The model is invalid for P < 1.") + end + + tb = TorqueBalance( + SLAYERModel{:fitzpatrick}(), + p, + Q0_here, + P_here, + p.lu, + p.sval_r + ) + + Qs, bal, Qpeak, br_crit, Qpeak_ind, Δs = + torque_balance_scan(tb; Qmin=ctrl.Qmin, Qmax=ctrl.Qmax, n=ctrl.n) + + push!(surface_index, isurf) + push!(Qpeak_vec, Qpeak) + push!(br_vec, br_crit) + push!(Q0_vec, Q0_here) + push!(P_vec, P_here) + + scan_entry = ( + surface=isurf, + Q=collect(Qs), + balance=collect(bal), + delta=collect(Δs), + Qpeak=Qpeak, + br_crit=br_crit, + Q0=Q0_here, + P=P_here, + lu=p.lu, + sval=p.sval_r, + m=p.m, + n=p.n, + params=p + ) + push!(scan_data, scan_entry) + + end + + return CriticalResonantFieldResult( + true, + params, + surface_index, + Qpeak_vec, + br_vec, + Q0_vec, + P_vec, + scan_data + ) +end + # --------------------------------------------------------------------- # Full pipeline: equilibrium + ForceFreeStates → parameters → analysis @@ -453,96 +562,30 @@ function run_slayer(equil, surfaces::AbstractVector, delta_prime_matrix::Abstrac rational_psi = Float64[surfaces[p.ising].psifac for p in params] rational_q = Float64[surfaces[p.ising].q for p in params] - return run_slayer_from_inputs(params, dp, control; rational_psi=rational_psi, rational_q=rational_q) -end - -# --------------------------------------------------------------------- -# Critical Resonant Field (Torque-Balance) Workflow -# --------------------------------------------------------------------- -""" - Critical Resonant Field (Torque-Balance) Workflow - - The critical resonant field is the minimum resonant magnetic perturbation - amplitude that can drive a tearing mode unstable. - - Returns a `CriticalResonantFieldResult` containing the critical resonant field - and the corresponding critical resoannt field values for each rational surface. -""" - -function run_critical_resonant_field(equil, intr, ctrl; dir_path="./", slayer_result=nothing) - ctrl.enabled || return empty_critical_resonant_field_result() - - profiles = load_kinetic_profiles(joinpath(dir_path, ctrl.profile_file)) - - params = if slayer_result !== nothing && slayer_result.enabled && !isempty(slayer_result.params) - slayer_result.params - else - build_slayer_inputs(equil, intr.sing, profiles) - end - - all(p -> p isa SLAYERParameters, params) || - throw(ArgumentError("CriticalResonantField requires SLAYERParameters; run SLAYER first or provide compatible params.")) - - surface_index = Int[] - Qpeak_vec = Float64[] - br_vec = Float64[] - Q0_vec = Float64[] - P_vec = Float64[] - scan_data = NamedTuple[] - - for (isurf, p) in enumerate(params) - psi_here = intr.sing[isurf].psifac - omega_here = profiles(psi_here).omega - Q0_here = p.tauk * omega_here - P_here = 1.0 - - tb = TorqueBalance( - SLAYERModel{:fitzpatrick}(), - p, - Q0_here, - P_here, - p.lu, - p.sval_r + # include critical resonant filed workflow here + if control.critical_resonant_field.enabled + slayer_result = run_slayer_from_inputs(params, dp, control; rational_psi=rational_psi, rational_q=rational_q) + crf_result = run_critical_resonant_field(equil, surfaces, control.critical_resonant_field; + dir_path=dir_path, slayer_result=slayer_result, profiles=profiles) + combined_result = SLAYERResult( + slayer_result.enabled, + slayer_result.control, + slayer_result.params, + slayer_result.rational_psi, + slayer_result.rational_q, + slayer_result.dp_matrix, + slayer_result.Q_root, + slayer_result.omega_Hz, + slayer_result.gamma_Hz, + slayer_result.per_surface_extraction, + slayer_result.coupled_extraction, + slayer_result.layer_widths, + slayer_result.scan_data, + crf_result ) - - Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs = - torque_balance_scan(tb; Qmin=ctrl.Qmin, Qmax=ctrl.Qmax, n=ctrl.n) - - push!(surface_index, isurf) - push!(Qpeak_vec, Qpeak) - push!(br_vec, br_crit) - push!(Q0_vec, Q0_here) - push!(P_vec, P_here) - - scan_entry = ( - surface=isurf, - Q=collect(Qs), - balance=collect(bal), - delta=collect(Δs), - Q_positive=collect(Qs_positive), - balance_positive=collect(bal_positive), - Qpeak=Qpeak, - br_crit=br_crit, - Q0=Q0_here, - P=P_here, - lu=p.lu, - sval=p.sval_r, - m=p.m, - n=p.n, - params=p - ) - push!(scan_data, scan_entry) - + @info("SLAYER: critical resonant field workflow completed; " * + "critical br values for each rational surface are available in the result.") + return combined_result end - - return CriticalResonantFieldResult( - true, - params, - surface_index, - Qpeak_vec, - br_vec, - Q0_vec, - P_vec, - scan_data - ) + return run_slayer_from_inputs(params, dp, control; rational_psi=rational_psi, rational_q=rational_q) end From fbacf333c2312537a76b336d4a0cdff79c71c059 Mon Sep 17 00:00:00 2001 From: ebursch <76970916+ebursch@users.noreply.github.com> Date: Thu, 20 Aug 2026 14:07:27 -0400 Subject: [PATCH 07/14] Full working bcrit intial implementation --- .gitignore | 2 + .../gpec.toml | 20 +- .../slayer_ex.ipynb | 394 ++++++++++ .../DIIID-like_SLAYER_example/slayer_ex.ipynb | 266 ------- .../CRF Dev/P_eta_calc.ipynb | 279 ------- .../CriticalResonantField/CRF Dev/b_crit.jls | Bin 74 -> 0 bytes .../CRF Dev/bcrit_dev.ipynb | 724 ------------------ .../CRF Dev/bcrit_dev_ggj.ipynb | 298 ------- .../CRF Dev/bcrit_numerics.ipynb | 122 --- .../CriticalResonantField/CRF Dev/gslayer.txt | 466 ----------- .../CRF Dev/pole_testing.ipynb | 395 ---------- .../CRF Dev/sample_number.jls | Bin 68 -> 0 bytes .../CriticalResonantField.jl | 1 + .../CriticalResonantField/TorqueBalance.jl | 35 +- src/Tearing/Runner/Control.jl | 3 +- src/Tearing/Runner/run_slayer.jl | 115 ++- 16 files changed, 511 insertions(+), 2609 deletions(-) rename examples/{DIIID-like_SLAYER_example => DIIID-like_SLAYER_and_bcrit_example}/gpec.toml (84%) create mode 100644 examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb delete mode 100644 examples/DIIID-like_SLAYER_example/slayer_ex.ipynb delete mode 100644 src/Tearing/CriticalResonantField/CRF Dev/P_eta_calc.ipynb delete mode 100644 src/Tearing/CriticalResonantField/CRF Dev/b_crit.jls delete mode 100644 src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb delete mode 100644 src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev_ggj.ipynb delete mode 100644 src/Tearing/CriticalResonantField/CRF Dev/bcrit_numerics.ipynb delete mode 100644 src/Tearing/CriticalResonantField/CRF Dev/gslayer.txt delete mode 100644 src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb delete mode 100644 src/Tearing/CriticalResonantField/CRF Dev/sample_number.jls diff --git a/.gitignore b/.gitignore index fcb3cc96c..8f463f94f 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ scratch/ # Local profiling scratch (one-off study scripts, not part of the package) profiling/ +examples/b_crit_standalone_example/ +src/Tearing/CriticalResonantField/CRF Dev/ diff --git a/examples/DIIID-like_SLAYER_example/gpec.toml b/examples/DIIID-like_SLAYER_and_bcrit_example/gpec.toml similarity index 84% rename from examples/DIIID-like_SLAYER_example/gpec.toml rename to examples/DIIID-like_SLAYER_and_bcrit_example/gpec.toml index 618372d02..b00fad0cc 100644 --- a/examples/DIIID-like_SLAYER_example/gpec.toml +++ b/examples/DIIID-like_SLAYER_and_bcrit_example/gpec.toml @@ -1,7 +1,7 @@ -# DIII-D-like SLAYER tearing-mode growth-rate example. +# DIII-D-like SLAYER tearing-mode growth-rate example with Critical Resonant Field calculations. # Reuses the equilibrium and H-mode kinetic profiles of the sibling # DIIID-like_ideal_example (geqdsk referenced by relative path; not -# duplicated). Runs equilibrium + ForceFreeStates + SLAYER and skips +# duplicated). Runs equilibrium + ForceFreeStates + SLAYER + CriticalResonantField and skips # PerturbedEquilibrium (ForceFreeStates.force_termination = true). [Equilibrium] @@ -87,11 +87,11 @@ Q_im_range = [-0.5, 3.0] # Scan box in the normalized Q plane, Im(Q) axis nre = 41 # Grid resolution along the Re(Q) axis nim = 31 # Grid resolution along the Im(Q) axis -[SLAYER.CriticalResonantField] -# CriticalResonantField used to find the critical resonant field sufficent for tearing onset at each rational surface. -enabled = true # Run CriticalResonantField analysis -Qmin = -10 # Minimum rotation scanned -Qmax = 10 # Maximum rotation scanned -n = 200 # Number of rotation points scanned -angular_momentum_diffusivity = [1.0,1.0,1.0,1.0,1.0,1.0] # Toroidal momentum diffusivity (if nothing, falls back on chi_perp ~ chi_e, electron thermal diffusivity) -store_scan = true # Per surface torque and inner layer quantities +[SLAYER.CriticalResonantField] # CriticalResonantField used to find the critical resonant field sufficent for tearing onset at each rational surface. +enabled = true # Run CriticalResonantField analysis +Qmin = -10 # Minimum normalized rotation scanned +Qmax = 10 # Maximum normalized rotation scanned +n = 2000 # Number of rotation points scanned +viscous_input_type = "angular_momentum_diffusivity" # Either "angular_momentum_diffusivity" or "magnetic_prandtl_number" +viscous_input = 1 # Either Prandlt number or angular momentum diffusivity (based on viscous_input_type). Takes in either an array across q surfaces, a single value for all, or false, which falls back on chi_perp ~ chi_e, electron thermal diffusivity. +store_scan = true # Per surface torque and inner layer quantities diff --git a/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb b/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb new file mode 100644 index 000000000..ed88780dd --- /dev/null +++ b/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb @@ -0,0 +1,394 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "0", + "metadata": {}, + "outputs": [], + "source": [ + "using Pkg\n", + "Pkg.build(\"GeneralizedPerturbedEquilibrium\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1", + "metadata": {}, + "outputs": [], + "source": [ + "using Pkg\n", + "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", + "Base.active_project()\n", + "\n", + "using GeneralizedPerturbedEquilibrium\n", + "using GeneralizedPerturbedEquilibrium: Analysis\n", + "using Printf\n", + "\n", + "using Plots\n", + "default(\n", + " fontfamily=\"Georgia\",\n", + " margin=12Plots.mm,\n", + " size=(800, 500),\n", + " dpi=150\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2", + "metadata": {}, + "outputs": [], + "source": [ + "h5path = \"/Users/bursche/Documents/GitHub/JPEC_BCRIT/examples/DIIID-like_SLAYER_and_bcrit_example/gpec.h5\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3", + "metadata": {}, + "outputs": [], + "source": [ + "using HDF5\n", + "\n", + "h5open(h5path, \"r\") do file\n", + " println(\"Top-level keys:\")\n", + " println(collect(keys(file)))\n", + "\n", + " if haskey(file, \"Tearing\")\n", + " println(\"\\nKeys in Tearing:\")\n", + " println(collect(keys(file[\"Tearing\"])))\n", + "\n", + " if haskey(file[\"Tearing\"], \"CriticalResonantField\")\n", + " println(\"\\nKeys in Tearing/CriticalResonantField:\")\n", + " println(collect(keys(file[\"Tearing\"][\"CriticalResonantField\"])))\n", + " end\n", + " else\n", + " println(\"No Tearing group found.\")\n", + " end\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4", + "metadata": {}, + "outputs": [], + "source": [ + "# Print the contents of the Tearing/CriticalResonantField group\n", + "h5open(h5path, \"r\") do file\n", + " if haskey(file, \"Tearing\") && haskey(file[\"Tearing\"], \"CriticalResonantField\")\n", + " println(\"\\nContents of Tearing/CriticalResonantField:\")\n", + " # Iterate over the keys in the Tearing/CriticalResonantField group and print their names and types\n", + " for key in keys(file[\"Tearing\"][\"CriticalResonantField\"])\n", + " dataset = file[\"Tearing\"][\"CriticalResonantField\"][key]\n", + " println(\"Key: $key, Type: $(typeof(dataset))\")\n", + " # print data \n", + " if isa(dataset, HDF5.Dataset)\n", + " data = read(dataset)\n", + " println(\"Data: $data\")\n", + " end\n", + " end\n", + " else\n", + " println(\"No Tearing/CriticalResonantField group found.\")\n", + " end\n", + " # Print bcrit data as .2e (in one line)\n", + " println(\"\\nBcrit data: $(join([@sprintf(\"%.2e\", x) for x in read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"])], \" \"))\")\n", + "end\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5", + "metadata": {}, + "outputs": [], + "source": [ + "println(keys(h5open(h5path, \"r\")[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_1\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7", + "metadata": {}, + "outputs": [], + "source": [ + "function bcrit_diag_plots(Δs, Qs, bal, name)\n", + "\n", + " p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", + " #plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + " xlabel!(p1, \"Q\")\n", + " ylabel!(p1, \"Δ\")\n", + " title!(p1, \"Inner-layer Δ(Q) - $name\")\n", + "\n", + " p2 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", + " plot!(p2, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + " xlabel!(p2, \"Q\")\n", + " ylabel!(p2, \"balance\")\n", + " title!(p2, \"2P(Q0-Q)/jxb - $name\")\n", + "\n", + " plot(p1, p2, layout=(2,1), size=(500, 700))\n", + "\n", + "\n", + "end\n", + "\n", + "function plot_all_vs_rational_q(h5path)\n", + " h5open(h5path, \"r\") do file\n", + " tearing = file[\"Tearing\"]\n", + " crf = tearing[\"CriticalResonantField\"]\n", + " scan = crf[\"Scan\"]\n", + "\n", + " rational_q = read(tearing[\"PerSurface\"][\"rational_q\"])\n", + " bcrit = read(crf[\"br_crit\"])\n", + " bal = [read(scan[\"surface_$(i)\"][\"balance\"]) for i in eachindex(rational_q)]\n", + " P = [read(scan[\"surface_$(i)\"][\"P\"]) for i in eachindex(rational_q)]\n", + " lu = [read(scan[\"surface_$(i)\"][\"lu\"]) for i in eachindex(rational_q)]\n", + " sval = [read(scan[\"surface_$(i)\"][\"sval\"]) for i in eachindex(rational_q)]\n", + " Q0 = [read(scan[\"surface_$(i)\"][\"Q0\"]) for i in eachindex(rational_q)]\n", + " max_balance = maximum.(bal)\n", + "\n", + " fig = plot(layout=(3, 2), size=(1000, 1200))\n", + " plot!(fig[1], rational_q, bcrit; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Critical Resonant Field (T)\", legend=false)\n", + " plot!(fig[2], rational_q, max_balance; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Maximum (Torque Balance)\", legend=false)\n", + " plot!(fig[3], rational_q, P; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"P\", legend=false)\n", + " plot!(fig[4], rational_q, lu; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Lundquist Number\", legend=false)\n", + " plot!(fig[5], rational_q, sval; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Magnetic Shear\", legend=false)\n", + " plot!(fig[6], rational_q, Q0; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Q0\", legend=false)\n", + "\n", + " display(fig)\n", + " #return fig\n", + " end\n", + "end\n", + "\n", + "plot_all_vs_rational_q(h5path)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8", + "metadata": {}, + "outputs": [], + "source": [ + "using GeneralizedPerturbedEquilibrium\n", + "using GeneralizedPerturbedEquilibrium: Analysis\n", + "using GeneralizedPerturbedEquilibrium.InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters,\n", + " SLAYERModel, SLAYERParameters, slayer_parameters\n", + "using GeneralizedPerturbedEquilibrium.Tearing.CriticalResonantField: TorqueBalance, torque_balance_value, torque_balance_scan\n", + "\n", + "surface_num = 5\n", + "h5open(h5path, \"r\") do file\n", + " sval_r = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"sval\"])\n", + " Q0 = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"Q0\"])\n", + " m = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"m\"])\n", + " n = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"n\"])\n", + " qval = m/n\n", + " Q_e = read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"])[surface_num]\n", + " Q_i = read(file[\"Tearing\"][\"PerSurface\"][\"Q_i\"])[surface_num]\n", + " lu = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"lu\"])\n", + " rs = read(file[\"Tearing\"][\"PerSurface\"][\"rs\"])[surface_num]\n", + " P = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"P\"])\n", + "\n", + " p = slayer_parameters( # Call slayer_parameters function to instantiate slab parameters\n", + " n_e=1e19, t_e=1e3, t_i=1e3,\n", + " omega=0.0, omega_e=40, omega_i=-20,\n", + " qval=qval, sval_r=sval_r, bt=2.0, rs=rs, R0=3.0, mu_i=2.0, zeff=1.0,\n", + " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", + " )\n", + " p = SLAYERParameters( # Modify the created SLAYERParameters struct to modify electron and ion diamagnetic resonance frequencies\n", + " ising=p.ising,\n", + " m=p.m, n=p.n,\n", + " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", + " P_perp=p.P_perp, P_tor=p.P_tor,\n", + " Q_e=Q_e, Q_i=Q_i, iota_e=p.iota_e,\n", + " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", + " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", + " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", + " eta=p.eta, d_beta=p.d_beta,\n", + " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", + " )\n", + "\n", + " tb = TorqueBalance( # Generate a TorqueBalance struct using the default (Fitzpatrick) SLAYERModel and the modified SLAYERParameters\n", + " SLAYERModel(;),\n", + " p, # Slayer Parameters struct\n", + " Q0, # Normalized rotation Q\n", + " P, # Magnetic Prandtl number\n", + " p.lu, # Lundquist Number\n", + " p.sval_r # r-based magnetic shear\n", + " )\n", + " Qmin = -.2\n", + " Qmax = .2\n", + " Qs, bal, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qmin, Qmax=Qmax, n=1000) # Run actual torque balance scan, finds inner-layer delta across Q vals\n", + "\n", + "\n", + " jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", + " T_VISC = [2.0 * tb.P * (tb.Q0 - q) for q in Qs] #(q, jxb) in zip(Qs, jxbs)]\n", + " T_EM = -imag(1.0 ./ (Δs .+ 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", + " i = Qpeak_ind\n", + " println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", + " println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", + " println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", + "\n", + " #T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", + " #T_visc ∝ 2 P (Q0 − Q)\n", + "\n", + "\n", + " xmi = Qmin\n", + " xma = Qmax\n", + "\n", + " \"\"\"\n", + " p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2, xlim=(xmi, xma))\n", + " #plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + " xlabel!(p1, \"Q\")\n", + " ylabel!(p1, \"Δ\")\n", + " #title!(p1, \"Inner-layer Δ(Q)\")\n", + " \"\"\"\n", + "\n", + " p1 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(-1000,1000))\n", + " plot!(p1, Qs, T_EM, label=\"T_EM\", lw=2)\n", + " vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + " xlabel!(p1, \"Q\")\n", + " ylabel!(p1, \"Torque\")\n", + "\n", + " #p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + " p2 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(0,500))\n", + " plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", + " vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", + " xlabel!(p2, \"Q\")\n", + " ylabel!(p2, \"Torque\")\n", + "\n", + " p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2, xlim=(xmi, xma),ylim=(-1e-2,1e-2))\n", + " plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + " ylabel!(p3, \"Torque Balance\")\n", + " xlabel!(p3, \"Q\")\n", + " vline!([Qpeak], label=\"Max Balance\", linestyle=:dash)\n", + "\n", + " # find index, q val and bal val of the q closest to Q_e\n", + " println(\"Q_e: \", -tb.params.Q_e)\n", + " idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e))\n", + " q_closest_Q_e = Qs[idx_closest_Q_e]\n", + " bal_closest_Q_e = bal[idx_closest_Q_e]\n", + " println(\"Closest Q to Q_e: \", q_closest_Q_e, \" with balance value: \", bal_closest_Q_e, \" at index: \", idx_closest_Q_e)\n", + " println(\"B crit: \", brcrit)\n", + " vline!([-tb.params.Q_e], label=\"Q_e\", linestyle=:dashdot, color=:orange)\n", + " vline!([q_closest_Q_e], label=\"Closest Q to Q_e\", linestyle=:dashdot, color=:purple)\n", + "\n", + " #plot(p1, p2, p3, layout=(3,1), size=(800, 1000))\n", + " plot(p3, layout=(1,1))#, size=(800, 1000))\n", + "\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9", + "metadata": {}, + "outputs": [], + "source": [ + "# plot jxb vs Qs for surface 1\n", + "# jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", + "surface_num = 5\n", + "h5open(h5path, \"r\") do file\n", + " Δs = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"delta\"])\n", + " Qs = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"Q\"])\n", + " bal = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"balance\"])\n", + " jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", + " aplot = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", + " xlabel!(\"Q\")\n", + " ylabel!(\"jxb\")\n", + " title!(\"jxb vs Q for surface $(surface_num)\")\n", + " println(\"max of balance: \", maximum(bal))\n", + " println(\"max of jxb: \", maximum(jxbs))\n", + " println(\"bcrit: \", read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"]))\n", + " println(\"Qpeak: \", read(file[\"Tearing\"][\"CriticalResonantField\"][\"Qpeak\"]))\n", + " println(\"Q_e: \", read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"]))\n", + " # plot balance vs q with bcrit as vertical line\n", + " p2 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2,xlim=(-.2,.2),ylim=(-1e-2,1e-2))\n", + " plot!(p2, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", + " xlabel!(p2, \"Q\")\n", + " ylabel!(p2, \"balance\")\n", + " title!(p2, \"2P(Q0-Q)/jxb - surface $(surface_num)\")\n", + " #vline!(p2, [read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"])], label=\"bcrit\", lw=2, lc=:red)\n", + " # add Q_e as vertical line\n", + " vline!(p2, [read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"])[surface_num]], label=\"Q_e\", lw=2, lc=:green)\n", + " vline!(p2, [read(file[\"Tearing\"][\"PerSurface\"][\"Q_i\"])[surface_num]], label=\"Q_i\", lw=2, lc=:blue)\n", + " vline!(p2, [read(file[\"Tearing\"][\"CriticalResonantField\"][\"Qpeak\"])[surface_num]], label=\"Qpeak\", lw=2, lc=:orange)\n", + " #display(aplot)\n", + " display(p2)\n", + "\n", + "end\n", + "\n", + "\"\"\"\n", + "Local maxima indices: [104, 103] with values: [80.15320925995013, 79.66428209429431] and corresponding Qs: [0.35175879396984927, 0.25125628140703515] closest Q to Q_e: -0.35175879396984927 closest Q to Q_i: 0.35175879396984927\n", + "Warning: The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead.\n", + "Selected local maximum index: 103 with value: 79.66428209429431 and corresponding Q: 0.25125628140703515\n", + "\"\"\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10", + "metadata": {}, + "outputs": [], + "source": [ + "# Plot bcrit vs q surface\n", + "\n", + "# print all contents of bcrit /scan /surface 1/\n", + "h5open(h5path, \"r\") do file\n", + " bcrit = file[\"Tearing\"][\"CriticalResonantField\"]\n", + "\n", + " for i in 1:6\n", + " ss = \"surface_$i\"\n", + "\n", + " delta = read(bcrit[\"Scan\"][ss][\"delta\"])\n", + " Q = read(bcrit[\"Scan\"][ss][\"Q\"])\n", + " balance = read(bcrit[\"Scan\"][ss][\"balance\"])\n", + "\n", + " display(bcrit_diag_plots(delta, Q, balance, \"surface_$i\"))\n", + " end\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "11", + "metadata": {}, + "outputs": [], + "source": [ + "p_eq = Analysis.Equilibrium.plot_equilibrium_summary(h5path)\n", + "p_ffs = Analysis.ForceFreeStates.plot_ffs_summary(h5path)\n", + "#p_pe = Analysis.PerturbedEquilibrium.plot_perturbed_equilibrium_summary(h5path)\n", + "\n", + "display(p_eq)\n", + "display(p_ffs)\n", + "#display(p_pe)" + ] + } + ], + "metadata": { + "language_info": { + "file_extension": ".jl", + "mimetype": "application/julia", + "name": "julia" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb b/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb deleted file mode 100644 index 710608340..000000000 --- a/examples/DIIID-like_SLAYER_example/slayer_ex.ipynb +++ /dev/null @@ -1,266 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "0", - "metadata": {}, - "outputs": [], - "source": [ - "using Pkg\n", - "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", - "Base.active_project()\n", - "\n", - "using GeneralizedPerturbedEquilibrium\n", - "using GeneralizedPerturbedEquilibrium: Analysis\n", - "using Printf\n", - "\n", - "using Plots\n", - "default(\n", - " fontfamily=\"Georgia\",\n", - " margin=12Plots.mm,\n", - " size=(800, 500),\n", - " dpi=150\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1", - "metadata": {}, - "outputs": [], - "source": [ - "h5path = \"/Users/bursche/Documents/GitHub/JPEC_BCRIT/examples/DIIID-like_SLAYER_example/gpec.h5\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2", - "metadata": {}, - "outputs": [], - "source": [ - "using HDF5\n", - "\n", - "h5open(h5path, \"r\") do file\n", - " println(\"Top-level keys:\")\n", - " println(collect(keys(file)))\n", - "\n", - " if haskey(file, \"Tearing\")\n", - " println(\"\\nKeys in Tearing:\")\n", - " println(collect(keys(file[\"Tearing\"])))\n", - "\n", - " if haskey(file[\"Tearing\"], \"CriticalResonantField\")\n", - " println(\"\\nKeys in Tearing/CriticalResonantField:\")\n", - " println(collect(keys(file[\"Tearing\"][\"CriticalResonantField\"])))\n", - " end\n", - " else\n", - " println(\"No Tearing group found.\")\n", - " end\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3", - "metadata": {}, - "outputs": [], - "source": [ - "# Print the contents of the Tearing/CriticalResonantField group\n", - "h5open(h5path, \"r\") do file\n", - " if haskey(file, \"Tearing\") && haskey(file[\"Tearing\"], \"CriticalResonantField\")\n", - " println(\"\\nContents of Tearing/CriticalResonantField:\")\n", - " # Iterate over the keys in the Tearing/CriticalResonantField group and print their names and types\n", - " for key in keys(file[\"Tearing\"][\"CriticalResonantField\"])\n", - " dataset = file[\"Tearing\"][\"CriticalResonantField\"][key]\n", - " println(\"Key: $key, Type: $(typeof(dataset))\")\n", - " # print data \n", - " if isa(dataset, HDF5.Dataset)\n", - " data = read(dataset)\n", - " println(\"Data: $data\")\n", - " end\n", - " end\n", - " else\n", - " println(\"No Tearing/CriticalResonantField group found.\")\n", - " end\n", - " # Print bcrit data as .2e (in one line)\n", - " println(\"\\nBcrit data: $(join([@sprintf(\"%.2e\", x) for x in read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"])], \" \"))\")\n", - "end\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4", - "metadata": {}, - "outputs": [], - "source": [ - "println(keys(h5open(h5path, \"r\")[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_1\"]))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5", - "metadata": {}, - "outputs": [], - "source": [ - "function bcrit_diag_plots(Δs, Qs, bal,name)\n", - "\n", - " p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", - " #plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - " xlabel!(p1, \"Q\")\n", - " ylabel!(p1, \"Δ\")\n", - " title!(p1, \"Inner-layer Δ(Q) - $name\")\n", - "\n", - " p2 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", - " plot!(p2, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - " xlabel!(p2, \"Q\")\n", - " ylabel!(p2, \"balance\")\n", - " title!(p2, \"2P(Q0-Q)/jxb - $name\")\n", - "\n", - " plot(p1, p2, layout=(2,1), size=(800, 1000))\n", - "\n", - "\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6", - "metadata": {}, - "outputs": [], - "source": [ - "# print all P values\n", - "println(\"\\nP values for each surface in the scan:\")\n", - "h5open(h5path, \"r\") do file\n", - " for i in 1:6\n", - " ss = \"surface_$i\"\n", - " if haskey(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"], ss)\n", - " P = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][ss][\"P\"])\n", - " println(\"Surface $i: P = $(join([@sprintf(\"%.2e\", x) for x in P], \" \"))\")\n", - " else\n", - " println(\"Surface $i: No data found.\")\n", - " end\n", - " end\n", - "end\n", - "# want to print chi_tor for each surface in the scan, need to use P = (4π * 1e-7) .* abs.(chi_sel) ./ η_neo, so chi_sel = P * η_neo / (4π * 1e-7)\n", - "println(\"\\nchi_tor values for each surface in the scan:\")\n", - "h5open(h5path, \"r\") do file\n", - " for i in 1:6\n", - " ss = \"surface_$i\"\n", - " if haskey(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"], ss)\n", - " P = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][ss][\"P\"])\n", - " η_neo = read(file[\"Tearing\"][\"PerSurface\"][\"eta\"])\n", - " chi_tor = P .* η_neo[i] ./ (4π * 1e-7)\n", - " println(\"Surface $i: chi_tor = $(join([@sprintf(\"%.2e\", x) for x in chi_tor], \" \"))\") \n", - " else\n", - " println(\"Surface $i: No data found.\")\n", - " end\n", - " end\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7", - "metadata": {}, - "outputs": [], - "source": [ - "# plot jxb vs Qs for surface 1\n", - "# jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", - "surface_num = 2\n", - "h5open(h5path, \"r\") do file\n", - " Δs = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"delta\"])\n", - " Qs = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"Q\"])\n", - " bal = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"balance\"])\n", - " jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", - " aplot = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - " xlabel!(\"Q\")\n", - " ylabel!(\"jxb\")\n", - " title!(\"jxb vs Q for surface $(surface_num)\")\n", - " println(\"max of balance: \", maximum(bal))\n", - " println(\"max of jxb: \", maximum(jxbs))\n", - " println(\"bcrit: \", read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"]))\n", - " println(\"Qpeak: \", read(file[\"Tearing\"][\"CriticalResonantField\"][\"Qpeak\"]))\n", - " println(\"Q_e: \", read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"]))\n", - " # plot balance vs q with bcrit as vertical line\n", - " p2 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", - " plot!(p2, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - " xlabel!(p2, \"Q\")\n", - " ylabel!(p2, \"balance\")\n", - " title!(p2, \"2P(Q0-Q)/jxb - surface $(surface_num)\")\n", - " vline!(p2, [read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"])], label=\"bcrit\", lw=2, lc=:red)\n", - " # add Q_e as vertical line\n", - " vline!(p2, [read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"])[surface_num]], label=\"Q_e\", lw=2, lc=:green)\n", - " vline!(p2, [read(file[\"Tearing\"][\"PerSurface\"][\"Q_i\"])[surface_num]], label=\"Q_i\", lw=2, lc=:blue)\n", - "\n", - " display(aplot)\n", - " display(p2)\n", - "\n", - "end\n", - "\n", - "\"\"\"\n", - "Local maxima indices: [104, 103] with values: [80.15320925995013, 79.66428209429431] and corresponding Qs: [0.35175879396984927, 0.25125628140703515] closest Q to Q_e: -0.35175879396984927 closest Q to Q_i: 0.35175879396984927\n", - "Warning: The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead.\n", - "Selected local maximum index: 103 with value: 79.66428209429431 and corresponding Q: 0.25125628140703515\n", - "\"\"\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8", - "metadata": {}, - "outputs": [], - "source": [ - "# Plot bcrit vs q surface\n", - "\n", - "# print all contents of bcrit /scan /surface 1/\n", - "h5open(h5path, \"r\") do file\n", - " bcrit = file[\"Tearing\"][\"CriticalResonantField\"]\n", - "\n", - " for i in 1:6\n", - " ss = \"surface_$i\"\n", - "\n", - " delta = read(bcrit[\"Scan\"][ss][\"delta\"])\n", - " Q = read(bcrit[\"Scan\"][ss][\"Q\"])\n", - " balance = read(bcrit[\"Scan\"][ss][\"balance\"])\n", - "\n", - " display(bcrit_diag_plots(delta, Q, balance, \"surface_$i\"))\n", - " end\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9", - "metadata": {}, - "outputs": [], - "source": [ - "p_eq = Analysis.Equilibrium.plot_equilibrium_summary(h5path)\n", - "p_ffs = Analysis.ForceFreeStates.plot_ffs_summary(h5path)\n", - "#p_pe = Analysis.PerturbedEquilibrium.plot_perturbed_equilibrium_summary(h5path)\n", - "\n", - "display(p_eq)\n", - "display(p_ffs)\n", - "#display(p_pe)" - ] - } - ], - "metadata": { - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/src/Tearing/CriticalResonantField/CRF Dev/P_eta_calc.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/P_eta_calc.ipynb deleted file mode 100644 index 0639317bd..000000000 --- a/src/Tearing/CriticalResonantField/CRF Dev/P_eta_calc.ipynb +++ /dev/null @@ -1,279 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "0", - "metadata": {}, - "outputs": [], - "source": [ - "using Pkg\n", - "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", - "Base.active_project()\n", - "\n", - "using Plots\n", - "using Printf" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1", - "metadata": {}, - "outputs": [], - "source": [ - "# Minimal Julia implementation of the `neo_2021` branch.\n", - "\n", - "# Inputs:\n", - "# Te : electron temperature [eV]\n", - "# ne : electron density [m^-3]\n", - "# Ti : ion temperature [eV]\n", - "# q : safety factor\n", - "# eps : inverse aspect ratio\n", - "# R : major radius [m]\n", - "# fT : trapped-particle fraction\n", - "# Zeff : effective charge\n", - "\n", - "# Output:\n", - "# σ_spitzer : Spitzer conductivity [1/(Ω m)]\n", - "# σ_neo : Redl 2021 neoclassical conductivity [1/(Ω m)]\n", - "\n", - "# All inputs can be scalars or arrays of the same size.\n", - "\n", - "function neoclassical_conductivity(\n", - " Te, ne, Ti, q, eps, R, fT, Zeff;\n", - " version = :neo_2021,\n", - ")\n", - "\n", - " # Coulomb logarithms\n", - " lnΛe = 23.5 .-\n", - " log.(sqrt.(ne ./ 1e6) .* Te.^(-5/4)) .-\n", - " sqrt.(1e-5 .+ (log.(Te) .- 2).^2 ./ 16)\n", - "\n", - " # Ion density.\n", - " #\n", - " # For the simple D + C model used in the original code:\n", - " # n_i = n_main + n_imp\n", - " #\n", - " # If only Zeff is supplied, the original function uses\n", - " # n_i = ne / Zeff\n", - " ni = ne ./ Zeff\n", - "\n", - " # With only Zeff available, Zdom = 1, giving\n", - " Zdom = 1.0\n", - "\n", - " # Average ion charge\n", - " Zavg = ne ./ ni\n", - "\n", - " # Koh effective ion charge\n", - " Zion = (Zdom^2 .* Zavg .* Zeff).^(1/4)\n", - "\n", - " # Ion Coulomb logarithm\n", - " lnΛi = 30.0 .-\n", - " log.(Zion.^3 .* sqrt.(ni) ./ Ti.^1.5)\n", - "\n", - " # Prevent pathological negative electron Coulomb logarithms\n", - " lnΛe_min = minimum(lnΛe[lnΛe .> 0])\n", - " lnΛe = max.(lnΛe, lnΛe_min)\n", - "\n", - " # Avoid eps = 0\n", - " eps_nz = copy(eps)\n", - " if any(eps .== 0)\n", - " eps_nz[eps .== 0] .= minimum(eps[eps .!= 0])\n", - " end\n", - "\n", - " # Electron collisionality, Eq. 18b\n", - " νe_star = 6.921e-18 .* abs.(q) .* R .* ne .* Zeff .* lnΛe ./\n", - " (Te.^2 .* eps_nz.^1.5)\n", - "\n", - " # Ion collisionality, Eq. 18c\n", - " νi_star = 4.90e-18 .* abs.(q) .* R .* ni .* Zion.^4 .* lnΛi ./\n", - " (Ti.^2 .* eps_nz.^1.5)\n", - "\n", - " # Sauter Eq. 18a\n", - " NZ(Z) = 0.58 + 0.74 ./ (0.76 + Z)\n", - "\n", - " σ_spitzer = 1.9012e4 .* Te.^1.5 ./\n", - " (Zeff .* NZ(Zeff) .* lnΛe)\n", - "\n", - " # Redl 2021, Eq. 18\n", - " f33teff = fT ./ (\n", - " 1 .+\n", - " 0.25 .* (1 .- 0.7 .* fT) .* sqrt.(νe_star) .*\n", - " (1 .+ 0.45 .* sqrt.(Zeff .- 1)) .+\n", - " 0.61 .* (1 .- 0.41 .* fT) .* νe_star ./ sqrt.(Zeff)\n", - " )\n", - "\n", - " # Redl 2021, Eq. 17\n", - " F33 = 1 .-\n", - " (1 .+ 0.21 ./ Zeff) .* f33teff .+\n", - " 0.54 ./ Zeff .* f33teff.^2 .-\n", - " 0.33 ./ Zeff .* f33teff.^3\n", - "\n", - " σ_neo = σ_spitzer .* F33\n", - "\n", - " return σ_neo, σ_spitzer\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2", - "metadata": {}, - "outputs": [], - "source": [ - "function calc_resistivity_P(chi, ne, Te, Zeff, q, eps, R, fT, volume;\n", - " model=:neoclassical)\n", - " cond = neoclassical_conductivity(\n", - " Te=Te,\n", - " ne=ne,\n", - " Ti=Te,\n", - " Zeff=Zeff,\n", - " q=q,\n", - " eps=eps,\n", - " R=R,\n", - " fT=fT,\n", - " volume=volume,\n", - " version=:neo_2021,\n", - " )\n", - "\n", - " σ = model == :neoclassical ?\n", - " cond.neoclassical_conductivity :\n", - " cond.spitzer_conductivity\n", - "\n", - " η = 1 ./ σ\n", - " P = (4π * 1e-7) .* abs.(chi) ./ η\n", - "\n", - " return η, P\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3", - "metadata": {}, - "outputs": [], - "source": [ - "σ_neo, σ_spitzer = neoclassical_conductivity(\n", - " Te_eV,\n", - " ne_sel,\n", - " Te_eV, # Ti = Te\n", - " qsing,\n", - " eps_sel,\n", - " R_sel,\n", - " fT_sel;\n", - " Zeff=zeff_sel,\n", - ")\n", - "\n", - "η_neo = 1.0 ./ σ_neo\n", - "η_spitzer = 1.0 ./ σ_spitzer\n", - "\n", - "P = (4π * 1e-7) .* abs.(chi_sel) ./ η_neo" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4", - "metadata": {}, - "outputs": [], - "source": [ - "σ_neo, σ_spitzer = neoclassical_conductivity(\n", - " 106.211805100300, # Te [eV]\n", - " 1.005827348013049e19, # ne [m^-3]\n", - " 106.211805100300, # Ti [eV]\n", - " 6.00000000000048, # q\n", - " 0.771873939341347 / 1.74333594120074, # eps = rs / R0\n", - " 1.74333594120074, # R [m]\n", - " 1, #fT; # trapped fraction\n", - " 1.80427095488192, # Zeff\n", - ")\n", - "\n", - "η_neo = 1.0 ./ σ_neo\n", - "η_spitzer = 1.0 ./ σ_spitzer\n", - "\n", - "chi_sel = 1\n", - "\n", - "P = (4π * 1e-7) .* abs.(chi_sel) ./ η_neo" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5", - "metadata": {}, - "outputs": [], - "source": [ - "using LinearAlgebra # or relevant module providing neoclassical_conductivity\n", - "\n", - "# --- Set 1 Inputs (5 radial points) ---\n", - "Te_eV = [718.04269217, 342.58020426, 188.39435197, 95.70267912, 44.04668565] # Te and Ti [eV]\n", - "ne_sel = [1.98796958e19, 1.80371630e19, 1.55527262e19, 1.23649097e19, 8.97867646e18] # ne [m^-3]\n", - "zeff_sel = [1.65619282, 1.64427584, 1.58198407, 1.55990923, 1.68572562] # Zeff\n", - "qsing = [2.0, 3.0, 4.0, 5.0, 6.0] # q\n", - "eps_sel = [0.22284171, 0.28956909, 0.32302672, 0.34432513, 0.35141583] # eps = r/R\n", - "R_sel = [1.72151657, 1.70693349, 1.69832026, 1.69192129, 1.68947514] # R [m]\n", - "fT_sel = [0.6127298, 0.66890766, 0.68553652, 0.68355803, 0.67414449] # Trapped fraction fT\n", - "\n", - "# Reference values from Python NCLASS run (for validation)\n", - "py_neo = [7683580.66632273, 3011088.07938057, 1644303.89021149, 782055.27991453, 274193.4323623]\n", - "py_spitzer = [16324797.88300323, 5666135.22162908, 2468477.31865855, 941040.7938515, 290205.76181926]\n", - "\n", - "# --- Run Neoclassical Conductivity in Julia ---\n", - "# Broadcasting across all 5 radial positions:\n", - "σ_neo, σ_spitzer = neoclassical_conductivity.(\n", - " Te_eV, # Te [eV]\n", - " ne_sel, # ne [m^-3]\n", - " Te_eV, # Ti [eV] (assumed Ti = Te)\n", - " qsing, # q\n", - " eps_sel, # eps\n", - " R_sel, # R [m]\n", - " fT_sel, # trapped fraction fT\n", - " zeff_sel # Zeff\n", - ")\n", - "\n", - "# Collect tuple outputs into a vector of tuples\n", - "results = [\n", - " neoclassical_conductivity(\n", - " Te_eV[i], ne_sel[i], Te_eV[i], qsing[i], \n", - " eps_sel[i], R_sel[i], fT_sel[i], zeff_sel[i]\n", - " ) for i in 1:length(Te_eV)\n", - "]\n", - "\n", - "# Extract σ_neo (1st element) and σ_spitzer (2nd element)\n", - "σ_neo = getindex.(results, 1)\n", - "σ_spitzer = getindex.(results, 2)\n", - "\n", - "η_neo = 1.0 ./ σ_neo\n", - "η_spitzer = 1.0 ./ σ_spitzer\n", - "\n", - "chi_sel = 1\n", - "P = (4π * 1e-7) .* abs.(chi_sel) ./ η_neo\n", - "\n", - "\n", - "# --- Comparison Printouts ---\n", - "println(\"=== Neoclassical Conductivity Comparison ===\")\n", - "for i in 1:length(Te_eV)\n", - " println(\"Point $i (q=$(qsing[i])):\")\n", - " println(\" Julia σ_neo : \", σ_neo[i])\n", - " println(\" Python σ_neo : \", py_neo[i])\n", - " println(\" Julia σ_spitzer : \", σ_spitzer[i])\n", - " println(\" Python σ_spitzer: \", py_spitzer[i])\n", - " println(\" P (magnetic diff): \", P[i])\n", - " println()\n", - "end" - ] - } - ], - "metadata": { - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/src/Tearing/CriticalResonantField/CRF Dev/b_crit.jls b/src/Tearing/CriticalResonantField/CRF Dev/b_crit.jls deleted file mode 100644 index dcd8e2611787cf2ae06b76a1ee64426e4009ac8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74 zcmXr_@{waLoNTscITzal0AxrQ1ONa4 diff --git a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb deleted file mode 100644 index 5f9dfac2a..000000000 --- a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev.ipynb +++ /dev/null @@ -1,724 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "0", - "metadata": {}, - "outputs": [], - "source": [ - "using Pkg\n", - "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", - "Base.active_project()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1", - "metadata": {}, - "outputs": [], - "source": [ - "using GeneralizedPerturbedEquilibrium\n", - "using GeneralizedPerturbedEquilibrium: Analysis\n", - "using GeneralizedPerturbedEquilibrium: InnerLayer\n", - "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", - "using GeneralizedPerturbedEquilibrium: Tearing\n", - "using ..InnerLayer\n", - "using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters,\n", - " SLAYERModel, SLAYERParameters\n", - "\n", - "using Plots\n", - "using Printf\n", - "default(\n", - " fontfamily=\"Georgia\",\n", - " margin=12Plots.mm,\n", - " size=(800, 500),\n", - " dpi=150\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2", - "metadata": {}, - "outputs": [], - "source": [ - "struct TorqueBalance{M<:InnerLayerModel,P}\n", - " model::M\n", - " params::P\n", - " Q0::Float64\n", - " P::Float64\n", - " lu::Float64\n", - " sval::Float64\n", - "end\n", - "\n", - "function torque_balance_value(tb::TorqueBalance, Q::Number)\n", - " Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing\n", - " alpha = 1e-2\n", - " jxb = -imag(1.0 / (Δ+ alpha))\n", - " return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ\n", - "end\n", - "\n", - "function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=200)\n", - " Qs = range(Qmin, Qmax; length=n)\n", - " torque_out = [torque_balance_value(tb, q) for q in Qs]\n", - " bal = [x[1] for x in torque_out]\n", - " Δs = [x[2] for x in torque_out]\n", - " #bal = [torque_balance_value(tb, q) for q in Qs]\n", - " positive = isfinite.(bal) .& (bal .> 0.0)\n", - "\n", - " if !any(positive)\n", - " return Qs, bal, NaN, NaN, 0.0, NaN, NaN, Δs\n", - " end\n", - " i = argmax(bal)\n", - " Qpeak_ind = i\n", - " Qs_positive = Qs[positive]\n", - " bal_positive = bal[positive]\n", - "\n", - " i = argmax(bal_positive)\n", - " Qpeak = Qs_positive[i]\n", - " \n", - " maxbal = bal_positive[i]\n", - "\n", - " br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", - " return Qs, bal, Qs_positive, bal_positive, Qpeak, br_crit, Qpeak_ind, Δs\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3", - "metadata": {}, - "outputs": [], - "source": [ - "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", - " n_e=1e19, t_e=1e3, t_i=1e3,\n", - " omega=0.0, omega_e=4, omega_i=-2,\n", - " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", - " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", - ")\n", - "p2 = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", - " ising=p.ising,\n", - " m=p.m, n=p.n,\n", - " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", - " P_perp=p.P_perp, P_tor=p.P_tor,\n", - " Q_e=0.818, Q_i=-0.543, iota_e=p.iota_e,\n", - " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", - " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", - " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", - " eta=p.eta, d_beta=p.d_beta,\n", - " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", - ")\n", - "\n", - "p2 = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", - " ising=p.ising,\n", - " m=p.m, n=p.n,\n", - " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", - " P_perp=p.P_perp, P_tor=p.P_tor,\n", - " Q_e=2, Q_i=3, iota_e=p.iota_e,\n", - " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", - " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", - " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", - " eta=p.eta, d_beta=p.d_beta,\n", - " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", - ")\n", - "\n", - "p = p2\n", - "\n", - "tb = TorqueBalance(\n", - " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", - " p,\n", - " 0.5,\n", - " p.P_tor,\n", - " p.lu,\n", - " p.sval_r\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4", - "metadata": {}, - "outputs": [], - "source": [ - "#Qs = range(-5.0, 5.0, length=200)\n", - "\n", - "#vals = [torque_balance_value(tb, q) for q in Qs]\n", - "\"\"\"\n", - "n=2000:\n", - "Qpeak = 0.24512256128064033\n", - "maxbal = 0.35873684252530247\n", - "br_crit = 4.668551985584323e-5\n", - "\n", - "n=200 (def):\n", - "Qpeak = 0.25125628140703515\n", - "maxbal = 0.3585219071071706\n", - "br_crit = 4.667153206033017e-5\n", - "\"\"\"\n", - "Qmi = -10\n", - "Qma = 10\n", - "\n", - "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qmi, Qmax=Qma, n=100)\n", - "\n", - "println(\"Qpeak = \", Qpeak)\n", - "println(\"maxbal = \", maximum(bal_positive))\n", - "println(\"maxbal = \", maximum(bal))\n", - "println(\"br_crit = \", brcrit)\n", - "\n", - "p1 = plot(Qs, bal, lw=2, label=\"balance\")#,ylim=(-40, 40))\n", - "z_inds = findall(i -> bal[i]*bal[i+1] < 0, 1:length(bal)-1)\n", - "println(\"zero crossings at Q = \", Qs[z_inds])\n", - "for i in z_inds\n", - " vline!([Qs[i]], label=\"0\", linestyle=:dot, color=:gray)\n", - "end\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"balance\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "\n", - "\n", - "p5 = plot(Qs, bal, lw=2, label=\"balance\",xlim=(Qs[z_inds[1]],Qs[z_inds[2]]))#,ylim=(-40, 40))#, xlim = (-.11,-.09))\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"balance\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "p2 = plot(Qs, -imag(Δs), lw=2, label=\"Im(Δ)\",ylim=(-5,2))#,xlim=(-.11,-.09))\n", - "plot!(p2, Qs, real(Δs), lw=2, label=\"Re(Δ)\")\n", - "#vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "#hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "vline!([-3], linestyle=:dashdot)\n", - "vline!([-2], linestyle=:dashdot)\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "vline!([0.499], linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"Δ\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "jxb = -imag(1.0 ./ (Δs .+ 1e-2))\n", - "jxb0 = -imag(1.0 ./ (Δs))\n", - "p3 = plot(Qs, jxb, lw=2, label=\"-Im(1 / (Δs + 1e-2))\",color=:blue)#, xlim = (-.11,-.09),ylim=(-500,500))\n", - "plot!(p3, Qs, jxb0, lw=2, label=\"-Im(1 / Δs)\",color=:red,linestyle=:dash)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"~ jxb\")\n", - "\n", - "p4 = plot(Qs, jxb, lw=2, label=\"-Im(1 / Δs)\",color=:blue)#, xlim = (-.11,-.09))\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"~ jxb\")\n", - "\"\"\"\n", - "#remake plot 1 but of derivative of balance with respect to Q\n", - "dQ = Qs[2] - Qs[1]\n", - "dbal_dQ = diff(bal) ./ dQ\n", - "p3 = plot(Qs[1:end-1], dbal_dQ, lw=2, label=\"d(balance)/dQ\",ylim=(-1000, 1000))\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"d(balance)/dQ\")\n", - "\"\"\"\n", - "\n", - "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qs[], Qmax=Qs[zin], n=10000)\n", - "\n", - "\n", - "plo = plot(p1, p2,p3,p4,p5, p6, layout=(6,1), size=(1000, 2000))\n", - "display(plo)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5", - "metadata": {}, - "outputs": [], - "source": [ - "Qlow = -0.1005100510051005\n", - "Qhigh = 0.49954995499549953\n", - "\n", - "#Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qlow, Qmax=Qhigh, n=10000)\n", - "\n", - "println(\"Qpeak = \", Qpeak)\n", - "println(\"maxbal = \", maximum(bal_positive))\n", - "println(\"maxbal = \", maximum(bal))\n", - "println(\"br_crit = \", brcrit)\n", - "\n", - "p1 = plot(Qs, bal, lw=2, label=\"balance\")#,ylim=(-40, 40))\n", - "z_inds = findall(i -> bal[i]*bal[i+1] < 0, 1:length(bal)-1)\n", - "println(\"zero crossings at Q = \", Qs[z_inds])\n", - "for i in z_inds\n", - " vline!([Qs[i]], label=\"0\", linestyle=:dot, color=:gray)\n", - "end\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"balance\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "\n", - "p5 = plot(Qs, bal, lw=2, label=\"balance\",ylim=(-40, 40), xlim = (-.11,-.09))\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"balance\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "p2 = plot(Qs, -imag(Δs), lw=2, label=\"Im(Δ)\",ylim=(-2,2))#,xlim=(-.11,-.09))\n", - "plot!(p2, Qs, real(Δs), lw=2, label=\"Re(Δ)\")\n", - "#vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "#hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"Δ\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "jxb = -imag(1.0 ./ (Δs .+ 1e-2))\n", - "jxb0 = -imag(1.0 ./ (Δs))\n", - "p3 = plot(Qs, jxb, lw=2, label=\"-Im(1 / (Δs + 1e-2))\",color=:blue, xlim = (-.11,-.09),ylim=(-500,500))\n", - "plot!(p3, Qs, jxb0, lw=2, label=\"-Im(1 / Δs)\",color=:red,linestyle=:dash)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"~ jxb\")\n", - "\n", - "p4 = plot(Qs, jxb, lw=2, label=\"-Im(1 / Δs)\",color=:blue, xlim = (-.11,-.09))\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"~ jxb\")\n", - "\"\"\"\n", - "#remake plot 1 but of derivative of balance with respect to Q\n", - "dQ = Qs[2] - Qs[1]\n", - "dbal_dQ = diff(bal) ./ dQ\n", - "p3 = plot(Qs[1:end-1], dbal_dQ, lw=2, label=\"d(balance)/dQ\",ylim=(-1000, 1000))\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"d(balance)/dQ\")\n", - "\"\"\"\n", - "plo = plot(p1, p2,p3,p4,p5, layout=(5,1), size=(1000, 2000))\n", - "display(plo)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6", - "metadata": {}, - "outputs": [], - "source": [ - "#Qs = range(-5.0, 5.0, length=200)\n", - "\n", - "#vals = [torque_balance_value(tb, q) for q in Qs]\n", - "\"\"\"\n", - "n=2000:\n", - "Qpeak = 0.24512256128064033\n", - "maxbal = 0.35873684252530247\n", - "br_crit = 4.668551985584323e-5\n", - "\n", - "n=200 (def):\n", - "Qpeak = 0.25125628140703515\n", - "maxbal = 0.3585219071071706\n", - "br_crit = 4.667153206033017e-5\n", - "\"\"\"\n", - "\n", - "#Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=-.2, Qmax=0.5, n=10000)\n", - "\n", - "println(\"Qpeak = \", Qpeak)\n", - "println(\"maxbal = \", maximum(bal_positive))\n", - "println(\"maxbal = \", maximum(bal))\n", - "println(\"br_crit = \", brcrit)\n", - "\n", - "p1 = plot(Qs, bal, lw=2, label=\"balance\")#,ylim=(-40, 40))\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"balance\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "p2 = plot(Qs, -imag(Δs), lw=2, label=\"Im(Δs)\")#,ylim=(-.2,.05))#,xlim=(-.11,-.09))\n", - "plot!(p2, Qs, real(Δs), lw=2, label=\"Re(Δs)\")\n", - "#vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "#hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"Δs\")\n", - "title!(\"Torque-balance scan\")\n", - "\n", - "\"\"\"\n", - "#remake plot 1 but of derivative of balance with respect to Q\n", - "dQ = Qs[2] - Qs[1]\n", - "dbal_dQ = diff(bal) ./ dQ\n", - "p3 = plot(Qs[1:end-1], dbal_dQ, lw=2, label=\"d(balance)/dQ\",ylim=(-1000, 1000))\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "hline!([0.0], label=\"zero\", linestyle=:dashdot)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"d(balance)/dQ\")\n", - "\"\"\"\n", - "plo = plot(p1, p2, layout=(2,1), size=(800, 1000))\n", - "display(plo)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7", - "metadata": {}, - "outputs": [], - "source": [ - "jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", - "\n", - "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Δ\")\n", - "title!(p1, \"Inner-layer Δ(Q)\")\n", - "\n", - "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - "xlabel!(p2, \"Q\")\n", - "ylabel!(p2, \"jxb\")\n", - "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", - "\n", - "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2)\n", - "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - "xlabel!(p3, \"Q\")\n", - "ylabel!(p3, \"balance\")\n", - "title!(p3, \"2P(Q0-Q)/jxb\")\n", - "\n", - "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8", - "metadata": {}, - "outputs": [], - "source": [ - "# Check torque is balanced\n", - "\n", - "viscous_torque = 2*tb.P*(tb.Q0 - Qpeak)\n", - "electromagnetic_torque = -imag(1.0 / (Δs[Qpeak_ind] + 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", - "\n", - "# delta_n_p = 1e-2\n", - "# jxb = -imag(1.0 / (Δ + delta_n_p))\n", - "# bal = 2.0 * tb.P * (tb.Q0 - Q) / jxb\n", - "# br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", - "\n", - "@printf(\"br_crit = %.5e\\n\", brcrit)\n", - "@printf(\"viscous_torque = %.5e\\n\", viscous_torque)\n", - "@printf(\"electromagnetic_torque = %.5e\\n\", electromagnetic_torque)\n", - "@printf(\"ratio = %.10f\\n\", viscous_torque / electromagnetic_torque)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9", - "metadata": {}, - "outputs": [], - "source": [ - "Qs_n, bal_n, Qs_positive_n, bal_positive_n, Qpeak_n, brcrit_n, Qpeak_ind_n, Δs_n = torque_balance_scan(tb,Qmin=-3, Qmax=3, n=2)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10", - "metadata": {}, - "outputs": [], - "source": [ - "sample_number = [2, 3, 4, 5, 10,100,1000]#,10000,100000]#,1000000]\n", - "b_crit = []\n", - "# make dicts to store Qs_n and Δs_n arrays for each sample number\n", - "Qs_n_dict = Dict{Int, Vector{Float64}}()\n", - "bal_n_dict = Dict{Int, Vector{Float64}}()\n", - "for i in sample_number\n", - " Qs_n, bal_n, Qs_positive_n, bal_positive_n, Qpeak_n, brcrit_n, Qpeak_ind_n, Δs_n = torque_balance_scan(tb,Qmin=-3, Qmax=3, n=i)\n", - " push!(b_crit, brcrit_n)\n", - " push!(Qs_n_dict, i => Qs_n)\n", - " push!(bal_n_dict, i => bal_n)\n", - " println(bal_n)\n", - "end\n", - "\n", - "# add bcrit = 3.50601e-03 for n=100000 to b_crit\n", - "#push!(b_crit, 3.50601e-03)\n", - "\n", - "# make a plot of b_crit vs sample_number \n", - "p1 = plot(sample_number, b_crit,\n", - " lw=2,\n", - " label=\"b_crit\",\n", - " #xscale=:log10,\n", - " #yscale=:log10,\n", - " xlabel=\"Sample Number\",\n", - " ylabel=\"b_crit\")\n", - "\n", - "p2 = plot(\n", - " xlabel=\"Q\",\n", - " ylabel=\"balance\",\n", - " title=\"Torque balance vs Q\"\n", - ")\n", - "\n", - "for i in sample_number[1:end-1]\n", - " plot!(p2, Qs_n_dict[i], bal_n_dict[i],\n", - " lw=2,\n", - " label=\"n=$i\")\n", - "end\n", - "\n", - "p3 = plot(layout=(3, 2), size=(1000, 800))\n", - "\n", - "for (k, i) in enumerate(sample_number[1:end-1])\n", - " plot!(\n", - " p3[k],\n", - " Qs_n_dict[i],\n", - " bal_n_dict[i],\n", - " lw=2,\n", - " label=\"n=$i\",\n", - " xlabel=\"Q\",\n", - " ylabel=\"balance\",\n", - " title=\"n = $i\"\n", - " )\n", - "end\n", - "\n", - "display(p1)\n", - "display(p2)\n", - "display(p3)\n", - "\n", - "\n", - "println(\"b_crit = \", b_crit)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11", - "metadata": {}, - "outputs": [], - "source": [ - "println(b_crit)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "12", - "metadata": {}, - "outputs": [], - "source": [ - "bcrit = Any[0.0014075170156654356, 0.0015190532807794722, 0.0015297173529485084, 0.0015297510027746748, 0.0015297613496804952, 0.0015297692159317363, 0.004702965572292843]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "13", - "metadata": {}, - "outputs": [], - "source": [ - "using Serialization\n", - "\n", - "# serialize(\"Qs_n_dict.jls\", Qs_n_dict)\n", - "# serialize(\"bal_n_dict.jls\", bal_n_dict)\n", - "# serialize(\"b_crit.jls\", b_crit)\n", - "# serialize(\"sample_number.jls\", sample_number)\n", - "#my_dict = deserialize(\"my_dict.jls\")\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "14", - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "Qs, bal, Qs_positive, bal_positive, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=-2.5, Qmax=0, n=20000)\n", - "\n", - "jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", - "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for q in Qs] #(q, jxb) in zip(Qs, jxbs)]\n", - "br_t = brcrit\n", - "println(tb.lu, \" \", tb.sval, \" \", br_t, \" \", p.bt, \" \", 1e-2)\n", - "@printf(\"br_crit = %.5e\\n\", brcrit)\n", - "#T_EM = tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs\n", - "T_EM = -imag(1.0 ./ (Δs .+ 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", - "i = Qpeak_ind\n", - "println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", - "println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", - "println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", - "\n", - "#T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", - "#T_visc ∝ 2 P (Q0 − Q)\n", - "\n", - "xmi = -2.5\n", - "xma = 0\n", - "\n", - "\"\"\"\n", - "p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2, xlim=(xmi, xma))\n", - "#plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Δ\")\n", - "#title!(p1, \"Inner-layer Δ(Q)\")\n", - "\"\"\"\n", - "\n", - "p1 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(-1000,1000))\n", - "plot!(p1, Qs, T_EM, label=\"T_EM\", lw=2)\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Torque\")\n", - "\n", - "#p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - "p2 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(0,500))\n", - "plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "xlabel!(p2, \"Q\")\n", - "ylabel!(p2, \"Torque\")\n", - "#title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", - "\n", - "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2, xlim=(xmi, xma))\n", - "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - "ylabel!(p3, \"Torque Balance\")\n", - "#title!(p3, \"2P(Q0-Q)/jxb\")\n", - "xlabel!(p3, \"Q\")\n", - "vline!([Qpeak], label=\"Max Balance\", linestyle=:dash)\n", - "\n", - "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "15", - "metadata": {}, - "outputs": [], - "source": [ - "# Recreate Cihan's plot:\n", - "\n", - "using Plots\n", - "using DataInterpolations\n", - "\n", - "default(\n", - " fontfamily=\"Georgia\",\n", - " grid=false,\n", - " linewidth=2,\n", - " guidefontsize=26,\n", - " tickfontsize=18,\n", - " titlefontsize=30,\n", - " legendfontsize=18,\n", - " size=(1200, 800),\n", - " dpi=150\n", - ")\n", - "\n", - "# Build the critical boundary bcrit(Q0)\n", - "Q0_scan = range(-1.0, 4.5; length=80)\n", - "bcrit_curve = Float64[]\n", - "\n", - "for Q0 in Q0_scan\n", - " tbQ = TorqueBalance(\n", - " tb.model,\n", - " tb.params,\n", - " Float64(Q0),\n", - " tb.P,\n", - " tb.delta_n_p,\n", - " tb.lu,\n", - " tb.sval\n", - " )\n", - "\n", - " Qs, bal, Qs_pos, bal_pos, Qpeak, brcrit, Qpeak_ind, Δs =\n", - " torque_balance_scan(tbQ; Qmin=-10.0, Qmax=10.0, n=250)\n", - "\n", - " if isempty(bal_pos) || !all(isfinite.(bal_pos)) || maximum(bal_pos) <= 0\n", - " push!(bcrit_curve, NaN)\n", - " else\n", - " push!(bcrit_curve, brcrit)\n", - " end\n", - "end\n", - "\n", - "ok = isfinite.(bcrit_curve)\n", - "Q0_plot = Q0_scan[ok]\n", - "bcrit_plot = bcrit_curve[ok]\n", - "\n", - "perm = sortperm(Q0_plot)\n", - "Q0_plot = Q0_plot[perm]\n", - "bcrit_plot = bcrit_plot[perm]\n", - "\n", - "# Interpolate the boundary: bcrit = f(Q0)\n", - "curve_itp = LinearInterpolation(bcrit_plot, Q0_plot)\n", - "\n", - "# Full phase-box bounds\n", - "x0 = minimum(bcrit_plot) * 0.8\n", - "x1 = maximum(bcrit_plot) * 1.2\n", - "y0 = minimum(Q0_plot)\n", - "y1 = maximum(Q0_plot)\n", - "\n", - "xvals = range(x0, x1; length=350)\n", - "yvals = range(y0, y1; length=350)\n", - "\n", - "locked_mask = zeros(Float64, length(yvals), length(xvals))\n", - "for iy in eachindex(yvals)\n", - " y = yvals[iy]\n", - " for ix in eachindex(xvals)\n", - " x = xvals[ix]\n", - " # locked when bcrit exceeds the boundary for that Q0\n", - " locked_mask[iy, ix] = x >= curve_itp(y) ? 1.0 : 0.0\n", - " end\n", - "end\n", - "\n", - "p = contourf(\n", - " xvals, yvals, locked_mask',\n", - " levels=[-0.5, 0.5, 1.5],\n", - " c=[:navy, :firebrick],\n", - " colorbar=false,\n", - " xlabel=\"b_crit\",\n", - " ylabel=\"Q_0\",\n", - " title=\"Locked / unlocked region\",\n", - " framestyle=:box,\n", - " xlims=(x0, x1),\n", - " ylims=(y0, y1),\n", - " legend=false\n", - ")\n", - "\n", - "# Critical boundary\n", - "plot!(p, bcrit_plot, Q0_plot; lw=3, color=:black, label=\"critical boundary\")\n", - "\n", - "# Critical point\n", - "cp_idx = argmax(bcrit_plot)\n", - "cp_x = bcrit_plot[cp_idx]\n", - "cp_y = Q0_plot[cp_idx]\n", - "scatter!(p, [cp_x], [cp_y]; color=:gold, marker=:star5, ms=12, label=\"critical point\")\n", - "\n", - "# Single legend block with one entry per category\n", - "plot!(p, [NaN], [NaN]; color=:firebrick, lw=4, label=\"locked\")\n", - "plot!(p, [NaN], [NaN]; color=:navy, lw=4, label=\"unlocked\")\n", - "plot!(p, [NaN], [NaN]; color=:black, lw=3, label=\"critical boundary\")\n", - "scatter!(p, [NaN], [NaN]; color=:gold, marker=:star5, ms=12, label=\"critical point\")\n", - "\n", - "plot!(p; legend=:topright)\n", - "\n", - "display(p)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "16", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "17", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev_ggj.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev_ggj.ipynb deleted file mode 100644 index 617d61585..000000000 --- a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_dev_ggj.ipynb +++ /dev/null @@ -1,298 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "0", - "metadata": {}, - "outputs": [], - "source": [ - "using Pkg\n", - "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", - "Base.active_project()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1", - "metadata": {}, - "outputs": [], - "source": [ - "using GeneralizedPerturbedEquilibrium\n", - "using GeneralizedPerturbedEquilibrium: GGJParameters\n", - "using GeneralizedPerturbedEquilibrium\n", - "using GeneralizedPerturbedEquilibrium: InnerLayer\n", - "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", - "import GeneralizedPerturbedEquilibrium.InnerLayer.GGJ: sfac\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2", - "metadata": {}, - "outputs": [], - "source": [ - "using Plots\n", - "default(\n", - " fontfamily=\"Georgia\",\n", - " margin=12Plots.mm,\n", - " size=(800, 500),\n", - " dpi=150\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3", - "metadata": {}, - "outputs": [], - "source": [ - "struct TorqueBalance\n", - " model\n", - " params\n", - " Q0::Float64\n", - " P::Float64\n", - " delta_n_p::Float64\n", - " lu::Float64\n", - " sval::Float64\n", - "end\n", - "\n", - "function torque_balance_value(tb::TorqueBalance, Q::Number)\n", - " Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing\n", - " jxb = -imag(1.0 / (Δ + tb.delta_n_p))\n", - " return 2.0 * tb.P * (tb.Q0 - Q) / jxb\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4", - "metadata": {}, - "outputs": [], - "source": [ - "# You can substitute any valid SLAYERParameters you already have.\n", - "# This is just an example skeleton.\n", - "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", - " n_e=1e19, t_e=1e3, t_i=1e3,\n", - " omega=0.0, omega_e=4, omega_i=-2,\n", - " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", - " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", - ")\n", - "\n", - "tb = TorqueBalance(\n", - " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", - " p,\n", - " 0.5,\n", - " 1.0,\n", - " 1e-2,\n", - " p.lu,\n", - " p.sval_r\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5", - "metadata": {}, - "outputs": [], - "source": [ - "p_ggj = GeneralizedPerturbedEquilibrium.InnerLayer.glasser_wang_2020_eq55()\n", - "lu_ggj = sfac(p_ggj)\n", - "sval_ggj = 0.5\n", - "\n", - "tb = TorqueBalance(\n", - " GeneralizedPerturbedEquilibrium.InnerLayer.GGJModel(; solver=:galerkin),\n", - " p_ggj,\n", - " 0.5,\n", - " 1.0,\n", - " 1e-2,\n", - " lu_ggj,\n", - " sval_ggj\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6", - "metadata": {}, - "outputs": [], - "source": [ - "\"\"\"\n", - "\n", - "tau_h=R0*(mu0*rho)**0.5/(nns*sval*bt) ! alfven time across surface\n", - "lu=tau_r/tau_h ! Lundquist number\n", - "Qconv=lu**(1.0/3.0)*tau_h ! conversion to Qs based on Cole\n", - "\n", - "! note Q depends on Qconv even if omega is fixed.\n", - "Q=Qconv*omega\n", - "Q_e=-Qconv*omega_e\n", - "Q_i=-Qconv*omega_i\n", - "\n", - "\"\"\"\n", - "2=-lu**(1.0/3.0)*tau_h *OE\n", - "OE = -2 " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7", - "metadata": {}, - "outputs": [], - "source": [ - "Qs = range(-5.0, 5.0, length=20)\n", - "\n", - "vals = [torque_balance_value(tb, q) for q in Qs]\n", - "\n", - "# 1m 34.7s for length = 2\n", - "# 46 m for length = 20\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8", - "metadata": {}, - "outputs": [], - "source": [ - "plot(Qs, real.(vals), label=\"Re(balance)\", lw=2)\n", - "plot!(Qs, imag.(vals), label=\"Im(balance)\", lw=2)\n", - "xlabel!(\"Q\")\n", - "ylabel!(\"torque balance\")\n", - "title!(\"tb(Q)\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9", - "metadata": {}, - "outputs": [], - "source": [ - "Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing for q in Qs]\n", - "jxbs = [-imag(1.0 / (d + tb.delta_n_p)) for d in Δs]\n", - "\n", - "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Δ\")\n", - "title!(p1, \"Inner-layer Δ(Q)\")\n", - "\n", - "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - "xlabel!(p2, \"Q\")\n", - "ylabel!(p2, \"jxb\")\n", - "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", - "\n", - "p3 = plot(Qs, real.(vals), label=\"Re(balance)\", lw=2)\n", - "plot!(p3, Qs, imag.(vals), label=\"Im(balance)\", lw=2)\n", - "xlabel!(p3, \"Q\")\n", - "ylabel!(p3, \"balance\")\n", - "title!(p3, \"2P(Q0-Q)/jxb\")\n", - "\n", - "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10", - "metadata": {}, - "outputs": [], - "source": [ - "println(p.lu^(1/3))\n", - "println(p.tauk)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11", - "metadata": {}, - "outputs": [], - "source": [ - "plt.figure()\n", - "for i in OMFIT['GPEC']['OUTPUTS'].keys():\n", - " try:\n", - " print(OMFIT['GPEC']['OUTPUTS'][i]['DATA'][0]['gpec_slayer_torque_balance_m2_n1_out']['bal'].values)\n", - " plt.plot(OMFIT['GPEC']['OUTPUTS'][i]['DATA'][0]['gpec_slayer_torque_balance_m2_n1_out']['inQ'].values, OMFIT['GPEC']['OUTPUTS'][i]['DATA'][0]['gpec_slayer_torque_balance_m2_n1_out']['bal'].values,label=i)\n", - " except:\n", - " continue\n", - "plt.axhline(0)\n", - "plt.legend()\n", - " \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "12", - "metadata": {}, - "outputs": [], - "source": [ - "Δs = [solve_inner(tb.model, tb.params, ComplexF64(q)).tearing/p.lu^(1 / 3)/p.rs for q in Qs]\n", - "jxbs = [-imag(1.0 / (d + tb.delta_n_p)) for d in Δs]\n", - "\n", - "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Δ\")\n", - "title!(p1, \"Inner-layer Δ(Q)\")\n", - "\n", - "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - "xlabel!(p2, \"Q\")\n", - "ylabel!(p2, \"jxb\")\n", - "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", - "\n", - "p3 = plot(Qs, real.(vals), label=\"Re(balance)\", lw=2)\n", - "plot!(p3, Qs, imag.(vals), label=\"Im(balance)\", lw=2)\n", - "xlabel!(p3, \"Q\")\n", - "ylabel!(p3, \"balance\")\n", - "title!(p3, \"2P(Q0-Q)/jxb\")\n", - "\n", - "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "13", - "metadata": {}, - "outputs": [], - "source": [ - "p1 = plot(Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - "plot!(p1, Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Δ\")\n", - "title!(p1, \"Inner-layer Δ(Q)\")\n", - "\n", - "p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - "xlabel!(p2, \"Q\")\n", - "ylabel!(p2, \"jxb\")\n", - "title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", - "\n", - "p3 = plot(Qs, real.(vals), label=\"Re(balance)\", lw=2)\n", - "plot!(p3, Qs, imag.(vals), label=\"Im(balance)\", lw=2)\n", - "xlabel!(p3, \"Q\")\n", - "ylabel!(p3, \"balance\")\n", - "title!(p3, \"2P(Q0-Q)/jxb\")\n", - "\n", - "plot(p1, p2, p3, layout=(3,1), size=(800, 1000))" - ] - } - ], - "metadata": { - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_numerics.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/bcrit_numerics.ipynb deleted file mode 100644 index 71ed79d9e..000000000 --- a/src/Tearing/CriticalResonantField/CRF Dev/bcrit_numerics.ipynb +++ /dev/null @@ -1,122 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "0", - "metadata": {}, - "outputs": [], - "source": [ - "using Pkg\n", - "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", - "Base.active_project()\n", - "using GeneralizedPerturbedEquilibrium\n", - "using GeneralizedPerturbedEquilibrium: Analysis\n", - "using GeneralizedPerturbedEquilibrium: InnerLayer\n", - "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", - "using GeneralizedPerturbedEquilibrium: Tearing\n", - "using ..InnerLayer\n", - "using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters,\n", - " SLAYERModel, SLAYERParameters\n", - "using Serialization\n", - "using Plots\n", - "using Printf\n", - "default(\n", - " fontfamily=\"Georgia\",\n", - " margin=12Plots.mm,\n", - " size=(800, 500),\n", - " dpi=150\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1", - "metadata": {}, - "outputs": [], - "source": [ - "bal_n_dict = deserialize(\"bal_n_dict.jls\")\n", - "Qs_n_dict = deserialize(\"Qs_n_dict.jls\")\n", - "sample_number = deserialize(\"sample_number.jls\")\n", - "bcrit = deserialize(\"b_crit.jls\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2", - "metadata": {}, - "outputs": [], - "source": [ - "# make a plot of b_crit vs sample_number \n", - "p1 = plot(\n", - " sample_number,\n", - " b_crit,\n", - " lw=2,\n", - " marker=:circle,\n", - " label=\"b_crit\",\n", - " xscale=:log10,\n", - " #yscale=:log10,\n", - " xlabel=\"Sample Number\",\n", - " ylabel=\"b_crit\"\n", - ")\n", - "\n", - "xticks!(p1,\n", - " [5, 10, 100, 1000, 10000, 100000, 1000000],\n", - " [\"5\", \"10\", \"100\", \"1k\", \"10k\", \"100k\", \"1M\"]\n", - ")\n", - "\n", - "p2 = plot(\n", - " xlabel=\"Q\",\n", - " ylabel=\"balance\",\n", - " title=\"Torque balance vs Q\"\n", - ")\n", - "\n", - "for i in sample_number\n", - " plot!(p2, Qs_n_dict[i], bal_n_dict[i],\n", - " lw=2,\n", - " label=\"n=$i\")\n", - "end\n", - "\n", - "p3 = plot(layout=(4, 2), size=(1000, 800))\n", - "\n", - "for (k, i) in enumerate(sample_number)\n", - " plot!(\n", - " p3[k],\n", - " Qs_n_dict[i],\n", - " bal_n_dict[i],\n", - " lw=2,\n", - " label=\"n=$i\",\n", - " xlabel=\"Q\",\n", - " ylabel=\"balance\",\n", - " title=\"n = $i\"\n", - " )\n", - "end\n", - "\n", - "display(p1)\n", - "display(p2)\n", - "display(p3)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3", - "metadata": {}, - "outputs": [], - "source": [ - "println(\"bcrit = $bcrit\")" - ] - } - ], - "metadata": { - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/src/Tearing/CriticalResonantField/CRF Dev/gslayer.txt b/src/Tearing/CriticalResonantField/CRF Dev/gslayer.txt deleted file mode 100644 index 91cc2f862..000000000 --- a/src/Tearing/CriticalResonantField/CRF Dev/gslayer.txt +++ /dev/null @@ -1,466 +0,0 @@ - MODULE gslayer_mod - - USE sglobal_mod, ONLY: out_unit, r8, mu0, m_p, chag, lnLamb, - $ Q_e,Q_i,pr,pe,c_beta,ds,tau, - $ eta,visc,rho_s,lu,omega_e,omega_i, - $ delta_n,layfac, - $ Q - USE delta_mod, ONLY: riccati,riccati_out, - $ parflow_flag,PeOhmOnly_flag - - IMPLICIT NONE - -c----------------------------------------------------------------------- -c torque balance scan resolution. public so that gpout_singfld can -c size the netcdf dimension from the same source of truth. -c----------------------------------------------------------------------- - INTEGER, PARAMETER :: slayer_inum=200 - INTEGER, PARAMETER :: slayer_nref=4 -c----------------------------------------------------------------------- -c dedicated logarithmic sampling window bracketing Q_e, the electron -c diamagnetic frequency. (Q-Q_e) sits in the denominator of both G -c and C3 in delta.f, so the layer solve is singular there; the -c coarse scan steps over that neighbourhood with dQ=0.1 and the -c adaptive refinement only visits it when the torque-balance peak -c happens to land on it. These samples always resolve it, so the -c structure can be inspected on every surface rather than only on -c the ones that fell into it. -c -c PURELY DIAGNOSTIC: filled after br_th is computed, and tagged -c kpass=slayer_qetag so the threshold search cannot see them. -c Costs slayer_nqe extra lsode solves per surface (~40% on top of -c the 1005 the scan already does). -c----------------------------------------------------------------------- - INTEGER, PARAMETER :: slayer_nqe=400 - INTEGER, PARAMETER :: slayer_qetag=99 - REAL(r8), PARAMETER :: slayer_qefar=1.0e-1_r8 - REAL(r8), PARAMETER :: slayer_qenear=1.0e-9_r8 - INTEGER, PARAMETER :: slayer_nq=(slayer_inum+1)*(slayer_nref+1) - $ +slayer_nqe -c----------------------------------------------------------------------- -c every term of Cole & Fitzpatrick Eq. (61) on one rational -c surface, -c Im[Delta]/|alpha+Delta|**2 -c = 2*P*(Q0-Q)/(S*kappa_hat*(b_r/B_phi)**2) -c recorded so the balance can be rebuilt piece by piece and -c rescanned in post processing. every component is default -c initialized, so both ALLOCATE and INTENT(OUT) leave a well -c defined (zero) state even when the layer solve is skipped. -c -c kpass tags the scan pass that produced each sample: 0 for the -c coarse scan, 1..slayer_nref for the adaptive refinement passes. -c----------------------------------------------------------------------- - TYPE :: slayer_diag_type - REAL(r8), DIMENSION(slayer_nq) :: qs=0.0_r8 - REAL(r8), DIMENSION(slayer_nq) :: lhs=0.0_r8 - REAL(r8), DIMENSION(slayer_nq) :: rhs=0.0_r8 - REAL(r8), DIMENSION(slayer_nq) :: bal=0.0_r8 - REAL(r8), DIMENSION(slayer_nq) :: brb=0.0_r8 - COMPLEX(r8), DIMENSION(slayer_nq) :: dlt=(0.0_r8,0.0_r8) - INTEGER, DIMENSION(slayer_nq) :: kpass=0 - REAL(r8) :: alpha=0.0_r8, kaphat=0.0_r8, slun=0.0_r8 - REAL(r8) :: prnd=0.0_r8, q0v=0.0_r8, qcnv=0.0_r8 - REAL(r8) :: qev=0.0_r8, qiv=0.0_r8, dsv=0.0_r8 - REAL(r8) :: cbeta=0.0_r8, tratio=0.0_r8, pev=0.0_r8 - REAL(r8) :: lfac=0.0_r8, dnorm=0.0_r8, rhos=0.0_r8 - REAL(r8) :: etav=0.0_r8, viscv=0.0_r8, tauh=0.0_r8 - REAL(r8) :: taur=0.0_r8, tauv=0.0_r8, taui=0.0_r8 - REAL(r8) :: shr=0.0_r8, bl=0.0_r8, va=0.0_r8 - REAL(r8) :: rhom=0.0_r8, lbet=0.0_r8, omg=0.0_r8 - REAL(r8) :: qsol=0.0_r8, wsol=0.0_r8, brth=0.0_r8 - REAL(r8) :: mxbal=0.0_r8, qmn=0.0_r8, qmx=0.0_r8 - END TYPE slayer_diag_type - - CONTAINS - -c----------------------------------------------------------------------- -c subprogram 1. gpec_slayer. -c run slayer to provide b_crit(ising). -c----------------------------------------------------------------------- -c----------------------------------------------------------------------- -c declarations. -c----------------------------------------------------------------------- - SUBROUTINE gpec_slayer(n_e,t_e,n_i,t_i,zeff,omega,omega_e, - $ omega_i,qval,sval,bt,rs,R0,mu_i,inpr,mms,nns,ascii_flag, - $ delta,psi0,jxb,omega_sol,br_th,diag,inlayfac,inlayfrac) - - REAL(r8),INTENT(IN) :: n_e,t_e,n_i,t_i,omega,omega_e,omega_i, - $ qval,sval,bt,rs,R0,zeff,inpr - REAL(r8),INTENT(IN),OPTIONAL :: inlayfac,inlayfrac - REAL(r8) :: layfac_max,layfac_frac - INTEGER, INTENT(IN) :: mms,nns,mu_i - LOGICAL, INTENT(IN) :: ascii_flag - COMPLEX(r8),INTENT(OUT) :: delta,psi0 - REAL(r8),INTENT(OUT) :: jxb,omega_sol,br_th - TYPE(slayer_diag_type), INTENT(OUT), OPTIONAL :: diag - - INTEGER :: i,inum - INTEGER, DIMENSION(1) :: index - - REAL(r8) :: inQ,inQ_e,inQ_i,inpe,inc_beta,inds,intau,inlu - REAL(r8) :: mrs,nrs,rho,b_l,v_a,Qconv,Q0,delta_n_p, - $ lbeta,tau_i,tau_h,tau_r,tau_v - REAL(r8) :: inQ_min,inQ_max,Q_sol,maxbal - INTEGER :: ipass - INTEGER, PARAMETER :: nref=slayer_nref - REAL(r8) :: xpk,rlo,rhi,rdq,rdqc,xq,bloc,jloc - COMPLEX(r8) :: dloc - -c Eq. (61) term capture. cqs/cdlt/clhs/crhs/cbal/cbrb hold every -c sample of the coarse and refinement scans, cpass its pass tag, -c and iperm the permutation that sorts them by ascending Q. - INTEGER :: j,k,kk - INTEGER, DIMENSION(slayer_nq) :: iperm,cpass - REAL(r8), DIMENSION(slayer_nq) :: cqs,clhs,crhs,cbal,cbrb - COMPLEX(r8), DIMENSION(slayer_nq) :: cdlt - REAL(r8) :: kaphat,xtmp - - REAL(r8), DIMENSION(:), ALLOCATABLE :: inQs,iinQs,jxbl,bal - COMPLEX(r8), DIMENSION(:), ALLOCATABLE :: deltal - CHARACTER(3) :: sn,sm - - parflow_flag=.FALSE. - PeOhmOnly_flag=.TRUE. - riccati_out=.FALSE. - - mrs = real(mms,4) - nrs = real(nns,4) - - ! String representations of the m and n mode numbers - IF (nns<10) THEN - WRITE(UNIT=sn,FMT='(I1)') nns - sn=ADJUSTL(sn) - ELSE - WRITE(UNIT=sn,FMT='(I2)') nns - ENDIF - IF (mms<10) THEN - WRITE(UNIT=sm,FMT='(I1)') mms - sm=ADJUSTL(sm) - ELSEIF (mms<100) THEN - WRITE(UNIT=sm,FMT='(I2)') mms - sm=ADJUSTL(sm) - ELSE - WRITE(UNIT=sm,FMT='(I3)') mms - ENDIF - - inpe=0.0 ! Waybright added this - - tau= t_i/t_e ! ratio of ion to electron temperature - tau_i = 6.6e17*mu_i**0.5*(t_i/1e3)**1.5/(n_e*lnLamb) ! ion colls. - eta= 1.65e-9*lnLamb/(t_e/1e3)**1.5 ! spitzer resistivity (wesson) - rho=(mu_i*m_p)*n_e ! mass density - - b_l=(nrs/mrs)*rs*sval*bt/R0 ! characteristic magnetic field - v_a=b_l/(mu0*rho)**0.5 ! alfven velocity - rho_s=1.02e-4*(mu_i*t_e)**0.5/bt ! ion Lamour by elec. Temp. - - tau_h=R0*(mu0*rho)**0.5/(nns*sval*bt) ! alfven time across surface - tau_r=mu0*rs**2.0/eta ! resistive time scale - tau_v=tau_r/inpr ! rho*rs**2.0/visc ! viscous time scale - - ! this one must be anomalous. calculated back from pr. - visc= rho*rs**2.0/tau_v - - lu=tau_r/tau_h ! Lundquist number - - Qconv=lu**(1.0/3.0)*tau_h ! conversion to Qs based on Cole - - ! note Q depends on Qconv even if omega is fixed. - Q=Qconv*omega - Q_e=-Qconv*omega_e - Q_i=-Qconv*omega_i - - ! This is the most critical parameter - ds=lu**(1.0/3.0)*rho_s/rs ! conversion based on Cole. - - lbeta=(5.0/3.0)*mu0*n_e*chag*(t_e+t_i)/bt**2.0 - c_beta=(lbeta/(1.0+lbeta))**0.5 - - delta_n=lu**(1.0/3.0)/rs ! norm factor for delta primes - - inQ=Q - inQ_e=Q_e - inQ_i=Q_i - inc_beta=c_beta - inds=ds - intau=tau - Q0=Q -c----------------------------------------------------------------------- -c set the layer regularization width. -c -c riccati excises a disc of radius layfac around Q_e, where Im[Delta] -c has a zero and bal=2P(Q0-Q)/lhs therefore has a pole. Without it the -c coarse scan and its refinement walk into that pole and MAXVAL(bal) -c returns a threshold set by the scan spacing rather than by the -c saddle-node bifurcation. gpec_slayer never assigned layfac, so on -c this path the guard was dead. -c -c A fixed width is not safe on every surface: the disc [Q_e-layfac, -c Q_e+layfac] can be a large fraction of the physical branch, and on -c high-m surfaces it can swallow the turning point or Q0 itself -- -c quietly, since a number still comes back. So the width is scaled to -c the accessible branch |Q0-Q_e| and capped: -c -c layfac_frac > 0 : layfac = MIN(layfac_max, layfac_frac*|Q0-Q_e|) -c layfac_frac <= 0: layfac = layfac_max (fixed width) -c layfac_max <= 0: layfac = 0 (guard off) -c -c Exposed through gpec.in so the choice is auditable per run; it is a -c physics judgement, not a constant. -c----------------------------------------------------------------------- - layfac_max=0.02_r8 - IF (PRESENT(inlayfac)) layfac_max=inlayfac - layfac_frac=0.25_r8 - IF (PRESENT(inlayfrac)) layfac_frac=inlayfrac - IF (layfac_max>0.0_r8) THEN - IF (layfac_frac>0.0_r8) THEN - layfac=MIN(layfac_max,layfac_frac*ABS(Q0-inQ_e)) - ELSE - layfac=layfac_max - ENDIF - ELSE - layfac=0.0_r8 - ENDIF -c----------------------------------------------------------------------- -c calculate basic delta, torque, balance, error fields. -c----------------------------------------------------------------------- - delta_n_p=1e-2 - ! kappa_hat of Eq. (61) is implicit in the br_th expression at the - ! end of this routine: sqrt(maxbal/lu*(sval**2/2)) is identically - ! sqrt(maxbal/(lu*kappa_hat)) for kappa_hat=2/sval**2. Named here - ! for output only; it is never used in a physics expression, so - ! the threshold is unchanged. - IF (sval/=0.0_r8) THEN - kaphat=2.0_r8/sval**2.0 - ELSE - kaphat=0.0_r8 - ENDIF - delta=riccati(inQ,inQ_e,inQ_i,inpr,inc_beta,inds,intau,inpe) - psi0=1.0/ABS(delta+delta_n_p) ! a.u. - jxb=-AIMAG(1.0/(delta+delta_n_p)) ! a.u. -c---------------------------------------------------------------------- -c find solutions based on simple torque balance. -c----------------------------------------------------------------------- - IF (Q0>inQ_e) THEN - inQ_max=2.0*Q0 - inQ_min=1.05*inQ_e - ELSE - inQ_max=0.95*inQ_e - IF (Q0>0) THEN - inQ_min=0.8*inQ_i - ELSE - inQ_min=1.5*MINVAL((/Q0,inQ_i/)) - ENDIF - ENDIF - - ! Scan of rotation - inQ_max=10.0 - inQ_min=-10.0 - inum=slayer_inum - ALLOCATE(inQs(0:inum),deltal(0:inum),jxbl(0:inum),bal(0:inum)) - DO i=0,inum - inQs(i)=inQ_min+(REAL(i)/inum)*(inQ_max-inQ_min) - deltal(i)=riccati(inQs(i),inQ_e,inQ_i, - $ inpr,inc_beta,inds,intau,inpe) - jxbl(i)=-AIMAG(1.0/(deltal(i)+delta_n_p)) - bal(i)=2.0*inpr*(Q0-inQs(i))/jxbl(i) - ENDDO - - ! Capture the coarse pass (tag 0). This only reads inQs/deltal/ - ! jxbl/bal, so both the ascii dump and the refinement below are - ! bit for bit unchanged. The Eq. (61) right hand side numerator - ! is recomputed rather than harvested out of the bal expression - ! above; 2.0*inpr*(Q0-inQs(i)) is a pure product chain, so the - ! recomputed value is identical to the one formed inline. - DO i=0,inum - cqs(i+1)=inQs(i) - cdlt(i+1)=deltal(i) - clhs(i+1)=jxbl(i) - crhs(i+1)=2.0*inpr*(Q0-inQs(i)) - cbal(i+1)=bal(i) - cpass(i+1)=0 - ENDDO - - ! Write torque balance curves to file for diagnostic purposes - IF(ascii_flag)THEN - OPEN(UNIT=out_unit,FILE="gpec_slayer_torque_balance_m"// - $ TRIM(sm)//"_n"//TRIM(sn)//".out", - $ STATUS="UNKNOWN") - WRITE(out_unit,'(1x,5(a17))') "inQ","RE(delta)", - $ "IM(delta)","jxb","bal" - DO i=0,inum - WRITE(out_unit,'(1x,5(es17.8e3))') - $ inQs(i),REAL(deltal(i)),AIMAG(deltal(i)),jxbl(i),bal(i) - ENDDO - CLOSE(out_unit) - ENDIF - - ! The coarse scan above gives the overall torque-balance shape - ! and the diagnostic output. The locking "nose" (the maximum of - ! bal) can be a very narrow spike near inQ=Q0, however, and the - ! coarse grid can step right over it, leaving a spuriously - ! negative MAXVAL(bal) and hence a NaN br_th. Bracket the coarse - ! maximum and iteratively refine the scan around the running peak - ! so the nose is resolved regardless of how narrow it is. Exclude - ! non-finite entries (NaN from 0/0, Inf from a near-zero jxbl). - index=MAXLOC(bal,MASK=(bal==bal .AND. ABS(bal)maxbal) THEN - maxbal=bloc - xpk=xq - ENDIF - ENDDO - rlo=xpk-2.0*rdq - rhi=xpk+2.0*rdq - ENDDO - Q_sol=xpk - omega_sol=xpk/Qconv - ! If even the refined nose is non-positive the surface has no - ! finite penetration threshold; floor at zero and warn rather - ! than propagating a NaN into b_crit/Phi_res_crit downstream. - IF (maxbal>0.0_r8) THEN - br_th=sqrt(maxbal/lu*(sval**2.0/2.0)) - ELSE - br_th=0.0_r8 - WRITE(*,'(1x,a,i0,a,i0,a)') - $ "!! WARNING: SLAYER torque balance has no positive "// - $ "maximum at m=",mms,", n=",nns,"; br_th set to 0" - ENDIF -c----------------------------------------------------------------------- -c assemble the Eq. (61) record: b_r/B_phi implied by each balance -c point, then merge the coarse and refined samples onto one -c ascending Q grid so the narrow nose is densely resolved and the -c curve can be interpolated in post processing. -c----------------------------------------------------------------------- - ! Dedicated logarithmic sweep through the Q_e singularity, half - ! the samples on each side, |Q-Q_e| running from slayer_qefar in - ! to slayer_qenear. br_th is already fixed above and these are - ! tagged slayer_qetag, so they are invisible to the peak search. - DO i=1,slayer_nqe/2 - xq=slayer_qefar*(slayer_qenear/slayer_qefar) - $ **(REAL(i-1,r8)/REAL(slayer_nqe/2-1,r8)) - DO j=0,1 - k=(inum+1)*(nref+1)+(i-1)*2+j+1 - IF (j==0) THEN - cqs(k)=inQ_e-xq - ELSE - cqs(k)=inQ_e+xq - ENDIF - cdlt(k)=riccati(cqs(k),inQ_e,inQ_i,inpr, - $ inc_beta,inds,intau,inpe) - clhs(k)=-AIMAG(1.0/(cdlt(k)+delta_n_p)) - crhs(k)=2.0*inpr*(Q0-cqs(k)) - cbal(k)=crhs(k)/clhs(k) - cpass(k)=slayer_qetag - ENDDO - ENDDO - ! deliberately the same expression form as br_th above, so the - ! peak sample reproduces br_th exactly rather than differing in - ! the last bit. - DO k=1,slayer_nq - IF (cbal(k)==cbal(k) .AND. cbal(k)>0.0_r8 - $ .AND. ABS(cbal(k))=1) - IF (cqs(iperm(j))<=xtmp) EXIT - iperm(j+1)=iperm(j) - j=j-1 - ENDDO - iperm(j+1)=kk - ENDDO - IF (PRESENT(diag)) THEN - DO k=1,slayer_nq - kk=iperm(k) - diag%qs(k)=cqs(kk) - diag%dlt(k)=cdlt(kk) - diag%lhs(k)=clhs(kk) - diag%rhs(k)=crhs(kk) - diag%bal(k)=cbal(kk) - diag%brb(k)=cbrb(kk) - diag%kpass(k)=cpass(kk) - ENDDO - ! scalars are taken from the local copies, never from the - ! sglobal_mod globals Q/Q_e/Q_i/ds/tau/c_beta/pr/pe: riccati - ! overwrites those on every call, so by this point the module - ! Q holds the last refinement sample rather than Q0. - diag%alpha=delta_n_p - diag%kaphat=kaphat - diag%slun=lu - diag%prnd=inpr - diag%q0v=Q0 - diag%qcnv=Qconv - diag%qev=inQ_e - diag%qiv=inQ_i - diag%dsv=inds - diag%cbeta=inc_beta - diag%tratio=intau - diag%pev=inpe - diag%lfac=layfac - diag%dnorm=delta_n - diag%rhos=rho_s - diag%etav=eta - diag%viscv=visc - diag%tauh=tau_h - diag%taur=tau_r - diag%tauv=tau_v - diag%taui=tau_i - diag%shr=sval - diag%bl=b_l - diag%va=v_a - diag%rhom=rho - diag%lbet=lbeta - diag%omg=omega - diag%qsol=Q_sol - diag%wsol=omega_sol - diag%brth=br_th - diag%qmn=inQ_min - diag%qmx=inQ_max - IF (maxbal>-HUGE(maxbal)) THEN - diag%mxbal=maxbal - ELSE - diag%mxbal=0.0_r8 - ENDIF - ENDIF - DEALLOCATE(inQs,deltal,jxbl,bal) - - RETURN - END SUBROUTINE gpec_slayer - - END MODULE gslayer_mod diff --git a/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb b/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb deleted file mode 100644 index d7f16a2b4..000000000 --- a/src/Tearing/CriticalResonantField/CRF Dev/pole_testing.ipynb +++ /dev/null @@ -1,395 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "0", - "metadata": {}, - "outputs": [], - "source": [ - "using Pkg\n", - "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", - "Base.active_project()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1", - "metadata": {}, - "outputs": [], - "source": [ - "using GeneralizedPerturbedEquilibrium\n", - "using GeneralizedPerturbedEquilibrium: Analysis\n", - "using GeneralizedPerturbedEquilibrium: InnerLayer\n", - "using GeneralizedPerturbedEquilibrium.InnerLayer: solve_inner\n", - "using GeneralizedPerturbedEquilibrium: Tearing\n", - "using ..InnerLayer\n", - "using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters,\n", - " SLAYERModel, SLAYERParameters\n", - "\n", - "using Plots\n", - "using Printf\n", - "default(\n", - " fontfamily=\"Georgia\",\n", - " margin=12Plots.mm,\n", - " size=(800, 500),\n", - " dpi=150\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2", - "metadata": {}, - "outputs": [], - "source": [ - "struct TorqueBalance{M<:InnerLayerModel,P}\n", - " model::M\n", - " params::P\n", - " Q0::Float64\n", - " P::Float64\n", - " lu::Float64\n", - " sval::Float64\n", - "end\n", - "\n", - "function torque_balance_value(tb::TorqueBalance, Q::Number)\n", - " Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing\n", - " alpha = 1e-2\n", - " jxb = -imag(1.0 / (Δ + alpha))\n", - " return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ\n", - "end\n", - "\n", - "function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=20000)\n", - " Qs = range(Qmin, Qmax; length=n)\n", - " torque_out = [torque_balance_value(tb, q) for q in Qs]\n", - " bal = [x[1] for x in torque_out]\n", - " Δs = [x[2] for x in torque_out]\n", - " positive = isfinite.(bal) .& (bal .> 0.0)\n", - "\n", - " if !any(positive)\n", - " @warn \"No positive torque balance found in the specified range. Try increasing the number of Q samples scanned or adjusting the range.\"\n", - " return Qs, bal, NaN, NaN, NaN, Δs\n", - " end\n", - "\n", - " # Find the highest point, then remove candidates within ΔQ of it.\n", - "\n", - " idx_maxima = findall(isfinite.(bal) .& (bal .> 0))\n", - " sort!(idx_maxima, by=i -> bal[i], rev=true)\n", - " selected = Int[]\n", - " min_ΔQ = 0.001 * abs(Qmax - Qmin)\n", - "\n", - " for i in idx_maxima\n", - " if all(abs(Qs[i] - Qs[j]) > min_ΔQ for j in selected)\n", - " push!(selected, i)\n", - " end\n", - " length(selected) == 2 && break\n", - " end\n", - "\n", - " if isempty(selected)\n", - " @warn \"No usable positive torque-balance maximum found. Try increasing the number of Q samples scanned or adjusting the range.\"\n", - " return Qs, bal, NaN, NaN, NaN, Δs\n", - " end\n", - "\n", - " idx_maxima = selected\n", - "\n", - "\n", - " # Find all local maxima in the positive region\n", - " #idx_positive = findall(positive)\n", - " #idx_maxima = idx_positive[partialsortperm(bal[idx_positive], 1:min(2, length(idx_positive)); rev=true)]\n", - " maxima = bal[idx_maxima]\n", - " Qs_maxima = Qs[idx_maxima]\n", - " # find index, q val and bal val of the q closest to Q_e\n", - " idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e)) # + Q_e since Q_e = -omega_e * Qconv\n", - " q_closest_Q_e = Qs[idx_closest_Q_e]\n", - " bal_closest_Q_e = bal[idx_closest_Q_e]\n", - "\n", - " # find index, q val and bal val of the q closest to Q_i\n", - " idx_closest_Q_i = argmin(abs.(Qs .+ tb.params.Q_i)) # + Q_i since Q_i = -omega_i * Qconv\n", - " q_closest_Q_i = Qs[idx_closest_Q_i]\n", - " bal_closest_Q_i = bal[idx_closest_Q_i]\n", - " \n", - " println(\"Local maxima indices: \", idx_maxima, \" with values: \", maxima, \" and corresponding Qs: \", Qs_maxima, \" closest Q to Q_e: \", q_closest_Q_e, \" closest Q to Q_i: \", q_closest_Q_i)\n", - " # check if 1st q_maxima is same as Q_e or Q_i from p\n", - " if idx_maxima[1] == idx_closest_Q_e || idx_maxima[1] == idx_closest_Q_i\n", - " if length(idx_maxima) < 2\n", - " @warn \"The first local maximum corresponds to a pole from Q_e or Q_i, but there is no second local maximum to select. Try increasing the number of Q samples scanned or adjusting the range.\"\n", - " return Qs, bal, NaN, NaN, NaN, Δs\n", - " end\n", - " println(\"Warning: The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead.\")\n", - " if idx_maxima[2] == idx_closest_Q_e || idx_maxima[2] == idx_closest_Q_i\n", - " @warn \"Both the first and second local maxima correspond to poles from Q_e or Q_i. Unable to select a valid local maximum. Try increasing the number of Q samples scanned or adjusting the range.\"\n", - " return Qs, bal, NaN, NaN, NaN, Δs\n", - " end\n", - " idx_maximum = idx_maxima[2]\n", - " maximum = bal[idx_maximum]\n", - " Qmaximum = Qs[idx_maximum]\n", - " else\n", - " idx_maximum = idx_maxima[1]\n", - " maximum = bal[idx_maximum]\n", - " Qmaximum = Qs[idx_maximum]\n", - " end\n", - "\n", - " println(\"Selected local maximum index: \", idx_maximum, \" with value: \", maximum, \" and corresponding Q: \", Qmaximum)\n", - "\n", - " br_crit = sqrt(maximum / tb.lu * (tb.sval^2 / 2.0))\n", - "\n", - " return Qs, bal, Qmaximum, br_crit, idx_maximum, Δs\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3", - "metadata": {}, - "outputs": [], - "source": [ - "p = GeneralizedPerturbedEquilibrium.InnerLayer.slayer_parameters(\n", - " n_e=1e19, t_e=1e3, t_i=1e3,\n", - " omega=0.0, omega_e=40, omega_i=-20,\n", - " qval=2.0, sval_r=0.5, bt=2.0, rs=1.0, R0=3.0, mu_i=2.0, zeff=1.0,\n", - " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", - ")\n", - "p = GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERParameters(\n", - " ising=p.ising,\n", - " m=p.m, n=p.n,\n", - " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", - " P_perp=p.P_perp, P_tor=p.P_tor,\n", - " Q_e=2, Q_i=3, iota_e=p.iota_e,\n", - " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", - " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", - " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", - " eta=p.eta, d_beta=p.d_beta,\n", - " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", - ")\n", - "\n", - "tb = TorqueBalance(\n", - " GeneralizedPerturbedEquilibrium.InnerLayer.SLAYERModel(;),\n", - " p,\n", - " 0.5,\n", - " 61.0, #1.0\n", - " p.lu,\n", - " p.sval_r\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4", - "metadata": {}, - "outputs": [], - "source": [ - "Qs, bal, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=-2.5, Qmax=0, n=200000)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5", - "metadata": {}, - "outputs": [], - "source": [ - "Qmax = 10\n", - "Qmin = -10\n", - "positive = isfinite.(bal) .& (bal .> 0.0)\n", - "\n", - "if !any(positive)\n", - " @warn \"No positive torque balance found in the specified range. Try increasing the number of Q samples scanned or adjusting the range.\"\n", - " return Qs, bal, NaN, NaN, NaN, Δs\n", - "end\n", - "\n", - "# Find the highest point, then remove candidates within ΔQ of it.\n", - "\n", - "idx_maxima = findall(isfinite.(bal) .& (bal .> 0))\n", - "sort!(idx_maxima, by=i -> bal[i], rev=true)\n", - "selected = Int[]\n", - "min_ΔQ = 0.001 * abs(Qmax - Qmin)\n", - "\n", - "for i in idx_maxima\n", - " if all(abs(Qs[i] - Qs[j]) > min_ΔQ for j in selected)\n", - " push!(selected, i)\n", - " end\n", - " length(selected) == 2 && break\n", - "end\n", - "\n", - "if isempty(selected)\n", - " @warn \"No usable positive torque-balance maximum found. Try increasing the number of Q samples scanned or adjusting the range.\"\n", - " return Qs, bal, NaN, NaN, NaN, Δs\n", - "end\n", - "\n", - "idx_maxima = selected\n", - "\n", - "\n", - "# Find all local maxima in the positive region\n", - "#idx_positive = findall(positive)\n", - "#idx_maxima = idx_positive[partialsortperm(bal[idx_positive], 1:min(2, length(idx_positive)); rev=true)]\n", - "maxima = bal[idx_maxima]\n", - "Qs_maxima = Qs[idx_maxima]\n", - "# find index, q val and bal val of the q closest to Q_e\n", - "idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e)) # + Q_e since Q_e = -omega_e * Qconv\n", - "q_closest_Q_e = Qs[idx_closest_Q_e]\n", - "bal_closest_Q_e = bal[idx_closest_Q_e]\n", - "\n", - "# find index, q val and bal val of the q closest to Q_i\n", - "idx_closest_Q_i = argmin(abs.(Qs .+ tb.params.Q_i)) # + Q_i since Q_i = -omega_i * Qconv\n", - "q_closest_Q_i = Qs[idx_closest_Q_i]\n", - "bal_closest_Q_i = bal[idx_closest_Q_i]\n", - "\n", - "println(\"Local maxima indices: \", idx_maxima, \" with values: \", maxima, \" and corresponding Qs: \", Qs_maxima, \" closest Q to Q_e: \", q_closest_Q_e, \" closest Q to Q_i: \", q_closest_Q_i)\n", - "# check if 1st q_maxima is same as Q_e or Q_i from p\n", - "if idx_maxima[1] == idx_closest_Q_e || idx_maxima[1] == idx_closest_Q_i\n", - " if length(idx_maxima) < 2\n", - " @warn \"The first local maximum corresponds to a pole from Q_e or Q_i, but there is no second local maximum to select. Try increasing the number of Q samples scanned or adjusting the range.\"\n", - " return Qs, bal, NaN, NaN, NaN, Δs\n", - " end\n", - " println(\"Warning: The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead.\")\n", - " if idx_maxima[2] == idx_closest_Q_e || idx_maxima[2] == idx_closest_Q_i\n", - " @warn \"Both the first and second local maxima correspond to poles from Q_e or Q_i. Unable to select a valid local maximum. Try increasing the number of Q samples scanned or adjusting the range.\"\n", - " return Qs, bal, NaN, NaN, NaN, Δs\n", - " end\n", - " idx_maximum = idx_maxima[2]\n", - " maximum = bal[idx_maximum]\n", - " Qmaximum = Qs[idx_maximum]\n", - "else\n", - " idx_maximum = idx_maxima[1]\n", - " maximum = bal[idx_maximum]\n", - " Qmaximum = Qs[idx_maximum]\n", - "end\n", - "\n", - "println(\"Selected local maximum index: \", idx_maximum, \" with value: \", maximum, \" and corresponding Q: \", Qmaximum)\n", - "\n", - "br_crit = sqrt(maximum / tb.lu * (tb.sval^2 / 2.0))\n", - "\n", - "println(Qmaximum, br_crit, idx_maximum)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6", - "metadata": {}, - "outputs": [], - "source": [ - "jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", - "T_VISC = [2.0 * tb.P * (tb.Q0 - q) for q in Qs] #(q, jxb) in zip(Qs, jxbs)]\n", - "#br_t = brcrit\n", - "#println(tb.lu, \" \", tb.sval, \" \", br_t, \" \", p.bt, \" \", 1e-2)\n", - "#@printf(\"br_crit = %.5e\\n\", brcrit)\n", - "#T_EM = tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs\n", - "T_EM = -imag(1.0 ./ (Δs .+ 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", - "i = Qpeak_ind\n", - "println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", - "println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", - "println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", - "\n", - "#T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", - "#T_visc ∝ 2 P (Q0 − Q)\n", - "\n", - "xmi = -2.5\n", - "xma = 0\n", - "\n", - "\"\"\"\n", - "p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2, xlim=(xmi, xma))\n", - "#plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Δ\")\n", - "#title!(p1, \"Inner-layer Δ(Q)\")\n", - "\"\"\"\n", - "\n", - "p1 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(-1000,1000))\n", - "plot!(p1, Qs, T_EM, label=\"T_EM\", lw=2)\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "xlabel!(p1, \"Q\")\n", - "ylabel!(p1, \"Torque\")\n", - "\n", - "#p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - "p2 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(0,500))\n", - "plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", - "vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - "xlabel!(p2, \"Q\")\n", - "ylabel!(p2, \"Torque\")\n", - "#title!(p2, \"jxb(Q) = -Im[1/(Δ + δ_n_p)]\")\n", - "\n", - "p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2, xlim=(xmi, xma)) #xlim=(-1.3,-.8),ylim=(375,389))#\n", - "plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - "loc_max_ind= [4001, 10050, 10094, 10186, 10195, 10213, 10258, 10272, 10340, 10355, 10365, 10376, 10385, 10387, 10392, 10405, 10412, 10421, 10430, 10443, 10450, 10457, 10470, 10473, 10494, 10498, 10512, 10520, 10537, 10544, 10552, 10557, 10573, 10576, 10578, 10586, 10588, 10596, 10606, 10610, 10632, 10637, 10648, 10655, 10659, 10665, 10670, 10676, 10679, 10691, 10695, 10697, 10705, 10707, 10719, 10730, 10742, 10746, 10751, 10755, 10761, 10765, 10770, 10776, 10778, 10783, 10786, 10788, 10793, 10798, 10810, 10814, 10821, 10824, 10829, 10834, 10837, 10841, 10843, 10847, 10849, 10856, 10858, 10861, 10863, 10868, 10871, 10877, 10881, 10887, 10892, 10895, 10897, 10900, 10904, 10906, 10909, 10911, 10916, 10918, 10923, 10929, 10931, 10933, 10937, 10942, 10945, 10950, 10955, 10959, 10963, 10969, 10971, 10974, 10976, 10981, 10984, 10988, 10991, 10994, 10997, 11001, 11003, 11005, 11012, 11015, 11018, 11021, 11024, 11027, 11029, 11031, 11033, 11036, 11039, 11042, 11044, 11048, 11053, 11056, 11058, 11060, 11062, 11064, 11068, 11078, 11080, 11083, 11085, 11096, 11098, 11100, 11102, 11104, 11106, 11109, 11111, 11116, 11119, 11121, 11128, 11131, 11133, 11139, 11145, 11148, 11150, 11152, 11155, 11157, 11162, 11165, 11169, 11174, 11180, 11183, 11186, 11188, 11205, 11218, 11220, 11222, 11224, 11228, 11233, 11235, 11243, 11249, 11254, 11257, 11259, 11276, 11281, 11294, 11299, 11303, 11306, 11312, 11316, 11319, 11322, 11335, 11341, 11358, 11369, 11376, 11381, 11386, 11391, 11394, 11396, 11399, 11406, 11410, 11417, 11420, 11422, 11428, 11437, 11446, 11448, 11453, 11457, 11469, 11473, 11486, 11497, 11513, 11540, 11542, 11544, 11552, 11554, 11565, 11570, 11573, 11578, 11587, 11594, 11597, 11602, 11614, 11620, 11633, 11654, 11660, 11662, 11669, 11677, 11682, 11687, 11711, 11764, 11804, 11806, 11821, 11848, 11860, 11882, 11901, 11928, 11991, 12108]\n", - "#plot!(p3, Qs[loc_max_ind], bal[loc_max_ind], seriestype=:scatter, label=\"Local Maxima\", color=:red)\n", - "loc_mx2 = [4001, 10963, 10955, 10950, 11005]\n", - "#plot!(p3, Qs[loc_mx2], bal[loc_mx2], seriestype=:scatter, label=\"Local Maxima 2\", color=:green)\n", - "ylabel!(p3, \"Torque Balance\")\n", - "#title!(p3, \"2P(Q0-Q)/jxb\")\n", - "xlabel!(p3, \"Q\")\n", - "vline!([Qpeak], label=\"Max Balance\", linestyle=:dash)\n", - "\n", - "# find index, q val and bal val of the q closest to Q_e\n", - "println(\"Q_e: \", -tb.params.Q_e)\n", - "idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e))\n", - "q_closest_Q_e = Qs[idx_closest_Q_e]\n", - "bal_closest_Q_e = bal[idx_closest_Q_e]\n", - "println(\"Closest Q to Q_e: \", q_closest_Q_e, \" with balance value: \", bal_closest_Q_e, \" at index: \", idx_closest_Q_e)\n", - "println(\"B crit: \", brcrit)\n", - "vline!([-tb.params.Q_e], label=\"Q_e\", linestyle=:dashdot, color=:orange)\n", - "vline!([q_closest_Q_e], label=\"Closest Q to Q_e\", linestyle=:dashdot, color=:purple)\n", - "\n", - "#plot(p1, p2, p3, layout=(3,1), size=(800, 1000))\n", - "plot(p3, layout=(1,1), size=(800, 1000))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8", - "metadata": {}, - "outputs": [], - "source": [ - "# compare Q_e to Q of max(bal)\n", - "println(\"-Q_e = \", -p.Q_e, \" Q_i = \", p.Q_i, \" Q_peak = \", Qpeak, \" br_crit = \", brcrit)\n", - "# check if |Qpeak+Q_e| < 1e-2\n", - "println(\"|Qpeak + Q_e| = \", abs(Qpeak + p.Q_e))\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9", - "metadata": {}, - "outputs": [], - "source": [ - "# Check torque is balanced\n", - "\n", - "viscous_torque = 2*tb.P*(tb.Q0 - Qpeak)\n", - "electromagnetic_torque = -imag(1.0 / (Δs[Qpeak_ind] + 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", - "\n", - "# delta_n_p = 1e-2\n", - "# jxb = -imag(1.0 / (Δ + delta_n_p))\n", - "# bal = 2.0 * tb.P * (tb.Q0 - Q) / jxb\n", - "# br_crit = sqrt(maxbal / tb.lu * (tb.sval^2 / 2.0))\n", - "\n", - "@printf(\"br_crit = %.5e\\n\", brcrit)\n", - "@printf(\"viscous_torque = %.5e\\n\", viscous_torque)\n", - "@printf(\"electromagnetic_torque = %.5e\\n\", electromagnetic_torque)\n", - "@printf(\"ratio = %.10f\\n\", viscous_torque / electromagnetic_torque)" - ] - } - ], - "metadata": { - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/src/Tearing/CriticalResonantField/CRF Dev/sample_number.jls b/src/Tearing/CriticalResonantField/CRF Dev/sample_number.jls deleted file mode 100644 index c320ccaa9d62b84e8037da421fd24ccf2da49346..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 ucmXr_@{wa Date: Thu, 20 Aug 2026 14:23:27 -0400 Subject: [PATCH 08/14] Cleaned up notebooks/ignore --- .gitignore | 1 - .../slayer_ex.ipynb | 257 +----------------- 2 files changed, 11 insertions(+), 247 deletions(-) diff --git a/.gitignore b/.gitignore index 8f463f94f..99ce15eb1 100644 --- a/.gitignore +++ b/.gitignore @@ -38,5 +38,4 @@ scratch/ # Local profiling scratch (one-off study scripts, not part of the package) profiling/ -examples/b_crit_standalone_example/ src/Tearing/CriticalResonantField/CRF Dev/ diff --git a/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb b/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb index ed88780dd..4e59b802d 100644 --- a/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb +++ b/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb @@ -6,17 +6,6 @@ "id": "0", "metadata": {}, "outputs": [], - "source": [ - "using Pkg\n", - "Pkg.build(\"GeneralizedPerturbedEquilibrium\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1", - "metadata": {}, - "outputs": [], "source": [ "using Pkg\n", "Pkg.activate(\"/Users/bursche/Documents/GitHub/JPEC_BCRIT\")\n", @@ -38,74 +27,17 @@ { "cell_type": "code", "execution_count": null, - "id": "2", - "metadata": {}, - "outputs": [], - "source": [ - "h5path = \"/Users/bursche/Documents/GitHub/JPEC_BCRIT/examples/DIIID-like_SLAYER_and_bcrit_example/gpec.h5\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3", - "metadata": {}, - "outputs": [], - "source": [ - "using HDF5\n", - "\n", - "h5open(h5path, \"r\") do file\n", - " println(\"Top-level keys:\")\n", - " println(collect(keys(file)))\n", - "\n", - " if haskey(file, \"Tearing\")\n", - " println(\"\\nKeys in Tearing:\")\n", - " println(collect(keys(file[\"Tearing\"])))\n", - "\n", - " if haskey(file[\"Tearing\"], \"CriticalResonantField\")\n", - " println(\"\\nKeys in Tearing/CriticalResonantField:\")\n", - " println(collect(keys(file[\"Tearing\"][\"CriticalResonantField\"])))\n", - " end\n", - " else\n", - " println(\"No Tearing group found.\")\n", - " end\n", - "end" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4", + "id": "1", "metadata": {}, "outputs": [], "source": [ - "# Print the contents of the Tearing/CriticalResonantField group\n", - "h5open(h5path, \"r\") do file\n", - " if haskey(file, \"Tearing\") && haskey(file[\"Tearing\"], \"CriticalResonantField\")\n", - " println(\"\\nContents of Tearing/CriticalResonantField:\")\n", - " # Iterate over the keys in the Tearing/CriticalResonantField group and print their names and types\n", - " for key in keys(file[\"Tearing\"][\"CriticalResonantField\"])\n", - " dataset = file[\"Tearing\"][\"CriticalResonantField\"][key]\n", - " println(\"Key: $key, Type: $(typeof(dataset))\")\n", - " # print data \n", - " if isa(dataset, HDF5.Dataset)\n", - " data = read(dataset)\n", - " println(\"Data: $data\")\n", - " end\n", - " end\n", - " else\n", - " println(\"No Tearing/CriticalResonantField group found.\")\n", - " end\n", - " # Print bcrit data as .2e (in one line)\n", - " println(\"\\nBcrit data: $(join([@sprintf(\"%.2e\", x) for x in read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"])], \" \"))\")\n", - "end\n", - "\n" + "h5path = \"gpec.h5\"" ] }, { "cell_type": "code", "execution_count": null, - "id": "5", + "id": "2", "metadata": {}, "outputs": [], "source": [ @@ -115,22 +47,14 @@ { "cell_type": "code", "execution_count": null, - "id": "6", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7", + "id": "3", "metadata": {}, "outputs": [], "source": [ "function bcrit_diag_plots(Δs, Qs, bal, name)\n", "\n", " p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2)\n", - " #plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", + " plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", " xlabel!(p1, \"Q\")\n", " ylabel!(p1, \"Δ\")\n", " title!(p1, \"Inner-layer Δ(Q) - $name\")\n", @@ -143,7 +67,6 @@ "\n", " plot(p1, p2, layout=(2,1), size=(500, 700))\n", "\n", - "\n", "end\n", "\n", "function plot_all_vs_rational_q(h5path)\n", @@ -172,184 +95,28 @@ " display(fig)\n", " #return fig\n", " end\n", - "end\n", - "\n", - "plot_all_vs_rational_q(h5path)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8", - "metadata": {}, - "outputs": [], - "source": [ - "using GeneralizedPerturbedEquilibrium\n", - "using GeneralizedPerturbedEquilibrium: Analysis\n", - "using GeneralizedPerturbedEquilibrium.InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters,\n", - " SLAYERModel, SLAYERParameters, slayer_parameters\n", - "using GeneralizedPerturbedEquilibrium.Tearing.CriticalResonantField: TorqueBalance, torque_balance_value, torque_balance_scan\n", - "\n", - "surface_num = 5\n", - "h5open(h5path, \"r\") do file\n", - " sval_r = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"sval\"])\n", - " Q0 = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"Q0\"])\n", - " m = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"m\"])\n", - " n = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"n\"])\n", - " qval = m/n\n", - " Q_e = read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"])[surface_num]\n", - " Q_i = read(file[\"Tearing\"][\"PerSurface\"][\"Q_i\"])[surface_num]\n", - " lu = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"lu\"])\n", - " rs = read(file[\"Tearing\"][\"PerSurface\"][\"rs\"])[surface_num]\n", - " P = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"P\"])\n", - "\n", - " p = slayer_parameters( # Call slayer_parameters function to instantiate slab parameters\n", - " n_e=1e19, t_e=1e3, t_i=1e3,\n", - " omega=0.0, omega_e=40, omega_i=-20,\n", - " qval=qval, sval_r=sval_r, bt=2.0, rs=rs, R0=3.0, mu_i=2.0, zeff=1.0,\n", - " chi_perp=1.0, chi_tor=1.0, m=2, n=1\n", - " )\n", - " p = SLAYERParameters( # Modify the created SLAYERParameters struct to modify electron and ion diamagnetic resonance frequencies\n", - " ising=p.ising,\n", - " m=p.m, n=p.n,\n", - " tau=p.tau, lu=p.lu, c_beta=p.c_beta, D_norm=p.D_norm,\n", - " P_perp=p.P_perp, P_tor=p.P_tor,\n", - " Q_e=Q_e, Q_i=Q_i, iota_e=p.iota_e,\n", - " tauk=p.tauk, tau_r=p.tau_r, delta_n=p.delta_n,\n", - " rs=p.rs, R0=p.R0, bt=p.bt, sval_r=p.sval_r,\n", - " dr_val=p.dr_val, dgeo_val=p.dgeo_val,\n", - " eta=p.eta, d_beta=p.d_beta,\n", - " dc_tmp=p.dc_tmp, dc_type=p.dc_type\n", - " )\n", - "\n", - " tb = TorqueBalance( # Generate a TorqueBalance struct using the default (Fitzpatrick) SLAYERModel and the modified SLAYERParameters\n", - " SLAYERModel(;),\n", - " p, # Slayer Parameters struct\n", - " Q0, # Normalized rotation Q\n", - " P, # Magnetic Prandtl number\n", - " p.lu, # Lundquist Number\n", - " p.sval_r # r-based magnetic shear\n", - " )\n", - " Qmin = -.2\n", - " Qmax = .2\n", - " Qs, bal, Qpeak, brcrit, Qpeak_ind, Δs = torque_balance_scan(tb,Qmin=Qmin, Qmax=Qmax, n=1000) # Run actual torque balance scan, finds inner-layer delta across Q vals\n", - "\n", - "\n", - " jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", - " T_VISC = [2.0 * tb.P * (tb.Q0 - q) for q in Qs] #(q, jxb) in zip(Qs, jxbs)]\n", - " T_EM = -imag(1.0 ./ (Δs .+ 1e-2)) *brcrit^2*tb.lu/(tb.sval^2/2)\n", - " i = Qpeak_ind\n", - " println(T_VISC[i]/(tb.lu * tb.sval^2/2 * (brcrit)^2 * jxbs[i]))\n", - " println(T_VISC[i] / (tb.lu * tb.sval^2/2 * (brcrit * p.bt)^2 * jxbs[i]))\n", - " println(T_VISC[i] / ( (brcrit / p.bt)^2 * jxbs[i]))\n", - "\n", - " #T_EM ∝ S ξ̂ (br/Bφ)² Im[-Δ̂(Q)⁻¹]\n", - " #T_visc ∝ 2 P (Q0 − Q)\n", - "\n", - "\n", - " xmi = Qmin\n", - " xma = Qmax\n", - "\n", - " \"\"\"\n", - " p1 = plot(Qs, imag.(Δs), label=\"Im(Δ)\", lw=2, xlim=(xmi, xma))\n", - " #plot!(p1, Qs, real.(Δs), label=\"Re(Δ)\", lw=2)\n", - " xlabel!(p1, \"Q\")\n", - " ylabel!(p1, \"Δ\")\n", - " #title!(p1, \"Inner-layer Δ(Q)\")\n", - " \"\"\"\n", - "\n", - " p1 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(-1000,1000))\n", - " plot!(p1, Qs, T_EM, label=\"T_EM\", lw=2)\n", - " vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - " xlabel!(p1, \"Q\")\n", - " ylabel!(p1, \"Torque\")\n", - "\n", - " #p2 = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - " p2 = plot( Qs, T_VISC, label=\"T_V\", lw=2, xlim=(xmi, xma))#,ylim=(0,500))\n", - " plot!(p2, Qs, T_EM, label=\"T_EM\", lw=2)\n", - " vline!([Qpeak], label=\"peak Q\", linestyle=:dash)\n", - " xlabel!(p2, \"Q\")\n", - " ylabel!(p2, \"Torque\")\n", - "\n", - " p3 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2, xlim=(xmi, xma),ylim=(-1e-2,1e-2))\n", - " plot!(p3, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - " ylabel!(p3, \"Torque Balance\")\n", - " xlabel!(p3, \"Q\")\n", - " vline!([Qpeak], label=\"Max Balance\", linestyle=:dash)\n", - "\n", - " # find index, q val and bal val of the q closest to Q_e\n", - " println(\"Q_e: \", -tb.params.Q_e)\n", - " idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e))\n", - " q_closest_Q_e = Qs[idx_closest_Q_e]\n", - " bal_closest_Q_e = bal[idx_closest_Q_e]\n", - " println(\"Closest Q to Q_e: \", q_closest_Q_e, \" with balance value: \", bal_closest_Q_e, \" at index: \", idx_closest_Q_e)\n", - " println(\"B crit: \", brcrit)\n", - " vline!([-tb.params.Q_e], label=\"Q_e\", linestyle=:dashdot, color=:orange)\n", - " vline!([q_closest_Q_e], label=\"Closest Q to Q_e\", linestyle=:dashdot, color=:purple)\n", - "\n", - " #plot(p1, p2, p3, layout=(3,1), size=(800, 1000))\n", - " plot(p3, layout=(1,1))#, size=(800, 1000))\n", - "\n", "end" ] }, { "cell_type": "code", "execution_count": null, - "id": "9", + "id": "4", "metadata": {}, "outputs": [], "source": [ - "# plot jxb vs Qs for surface 1\n", - "# jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", - "surface_num = 5\n", - "h5open(h5path, \"r\") do file\n", - " Δs = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"delta\"])\n", - " Qs = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"Q\"])\n", - " bal = read(file[\"Tearing\"][\"CriticalResonantField\"][\"Scan\"][\"surface_$(surface_num)\"][\"balance\"])\n", - " jxbs = [-imag(1.0 / (d + 1e-2)) for d in Δs]\n", - " aplot = plot(Qs, jxbs, label=\"jxb\", lw=2)\n", - " xlabel!(\"Q\")\n", - " ylabel!(\"jxb\")\n", - " title!(\"jxb vs Q for surface $(surface_num)\")\n", - " println(\"max of balance: \", maximum(bal))\n", - " println(\"max of jxb: \", maximum(jxbs))\n", - " println(\"bcrit: \", read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"]))\n", - " println(\"Qpeak: \", read(file[\"Tearing\"][\"CriticalResonantField\"][\"Qpeak\"]))\n", - " println(\"Q_e: \", read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"]))\n", - " # plot balance vs q with bcrit as vertical line\n", - " p2 = plot(Qs, real.(bal), label=\"Re(balance)\", lw=2,xlim=(-.2,.2),ylim=(-1e-2,1e-2))\n", - " plot!(p2, Qs, imag.(bal), label=\"Im(balance)\", lw=2)\n", - " xlabel!(p2, \"Q\")\n", - " ylabel!(p2, \"balance\")\n", - " title!(p2, \"2P(Q0-Q)/jxb - surface $(surface_num)\")\n", - " #vline!(p2, [read(file[\"Tearing\"][\"CriticalResonantField\"][\"br_crit\"])], label=\"bcrit\", lw=2, lc=:red)\n", - " # add Q_e as vertical line\n", - " vline!(p2, [read(file[\"Tearing\"][\"PerSurface\"][\"Q_e\"])[surface_num]], label=\"Q_e\", lw=2, lc=:green)\n", - " vline!(p2, [read(file[\"Tearing\"][\"PerSurface\"][\"Q_i\"])[surface_num]], label=\"Q_i\", lw=2, lc=:blue)\n", - " vline!(p2, [read(file[\"Tearing\"][\"CriticalResonantField\"][\"Qpeak\"])[surface_num]], label=\"Qpeak\", lw=2, lc=:orange)\n", - " #display(aplot)\n", - " display(p2)\n", - "\n", - "end\n", - "\n", - "\"\"\"\n", - "Local maxima indices: [104, 103] with values: [80.15320925995013, 79.66428209429431] and corresponding Qs: [0.35175879396984927, 0.25125628140703515] closest Q to Q_e: -0.35175879396984927 closest Q to Q_i: 0.35175879396984927\n", - "Warning: The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead.\n", - "Selected local maximum index: 103 with value: 79.66428209429431 and corresponding Q: 0.25125628140703515\n", - "\"\"\"" + "plot_all_vs_rational_q(h5path)" ] }, { "cell_type": "code", "execution_count": null, - "id": "10", + "id": "5", "metadata": {}, "outputs": [], "source": [ - "# Plot bcrit vs q surface\n", + "# Plot All Inner-layer Δ(Q) and Torque Balance vs Q for each rational surface\n", "\n", - "# print all contents of bcrit /scan /surface 1/\n", "h5open(h5path, \"r\") do file\n", " bcrit = file[\"Tearing\"][\"CriticalResonantField\"]\n", "\n", @@ -368,17 +135,15 @@ { "cell_type": "code", "execution_count": null, - "id": "11", + "id": "6", "metadata": {}, "outputs": [], "source": [ "p_eq = Analysis.Equilibrium.plot_equilibrium_summary(h5path)\n", "p_ffs = Analysis.ForceFreeStates.plot_ffs_summary(h5path)\n", - "#p_pe = Analysis.PerturbedEquilibrium.plot_perturbed_equilibrium_summary(h5path)\n", "\n", "display(p_eq)\n", - "display(p_ffs)\n", - "#display(p_pe)" + "display(p_ffs)" ] } ], From 674efa402a83310006b724a7fd92aa6b1ac5fbee Mon Sep 17 00:00:00 2001 From: ebursch <76970916+ebursch@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:53:21 -0400 Subject: [PATCH 09/14] Added bcrit profile inputs for angular momentum diffusivity --- .../gpec.toml | 4 +- .../slayer_ex.ipynb | 10 +- .../TkMkr_D3Dlike_Hmode_kinetic.h5 | Bin 57472 -> 69792 bytes src/Tearing/Runner/run_slayer.jl | 145 +++++++++++++++--- 4 files changed, 132 insertions(+), 27 deletions(-) diff --git a/examples/DIIID-like_SLAYER_and_bcrit_example/gpec.toml b/examples/DIIID-like_SLAYER_and_bcrit_example/gpec.toml index b00fad0cc..9b37ce9b4 100644 --- a/examples/DIIID-like_SLAYER_and_bcrit_example/gpec.toml +++ b/examples/DIIID-like_SLAYER_and_bcrit_example/gpec.toml @@ -92,6 +92,6 @@ enabled = true # Run CriticalResonantFi Qmin = -10 # Minimum normalized rotation scanned Qmax = 10 # Maximum normalized rotation scanned n = 2000 # Number of rotation points scanned -viscous_input_type = "angular_momentum_diffusivity" # Either "angular_momentum_diffusivity" or "magnetic_prandtl_number" -viscous_input = 1 # Either Prandlt number or angular momentum diffusivity (based on viscous_input_type). Takes in either an array across q surfaces, a single value for all, or false, which falls back on chi_perp ~ chi_e, electron thermal diffusivity. +viscous_input_type = "magnetic_prandtl_number" # "angular_momentum_diffusivity" # Either "angular_momentum_diffusivity" or "magnetic_prandtl_number" +viscous_input = "test_ang_mom_diff" # Either Prandlt number or angular momentum diffusivity (based on viscous_input_type). Takes in either a string name for the .h5 profile file, a single value for all, or false, which falls back on chi_perp ~ chi_e, electron thermal diffusivity. store_scan = true # Per surface torque and inner layer quantities diff --git a/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb b/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb index 4e59b802d..1b3ee30f5 100644 --- a/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb +++ b/examples/DIIID-like_SLAYER_and_bcrit_example/slayer_ex.ipynb @@ -83,15 +83,21 @@ " sval = [read(scan[\"surface_$(i)\"][\"sval\"]) for i in eachindex(rational_q)]\n", " Q0 = [read(scan[\"surface_$(i)\"][\"Q0\"]) for i in eachindex(rational_q)]\n", " max_balance = maximum.(bal)\n", + " #read eta from persurface\n", + " eta = read(tearing[\"PerSurface\"][\"eta\"])\n", + " # Calculate angular momentum diffusivity\n", + " # P_here = (4π * 1e-7) * abs(chi_here) / eta_here\n", + " ang_mom_diff = P .* eta / (4π * 1e-7)\n", "\n", - " fig = plot(layout=(3, 2), size=(1000, 1200))\n", + " fig = plot(layout=(4, 2), size=(1000, 1200))\n", " plot!(fig[1], rational_q, bcrit; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Critical Resonant Field (T)\", legend=false)\n", " plot!(fig[2], rational_q, max_balance; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Maximum (Torque Balance)\", legend=false)\n", " plot!(fig[3], rational_q, P; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"P\", legend=false)\n", " plot!(fig[4], rational_q, lu; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Lundquist Number\", legend=false)\n", " plot!(fig[5], rational_q, sval; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Magnetic Shear\", legend=false)\n", " plot!(fig[6], rational_q, Q0; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Q0\", legend=false)\n", - "\n", + " plot!(fig[7], rational_q, ang_mom_diff; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Angular Momentum Diffusivity\", legend=false)\n", + " plot!(fig[8], rational_q, eta; marker=:circle, lw=2, xlabel=\"Rational Surface (q)\", ylabel=\"Resistivity (η)\", legend=false)\n", " display(fig)\n", " #return fig\n", " end\n", diff --git a/examples/DIIID-like_ideal_example/TkMkr_D3Dlike_Hmode_kinetic.h5 b/examples/DIIID-like_ideal_example/TkMkr_D3Dlike_Hmode_kinetic.h5 index 2f084f080315cfd157a6c6ed58ddd06cd72bf2e3..4ee95ff2d875c73e8c03e421e9af12ce6393e823 100644 GIT binary patch delta 885 zcmZuvO=uHA6#iy6+axX2ZAc}kDJcq8L{MnS!HbE>Ce;>Wlaoj{q1iNRO%qHHRSSt; z^wuQBgP23~`=KRwh88XahZd(8!=`^OlG{%)=GK$OZnMwS>s!2(Z;FU>Uq{|Z~ zLJ%x~=ml9@m%JmA03!CgJb*~5pIB06J%IJP(GK2Q`IZ&nV<|k@VMMWeG1U(jh+V;8 zt8R2-%1k@~Cp857*jDbh9VvSSKQ^sm!O@oPx^cMTFgLM-tqahO@4DREebf9EPQ@dT z%(?+;XUCq}XLQ4Dm!0321u$m~8BQpu{8Lzt3cv`|m8=B@k1p zc52ep=9Q?@kH@)^=JL9#rO$HhG<7Mjm!`NQE~?t?zJF>~)t4nMoyCGSpHZWUGu#nN zWj!F;N+v_O%z~z77U$JMv7l!4T#o-uLX%5cd8sE^`(YSe(n(ikdHh^FG9!#)_SU7I jj}R{%2to)SXpa9K>>7JS^bEG6oopWIkbNKetWJLbx=WkB delta 71 zcmZ3mkfq@u^8^j%h6fB2wPmFl86cnoO0QsoFc=wFHzv#a3JEd@fCUipn p isa SLAYERParameters, params) || - throw(ArgumentError("CriticalResonantField requires SLAYERParameters; run SLAYER first or provide compatible params.")) + throw(ArgumentError( + "CriticalResonantField requires SLAYERParameters; " * + "run SLAYER first or provide compatible params." + )) surface_index = Int[] Qpeak_vec = Float64[] @@ -385,37 +431,77 @@ function run_critical_resonant_field(equil, intr, ctrl; dir_path="./", slayer_re P_vec = Float64[] scan_data = NamedTuple[] + chi_vec = nothing + P_input = nothing + use_P = false + if ctrl.viscous_input_type === "angular_momentum_diffusivity" + if ctrl.viscous_input === false chi_vec = nothing - use_P = false + elseif ctrl.viscous_input isa AbstractArray + length(ctrl.viscous_input) == length(params) || + throw(ArgumentError( + "CriticalResonantField viscous_input has length " * + "$(length(ctrl.viscous_input)), expected $(length(params))." + )) chi_vec = ctrl.viscous_input - use_P = false + elseif ctrl.viscous_input isa Number - chi_vec = fill(ctrl.viscous_input, length(params)) - use_P = false + chi_vec = fill(Float64(ctrl.viscous_input), length(params)) + + elseif ctrl.viscous_input isa String + viscous_profile === nothing && + throw(ArgumentError( + "CriticalResonantField profile " * + "'$(ctrl.viscous_input)' was not loaded." + )) + chi_vec = viscous_profile + else - throw(ArgumentError("Invalid viscous_input for angular_momentum_diffusivity.")) + throw(ArgumentError( + "Invalid viscous_input for angular_momentum_diffusivity." + )) end elseif ctrl.viscous_input_type === "magnetic_prandtl_number" - chi_vec = nothing + use_P = true + if ctrl.viscous_input isa AbstractArray - P_vec = ctrl.viscous_input + length(ctrl.viscous_input) == length(params) || + throw(ArgumentError( + "CriticalResonantField viscous_input has length " * + "$(length(ctrl.viscous_input)), expected $(length(params))." + )) + P_input = ctrl.viscous_input + elseif ctrl.viscous_input isa Number - P_vec = fill(ctrl.viscous_input, length(params)) + P_input = fill(Float64(ctrl.viscous_input), length(params)) + + elseif ctrl.viscous_input isa String + viscous_profile === nothing && + throw(ArgumentError( + "CriticalResonantField profile " * + "'$(ctrl.viscous_input)' was not loaded." + )) + P_input = viscous_profile + elseif ctrl.viscous_input === false use_P = false + else - throw(ArgumentError("Invalid viscous_input for magnetic_prandtl_number.")) + throw(ArgumentError( + "Invalid viscous_input for magnetic_prandtl_number." + )) end else throw(ArgumentError( "Invalid viscous_input_type: $(ctrl.viscous_input_type). " * - "Must be 'angular_momentum_diffusivity' or 'magnetic_prandtl_number'." + "Must be 'angular_momentum_diffusivity' or " * + "'magnetic_prandtl_number'." )) end @@ -427,20 +513,29 @@ function run_critical_resonant_field(equil, intr, ctrl; dir_path="./", slayer_re eta_here = p.eta if use_P - P_here = P_vec[isurf] + P_here = P_input isa AbstractArray ? + Float64(P_input[isurf]) : + _eval(P_input, psi_here) + elseif chi_vec === nothing - try - chi_here = _eval(chi_prof, psi_here) - catch + if chi_prof === nothing @warn "CriticalResonantField: chi_prof is not provided, using control chi_perp as fallback." chi_here = slayer_ctrl.chi_perp + else + chi_here = _eval(chi_prof, psi_here) end + P_here = (4π * 1e-7) * abs(chi_here) / eta_here + else - chi_here = chi_vec[isurf] + chi_here = chi_vec isa AbstractArray ? + Float64(chi_vec[isurf]) : + _eval(chi_vec, psi_here) + P_here = (4π * 1e-7) * abs(chi_here) / eta_here end + if P_here < 1 @warn "CriticalResonantField: P < 1 at surface $isurf (P = $P_here)." end @@ -454,7 +549,7 @@ function run_critical_resonant_field(equil, intr, ctrl; dir_path="./", slayer_re p.sval_r ) - Qs, bal, Qpeak, br_crit, Qpeak_ind, Δs = + Qs, bal, Qpeak, br_crit, _, Δs = torque_balance_scan( tb; Qmin=ctrl.Qmin, @@ -607,11 +702,15 @@ function run_slayer(equil, surfaces::AbstractVector, delta_prime_matrix::Abstrac rational_psi = Float64[surfaces[p.ising].psifac for p in params] rational_q = Float64[surfaces[p.ising].q for p in params] - # include critical resonant filed workflow here + # include critical resonant field workflow here if control.critical_resonant_field.enabled slayer_result = run_slayer_from_inputs(params, dp, control; rational_psi=rational_psi, rational_q=rational_q) crf_result = run_critical_resonant_field(equil, surfaces, control; - dir_path=dir_path, slayer_result=slayer_result, profiles=profiles, chi_prof=chi_perp) + dir_path=dir_path, + slayer_result=slayer_result, + profiles=profiles, + chi_prof=chi_perp, + viscous_profile=loaded.viscous_input) combined_result = SLAYERResult( slayer_result.enabled, slayer_result.control, From 4f713fc9d5d0251fcd365a6c5504d02118c7873b Mon Sep 17 00:00:00 2001 From: Evan Bursch Date: Tue, 6 Oct 2026 11:21:20 -0400 Subject: [PATCH 10/14] Tearing - BUGFIX - Evaluate the critical resonant field torque balance on Cole's Q axis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit solve_inner mirrors the real-Q axis, so the torque balance paired a mirrored Δ with an unmirrored Q0 and put the diamagnetic poles at −Q_e, −Q_i. Map back with conj(Δ(−Q)) so the branch lies between Q_e and Q0 as in Cole and Fitzpatrick 2006 and Fortran gslayer.f. Replace the two-largest-samples search with true local maxima, reject maxima within one grid step of a pole, derive the scan window from Q0, Q_e, Q_i as gslayer.f does, and carry κ̂ explicitly (held at 2/s² for Fortran parity). Fix the header equation and attach the docstrings. Co-Authored-By: Claude Opus 5.5 --- src/InnerLayer/SLAYER/Riccati.jl | 1 + .../CriticalResonantField.jl | 8 +- .../CriticalResonantField/TorqueBalance.jl | 201 +++++++----------- src/Tearing/Tearing.jl | 4 +- 4 files changed, 86 insertions(+), 128 deletions(-) diff --git a/src/InnerLayer/SLAYER/Riccati.jl b/src/InnerLayer/SLAYER/Riccati.jl index 87781259b..373180e24 100644 --- a/src/InnerLayer/SLAYER/Riccati.jl +++ b/src/InnerLayer/SLAYER/Riccati.jl @@ -225,6 +225,7 @@ function solve_inner(::SLAYERModel{:fitzpatrick}, # growth-rate roots are identical to those of Δ̂_s(ĝ); it only reflects # the off-root residual surface, fixing the integration-path orientation # so |Δ| contours are consistent across the scan plane. + # Real-Q callers see a mirrored axis; the critical resonant field maps back via conj(Δ(−Q)). Q_c = im * conj(ComplexF64(Q)) # Boundary condition at p_start diff --git a/src/Tearing/CriticalResonantField/CriticalResonantField.jl b/src/Tearing/CriticalResonantField/CriticalResonantField.jl index b51360cd0..0cc09daf2 100644 --- a/src/Tearing/CriticalResonantField/CriticalResonantField.jl +++ b/src/Tearing/CriticalResonantField/CriticalResonantField.jl @@ -7,16 +7,12 @@ module CriticalResonantField -using LinearAlgebra -using StaticArrays using Printf -using ..InnerLayer -using ..InnerLayer: InnerLayerModel, solve_inner, GGJModel, GGJParameters, - SLAYERModel, SLAYERParameters +using ..InnerLayer: InnerLayerModel, solve_inner include("TorqueBalance.jl") -export TorqueBalance, torque_balance_value, torque_balance_scan +export TorqueBalance, cole_delta, torque_balance_value, torque_balance_window, torque_balance_scan end # module CriticalResonantField diff --git a/src/Tearing/CriticalResonantField/TorqueBalance.jl b/src/Tearing/CriticalResonantField/TorqueBalance.jl index 76042479d..c78772f5e 100644 --- a/src/Tearing/CriticalResonantField/TorqueBalance.jl +++ b/src/Tearing/CriticalResonantField/TorqueBalance.jl @@ -1,149 +1,110 @@ # TorqueBalance.jl # -# `TorqueBalance` solves the torque balance eqution for each rational surface. -# It follows the derivation found in Cole PopP 2006. For simplicity, the script -# uses equation 62 of Cole. This can be improved by incorporating the true -# outer-layer Δ' from the perturbed equilibrium and then solving equation 61. +# Error-field penetration threshold from the steady-state torque balance at a +# rational surface (Cole and Fitzpatrick, Phys. Plasmas 13, 032503 (2006), Sec. IV). +# The electromagnetic and viscous torques balance when (Cole Eq. 61) # -# The viscous torque is: +# Im[Δ(Q)] / |α + Δ(Q)|² = 2·P·(Q0 − Q) / (S·κ̂·(b_r/B_φ)²), # -# T_v = 2 · P (Q_0 - Q) / ((S kappa^hat) · (b_r(r_s)/B_phi))^2 +# with κ̂ = [2/s(r_s)]² ∫_{r_s}^{a} [μ(r_s)/μ(r)] dr/r. Balance is lost when no Q +# satisfies this, so the critical field is (Cole Eq. 62) # -# The electromagnetic torque is: +# (b_r/B_φ)²_crit = max_Q 2·P·(Q0 − Q) / (S·κ̂·Im[−1/(α + Δ(Q))]). # -# T_em = Im[Δ_inner(Q)] / |alpha + Δ_inner(Q)|^2 -# -# Now solving for critical resonant field, we have: -# -# (b_r(r_s)/B_phi))^2_crit = max(2 · P (Q_0 - Q) / ((S kappa^hat) · Im[-Δ_inner(Q)^-1]) -# -# Normalizations, definitions, and other conventions are taken from the Cole paper. -# The critical resonant field is found at each rational surface. For each, the script -# scans over a range of Q values and finds the maximum value of the right-hand side of -# the equation above. +# As in Fortran gslayer.f, the viscosity integral is taken as 1/2 (κ̂ = 2/s²) and α +# is kept finite at 1e-2. Q is on Cole's axis: the electron and ion diamagnetic +# frequencies sit at Q = Q_e and Q = Q_i (see `cole_delta`). + +# Finite stand-in for α = S^(-1/3)·(−r_s Δ'_s) ≪ 1; b_crit moves ~4% over 1e-4 to 1e-1. +const TORQUE_BALANCE_ALPHA = 1e-2 """ - TorqueBalance{M<:InnerLayerModel, P} + TorqueBalance{M<:InnerLayerModel,P} -Per-surface torque balance data: `(model, params, Q0, P, lu, sval)`. +Torque-balance inputs at one rational surface. -""" +## Fields + - `model` -- inner-layer model passed to `solve_inner` + - `params` -- that model's layer parameters at the surface + - `Q0` -- normalized natural E×B rotation of the m/n mode, τ_k·n·ω_E + - `P` -- magnetic Prandtl number τ_R/τ_V (the layer's P_φ) + - `lu` -- Lundquist number S + - `kappa_hat` -- Cole's slab-to-tokamak factor κ̂ (Eq. 61) +""" struct TorqueBalance{M<:InnerLayerModel,P} model::M params::P Q0::Float64 P::Float64 lu::Float64 - sval::Float64 -end - -function torque_balance_value(tb::TorqueBalance, Q::Number) - Δ = solve_inner(tb.model, tb.params, ComplexF64(Q)).tearing - alpha = 1e-2 # Equation 62 of Cole PopP 2006 takes limit of alpha << 1. Set at 1e-2 but more accurate method is alpha = S^(-1/3) * (-r_s Δ'_s) - jxb = -imag(1.0 / (Δ + alpha)) - return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ + kappa_hat::Float64 end """ - torque_balance_scan(model::InnerLayerModel, params::InnerLayerParameters, Q0::Real, P::Real, - lu::Real, sval::Real;Qmin=-10.0, Qmax=10.0, n=200) -> (Qs, bal, Qs_positive, bal_positive, - Qpeak, br_crit, Qpeak_ind, Δs) + cole_delta(model, params, Q::Real) -> ComplexF64 -Scan over a range of Q values to find the maximum of the torque balance equation. -Returns the Q values, torque balance values, positive Q values, positive torque balance values, -the Q value at the peak, the critical resonant field, the index of the peak Q value, and the Δ values for each Q. +Inner-layer Δ at real frequency `Q` on Cole's axis. `solve_inner` evaluates the layer +at `i·conj(Q)`, which mirrors the real axis, so Cole's Δ(Q) is `conj(Δ_solve_inner(−Q))`. """ +cole_delta(model::InnerLayerModel, params, Q::Real) = + conj(solve_inner(model, params, ComplexF64(-Q)).tearing) -function torque_balance_scan(tb; Qmin=-10.0, Qmax=10.0, n=2000) - Qs = range(Qmin, Qmax; length=n) - torque_out = [torque_balance_value(tb, q) for q in Qs] - bal = [x[1] for x in torque_out] - Δs = [x[2] for x in torque_out] - positive = isfinite.(bal) .& (bal .> 0.0) - - if !any(positive) - @warn "No positive torque balance found in the specified range. Try increasing the number of Q samples scanned or adjusting the range." - return Qs, bal, NaN, NaN, NaN, Δs - end - - # Find the highest point, then remove candidates within ΔQ of it. - idx_maxima = findall(isfinite.(bal) .& (bal .> 0)) - sort!(idx_maxima; by=i -> bal[i], rev=true) - selected = Int[] - min_ΔQ = 0.001 * abs(Qmax - Qmin) - - for i in idx_maxima - if all(abs(Qs[i] - Qs[j]) > min_ΔQ for j in selected) - push!(selected, i) - end - length(selected) == 2 && break - end - - if isempty(selected) - @warn "No usable positive torque-balance maximum found. Try increasing the number of Q samples scanned or adjusting the range." - return Qs, bal, NaN, NaN, NaN, Δs - end - - idx_maxima = selected - maxima = bal[idx_maxima] - Qs_maxima = Qs[idx_maxima] +""" + torque_balance_value(tb::TorqueBalance, Q::Real) -> (bal, Δ) - # find index, q val and bal val of the q closest to Q_e - idx_closest_Q_e = argmin(abs.(Qs .+ tb.params.Q_e)) # + Q_e since Q_e = -omega_e * Qconv - q_closest_Q_e = Qs[idx_closest_Q_e] - bal_closest_Q_e = bal[idx_closest_Q_e] +Right-hand side of Cole Eq. 62 before the maximum, `bal = 2·P·(Q0 − Q) / Im[−1/(α + Δ)]`, +and the layer `Δ(Q)` it used. +""" +function torque_balance_value(tb::TorqueBalance, Q::Real) + Δ = cole_delta(tb.model, tb.params, Q) + jxb = -imag(1.0 / (Δ + TORQUE_BALANCE_ALPHA)) + return 2.0 * tb.P * (tb.Q0 - Q) / jxb, Δ +end - # find index, q val and bal val of the q closest to Q_i - idx_closest_Q_i = argmin(abs.(Qs .+ tb.params.Q_i)) # + Q_i since Q_i = -omega_i * Qconv - q_closest_Q_i = Qs[idx_closest_Q_i] - bal_closest_Q_i = bal[idx_closest_Q_i] +""" + torque_balance_window(Q0, Q_e, Q_i) -> (Qmin, Qmax) - println( - "Highest Qs: ", - [@sprintf("%.2f", q) for q in Qs_maxima], - ", Closest Q to Q_e: ", - @sprintf("%.2f", q_closest_Q_e), - " closest Q to Q_i: ", - @sprintf("%.2f", q_closest_Q_i) - ) +Q range bracketing the torque-balance branch between the natural rotation `Q0` and the +electron diamagnetic pole `Q_e` (the rule of Fortran gslayer.f). +""" +function torque_balance_window(Q0::Real, Q_e::Real, Q_i::Real) + Q0 > Q_e && return (1.05 * Q_e, 2.0 * Q0) + Qmin = Q0 > 0 ? 0.8 * Q_i : 1.5 * min(Q0, Q_i) + return (Qmin, 0.95 * Q_e) +end - # check if 1st q_maxima is same as Q_e or Q_i from p - if idx_maxima[1] == idx_closest_Q_e || idx_maxima[1] == idx_closest_Q_i - if length(idx_maxima) < 2 - @warn "The first local maximum corresponds to a pole from Q_e or Q_i, but there is no second local maximum to select. Try increasing the number of Q samples scanned or adjusting the range." - return Qs, bal, NaN, NaN, NaN, Δs - end - @warn "The first local maximum may correspond to an electron or ion diamagnetic resonance. Selecting the second local maximum instead." - if idx_maxima[2] == idx_closest_Q_e || idx_maxima[2] == idx_closest_Q_i - @warn "Both the first and second local maxima correspond to poles from Q_e or Q_i. Unable to select a valid local maximum. Try increasing the number of Q samples scanned or adjusting the range." - return Qs, bal, NaN, NaN, NaN, Δs - end - idx_maximum = idx_maxima[2] - maximum = bal[idx_maximum] - Qmaximum = Qs[idx_maximum] - else - idx_maximum = idx_maxima[1] - maximum = bal[idx_maximum] - Qmaximum = Qs[idx_maximum] +""" + torque_balance_scan(tb::TorqueBalance; Qmin=nothing, Qmax=nothing, n=2000) + -> (Qs, bal, Qpeak, br_crit, idx_peak, Δs) + +Sample `torque_balance_value` on `n` uniform real Q points and return the critical +normalized field `br_crit = b_r/B_φ` (Cole Eq. 62) at the largest positive interior local +maximum of `bal`, located at `Qpeak = Qs[idx_peak]`. A maximum within one grid step of +the diamagnetic poles `Q_e`, `Q_i` is discarded as a pole artifact. `Qmin`/`Qmax` +default to `torque_balance_window`. Returns NaN for `Qpeak`, `br_crit` and 0 for +`idx_peak` when no valid maximum is found. +""" +function torque_balance_scan(tb::TorqueBalance; Qmin=nothing, Qmax=nothing, n::Integer=2000) + p = tb.params + wmin, wmax = torque_balance_window(tb.Q0, p.Q_e, p.Q_i) + Qs = range(something(Qmin, wmin), something(Qmax, wmax); length=n) + out = [torque_balance_value(tb, Q) for Q in Qs] + bal = first.(out) + Δs = last.(out) + + dQ = step(Qs) + near_pole(Q) = abs(Q - p.Q_e) <= dQ || abs(Q - p.Q_i) <= dQ + peaks = [i for i in 2:(n-1) if isfinite(bal[i]) && bal[i] > 0 && + bal[i-1] < bal[i] && bal[i] >= bal[i+1] && !near_pole(Qs[i])] + if isempty(peaks) + @warn "CriticalResonantField: no positive torque-balance maximum on " * + "Q ∈ [$(first(Qs)), $(last(Qs))] at the $(p.m)/$(p.n) surface." + return Qs, bal, NaN, NaN, 0, Δs end - - br_crit = sqrt(maximum / tb.lu * (tb.sval^2 / 2.0)) - - println( - "Critical Resonant Field at ", - tb.params.m, - "/", - tb.params.n, - " surface: ", - @sprintf("%.2e", br_crit), - " T at index: ", - idx_maximum, - " with value: ", - @sprintf("%.2f", maximum), - " and corresponding Q: ", - @sprintf("%.2f", Qmaximum) - ) - - return Qs, bal, Qmaximum, br_crit, idx_maximum, Δs + idx = peaks[argmax(bal[peaks])] + br_crit = sqrt(bal[idx] / (tb.lu * tb.kappa_hat)) + @info @sprintf("CriticalResonantField: %d/%d surface b_r/B_φ crit = %.3e at Q = %.3f", + p.m, p.n, br_crit, Qs[idx]) + return Qs, bal, Qs[idx], br_crit, idx, Δs end diff --git a/src/Tearing/Tearing.jl b/src/Tearing/Tearing.jl index 3ebd35996..d4c225246 100644 --- a/src/Tearing/Tearing.jl +++ b/src/Tearing/Tearing.jl @@ -6,8 +6,8 @@ # InnerLayer -- pure physics: Δ_inner(Q) for GGJ or SLAYER models # Dispersion -- physics-agnostic scan + contour-intersection root # extraction (consumes any InnerLayerModel) -# CriticalResonantField -- physics-agnostic scan + torque-balance root -# extraction (consumes any InnerLayerModel) +# CriticalResonantField -- real-Q torque-balance scan for the critical +# resonant field of error-field penetration # Runner -- user-facing orchestration: TOML config, profile # loading, HDF5 output, workflow hooks # From baf49d768cabd2e8dc6f167e4cd5b63e6febf4ca Mon Sep 17 00:00:00 2001 From: Evan Bursch Date: Tue, 6 Oct 2026 11:21:20 -0400 Subject: [PATCH 11/14] Tearing - API - Take the critical resonant field Prandtl number from the layer P_tor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove viscous_input and viscous_input_type: the torque balance now uses each surface's SLAYER P_tor, so χ_φ (or a future τ_E closure) set in InnerLayer flows through unchanged. Q0 gains the toroidal mode number, τ_k·n·ω_E, matching Q_e and Q_i, and ω_E is read at each surface's own ψ. Results use concrete types; HDF5 datasets are snake_case with metadata and the scans are written only with store_scan. The CRF block moves into the shipped SLAYER example. Co-Authored-By: Claude Opus 5.5 --- docs/development/hdf5-conventions.md | 2 +- examples/DIIID-like_SLAYER_example/gpec.toml | 8 + src/Tearing/Runner/Control.jl | 71 +++-- src/Tearing/Runner/HDF5Output.jl | 88 +++--- src/Tearing/Runner/Result.jl | 64 ++-- src/Tearing/Runner/Runner.jl | 7 +- src/Tearing/Runner/run_slayer.jl | 299 ++----------------- 7 files changed, 165 insertions(+), 374 deletions(-) diff --git a/docs/development/hdf5-conventions.md b/docs/development/hdf5-conventions.md index c4631c984..692407c96 100644 --- a/docs/development/hdf5-conventions.md +++ b/docs/development/hdf5-conventions.md @@ -46,7 +46,7 @@ Top level (11 groups): | `PerturbedEquilibrium/` | `ForcingModes/`, `Response/`, `ResponseMatrices/`, `SingularCoupling/`, `Energies/`, control-surface spectra | | `KineticForces/` | `/` (torque/energy profiles, `EnergyIntegrals/`, `KineticMatrices/`); multi-ion runs add `PerSpecies///` with the same per-method layout, summing to the top-level total | | `ErrorFields/` | `CoilSensitivities/` (per-coil-set control-surface spectra and their rigid shift/tilt derivatives, `DominantMode/` full-window projection); `MonteCarlo/` (intrinsic and corrected `\|δ\|` histograms over the sampled tolerances, per batch and averaged); `Risk/` (threshold density, `P(lock\|δ)`, locking probabilities, `ToleranceScan/`); `NTV/` (correction-coil overlap and NTV torque couplings per kAt) | -| `Tearing/` | `PerSurface/` (+ `DpMatrix/`), `Roots/`, `LayerWidths/`, `Diagnostics/{ValidRoots,Poles,FilteredRoots}`, `Scan/Surface_/` | +| `Tearing/` | `PerSurface/` (+ `DpMatrix/`), `Roots/`, `LayerWidths/`, `Diagnostics/{ValidRoots,Poles,FilteredRoots}`, `Scan/Surface_/`, `CriticalResonantField/` (+ `Scan/Surface_/`) | | `SurfaceGeometries/` | `{Plasma,Wall}/{x,y,z}` point clouds | Reserved (documented, not yet written): `ForceFreeStates/Solutions/RiccatiIntegration/` — the third integrator backend slot alongside `ForwardIntegration` and `GalerkinIntegration`. diff --git a/examples/DIIID-like_SLAYER_example/gpec.toml b/examples/DIIID-like_SLAYER_example/gpec.toml index a8a99f4c7..b3efc474c 100644 --- a/examples/DIIID-like_SLAYER_example/gpec.toml +++ b/examples/DIIID-like_SLAYER_example/gpec.toml @@ -89,3 +89,11 @@ Q_re_range = [-2.0, 2.0] # Scan box in the normalized Q plane, Re(Q) axis Q_im_range = [-0.5, 3.0] # Scan box in the normalized Q plane, Im(Q) axis nre = 41 # Grid resolution along the Re(Q) axis nim = 31 # Grid resolution along the Im(Q) axis + +[SLAYER.CriticalResonantField] +# Critical resonant field b_r/B_φ for error-field penetration at each SLAYER surface, from the +# Cole-Fitzpatrick 2006 torque balance with P = P_tor of each layer. Qmin/Qmax may be set to +# override the per-surface scan window derived from Q0, Q_e and Q_i. +enabled = true # run the analysis after SLAYER +n = 2000 # number of Q samples per surface +store_scan = false # write the per-surface Q, torque balance and Δ samples to gpec.h5 diff --git a/src/Tearing/Runner/Control.jl b/src/Tearing/Runner/Control.jl index d465b8cde..370ef04c6 100644 --- a/src/Tearing/Runner/Control.jl +++ b/src/Tearing/Runner/Control.jl @@ -4,44 +4,45 @@ # growth-rate analysis. Populated either directly via the `@kwdef` # constructor or by parsing the `[SLAYER]` (and nested `[SLAYER.*]`) # section(s) of a `gpec.toml`. -# -# `CriticalResonantFieldControl` holds the user-facing knobs that drive the critical resonant field -# analysis. Populated either directly via the `@kwdef` constructor or by parsing the `[CriticalResonantField]` section of a `gpec.toml`. + """ CriticalResonantFieldControl -Configuration for the critical resonant field analysis. All fields are -user-facing: read from the `[CriticalResonantField]` TOML section of a `gpec.toml` via -`critical_resonant_field_control_from_toml`, or built directly via the `@kwdef` keyword -constructor. +Configuration for the critical resonant field (torque-balance) analysis, read from the +`[SLAYER.CriticalResonantField]` TOML section via `critical_resonant_field_control_from_toml` +or built with the `@kwdef` keyword constructor. The magnetic Prandtl number is the per-surface +`P_tor` of the SLAYER layer parameters. + +## Fields + + - `enabled` -- run the analysis after SLAYER + - `Qmin`, `Qmax` -- override the real-Q scan window; `nothing` derives it per surface from Q0, Q_e and Q_i + - `n` -- number of Q samples per surface + - `store_scan` -- write the per-surface Q, torque balance and Δ samples to `gpec.h5` """ @kwdef struct CriticalResonantFieldControl enabled::Bool = false - Qmin::Float64 = -10.0 - Qmax::Float64 = 10.0 - n::Int = 200 - viscous_input_type::String = "angular_momentum_diffusivity" # Either "angular_momentum_diffusivity" or "magnetic_prandtl_number" - viscous_input::Any = 1.0 + Qmin::Union{Nothing,Float64} = nothing + Qmax::Union{Nothing,Float64} = nothing + n::Int = 2000 store_scan::Bool = false end -function critical_resonant_field_control_from_toml(section::AbstractDict) - flat = Dict{String,Any}() - for (k, v) in section - flat[k] = v - end - - kwargs = Dict{Symbol,Any}() - for (k, v) in flat - sym = Symbol(k) - if sym in (:inner_model,) - kwargs[sym] = v isa Symbol ? v : Symbol(String(v)) - else - kwargs[sym] = v - end - end +""" + critical_resonant_field_control_from_toml(section::AbstractDict) -> CriticalResonantFieldControl - return CriticalResonantFieldControl(; kwargs...) +Parse a `[SLAYER.CriticalResonantField]` TOML section. Unknown keys raise an error. +""" +function critical_resonant_field_control_from_toml(section::AbstractDict) + field_names = Set(String.(fieldnames(CriticalResonantFieldControl))) + unknown = [k for k in keys(section) if !(k in field_names)] + isempty(unknown) || + throw( + ArgumentError("critical_resonant_field_control_from_toml: unknown keys " * + "$(unknown) in [SLAYER.CriticalResonantField]. Known: " * + "$(sort(collect(field_names))).") + ) + return CriticalResonantFieldControl(; (Symbol(k) => v for (k, v) in section)...) end """ @@ -133,6 +134,11 @@ there is one consistent interface for resistive and kinetic profiles. - `store_scan` -- write the full Q/Δ scan grid to HDF5. `false` by default to keep the output file small. + +# Critical resonant field + + - `critical_resonant_field` -- `CriticalResonantFieldControl` from the + `[SLAYER.CriticalResonantField]` subsection; requires `inner_model = :slayer_fitzpatrick` """ @kwdef struct SLAYERControl enabled::Bool = false @@ -195,7 +201,6 @@ there is one consistent interface for resistive and kinetic profiles. store_scan::Bool = false - # Critical resonant field analysis. Enabled via `[SLAYER.CriticalResonantField]` TOML section. critical_resonant_field::CriticalResonantFieldControl = CriticalResonantFieldControl() end @@ -231,6 +236,10 @@ function validate(ctrl::SLAYERControl) throw(ArgumentError("SLAYERControl: nre and nim must both be ≥ 2")) ctrl.amr_passes >= 0 || throw(ArgumentError("SLAYERControl: amr_passes must be ≥ 0")) + !ctrl.critical_resonant_field.enabled || ctrl.inner_model === :slayer_fitzpatrick || + throw(ArgumentError("SLAYERControl: CriticalResonantField requires inner_model=:slayer_fitzpatrick")) + ctrl.critical_resonant_field.n >= 3 || + throw(ArgumentError("SLAYERControl: CriticalResonantField n must be ≥ 3")) return ctrl end @@ -267,9 +276,7 @@ function slayer_control_from_toml(section::AbstractDict) haskey(v, "filter_above_poles") && (flat["filter_above_poles"] = v["filter_above_poles"]) haskey(v, "filter_outside_re") && (flat["filter_outside_re"] = v["filter_outside_re"]) elseif k == "CriticalResonantField" && v isa AbstractDict - flat["critical_resonant_field"] = - critical_resonant_field_control_from_toml(v) - + flat["critical_resonant_field"] = critical_resonant_field_control_from_toml(v) else flat[k] = v end diff --git a/src/Tearing/Runner/HDF5Output.jl b/src/Tearing/Runner/HDF5Output.jl index 959d7088f..93ddde447 100644 --- a/src/Tearing/Runner/HDF5Output.jl +++ b/src/Tearing/Runner/HDF5Output.jl @@ -1,6 +1,6 @@ # HDF5Output.jl # -# Write a `SLAYERResult` or `CriticalResonantFieldResult` into an HDF5 group. Designed to be called by the +# Write a `SLAYERResult` into an HDF5 group. Designed to be called by the # existing `PerturbedEquilibrium.write_outputs_to_HDF5` path — the # top-level GPEC runner wires that up; this file only defines the pure # writer. @@ -15,7 +15,8 @@ # ├── Roots/ -- complex Q_root, omega_Hz, gamma_Hz # ├── Diagnostics/ -- ValidRoots, Poles, FilteredRoots # │ (flat-plus-offsets ragged encoding) -# └── Scan/ -- optional: full Q/Δ scan data +# ├── Scan/ -- optional: full Q/Δ scan data +# └── CriticalResonantField/ -- optional: torque-balance b_r/B_φ crit per surface using HDF5 @@ -38,10 +39,6 @@ function write_slayer_hdf5!(parent::Union{HDF5.File,HDF5.Group}, # disjoint field sets, so readers must not have to infer it from the schema. attrs(g)["layer_model"] = result.enabled ? _layer_model_token(eltype(result.params)) : "none" - if result.critical_resonant_field.enabled - write_critical_resonant_field_hdf5!(g, result.critical_resonant_field) - end - if !result.enabled # nothing else to write _annotate_tearing!(g) return g @@ -57,42 +54,28 @@ function write_slayer_hdf5!(parent::Union{HDF5.File,HDF5.Group}, if result.control.store_scan && !isempty(result.scan_data) _write_scan_data!(g, result) end + result.critical_resonant_field.enabled && _write_critical_resonant_field!(g, result.critical_resonant_field) _annotate_tearing!(g) return g end -function write_critical_resonant_field_hdf5!(parent::Union{HDF5.File,HDF5.Group}, - result::CriticalResonantFieldResult) - - g = create_group(parent, "CriticalResonantField") - - g["surface_index"] = result.surface_index - g["Qpeak"] = result.Qpeak - g["br_crit"] = result.br_crit - g["Q0"] = result.Q0 - g["P"] = result.P - - if !isempty(result.scan_data) - scan_group = create_group(g, "Scan") - for d in result.scan_data - sg = create_group(scan_group, "surface_$(d.surface)") - sg["Q"] = d.Q - sg["balance"] = d.balance - sg["delta"] = d.delta - sg["Qpeak"] = d.Qpeak - sg["br_crit"] = d.br_crit - - # Save inputs for analysis in post - for field in (:Q0, :P, :lu, :sval, :m, :n) - if field in keys(d) - sg[String(field)] = getfield(d, field) - end - end - end +# ---------- critical resonant field ---------- +function _write_critical_resonant_field!(g, crf::CriticalResonantFieldResult) + cg = create_group(g, "CriticalResonantField") + cg["rational_index"] = crf.rational_index + cg["q_peak"] = crf.q_peak + cg["br_crit"] = crf.br_crit + cg["q0"] = crf.q0 + cg["p_phi"] = crf.p_phi + isempty(crf.scan) && return nothing + scan = create_group(cg, "Scan") + for (k, sc) in enumerate(crf.scan) + sg = create_group(scan, "Surface_$k") + sg["Q"] = sc.Q + sg["balance"] = sc.balance + sg["Delta"] = sc.Delta end - - attrs(g)["kind"] = "critical_resonant_field" - return g + return nothing end # Token recorded in the Tearing group's layer_model attribute; keyed by the @@ -144,8 +127,14 @@ const TEARING_H5_ANNOTATIONS = [ "PerSurface/M" => (; long_name="Glasser-Greene-Johnson coefficient M per surface", dims=("surface",)), "PerSurface/tau_A" => (; long_name="Alfvén time τ_A per surface (GGJ layer parameters)", units="s", dims=("surface",)), "PerSurface/dVdpsi" => (; long_name="dV/dψ_N at each surface", units="m^3", dims=("surface",)), - "PerSurface/Delta_prime_matrix" => (; long_name="full complex Δ' matrix coupling the rational surfaces, ψ_N-referenced (GGJ path; identical to SingularSurfaces/Delta_prime_matrix)", dims=("surface_row", "surface_col")), - "PerSurface/Delta_prime_matrix_rs" => (; long_name="full complex Δ' matrix as used in the slab-layer matching, converted to the r_s reference length (K^(2α) on the diagonal; the ψ_N-referenced BVP matrix is SingularSurfaces/Delta_prime_matrix)", dims=("surface_row", "surface_col")), + "PerSurface/Delta_prime_matrix" => (; + long_name="full complex Δ' matrix coupling the rational surfaces, ψ_N-referenced (GGJ path; identical to SingularSurfaces/Delta_prime_matrix)", + dims=("surface_row", "surface_col") + ), + "PerSurface/Delta_prime_matrix_rs" => (; + long_name="full complex Δ' matrix as used in the slab-layer matching, converted to the r_s reference length (K^(2α) on the diagonal; the ψ_N-referenced BVP matrix is SingularSurfaces/Delta_prime_matrix)", + dims=("surface_row", "surface_col") + ), "Roots/Q_root" => (; long_name="complex dispersion-root normalized frequency Q (NaN = no root)", dims=("surface",)), "Roots/omega" => (; long_name="mode rotation angular frequency ω = Re(Q)/τ_k of each root", units="rad/s", dims=("surface",)), @@ -158,7 +147,21 @@ const TEARING_H5_ANNOTATIONS = [ "LayerWidths/delta_s_over_d_beta" => (; long_name="complex dimensionless layer thickness δ_s/d_β", dims=("surface",)), "LayerWidths/delta_s" => (; long_name="complex resistive layer thickness δ_s (Riccati)", dims=("surface",)), "LayerWidths/delta_s_abs" => (; long_name="physical resistive layer thickness |δ_s|", units="m", dims=("surface",)), - "LayerWidths/d_beta" => (; long_name="β-weighted ion drift scale d_β", units="m", dims=("surface",)) + "LayerWidths/d_beta" => (; long_name="β-weighted ion drift scale d_β", units="m", dims=("surface",)), + "CriticalResonantField/rational_index" => (; long_name="rational-surface index of each row", dims=("surface",)), + "CriticalResonantField/q_peak" => + (; long_name="normalized frequency Q (Cole axis) at the torque-balance maximum (NaN = no maximum)", units="1", dims=("surface",)), + "CriticalResonantField/br_crit" => + (; long_name="critical normalized resonant field b_r/B_φ for error-field penetration (Cole-Fitzpatrick 2006 Eq. 62; NaN = no maximum)", + units="1", dims=("surface",)), + "CriticalResonantField/q0" => (; long_name="normalized natural E×B rotation Q0 = τ_k·n·ω_E", units="1", dims=("surface",)), + "CriticalResonantField/p_phi" => (; long_name="magnetic Prandtl number used in the torque balance (the layer P_tor)", units="1", dims=("surface",)) +] + +const TEARING_CRF_SCAN_H5_ANNOTATIONS = [ + "Q" => (; long_name="sampled real normalized frequency Q (Cole axis)", units="1"), + "balance" => (; long_name="torque balance 2·P·(Q0 − Q)/Im[−1/(α + Δ)]", units="1"), + "Delta" => (; long_name="complex inner-layer Δ(Q) on the Cole axis", units="1") ] const TEARING_RAGGED_H5_ANNOTATIONS = [ @@ -185,6 +188,11 @@ function _annotate_tearing!(g) ann.annotate!(g["Diagnostics"][sub], TEARING_RAGGED_H5_ANNOTATIONS) end end + if haskey(g, "CriticalResonantField/Scan") + for sub in keys(g["CriticalResonantField/Scan"]) + ann.annotate!(g["CriticalResonantField/Scan"][sub], TEARING_CRF_SCAN_H5_ANNOTATIONS) + end + end if haskey(g, "Scan") for sub in keys(g["Scan"]) sg = g["Scan"][sub] diff --git a/src/Tearing/Runner/Result.jl b/src/Tearing/Runner/Result.jl index ef0a2e5cd..5bd6861f3 100644 --- a/src/Tearing/Runner/Result.jl +++ b/src/Tearing/Runner/Result.jl @@ -4,40 +4,53 @@ # per-surface layer parameters, the extracted tearing eigenvalues, and (if # `control.store_scan`) the full Q-plane scan data for plotting. # -# `CriticalResonantFieldResult` packages the output of the critical resonant field analysis run: -# per-surface critical resoant field. If `control.store_scan` is true, the full Q scan data, -# viscous torque, and electromagnetic torque are also stored for plotting. +# `CriticalResonantFieldResult` packages the per-surface critical resonant field +# from the torque-balance analysis (and, if requested, its Q scans). """ - CriticalResonantFieldResult + CriticalResonantFieldScan + +Real-Q torque-balance samples at one surface. -Output of `run_critical_resonant_field`. Carries both summary critical resonant field values and if `control.store_scan` is true, the full Q scan data, viscous torque, and electromagnetic torque for plotting. +## Fields + + - `Q` -- sampled normalized frequencies (Cole's axis) + - `balance` -- torque-balance value 2·P·(Q0 − Q)/Im[−1/(α + Δ)] at each Q + - `Delta` -- inner-layer Δ(Q) at each Q """ +struct CriticalResonantFieldScan + Q::Vector{Float64} + balance::Vector{Float64} + Delta::Vector{ComplexF64} +end + +""" + CriticalResonantFieldResult +Output of `run_critical_resonant_field`, one entry per SLAYER surface. + +## Fields + + - `enabled` -- the analysis ran + - `rational_index` -- rational-surface index of each entry + - `q_peak` -- normalized frequency Q at the torque-balance maximum (NaN if none) + - `br_crit` -- critical normalized resonant field b_r/B_φ (NaN if none) + - `q0` -- normalized natural E×B rotation τ_k·n·ω_E + - `p_phi` -- magnetic Prandtl number used (the layer `P_tor`) + - `scan` -- per-surface Q scans; empty unless `store_scan` +""" struct CriticalResonantFieldResult enabled::Bool - params::AbstractVector{<:InnerLayerParameters} - surface_index::Vector{Int} - Qpeak::Vector{Float64} + rational_index::Vector{Int} + q_peak::Vector{Float64} br_crit::Vector{Float64} - Q0::Vector{Float64} - P::Vector{Float64} - scan_data::Vector{NamedTuple} -end - -function empty_critical_resonant_field_result() - return CriticalResonantFieldResult( - false, - InnerLayerParameters[], - Int[], - Float64[], - Float64[], - Float64[], - Float64[], - NamedTuple[] - ) + q0::Vector{Float64} + p_phi::Vector{Float64} + scan::Vector{CriticalResonantFieldScan} end +empty_critical_resonant_field_result() = + CriticalResonantFieldResult(false, Int[], Float64[], Float64[], Float64[], Float64[], CriticalResonantFieldScan[]) """ SLAYERResult @@ -60,6 +73,7 @@ downstream inspection and HDF5 output. `delta_prime_to_rs_reference`, written as `PerSurface/Delta_prime_matrix_rs`); GGJ path: the ψ_N matrix unchanged (written as `PerSurface/Delta_prime_matrix`) - `Q_root` -- tearing eigenvalue(s) in normalized Q + + length `nsurfaces` in `:uncoupled` mode + length `1` in `:coupled` mode (global eigenvalue normalized by `params[1].tauk`) @@ -74,6 +88,8 @@ downstream inspection and HDF5 output. plus FKR / visco-resistive sanity scales. Empty when disabled. - `scan_data` -- scan results (per-surface in uncoupled, single entry in coupled). Empty unless `control.store_scan == true`. + - `critical_resonant_field` -- `CriticalResonantFieldResult`; `enabled=false` + unless `control.critical_resonant_field.enabled` """ struct SLAYERResult enabled::Bool diff --git a/src/Tearing/Runner/Runner.jl b/src/Tearing/Runner/Runner.jl index 2d45b3d54..be4b74391 100644 --- a/src/Tearing/Runner/Runner.jl +++ b/src/Tearing/Runner/Runner.jl @@ -27,10 +27,10 @@ using LinearAlgebra using Statistics: mean, median using HDF5 - using FastInterpolations: cubic_interp using ..Utilities using ..Utilities: KineticProfiles +using ...Equilibrium: read_kinetic_file, KineticProfileData using ..InnerLayer using ..InnerLayer: InnerLayerParameters, InnerLayerResponse, solve_inner, @@ -38,8 +38,6 @@ using ..InnerLayer: GGJModel, GGJParameters, LayerWidths, slayer_layer_thickness import ..build_ggj_inputs # defined at the Tearing level (needs ForceFreeStates) -import ...Equilibrium as Equilibrium -using ...Equilibrium: read_kinetic_file, KineticProfileData, load_kinetic_profiles using ..Dispersion using ..Dispersion: SurfaceCoupling, surface_coupling, MultiSurfaceCoupling, multi_surface_coupling, @@ -59,8 +57,7 @@ export SLAYERResult, empty_slayer_result export run_slayer, run_slayer_from_inputs, ggj_inner_deltas export write_slayer_hdf5! export CriticalResonantFieldControl, critical_resonant_field_control_from_toml -export CriticalResonantFieldResult, empty_critical_resonant_field_result +export CriticalResonantFieldScan, CriticalResonantFieldResult, empty_critical_resonant_field_result export run_critical_resonant_field -export write_critical_resonant_field_hdf5! end # module Runner diff --git a/src/Tearing/Runner/run_slayer.jl b/src/Tearing/Runner/run_slayer.jl index 7093d96f6..17403308f 100644 --- a/src/Tearing/Runner/run_slayer.jl +++ b/src/Tearing/Runner/run_slayer.jl @@ -53,40 +53,7 @@ function _load_profiles(control::SLAYERControl, dir_path::AbstractString) cubic_interp(psi_xs, collect(Float64, v)) chi_perp = _chi_spline(data.chi_e) chi_tor = _chi_spline(data.chi_phi) - - # If present, load viscosity data for the critical resonant field. - viscous_input = control.critical_resonant_field.viscous_input - if viscous_input isa AbstractString - profile_name = String(viscous_input) - isempty(profile_name) && - error("run_slayer: CriticalResonantField.viscous_input is an empty profile name.") - - viscous_data = HDF5.h5open(path, "r") do f - grp = control.profile_group == "/" ? f : f[control.profile_group] - - haskey(grp, profile_name) || - error("run_slayer: kinetic file '$path' is missing requested " * - "CriticalResonantField profile '$profile_name'.") - - collect(Float64, read(grp[profile_name])) - end - - length(viscous_data) == npsi || - error("run_slayer: CriticalResonantField profile '$profile_name' " * - "has length $(length(viscous_data)), expected $npsi.") - - viscous_input = cubic_interp( - collect(Float64, data.psi), - viscous_data - ) - end - - return ( - profiles=profiles, - chi_perp=chi_perp, - chi_tor=chi_tor, - viscous_input=viscous_input - ) + return (profiles=profiles, chi_perp=chi_perp, chi_tor=chi_tor) end # --------------------------------------------------------------------- @@ -429,223 +396,37 @@ function ggj_inner_deltas(params::AbstractVector{GGJParameters}, Q::Number; end return out end + # --------------------------------------------------------------------- -# Critical Resonant Field (Torque-Balance) Workflow +# Critical resonant field (torque balance) # --------------------------------------------------------------------- """ - Critical Resonant Field (Torque-Balance) Workflow - - The critical resonant field is the minimum resonant magnetic perturbation - amplitude that can drive a tearing mode unstable. + run_critical_resonant_field(params, rational_psi, profiles, ctrl) -> CriticalResonantFieldResult - Returns a `CriticalResonantFieldResult` containing the critical resonant field - and the corresponding critical resonant field values for each rational surface. +Critical normalized resonant field b_r/B_φ for error-field penetration at each SLAYER +surface, from the torque balance of Cole and Fitzpatrick, Phys. Plasmas 13, 032503 (2006), +Eq. 62. The magnetic Prandtl number is the layer's `P_tor`, and the natural rotation is the +E×B frequency of the m/n mode, Q0 = τ_k·n·ω_E, with ω_E read from `profiles` at +`rational_psi`. """ - -function run_critical_resonant_field( - equil, intr, ctrl; - dir_path="./", - slayer_result=nothing, - profiles=nothing, - chi_prof=nothing, - viscous_profile=nothing -) - slayer_ctrl = ctrl - ctrl = slayer_ctrl.critical_resonant_field +function run_critical_resonant_field(params::AbstractVector{SLAYERParameters}, rational_psi::AbstractVector{<:Real}, + profiles::KineticProfiles, ctrl::CriticalResonantFieldControl) ctrl.enabled || return empty_critical_resonant_field_result() - - _eval(x, ψ) = x isa Real ? Float64(x) : Float64(x(ψ)) - - profiles === nothing && - throw(ArgumentError("CriticalResonantField requires kinetic profiles.")) - - params = if slayer_result !== nothing && slayer_result.enabled && !isempty(slayer_result.params) - slayer_result.params - else - throw(ArgumentError( - "CriticalResonantField requires SLAYERParameters; " * - "run SLAYER first or provide compatible params." - )) - end - - all(p -> p isa SLAYERParameters, params) || - throw(ArgumentError( - "CriticalResonantField requires SLAYERParameters; " * - "run SLAYER first or provide compatible params." - )) - - surface_index = Int[] - Qpeak_vec = Float64[] - br_vec = Float64[] - Q0_vec = Float64[] - P_vec = Float64[] - scan_data = NamedTuple[] - - chi_vec = nothing - P_input = nothing - use_P = false - - if ctrl.viscous_input_type === "angular_momentum_diffusivity" - - if ctrl.viscous_input === false - chi_vec = nothing - - elseif ctrl.viscous_input isa AbstractArray - length(ctrl.viscous_input) == length(params) || - throw(ArgumentError( - "CriticalResonantField viscous_input has length " * - "$(length(ctrl.viscous_input)), expected $(length(params))." - )) - chi_vec = ctrl.viscous_input - - elseif ctrl.viscous_input isa Number - chi_vec = fill(Float64(ctrl.viscous_input), length(params)) - - elseif ctrl.viscous_input isa String - viscous_profile === nothing && - throw(ArgumentError( - "CriticalResonantField profile " * - "'$(ctrl.viscous_input)' was not loaded." - )) - chi_vec = viscous_profile - - else - throw(ArgumentError( - "Invalid viscous_input for angular_momentum_diffusivity." - )) - end - - elseif ctrl.viscous_input_type === "magnetic_prandtl_number" - - use_P = true - - if ctrl.viscous_input isa AbstractArray - length(ctrl.viscous_input) == length(params) || - throw(ArgumentError( - "CriticalResonantField viscous_input has length " * - "$(length(ctrl.viscous_input)), expected $(length(params))." - )) - P_input = ctrl.viscous_input - - elseif ctrl.viscous_input isa Number - P_input = fill(Float64(ctrl.viscous_input), length(params)) - - elseif ctrl.viscous_input isa String - viscous_profile === nothing && - throw(ArgumentError( - "CriticalResonantField profile " * - "'$(ctrl.viscous_input)' was not loaded." - )) - P_input = viscous_profile - - elseif ctrl.viscous_input === false - use_P = false - - else - throw(ArgumentError( - "Invalid viscous_input for magnetic_prandtl_number." - )) - end - - else - throw(ArgumentError( - "Invalid viscous_input_type: $(ctrl.viscous_input_type). " * - "Must be 'angular_momentum_diffusivity' or " * - "'magnetic_prandtl_number'." - )) - end - - for (isurf, p) in enumerate(params) - - psi_here = intr[isurf].psifac - omega_here = profiles(psi_here).omega - Q0_here = p.tauk * omega_here - eta_here = p.eta - - if use_P - P_here = P_input isa AbstractArray ? - Float64(P_input[isurf]) : - _eval(P_input, psi_here) - - elseif chi_vec === nothing - if chi_prof === nothing - @warn "CriticalResonantField: chi_prof is not provided, using control chi_perp as fallback." - chi_here = slayer_ctrl.chi_perp - else - chi_here = _eval(chi_prof, psi_here) - end - - P_here = (4π * 1e-7) * abs(chi_here) / eta_here - - else - chi_here = chi_vec isa AbstractArray ? - Float64(chi_vec[isurf]) : - _eval(chi_vec, psi_here) - - P_here = (4π * 1e-7) * abs(chi_here) / eta_here - end - - - if P_here < 1 - @warn "CriticalResonantField: P < 1 at surface $isurf (P = $P_here)." - end - - tb = TorqueBalance( - SLAYERModel{:fitzpatrick}(), - p, - Q0_here, - P_here, - p.lu, - p.sval_r - ) - - Qs, bal, Qpeak, br_crit, _, Δs = - torque_balance_scan( - tb; - Qmin=ctrl.Qmin, - Qmax=ctrl.Qmax, - n=ctrl.n - ) - - push!(surface_index, isurf) - push!(Qpeak_vec, Qpeak) - push!(br_vec, br_crit) - push!(Q0_vec, Q0_here) - push!(P_vec, P_here) - - push!( - scan_data, - ( - surface=isurf, - Q=collect(Qs), - balance=collect(bal), - delta=collect(Δs), - Qpeak=Qpeak, - br_crit=br_crit, - Q0=Q0_here, - P=P_here, - lu=p.lu, - sval=p.sval_r, - m=p.m, - n=p.n, - params=p - ) - ) + model = SLAYERModel{:fitzpatrick}() + nsurf = length(params) + q_peak, br_crit, q0 = fill(NaN, nsurf), fill(NaN, nsurf), zeros(nsurf) + scan = CriticalResonantFieldScan[] + for (k, p) in enumerate(params) + # Cole Sec. IV: ω0 is the mode frequency in the E×B frame; diamagnetic parts enter via Q_e, Q_i. + q0[k] = p.tauk * p.n * profiles(rational_psi[k]).omega + tb = TorqueBalance(model, p, q0[k], p.P_tor, p.lu, 2.0 / p.sval_r^2) + Qs, bal, q_peak[k], br_crit[k], _, Δs = torque_balance_scan(tb; Qmin=ctrl.Qmin, Qmax=ctrl.Qmax, n=ctrl.n) + ctrl.store_scan && push!(scan, CriticalResonantFieldScan(collect(Qs), bal, Δs)) end - - return CriticalResonantFieldResult( - true, - params, - surface_index, - Qpeak_vec, - br_vec, - Q0_vec, - P_vec, - scan_data - ) + return CriticalResonantFieldResult(true, Int[p.ising for p in params], q_peak, br_crit, q0, + Float64[p.P_tor for p in params], scan) end - # --------------------------------------------------------------------- # Full pipeline: equilibrium + ForceFreeStates → parameters → analysis # --------------------------------------------------------------------- @@ -752,34 +533,8 @@ function run_slayer(equil, surfaces::AbstractVector, delta_prime_matrix::Abstrac rational_psi = Float64[surfaces[p.ising].psifac for p in params] rational_q = Float64[surfaces[p.ising].q for p in params] - # include critical resonant field workflow here - if control.critical_resonant_field.enabled - slayer_result = run_slayer_from_inputs(params, dp, control; rational_psi=rational_psi, rational_q=rational_q) - crf_result = run_critical_resonant_field(equil, surfaces, control; - dir_path=dir_path, - slayer_result=slayer_result, - profiles=profiles, - chi_prof=chi_perp, - viscous_profile=loaded.viscous_input) - combined_result = SLAYERResult( - slayer_result.enabled, - slayer_result.control, - slayer_result.params, - slayer_result.rational_psi, - slayer_result.rational_q, - slayer_result.dp_matrix, - slayer_result.Q_root, - slayer_result.omega_Hz, - slayer_result.gamma_Hz, - slayer_result.per_surface_extraction, - slayer_result.coupled_extraction, - slayer_result.layer_widths, - slayer_result.scan_data, - crf_result - ) - @info("SLAYER: critical resonant field workflow completed; " * - "critical br values for each rational surface are available in the result.") - return combined_result - end - return run_slayer_from_inputs(params, dp, control; rational_psi=rational_psi, rational_q=rational_q) + result = run_slayer_from_inputs(params, dp, control; rational_psi=rational_psi, rational_q=rational_q) + control.critical_resonant_field.enabled || return result + crf = run_critical_resonant_field(params, rational_psi, profiles, control.critical_resonant_field) + return SLAYERResult((f === :critical_resonant_field ? crf : getfield(result, f) for f in fieldnames(SLAYERResult))...) end From 407f96d3d54bac4f3d7a0680026ac96b47a4a329 Mon Sep 17 00:00:00 2001 From: Evan Bursch Date: Tue, 6 Oct 2026 11:21:20 -0400 Subject: [PATCH 12/14] Tearing - TEST - Cover the critical resonant field torque balance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unit tests pin the Cole-axis branch (Q_e < Q_peak < Q0), the scan window, local-maximum and pole selection, P = P_tor, Q0 = τ_k·n·ω_E, TOML parsing and the HDF5 metadata contract. The diiid_slayer_n1 regression case now tracks b_r/B_φ crit and Q_peak on the inner three surfaces. Co-Authored-By: Claude Opus 5.5 --- regression-harness/cases/diiid_slayer_n1.toml | 18 +++ test/runtests.jl | 1 + test/runtests_critical_resonant_field.jl | 115 ++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 test/runtests_critical_resonant_field.jl diff --git a/regression-harness/cases/diiid_slayer_n1.toml b/regression-harness/cases/diiid_slayer_n1.toml index 90edf2e09..ce620d53d 100644 --- a/regression-harness/cases/diiid_slayer_n1.toml +++ b/regression-harness/cases/diiid_slayer_n1.toml @@ -152,6 +152,24 @@ label = "SLAYER no_root flags [2/1,3/1,4/1]" noise_threshold = 0 order = 34 +# Critical resonant field (torque balance) for the inner three surfaces, matching +# the root pins above. +[quantities.crf_br_crit] +h5path = "Tearing/CriticalResonantField/br_crit" +type = "real_vector" +extract = "first_3" +label = "CRF b_r/B_φ crit [2/1,3/1,4/1]" +noise_threshold = 1e-9 +order = 40 + +[quantities.crf_q_peak] +h5path = "Tearing/CriticalResonantField/q_peak" +type = "real_vector" +extract = "first_3" +label = "CRF Q_peak [2/1,3/1,4/1]" +noise_threshold = 1e-6 +order = 41 + # Settings (catches accidental config drift) [quantities.slayer_enabled] h5path = "Tearing/enabled" diff --git a/test/runtests.jl b/test/runtests.jl index 389370209..9c4075d9f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -55,6 +55,7 @@ else include("./runtests_dispersion_amr.jl") include("./runtests_dispersion_polish.jl") include("./runtests_slayer_runner.jl") + include("./runtests_critical_resonant_field.jl") include("./runtests_kinetic.jl") include("./runtests_multiion.jl") include("./runtests_fullruns.jl") diff --git a/test/runtests_critical_resonant_field.jl b/test/runtests_critical_resonant_field.jl new file mode 100644 index 000000000..c8933f411 --- /dev/null +++ b/test/runtests_critical_resonant_field.jl @@ -0,0 +1,115 @@ +using GeneralizedPerturbedEquilibrium +using GeneralizedPerturbedEquilibrium.InnerLayer +using GeneralizedPerturbedEquilibrium.InnerLayer: InnerLayerModel + +# Layer stub returning a prescribed torque balance, to test the maximum selection. +struct _CRFStubLayer <: InnerLayerModel end +const _CRF_Q0_STUB = 10.0 +_crf_target(Q) = 0.1 + exp(-(Q - 1)^2 / 0.01) + 2exp(-(Q - 3)^2 / 0.01) +function InnerLayer.solve_inner(::_CRFStubLayer, p, Q::Number) + Qc = -real(Q) # undo the axis mirror cole_delta applies + jxb = 2 * (_CRF_Q0_STUB - Qc) / _crf_target(Qc) + return (; tearing=conj(im / jxb - 1e-2)) +end + +@testset "CriticalResonantField: torque balance" begin + using GeneralizedPerturbedEquilibrium + using GeneralizedPerturbedEquilibrium.InnerLayer + using GeneralizedPerturbedEquilibrium.InnerLayer: InnerLayerModel, SLAYERModel, SLAYERParameters + using GeneralizedPerturbedEquilibrium.Tearing.CriticalResonantField + using GeneralizedPerturbedEquilibrium.Runner + using GeneralizedPerturbedEquilibrium.Utilities: KineticProfiles + using HDF5 + + include("h5_metadata_check.jl") + + # DIII-D-like 2/1 layer (Fortran-normalized inputs of the shipped SLAYER example). + _mk(; n=1, P_tor=1.0, Q_e=1.38, Q_i=-2.15, ising=1) = SLAYERParameters(; + tau=1.2, lu=6.44e7, c_beta=0.112, D_norm=3.0, P_perp=1.0, P_tor=P_tor, + Q_e=Q_e, Q_i=Q_i, iota_e=Q_e / (Q_e - Q_i), tauk=1.31e-4, tau_r=21.1, + delta_n=885.0, rs=0.453, R0=1.74, bt=2.0, sval_r=1.09, eta=1.22e-8, + d_beta=3.6e-3, m=2, n=n, ising=ising) + model = SLAYERModel{:fitzpatrick}() + + @testset "Cole axis: branch lies between Q_e and Q0" begin + p = _mk() + @test cole_delta(model, p, 0.7) ≈ conj(InnerLayer.solve_inner(model, p, -0.7).tearing) + Q0 = 5.45 + tb = TorqueBalance(model, p, Q0, 1.0, p.lu, 2 / p.sval_r^2) + Qs, bal, Qpeak, br, idx, _ = torque_balance_scan(tb; n=401) + # Cole's picture: with Q0 above the electron pole, balance holds only for Q_e < Q < Q0. + @test p.Q_e < Qpeak < Q0 + @test bal[idx] > 0 && isfinite(br) && br > 0 + @test br ≈ sqrt(bal[idx] / (p.lu * 2 / p.sval_r^2)) + # Refining the grid moves b_crit by well under a percent. + _, _, _, br_fine, _, _ = torque_balance_scan(tb; n=801) + @test isapprox(br_fine, br; rtol=5e-3) + end + + @testset "Fortran scan window" begin + @test torque_balance_window(5.0, 1.0, -2.0) == (1.05, 10.0) + @test torque_balance_window(0.5, 1.0, -2.0) == (0.8 * -2.0, 0.95) + @test torque_balance_window(-0.5, 1.0, -2.0) == (1.5 * -2.0, 0.95) + end + + @testset "local-maximum selection and pole rejection" begin + p = _mk(; Q_e=50.0, Q_i=-50.0) + tb = TorqueBalance(_CRFStubLayer(), p, _CRF_Q0_STUB, 1.0, p.lu, 1.0) + _, bal, Qpeak, br, idx, _ = torque_balance_scan(tb; Qmin=0.0, Qmax=4.0, n=401) + @test Qpeak ≈ 3.0 atol = 0.011 + @test bal[idx] ≈ _crf_target(Qpeak) rtol = 1e-8 + # A maximum on the electron pole is skipped for the next one. + p_pole = _mk(; Q_e=3.0, Q_i=-50.0) + tb_pole = TorqueBalance(_CRFStubLayer(), p_pole, _CRF_Q0_STUB, 1.0, p.lu, 1.0) + _, _, Qpeak_pole, _, _, _ = torque_balance_scan(tb_pole; Qmin=0.0, Qmax=4.0, n=401) + @test Qpeak_pole ≈ 1.0 atol = 0.011 + # No interior maximum (monotone balance) returns NaN. + _, _, Qnone, brnone, inone, _ = @test_logs (:warn,) torque_balance_scan(tb; Qmin=2.7, Qmax=2.95, n=51) + @test isnan(Qnone) && isnan(brnone) && inone == 0 + end + + @testset "runner: P from P_tor, Q0 = τ_k·n·ω_E" begin + psi = collect(range(0.0, 1.0; length=11)) + ω_E = 4.0e4 + prof = KineticProfiles(; psi=psi, n_e=fill(4e19, 11), T_e=fill(1.7e3, 11), T_i=fill(2e3, 11), + omega=fill(ω_E, 11), omega_e=fill(-1e4, 11), omega_i=fill(1.6e4, 11)) + params = [_mk(; n=1, P_tor=3.0, ising=1), _mk(; n=2, P_tor=5.0, ising=2)] + ctrl = CriticalResonantFieldControl(; enabled=true, n=201, store_scan=true) + r = run_critical_resonant_field(params, [0.5, 0.7], prof, ctrl) + @test r.enabled + @test r.p_phi == [3.0, 5.0] + @test r.q0 ≈ [p.tauk * p.n * ω_E for p in params] + @test r.rational_index == [1, 2] + @test length(r.scan) == 2 && length(r.scan[1].Q) == 201 + @test !run_critical_resonant_field(params, [0.5, 0.7], prof, CriticalResonantFieldControl()).enabled + + # HDF5 output honours the metadata contract. + c = SLAYERControl(; enabled=true, scan_mode=:brute_force, nre=4, nim=4, critical_resonant_field=ctrl) + base = run_slayer_from_inputs(params, ComplexF64[1.0 0.0; 0.0 1.0], c; rational_psi=[0.5, 0.7], rational_q=[2.0, 1.5]) + res = SLAYERResult((f === :critical_resonant_field ? r : getfield(base, f) for f in fieldnames(SLAYERResult))...) + mktemp() do path, io + close(io) + h5open(path, "w") do f + write_slayer_hdf5!(f, res) + end + h5open(path, "r") do f + @test isempty(_collect_metadata_violations(f)) + g = f["Tearing/CriticalResonantField"] + @test read(g["p_phi"]) == [3.0, 5.0] + @test read(g["br_crit"]) ≈ r.br_crit nans = true + @test haskey(g, "Scan/Surface_2/Delta") + end + end + end + + @testset "control: TOML parsing and validation" begin + c = critical_resonant_field_control_from_toml(Dict("enabled" => true, "n" => 500)) + @test c.enabled && c.n == 500 && c.Qmin === nothing && !c.store_scan + @test critical_resonant_field_control_from_toml(Dict("Qmin" => -2.0)).Qmin == -2.0 + @test_throws ArgumentError critical_resonant_field_control_from_toml(Dict("viscous_input" => 1.0)) + s = slayer_control_from_toml(Dict("enabled" => true, "CriticalResonantField" => Dict("enabled" => true))) + @test s.critical_resonant_field.enabled + @test_throws ArgumentError Runner.validate(SLAYERControl(; inner_model=:ggj_shooting, + critical_resonant_field=CriticalResonantFieldControl(; enabled=true))) + end +end From f0325543cd61e715f8400f1655e2788b620286f5 Mon Sep 17 00:00:00 2001 From: Evan Bursch Date: Tue, 6 Oct 2026 11:33:17 -0400 Subject: [PATCH 13/14] Tearing - BUGFIX - Skip torque-balance maxima inside the diamagnetic pole region A one-grid-step exclusion lets the Q_e pole spike win on fine scans. Exclude maxima within 0.02 of Q_e and Q_i, Fortran SLAYER's pole-regularization radius, so the threshold is the maximum between Q_e and Q0. Co-Authored-By: Claude Opus 5.5 --- src/Tearing/CriticalResonantField/TorqueBalance.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Tearing/CriticalResonantField/TorqueBalance.jl b/src/Tearing/CriticalResonantField/TorqueBalance.jl index c78772f5e..9cffa549f 100644 --- a/src/Tearing/CriticalResonantField/TorqueBalance.jl +++ b/src/Tearing/CriticalResonantField/TorqueBalance.jl @@ -17,6 +17,8 @@ # Finite stand-in for α = S^(-1/3)·(−r_s Δ'_s) ≪ 1; b_crit moves ~4% over 1e-4 to 1e-1. const TORQUE_BALANCE_ALPHA = 1e-2 +# Half-width around Q_e, Q_i where the layer response is pole-dominated (Fortran SLAYER layfac). +const TORQUE_BALANCE_POLE_WIDTH = 0.02 """ TorqueBalance{M<:InnerLayerModel,P} @@ -80,8 +82,9 @@ end Sample `torque_balance_value` on `n` uniform real Q points and return the critical normalized field `br_crit = b_r/B_φ` (Cole Eq. 62) at the largest positive interior local -maximum of `bal`, located at `Qpeak = Qs[idx_peak]`. A maximum within one grid step of -the diamagnetic poles `Q_e`, `Q_i` is discarded as a pole artifact. `Qmin`/`Qmax` +maximum of `bal`, located at `Qpeak = Qs[idx_peak]`. A maximum within +`TORQUE_BALANCE_POLE_WIDTH` (or one grid step, if larger) of the diamagnetic poles `Q_e`, +`Q_i` is discarded as a pole artifact. `Qmin`/`Qmax` default to `torque_balance_window`. Returns NaN for `Qpeak`, `br_crit` and 0 for `idx_peak` when no valid maximum is found. """ @@ -93,8 +96,8 @@ function torque_balance_scan(tb::TorqueBalance; Qmin=nothing, Qmax=nothing, n::I bal = first.(out) Δs = last.(out) - dQ = step(Qs) - near_pole(Q) = abs(Q - p.Q_e) <= dQ || abs(Q - p.Q_i) <= dQ + w = max(step(Qs), TORQUE_BALANCE_POLE_WIDTH) + near_pole(Q) = abs(Q - p.Q_e) <= w || abs(Q - p.Q_i) <= w peaks = [i for i in 2:(n-1) if isfinite(bal[i]) && bal[i] > 0 && bal[i-1] < bal[i] && bal[i] >= bal[i+1] && !near_pole(Qs[i])] if isempty(peaks) From acd8bca7859970382ca52bba263cc87c702e89cd Mon Sep 17 00:00:00 2001 From: Evan Bursch Date: Tue, 6 Oct 2026 11:33:17 -0400 Subject: [PATCH 14/14] Docs - DOCS - Document the critical resonant field and its Fortran benchmark Add the Cole-Fitzpatrick torque balance, its inputs and approximations, the HDF5 outputs and the Fortran gslayer.f comparison figure to the Tearing page, cite Cole and Fitzpatrick 2006, and add the module to the API reference. Co-Authored-By: Claude Opus 5.5 --- docs/src/assets/crf_fortran_benchmark.png | Bin 0 -> 184266 bytes docs/src/citations.md | 8 +++ docs/src/inner_layer.md | 63 +++++++++++++++++++++- 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 docs/src/assets/crf_fortran_benchmark.png diff --git a/docs/src/assets/crf_fortran_benchmark.png b/docs/src/assets/crf_fortran_benchmark.png new file mode 100644 index 0000000000000000000000000000000000000000..80ce504eb992b7b72c1c5d4b9cb48c252a87965e GIT binary patch literal 184266 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 RgWz4}TiRM&oU?ZC{{dU$7C`_2 literal 0 HcmV?d00001 diff --git a/docs/src/citations.md b/docs/src/citations.md index e78370553..076daa527 100644 --- a/docs/src/citations.md +++ b/docs/src/citations.md @@ -124,6 +124,14 @@ The basis for the presently implemented in Fortran SLAYER code which computes th --- +> A. Cole and R. Fitzpatrick, "Drift-magnetohydrodynamical model of error-field penetration in tokamak plasmas," +> *Physics of Plasmas* **13**, 032503 (2006). +> DOI: [10.1063/1.2178167](https://doi.org/10.1063/1.2178167) + +The torque-balance error-field penetration threshold (Eqs. 61–62) behind the critical resonant field computed in `Tearing.CriticalResonantField`. + +--- + > A. Burgess et al., "Tearing Stability Prediction Combining Toroidal Calculations With a Two-Fluid Slab Layer," > Preprint (2026). diff --git a/docs/src/inner_layer.md b/docs/src/inner_layer.md index 7ddfecb95..20fc32bb9 100644 --- a/docs/src/inner_layer.md +++ b/docs/src/inner_layer.md @@ -3,7 +3,8 @@ The `Tearing` module groups the resistive tearing-mode analysis stack: `InnerLayer` (per-surface inner-layer matching data Δ(Q) for the GGJ and SLAYER models), `Dispersion` (physics-agnostic complex-plane scan and -contour-intersection root extraction), and `Runner` (user-facing TOML +contour-intersection root extraction), `CriticalResonantField` (torque-balance +error-field penetration threshold), and `Runner` (user-facing TOML configuration, profile loading, and HDF5 output). ## Layer Inputs @@ -278,6 +279,60 @@ res = solve_ray(p, GGJ.inner_Q(p, γ)) res.Δ, res.resid, res.bc_cond ``` +## Critical resonant field + +With `[SLAYER.CriticalResonantField] enabled = true`, each SLAYER surface also gets the +critical resonant field for error-field penetration, from the steady-state torque balance of +Cole and Fitzpatrick, Phys. Plasmas **13**, 032503 (2006). The electromagnetic torque on the +layer balances the viscous restoring torque when (Cole Eq. 61) + +```math +\frac{\operatorname{Im}\hat\Delta(Q)}{|\alpha + \hat\Delta(Q)|^2} + = \frac{2P\,(Q_0 - Q)}{S\hat\kappa\,(b_r/B_\phi)^2}, +\qquad +\hat\kappa = \left[\frac{2}{s}\right]^2 \int_{r_s}^{a} \frac{\mu(r_s)}{\mu(r)}\,\frac{dr}{r}, +``` + +and balance is lost above (Cole Eq. 62) + +```math +\left(\frac{b_r}{B_\phi}\right)^2_\mathrm{crit} + = \max_Q \frac{2P\,(Q_0 - Q)}{S\hat\kappa\,\operatorname{Im}[-1/(\alpha + \hat\Delta(Q))]} . +``` + +- **Inputs.** P is each layer's `P_tor` (so χ_φ from the kinetic file, or the scalar + `chi_tor`), S its Lundquist number, and Q0 = τ_k·n·ω_E the natural E×B rotation of the + m/n mode (Cole's ω0; the diamagnetic drifts enter through Q_e and Q_i in Δ̂). +- **Approximations.** As in Fortran `gslayer.f`, the viscosity integral is taken as 1/2 + (κ̂ = 2/s²) and α = 10⁻² stands in for S^(−1/3)(−r_s Δ'_s) ≪ 1 (b_crit moves about 4 % + over 10⁻⁴–10⁻¹). +- **Q axis.** Q is on Cole's axis, with the diamagnetic poles at Q_e and Q_i; `solve_inner` + mirrors the real axis, so the scan uses conj(Δ(−Q)). +- **Maximum.** The scan window follows `gslayer.f` (between Q0 and the Q_e pole), and the + largest positive interior local maximum is taken, skipping any within 0.02 of Q_e or Q_i + (Fortran SLAYER's pole-regularization radius). + +Outputs go to `Tearing/CriticalResonantField/` (`br_crit` = b_r/B_φ, `q_peak`, `q0`, `p_phi`, +and with `store_scan` the per-surface `Scan/Surface_/{Q, balance, Delta}`). + +### Benchmark against Fortran + +On the DIII-D-like example (2/1–6/1, n = 1, P = 1, κ̂ = 2/s², Q ∈ [−5, 5] with 20001 +points), both codes were given Fortran's normalized inputs. + +- **Torque-balance routine.** Fed Fortran's own Δ(Q) table with the pole exclusion narrowed to + one grid step, the Julia routine reproduces Fortran's b_crit and Q_peak to all printed digits + on every surface. +- **Pole handling.** Fortran's global maximum sits within 0.003 of the Q_e pole on 2/1, 3/1, + 4/1 and 6/1. Skipping the pole region moves the threshold to the torque-balance maximum + between Q_e and Q0 (blue dots below), lowering the Fortran-table b_crit by 6–88 %. +- **Layer model.** Fortran solves Park's drift-MHD layer and Julia Fitzpatrick's, so Δ(Q) + differs by a median 7–78 % between Q_i and Q_e, and Julia's b_crit is 82–89 % of the + Fortran-table value on 2/1, 3/1, 4/1 and 6/1. The 5/1 edge surface is dominated by a + zero of the electromagnetic torque in both codes and is not a usable threshold. + +![Fortran vs Julia inner-layer Δ(Q) and torque balance](assets/crf_fortran_benchmark.png) + ## API Reference ### InnerLayer @@ -304,6 +359,12 @@ Modules = [GeneralizedPerturbedEquilibrium.InnerLayer.SLAYER] Modules = [GeneralizedPerturbedEquilibrium.Dispersion] ``` +## CriticalResonantField + +```@autodocs +Modules = [GeneralizedPerturbedEquilibrium.Tearing.CriticalResonantField] +``` + ## Runner ```@autodocs