示例#1
0
def test_abundances_consistency():
    """Test that ``abundances`` and ``log_abundances`` are consistent."""

    inputs = {'H': [1, 0], 'He': [1, 0, 0]}
    abundances = {'H': 1.0, 'He': 0.1}
    elements = abundances.keys()

    log_abundances = {
        element: np.log10(abundances[element])
        for element in elements
    }

    instance_nolog = IonizationStates(inputs, abundances=abundances)
    instance_log = IonizationStates(inputs, log_abundances=log_abundances)

    for element in elements:
        assert np.allclose(
            instance_log.abundances[element],
            instance_nolog.abundances[element],
        ), 'abundances not consistent.'

    for element in elements:
        assert np.allclose(
            instance_log.log_abundances[element],
            instance_nolog.log_abundances[element],
        ), 'log_abundances not consistent.'
示例#2
0
 def test_instantiation(self, test_name):
     try:
         self.instances[test_name] = IonizationStates(**tests[test_name])
     except Exception:
         pytest.fail(
             f"Cannot create IonizationStates instance for test='{test_name}'"
         )
示例#3
0
    def setup_class(cls):

        cls.initial_ionfracs = {
            'H': np.array([0.87, 0.13]),
            'He': np.array([0.24, 0.37, 0.39])
        }
        cls.abundances = {'H': 1.0, 'He': 0.0835}
        cls.n = 10 * u.m**-3

        cls.expected_densities = {
            'H': np.array([8.7, 1.3]) * u.m**-3,
            'He': np.array([0.2004, 0.30895, 0.32565]) * u.m**-3,
        }

        cls.expected_electron_density = 2.26025 * u.m**-3
        cls.states = IonizationStates(cls.initial_ionfracs,
                                      abundances=cls.abundances,
                                      n=cls.n)
示例#4
0
    def setup_class(cls):

        # Create arguments to IonizationStates that are all consistent
        # with each other.

        cls.ionic_fractions = {'H': [0.9, 0.1], 'He': [0.99, 0.01, 0.0]}
        cls.abundances = {'H': 1, 'He': 0.08}
        cls.n = 5.3 * u.m**-3
        cls.number_densities = {
            element:
            cls.ionic_fractions[element] * cls.n * cls.abundances[element]
            for element in cls.ionic_fractions.keys()
        }

        # The keys that begin with 'ndens' have enough information to
        # yield the number_densities attribute, whereas the keys that
        # begin with "no_ndens" do not.

        cls.dict_of_kwargs = {
            'ndens1': {
                'inputs': cls.ionic_fractions,
                'abundances': cls.abundances,
                'n': cls.n
            },
            'ndens2': {
                'inputs': cls.number_densities
            },
            'no_ndens3': {
                'inputs': cls.ionic_fractions
            },
            'no_ndens4': {
                'inputs': cls.ionic_fractions,
                'abundances': cls.abundances
            },
            'no_ndens5': {
                'inputs': cls.ionic_fractions,
                'n': cls.n
            },
        }

        cls.instances = {
            key: IonizationStates(**cls.dict_of_kwargs[key])
            for key in cls.dict_of_kwargs.keys()
        }
示例#5
0
    def _finalize_simulation(self):
        self._results._cleanup()

        final_ionfracs = {
            element: self.results.ionic_fractions[element][-1, :]
            for element in self.elements
        }

        self._final = IonizationStates(
            inputs=final_ionfracs,
            abundances=self.abundances,
            n=np.sum(self.results.number_densities["H"][
                -1, :]),  # modify this later?,
            T_e=self.results.T_e[-1],
            tol=1e-6,
        )

        if not np.isclose(self.time_max / u.s, self.results.time[-1] / u.s):
            warnings.warn(f"The simulation ended at {self.results.time[-1]}, "
                          f"which is prior to time_max = {self.time_max}.")
示例#6
0
 def setup_class(cls):
     cls.elements = ['H', 'He', 'Li', 'Fe']
     cls.instance = IonizationStates(cls.elements)
     cls.new_n = 5.153 * u.cm**-3
示例#7
0
 def setup_class(cls):
     cls.states = IonizationStates({
         'H': [0.9, 0.1],
         'He': [0.5, 0.4999, 1e-4]
     })
示例#8
0
 def test_simple_equality(self, test_name):
     """Test that __eq__ is not extremely broken."""
     a = IonizationStates(**tests[test_name])
     b = IonizationStates(**tests[test_name])
     assert a == a, f"IonizationStates instance does not equal itself."
     assert a == b, f"IonizationStates instance does not equal identical instance."
示例#9
0
def test_number_density_assignment():
    instance = IonizationStates(["H", "He"])
    number_densities = [2, 3, 5] * u.m**-3
    instance["He"] = number_densities
示例#10
0
    def __init__(
        self,
        inputs,
        abundances: Union[Dict, str] = None,
        T_e: Union[Callable, u.Quantity] = None,
        n: Union[Callable, u.Quantity] = None,
        time_input: u.Quantity = None,
        time_start: u.Quantity = None,
        time_max: u.Quantity = None,
        max_steps: Union[int, np.integer] = 10000,
        tol: Union[int, float] = 1e-15,
        dt: u.Quantity = None,
        dt_max: u.Quantity = np.inf * u.s,
        dt_min: u.Quantity = 0 * u.s,
        adapt_dt: bool = None,
        safety_factor: Union[int, float] = 1,
        verbose: bool = False,
    ):

        try:

            self.time_input = time_input
            self.time_start = time_start
            self.time_max = time_max
            self.T_e_input = T_e
            self.n_input = n
            self.max_steps = max_steps
            self.dt_input = dt

            if self.dt_input is None:
                self._dt = self.time_max / max_steps
            else:
                self._dt = self.dt_input

            self.dt_min = dt_min
            self.dt_max = dt_max
            self.adapt_dt = adapt_dt
            self.safety_factor = safety_factor
            self.verbose = verbose

            T_e_init = self.electron_temperature(self.time_start)
            n_init = self.hydrogen_number_density(self.time_start)

            self.initial = IonizationStates(
                inputs=inputs,
                abundances=abundances,
                T_e=T_e_init,
                n=n_init,
                tol=tol,
            )

            self.tol = tol

            # TODO: Update IonizationStates in PlasmaPy to have elements attribute

            self.elements = list(self.initial.ionic_fractions.keys())

            if "H" not in self.elements:
                raise NEIError("Must have H in elements")

            self.abundances = self.initial.abundances

            self._eigen_data_dict = eigen_data_dict

            if self.T_e_input is not None and not isinstance(inputs, dict):
                for element in self.initial.ionic_fractions.keys():
                    self.initial.ionic_fractions[
                        element] = self.eigen_data_dict[
                            element].equilibrium_state(T_e_init.value)

            self._temperature_grid = self._eigen_data_dict[
                self.elements[0]].temperature_grid

            self._get_temperature_index = self._eigen_data_dict[
                self.elements[0]]._get_temperature_index

            self._results = None

        except Exception as e:
            raise NEIError(f"Unable to create NEI object for:\n"
                           f"     inputs = {inputs}\n"
                           f" abundances = {abundances}\n"
                           f"        T_e = {T_e}\n"
                           f"          n = {n}\n"
                           f" time_input = {time_input}\n"
                           f" time_start = {time_start}\n"
                           f"   time_max = {time_max}\n"
                           f"  max_steps = {max_steps}\n") from e