Coverage for python/gsfit/database_readers/freegsnke/setup_tf.py: 100%

14 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-14 15:25 +0000

1import typing 

2from typing import TYPE_CHECKING 

3 

4import numpy as np 

5import numpy.typing as npt 

6from freegsnke.equilibrium_update import Equilibrium as FreeGsnkeEquilibrium 

7from gsfit_rs import Tf 

8from scipy.constants import mu_0 

9 

10if TYPE_CHECKING: 

11 from . import DatabaseReader 

12 

13# There is no toroidal field circuit in the synthetic data, so a constant rod current stands in 

14SYNTHETIC_ROD_CURRENT = 1.0e6 # [ampere] 

15 

16 

17def setup_tf( 

18 self: "DatabaseReader", 

19 pulseNo: int, 

20 settings: dict[str, typing.Any], 

21 time: npt.NDArray[np.float64], 

22 freegsnke_eqs: list[FreeGsnkeEquilibrium], 

23) -> Tf: 

24 """ 

25 This method initialises the Rust `Tf` class, which holds an IMAS `tf` IDS. 

26 

27 :param pulseNo: Pulse number, used to read from the database 

28 :param settings: Dictionary containing the JSON settings read from the `settings` directory 

29 :param time: Times the equilibrium will be solved at [second] 

30 :param freegsnke_eqs: The forward-solved equilibria the synthetic measurements come from 

31 

32 **This method is specific to synthetic data from FreeGSNKE.** 

33 

34 Two nodes are filled: 

35 1. `tf/r0`, the reference major radius the vacuum toroidal field is quoted at 

36 2. `tf/b_field_phi_vacuum_r`, the vacuum field times major radius, on the **experimental** 

37 timebase. `solve_grad_shafranov` interpolates it onto the reconstruction times itself, so 

38 do not interpolate it here. 

39 

40 `b_field_phi_vacuum_r` is signed: positive means counter-clockwise viewed from above. 

41 

42 See `python/gsfit/database_readers/interface.py` for more details on how a new database_reader should be implemented. 

43 """ 

44 

45 # Initialise the Tf Rust class 

46 tf = Tf() 

47 

48 tf.set_r0(settings["GSFIT_code_settings.json"]["vacuum_toroidal_field_reference_radius"]) 

49 

50 # `f_vac = R0 * B_phi0 = mu_0 * i_rod / (2 * pi)`, the poloidal-current function in vacuum 

51 f_vac = mu_0 * SYNTHETIC_ROD_CURRENT / (2.0 * np.pi) 

52 

53 # Constant in time, so two points are enough to interpolate from 

54 tf.set_b_field_phi_vacuum_r( 

55 time=np.array([0.0, 1.0]), 

56 data=np.array([f_vac, f_vac]), 

57 ) 

58 

59 return tf