Replace all deprecated Python typing imports and syntax with updated forms (#3085)

Co-authored-by: Paul Romano <paul.k.romano@gmail.com>
This commit is contained in:
John Vincent Cauilan 2024-07-18 12:40:42 -05:00 committed by GitHub
parent 32440ad203
commit 4c0e08bae8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 204 additions and 227 deletions

View file

@ -1,5 +1,5 @@
from __future__ import annotations
from typing import Iterable
from collections.abc import Iterable
import numpy as np

View file

@ -1,12 +1,11 @@
import copy
import os
import typing # required to prevent typing.Union namespace overwriting Union
from collections.abc import Iterable
import numpy as np
# Type for arguments that accept file paths
PathLike = typing.Union[str, os.PathLike]
PathLike = str | os.PathLike
def check_type(name, value, expected_type, expected_iter_type=None, *, none_ok=False):

View file

@ -5,7 +5,6 @@ import re
from pathlib import Path
from math import sqrt, log
from warnings import warn
from typing import Dict
# Isotopic abundances from Meija J, Coplen T B, et al, "Isotopic compositions
# of the elements 2013 (IUPAC Technical Report)", Pure. Appl. Chem. 88 (3),
@ -283,13 +282,13 @@ AVOGADRO = 6.02214076e23
NEUTRON_MASS = 1.00866491595
# Used in atomic_mass function as a cache
_ATOMIC_MASS: Dict[str, float] = {}
_ATOMIC_MASS: dict[str, float] = {}
# Regex for GNDS nuclide names (used in zam function)
_GNDS_NAME_RE = re.compile(r'([A-Zn][a-z]*)(\d+)((?:_[em]\d+)?)')
# Used in half_life function as a cache
_HALF_LIFE: Dict[str, float] = {}
_HALF_LIFE: dict[str, float] = {}
_LOG_TWO = log(2.0)
def atomic_mass(isotope):

View file

@ -2,7 +2,6 @@ from collections.abc import Iterable
from io import StringIO
from math import log
import re
from typing import Optional
from warnings import warn
import numpy as np
@ -579,7 +578,7 @@ class Decay(EqualityMixin):
_DECAY_PHOTON_ENERGY = {}
def decay_photon_energy(nuclide: str) -> Optional[Univariate]:
def decay_photon_energy(nuclide: str) -> Univariate | None:
"""Get photon energy distribution resulting from the decay of a nuclide
This function relies on data stored in a depletion chain. Before calling it

View file

@ -10,7 +10,6 @@ filesystem.
import copy
from warnings import warn
from typing import Optional
import numpy as np
from uncertainties import ufloat
@ -34,7 +33,7 @@ from .helpers import (
__all__ = ["CoupledOperator", "Operator", "OperatorResult"]
def _find_cross_sections(model: Optional[str] = None):
def _find_cross_sections(model: str | None = None):
"""Determine cross sections to use for depletion
Parameters

View file

@ -8,7 +8,6 @@ transport solver by using user-provided one-group cross sections.
from __future__ import annotations
from collections.abc import Iterable
import copy
from typing import List, Set
import numpy as np
from uncertainties import ufloat
@ -279,7 +278,7 @@ class IndependentOperator(OpenMCOperator):
new_res = res_obj.distribute(self.local_mats, mat_indexes)
self.prev_res.append(new_res)
def _get_nuclides_with_data(self, cross_sections: List[MicroXS]) -> Set[str]:
def _get_nuclides_with_data(self, cross_sections: list[MicroXS]) -> set[str]:
"""Finds nuclides with cross section data"""
return set(cross_sections[0].nuclides)

View file

@ -5,8 +5,8 @@ IndependentOperator class for depletion.
"""
from __future__ import annotations
from collections.abc import Iterable, Sequence
from tempfile import TemporaryDirectory
from typing import List, Tuple, Iterable, Optional, Union, Sequence
import pandas as pd
import numpy as np
@ -27,7 +27,7 @@ _valid_rxns.append('fission')
_valid_rxns.append('damage-energy')
def _resolve_chain_file_path(chain_file: str):
def _resolve_chain_file_path(chain_file: str | None):
if chain_file is None:
chain_file = openmc.config.get('chain_file')
if 'chain_file' not in openmc.config:
@ -41,12 +41,12 @@ def _resolve_chain_file_path(chain_file: str):
def get_microxs_and_flux(
model: openmc.Model,
domains,
nuclides: Optional[Iterable[str]] = None,
reactions: Optional[Iterable[str]] = None,
energies: Optional[Union[Iterable[float], str]] = None,
chain_file: Optional[PathLike] = None,
nuclides: Iterable[str] | None = None,
reactions: Iterable[str] | None = None,
energies: Iterable[float] | str | None = None,
chain_file: PathLike | None = None,
run_kwargs=None
) -> Tuple[List[np.ndarray], List[MicroXS]]:
) -> tuple[list[np.ndarray], list[MicroXS]]:
"""Generate a microscopic cross sections and flux from a Model
.. versionadded:: 0.14.0
@ -183,7 +183,7 @@ class MicroXS:
:data:`openmc.deplete.chain.REACTIONS`
"""
def __init__(self, data: np.ndarray, nuclides: List[str], reactions: List[str]):
def __init__(self, data: np.ndarray, nuclides: list[str], reactions: list[str]):
# Validate inputs
if data.shape[:2] != (len(nuclides), len(reactions)):
raise ValueError(
@ -205,12 +205,12 @@ class MicroXS:
@classmethod
def from_multigroup_flux(
cls,
energies: Union[Sequence[float], str],
energies: Sequence[float] | str,
multigroup_flux: Sequence[float],
chain_file: Optional[PathLike] = None,
chain_file: PathLike | None = None,
temperature: float = 293.6,
nuclides: Optional[Sequence[str]] = None,
reactions: Optional[Sequence[str]] = None,
nuclides: Sequence[str] | None = None,
reactions: Sequence[str] | None = None,
**init_kwargs: dict,
) -> MicroXS:
"""Generated microscopic cross sections from a known flux.

View file

@ -7,7 +7,6 @@ transport-independent transport operators.
from abc import abstractmethod
from warnings import warn
from typing import List, Tuple, Dict
import numpy as np
@ -185,7 +184,7 @@ class OpenMCOperator(TransportOperator):
"""Assign distribmats for each burnable material"""
pass
def _get_burnable_mats(self) -> Tuple[List[str], Dict[str, float], List[str]]:
def _get_burnable_mats(self) -> tuple[list[str], dict[str, float], list[str]]:
"""Determine depletable materials, volumes, and nuclides
Returns

View file

@ -2,7 +2,6 @@
An ndarray to store reaction rates with string, integer, or slice indexing.
"""
from typing import Dict
import numpy as np
@ -53,9 +52,9 @@ class ReactionRates(np.ndarray):
# the __array_finalize__ method (discussed here:
# https://docs.scipy.org/doc/numpy/user/basics.subclassing.html)
index_mat: Dict[str, int]
index_nuc: Dict[str, int]
index_rx: Dict[str, int]
index_mat: dict[str, int]
index_nuc: dict[str, int]
index_rx: dict[str, int]
def __new__(cls, local_mats, nuclides, reactions, from_results=False):
# Create appropriately-sized zeroed-out ndarray

View file

@ -1,8 +1,7 @@
import numbers
import bisect
import math
import typing # required to prevent typing.Union namespace overwriting Union
from typing import Iterable, Optional, Tuple, List
from collections.abc import Iterable
from warnings import warn
import h5py
@ -97,11 +96,11 @@ class Results(list):
def get_activity(
self,
mat: typing.Union[Material, str],
mat: Material | str,
units: str = "Bq/cm3",
by_nuclide: bool = False,
volume: Optional[float] = None
) -> Tuple[np.ndarray, typing.Union[np.ndarray, List[dict]]]:
volume: float | None = None
) -> tuple[np.ndarray, np.ndarray | list[dict]]:
"""Get activity of material over time.
.. versionadded:: 0.14.0
@ -152,11 +151,11 @@ class Results(list):
def get_atoms(
self,
mat: typing.Union[Material, str],
mat: Material | str,
nuc: str,
nuc_units: str = "atoms",
time_units: str = "s"
) -> Tuple[np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray]:
"""Get number of nuclides over time from a single material
Parameters
@ -215,11 +214,11 @@ class Results(list):
def get_decay_heat(
self,
mat: typing.Union[Material, str],
mat: Material | str,
units: str = "W",
by_nuclide: bool = False,
volume: Optional[float] = None
) -> Tuple[np.ndarray, typing.Union[np.ndarray, List[dict]]]:
volume: float | None = None
) -> tuple[np.ndarray, np.ndarray | list[dict]]:
"""Get decay heat of material over time.
.. versionadded:: 0.14.0
@ -242,7 +241,7 @@ class Results(list):
-------
times : numpy.ndarray
Array of times in [s]
decay_heat : numpy.ndarray or List[dict]
decay_heat : numpy.ndarray or list[dict]
Array of total decay heat values if by_nuclide = False (default)
or list of dictionaries of decay heat values by nuclide if
by_nuclide = True.
@ -270,11 +269,11 @@ class Results(list):
return times, decay_heat
def get_mass(self,
mat: typing.Union[Material, str],
mat: Material | str,
nuc: str,
mass_units: str = "g",
time_units: str = "s"
) -> Tuple[np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray]:
"""Get mass of nuclides over time from a single material
.. versionadded:: 0.14.0
@ -324,10 +323,10 @@ class Results(list):
def get_reaction_rate(
self,
mat: typing.Union[Material, str],
mat: Material | str,
nuc: str,
rx: str
) -> Tuple[np.ndarray, np.ndarray]:
) -> tuple[np.ndarray, np.ndarray]:
"""Get reaction rate in a single material/nuclide over time
Parameters
@ -364,7 +363,7 @@ class Results(list):
return times, rates
def get_keff(self, time_units: str = 's') -> Tuple[np.ndarray, np.ndarray]:
def get_keff(self, time_units: str = 's') -> tuple[np.ndarray, np.ndarray]:
"""Evaluates the eigenvalue from a results list.
.. versionadded:: 0.13.1
@ -400,7 +399,7 @@ class Results(list):
times = _get_time_as(times, time_units)
return times, eigenvalues
def get_eigenvalue(self, time_units: str = 's') -> Tuple[np.ndarray, np.ndarray]:
def get_eigenvalue(self, time_units: str = 's') -> tuple[np.ndarray, np.ndarray]:
warn("The get_eigenvalue(...) function has been renamed get_keff and "
"will be removed in a future version of OpenMC.", FutureWarning)
return self.get_keff(time_units)
@ -526,7 +525,7 @@ class Results(list):
def export_to_materials(
self,
burnup_index: int,
nuc_with_data: Optional[Iterable[str]] = None,
nuc_with_data: Iterable[str] | None = None,
path: PathLike = 'materials.xml'
) -> Materials:
"""Return openmc.Materials object based on results at a given step

View file

@ -1,6 +1,5 @@
from __future__ import annotations
import os
import typing
from collections import defaultdict
from copy import deepcopy
from collections.abc import Iterable
@ -41,7 +40,7 @@ class Geometry:
def __init__(
self,
root: openmc.UniverseBase | typing.Iterable[openmc.Cell] | None = None,
root: openmc.UniverseBase | Iterable[openmc.Cell] | None = None,
merge_surfaces: bool = False,
surface_precision: int = 10
):
@ -267,7 +266,7 @@ class Geometry:
def from_xml(
cls,
path: PathLike = 'geometry.xml',
materials: typing.Optional[typing.Union[PathLike, 'openmc.Materials']] = 'materials.xml'
materials: PathLike | 'openmc.Materials' | None = 'materials.xml'
) -> Geometry:
"""Generate geometry from XML file
@ -316,7 +315,7 @@ class Geometry:
"""
return self.root_universe.find(point)
def get_instances(self, paths) -> typing.Union[int, typing.List[int]]:
def get_instances(self, paths) -> int | list[int]:
"""Return the instance number(s) for a cell/material in a geometry path.
The instance numbers are used as indices into distributed
@ -363,7 +362,7 @@ class Geometry:
return indices if return_list else indices[0]
def get_all_cells(self) -> typing.Dict[int, openmc.Cell]:
def get_all_cells(self) -> dict[int, openmc.Cell]:
"""Return all cells in the geometry.
Returns
@ -377,7 +376,7 @@ class Geometry:
else:
return {}
def get_all_universes(self) -> typing.Dict[int, openmc.Universe]:
def get_all_universes(self) -> dict[int, openmc.Universe]:
"""Return all universes in the geometry.
Returns
@ -392,7 +391,7 @@ class Geometry:
universes.update(self.root_universe.get_all_universes())
return universes
def get_all_nuclides(self) -> typing.List[str]:
def get_all_nuclides(self) -> list[str]:
"""Return all nuclides within the geometry.
Returns
@ -406,7 +405,7 @@ class Geometry:
all_nuclides |= set(material.get_nuclides())
return sorted(all_nuclides)
def get_all_materials(self) -> typing.Dict[int, openmc.Material]:
def get_all_materials(self) -> dict[int, openmc.Material]:
"""Return all materials within the geometry.
Returns
@ -421,7 +420,7 @@ class Geometry:
else:
return {}
def get_all_material_cells(self) -> typing.Dict[int, openmc.Cell]:
def get_all_material_cells(self) -> dict[int, openmc.Cell]:
"""Return all cells filled by a material
Returns
@ -440,7 +439,7 @@ class Geometry:
return material_cells
def get_all_material_universes(self) -> typing.Dict[int, openmc.Universe]:
def get_all_material_universes(self) -> dict[int, openmc.Universe]:
"""Return all universes having at least one material-filled cell.
This method can be used to find universes that have at least one cell
@ -463,7 +462,7 @@ class Geometry:
return material_universes
def get_all_lattices(self) -> typing.Dict[int, openmc.Lattice]:
def get_all_lattices(self) -> dict[int, openmc.Lattice]:
"""Return all lattices defined
Returns
@ -481,7 +480,7 @@ class Geometry:
return lattices
def get_all_surfaces(self) -> typing.Dict[int, openmc.Surface]:
def get_all_surfaces(self) -> dict[int, openmc.Surface]:
"""
Return all surfaces used in the geometry
@ -517,7 +516,7 @@ class Geometry:
def get_materials_by_name(
self, name, case_sensitive=False, matching=False
) -> typing.List[openmc.Material]:
) -> list[openmc.Material]:
"""Return a list of materials with matching names.
Parameters
@ -540,7 +539,7 @@ class Geometry:
def get_cells_by_name(
self, name, case_sensitive=False, matching=False
) -> typing.List[openmc.Cell]:
) -> list[openmc.Cell]:
"""Return a list of cells with matching names.
Parameters
@ -563,7 +562,7 @@ class Geometry:
def get_surfaces_by_name(
self, name, case_sensitive=False, matching=False
) -> typing.List[openmc.Surface]:
) -> list[openmc.Surface]:
"""Return a list of surfaces with matching names.
.. versionadded:: 0.13.3
@ -588,7 +587,7 @@ class Geometry:
def get_cells_by_fill_name(
self, name, case_sensitive=False, matching=False
) -> typing.List[openmc.Cell]:
) -> list[openmc.Cell]:
"""Return a list of cells with fills with matching names.
Parameters
@ -635,7 +634,7 @@ class Geometry:
def get_universes_by_name(
self, name, case_sensitive=False, matching=False
) -> typing.List[openmc.Universe]:
) -> list[openmc.Universe]:
"""Return a list of universes with matching names.
Parameters
@ -658,7 +657,7 @@ class Geometry:
def get_lattices_by_name(
self, name, case_sensitive=False, matching=False
) -> typing.List[openmc.Lattice]:
) -> list[openmc.Lattice]:
"""Return a list of lattices with matching names.
Parameters
@ -679,7 +678,7 @@ class Geometry:
"""
return self._get_domains_by_name(name, case_sensitive, matching, 'lattice')
def remove_redundant_surfaces(self) -> typing.Dict[int, openmc.Surface]:
def remove_redundant_surfaces(self) -> dict[int, openmc.Surface]:
"""Remove and return all of the redundant surfaces.
Uses surface_precision attribute of Geometry instance for rounding and

View file

@ -1,8 +1,7 @@
from collections.abc import Mapping
from collections.abc import Mapping, Sequence
from ctypes import (c_int, c_int32, c_char_p, c_double, POINTER, Structure,
create_string_buffer, c_uint64, c_size_t)
from random import getrandbits
from typing import Optional, List, Tuple, Sequence
from weakref import WeakValueDictionary
import numpy as np
@ -170,8 +169,8 @@ class Mesh(_FortranObjectWithID):
def material_volumes(
self,
n_samples: int = 10_000,
prn_seed: Optional[int] = None
) -> List[List[Tuple[Material, float]]]:
prn_seed: int | None = None
) -> list[list[tuple[Material, float]]]:
"""Determine volume of materials in each mesh element
.. versionadded:: 0.15.0

View file

@ -5,9 +5,7 @@ from copy import deepcopy
from numbers import Real
from pathlib import Path
import re
import typing # imported separately as py3.8 requires typing.Iterable
import warnings
from typing import Optional, List, Union, Dict
import lxml.etree as ET
import numpy as np
@ -161,11 +159,11 @@ class Material(IDManagerMixin):
return string
@property
def name(self) -> Optional[str]:
def name(self) -> str | None:
return self._name
@name.setter
def name(self, name: Optional[str]):
def name(self, name: str | None):
if name is not None:
cv.check_type(f'name for Material ID="{self._id}"',
name, str)
@ -174,17 +172,17 @@ class Material(IDManagerMixin):
self._name = ''
@property
def temperature(self) -> Optional[float]:
def temperature(self) -> float | None:
return self._temperature
@temperature.setter
def temperature(self, temperature: Optional[Real]):
def temperature(self, temperature: Real | None):
cv.check_type(f'Temperature for Material ID="{self._id}"',
temperature, (Real, type(None)))
self._temperature = temperature
@property
def density(self) -> Optional[float]:
def density(self) -> float | None:
return self._density
@property
@ -202,7 +200,7 @@ class Material(IDManagerMixin):
self._depletable = depletable
@property
def paths(self) -> List[str]:
def paths(self) -> list[str]:
if self._paths is None:
raise ValueError('Material instance paths have not been determined. '
'Call the Geometry.determine_paths() method.')
@ -217,15 +215,15 @@ class Material(IDManagerMixin):
return self._num_instances
@property
def nuclides(self) -> List[namedtuple]:
def nuclides(self) -> list[namedtuple]:
return self._nuclides
@property
def isotropic(self) -> List[str]:
def isotropic(self) -> list[str]:
return self._isotropic
@isotropic.setter
def isotropic(self, isotropic: typing.Iterable[str]):
def isotropic(self, isotropic: Iterable[str]):
cv.check_iterable_type('Isotropic scattering nuclides', isotropic,
str)
self._isotropic = list(isotropic)
@ -248,7 +246,7 @@ class Material(IDManagerMixin):
return mass / moles
@property
def volume(self) -> Optional[float]:
def volume(self) -> float | None:
return self._volume
@volume.setter
@ -258,7 +256,7 @@ class Material(IDManagerMixin):
self._volume = volume
@property
def ncrystal_cfg(self) -> Optional[str]:
def ncrystal_cfg(self) -> str | None:
return self._ncrystal_cfg
@property
@ -274,7 +272,7 @@ class Material(IDManagerMixin):
return density*self.volume
@property
def decay_photon_energy(self) -> Optional[Univariate]:
def decay_photon_energy(self) -> Univariate | None:
warnings.warn(
"The 'decay_photon_energy' property has been replaced by the "
"get_decay_photon_energy() method and will be removed in a future "
@ -285,8 +283,8 @@ class Material(IDManagerMixin):
self,
clip_tolerance: float = 1e-6,
units: str = 'Bq',
volume: Optional[float] = None
) -> Optional[Univariate]:
volume: float | None = None
) -> Univariate | None:
r"""Return energy distribution of decay photons from unstable nuclides.
.. versionadded:: 0.14.0
@ -471,7 +469,7 @@ class Material(IDManagerMixin):
else:
raise ValueError(f'No volume information found for material ID={self.id}.')
def set_density(self, units: str, density: Optional[float] = None):
def set_density(self, units: str, density: float | None = None):
"""Set the density of the material
Parameters
@ -685,10 +683,10 @@ class Material(IDManagerMixin):
self._macroscopic = None
def add_element(self, element: str, percent: float, percent_type: str = 'ao',
enrichment: Optional[float] = None,
enrichment_target: Optional[str] = None,
enrichment_type: Optional[str] = None,
cross_sections: Optional[str] = None):
enrichment: float | None = None,
enrichment_target: str | None = None,
enrichment_type: str | None = None,
cross_sections: str | None = None):
"""Add a natural element to the material
Parameters
@ -799,9 +797,9 @@ class Material(IDManagerMixin):
self.add_nuclide(*nuclide)
def add_elements_from_formula(self, formula: str, percent_type: str = 'ao',
enrichment: Optional[float] = None,
enrichment_target: Optional[str] = None,
enrichment_type: Optional[str] = None):
enrichment: float | None = None,
enrichment_target: str | None = None,
enrichment_type: str | None = None):
"""Add a elements from a chemical formula to the material.
.. versionadded:: 0.12
@ -930,7 +928,7 @@ class Material(IDManagerMixin):
def make_isotropic_in_lab(self):
self.isotropic = [x.name for x in self._nuclides]
def get_elements(self) -> List[str]:
def get_elements(self) -> list[str]:
"""Returns all elements in the material
.. versionadded:: 0.12
@ -944,7 +942,7 @@ class Material(IDManagerMixin):
return sorted({re.split(r'(\d+)', i)[0] for i in self.get_nuclides()})
def get_nuclides(self, element: Optional[str] = None) -> List[str]:
def get_nuclides(self, element: str | None = None) -> list[str]:
"""Returns a list of all nuclides in the material, if the element
argument is specified then just nuclides of that element are returned.
@ -974,7 +972,7 @@ class Material(IDManagerMixin):
return matching_nuclides
def get_nuclide_densities(self) -> Dict[str, tuple]:
def get_nuclide_densities(self) -> dict[str, tuple]:
"""Returns all nuclides in the material and their densities
Returns
@ -992,7 +990,7 @@ class Material(IDManagerMixin):
return nuclides
def get_nuclide_atom_densities(self, nuclide: Optional[str] = None) -> Dict[str, float]:
def get_nuclide_atom_densities(self, nuclide: str | None = None) -> dict[str, float]:
"""Returns one or all nuclides in the material and their atomic
densities in units of atom/b-cm
@ -1078,7 +1076,7 @@ class Material(IDManagerMixin):
return nuclides
def get_activity(self, units: str = 'Bq/cm3', by_nuclide: bool = False,
volume: Optional[float] = None) -> Union[Dict[str, float], float]:
volume: float | None = None) -> dict[str, float] | float:
"""Returns the activity of the material or for each nuclide in the
material in units of [Bq], [Bq/g] or [Bq/cm3].
@ -1101,7 +1099,7 @@ class Material(IDManagerMixin):
Returns
-------
typing.Union[dict, float]
Union[dict, float]
If by_nuclide is True then a dictionary whose keys are nuclide
names and values are activity is returned. Otherwise the activity
of the material is returned as a float.
@ -1125,7 +1123,7 @@ class Material(IDManagerMixin):
return activity if by_nuclide else sum(activity.values())
def get_decay_heat(self, units: str = 'W', by_nuclide: bool = False,
volume: Optional[float] = None) -> Union[Dict[str, float], float]:
volume: float | None = None) -> dict[str, float] | float:
"""Returns the decay heat of the material or for each nuclide in the
material in units of [W], [W/g] or [W/cm3].
@ -1173,7 +1171,7 @@ class Material(IDManagerMixin):
return decayheat if by_nuclide else sum(decayheat.values())
def get_nuclide_atoms(self, volume: Optional[float] = None) -> Dict[str, float]:
def get_nuclide_atoms(self, volume: float | None = None) -> dict[str, float]:
"""Return number of atoms of each nuclide in the material
.. versionadded:: 0.13.1
@ -1202,7 +1200,7 @@ class Material(IDManagerMixin):
atoms[nuclide] = 1.0e24 * atom_per_bcm * volume
return atoms
def get_mass_density(self, nuclide: Optional[str] = None) -> float:
def get_mass_density(self, nuclide: str | None = None) -> float:
"""Return mass density of one or all nuclides
Parameters
@ -1224,7 +1222,7 @@ class Material(IDManagerMixin):
mass_density += density_i
return mass_density
def get_mass(self, nuclide: Optional[str] = None, volume: Optional[float] = None) -> float:
def get_mass(self, nuclide: str | None = None, volume: float | None = None) -> float:
"""Return mass of one or all nuclides.
Note that this method requires that the :attr:`Material.volume` has
@ -1254,7 +1252,7 @@ class Material(IDManagerMixin):
raise ValueError("Volume must be set in order to determine mass.")
return volume*self.get_mass_density(nuclide)
def clone(self, memo: Optional[dict] = None) -> Material:
def clone(self, memo: dict | None = None) -> Material:
"""Create a copy of this material with a new unique ID.
Parameters
@ -1311,8 +1309,8 @@ class Material(IDManagerMixin):
return xml_element
def _get_nuclides_xml(
self, nuclides: typing.Iterable[NuclideTuple],
nuclides_to_ignore: Optional[typing.Iterable[str]] = None)-> List[ET.Element]:
self, nuclides: Iterable[NuclideTuple],
nuclides_to_ignore: Iterable[str] | None = None)-> list[ET.Element]:
xml_elements = []
# Remove any nuclides to ignore from the XML export
@ -1324,7 +1322,7 @@ class Material(IDManagerMixin):
return xml_elements
def to_xml_element(
self, nuclides_to_ignore: Optional[typing.Iterable[str]] = None) -> ET.Element:
self, nuclides_to_ignore: Iterable[str] | None = None) -> ET.Element:
"""Return XML representation of the material
Parameters
@ -1398,8 +1396,8 @@ class Material(IDManagerMixin):
return element
@classmethod
def mix_materials(cls, materials, fracs: typing.Iterable[float],
percent_type: str = 'ao', name: Optional[str] = None) -> Material:
def mix_materials(cls, materials, fracs: Iterable[float],
percent_type: str = 'ao', name: str | None = None) -> Material:
"""Mix materials together based on atom, weight, or volume fractions
.. versionadded:: 0.12
@ -1596,7 +1594,7 @@ class Materials(cv.CheckedList):
self += materials
@property
def cross_sections(self) -> Optional[Path]:
def cross_sections(self) -> Path | None:
return self._cross_sections
@cross_sections.setter
@ -1686,7 +1684,7 @@ class Materials(cv.CheckedList):
file.write(indentation)
def export_to_xml(self, path: PathLike = 'materials.xml',
nuclides_to_ignore: Optional[typing.Iterable[str]] = None):
nuclides_to_ignore: Iterable[str] | None = None):
"""Export material collection to an XML file.
Parameters

View file

@ -1,14 +1,12 @@
from __future__ import annotations
import typing
import warnings
from abc import ABC, abstractmethod
from collections.abc import Iterable
from collections.abc import Iterable, Sequence
from functools import wraps
from math import pi, sqrt, atan2
from numbers import Integral, Real
from pathlib import Path
import tempfile
from typing import Optional, Sequence, Tuple, List
import h5py
import lxml.etree as ET
@ -49,7 +47,7 @@ class MeshBase(IDManagerMixin, ABC):
next_id = 1
used_ids = set()
def __init__(self, mesh_id: Optional[int] = None, name: str = ''):
def __init__(self, mesh_id: int | None = None, name: str = ''):
# Initialize Mesh class attributes
self.id = mesh_id
self.name = name
@ -151,10 +149,10 @@ class MeshBase(IDManagerMixin, ABC):
self,
model: openmc.Model,
n_samples: int = 10_000,
prn_seed: Optional[int] = None,
prn_seed: int | None = None,
include_void: bool = True,
**kwargs
) -> List[openmc.Material]:
) -> list[openmc.Material]:
"""Generate homogenized materials over each element in a mesh.
.. versionadded:: 0.15.0
@ -393,7 +391,7 @@ class StructuredMesh(MeshBase):
def write_data_to_vtk(self,
filename: PathLike,
datasets: Optional[dict] = None,
datasets: dict | None = None,
volume_normalization: bool = True,
curvilinear: bool = False):
"""Creates a VTK object of the mesh
@ -642,7 +640,7 @@ class RegularMesh(StructuredMesh):
"""
def __init__(self, mesh_id: Optional[int] = None, name: str = ''):
def __init__(self, mesh_id: int | None = None, name: str = ''):
super().__init__(mesh_id, name)
self._dimension = None
@ -655,7 +653,7 @@ class RegularMesh(StructuredMesh):
return tuple(self._dimension)
@dimension.setter
def dimension(self, dimension: typing.Iterable[int]):
def dimension(self, dimension: Iterable[int]):
cv.check_type('mesh dimension', dimension, Iterable, Integral)
cv.check_length('mesh dimension', dimension, 1, 3)
self._dimension = dimension
@ -672,7 +670,7 @@ class RegularMesh(StructuredMesh):
return self._lower_left
@lower_left.setter
def lower_left(self, lower_left: typing.Iterable[Real]):
def lower_left(self, lower_left: Iterable[Real]):
cv.check_type('mesh lower_left', lower_left, Iterable, Real)
cv.check_length('mesh lower_left', lower_left, 1, 3)
self._lower_left = lower_left
@ -692,7 +690,7 @@ class RegularMesh(StructuredMesh):
return [l + w * d for l, w, d in zip(ls, ws, dims)]
@upper_right.setter
def upper_right(self, upper_right: typing.Iterable[Real]):
def upper_right(self, upper_right: Iterable[Real]):
cv.check_type('mesh upper_right', upper_right, Iterable, Real)
cv.check_length('mesh upper_right', upper_right, 1, 3)
self._upper_right = upper_right
@ -716,7 +714,7 @@ class RegularMesh(StructuredMesh):
return [(u - l) / d for u, l, d in zip(us, ls, dims)]
@width.setter
def width(self, width: typing.Iterable[Real]):
def width(self, width: Iterable[Real]):
cv.check_type('mesh width', width, Iterable, Real)
cv.check_length('mesh width', width, 1, 3)
self._width = width
@ -815,7 +813,7 @@ class RegularMesh(StructuredMesh):
cls,
lattice: 'openmc.RectLattice',
division: int = 1,
mesh_id: Optional[int] = None,
mesh_id: int | None = None,
name: str = ''
):
"""Create mesh from an existing rectangular lattice
@ -853,9 +851,9 @@ class RegularMesh(StructuredMesh):
@classmethod
def from_domain(
cls,
domain: typing.Union['openmc.Cell', 'openmc.Region', 'openmc.Universe', 'openmc.Geometry'],
domain: 'openmc.Cell' | 'openmc.Region' | 'openmc.Universe' | 'openmc.Geometry',
dimension: Sequence[int] = (10, 10, 10),
mesh_id: Optional[int] = None,
mesh_id: int | None = None,
name: str = ''
):
"""Create mesh from an existing openmc cell, region, universe or
@ -962,7 +960,7 @@ class RegularMesh(StructuredMesh):
return mesh
def build_cells(self, bc: Optional[str] = None):
def build_cells(self, bc: str | None = None):
"""Generates a lattice of universes with the same dimensionality
as the mesh object. The individual cells/universes produced
will not have material definitions applied and so downstream code
@ -1363,7 +1361,7 @@ class CylindricalMesh(StructuredMesh):
z_grid: Sequence[float],
phi_grid: Sequence[float] = (0, 2*pi),
origin: Sequence[float] = (0., 0., 0.),
mesh_id: Optional[int] = None,
mesh_id: int | None = None,
name: str = '',
):
super().__init__(mesh_id, name)
@ -1484,7 +1482,7 @@ class CylindricalMesh(StructuredMesh):
def get_indices_at_coords(
self,
coords: Sequence[float]
) -> Tuple[int, int, int]:
) -> tuple[int, int, int]:
"""Finds the index of the mesh voxel at the specified x,y,z coordinates.
.. versionadded:: 0.15.0
@ -1496,7 +1494,7 @@ class CylindricalMesh(StructuredMesh):
Returns
-------
Tuple[int, int, int]
tuple[int, int, int]
The r, phi, z indices
"""
@ -1562,9 +1560,9 @@ class CylindricalMesh(StructuredMesh):
@classmethod
def from_domain(
cls,
domain: typing.Union['openmc.Cell', 'openmc.Region', 'openmc.Universe', 'openmc.Geometry'],
domain: 'openmc.Cell' | 'openmc.Region' | 'openmc.Universe' | 'openmc.Geometry',
dimension: Sequence[int] = (10, 10, 10),
mesh_id: Optional[int] = None,
mesh_id: int | None = None,
phi_grid_bounds: Sequence[float] = (0.0, 2*pi),
name: str = ''
):
@ -1813,7 +1811,7 @@ class SphericalMesh(StructuredMesh):
phi_grid: Sequence[float] = (0, 2*pi),
theta_grid: Sequence[float] = (0, pi),
origin: Sequence[float] = (0., 0., 0.),
mesh_id: Optional[int] = None,
mesh_id: int | None = None,
name: str = '',
):
super().__init__(mesh_id, name)
@ -2139,9 +2137,9 @@ class UnstructuredMesh(MeshBase):
_LINEAR_TET = 0
_LINEAR_HEX = 1
def __init__(self, filename: PathLike, library: str, mesh_id: Optional[int] = None,
def __init__(self, filename: PathLike, library: str, mesh_id: int | None = None,
name: str = '', length_multiplier: float = 1.0,
options: Optional[str] = None):
options: str | None = None):
super().__init__(mesh_id, name)
self.filename = filename
self._volumes = None
@ -2173,11 +2171,11 @@ class UnstructuredMesh(MeshBase):
self._library = lib
@property
def options(self) -> Optional[str]:
def options(self) -> str | None:
return self._options
@options.setter
def options(self, options: Optional[str]):
def options(self, options: str | None):
cv.check_type('options', options, (str, type(None)))
self._options = options
@ -2215,7 +2213,7 @@ class UnstructuredMesh(MeshBase):
return self._volumes
@volumes.setter
def volumes(self, volumes: typing.Iterable[Real]):
def volumes(self, volumes: Iterable[Real]):
cv.check_type("Unstructured mesh volumes", volumes, Iterable, Real)
self._volumes = volumes
@ -2353,8 +2351,8 @@ class UnstructuredMesh(MeshBase):
def write_data_to_vtk(
self,
filename: Optional[PathLike] = None,
datasets: Optional[dict] = None,
filename: PathLike | None = None,
datasets: dict | None = None,
volume_normalization: bool = True
):
"""Map data to unstructured VTK mesh elements.

View file

@ -6,7 +6,6 @@ from pathlib import Path
from numbers import Integral
from tempfile import NamedTemporaryFile
import warnings
from typing import Optional, Dict
import h5py
import lxml.etree as ET
@ -83,7 +82,7 @@ class Model:
self.plots = plots
@property
def geometry(self) -> Optional[openmc.Geometry]:
def geometry(self) -> openmc.Geometry | None:
return self._geometry
@geometry.setter
@ -92,7 +91,7 @@ class Model:
self._geometry = geometry
@property
def materials(self) -> Optional[openmc.Materials]:
def materials(self) -> openmc.Materials | None:
return self._materials
@materials.setter
@ -106,7 +105,7 @@ class Model:
self._materials.append(mat)
@property
def settings(self) -> Optional[openmc.Settings]:
def settings(self) -> openmc.Settings | None:
return self._settings
@settings.setter
@ -115,7 +114,7 @@ class Model:
self._settings = settings
@property
def tallies(self) -> Optional[openmc.Tallies]:
def tallies(self) -> openmc.Tallies | None:
return self._tallies
@tallies.setter
@ -129,7 +128,7 @@ class Model:
self._tallies.append(tally)
@property
def plots(self) -> Optional[openmc.Plots]:
def plots(self) -> openmc.Plots | None:
return self._plots
@plots.setter
@ -169,7 +168,7 @@ class Model:
@property
@lru_cache(maxsize=None)
def _cells_by_name(self) -> Dict[int, openmc.Cell]:
def _cells_by_name(self) -> dict[int, openmc.Cell]:
# Get the names maps, but since names are not unique, store a set for
# each name key. In this way when the user requests a change by a name,
# the change will be applied to all of the same name.
@ -182,7 +181,7 @@ class Model:
@property
@lru_cache(maxsize=None)
def _materials_by_name(self) -> Dict[int, openmc.Material]:
def _materials_by_name(self) -> dict[int, openmc.Material]:
if self.materials is None:
mats = self.geometry.get_all_materials().values()
else:

View file

@ -1,12 +1,11 @@
from abc import ABC, abstractmethod
from collections.abc import Iterable
from collections.abc import Iterable, Sequence
from copy import copy
from functools import partial
from math import sqrt, pi, sin, cos, isclose
from numbers import Real
import warnings
import operator
from typing import Sequence
import numpy as np
from scipy.spatial import ConvexHull, Delaunay

View file

@ -1,7 +1,6 @@
from collections.abc import Iterable, Mapping
from numbers import Integral, Real
from pathlib import Path
from typing import Optional
import h5py
import lxml.etree as ET
@ -942,7 +941,7 @@ class Plot(PlotBase):
# Return produced image
return _get_plot_image(self, cwd)
def to_vtk(self, output: Optional[PathLike] = None,
def to_vtk(self, output: PathLike | None = None,
openmc_exec: str = 'openmc', cwd: str = '.'):
"""Render plot as an voxel image

View file

@ -4,8 +4,6 @@ import itertools
from math import ceil
from numbers import Integral, Real
from pathlib import Path
import typing # required to prevent typing.Union namespace overwriting Union
from typing import Optional
import lxml.etree as ET
@ -514,7 +512,7 @@ class Settings:
return self._max_order
@max_order.setter
def max_order(self, max_order: Optional[int]):
def max_order(self, max_order: int | None):
if max_order is not None:
cv.check_type('maximum scattering order', max_order, Integral)
cv.check_greater_than('maximum scattering order', max_order, 0,
@ -522,11 +520,11 @@ class Settings:
self._max_order = max_order
@property
def source(self) -> typing.List[SourceBase]:
def source(self) -> list[SourceBase]:
return self._source
@source.setter
def source(self, source: typing.Union[SourceBase, typing.Iterable[SourceBase]]):
def source(self, source: SourceBase | Iterable[SourceBase]):
if not isinstance(source, MutableSequence):
source = [source]
self._source = cv.CheckedList(SourceBase, 'source distributions', source)
@ -804,7 +802,7 @@ class Settings:
self._temperature = temperature
@property
def trace(self) -> typing.Iterable:
def trace(self) -> Iterable:
return self._trace
@trace.setter
@ -817,11 +815,11 @@ class Settings:
self._trace = trace
@property
def track(self) -> typing.Iterable[typing.Iterable[int]]:
def track(self) -> Iterable[Iterable[int]]:
return self._track
@track.setter
def track(self, track: typing.Iterable[typing.Iterable[int]]):
def track(self, track: Iterable[Iterable[int]]):
cv.check_type('track', track, Sequence)
for t in track:
if len(t) != 3:
@ -904,12 +902,12 @@ class Settings:
self._resonance_scattering = res
@property
def volume_calculations(self) -> typing.List[VolumeCalculation]:
def volume_calculations(self) -> list[VolumeCalculation]:
return self._volume_calculations
@volume_calculations.setter
def volume_calculations(
self, vol_calcs: typing.Union[VolumeCalculation, typing.Iterable[VolumeCalculation]]
self, vol_calcs: VolumeCalculation | Iterable[VolumeCalculation]
):
if not isinstance(vol_calcs, MutableSequence):
vol_calcs = [vol_calcs]
@ -1003,11 +1001,11 @@ class Settings:
self._write_initial_source = value
@property
def weight_windows(self) -> typing.List[WeightWindows]:
def weight_windows(self) -> list[WeightWindows]:
return self._weight_windows
@weight_windows.setter
def weight_windows(self, value: typing.Union[WeightWindows, typing.Iterable[WeightWindows]]):
def weight_windows(self, value: WeightWindows | Iterable[WeightWindows]):
if not isinstance(value, MutableSequence):
value = [value]
self._weight_windows = cv.CheckedList(WeightWindows, 'weight windows', value)
@ -1056,7 +1054,7 @@ class Settings:
self._max_tracks = value
@property
def weight_windows_file(self) -> Optional[PathLike]:
def weight_windows_file(self) -> PathLike | None:
return self._weight_windows_file
@weight_windows_file.setter
@ -1065,7 +1063,7 @@ class Settings:
self._weight_windows_file = value
@property
def weight_window_generators(self) -> typing.List[WeightWindowGenerator]:
def weight_window_generators(self) -> list[WeightWindowGenerator]:
return self._weight_window_generators
@weight_window_generators.setter

View file

@ -1,12 +1,10 @@
from __future__ import annotations
from abc import ABC, abstractmethod
from collections.abc import Iterable
from collections.abc import Iterable, Sequence
from enum import IntEnum
from numbers import Real
import warnings
import typing # imported separately as py3.8 requires typing.Iterable
# also required to prevent typing.Union namespace overwriting Union
from typing import Optional, Sequence, Dict, Any
from typing import Any
import lxml.etree as ET
import numpy as np
@ -57,8 +55,8 @@ class SourceBase(ABC):
def __init__(
self,
strength: Optional[float] = 1.0,
constraints: Optional[Dict[str, Any]] = None
strength: float | None = 1.0,
constraints: dict[str, Any] | None = None
):
self.strength = strength
self.constraints = constraints
@ -75,11 +73,11 @@ class SourceBase(ABC):
self._strength = strength
@property
def constraints(self) -> Dict[str, Any]:
def constraints(self) -> dict[str, Any]:
return self._constraints
@constraints.setter
def constraints(self, constraints: Optional[Dict[str, Any]]):
def constraints(self, constraints: dict[str, Any] | None):
self._constraints = {}
if constraints is None:
return
@ -200,7 +198,7 @@ class SourceBase(ABC):
raise ValueError(f'Source type {source_type} is not recognized')
@staticmethod
def _get_constraints(elem: ET.Element) -> Dict[str, Any]:
def _get_constraints(elem: ET.Element) -> dict[str, Any]:
# Find element containing constraints
constraints_elem = elem.find("constraints")
elem = constraints_elem if constraints_elem is not None else elem
@ -308,14 +306,14 @@ class IndependentSource(SourceBase):
def __init__(
self,
space: Optional[openmc.stats.Spatial] = None,
angle: Optional[openmc.stats.UnitSphere] = None,
energy: Optional[openmc.stats.Univariate] = None,
time: Optional[openmc.stats.Univariate] = None,
space: openmc.stats.Spatial | None = None,
angle: openmc.stats.UnitSphere | None = None,
energy: openmc.stats.Univariate | None = None,
time: openmc.stats.Univariate | None = None,
strength: float = 1.0,
particle: str = 'neutron',
domains: Optional[Sequence[typing.Union[openmc.Cell, openmc.Material, openmc.Universe]]] = None,
constraints: Optional[Dict[str, Any]] = None
domains: Sequence[openmc.Cell | openmc.Material | openmc.Universe] | None = None,
constraints: dict[str, Any] | None = None
):
if domains is not None:
warnings.warn("The 'domains' arguments has been replaced by the "
@ -528,7 +526,7 @@ class MeshSource(SourceBase):
self,
mesh: MeshBase,
sources: Sequence[SourceBase],
constraints: Optional[Dict[str, Any]] = None,
constraints: dict[str, Any] | None = None,
):
super().__init__(strength=None, constraints=constraints)
self.mesh = mesh
@ -702,10 +700,10 @@ class CompiledSource(SourceBase):
"""
def __init__(
self,
library: Optional[str] = None,
parameters: Optional[str] = None,
library: str | None = None,
parameters: str | None = None,
strength: float = 1.0,
constraints: Optional[Dict[str, Any]] = None
constraints: dict[str, Any] | None = None
) -> None:
super().__init__(strength=strength, constraints=constraints)
@ -829,9 +827,9 @@ class FileSource(SourceBase):
def __init__(
self,
path: Optional[PathLike] = None,
path: PathLike | None = None,
strength: float = 1.0,
constraints: Optional[Dict[str, Any]] = None
constraints: dict[str, Any] | None = None
):
super().__init__(strength=strength, constraints=constraints)
self._path = None
@ -966,8 +964,8 @@ class SourceParticle:
"""
def __init__(
self,
r: typing.Iterable[float] = (0., 0., 0.),
u: typing.Iterable[float] = (0., 0., 1.),
r: Iterable[float] = (0., 0., 0.),
u: Iterable[float] = (0., 0., 1.),
E: float = 1.0e6,
time: float = 0.0,
wgt: float = 1.0,
@ -1003,7 +1001,7 @@ class SourceParticle:
def write_source_file(
source_particles: typing.Iterable[SourceParticle],
source_particles: Iterable[SourceParticle],
filename: PathLike, **kwargs
):
"""Write a source file using a collection of source particles
@ -1046,7 +1044,7 @@ def write_source_file(
fh.create_dataset('source_bank', data=arr, dtype=source_dtype)
def read_source_file(filename: PathLike) -> typing.List[SourceParticle]:
def read_source_file(filename: PathLike) -> list[SourceParticle]:
"""Read a source file and return a list of source particles.
.. versionadded:: 0.15.0

View file

@ -1,7 +1,6 @@
from __future__ import annotations
import typing
from abc import ABC, abstractmethod
from collections.abc import Iterable
from collections.abc import Iterable, Sequence
from math import cos, pi
from numbers import Real
from warnings import warn
@ -9,6 +8,7 @@ from warnings import warn
import lxml.etree as ET
import numpy as np
import openmc
import openmc.checkvalue as cv
from .._xml import get_text
from ..mesh import MeshBase
@ -212,7 +212,7 @@ class Monodirectional(UnitSphere):
"""
def __init__(self, reference_uvw: typing.Sequence[float] = [1., 0., 0.]):
def __init__(self, reference_uvw: Sequence[float] = [1., 0., 0.]):
super().__init__(reference_uvw)
def to_xml_element(self):
@ -789,8 +789,8 @@ class Box(Spatial):
def __init__(
self,
lower_left: typing.Sequence[float],
upper_right: typing.Sequence[float],
lower_left: Sequence[float],
upper_right: Sequence[float],
only_fissionable: bool = False
):
self.lower_left = lower_left
@ -889,7 +889,7 @@ class Point(Spatial):
"""
def __init__(self, xyz: typing.Sequence[float] = (0., 0., 0.)):
def __init__(self, xyz: Sequence[float] = (0., 0., 0.)):
self.xyz = xyz
@property
@ -939,9 +939,9 @@ class Point(Spatial):
def spherical_uniform(
r_outer: float,
r_inner: float = 0.0,
thetas: typing.Sequence[float] = (0., pi),
phis: typing.Sequence[float] = (0., 2*pi),
origin: typing.Sequence[float] = (0., 0., 0.)
thetas: Sequence[float] = (0., pi),
phis: Sequence[float] = (0., 2*pi),
origin: Sequence[float] = (0., 0., 0.)
):
"""Return a uniform spatial distribution over a spherical shell.

View file

@ -1,9 +1,8 @@
from __future__ import annotations
import math
import typing
from abc import ABC, abstractmethod
from collections import defaultdict
from collections.abc import Iterable
from collections.abc import Iterable, Sequence
from copy import deepcopy
from numbers import Real
from warnings import warn
@ -68,7 +67,7 @@ class Univariate(EqualityMixin, ABC):
return Mixture.from_xml_element(elem)
@abstractmethod
def sample(n_samples: int = 1, seed: typing.Optional[int] = None):
def sample(n_samples: int = 1, seed: int | None = None):
"""Sample the univariate distribution
Parameters
@ -210,8 +209,8 @@ class Discrete(Univariate):
@classmethod
def merge(
cls,
dists: typing.Sequence[Discrete],
probs: typing.Sequence[int]
dists: Sequence[Discrete],
probs: Sequence[int]
):
"""Merge multiple discrete distributions into a single distribution
@ -859,8 +858,8 @@ class Tabular(Univariate):
def __init__(
self,
x: typing.Sequence[float],
p: typing.Sequence[float],
x: Sequence[float],
p: Sequence[float],
interpolation: str = 'linear-linear',
ignore_negative: bool = False
):
@ -958,7 +957,7 @@ class Tabular(Univariate):
"""Normalize the probabilities stored on the distribution"""
self._p /= self.cdf().max()
def sample(self, n_samples: int = 1, seed: typing.Optional[int] = None):
def sample(self, n_samples: int = 1, seed: int | None = None):
rng = np.random.RandomState(seed)
xi = rng.random(n_samples)
@ -1100,7 +1099,7 @@ class Legendre(Univariate):
"""
def __init__(self, coefficients: typing.Sequence[float]):
def __init__(self, coefficients: Sequence[float]):
self.coefficients = coefficients
self._legendre_poly = None
@ -1156,8 +1155,8 @@ class Mixture(Univariate):
def __init__(
self,
probability: typing.Sequence[float],
distribution: typing.Sequence[Univariate]
probability: Sequence[float],
distribution: Sequence[Univariate]
):
self.probability = probability
self.distribution = distribution
@ -1319,8 +1318,8 @@ class Mixture(Univariate):
def combine_distributions(
dists: typing.Sequence[Univariate],
probs: typing.Sequence[float]
dists: Sequence[Univariate],
probs: Sequence[float]
):
"""Combine distributions with specified probabilities

View file

@ -2,12 +2,11 @@ from contextlib import contextmanager
import os
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import Optional
from .checkvalue import PathLike
@contextmanager
def change_directory(working_dir: Optional[PathLike] = None, *, tmpdir: bool = False):
def change_directory(working_dir: PathLike | None = None, *, tmpdir: bool = False):
"""Context manager for executing in a provided working directory
Parameters

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from numbers import Real, Integral
from typing import Iterable, List, Optional, Dict, Sequence
from collections.abc import Iterable, Sequence
import warnings
import lxml.etree as ET
@ -110,15 +110,15 @@ class WeightWindows(IDManagerMixin):
self,
mesh: MeshBase,
lower_ww_bounds: Iterable[float],
upper_ww_bounds: Optional[Iterable[float]] = None,
upper_bound_ratio: Optional[float] = None,
energy_bounds: Optional[Iterable[Real]] = None,
upper_ww_bounds: Iterable[float] | None = None,
upper_bound_ratio: float | None = None,
energy_bounds: Iterable[Real] | None = None,
particle_type: str = 'neutron',
survival_ratio: float = 3,
max_lower_bound_ratio: Optional[float] = None,
max_lower_bound_ratio: float | None = None,
max_split: int = 10,
weight_cutoff: float = 1.e-38,
id: Optional[int] = None
id: int | None = None
):
self.mesh = mesh
self.id = id
@ -353,7 +353,7 @@ class WeightWindows(IDManagerMixin):
return element
@classmethod
def from_xml_element(cls, elem: ET.Element, meshes: Dict[int, MeshBase]) -> WeightWindows:
def from_xml_element(cls, elem: ET.Element, meshes: dict[int, MeshBase]) -> WeightWindows:
"""Generate weight window settings from an XML element
Parameters
@ -407,7 +407,7 @@ class WeightWindows(IDManagerMixin):
)
@classmethod
def from_hdf5(cls, group: h5py.Group, meshes: Dict[int, MeshBase]) -> WeightWindows:
def from_hdf5(cls, group: h5py.Group, meshes: dict[int, MeshBase]) -> WeightWindows:
"""Create weight windows from HDF5 group
Parameters
@ -457,7 +457,7 @@ class WeightWindows(IDManagerMixin):
)
def wwinp_to_wws(path: PathLike) -> List[WeightWindows]:
def wwinp_to_wws(path: PathLike) -> list[WeightWindows]:
"""Create WeightWindows instances from a wwinp file
.. versionadded:: 0.13.1
@ -698,7 +698,7 @@ class WeightWindowGenerator:
def __init__(
self,
mesh: openmc.MeshBase,
energy_bounds: Optional[Sequence[float]] = None,
energy_bounds: Sequence[float] | None = None,
particle_type: str = 'neutron',
method: str = 'magic',
max_realizations: int = 1,