Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
83a9ca1c9a |
@ -33,7 +33,7 @@ let
|
|||||||
src = builtins.filterSource sieve ./.;
|
src = builtins.filterSource sieve ./.;
|
||||||
|
|
||||||
format = "other";
|
format = "other";
|
||||||
propagatedBuildInputs = with pkgs.python3Packages; [ numpy scipy matplotlib ];
|
propagatedBuildInputs = with pkgs.python3Packages; [ numpy matplotlib ];
|
||||||
makeFlags = [ "PREFIX=$(out)" ];
|
makeFlags = [ "PREFIX=$(out)" ];
|
||||||
|
|
||||||
dontConfigure = true;
|
dontConfigure = true;
|
||||||
|
@ -58,7 +58,7 @@ def read_eqdsk(filepath: Path) -> Eqdsk:
|
|||||||
skip(file, nr * 4)
|
skip(file, nr * 4)
|
||||||
|
|
||||||
# read flux and safety factor
|
# read flux and safety factor
|
||||||
psi = read(file, nr * nz).reshape((nr, nz), order='F').T
|
psi = read(file, nr * nz).reshape(nr, nz)
|
||||||
q = read(file, nr)
|
q = read(file, nr)
|
||||||
|
|
||||||
# normalise flux
|
# normalise flux
|
||||||
|
@ -39,20 +39,6 @@ def cli_args() -> argparse.Namespace:
|
|||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
def placeholder(ax: plt.Axes, text: str):
|
|
||||||
'''
|
|
||||||
Puts a placeholder text at the center of an axis
|
|
||||||
'''
|
|
||||||
left, width = .25, .5
|
|
||||||
bottom, height = .25, .5
|
|
||||||
right = left + width
|
|
||||||
top = bottom + height
|
|
||||||
|
|
||||||
ax.text(0.5*(left+right), 0.5*(top+bottom), text,
|
|
||||||
horizontalalignment='center',
|
|
||||||
verticalalignment='center')
|
|
||||||
|
|
||||||
|
|
||||||
def align_yaxis(*axes: [plt.Axes]):
|
def align_yaxis(*axes: [plt.Axes]):
|
||||||
'''
|
'''
|
||||||
Aligns the origins of two axes
|
Aligns the origins of two axes
|
||||||
@ -130,7 +116,6 @@ def plot_poloidal(inputs: Path, outputs: Path, ax: plt.Axes):
|
|||||||
ax.set_ylabel('$z$ / m')
|
ax.set_ylabel('$z$ / m')
|
||||||
|
|
||||||
# load flux surfaces
|
# load flux surfaces
|
||||||
try:
|
|
||||||
surfaces = gray.read_table(outputs / 'flux-surfaces.71.txt')
|
surfaces = gray.read_table(outputs / 'flux-surfaces.71.txt')
|
||||||
surfaces = surfaces.reshape(-1, int(surfaces['i'].max()))
|
surfaces = surfaces.reshape(-1, int(surfaces['i'].max()))
|
||||||
|
|
||||||
@ -155,8 +140,6 @@ def plot_poloidal(inputs: Path, outputs: Path, ax: plt.Axes):
|
|||||||
fontsize=10, fmt={1: label})
|
fontsize=10, fmt={1: label})
|
||||||
ax.plot(np.nan, np.nan, '--', color='xkcd:ocean blue',
|
ax.plot(np.nan, np.nan, '--', color='xkcd:ocean blue',
|
||||||
label='rational surfaces')
|
label='rational surfaces')
|
||||||
except FileNotFoundError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# load limiter
|
# load limiter
|
||||||
limiter = gray.get_limiter(conf, inputs)
|
limiter = gray.get_limiter(conf, inputs)
|
||||||
@ -203,15 +186,12 @@ def plot_toroidal(inputs: Path, outputs: Path, ax: plt.Axes):
|
|||||||
limiter = gray.get_limiter(conf, inputs)
|
limiter = gray.get_limiter(conf, inputs)
|
||||||
|
|
||||||
# plot plasma boundary
|
# plot plasma boundary
|
||||||
try:
|
|
||||||
surfaces = gray.read_table(outputs / 'flux-surfaces.71.txt')
|
surfaces = gray.read_table(outputs / 'flux-surfaces.71.txt')
|
||||||
boundary = surfaces[np.isclose(surfaces['ψ_n'], 1, 1e-3)]
|
boundary = surfaces[np.isclose(surfaces['ψ_n'], 1, 1e-3)]
|
||||||
|
|
||||||
# plot plasma boundary
|
# plot plasma boundary
|
||||||
plot_circle(ax, radius=boundary['R'].min(), color='xkcd:slate gray')
|
plot_circle(ax, radius=boundary['R'].min(), color='xkcd:slate gray')
|
||||||
plot_circle(ax, radius=boundary['R'].max(), color='xkcd:slate gray')
|
plot_circle(ax, radius=boundary['R'].max(), color='xkcd:slate gray')
|
||||||
except FileNotFoundError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# plot limiter
|
# plot limiter
|
||||||
if limiter[0].size > 0:
|
if limiter[0].size > 0:
|
||||||
@ -394,30 +374,23 @@ def plot_inputs(inputs: Path, outputs: Path, axes: [plt.Axes]):
|
|||||||
'''
|
'''
|
||||||
from matplotlib.colors import TwoSlopeNorm
|
from matplotlib.colors import TwoSlopeNorm
|
||||||
|
|
||||||
conf = gray.read_conf(inputs / 'gray.ini')
|
|
||||||
|
|
||||||
try:
|
|
||||||
maps = gray.read_table(outputs / 'inputs-maps.72.txt')
|
maps = gray.read_table(outputs / 'inputs-maps.72.txt')
|
||||||
|
|
||||||
# filter valid points
|
# filter valid points
|
||||||
maps = maps[maps['ψ_n'] > 0]
|
maps = maps[maps['ψ_n'] > 0]
|
||||||
flux = maps['R'], maps['z'], maps['ψ_n']
|
flux = maps['R'], maps['z'], maps['ψ_n']
|
||||||
except FileNotFoundError:
|
|
||||||
maps = None
|
|
||||||
placeholder(axes['B'], 'inputs-maps.72.txt not found')
|
|
||||||
|
|
||||||
# contour levels
|
# contour levels
|
||||||
ψ_max = maps['ψ_n'].max() if maps is not None else 1.2
|
|
||||||
inner_levels = np.linspace(0, 0.99, 8)
|
inner_levels = np.linspace(0, 0.99, 8)
|
||||||
outer_levels = np.linspace(0.9991, ψ_max*0.99, 6)
|
outer_levels = np.linspace(0.9991, maps['ψ_n'].max()*0.99, 6)
|
||||||
all_levels = np.concatenate([inner_levels, outer_levels])
|
all_levels = np.concatenate([inner_levels, outer_levels])
|
||||||
|
|
||||||
# contour style
|
# contour style
|
||||||
norm = TwoSlopeNorm(vmin=0, vcenter=1, vmax=ψ_max)
|
norm = TwoSlopeNorm(vmin=0, vcenter=1, vmax=maps['ψ_n'].max())
|
||||||
cmap = plt.cm.RdYlGn_r
|
cmap = plt.cm.RdYlGn_r
|
||||||
borders = dict(colors='xkcd:grey', linestyles='-', linewidths=0.8)
|
borders = dict(colors='xkcd:grey', linestyles='-', linewidths=0.8)
|
||||||
|
|
||||||
# interpolated equilibrium
|
# interpolated equilibrium
|
||||||
if maps is not None:
|
|
||||||
interp = axes['B']
|
interp = axes['B']
|
||||||
interp.set_title('poloidal flux', loc='right')
|
interp.set_title('poloidal flux', loc='right')
|
||||||
interp.set_xlabel('$R$ / m')
|
interp.set_xlabel('$R$ / m')
|
||||||
@ -428,6 +401,7 @@ def plot_inputs(inputs: Path, outputs: Path, axes: [plt.Axes]):
|
|||||||
interp.plot(np.nan, np.nan, c='xkcd:slate gray', label='plasma boundary')
|
interp.plot(np.nan, np.nan, c='xkcd:slate gray', label='plasma boundary')
|
||||||
|
|
||||||
# add limiter
|
# add limiter
|
||||||
|
conf = gray.read_conf(inputs / 'gray.ini')
|
||||||
limiter = gray.get_limiter(conf, inputs)
|
limiter = gray.get_limiter(conf, inputs)
|
||||||
interp.plot(*limiter, c='xkcd:black', label='limiter')
|
interp.plot(*limiter, c='xkcd:black', label='limiter')
|
||||||
|
|
||||||
@ -444,18 +418,14 @@ def plot_inputs(inputs: Path, outputs: Path, axes: [plt.Axes]):
|
|||||||
orig.plot(*eqdsk.limiter, c='xkcd:black')
|
orig.plot(*eqdsk.limiter, c='xkcd:black')
|
||||||
orig.plot(*eqdsk.boundary, c='xkcd:slate gray')
|
orig.plot(*eqdsk.boundary, c='xkcd:slate gray')
|
||||||
else:
|
else:
|
||||||
placeholder(orig, 'not an EQDSK')
|
orig.axis('off')
|
||||||
|
|
||||||
# colorbar
|
# colorbar
|
||||||
bar = plt.colorbar(plt.cm.ScalarMappable(norm, cmap), cax=axes['C'])
|
bar = plt.colorbar(plt.cm.ScalarMappable(norm, cmap), cax=axes['C'])
|
||||||
bar.set_label(label='normalised poloidal flux', labelpad=10)
|
bar.set_label(label='normalised poloidal flux', labelpad=10)
|
||||||
|
|
||||||
# Plasma radial profiles
|
# Plasma radial profiles
|
||||||
try:
|
|
||||||
profiles = gray.read_table(outputs / 'kinetic-profiles.55.txt')
|
profiles = gray.read_table(outputs / 'kinetic-profiles.55.txt')
|
||||||
except FileNotFoundError:
|
|
||||||
placeholder(axes['D'], 'kinetic-profiles.55.txt not found')
|
|
||||||
return
|
|
||||||
|
|
||||||
axes['D'].set_title('plasma profiles', loc='right')
|
axes['D'].set_title('plasma profiles', loc='right')
|
||||||
add_alt_axis(axes['D'], profiles['ρ_t'], profiles['ψ_n']**0.5,
|
add_alt_axis(axes['D'], profiles['ρ_t'], profiles['ψ_n']**0.5,
|
||||||
|
1694
src/gray_core.f90
1694
src/gray_core.f90
File diff suppressed because it is too large
Load Diff
@ -138,7 +138,7 @@ module gray_params
|
|||||||
real(wp_) :: dst ! Integration step size
|
real(wp_) :: dst ! Integration step size
|
||||||
real(wp_) :: rwmax = 1 ! Normalized maximum radius of beam power
|
real(wp_) :: rwmax = 1 ! Normalized maximum radius of beam power
|
||||||
integer :: nray, nrayr, nrayth ! Total/radial/angular number of rays
|
integer :: nray, nrayr, nrayth ! Total/radial/angular number of rays
|
||||||
integer :: igrad = 0 ! Complex eikonal switch
|
logical :: igrad = .false. ! Complex eikonal switch
|
||||||
integer :: nstep = 12000 ! Max number of integration steps
|
integer :: nstep = 12000 ! Max number of integration steps
|
||||||
integer(kind(step_enum)) :: idst = STEP_TIME ! Choice of the integration variable
|
integer(kind(step_enum)) :: idst = STEP_TIME ! Choice of the integration variable
|
||||||
integer :: ipass = 1 ! Number of plasma passes
|
integer :: ipass = 1 ! Number of plasma passes
|
||||||
@ -341,7 +341,7 @@ contains
|
|||||||
call append(header, line)
|
call append(header, line)
|
||||||
|
|
||||||
! code parameters
|
! code parameters
|
||||||
write(line, '("# COD igrad idst ipass ipol:",3(1x,i4),1x,l4)') &
|
write(line, '("# COD igrad idst ipass ipol:",l4,2(1x,i4),1x,l4)') &
|
||||||
params%raytracing%igrad, params%raytracing%idst, &
|
params%raytracing%igrad, params%raytracing%idst, &
|
||||||
params%raytracing%ipass, params%raytracing%ipol
|
params%raytracing%ipass, params%raytracing%ipol
|
||||||
call append(header, line)
|
call append(header, line)
|
||||||
|
@ -21,7 +21,7 @@ module gray_plasma
|
|||||||
end type
|
end type
|
||||||
|
|
||||||
abstract interface
|
abstract interface
|
||||||
subroutine density_sub(self, psin, dens, ddens)
|
pure subroutine density_sub(self, psin, dens, ddens)
|
||||||
! Computes the density its first derivative as a function of
|
! Computes the density its first derivative as a function of
|
||||||
! normalised poloidal flux.
|
! normalised poloidal flux.
|
||||||
!
|
!
|
||||||
@ -32,7 +32,7 @@ module gray_plasma
|
|||||||
real(wp_), intent(out) :: dens, ddens ! density and first derivative
|
real(wp_), intent(out) :: dens, ddens ! density and first derivative
|
||||||
end subroutine density_sub
|
end subroutine density_sub
|
||||||
|
|
||||||
function temp_fun(self, psin) result(temp)
|
pure function temp_fun(self, psin) result(temp)
|
||||||
! Computes the temperature as a function of the
|
! Computes the temperature as a function of the
|
||||||
! normalised poloidal flux.
|
! normalised poloidal flux.
|
||||||
!
|
!
|
||||||
@ -43,7 +43,7 @@ module gray_plasma
|
|||||||
real(wp_) :: temp
|
real(wp_) :: temp
|
||||||
end function temp_fun
|
end function temp_fun
|
||||||
|
|
||||||
function zeff_fun(self, psin) result(zeff)
|
pure function zeff_fun(self, psin) result(zeff)
|
||||||
! Computes the effective charge Z_eff as a
|
! Computes the effective charge Z_eff as a
|
||||||
! function of the normalised poloidal flux.
|
! function of the normalised poloidal flux.
|
||||||
import :: abstract_plasma, wp_
|
import :: abstract_plasma, wp_
|
||||||
@ -97,7 +97,7 @@ module gray_plasma
|
|||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
subroutine analytic_density(self, psin, dens, ddens)
|
pure subroutine analytic_density(self, psin, dens, ddens)
|
||||||
! subroutine arguments
|
! subroutine arguments
|
||||||
class(analytic_plasma), intent(in) :: self
|
class(analytic_plasma), intent(in) :: self
|
||||||
real(wp_), intent(in) :: psin ! normalised poloidal flux
|
real(wp_), intent(in) :: psin ! normalised poloidal flux
|
||||||
@ -116,7 +116,7 @@ contains
|
|||||||
end subroutine analytic_density
|
end subroutine analytic_density
|
||||||
|
|
||||||
|
|
||||||
function analytic_temp(self, psin) result(temp)
|
pure function analytic_temp(self, psin) result(temp)
|
||||||
! function arguments
|
! function arguments
|
||||||
class(analytic_plasma), intent(in) :: self
|
class(analytic_plasma), intent(in) :: self
|
||||||
real(wp_), intent(in) :: psin
|
real(wp_), intent(in) :: psin
|
||||||
@ -139,7 +139,7 @@ contains
|
|||||||
end function analytic_temp
|
end function analytic_temp
|
||||||
|
|
||||||
|
|
||||||
function analytic_zeff(self, psin) result(zeff)
|
pure function analytic_zeff(self, psin) result(zeff)
|
||||||
! function arguments
|
! function arguments
|
||||||
class(analytic_plasma), intent(in) :: self
|
class(analytic_plasma), intent(in) :: self
|
||||||
real(wp_), intent(in) :: psin
|
real(wp_), intent(in) :: psin
|
||||||
@ -155,7 +155,7 @@ contains
|
|||||||
end function analytic_zeff
|
end function analytic_zeff
|
||||||
|
|
||||||
|
|
||||||
subroutine numeric_density(self, psin, dens, ddens)
|
pure subroutine numeric_density(self, psin, dens, ddens)
|
||||||
use logger, only : log_error
|
use logger, only : log_error
|
||||||
|
|
||||||
! subroutine arguments
|
! subroutine arguments
|
||||||
@ -221,16 +221,16 @@ contains
|
|||||||
end block
|
end block
|
||||||
end if
|
end if
|
||||||
|
|
||||||
if (dens < 0) then
|
! if (dens < 0) then
|
||||||
write (msg, '("negative density:", 2(x,a,"=",g0.3))') &
|
! write (msg, '("negative density:", 2(x,a,"=",g0.3))') &
|
||||||
'ne', dens, 'ψ', psin
|
! 'ne', dens, 'ψ', psin
|
||||||
call log_error(msg, mod='coreprofiles', proc='density')
|
! call log_error(msg, mod='coreprofiles', proc='density')
|
||||||
end if
|
! end if
|
||||||
|
|
||||||
end subroutine numeric_density
|
end subroutine numeric_density
|
||||||
|
|
||||||
|
|
||||||
function numeric_temp(self, psin) result(temp)
|
pure function numeric_temp(self, psin) result(temp)
|
||||||
! function arguments
|
! function arguments
|
||||||
class(numeric_plasma), intent(in) :: self
|
class(numeric_plasma), intent(in) :: self
|
||||||
real(wp_), intent(in) :: psin
|
real(wp_), intent(in) :: psin
|
||||||
@ -246,7 +246,7 @@ contains
|
|||||||
end function numeric_temp
|
end function numeric_temp
|
||||||
|
|
||||||
|
|
||||||
function numeric_zeff(self, psin) result(zeff)
|
pure function numeric_zeff(self, psin) result(zeff)
|
||||||
! function arguments
|
! function arguments
|
||||||
class(numeric_plasma), intent(in) :: self
|
class(numeric_plasma), intent(in) :: self
|
||||||
real(wp_), intent(in) :: psin
|
real(wp_), intent(in) :: psin
|
||||||
|
@ -121,7 +121,7 @@ contains
|
|||||||
real(wp_) :: rho_t, J_phi, dens, ddens
|
real(wp_) :: rho_t, J_phi, dens, ddens
|
||||||
real(wp_) :: psi_n, rho_p, drho_p
|
real(wp_) :: psi_n, rho_p, drho_p
|
||||||
|
|
||||||
call tbl%init(title='kinetic-profiles', id=55, active=is_active(params, 55), &
|
call tbl%init(title='kinetic-profiles', id=55, active=is_active(params, 25), &
|
||||||
labels=[character(64) :: 'ψ_n', 'ρ_t', 'n_e', 'T_e', 'q', 'J_φ'])
|
labels=[character(64) :: 'ψ_n', 'ρ_t', 'n_e', 'T_e', 'q', 'J_φ'])
|
||||||
|
|
||||||
if (.not. tbl%active) return
|
if (.not. tbl%active) return
|
||||||
|
@ -77,10 +77,10 @@ program main
|
|||||||
|
|
||||||
! Do some checks on the inputs
|
! Do some checks on the inputs
|
||||||
associate (p => params%raytracing)
|
associate (p => params%raytracing)
|
||||||
if (p%igrad == 1 .and. p%nrayr < 5) then
|
if (p%igrad .and. p%nrayr < 5) then
|
||||||
p%igrad = 0
|
p%igrad = .false.
|
||||||
call log_message(level=WARNING, mod='main', &
|
call log_message(level=WARNING, mod='main', &
|
||||||
msg='igrad = 1 but nrayr < 5: disabling beamtracing')
|
msg='igrad = .true. but nrayr < 5: disabling beamtracing')
|
||||||
end if
|
end if
|
||||||
if (p%nrayr == 1) p%nrayth = 1
|
if (p%nrayr == 1) p%nrayth = 1
|
||||||
|
|
||||||
|
@ -156,8 +156,8 @@ contains
|
|||||||
write(u, fmt) "nrayth", params%raytracing%nrayth
|
write(u, fmt) "nrayth", params%raytracing%nrayth
|
||||||
if (params%raytracing%rwmax /= defaults%raytracing%rwmax) &
|
if (params%raytracing%rwmax /= defaults%raytracing%rwmax) &
|
||||||
write(u, fmt) "rwmax", params%raytracing%rwmax
|
write(u, fmt) "rwmax", params%raytracing%rwmax
|
||||||
if (params%raytracing%igrad /= defaults%raytracing%igrad) &
|
if (params%raytracing%igrad .neqv. defaults%raytracing%igrad) &
|
||||||
write(u, fmt) "igrad", params%raytracing%igrad
|
write(u, fmt) "igrad", format_bool(params%raytracing%igrad)
|
||||||
if (params%raytracing%ipass /= defaults%raytracing%ipass) &
|
if (params%raytracing%ipass /= defaults%raytracing%ipass) &
|
||||||
write(u, fmt) "ipass", params%raytracing%ipass
|
write(u, fmt) "ipass", params%raytracing%ipass
|
||||||
if (params%raytracing%ipol .neqv. defaults%raytracing%ipol) &
|
if (params%raytracing%ipol .neqv. defaults%raytracing%ipol) &
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[raytracing]
|
[raytracing]
|
||||||
nrayr = 11
|
nrayr = 11
|
||||||
nrayth = 16
|
nrayth = 16
|
||||||
igrad = 1
|
igrad = true
|
||||||
dst = 0.1
|
dst = 0.1
|
||||||
nstep = 8000
|
nstep = 8000
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user