Skip to content

Commit d5d9144

Browse files
committed
refactor sol() with OpenFieldLine constructor
mention @ggdose
1 parent 75f9480 commit d5d9144

File tree

2 files changed

+141
-105
lines changed

2 files changed

+141
-105
lines changed

src/physics/fluxsurfaces.jl

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,11 @@ end
210210
PSI_interpolant::Interpolations.AbstractInterpolation;
211211
precision::Float64=1e-7)
212212
213-
Returns `[psi_low, psi_up], null_is_inside` of the two flux surfaces around the last diverted flux surface.
213+
Returns `psi_last_lfs, `psi_first_lfs_far`, and `null_within_wall`
214214
215-
psi_up will be the first surface inside OFL[:lfs_far]; psi_low will be the last surface inside OFL[:lfs]
215+
psi_first_lfs_far will be the first surface inside OFL[:lfs_far]; psi_last_lfs will be the last surface inside OFL[:lfs]
216216
217-
Precision between the two is defined on the poloidal crossection area at the OMP (Psol*precision = power flowing between psi_up and psi_low ~ 0)
217+
Precision between the two is defined on the poloidal crossection area at the OMP (Psol*precision = power flowing between psi_first_lfs_far and psi_last_lfs ~ 0)
218218
"""
219219
function find_psi_last_diverted(
220220
eqt::IMAS.equilibrium__time_slice,
@@ -225,7 +225,7 @@ function find_psi_last_diverted(
225225

226226
# if no wall in dd, psi_last diverted not defined
227227
if isempty(wall_r) || isempty(wall_z)
228-
return [Float64[], Float64[]], true # [psi_low, psi_up], null_is_inside
228+
return (psi_last_lfs=NaN, psi_first_lfs_far=NaN, null_within_wall=true)
229229
end
230230

231231
RA = eqt.global_quantities.magnetic_axis.r
@@ -270,7 +270,7 @@ function find_psi_last_diverted(
270270
z_intersect = z_intersect[partialsortperm(dist, 1:2)]
271271
end
272272

273-
# order intersection clockwise (needed for null_is_inside)
273+
# order intersection clockwise (needed for null_within_wall)
274274
angle = 2 * π .- mod.(atan.(z_intersect .- ZA, r_intersect .- RA), 2 * π) # clockwise angle from midplane
275275
r_intersect = r_intersect[sortperm(angle)]
276276
z_intersect = z_intersect[sortperm(angle)]
@@ -283,20 +283,21 @@ function find_psi_last_diverted(
283283
vec2 = Xpoint2 - [r_intersect[1], z_intersect[1]]
284284
if vec[1] * vec2[2] - vec[2] * vec2[1] > 0
285285
# upper null on the left = is outside wall
286-
null_is_inside = false
286+
null_within_wall = false
287287
else
288288
# upper null on the right = is inside wall
289-
null_is_inside = true
289+
null_within_wall = true
290290
end
291-
# find the two surfaces psi_up (inside OFL[:lfs_far]) and psi_low (inside OFL[:lfs]) around the last diverted flux surface
291+
292+
# find the two surfaces `psi_first_lfs_far` and `psi_last_lfs` around the last diverted flux surface
292293
counter_max = 50
293294
counter = 0
294295
psi_axis_level = eqt.profiles_1d.psi[1] # psi value on axis
295296
psi_sign = sign(psi_separatrix - psi_axis_level) # sign of the poloidal flux taking psi_axis = 0
296-
psi_up = psi_wall_midplane
297-
psi_low = psi_separatrix
298-
psi = (psi_up + psi_low) / 2
299-
err = 1
297+
psi_first_lfs_far = psi_wall_midplane
298+
psi_last_lfs = psi_separatrix
299+
psi = (psi_first_lfs_far + psi_last_lfs) / 2
300+
err = Inf
300301
while abs(err) > precision && counter < counter_max
301302
surface, _ = flux_surface(eqt, psi, :open)
302303
for (r, z) in surface
@@ -308,35 +309,35 @@ function find_psi_last_diverted(
308309

309310
if sign_z * zz[1] > 0 || sign_z * zz[end] > 0
310311
# psi intersects FW -> update upper bound
311-
psi_up = psi
312+
psi_first_lfs_far = psi
312313
else
313-
#psi intersects divertor -> update lower bound
314-
psi_low = psi
314+
# psi intersects divertor -> update lower bound
315+
psi_last_lfs = psi
315316
end
316317
end
317318

318-
# better to compute error on poloidal area between [psi_low, psi_up] (needed for accurate power balance)
319-
r_up = r_mid_itp(psi_up)
320-
r_low = r_mid_itp(psi_low)
319+
# better to compute error on poloidal area between [psi_last_lfs, psi_first_lfs_far] (needed for accurate power balance)
320+
r_up = r_mid_itp(psi_first_lfs_far)
321+
r_low = r_mid_itp(psi_last_lfs)
321322

322323
A = π * (r_up^2 - r_low^2) # annular area between r_up and r_low [m^2]
323324
err = abs(A)
324-
psi = (psi_up + psi_low) / 2
325+
psi = (psi_first_lfs_far + psi_last_lfs) / 2
325326

326327
counter = counter + 1
327328
end
328329

329-
return [psi_low, psi_up], null_is_inside # return both psi_up and psi_low to increase resolution around last diverted flux surface
330+
return (psi_last_lfs=psi_last_lfs, psi_first_lfs_far=psi_first_lfs_far, null_within_wall=null_within_wall)
330331
end
331332

332333
"""
333334
find_psi_last_diverted(eqt::IMAS.equilibrium__time_slice, wall::IMAS.wall, PSI_interpolant::Interpolations.AbstractInterpolation; precision::Float64=1e-7)
334335
335-
Returns `[psi_low, psi_up], null_is_inside` of the two flux surfaces around the last diverted flux surface.
336+
Returns `psi_last_lfs, `psi_first_lfs_far`, and `null_within_wall`
336337
337-
psi_up will be the first surface inside OFL[:lfs_far]; psi_low will be the last surface inside OFL[:lfs]
338+
psi_first_lfs_far will be the first surface inside OFL[:lfs_far]; psi_last_lfs will be the last surface inside OFL[:lfs]
338339
339-
Precision between the two is defined on the poloidal crossection area at the OMP (Psol*precision = power flowing between psi_up and psi_low ~ 0)
340+
Precision between the two is defined on the poloidal crossection area at the OMP (Psol*precision = power flowing between psi_first_lfs_far and psi_last_lfs ~ 0)
340341
"""
341342

342343
function find_psi_last_diverted(eqt::IMAS.equilibrium__time_slice, wall::IMAS.wall, PSI_interpolant::Interpolations.AbstractInterpolation; precision::Float64=1e-7)
@@ -347,11 +348,11 @@ end
347348
"""
348349
find_psi_last_diverted(dd.IMAS.dd; precision::Float64=1e-7)
349350
350-
Returns `[psi_low, psi_up], null_is_inside` of the two flux surfaces around the last diverted flux surface.
351+
Returns `psi_last_lfs, `psi_first_lfs_far`, and `null_within_wall`
351352
352-
psi_up will be the first surface inside OFL[:lfs_far]; psi_low will be the last surface inside OFL[:lfs]
353+
psi_first_lfs_far will be the first surface inside OFL[:lfs_far]; psi_last_lfs will be the last surface inside OFL[:lfs]
353354
354-
Precision between the two is defined on the poloidal crossection area at the OMP (Psol*precision = power flowing between psi_up and psi_low ~ 0)
355+
Precision between the two is defined on the poloidal crossection area at the OMP (Psol*precision = power flowing between psi_first_lfs_far and psi_last_lfs ~ 0)
355356
"""
356357

357358
function find_psi_last_diverted(dd::IMAS.dd; precision::Float64=1e-7)
@@ -1025,8 +1026,8 @@ function find_x_point!(eqt::IMAS.equilibrium__time_slice)::IDSvector{<:IMAS.equi
10251026

10261027

10271028
# remove x-points that have fallen on the magnetic axis
1028-
sign_closest = sign(psidist_lcfs_xpoints[argmin(abs.(psidist_lcfs_xpoints))] )# sign of psi of closest X-point in psi to LCFS
1029-
index = psidist_lcfs_xpoints.*psi_sign .>= (psi_sign - sign_closest * 1E-5) * psidist_lcfs_xpoints[argmin(abs.(psidist_lcfs_xpoints))]
1029+
sign_closest = sign(psidist_lcfs_xpoints[argmin(abs.(psidist_lcfs_xpoints))])# sign of psi of closest X-point in psi to LCFS
1030+
index = psidist_lcfs_xpoints .* psi_sign .>= (psi_sign - sign_closest * 1E-5) * psidist_lcfs_xpoints[argmin(abs.(psidist_lcfs_xpoints))]
10301031
psidist_lcfs_xpoints = psidist_lcfs_xpoints[index]
10311032
eqt.boundary.x_point = eqt.boundary.x_point[index]
10321033
z_x = z_x[index]

0 commit comments

Comments
 (0)