bluemira.radiation_transport.radiation_tools ============================================ .. py:module:: bluemira.radiation_transport.radiation_tools .. autoapi-nested-parse:: 1-D radiation model inspired by the PROCESS function "plot_radprofile" in plot_proc.py. Classes ------- .. autoapisummary:: bluemira.radiation_transport.radiation_tools.WallDetector bluemira.radiation_transport.radiation_tools.DetectedRadiation bluemira.radiation_transport.radiation_tools.FirstWallRadiationSolver Functions --------- .. autoapisummary:: bluemira.radiation_transport.radiation_tools.upstream_temperature bluemira.radiation_transport.radiation_tools.target_temperature bluemira.radiation_transport.radiation_tools.specific_point_temperature bluemira.radiation_transport.radiation_tools.electron_density_and_temperature_sol_decay bluemira.radiation_transport.radiation_tools.gaussian_decay bluemira.radiation_transport.radiation_tools.exponential_decay bluemira.radiation_transport.radiation_tools.ion_front_distance bluemira.radiation_transport.radiation_tools.calculate_zeff bluemira.radiation_transport.radiation_tools.calculate_total_radiated_power bluemira.radiation_transport.radiation_tools.radiative_loss_function_values bluemira.radiation_transport.radiation_tools.radiative_loss_function_plot bluemira.radiation_transport.radiation_tools.calculate_line_radiation_loss bluemira.radiation_transport.radiation_tools.linear_interpolator bluemira.radiation_transport.radiation_tools.interpolated_field_values bluemira.radiation_transport.radiation_tools.grid_interpolator bluemira.radiation_transport.radiation_tools.pfr_filter bluemira.radiation_transport.radiation_tools.filtering_in_or_out bluemira.radiation_transport.radiation_tools.get_impurity_data bluemira.radiation_transport.radiation_tools.detect_radiation bluemira.radiation_transport.radiation_tools.make_wall_detectors bluemira.radiation_transport.radiation_tools.plot_radiation_loads Module Contents --------------- .. py:class:: WallDetector Dataclass for wall detectors. detector_id: ID number for detector x_width: Detector (rectangular) width in x-direction [m] (N.B this value is in detector local coordinates) y_width: Detector (rectangular) width in y-direction [m] (N.B this value is in detector local coordinates) detector_center: Detector center pont normal_vector: Unit vector normal to the detector surface y_vector: Detector unit y-vector .. py:attribute:: detector_id :type: int .. py:attribute:: x_width :type: float .. py:attribute:: y_width :type: float .. py:attribute:: detector_center :type: raysect.core.Point3D .. py:attribute:: normal_vector :type: raysect.core.Vector3D .. py:attribute:: y_vector :type: raysect.core.Vector3D .. py:function:: upstream_temperature(b_pol: float, b_tot: float, lambda_q_near: float, p_sol: float, eq: bluemira.equilibria.equilibrium.Equilibrium, r_sep_mp: float, z_mp: float, k_0: float, firstwall_geom: bluemira.geometry.coordinates.Coordinates, connection_length: float | None = None) -> float Calculate the upstream temperature. Knowing the power entering the SOL, and assuming large temperature gradient between upstream and target. :param b_pol: Poloidal magnetic field at the midplane [T] :param b_tot: Total magnetic field at the midplane [T] :param lambda_q_near: Power decay length in the near SOL [m] :param p_sol: Total power entering the SOL [W] :param eq: Equilibrium in which to calculate the upstream temperature :param r_sep_mp: Upstream location radial coordinate [m] :param z_mp: Upstream location z coordinate [m] :param k_0: Material's conductivity :param firstwall_geom: First wall geometry :param connection_length: connection length from the midplane to the target :returns: upstream temperature. Unit [keV] :rtype: t_upstream_kev .. rubric:: Notes .. doi:: 10.1088/0741-3335/39/6/001 :title: C S Pitcher and P C Stangeby, 1997 .. py:function:: target_temperature(p_sol: float, t_u: float, n_u: float, gamma: float, eps_cool: float, f_ion_t: float, b_pol_tar: float, b_pol_u: float, alpha_pol_deg: float, r_u: float, r_tar: float, lambda_q_near: float, b_tot_tar: float) -> float Calculate the target as suggested from the 2-point model. It includes hydrogen recycle loss energy. :param p_sol: Total power entering the SOL [W] :param t_u: Upstream temperature. Unit [eV] :param n_u: Electron density at the upstream [1/m^3] :param gamma: Sheath heat transmission coefficient :param eps_cool: Electron energy loss [eV] :param f_ion_t: Hydrogen first ionization [eV] :param b_pol_tar: Poloidal magnetic field at the target [T] :param b_pol_u: Poloidal magnetic field at the midplane [T] :param alpha_pol_deg: Incident angle between separatrix and target plate as poloidal projection [deg] :param r_u: Upstream location radial coordinate [m] :param r_tar: strike point radial coordinate [m] :param lambda_q_near: Power decay length in the near SOL at the midplane [m] :param b_tot_tar: Total magnetic field at the target [T] :returns: target temperature. Unit [eV] :rtype: t_tar .. rubric:: Notes .. doi:: 10.1201/9780367801489 :title: P C Stangeby, 2000 .. py:function:: specific_point_temperature(x_p: float, z_p: float, t_u: float, p_sol: float, lambda_q_near: float, eq: bluemira.equilibria.equilibrium.Equilibrium, r_sep_mp: float, z_mp: float, k_0: float, sep_corrector: float, firstwall_geom: bluemira.geometry.coordinates.Coordinates, connection_length: float | None = None, *, lfs=True) -> float Calculate the temperature at a specific point above the x-point. :param x_p: x coordinate of the point of interest [m] :param z_p: z coordinate of the point of interest [m] :param t_u: upstream temperature [eV] :param p_sol: Total power entering the SOL [W] :param lambda_q_near: Power decay length in the near SOL at the midplane [m] :param eq: Equilibrium in which to calculate the point temperature :param r_sep_mp: radial coordinate (i.e. x coordinate on the xz plane) of the x-point [m] :param z_mp: z coordinate of the x-point [m] :param k_0: Material's conductivity :param firstwall_geom: first wall geometry :param connection_length: connection length from the midplane to the target :param lfs: low (toroidal) field side (outer wall side). Default value True. If False it stands for high field side (hfs). :returns: point temperature. Unit [eV] :rtype: t_p .. py:function:: electron_density_and_temperature_sol_decay(t_sep: float, n_sep: float, lambda_q_near: float, lambda_q_far: float, dx_mp: float, f_exp: float = 1, t_factor_det: float | None = None, n_factor_det: float | None = None) -> tuple[numpy.ndarray, Ellipsis] Generic radial exponential decay to be applied from a generic starting point at the separatrix (not only at the mid-plane). The vertical location is dictated by the choice of the flux expansion f_exp. By default f_exp = 1, meaning mid-plane. From the power decay length it calculates the temperature decay length and the density decay length. :param t_sep: initial temperature value at the separatrix [keV] :param n_sep: initial density value at the separatrix [1/m^3] :param lambda_q_near: Power decay length in the near SOL [m] :param lambda_q_far: Power decay length in the far SOL [m] :param dx_mp: Gaps between flux tubes at the mp [m] :param f_exp: flux expansion. Default value=1 referred to the mid-plane :param t_factor_det: to the power decay length. :type t_factor_det: temperature decay length scaling factor in relation :param n_factor_det: to the temperature decay length. :type n_factor_det: density decay length scaling factor in relation :returns: * *te_sol* -- radial decayed temperatures through the SoL. Unit [eV] * *ne_sol* -- radial decayed densities through the SoL. unit [1/m^3] .. rubric:: Notes Temperature and density radially decay different than power. At the mid-plane, the decay length relationships are usually assumed to be lambda_q = 0.285*lambda_t and lambda_n = 0.333*lambda_t. In more radiative regions, especially in a detached regime, they may change. .. rubric:: References [1] Stangeby, P. C. (2000). The Plasma Boundary of Magnetic Fusion Devices. Institute of Physics Publishing. [2] Loarte, A., et al. (2007). "Chapter 4: Power and particle control." Nuclear Fusion, 47(6), S203. .. py:function:: gaussian_decay(max_value: float, min_value: float, no_points: float, *, decay: bool = True) -> numpy.ndarray Generic gaussian decay to be applied between two extreme values and for a given number of points. :param max_value: maximum value of the parameters :param min_value: minimum value of the parameters :param no_points: number of points through which make the parameter decay :returns: decayed parameter :rtype: dec_param .. py:function:: exponential_decay(max_value: float, min_value: float, no_points: float, *, decay: bool = False) -> numpy.ndarray Generic exponential decay to be applied between two extreme values and for a given number of points. :param max_value: maximum value of the parameters :param min_value: minimum value of the parameters :param no_points: number of points through which make the parameter decay :param decay: to define either a decay or increment :returns: decayed parameter :rtype: dec_param .. py:function:: ion_front_distance(x_strike: float, z_strike: float, eq: bluemira.equilibria.equilibrium.Equilibrium, x_pt_z: float, t_tar: float | None = None, avg_ion_rate: float | None = None, avg_momentum_rate: float | None = None, n_r: float | None = None, rec_ext: float | None = None) -> float Manual definition of ion penetration depth. TODO: Find sv_i and sv_m # 4016 :param x_strike: x coordinate of the strike point [m] :param z_strike: z coordinate of the strike point [m] :param eq: Equilibrium in which to calculate the x-point temperature :param x_pt_z: x-point location z coordinate [m] :param t_tar: target temperature [keV] :param avg_ion_rate: average ionization rate :param avg_momentum_rate: average momentum loss rate :param n_r: density at the recycling region entrance [1/m^3] :param rec_ext: recycling region extension (along the field line) from the target [m] :returns: z coordinate of the ionization front :rtype: z_front .. py:function:: calculate_zeff(impurities_content: numpy.ndarray, imp_data_z_ref: numpy.ndarray, imp_data_t_ref: numpy.ndarray, impurity_symbols: numpy.ndarray, te: numpy.ndarray) Calculate the effective charge (Z_eff) for the plasma core. This function computes Z_eff based on the species information and the temperature profile. :param impurities_content: Content of each impurity species in the plasma. :type impurities_content: np.array :param imp_data_z_ref: Reference effective charge values corresponding to the reference temperatures. :type imp_data_z_ref: np.array :param imp_data_t_ref: Reference temperatures (in keV) for interpolation. :type imp_data_t_ref: np.array :param impurity_symbols: All the impurity species symbols in the plasma. :type impurity_symbols: np.array :param te: Electron temperature profile (in keV) at various positions in the plasma. :type te: np.ndarray :returns: * **zeff** (*np.ndarray*) -- Effective charge profile for each plasma position. * **avg_zeff** (*float*) -- Average Z_eff across the plasma. * **total_fraction** (*float*) -- Total fraction of impurities. * **intermediate_values** (*dict*) -- A dictionary containing species fractions, average charge states, and symbols. .. py:function:: calculate_total_radiated_power(x: numpy.ndarray, z: numpy.ndarray, p_rad: numpy.ndarray) -> float Calculate the total radiated power from the radiation map. :param x: Array of x-coordinates (in meters) of the radiation map. :param z: Array of z-coordinates (in meters) of the radiation map. :param p_rad: Array of radiation power density values (in MW/m³) at the corresponding x and z coordinates. :returns: **P_total** -- Total radiated power in megawatts (MW). :rtype: float .. py:function:: radiative_loss_function_values(te: numpy.ndarray, t_ref: numpy.ndarray, l_ref: numpy.ndarray) -> numpy.ndarray By interpolation, from reference values, it returns the radiative power loss values for a given set of electron temperature. :param te: electron temperature [keV] :param t_ref: temperature reference [eV] :param l_ref: radiative power loss reference [Wm^3] :returns: interpolated local values of the radiative power loss function [W m^3] .. py:function:: radiative_loss_function_plot(t_ref: numpy.ndarray, lz_val: collections.abc.Iterable[numpy.ndarray], species: collections.abc.Iterable[str]) -> matplotlib.pyplot.Axes Radiative loss function plot for a set of given impurities. :param t_ref: temperature reference [keV] :param lz_val: radiative power loss reference [Wm^3] :param species: species names :returns: The axes object on which radiative loss function is plotted. :rtype: ax .. py:function:: calculate_line_radiation_loss(ne: numpy.ndarray, p_loss_f: numpy.ndarray, species_frac: float) -> numpy.ndarray Calculation of Line radiation losses. For a given impurity this is the total power lost, per unit volume, by all line-radiation processes INCLUDING Bremsstrahlung. :param ne: electron density [1/m^3] :param p_loss_f: local values of the radiative power loss function :param species_frac: fraction of relevant impurity :returns: Line radiation losses [MW m^-3] .. py:function:: linear_interpolator(x: numpy.ndarray, z: numpy.ndarray, field: numpy.ndarray) -> collections.abc.Callable[[numpy.ndarray, numpy.ndarray], numpy.ndarray] Interpolating function calculated over 1D coordinate arrays and 1D field value array. :param x: x coordinates of given points [m] :param z: z coordinates of given points [m] :param field: set of punctual field values associated to the given points :returns: LinearNDInterpolator object :rtype: interpolated_function .. py:function:: interpolated_field_values(x: numpy.ndarray, z: numpy.ndarray, linear_interpolator: collections.abc.Callable[[numpy.ndarray, numpy.ndarray], numpy.ndarray]) -> numpy.ndarray Interpolated field values for a given set of points. :param x: x coordinates of point in which interpolate [m] :param z: z coordinates of point in which interpolate [m] :param linear_interpolator: LinearNDInterpolator object :returns: matrix len(x) x len(z), 2D grid of interpolated field values :rtype: field_grid .. py:function:: grid_interpolator(x: numpy.ndarray, z: numpy.ndarray, field_grid: numpy.ndarray) -> collections.abc.Callable[[numpy.ndarray], numpy.ndarray] Interpolated field function obtained for a given grid. Needed: length(xx) = m, length(zz) = n, field_grid.shape = n x m. :param x: x coordinates. length(xx)=m [m] :type x: np.array :param z: z coordinates. length(xx)=n [m] :type z: np.array :param field_grid: matrix n x m corresponding field values arranged according to the grid of given points :returns: interpolated field function, to be used to calculate the field values for a new set of points or to be provided to a tracing code such as CHERAB :rtype: interpolated_function .. py:function:: pfr_filter(separatrix: collections.abc.Iterable[bluemira.geometry.coordinates.Coordinates] | bluemira.geometry.coordinates.Coordinates, x_point_z: float) -> tuple[numpy.ndarray, Ellipsis] To filter out from the radiation interpolation domain the private flux regions :param separatrix: Object containing x and z coordinates of each separatrix half :param x_point_z: z coordinates of the x-point [m] :returns: * *domains_x* -- x coordinates of pfr domain * *domains_z* -- z coordinates of pfr domain .. py:function:: filtering_in_or_out(domain_x: list[float], domain_z: list[float], *, include_points: bool = True) -> collections.abc.Callable[[collections.abc.Iterable[float]], bool] To exclude from the calculation a specific region which is either contained or not contained within a given domain :param domain_x: list of x coordinates defining the domain :param domain_z: list of x coordinates defining the domain :param include_points: whether the points inside or outside the domain must be excluded :returns: method which includes or excludes from the domain a given point :rtype: include .. py:function:: get_impurity_data(impurities_list: collections.abc.Iterable[str] = ('H', 'He'), confinement_time_ms: float = 0.1) -> dict[str, dict[str, tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]]] Function getting the PROCESS impurity data :param impurities_list: List of impurity dictionaries to get the species data for. Dictionary contains the impurity names (which should be found in the :class:`~bluemira.codes.process.api.Impurities` Enum0, and their fraction in the region of interest. :param confinement_time_ms: Confinement timescale in the region of interest. Times available to read the data for are: [0.1, 1.0, 10.0, 100.0, 1000.0, np.inf]. :returns: The dictionary of impurities at the defined time, sorted by species, then sorted by "T_ref" v.s. "L_ref", where "T_ref" = reference ion temperature [eV], "L_ref" = the loss function value $L_z(n_e, T_e)$ [W m^3]. :rtype: impurity_data .. py:class:: DetectedRadiation Detected radiation data power_density: The mean detected power divided by the detector (aka pixel/tile) rectangular area [W/m^2] power_density_stdev: Standard deviation of the power density detected_power: Average power observed by the detector [W] (N.B. Pixel/tile is revolved around the CYLINDRICAL z-axis) detected_power_stdev: Standard deviation of power observed by the detector detector_area: Detector area [m^2] detector_numbers: Number of wall detectors that have been created distance: The running distance from detector centre to detector centre, starting from the first listed detector, moving around the wall in the poloidal direction [m]. total_power: Sum of the power observed by the detectors [W] .. py:attribute:: power_density :type: numpy.typing.NDArray[numpy.float64] .. py:attribute:: power_density_stdev :type: numpy.typing.NDArray[numpy.float64] .. py:attribute:: detected_power :type: numpy.typing.NDArray[numpy.float64] .. py:attribute:: detected_power_stdev :type: numpy.typing.NDArray[numpy.float64] .. py:attribute:: detector_area :type: numpy.typing.NDArray[numpy.float64] .. py:attribute:: detector_numbers :type: numpy.typing.NDArray[numpy.float64] .. py:attribute:: distance :type: numpy.typing.NDArray[numpy.float64] .. py:attribute:: total_power :type: float .. py:function:: detect_radiation(wall_detectors: list[WallDetector], n_samples: int, world: raysect.optical.World, *, verbose: bool = False) -> DetectedRadiation To sample the wall and detect radiation. :param wall_detectors: List of wall detector dataclasses :param n_samples: Number of samples to generate per pixel for a Raysect Pixel observer. A Pixel observer samples rays from a hemisphere and rectangular area. :param world: Raysect class, tracks all primitives (objects making up the Raysect scene) and observers in the 'world'. :returns: DetectedRadiation object describing the radiation data. .. rubric:: Notes Each detector tile is rectangular and located on a cylindrical surface. The detected power is the average radiation power that would be intercepted by revolving the tile around the cylindrical z-axis. i.e. This models a wall detector as representative of a full ring in a cylindrically symmetric system. For more information on observers please see the `Raysect documentation `_ .. py:function:: make_wall_detectors(wall_r, wall_z, max_wall_len, x_width, *, plot=False) -> list[WallDetector] To make the detectors on the wall :returns: list of WallDetectors :rtype: wall_detectors .. py:function:: plot_radiation_loads(radiation_function, wall_detectors, wall_loads, plot_title, fw_shape) To plot the radiation on the wall as [MW/m^2]. :param radiation_function: Cherab AxisymmetricMapper created using a function describing radiation source :param wall_detectors: List of wall detector objects :param wall_loads: DetectedRadiation object for associated wall_detectors :param plot_title: Name of the plot :param fw_shape: First wall coordinates .. py:class:: FirstWallRadiationSolver(source_func: collections.abc.Callable, firstwall_shape: bluemira.geometry.coordinates.Coordinates) Calculate the radiation detected at the first wall. This class make use of Raysect and Cherab libraries. - The resulting data class contains the following information: - The power density for each first wall detector [W/m^2] and its associated standard deviation. - The power observed for each for each first wall detector [W] and its associated standard deviation. - The area of each detector [m^2]. - The running distance from detector centre to detector centre, starting from the first listed detector, moving around the wall in the poloidal direction [m]. - The sum of the power observed by the detectors [W] :param firstwall_shape: Coordinates defining the first wall. :param source_func: Function describing radiation source :returns: DetectedRadiation object for associated wall detectors :rtype: wall_loads .. py:attribute:: rad_source .. py:attribute:: rad_3d .. py:attribute:: fw_shape .. py:attribute:: wall_detectors :value: None .. py:attribute:: wall_loads :value: None .. py:method:: solve(max_wall_len: float = 0.1, x_width: float = 0.01, n_samples: int = 500, ray_stepsize=1.0, *, plot: bool = True, verbose: bool = False) -> DetectedRadiation Solve first wall radiation problem. :param max_wall_len: Maximum wall length :param x_width: Detector (rectangular) width in x-direction (local coords) Note: y_width is calculated. :param n_samples: Number of samples to generate per pixel :param ray_stepsize: cherab radiation function step size :param plot: Whether or not to plot and show the radiation on the wall [MW/m^2]. :param verbose: Whether or not to print and plot additional information, i.e., plot wall detectors and their normal vectors, and print Raysect information (incident power, incident power error, time for render and rays per second). :returns: **wall_loads** -- Detected radiation data. :rtype: DetectedRadiation .. py:method:: plot() Plot the radiation on the wall [MW/m^2].