From bcc4a52eb9ef7e2634897025ef5531abc244879f Mon Sep 17 00:00:00 2001 From: Mikolaj-A-Kowalski <32641577+Mikolaj-A-Kowalski@users.noreply.github.com> Date: Wed, 4 Mar 2020 11:41:52 +0000 Subject: [PATCH] Apply suggestions from code review Co-Authored-By: Paul Romano --- docs/source/usersguide/materials.rst | 2 +- openmc/element.py | 72 +++++++++++++--------------- openmc/material.py | 4 +- tests/unit_tests/test_element.py | 66 ++++++++++++------------- 4 files changed, 67 insertions(+), 77 deletions(-) diff --git a/docs/source/usersguide/materials.rst b/docs/source/usersguide/materials.rst index 4c6e867596..feebbe5884 100644 --- a/docs/source/usersguide/materials.rst +++ b/docs/source/usersguide/materials.rst @@ -56,7 +56,7 @@ In addition to U235 and U238, concentrations of U234 and U236 will be present and are determined through a correlation based on measured data. It is also possible to perform enrichment of any element that is composed -of two naturally-occurring isotopes (e.g. Li, B) in terms of atomic percent. +of two naturally-occurring isotopes (e.g., Li or B) in terms of atomic percent. To invoke this, provide the additional argument `enrichment_target` to :meth:`Material.add_element`. For example the following would enrich B10 to 30ao%:: diff --git a/openmc/element.py b/openmc/element.py index c882791095..94b6ae8d6d 100644 --- a/openmc/element.py +++ b/openmc/element.py @@ -58,9 +58,8 @@ class Element(str): If enrichment_taget is not supplied then it is enrichment for U235 in weight percent. For example, input 4.95 for 4.95 weight percent enriched U. Default is None (natural composition). - Value must be in <0;100> enrichment_target: str, optional - Single nuclide name to enrich from a natural composition e.g. O16 + Single nuclide name to enrich from a natural composition (e.g., 'O16') enrichment_type: {'ao', 'wo'}, optional 'ao' for enrichment as atom percent and 'wo' for weight percent. Default is 'ao' @@ -79,14 +78,13 @@ class Element(str): ValueError No data is available for any of natural isotopes of the element ValueError - If only some natural isotopes are avaiable in cross-sections data - library and element is not O, W or Ta + If only some natural isotopes are available in the cross-section data + library and the element is not O, W, or Ta ValueError - Enrichment of isotope which is not present in natural composition - of the element is requested + If a non-naturally-occurring isotope is requested ValueError - Enrichment is requested of the element that is not composed of - two isotopes. + If enrichment is requested of an element with more than two + naturally-occurring isotopes. ValueError If enrichment procedure for Uranium is used when element is not Uranium. @@ -102,11 +100,11 @@ class Element(str): respectively, of the U235 weight fraction. The remainder of the isotopic weight is assigned to U238. - When the `enrichment` argument is specified with `enrichment_target` a - general enrichment procedure is used. It will raise exception unless - element is composed of exactly 2 isotopes. `enrichment` is interpreted - as percent. By default it is atomic. Can be controlled by variable - `enrichment_type`. + When the `enrichment` argument is specified with `enrichment_target`, a + general enrichment procedure is used for elements composed of exactly + two naturally-occurring isotopes. `enrichment` is interpreted as atom + percent by default but can be controlled by the `enrichment_type` + argument. """ # Check input @@ -210,14 +208,14 @@ class Element(str): # Check that the element is Uranium if self.name != 'U': - msg = 'Enrichment procedure for Uranium was requested, '\ - 'but the isotope is {0} not U'.format(self) + msg = ('Enrichment procedure for Uranium was requested, ' + 'but the isotope is {} not U'.format(self)) raise ValueError(msg) # Check that enrichment_type is not 'ao' if enrichment_type == 'ao': - msg = 'Enrichment procedure for Uranium requires that '\ - 'enrichment value is provided as wo%.' + msg = ('Enrichment procedure for Uranium requires that ' + 'enrichment value is provided as wo%.') raise ValueError(msg) # Calculate the mass fractions of isotopes @@ -241,49 +239,43 @@ class Element(str): # Provide more informative error message for U235 if enrichment_target == 'U235': - msg = "There is a special procedure for enrichment of U235 "\ - "in U. To invoke it, the arguments 'enrichment_taget'"\ - "and 'enrichment_type' should be omitted. Provide "\ - "only 'enrichment' as 'wo%'. See User Guide for more "\ - "details" + msg = ("There is a special procedure for enrichment of U235 " + "in U. To invoke it, the arguments 'enrichment_target'" + "and 'enrichment_type' should be omitted. Provide " + "a value only for 'enrichment' in weight percent.") raise ValueError(msg) # Check if it is two-isotope mixture if len(abundances) != 2: - msg = 'Element {0} does not consist of 2 naturally-occurring '\ - 'isotopes. Therefore it cannot be enriched with the '\ - 'in-build procedure. Please enter isotopic abundances '\ - 'manually.'.format(self) + msg = ('Element {} does not consist of two naturally-occurring ' + 'isotopes. Please enter isotopic abundances manually.' + .format(self)) raise ValueError(msg) # Check if the target nuclide is present in the mixture - if enrichment_target not in abundances.keys(): - msg = 'Could not find the the target nuclide {0} in natural '\ - 'isotopic composition of element {1}. Following ' \ - 'isotopes are available: {2} '\ - .format(enrichment_target, self, list(abundances.keys())) + if enrichment_target not in abundances: + msg = ('The target nuclide {} is not one of the naturally-occurring ' + 'isotopes ({})'.format(enrichment_target, list(abundances))) raise ValueError(msg) # If weight percent enrichment is requested convert to mass fractions if enrichment_type == 'wo': # Convert the atomic abundances to weight fractions # Compute the element atomic mass - element_am = 0.0 - for nuclide in abundances.keys(): - element_am += atomic_mass(nuclide) * abundances[nuclide] + element_am = sum(atomic_mass(nuc)*abundances[nuc] for nuc in abundances) # Convert Molar Fractions to mass fractions - for nuclide in abundances.keys(): + for nuclide in abundances: abundances[nuclide] *= atomic_mass(nuclide) / element_am - # Normalise to one + # Normalize to one sum_abundances = sum(abundances.values()) - for nuclide in abundances.keys(): + for nuclide in abundances: abundances[nuclide] /= sum_abundances # Enrich the mixture # The procedure is more generic that it needs to be. It allows - # to enrich mixtures of more then 2 isotopes, keeping the rations + # to enrich mixtures of more then 2 isotopes, keeping the ratios # of non-enriched nuclides the same as in natural composition # Get fraction of non-enriched isotopes in nat. composition @@ -300,12 +292,12 @@ class Element(str): # Convert back to atomic fractions if requested if enrichment_type == 'wo': # Convert the mass fractions to mole fractions - for nuclide in abundances.keys(): + for nuclide in abundances: abundances[nuclide] /= atomic_mass(nuclide) # Normalize the mole fractions to one sum_abundances = sum(abundances.values()) - for nuclide in abundances.keys(): + for nuclide in abundances: abundances[nuclide] /= sum_abundances # Compute the ratio of the nuclide atomic masses to the element diff --git a/openmc/material.py b/openmc/material.py index aea6a10376..e9ef21db06 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -518,10 +518,8 @@ class Material(IDManagerMixin): in weight percent. For example, input 4.95 for 4.95 weight percent enriched U. Default is None (natural composition). - Value must be in <0;100> for general nuclide - Value must be in <0;100./1.008) for Uranium enrichment_target: str, optional - Single nuclide name to enrich from a natural composition e.g. O16 + Single nuclide name to enrich from a natural composition (e.g., 'O16') enrichment_type: {'ao', 'wo'}, optional 'ao' for enrichment as atom percent and 'wo' for weight percent. Default is 'ao' diff --git a/tests/unit_tests/test_element.py b/tests/unit_tests/test_element.py index 5a17f1f221..ebbdab24e8 100644 --- a/tests/unit_tests/test_element.py +++ b/tests/unit_tests/test_element.py @@ -1,5 +1,5 @@ -import openmc.element -import pytest as pt +import openmc +from pytest import approx, raises from openmc.data import NATURAL_ABUNDANCE, atomic_mass @@ -9,76 +9,76 @@ TOL = 1e-9 def test_expand_no_enrichment(): """ Expand Li in natural compositions""" - lithium = openmc.element.Element('Li') + lithium = openmc.Element('Li') # Verify the expansion into ATOMIC fraction against natural composition for isotope in lithium.expand(100.0, 'ao'): - assert isotope[1] == pt.approx(NATURAL_ABUNDANCE[isotope[0]] * 100.0, rel=TOL) + assert isotope[1] == approx(NATURAL_ABUNDANCE[isotope[0]] * 100.0, rel=TOL) # Verify the expansion into WEIGHT fraction against natural composition natural = {'Li6': NATURAL_ABUNDANCE['Li6'] * atomic_mass('Li6'), 'Li7': NATURAL_ABUNDANCE['Li7'] * atomic_mass('Li7')} li_am = sum(natural.values()) - for key in natural.keys(): + for key in natural: natural[key] /= li_am for isotope in lithium.expand(100.0, 'wo'): - assert isotope[1] == pt.approx(natural[isotope[0]] * 100.0, rel=TOL) + assert isotope[1] == approx(natural[isotope[0]] * 100.0, rel=TOL) def test_expand_enrichment(): """ Expand and verify enrichment of Li """ - lithium = openmc.element.Element('Li') + lithium = openmc.Element('Li') # Verify the enrichment by atoms ref = {'Li6': 75.0, 'Li7': 25.0} for isotope in lithium.expand(100.0, 'ao', 25.0, 'Li7', 'ao'): - assert isotope[1] == pt.approx(ref[isotope[0]], rel=TOL) + assert isotope[1] == approx(ref[isotope[0]], rel=TOL) # Verify the enrichment by weight for isotope in lithium.expand(100.0, 'wo', 25.0, 'Li7', 'wo'): - assert isotope[1] == pt.approx(ref[isotope[0]], rel=TOL) + assert isotope[1] == approx(ref[isotope[0]], rel=TOL) def test_expand_exceptions(): """ Test that correct exceptions are raised for invalid input """ # 1 Isotope Element - with pt.raises(ValueError): - element = openmc.element.Element('Be') - fail = element.expand(70.0, 'ao', 4.0, 'Be9') + with raises(ValueError): + element = openmc.Element('Be') + element.expand(70.0, 'ao', 4.0, 'Be9') # 3 Isotope Element - with pt.raises(ValueError): - element = openmc.element.Element('Cr') - fail = element.expand(70.0, 'ao', 4.0, 'Cr52') + with raises(ValueError): + element = openmc.Element('Cr') + element.expand(70.0, 'ao', 4.0, 'Cr52') # Non-present Enrichment Target - with pt.raises(ValueError): - element = openmc.element.Element('H') - fail = element.expand(70.0, 'ao', 4.0, 'H4') + with raises(ValueError): + element = openmc.Element('H') + element.expand(70.0, 'ao', 4.0, 'H4') # Enrichment Procedure for Uranium if not Uranium - with pt.raises(ValueError): - element = openmc.element.Element('Li') - fail = element.expand(70.0, 'ao', 4.0) + with raises(ValueError): + element = openmc.Element('Li') + element.expand(70.0, 'ao', 4.0) # Missing Enrichment Target - with pt.raises(ValueError): - element = openmc.element.Element('Li') - fail = element.expand(70.0, 'ao', 4.0, enrichment_type='ao') + with raises(ValueError): + element = openmc.Element('Li') + element.expand(70.0, 'ao', 4.0, enrichment_type='ao') # Invalid Enrichment Type Entry - with pt.raises(ValueError): - element = openmc.element.Element('Li') - fail = element.expand(70.0, 'ao', 4.0, 'Li7', 'Grand Moff Tarkin') + with raises(ValueError): + element = openmc.Element('Li') + element.expand(70.0, 'ao', 4.0, 'Li7', 'Grand Moff Tarkin') # Trying to enrich Uranium - with pt.raises(ValueError): - element = openmc.element.Element('U') - fail = element.expand(70.0, 'ao', 4.0, 'U235', 'wo') + with raises(ValueError): + element = openmc.Element('U') + element.expand(70.0, 'ao', 4.0, 'U235', 'wo') # Trying to enrich Uranium with wrong enrichment_target - with pt.raises(ValueError): - element = openmc.element.Element('U') - fail = element.expand(70.0, 'ao', 4.0, enrichment_type='ao') + with raises(ValueError): + element = openmc.Element('U') + element.expand(70.0, 'ao', 4.0, enrichment_type='ao')