Open keckler opened 1 year ago
This is probably a specific instance of https://github.com/terrapower/armi/issues/865
Okay, the problem here is clearly that this is not how we calculate mass:
a[0][0].getVolume() * a[0][0].material.density(Tc=25+dT)
We calculate mass starting at the number densities of each nuclide:
The difference is, of course, that you did this:
c.getVolume() * c.material.density(Tc=T)
when you should have done this:
c.getVolume() * c.density()
When I run this second line, I get the exact result. It matches perfectly. Does that make sense?
Yeah, it has only recently sunk in for me that c.material.density()
should pretty much never be used. This has always struck me as not obvious to a user, and thus dangerous.
But I think still, for a component that has experienced no burnup and no physics manipulation of any kind outside of thermal expansion (as the component in my example), wouldn't we expect for the material object's density()
to be in agreement with the expanded component? I guess my impression was that we only don't expect that after "physics" has been performed upon the model.
If I'm wrong there, can you explain to me why not?
I'm not sure what you would want to do differently.
People DO use (and need) many other things from a component's material
c.material.uFrac
c.material.puFrac
c.material.zrFrac
c.material.liquidusTemperature()
c.material.solidusTemperature()
Those are all real examples taken from the wild. And there are many more. The .material
of each Component
needs to be accessible.
I believe the general idea was supposed to be that users could do this:
c.density()
but this fails:
c.material.density()
And that should stop people from getting confused. BUT, okay, confusion was had. That's no good. I don't immediately see an improvement that is shorter term than just rewrite the materials library, which will hopefully happen within the next year.
but this fails:
c.material.density()
And that should stop people from getting confused.
Can you clarify what you mean by this? As shown in my example in the initial post above, that type of call does not fail.
Long story short, if you build an assembly with
UraniumOxide
in it and then expand components of that assembly, you will see that the total mass is different depending on how you calculate it. My belief is that this is caused by theUraniumOxide.density()
andUraniumOxide.linearExpansion()
and/orUraniumOxide.linearExpansionPercent()
methods not being completely aligned with each other. Here is an example of the problem.Let's build a very simple assembly with just one component, made of
UraniumOxide
.We can now change the temperature of the component and perform full expansion:
If we now query the mass of that component in two separate ways, we get different answers:
That clearly is not correct. This difference is small, but it presents a problem when one is trying to show that mass is conserved between their blueprints and the actual instantiated ARMI model.
If we repeat the process for
UZr
instead, we get the same component mass when calculated in the two ways shown:The reason that
UZr
does this correctly, butUraniumOxide
does not, is becauseUZr
defines only thelinearExpansionPercent()
method and letsdensity()
be calculated relative to that. InUraniumOxide
we define both explicitly, and thus they are able to be not perfectly aligned with each other.I do not know if this problem extends to other material classes, but I imagine that it might. We currently have no guardrails to prevent this sort of thing.