Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
6f6e546
fix fprime for the negative Bp case
HarukiST Aug 1, 2024
731a330
define increasing radial label xcoord
HarukiST Aug 1, 2024
107c5db
pressure extrapolation fix
HarukiST Aug 2, 2024
0c6a084
pressure and pprime has been added in __init__
HarukiST Aug 2, 2024
aecafcb
slight modification on f_psi_sign
HarukiST Aug 2, 2024
16c5697
fprime and pprime have been added in read_geqdsk
HarukiST Aug 2, 2024
2816d33
extrapolation rule for fprime/pprime should be ext=1 for consistency …
HarukiST Aug 2, 2024
6f38a09
function pprime has been added
HarukiST Aug 2, 2024
4c1fb53
add pprime and ffprime in doc of read
HarukiST Aug 2, 2024
44c2778
fix interpolation for negative Bp case
HarukiST Aug 3, 2024
f3a364c
cocos=+1 convention fix in find_critical
HarukiST Aug 12, 2024
9c86ab1
fix xrd in _geqdsk.py
HarukiST Aug 13, 2024
58489ae
fix xrd in _geqdsk.py
HarukiST Aug 13, 2024
59dabca
fix pprime in _geqdsk.py
HarukiST Aug 13, 2024
4b26b80
flake8 fix in tokamak.py
HarukiST Aug 13, 2024
93bdecf
flake8 fix in _geqdsk.py
HarukiST Aug 13, 2024
0bf561f
flake8 fix in _geqdsk.py
HarukiST Aug 13, 2024
efbd961
flake8 fix in _geqdsk.py
HarukiST Aug 13, 2024
be66d65
flake8 fix in tokamak.py
HarukiST Aug 13, 2024
0d3ae26
flake8 fix in tokamak.py
HarukiST Aug 13, 2024
e806fb4
black fix in tokamak.py
HarukiST Aug 13, 2024
8f5b7c6
black fixs in _geqdsk.py
HarukiST Aug 13, 2024
bf27fa4
cocos class has been added
HarukiST Aug 14, 2024
ac8593d
flake8 and black fixes
HarukiST Aug 15, 2024
c6bf6dd
add signed Bp function in module equilibrium
HarukiST Sep 18, 2024
8458d98
use signed Bp in zShift calculation
HarukiST Sep 18, 2024
de512ca
black reformatting forsigned Bp
HarukiST Sep 18, 2024
7d849d3
f_psi_sign has been added for signed Bp
HarukiST Sep 18, 2024
f7e7882
f_psi_sign has been added in torpex.py for signed Bp
HarukiST Sep 18, 2024
7653245
f_psi_sign has been added for matfile in torpex.py for signed Bp
HarukiST Sep 18, 2024
a69274d
f_psi_sign has been added for coil in torpex.py for signed Bp
HarukiST Sep 18, 2024
bf4eebb
signed Bp with self.bpsign rather than self.f_psi_sign in geometry1 f…
HarukiST Sep 18, 2024
dabf4d0
flipping sign of Bp in if statement with Bp_dot_grady has been commen…
HarukiST Sep 18, 2024
bc2e893
note on capBpYlowXpoint has been added
HarukiST Sep 18, 2024
575226c
use positive definit Jacobian J=h/|Bp|
HarukiST Sep 20, 2024
a25caac
modify Jcheck for Jacobian J=h/|Bp|
HarukiST Sep 20, 2024
8453924
add Jpar0 based on output-jpar0 branch
HarukiST Sep 20, 2024
7705e2c
add dummy sinty for backward compatibility
HarukiST Sep 26, 2024
ed2c33c
add dummy sinty for backward compatibility (black)
HarukiST Sep 26, 2024
f5b8f87
fix bxcvx in bxkappae
HarukiST Sep 26, 2024
de25952
fix curvature terms in bxkappae
HarukiST Oct 1, 2024
aeaddb9
fix curvature terms in bxkappae
HarukiST Oct 1, 2024
2617c5d
add in bxkappa2 and bxkappa3
HarukiST Oct 4, 2024
36fb632
re-define BOUT-3 style curvature with pre-cancellation as bxkappa
HarukiST Oct 4, 2024
b5331ed
dx should be always positive definie
HarukiST Oct 8, 2024
ffb98cd
comment fix
HarukiST Nov 12, 2024
37f12e3
add netcdf3_64bit for BOUTv3.1
HarukiST Nov 12, 2024
0dcac98
black fix
HarukiST Nov 12, 2024
d7af073
black fix
HarukiST Nov 12, 2024
598fd8e
delete useless duplication of hthe and hy
HarukiST Nov 15, 2024
4a5dde0
set dx at separatrix without pf regions
HarukiST Jan 16, 2025
4ebd334
set minimum grid width around sepatatrix
HarukiST May 19, 2025
218c501
clean pressure and Jpar
HarukiST May 19, 2025
80b01e5
add dummy data for kinetic profiles
HarukiST May 20, 2025
756be55
add user option of kinetic profiles
HarukiST May 20, 2025
30ee20a
name of option of kinetic profiles has been changed
HarukiST May 20, 2025
edbe03e
delete options for kinetic profiles
HarukiST May 23, 2025
8574183
delete options for kinetic profiles
HarukiST Sep 4, 2025
06a8fca
formatted with black
HarukiST Sep 4, 2025
2707fb6
formatted with black
HarukiST Sep 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions hypnotoad/cases/circular.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ def __init__(self, settings=None, nonorthogonal_settings=None):
# Core-only geometry: add connection so domain is periodic in y
self.makeConnection("circular", 0, "circular", 0)

self.f_psi_sign = np.sign(self.psi_r(1.0) - self.psi_r(0.0))

def makeRegion(self):
"""
Create the EquilibriumRegion to build the grid around
Expand Down
104 changes: 84 additions & 20 deletions hypnotoad/cases/tokamak.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ def __init__(
psi1D,
fpol1D,
pressure=None,
fprime=None,
pprime=None,
wall=None,
psi_axis_gfile=None,
psi_bdry_gfile=None,
Expand All @@ -340,6 +342,8 @@ def __init__(
--------

pressure[nf] = 1D array of pressure as a function of psi1D [Pa]
fprime[nf] = 1D array of df / dpsi
pprime[nf] = 1D array of dp / dpsi . If set then pressure must also be set.

wall = [(R0,Z0), (R1, Z1), ...]
A list of coordinate pairs, defining the vessel wall.
Expand All @@ -362,6 +366,9 @@ def __init__(

"""

if pprime is not None:
assert pressure is not None

self.user_options = self.user_options_factory.create(settings)

if self.user_options.reverse_current:
Expand Down Expand Up @@ -403,50 +410,83 @@ def __init__(
):
# if psi_outer is not beyond the last point of psi1D, no need to extend
# Exclude first point since duplicates last point in core
psiSOL = np.linspace(psi1D[-1], psi_outer, 50)[1:]
psi_lcfs = psi1D[-1]
psiSOL = np.linspace(psi_lcfs, psi_outer, 50)[1:]
psi1D = np.concatenate([psi1D, psiSOL])

# fpol constant in SOL
fpol1D = np.concatenate([fpol1D, np.full(psiSOL.shape, fpol1D[-1])])

if pressure is not None:
# Use an exponential decay for the pressure, based on
# the value and gradient at the plasma edge
p0 = pressure[-1]
# p = p0 * exp( (psi - psi0) * dpdpsi / p0)
pressure = np.concatenate([pressure, p0 * np.exp(psiSOL * dpdpsi / p0)])
if fprime is not None:
fprime = np.concatenate([fprime, np.full(psiSOL.shape, 0.0)])

if pressure is not None:
# Use an exponential decay for the pressure, based on
# the value and gradient at the plasma edge
p_lcfs = pressure[-1]
# p_SOL = p_lcfs * exp( (psi - psi_lcfs) * dpdpsi / p_lcfs)
p_SOL = p_lcfs * np.exp((psiSOL - psi_lcfs) * dpdpsi / p_lcfs)
pressure = np.concatenate([pressure, p_SOL])
if pprime is not None:
pprime = np.concatenate([pprime, dpdpsi * p_SOL / p_lcfs])

self.magneticFunctionsFromGrid(
R1D, Z1D, psi2D, self.user_options.psi_interpolation_method
)

self.f_psi_sign = 1.0
if len(fpol1D) > 0:
# Spline for interpolation of f = R*Bt
# Note: radial label must be increasing
if psi1D[-1] < psi1D[0]:
self.f_psi_sign = -1.0
else:
self.f_psi_sign = 1.0

# Note: psi1D must be increasing
if psi1D[-1] < psi1D[0]:
self.f_psi_sign = -1.0
xcoord = self.f_psi_sign * psi1D

self.f_spl = interpolate.InterpolatedUnivariateSpline(
psi1D * self.f_psi_sign, fpol1D, ext=3
)
if len(fpol1D) > 0:

# Spline for interpolation of f = R*Bt
self.f_spl = interpolate.InterpolatedUnivariateSpline(xcoord, fpol1D, ext=3)
# ext=3 specifies that boundary values are used outside range

# Spline representing the derivative of f
self.fprime_spl = self.f_spl.derivative()
if fprime is not None:
self.fprime_spl = interpolate.InterpolatedUnivariateSpline(
xcoord, fprime, ext=1
)
else:
# fprime is derivative of fpol with respect to psi
# rather than increasing radial label xcoord
fpol_f_psi_sign_spl = interpolate.InterpolatedUnivariateSpline(
xcoord, fpol1D * self.f_psi_sign, ext=3
)
self.fprime_spl = fpol_f_psi_sign_spl.derivative()
else:
self.f_spl = lambda psi: 0.0
self.fprime_spl = lambda psi: 0.0

# Optional pressure profile
if pressure is not None:
self.p_spl = interpolate.InterpolatedUnivariateSpline(
psi1D * self.f_psi_sign, pressure, ext=3
xcoord, pressure, ext=3
)

if pprime is not None:
self.pprime_spl = interpolate.InterpolatedUnivariateSpline(
xcoord, pprime, ext=1
)
else:
# pprime is derivative of pressure with respect to psi
# rather than increasing radial label xcoord

pressure_f_psi_sign_spl = interpolate.InterpolatedUnivariateSpline(
xcoord, pressure * self.f_psi_sign, ext=3
)
self.pprime_spl = pressure_f_psi_sign_spl.derivative()

else:
# If no pressure, then not output to grid file
self.p_spl = None
self.pprime_spl = None

# Find critical points (O- and X-points)
R2D, Z2D = np.meshgrid(R1D, Z1D, indexing="ij")
Expand Down Expand Up @@ -816,7 +856,13 @@ def describeSingleNull(self):
dpsidi_pf = (self.psi_sep[0] - self.psi_pf_upper) / self.user_options.nx_pf

# Get the smallest absolute grid spacing for the separatrix
dpsidi_sep = min([dpsidi_sol, dpsidi_core, dpsidi_pf], key=abs)
# dpsidi_pf_minimum is introduced to avoid very narrow radial grid width
# around separatrix in core and SOL region and 0.3 is an emprical factor.

# dpsidi_sep = min([dpsidi_sol, dpsidi_core, dpsidi_pf], key=abs)
dpsidi_sep = min([dpsidi_sol, dpsidi_core], key=abs) # set dx at separatrix
# dpsidi_pf_minimum = max([0.3*dpsidi_sep, 0.3*dpsidi_pf], key=abs)
dpsidi_pf_minimum = max([0.3 * dpsidi_sep, dpsidi_pf], key=abs)

# decrease (assuming the factor is <1) the spacing around the separatrix by the
# factor psi_spacing_separatrix_multiplier
Expand Down Expand Up @@ -859,6 +905,7 @@ def describeSingleNull(self):
"psi_start": self.psi_pf_lower,
"psi_end": psi_sep,
"grad_end": dpsidi_sep,
"grad_start": dpsidi_pf_minimum,
}

leg_regions = {
Expand Down Expand Up @@ -909,6 +956,7 @@ def describeSingleNull(self):
"psi_start": self.psi_pf_upper,
"psi_end": psi_sep,
"grad_end": dpsidi_sep,
"grad_start": dpsidi_pf_minimum,
}

leg_regions = {
Expand Down Expand Up @@ -1621,9 +1669,14 @@ def createRegionObjects(self, all_regions, segments):
eqreg.pressure = lambda psi: self.pressure(
leg_psi + sign * abs(psi - leg_psi)
)
# Set pprime and fprime to zero so Jpar0 = 0
eqreg.pprime = lambda psi: 0.0
eqreg.fprime = lambda psi: 0.0
else:
# Core region, so use the core pressure
# Core region, so use the core profiles
eqreg.pressure = self.pressure
eqreg.pprime = self.pprime
eqreg.fprime = self.fpolprime

region_objects[name] = eqreg
# The region objects need to be sorted, so that the
Expand Down Expand Up @@ -1687,6 +1740,13 @@ def pressure(self, psi):
return None
return self.p_spl(psi * self.f_psi_sign)

@Equilibrium.handleMultiLocationArray
def pprime(self, psi):
"""psi-derivative of plasma pressure"""
if self.pprime_spl is None:
return None
return self.pprime_spl(psi * self.f_psi_sign)

@property
def Bt_axis(self):
"""Calculate toroidal field on axis"""
Expand Down Expand Up @@ -1751,6 +1811,8 @@ def read_geqdsk(

pressure = data["pres"]
fpol = data["fpol"]
fprime = data["ffprime"] / fpol
pprime = data["pprime"]

result = TokamakEquilibrium(
R1D,
Expand All @@ -1761,6 +1823,8 @@ def read_geqdsk(
psi_bdry_gfile=psi_bdry_gfile,
psi_axis_gfile=psi_axis_gfile,
pressure=pressure,
fprime=fprime,
pprime=pprime,
wall=wall,
make_regions=make_regions,
settings=settings,
Expand Down
9 changes: 9 additions & 0 deletions hypnotoad/cases/torpex.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ def __init__(self, equilibOptions, meshOptions):
self.Rmax = float("inf")
self.Zmin = -float("inf")
self.Zmax = float("inf")

self.f_psi_sign = 1.0 # H.seto (dummy)

elif "gfile" in equilibOptions:
# load a g-file
with open(equilibOptions["gfile"], "rt") as fh:
Expand Down Expand Up @@ -206,6 +209,9 @@ def __init__(self, equilibOptions, meshOptions):
"direction of plasma current should be clockwise to be "
"consistent with sign of grad(psi)"
)

self.f_psi_sign = numpy.sign(psi_bndry - psi_axis) # H.seto (dummy)

# index of a point close to the magnetic axis
i_axis = numpy.searchsorted(R, R_axis)
j_axis = numpy.searchsorted(Z, Z_axis)
Expand Down Expand Up @@ -294,6 +300,9 @@ def __init__(self, equilibOptions, meshOptions):
f"{eqfile['Z'][0, 0][ZindMid, RindMid]}"
)
self.Bt_axis = Bt[ZindMid, RindMid]

self.f_psi_sign = numpy.sign(0.0 - psi[ZindMid, RindMid]) # H.seto (dummy)

else:
raise ValueError("Failed to initialise psi function from inputs")

Expand Down
Loading
Loading