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

Make standard way to represent TRISO fuel #228

Open
ntouran opened this issue Dec 18, 2020 · 5 comments · May be fixed by #702
Open

Make standard way to represent TRISO fuel #228

ntouran opened this issue Dec 18, 2020 · 5 comments · May be fixed by #702
Labels
enhancement New feature or request

Comments

@ntouran
Copy link
Member

ntouran commented Dec 18, 2020

TRISO fuel is a common need and it'd be nice if there were an obvious straightforward way to define it and use it in reactor models (e.g. #224). Let's try to draft requirements and then talk about implementing.

Requirements

Faithfully represent standard five-layer TRISO fuel (fuel, buffer, inner pyrolytic carbon, SiC, outer pyrolytic carbon

  • User shall be able to define the dimensions and materials of each layer
  • User shall be able to define porosity of each layer
  • User shall be able to define the overall concentration of TRISO particles in the graphite matrix
    (How should it be specified?)
    • Avg pitch to diameter
    • Number of triso particles/volume
    • Graphite/heavy metal ratio
  • Pebble bed and prismatic arrangements shall be allowed

State information shall be storable on parts of the TRISO fuel

  • Temperatures of each layer?

What else?

  • ? Should we allow non-standard layerings as well? Maybe as a follow-up.

Follow-on development needs

  • Add basic material properties to the material library for the layers
  • Make it possible to define more arbitrarily nested collections of components in the input
  • Add TRISO fuel example
@ntouran
Copy link
Member Author

ntouran commented Dec 18, 2020

@drewejohnson can you help us get more specific about the requirements of this? What specific parameters do you need to be able to specify about the fuel blocks? What information will you need as you do the modeling? How detailed will you want temperature distributions (or other state) within the fuel, etc? I'll edit the task description with new requirements as you suggest them.

@drewejohnson
Copy link
Contributor

drewejohnson commented Dec 18, 2020

Thanks for the fast response! Some thoughts off the top of my head

Specifying the particle loading as a packing fraction

Some option to indicate to the neutronic solver that the particles should be explicitly modeled or homogenized. Not saying ARMI should handle explicitly modeling the particles, but would be a very useful bit of data for post-processing and modeling comparisons

For state data, I'm not sure how much would be useful without being a overwhelming amount of data. I've pinged some other team members for their thoughts too.

A generalized particle structure would be useful in the same way LWR fuel pins aren't always a fuel / gap / clad pin. I wonder if there could be cross-over in the structures to model particle fuel and pin-type fuel with some number of materials in concentric rings (https://terrapower.github.io/armi/tutorials/walkthrough_lwr_inputs.html#the-uo2-block)

edit: just saw #100 which shows specifying material inner / outer diameters for fuel pins 👍

@ntouran
Copy link
Member Author

ntouran commented Dec 19, 2020

Ok great, thanks. One starting point as @onufer was reminding me is to use volumetric components to make a unit cell that defines the spherical shell volumes and a cubic graphite unit cell with a hole in it. Mocking it up (you'd need to bring in the materials and add the CubeWithSphericalHole component in a plugin, and add temperatures and whatnot to make this a fully valid input), I am thinking along the lines of:

blocks:
   triso unit cell: 
       fuel:
         shape: Sphere
         material: UraniumOxide
         od: 0.01
         id: 0.0
       buffer:
         shape: Sphere
         material: PourousCarbon
         id: fuel.od
         od: 0.02
       inner pyrolytic carbon:
         shape: Sphere
         material: PyC
         id: buffer.od
         od: 0.03
       SiC:
         shape: Sphere
         material: PourousCarbon
         id:  inner pyrolytic carbon.od
         od: 0.04
       outer pyrolytic carbon:
         shape: Sphere
         material: PourousCarbon
         id: SiC.od
         od: 0.05
       Matrix:
         shape: CubeWithSphericalHole
         material: Graphite
         id:  outer pyrolytic carbon
         op: 1.0

Then I imagine it'd be nice to be able to load that unit cell into another block representing like a prismatic block with coolant holes or a set of pebbles with coolant space, etc. which you could then stack up in assemblies and specify enrichment distributions and whatnot.

A few current issues with this:

  • Volumetric components will not expand in mass as you adjust the block height, so you have to set multiplicity as a function of height at the moment. Or your plugin could provide a Block subclass that updates the multiplicity as a function of height to get the masses right.

  • Adding the unit cell into another block is not yet supported. We are working on a few related input deficiencies internally and want to make sure we add support for this and a few other things in our next input format change (since input changes can be painful to migrate).

In the meantime, it may be possible to set obscenely high multiplicities on the unit cell quantities and add in some other components representing coolant channels and other parts just to be able to load the data onto the model. At that point your physics solvers should be able to grab the info and pass it around to different physics kernels.

drewj-usnctech added a commit to drewj-usnctech/armi that referenced this issue Nov 17, 2021
Provides a yaml-interface for
- modeling particle fuel with arbitrary layers
- multiple particle fuel types in the reactor
- assigning particle fuel as children to some parent component

We have been decently successful with these changes internally in that
downstream plugins can see `Component.particleFuel` and perform actions
based on their content. What follows is an overview of the interface,
implementation, and a discussion of where to go next.

Related to terrapower#228 and
would support modeling the MHTGR-350 benchmark
terrapower#224

This patch is submitted to kick-start a discussion on better ways to add
this feature into ARMI, leveraging the domain knowledge of the ARMI
developers and the "particle fuel aware" plugins internally developed at
USNC Tech.

Input interface
---------------

```yaml
particle fuel:
    demo:
        kernel:
            material: UO2
            id: 0
            od: 0.6
            Tinput: 900
            Thot: 900
            flags: DEPLETABLE
        buffer:
            material: SiC
            id: 0.6
            od: 0.61
            Tinput: 900
            Thot: 900
```

```yaml
matrix:
    shape: Circle
    material: Graphite
    Tinput: 1200
    Thot: 1200
    id: 0.0
    od: 2.2
    latticeIDs: [F]
    flags: DEPLETABLE
    particleFuelSpec: demo
    particleFuelPackingFraction: 0.4

```

With this interface it's possible to define several specifications
in the model and assign them to different cylindrical components.

Implementation
--------------

The particle fuel is stored as a child of the parent component, such
that `<Circle: Matrix>.children` is used to dynamically find the particle
fuel spec. We can't store the specification as an attribute because we
have to support potentially dynamic addition and removal of children to this
component. Something like `self.particleFuel = spec` that makes spec a
child would also have to understand what happens if we remove the spec
from the parent, e.g., `self.remove(self.particleFuel)`. What is then the
outcome of `self.particleFuel` unless we always check the children of the
matrix?

By making the particle fuel spec a `Composite` and placing it in the
`.children` of the parent, the spec is able to be written to and read
from the database.

Adds `Component.setParticleMultiplicity`. The method is called during
block construction when the block's height is available to the matrix
component (particle's parent). The multiplicity is determined from the
matrix volume and target packing fraction.

Note: the particle mult is, by design, for a single component.

Unresolved issues
-----------------

- Volume of the parent matrix is not reduced by the volume occupied
by the particles.
- No support for homogenizing regions that contain particle fuel
- Various homogenization properties don't account for particle fuel
  (e.g., `Core.getHM*`)
- Particle fuel is not included in some text-reporting, leading to
statements like

```
[info] Nuclide categorization for cross section temperature assignments:
       ------------------  ------------------------------------------------------
       Nuclide Category    Nuclides
       ------------------  ------------------------------------------------------
       Fuel
```
and
```
[warn] The system has no heavy metal and therefore is not a nuclear reactor. Please make sure that this is intended and not a input error.
```

- No provided routines for packing the particles into their parent. This
  could be facilitated with a dedicated packing plugin and an unstructured
  3-D `SpatialGrid` class. It's burdensome to expect the user to define
  the exact location of _every_ particle every time. But, if some `Plugin`
  performs the packing and creates this spatial grid, the multiplicity is
  tackled, and you potentially avoid adding or removing particles as their
  parent expands or contracts.
- Unsure if material modifications make their way down to the materials
  in the particle fuel spec. The implementation suggests it as the `matMods`
  argument is passed into the particle fuel YAML object constructor. But
  we have yet to stress test that

Next steps
----------

This patch is submitted because we continue to find places where this
approach does not play well with the rest of the ARMI stack. While Blocks
that contain particle fuel are correctly able to compute their heavy
metal mass by iterating over their children, which in turn finds the
particle fuel. However, higher-level actions like `Core.getHM*` do not
go down to the sub-block level, instead asking to homogenize Blocks.
The homogenization methods are not yet aware of the particle fuel because
they rely on `Component.getNuclides` which reports the nuclides for it's
`Material`, and does not include the children.

This approach is sensible because if I'm writing a neutronic input file
and I can exactly model the matrix and it's particle fuel, I would expect
`matrix.getNuclides` to return the nuclides for _just the matrix_. Then,
being informed of the particle fuel, I can write those materials and geometry
uniquely. However, codes that cannot handle particle fuel and/or work
with homogenized regions (e.g., nodal diffusion) would need this
homogenized data. Allowing `Component.getNuclides` to return the nuclides
on the child particle fuel would support this case, but not the previous case.

My speculation is that the optimal strategy lies somewhere in making the
matrix object not a `Component` but a `Block` and having the ARMI Composite
tree accept blocks that potentially contain blocks. I think this is valid
using the API but the user interface would need some work. Having the matrix
be a block would provide a better interface for homogenization and exact
representation of the particle fuel. I think...

Other related changes
---------------------

Added `Sphere.getBoundingCircleOuterDiameter` so that the particle fuel
composites can be properly added to the database. They need to be
"sortable" other wise `Database3._createLayout` breaks trying to sort
components. This enables the particle fuel spec to be added to and read
from the HDF data file

The material constructor is a more public function as it is needed both
in creating `Components` but also in creating the particle fuel spec.

Added `MATRIX` flag

Signed-off-by: Andrew Johnson <a.johnson@usnc-tech.com>
@ntouran
Copy link
Member Author

ntouran commented Dec 1, 2021

I brought in a discussion we've been having internally for some time here: #503, which might be relevant.

@drewj-usnctech
Copy link
Contributor

After a conversation with @ntouran @john-science (👋 @sombrereau), some requirements or considerations for development were requested.

As someone who wishes to use ARMI for particle fuel modeling, these features would be very useful (roughly decreasing order)

  • Ability to model particles based on diameters as these are most likely to be provided from vendors
  • Ability to model mixture of particles + background material (matrix) with a packing fraction (ratio of total volume of particles to container) known at beginning of life
  • Resistance to changing the number of particles in a material due to thermal expansion / contraction of the container
  • Translation layer / plugin to convert diameters and packing fraction to fixed mult
  • Translation layer / plugin to perform particle packing and determine locations in 3-D space inside container (also provides mult for free by counting number of locations)
  • Ability to load in locations from a file rather than performing packing every simulation (good for saving time by avoiding re-packing all the time)

Miscellany

It might be useful to have some translation layer / plugin re-compute the packing fraction at time steps. This value could be reported and serialized to HDF rather than writing all the locations to HDF. That way, if you wanted to re-build the reactor at some non-BOL point, you could recover the packing fraction that reflects how the parent material has expanded / contracted over time.

There is likely an argument for at least reporting the maximum and average of some properties in a material that contains particle fuel. Would be very important for fuel performance to know the maximum temperature in a fuel kernel and the average, but maybe less so the temperature of every fuel kernel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants