try:
# framework is running
from .startup_choice import *
except ImportError as _excp:
# class is imported by itself
if (
'attempted relative import with no known parent package' in str(_excp)
or 'No module named \'omfit_classes\'' in str(_excp)
or "No module named '__main__.startup_choice'" in str(_excp)
):
from startup_choice import *
else:
raise
from omfit_classes.omfit_nc import OMFITnc
from omfit_classes.fluxSurface import *
__all__ = ['OMFITgenray']
[docs]class OMFITgenray(OMFITnc):
[docs] def pr(self, inp):
out = inp.T.copy()
# out[np.where(self,['wr']['data'].T==0)]=np.nan
# out[np.where(self,['wr']['data'].T is nan)]=np.nan
return out
[docs] def slow_fast(self):
n_par = self.pr(self['wnpar']['data'])
n_per = self.pr(self['wnper']['data'])
S = self.pr(self['cweps11']['data'])
S = S[:, :, 0] + 1.0j * S[:, :, 1]
D = self.pr(self['cweps12']['data'])
D = (D[:, :, 0] + 1.0j * D[:, :, 1]) / -1.0j
P = self.pr(self['cweps33']['data'])
P = P[:, :, 0] + 1.0j * P[:, :, 1]
R = S + D
L = S - D
A = S
B = R * L + P * S - P * n_par**2 - S * n_par**2
C = P * (R * L - 2 * S * n_par**2 + n_par**4)
n_per2_f = (B - np.sqrt(B**2 - 4 * A * C)) / (2 * A)
n_per2_s = (B + np.sqrt(B**2 - 4 * A * C)) / (2 * A)
tmp = np.zeros((n_per2_s.shape[0], n_per2_s.shape[1], 2))
tmp[:, :, 0] = abs(n_per2_s - n_per**2)
tmp[:, :, 1] = abs(n_per2_f - n_per**2)
slow_fast = np.argmin(tmp, 2) * 1.0
return slow_fast
[docs] def to_omas(self, ods=None, time_index=0, new_sources=True, n_rho=201):
"""
translate GENRAY class to OMAS data structure
:param ods: input ods to which data is added
:param time_index: time index to which data is added
:param new_sources: wipe out existing sources
:return: ODS
"""
from omas import ODS, omas_environment
if ods is None:
ods = ODS()
if new_sources or 'core_sources.source' not in ods:
ods['core_sources']['source'] = ODS()
s = 0
else:
s = len(ods['core_sources']['source'])
freq = self['freqcy']['data'] / 1e9
ergs_to_J = 1e-7
cm_to_m = 1e-2
with omas_environment(ods, cocosio=5):
if self['freqcy']['data'] < 100e6:
ods[f'core_sources.source.{s}.identifier.description'] = f"GENRAY IC heating source at {freq:3.3f} GHz"
ods[f'core_sources.source.{s}.identifier.name'] = 'GENRAY IC'
ods[f'core_sources.source.{s}.identifier.index'] = 5 # IC
elif self['freqcy']['data'] < 1e9:
ods[f'core_sources.source.{s}.identifier.description'] = f"GENRAY Helicon heating source at {freq:3.3f} GHz"
ods[f'core_sources.source.{s}.identifier.name'] = 'GENRAY Helicon'
ods[f'core_sources.source.{s}.identifier.index'] = 5 # Helicon
elif self['freqcy']['data'] < 10e9:
ods[f'core_sources.source.{s}.identifier.description'] = f"GENRAY LH heating source at {freq:3.3f} GHz"
ods[f'core_sources.source.{s}.identifier.name'] = 'GENRAY LH'
ods[f'core_sources.source.{s}.identifier.index'] = 4 # LH
else:
ods[f'core_sources.source.{s}.identifier.description'] = f"GENRAY EC heating source at {freq:3.3f} GHz"
ods[f'core_sources.source.{s}.identifier.name'] = 'GENRAY EC'
ods[f'core_sources.source.{s}.identifier.index'] = 3 # ECH
source = ods[f'core_sources.source.{s}.profiles_1d'][time_index]
source['j_parallel'] = self['s_cur_den_onetwo']['data'] / (cm_to_m**2) # from A/cm^2 to A/m^2
source['electrons']['energy'] = self['powden_e']['data'] * ergs_to_J / (cm_to_m**3) # from erg/cm^3/s to J/m^3/s
source['total_ion_energy'] = self['powden_i']['data'] * ergs_to_J / (cm_to_m**3) # from erg/cm^3/s to J/m^3/s
rho = np.linspace(0, 1, n_rho)
rho_genray = self['rho_bin_center']['data']
source['grid']['rho_tor_norm'] = rho
source['j_parallel'] = interp1e(rho_genray, source['j_parallel'])(rho)
source['electrons']['energy'] = interp1e(rho_genray, source['electrons']['energy'])(rho)
source['total_ion_energy'] = interp1e(rho_genray, source['total_ion_energy'])(rho)
return ods
[docs] def plot(self, gEQDSK=None, showSlowFast=False):
with pyplot.style.context('default'):
fig = pyplot.gcf()
fig.set_size_inches(16, 8)
ax0 = pyplot.subplot(131)
if gEQDSK is None:
gEQDSK = {}
gEQDSK['RHORZ'] = self['eqdsk_psi']['data']
gEQDSK['R'] = self['eqdsk_r']['data']
gEQDSK['Z'] = self['eqdsk_z']['data']
n = 10
flx = fluxSurfaces(
Rin=self['eqdsk_r']['data'],
Zin=self['eqdsk_z']['data'],
PSIin=self['eqdsk_psi']['data'],
Btin=self['eqdsk_psi']['data'] * 0,
levels=n,
quiet=True,
cocosin=1,
)
for k in range(n):
pyplot.plot(flx['flux'][k]['R'], flx['flux'][k]['Z'], 'k', linewidth=0.5)
pyplot.xlabel('R')
pyplot.ylabel('Z')
else:
gEQDSK.plot(only2D=True)
flx = gEQDSK['fluxSurfaces']
pyplot.title('Ray trajectories')
rho = self['rho_bin_center']['data']
powden = self['powden']['data']
powden_e = self['powden_e']['data']
powden_i = self['powden_i']['data']
powtot_e = self['powtot_e']['data']
powtot_i = self['powtot_i']['data']
powtot = self['power_total']['data']
cur_parallel = self['s_cur_den_parallel']['data']
curtotal_parallel = self['parallel_cur_total']['data']
powden = powden / 1e7 # ergs/sec/cm^3 to W/cm^3 = MW/m^3
powden_e = powden_e / 1e7 # ergs/sec/cm^3 to W/cm^3 = MW/m^3
powden_i = powden_i / 1e7 # ergs/sec/cm^3 to W/cm^3 = MW/m^3
powtot_elec = powtot_e / 1e7 / 1e6 # from ergs/sec to W, and to MW
powtot_ions = powtot_i / 1e7 / 1e6
powtot = powtot / 1e7 / 1e6
cur_parallel = cur_parallel / 1e2 # from A/cm^2 to MA/m^2
curtotal_parallel = curtotal_parallel / 1e3 # from A to kA
npar = self['wnpar']['data'].flatten()
wr_vals = self['wr']['data'].flatten()
wz_vals = self['wz']['data'].flatten()
wphi_vals = self['wphi']['data'].flatten()
rho_ray = self['spsi']['data'].flatten()
btot_ray = self['sbtot']['data'].flatten()
dpol = self['ws']['data'].flatten()
dpol = dpol / 1e2 # from cm to m
wr_vals = wr_vals / 1e2 # from cm to m
wz_vals = wz_vals / 1e2 # from cm to m
raypower = self['delpwr']['data'].flatten()
raypower = raypower / 1e7 / 1e6 # from ergs/sec to W, and to MW
deriv_raypower = abs(np.gradient(raypower, dpol)) # in MW/m
deriv_raypower[np.isinf(deriv_raypower)] = 0
dpolmax = max(dpol)
wr_vals[wr_vals == 0] = np.nan
wz_vals[wz_vals == 0] = np.nan
wphi_vals[wphi_vals == 0] = np.nan
dpol[dpol == 0] = np.nan
ray_Te = self['ste']['data'].flatten()
vpar = 3e10 / abs(npar)
vthe = 4.19e7 * np.sqrt(2 * ray_Te * 1e3) # ray_Te was in keV, using sqrt(2Te/m) as thermal velocity
# ax0 = pyplot.subplot(131)
pyplot.scatter(wr_vals, wz_vals, c='k', edgecolor='None', s=deriv_raypower / max(deriv_raypower) * 200, marker=',', alpha=0.1)
myplot = pyplot.scatter(wr_vals, wz_vals, c=(raypower / max(raypower)), cmap='rainbow', edgecolor='None', marker='.')
pyplot.xlabel('R (m)')
pyplot.ylabel('Z (m)')
pyplot.title('Ray trajectory')
pyplot.axis('image')
pyplot.colorbar(myplot, ax=ax0, norm=raypower, label='Power in ray (MW)')
ax0 = pyplot.subplot(232)
angles = np.arange(0, 6.3, 0.05)
pyplot.scatter(
wr_vals * np.cos(wphi_vals),
wr_vals * np.sin(wphi_vals),
c='k',
edgecolor='None',
s=deriv_raypower / max(deriv_raypower) * 200,
marker=',',
alpha=0.1,
)
myplot = pyplot.scatter(
wr_vals * np.cos(wphi_vals),
wr_vals * np.sin(wphi_vals),
c=(raypower / max(raypower)),
cmap='rainbow',
edgecolor='None',
marker='.',
)
Rmax_psin1 = max(flx['geo']['Rmax_centroid'])
R_psin0 = min(flx['geo']['Rmax_centroid'])
Rmin_psin1 = min(flx['geo']['Rmin_centroid'])
pyplot.plot(Rmax_psin1 * np.cos(angles), Rmax_psin1 * np.sin(angles), 'k')
pyplot.plot(R_psin0 * np.cos(angles), R_psin0 * np.sin(angles), 'k', linestyle='dashed')
pyplot.plot(Rmin_psin1 * np.cos(angles), Rmin_psin1 * np.sin(angles), 'k')
pyplot.xlabel('X (m)')
pyplot.ylabel('Y (m)')
pyplot.title('Ray trajectory')
pyplot.axis('image')
pyplot.colorbar(myplot, ax=ax0, norm=raypower, label='Power in ray (MW)')
ax = pyplot.subplot(235)
ax.clear()
pyplot.plot(rho, powden, label='Total {:.2f} MW'.format(powtot), linewidth=1.5)
pyplot.plot(rho, powden_e, label='Electrons {:.2f} MW'.format(powtot_elec), linewidth=1.5)
pyplot.plot(rho, powden_i, label='Ions {:.2f} MW'.format(powtot_ions), linewidth=1.5)
pyplot.legend(fontsize='medium', framealpha=0.2, frameon=0, loc='upper left')
pyplot.xlabel('$\\rho$')
pyplot.ylabel('Power density (MW/m$^3$)')
pyplot.axis('tight')
ax2 = ax.twinx()
pyplot.plot(rho, cur_parallel, color='darkorange', label='$J_\parallel$ {:.1f} kA'.format(curtotal_parallel), linewidth=1.5)
pyplot.ylabel('$J_\parallel$ (MA/m$^2$)')
pyplot.title('$P_{abs}$ & CD')
pyplot.legend(fontsize='medium', framealpha=0.2, frameon=0, loc='upper right')
pyplot.axis('tight')
ax3 = pyplot.subplot(233)
ax3.clear()
pyplot.plot(dpol, npar, c='r', label='Rainbow line: $n_\parallel$', linewidth=0)
pyplot.scatter(dpol, npar, c='k', edgecolor='none', marker='.', s=deriv_raypower / max(deriv_raypower) * 1000, alpha=0.1)
pyplot.scatter(dpol, npar, c=(raypower / max(raypower)), cmap='rainbow', edgecolor='none', marker='.')
pyplot.xlabel('Distance along ray (m)')
pyplot.ylabel('$n_\parallel$')
ax4 = ax3.twinx()
pyplot.plot(dpol, vpar / vthe, c='g', label='Green line: $v_\\parallel/v_{th,e}$', linewidth=0)
pyplot.scatter(dpol, vpar / vthe, c='g', edgecolor='none', marker='.', s=deriv_raypower / max(deriv_raypower) * 1000, alpha=0.1)
pyplot.plot(dpol, vpar / vthe, c='g')
pyplot.ylabel('$v_\\parallel/v_{th,e}$')
pyplot.xlim(0, dpolmax)
pyplot.title('Green line: $v_\\parallel/v_{th,e}$ Rainbow line: $n_\parallel$')
pyplot.axis('tight')
ax5 = pyplot.subplot(236)
pyplot.plot(vpar / vthe, deriv_raypower, c='b')
pyplot.xlabel('$v_\\parallel/v_{th,e}$')
pyplot.ylabel('Ray absorption (MW/m)')
pyplot.xlim(0, 5)
pyplot.subplots_adjust(hspace=0.4, left=0.03, wspace=0.4, right=0.95)