-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Added enrich function to material-db-material_db_tools" #36
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,6 +1,9 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from typing import Dict, Union, Optional | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from pyne import material | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from pyne.material import Material, MultiMaterial | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from pyne.material_library import MaterialLibrary | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from pyne import nucname | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from decimal import Decimal, getcontext | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def make_mat(nucvec, density, citation, molecular_mass = None): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mat = Material(nucvec, density = density, metadata = {'citation' : citation}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -53,3 +56,39 @@ def mix_by_volume(material_library, vol_fracs, citation, density_factor=1): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return mat | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def enrich( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
material_composition: Dict[Union[int, str], float], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
element_to_enrich: Union[int, str], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
isotope_enrichments: Dict[Union[int, str], float], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> Dict[int, float]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Enrich a specific element in a material composition by replacing it with its isotopes. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Args: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
material_composition (Dict[Union[int, str], float]): The original material composition. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Keys can be nuclide IDs (int) or element symbols (str), and values are their fractions (float). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
element_to_enrich (Union[int, str]): The ID or symbol of the element to be enriched. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
isotope_enrichments (Dict[Union[int, str], float]): The isotopic composition for element_to_enrich. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Keys can be isotope IDs (int) or isotope symbols (str), and values are their enrichment fractions (float). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Returns: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Dict[int, float]: The updated material composition with the enriched element. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Keys are nuclide IDs (int) and values are their fractions (float). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Convert all keys to PyNE nuclide IDs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
material_composition = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
nucname.id(k): Decimal(str(v)) for k, v in material_composition.items() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
You also change this back to a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Converting material_composition and isotope_enrichments allows the enrichment function to take either letters or numbers for the isotopes and elements as input. With how Pyne likes to switch between letter and number names for materials, it makes the function a lot more flexible. In regards to returning it as a float, I had left it like that for the pytests. But I'm thinking of rewriting them to all work with decimal and/or using the pytest.approx. That should remove the issues of pytests failing from testing two floats together. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
isotope_enrichments = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
nucname.id(k): Decimal(str(v)) for k, v in isotope_enrichments.items() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+83
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you need this step? It seems that it's just converting the key from potentially being a valid string representation to being a canonical nucname ID. The string representation will work below, won't it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this provides protection for the cases where the isotope_enrichment is provided with letters such as "Li6" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given the way you use this data below, I don't think it matters what form is uses. You don't compare it to anything, but just use it to define a composition. PyNE doesn't care if you mix integers and strings for this. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
element_to_enrich_id = nucname.id(element_to_enrich) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if element_to_enrich_id in material_composition: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since you have to loop through the materials above to convert the keys to the nucname ID, perhaps this whole method could be inside that loop.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fract = material_composition.pop(element_to_enrich_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for nuclide, enrich_frac in isotope_enrichments.items(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
material_composition[nuclide] = enrich_frac * fract | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One of the lingering concerns I have is about assumptions regarding elemental mass fractions when we change enrichment. We should discuss. I think it may depend on how materials are manufactured and/or specified, and may be outside the scope of our work, but we should probably be clear about our assumptions. Here is an example of what I mean: I could imagine a material that is specified as being 10% Li by mass, where that really represents an atom ratio that is determiend by the manufacturing process. If we change the Li enrichment substantially, the molar mass of Li changes, and the mass ratio for a given atom ratio changes. In most cases, this will be a small effect, but we need to be sure we understand exactly what the impact is and how to document it for users. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the example you provided, a user could specify their original material which is 10% Li by mass, then convert the material to atomic fraction. Then if they enriched either material using make_mat_from_atom that would allow them to easily maintain their atomic ratio while enriching the element. I ran a test based on your example using Li2O3Ti with 10% mass lithium and enriching it to 0 and 100%. The elemental mass fraction of lithium stayed at 10%. The atomic mass fraction of lithium changed by 3.5% from the 0% to 100% lithium 6 enrichment case, or roughly +-5% relative to the overall atomic mass. We could tell them that the enrichment function does not currently take into consideration changes in density that result from enrichment and that the density provided will be the final material density. The user-specified fractions for either case are what the material's final composition is. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Convert back to float for consistency with the original function signature | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return {k: float(v) for k, v in material_composition.items()} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+80
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this will do the same thing with less converting things back and forth, fewer loops, and valid with PyNE's interface.
Suggested change
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this method only work for mass fractions? Or maybe it works for both as long as the fraction in
material_composition
are the same basis as the fractions inisotope_enrichments
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right that they both need to be on the same basis for the current version of the enrich function. With the logic currently in the make_mat_from_atom you'd have to make your function that converts the mass fraction to an atomic fraction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to add this to the docstring - that if the material composition is defined as atom fractions, the enrichment must be as well, and vice versa.