Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
81 changes: 81 additions & 0 deletions process/current_drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,27 @@ def cudriv(self) -> None:
/ physics_variables.plasma_current
)

# Calculate the dimensionless current drive efficiency for the primary heating method (ζ)
current_drive_variables.eta_cd_dimensionless_hcd_primary = self.calculate_dimensionless_current_drive_efficiency(
nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg,
rmajor=physics_variables.rmajor,
temp_plasma_electron_vol_avg_kev=physics_variables.temp_plasma_electron_vol_avg_kev,
c_hcd_driven=current_drive_variables.c_hcd_primary_driven,
p_hcd_injected=current_drive_variables.p_hcd_primary_injected_mw
* 1.0e6,
)

if current_drive_variables.p_hcd_secondary_injected_mw > 0.0:
# Calculate the dimensionless current drive efficiency for the secondary heating method (ζ)
current_drive_variables.eta_cd_dimensionless_hcd_secondary = self.calculate_dimensionless_current_drive_efficiency(
nd_plasma_electrons_vol_avg=physics_variables.nd_plasma_electrons_vol_avg,
rmajor=physics_variables.rmajor,
temp_plasma_electron_vol_avg_kev=physics_variables.temp_plasma_electron_vol_avg_kev,
c_hcd_driven=current_drive_variables.c_hcd_secondary_driven,
p_hcd_injected=current_drive_variables.p_hcd_secondary_injected_mw
* 1.0e6,
)

# ===========================================================

# Calculate the wall plug power for the secondary heating method
Expand Down Expand Up @@ -1911,6 +1932,52 @@ def cudriv(self) -> None:
)
)

def calculate_dimensionless_current_drive_efficiency(
self,
nd_plasma_electrons_vol_avg: float,
rmajor: float,
temp_plasma_electron_vol_avg_kev: float,
c_hcd_driven: float,
p_hcd_injected: float,
) -> float:
"""
Calculate the dimensionless current drive efficiency, ζ.

This function computes the dimensionless current drive efficiency
based on the average electron density, major radius, and electron temperature.

:param nd_plasma_electrons_vol_avg: Volume averaged electron density in m^-3.
:type nd_plasma_electrons_vol_avg: float
:param rmajor: Major radius of the plasma in meters.
:type rmajor: float
:param temp_plasma_electron_vol_avg_kev: Volume averaged electron temperature in keV.
:type temp_plasma_electron_vol_avg_kev: float
:param c_hcd_driven: Current driven by the heating and current drive system.
:type c_hcd_driven: float
:param p_hcd_injected: Power injected by the heating and current drive system.
:type p_hcd_injected: float
:return: The calculated dimensionless current drive efficiency.
:rtype: float

:references:
- E. Poli et al., “Electron-cyclotron-current-drive efficiency in DEMO plasmas,”
Nuclear Fusion, vol. 53, no. 1, pp. 013011-013011, Dec. 2012,
doi: https://doi.org/10.1088/0029-5515/53/1/013011.
- T. C. Luce et al., “Generation of Localized Noninductive Current by Electron Cyclotron Waves on the DIII-D Tokamak,”
Physical Review Letters, vol. 83, no. 22, pp. 4550-4553, Nov. 1999,
doi: https://doi.org/10.1103/physrevlett.83.4550.
"""

return (
(constants.ELECTRON_CHARGE**3 / constants.EPSILON0**2)
* (
(nd_plasma_electrons_vol_avg * rmajor)
/ (temp_plasma_electron_vol_avg_kev * constants.KILOELECTRON_VOLT)
)
* (c_hcd_driven / p_hcd_injected)
)

def output_current_drive(self):
"""
Output the current drive information to the output file.
Expand Down Expand Up @@ -1990,6 +2057,13 @@ def output_current_drive(self):
current_drive_variables.eta_cd_norm_hcd_primary,
"OP ",
)
po.ovarre(
self.outfile,
"Dimensionless current drive efficiency of primary system, ζ",
"(eta_cd_dimensionless_hcd_primary)",
current_drive_variables.eta_cd_dimensionless_hcd_primary,
"OP ",
)
if current_drive_variables.i_hcd_primary == 10:
po.ovarre(
self.outfile,
Expand Down Expand Up @@ -2211,6 +2285,13 @@ def output_current_drive(self):
current_drive_variables.eta_cd_norm_hcd_secondary,
"OP ",
)
po.ovarre(
self.outfile,
"Dimensionless current drive efficiency of secondary system, ζ",
"(eta_cd_dimensionless_hcd_secondary)",
current_drive_variables.eta_cd_dimensionless_hcd_secondary,
"OP ",
)
if current_drive_variables.i_hcd_secondary == 10:
po.ovarre(
self.outfile,
Expand Down
10 changes: 10 additions & 0 deletions process/data_structure/current_drive_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,16 @@
eta_cd_norm_hcd_primary: float = None
"""Normalised current drive efficiency for primary HCD system [(1.0e20 A)/(W m^2)]"""

eta_cd_dimensionless_hcd_primary: float = None
"""Dimensionless current drive efficiency for primary HCD system (ζ)"""


eta_cd_norm_hcd_secondary: float = None
"""Normalised current drive efficiency for secondary HCD system [(1.0e20 A)/(W m^2)]"""

eta_cd_dimensionless_hcd_secondary: float = None
"""Dimensionless current drive efficiency for secondary HCD system (ζ)"""


eta_cd_norm_ecrh: float = None
"""User input ECRH gamma (1.0e20 A/(W m^2))"""
Expand Down Expand Up @@ -424,7 +430,9 @@ def init_current_drive_variables():
global f_radius_beam_tangency_rmajor
global f_beam_tritium
global eta_cd_norm_hcd_primary
global eta_cd_dimensionless_hcd_primary
global eta_cd_norm_hcd_secondary
global eta_cd_dimensionless_hcd_secondary
global eta_cd_norm_ecrh
global xi_ebw
global i_hcd_primary
Expand Down Expand Up @@ -497,6 +505,7 @@ def init_current_drive_variables():
f_radius_beam_tangency_rmajor = 1.05
f_beam_tritium = 1e-6
eta_cd_norm_hcd_primary = 0.0
eta_cd_dimensionless_hcd_primary = 0.0
eta_cd_norm_ecrh = 0.35
xi_ebw = 0.8
i_hcd_primary = 5
Expand All @@ -521,6 +530,7 @@ def init_current_drive_variables():
n_beam_decay_lengths_core = 0.0
n_beam_decay_lengths_core_required = 3.0
eta_cd_norm_hcd_secondary = 0.0
eta_cd_dimensionless_hcd_secondary = 0.0
eta_cd_hcd_secondary = 0.0
p_ebw_injected_mw = 0.0
p_hcd_ecrh_electric_mw = 0.0
Expand Down
4 changes: 2 additions & 2 deletions process/io/plot_proc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2587,13 +2587,13 @@ def plot_main_plasma_information(
f"$\\mathbf{{Primary \\ system: {primary_heating}}}$ \n"
f"Current driving power {mfile_data.data['p_hcd_primary_injected_mw'].get_scan(scan):.4f} MW\n"
f"Extra heat power: {mfile_data.data['p_hcd_primary_extra_heat_mw'].get_scan(scan):.4f} MW\n"
f"$\\gamma_{{\\text{{CD,prim}}}}$: {mfile_data.data['eta_cd_hcd_primary'].get_scan(scan):.4f} A/W\n"
f"$\\gamma_{{\\text{{CD,prim}}}}$: {mfile_data.data['eta_cd_hcd_primary'].get_scan(scan):.4f} A/W | $\\langle\\zeta_{{\\text{{CD,prim}}}}\\rangle$: {mfile_data.data['eta_cd_dimensionless_hcd_primary'].get_scan(scan):.4f} \n"
f"$\\eta_{{\\text{{CD,prim}}}}$: {mfile_data.data['eta_cd_norm_hcd_primary'].get_scan(scan):.4f} $\\times 10^{{20}} \\mathrm{{A}} / \\mathrm{{Wm}}^2$\n"
f"Current driven by primary: {mfile_data.data['c_hcd_primary_driven'].get_scan(scan) / 1e6:.3f} MA\n\n"
f"$\\mathbf{{Secondary \\ system: {secondary_heating}}}$ \n"
f"Current driving power {mfile_data.data['p_hcd_secondary_injected_mw'].get_scan(scan):.4f} MW\n"
f"Extra heat power: {mfile_data.data['p_hcd_secondary_extra_heat_mw'].get_scan(scan):.4f} MW\n"
f"$\\gamma_{{\\text{{CD,sec}}}}$: {mfile_data.data['eta_cd_hcd_secondary'].get_scan(scan):.4f} A/W\n"
f"$\\gamma_{{\\text{{CD,sec}}}}$: {mfile_data.data['eta_cd_hcd_secondary'].get_scan(scan):.4f} A/W | $\\langle\\zeta_{{\\text{{CD,sec}}}}\\rangle$: {mfile_data.data['eta_cd_dimensionless_hcd_secondary'].get_scan(scan):.4f} \n"
f"$\\eta_{{\\text{{CD,sec}}}}$: {mfile_data.data['eta_cd_norm_hcd_secondary'].get_scan(scan):.4f} $\\times 10^{{20}} \\mathrm{{A}} / \\mathrm{{Wm}}^2$\n"
f"Current driven by secondary: {mfile_data.data['c_hcd_secondary_driven'].get_scan(scan) / 1e6:.3f} MA\n"
)
Expand Down
40 changes: 40 additions & 0 deletions tests/unit/test_current_drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,43 @@ def test_cudriv_primary_electron_bernstein(current_drive):
assert current_drive_variables.p_hcd_injected_total_mw == pytest.approx(
257.72205307406523, rel=1e-6
)


@pytest.mark.parametrize(
"nd_plasma_electrons_vol_avg, rmajor, temp_plasma_electron_vol_avg_kev, c_hcd_driven, p_hcd_injected",
[
(1e20, 1.0, 1.0, 1.0, 1.0),
],
)
def test_calculate_dimensionless_current_drive_efficiency_simple(
nd_plasma_electrons_vol_avg,
rmajor,
temp_plasma_electron_vol_avg_kev,
c_hcd_driven,
p_hcd_injected,
):
plasma_profile = PlasmaProfile()
cd = CurrentDrive(
plasma_profile=plasma_profile,
electron_cyclotron=ElectronCyclotron(plasma_profile),
ion_cyclotron=IonCyclotron(plasma_profile),
lower_hybrid=LowerHybrid(plasma_profile),
neutral_beam=NeutralBeam(plasma_profile),
electron_bernstein=ElectronBernstein(plasma_profile),
)
expected = (
(constants.ELECTRON_CHARGE**3 / constants.EPSILON0**2)
* (
(nd_plasma_electrons_vol_avg * rmajor)
/ (temp_plasma_electron_vol_avg_kev * constants.KILOELECTRON_VOLT)
)
* (c_hcd_driven / p_hcd_injected)
)
result = cd.calculate_dimensionless_current_drive_efficiency(
nd_plasma_electrons_vol_avg,
rmajor,
temp_plasma_electron_vol_avg_kev,
c_hcd_driven,
p_hcd_injected,
)
assert result == pytest.approx(expected, rel=1e-12)
Loading