Skip to content
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

Refactoring Material to not subclass Composite #1062

Merged
merged 43 commits into from
Jan 24, 2023
Merged

Conversation

john-science
Copy link
Member

@john-science john-science commented Jan 4, 2023

Description

This PR refactors the Material class to no longer be a subclass of Composite.

It also removes (most, not all) of the statefulness in ARMI Materials. For instance, I removed all Parameters from Material. Some of those I copied over to a simpler class attribute (mat.p.massFrac became mat.massFrac). And some I was able to delete entirely (like yieldStrength and atomFracDenom).

Also, I should note that three parameters (uFrac, puFrac, and zrFrac) applied only to FUEL materials, but were defined by default for all materials. That was fixed.

Stateful things I haven't removed in this PR (because they are going to be tricky):

  • ARMI supports Custom materials, which are obviously stateful by design.
  • ARMI supports custom isotopics for fuels, which again is a stateful idea.
  • The Material class still has a self.parent, which is necessary for a whole LOAD of logic to do with Material.getNuclides(). (@ntouran Please note this proved to be a big enough change that if we want to remove it, it will be it's own PR.)

@drewj-usnctech @sombrereau In any repo I can see, I am making PRs to match this one. But if you have a private repo I can't see, 99% of the changes are just to switch calls to mat.p.thing to mat.thing. (Once, a material outside ARMI needed an __init__() method, that it didn't have before.)


Checklist

  • This PR has only one purpose or idea.
  • Tests have been added/updated to verify that the new/changed code works.
  • The release notes (location doc/release/0.X.rst) are up-to-date with any bug fixes or new features.
  • The documentation is still up-to-date in the doc folder.
  • The dependencies are still up-to-date in setup.py.

@john-science john-science added architecture Issues related to big picture system architecture feature request Smaller user request labels Jan 4, 2023
@john-science john-science linked an issue Jan 4, 2023 that may be closed by this pull request
@john-science john-science added cleanup Code/comment cleanup: Low Priority and removed feature request Smaller user request labels Jan 4, 2023
@john-science
Copy link
Member Author

@drewj-usnctech Just FYI

@drewj-usnctech
Copy link
Contributor

Thanks @john-science

Quick skim and nothing seems to jump out to me here

armi/materials/material.py Outdated Show resolved Hide resolved
@@ -73,7 +87,8 @@ class Material(composites.Composite):
with information about thermal scattering."""

def __init__(self):
composites.Composite.__init__(self, self.__class__.name)
self.parent = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do materials still have parents? They shouldn't, since they're no longer in the hierarchical tree.

Remove or justify with implementation docs.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears to me that the mass fractions in all ARMI materials are designed to be changed by the user's choice of nuclides. And right now those nuclide choices come from the parent.

Can you enlighten me on this? Because these nuclides are also the reason materials have parameters.

ARMI materials seem to change a LOT based on the nuclides present in ARMI, and those nuclide are not static in ARMI.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Materials used to be the place where composition (defined as number density vectors of elements and nuclides) was stored. We moved that to the Component's numberDensities param long ago.

However, we still initialize this param based on the Materials that users add to their problem via the Material.setDefaultMassFracs method, which sets Material.p.massFrac. This is indeed (and unfortunately) a bit coupled to nuclide choices, since sometimes users want to model Carbon while other times they want to model Carbon-12.

So may be we need an intermediate ticket here, with the goal of: "Decouple composition definitions from neutronics library assumptions".

Material definitions should be static and evergreen, not dependent in any way on user modeling settings. This should include initial material composition, and probably also the process of building Component numberDensities, and potentially even the evolution of composition vs. time from transmutation and decay and reprocessing and everything else. The user modeling settings that map compositions to specific subsets of nuclides based on neutronics library needs should be isolated to the neutronics physics modules. For example, if a neutronics input is being built for a code that only has C-12 but the composition has Carbon, a mapping between carbon and C-12 should happen as the input is being written.

At this point, changing setDefaultMassFracs to getDefaultMassFracs in a way that just returns the data might be workable, and just eliminate Material.p.massFrac altogether. We'll have to see how much code accesses p.massFrac and assess how exactly to pull off an upgrade like this.

Copy link
Member Author

@john-science john-science Jan 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, the list of parameters that Material needs is short. I just removed two with no trouble, and a third is only used in UThZr.

I think this PR could probably be merged in as-is.

But for now, let me see if I can attack the situation with a process like this:

  1. The original PR, just removing the Material(Composite) subclass.
  2. Remove all the Material Parameter except the massFrac ones.
  3. See if it's possible to remove Material.p.massFrac
  4. Finally remove the Material metaclass.

I think (3) above is by far the hardest. So I will see how far I get and if that needs to be its own PR. I'm experimenting now.

Copy link
Member Author

@john-science john-science Jan 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I have made progress. I have removed all Parameters from Material and FuelMaterial except massFrac.

I'm hoping I'll remove that today, and we can re-open this PR.

(I have also prepped 7 parallel PRs to update downstream repos to match this one.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Okay, I removed a lot of code, so I'm sure the code coverage will go down. BUT Material not longer has any Parameters.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, please just add docs in the code explaining why there's a parent and what's to be done about it.

Comment on lines 125 to 143
def backUp(self):
"""Empty because statelss materials shouldn't use cache"""
pass

def restoreBackup(self, paramsToApply):
"""Empty because statelss materials shouldn't use cache"""
pass

def clearCache(self):
"""Empty because statelss materials shouldn't use cache"""
pass

def _getCached(self, name):
"""Empty because statelss materials shouldn't use cache"""
return None

def _setCache(self, name, val):
"""Empty because statelss materials shouldn't use cache"""
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just delete all these?

Spelling error: stateless

Big picture: have you measured the performance impact of not caching the material properties vs. temperature? That was a hugely major performance bottleneck we identified through formal profiling of test cases.

We need to see a profiler trace of loading a reactor and printing out all number densities in order to judge this. Can you paste the before/after highlights of the profiler results as a comment to this PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two questions:

  1. Isn't a cache a "state" for the class?
  2. In downstream repos, we have temperature-dependent densities. These caches will preserve the first value they get forever. Shouldn't that lead to incorrect material densities?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look into this more once I have fully removed the Parameters from Materials.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Since Material no longer subclasses Composite, I had to mostly copy them over from the Composite class. But now they aren't blank here any more.

armi/materials/mgO.py Outdated Show resolved Hide resolved
armi/materials/molybdenum.py Outdated Show resolved Hide resolved
armi/materials/thoriumOxide.py Outdated Show resolved Hide resolved
@john-science john-science marked this pull request as draft January 9, 2023 20:24
@john-science john-science marked this pull request as ready for review January 12, 2023 14:56
@drewj-usnctech
Copy link
Contributor

In any repo I can see, I am making PRs to match this one. But if you have a private repo I can't see, 99% of the changes are just to switch calls to mat.p.thing to mat.thing. (The only other change I've seen is a couple materials outside ARMI needed an init() method, that they didn't before.)

Thanks for the heads up @john-science 👍

Copy link
Member

@ntouran ntouran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great, thanks! Just some minor comments.

@@ -40,7 +40,7 @@ def __init__(self):
by a constant user-input density.
"""
Material.__init__(self)
self.p.density = 1.0
self.customDensity = 1.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kind of a minor point but if we're renaming things like this it might be wise to make them supernames like customDensityInGPerCC. As it turns out, putting units in names is one honkin good idea, especially for super generic terms like 'density'

@@ -73,7 +87,8 @@ class Material(composites.Composite):
with information about thermal scattering."""

def __init__(self):
composites.Composite.__init__(self, self.__class__.name)
self.parent = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, please just add docs in the code explaining why there's a parent and what's to be done about it.

armi/materials/material.py Show resolved Hide resolved
armi/materials/material.py Outdated Show resolved Hide resolved
@john-science john-science merged commit 4699c86 into main Jan 24, 2023
@john-science john-science deleted the mats_arent_shapes branch January 24, 2023 18:36
@keckler keckler mentioned this pull request Jan 24, 2023
7 tasks
drewj-usnctech added a commit to drewj-usnctech/armi that referenced this pull request Jan 25, 2023
…30/assembly-1d-parent-class

* terrapower/main:
  Updating B4C docstring for assumed TD frac (terrapower#1117)
  bug fix for xsGroup manager w/ coupling (terrapower#1118)
  Add neutronics category to linPow parameter (terrapower#1119)
  Refactoring Material to not subclass Composite (terrapower#1062)
  Exposing tight coupling to `OperatorSnapshots` (terrapower#1113)
@onufer onufer mentioned this pull request Aug 13, 2024
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
architecture Issues related to big picture system architecture cleanup Code/comment cleanup: Low Priority
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make Materials stateless and remove Composite as their parent
3 participants