openmc-plasma-source

OpenMC neutron sources for fusion applications

Published: Feb 23, 2022 by Liam Pattinson

Project info

openmc-plasma-source is a Python package that simplifies the creation of neutron sources for OpenMC Monte-Carlo simulations in tokamaks. It allows users to create point sources, ring sources, and randomised collections of ring sources called TokamakSource.

The library is quite small, so it was possible to make small improvements over the whole project. First, the Python packaging system was updated to use the PEP 517/518 method, which requires using a pyproject.toml file and setup.cfg file in place of the previously-recommended setup.py. Following this, the unit tests were greatly expanded to ensure all components of the library are working as intended. To ensure TokamakSource would work for a range of Tokamak geometries, the Hypothesis library was used to test over hundreds of randomly generated Tokamaks.

One of the most significant upgrades to the library was the introduction of input constraints for all classes. These are used to ensure that variables passed to a class’s __init__ function are of the expected type, and to prevent the undefined behaviour that may result if, for example, a negative major radius were used to initialise a class. Python properties are a great way to enforce these conditions, as by giving each attribute a custom setter function, the user can avoid listing endless try/except blocks in the __init__ function, and they protect against attributes being set to inappropriate values even after initialisation.

However, the class TokamakSource takes a lot of inputs, and this necessitates a lot of properties. Defining two functions – a getter and a setter – for each attribute is error prone, and it can make it confusing to navigate a Python class. To automate the process, I wrote a small library called proper_tea which provides ‘property factories’ with descriptive names such as positive_float(), int_greater_than(value), or in_set(iterable). Properties with constraints on their setter functions can then be simply declared as follows:

class MyClass:

    pos_int = proper_tea.positive_int()
    abc = proper_tea.in_set(["A","B","C"])
    
    def __init__(self, pos_int, abc):
        self.pos_int = pos_int
        self.abc = abc

Now, If the user tries to set pos_int to -5, or abc is set to "hello world", an exception is raised.

After developing this, I was made aware of an existing package that does the same thing! The param library is much more developed than proper_tea, and makes use of descriptors and a frightening amount of metaclassing rather than properties. It was decided to use this instead of proper_tea, as it’s much better supported and is more likely to remain stable over time.

openmc-plasma-source is now a much more tested library, and a significant amount of code was cleaned up during the upgrades. Using the param library, its classes are also protected against bad inputs, and as the class attributes now behave like properties, they are also protected against being set to inappropriate values elsewhere in the code.

openmc python

Share