Source code for pyMETHES.gas_mixture

#  Copyright (c) 2020 ETH Zurich

"""
Module for the GasMixture class, which aggregates data of different gases.

The GasMixture uses the cross_section module to read cross section data. It stores
linear interpolations of each cross section, as well as the mass ratio,
energy threshold and type of cross section, which are needed for the simulation.
The proportions of the gas mixture should sum up to 1. A common energy_vector for all
cross sections is calculated, as well as the total_cross_section.
"""

# Import Packages
import numpy as np
from lxcat_data_parser import CrossSectionTypes as CST
import scipy.interpolate

# Import modules
from pyMETHES.cross_section import InterpolatedCrossSectionSet

np.seterr(all='raise')


[docs]class GasMixture: """ Class representing a gas mixture. Attributes: cross_sections (ndarray): array of cross section interpolations (from all gases) types (ndarray): type of each cross section of each species thresholds (ndarray): threshold of each cross section of each species mass_ratios (ndarray): mass ratios (repeated for each cross section) is_attachment (ndarray): boolean mask for ATTACHMENT cross sections is_ionization (ndarray): boolean mask for IONIZATION cross sections energy_vector (ndarray): common energy vector, containing all distinct energies of all cross sections total_cross_section (ndarray): sum of all cross sections of all species, linearly interpolated at energy_vector number_of_cross_sections (int): total number of cross sections (from all gases) """
[docs] def __init__(self, gas_formulas: list, path_to_cross_section_files: list, proportions: list, max_cross_section_energy: float): """ Instantiates a GasMixture. Args: gas_formulas (list): list of the chemical formulas of the species path_to_cross_section_files (list): path to the cross section data of each species proportions (list): proportion of each species in the mixture gases (list): InterpolatedCrossSectionSet of each species max_cross_section_energy (float): maximum cross section energy (eV) number_of_cross_sections (int): total number of cross sections across all species Raises: ValueError: If the proportions do not sum up to 1 """ # check if the sum of proportions is 1 if not np.isclose(sum(proportions), 1): raise ValueError("The sum of the proportions of the gases in the GasMixture" "must be 1, but it is %1.2f" % (sum(proportions))) # Create a list with a Gas Object for each gas of the mixture gases = [InterpolatedCrossSectionSet(max_cross_section_energy, *args) for args in zip(path_to_cross_section_files, gas_formulas)] self.cross_sections = np.array([ scipy.interpolate.interp1d(x.data['energy'].to_numpy(), x.data['cross section'].to_numpy() * p, kind='linear') for p, gas in zip(proportions, gases) for x in gas.cross_sections ]) cross_sections = [x for gas in gases for x in gas.cross_sections] self.thresholds = np.asarray([x.threshold for x in cross_sections]) self.mass_ratios = np.asarray([x.mass_ratio for x in cross_sections]) self.types = [x.type for x in cross_sections] types_array = np.asarray(self.types) self.is_attachment = types_array == CST.ATTACHMENT self.is_ionization = types_array == CST.IONIZATION # combine the energy vectors into a total energy vector all_energies = np.concatenate([x.data['energy'] for x in cross_sections]) self.energy_vector = np.unique(all_energies) # calculate the total cross section self.total_cross_section = \ np.sum([interp(self.energy_vector) for interp in self.cross_sections], axis=0)
@property def number_of_cross_sections(self) -> int: """ Returns: Total number of cross sections, all gases considered. """ return self.cross_sections.size