fusion-energy / openmc-plasma-source

Creates a plasma source as an openmc.source object from input parameters that describe the plasma
MIT License
26 stars 11 forks source link

added ring and point source classes #8

Closed shimwell closed 2 years ago

shimwell commented 2 years ago

Not ready for review yet, missing tests

Adding a few more sources. This adds a simple ring source and a point source.

This point source is useful for inertial confinement fusion This ring source is useful for magnetic confinement fusion when extra plasma details are not known

TODO tests

shimwell commented 2 years ago

Looks like the tests are passing, what do you think @RemDelaporteMathurin

shimwell commented 2 years ago

Thanks for this @Shimwell !!!

About the fact that openmc users are used to modify the source attribute directly: you could add setters that modify the openmc attribute.

For instance:

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        self.set_space()
        self._radius = value

    def set_space(self):
        radius = openmc.stats.Discrete([self.radius], [1])
        z_values = openmc.stats.Discrete([0], [1])
        angle = openmc.stats.Uniform(a=start_angle, b=stop_angle)
        self.space = openmc.stats.CylindricalIndependent(
            r=radius,
            phi=angle,
            z=z_values,
            origin=(0.0, 0.0, 0.0)
        )

I just tried this but couldn't quite get it to work. Will try again soon


import openmc

class FusionRingSource(openmc.Source):
    """An openmc.Source object with some presets to make it more convenient
    for fusion simulations using a ring source. All attributes can be changed
    after initialization if required. Default isotropic ring source with a Muir
    energy distribution.

    Args:
        radius: the inner radius of the ring source
        start_angle: the start angle of the ring in radians,
        stop_angle: the end angle of the ring in radians,
        temperature: the temperature to use in the Muir distribution in eV,
    """
    def __init__(
        self,
        radius,
        start_angle: float =0.,
        stop_angle: float = 6.28318530718,
        temperature: float = 20000.,
        fuel='DT'
    ):

        self.radius = radius
        self.start_angle = start_angle
        self.stop_angle = stop_angle
        self.temperature = temperature
        self.fuel = fuel

        super().__init__()

        self.set_space()
        self.set_energy()

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        self.set_space()
        self._radius = value

    @property
    def start_angle(self):
        return self._start_angle

    @start_angle.setter
    def start_angle(self, value):
        self.set_space()
        self._start_angle = value

    @property
    def start_angle(self):
        return self._start_angle

    @start_angle.setter
    def start_angle(self, value):
        self.set_space()
        self._start_angle = value

    @property
    def fuel(self):
        return self._fuel

    @fuel.setter
    def fuel(self, value):
        self.set_energy()
        self._fuel = value

    @property
    def temperature(self):
        return self._temperature

    @temperature.setter
    def temperature(self, value):
        self.set_energy()
        self._temperature = value

    def set_space(self):
        print('setting space')
        radius = openmc.stats.Discrete([self.radius], [1])
        z_values = openmc.stats.Discrete([0], [1])
        angle = openmc.stats.Uniform(a=self.start_angle, b=self.stop_angle)
        self.space = openmc.stats.CylindricalIndependent(
            r=radius,
            phi=angle,
            z=z_values,
            origin=(0.0, 0.0, 0.0)
        )

    def set_energy(self):
        print('setting energy')
        if self.fuel == 'DT':
            mean_energy = 14080000.  # mean energy in eV
            mass_of_reactants = 5  # mass of the reactants (D + T) AMU
        elif self.fuel == 'DT':
            mean_energy = 2450000.  # mean energy in eV
            mass_of_reactants = 4  # mass of the reactants (D + D) AMU
        else:
            raise ValueError(f'fuel must be either "DT" or "DD", not {self.fuel}')

        self.energy = openmc.stats.Muir(
            e0=mean_energy,
            m_rat=mass_of_reactants,
            kt=self.temperature
        )
shimwell commented 2 years ago

:rocket: looks like tests are passing

RemDelaporteMathurin commented 2 years ago

@Shimwell do you want to leave that "setter" thing for later or shall I add pytests and merge this?

shimwell commented 2 years ago

yep lets get this one merged. The setters would be nice but it think the functionality now ready.

RemDelaporteMathurin commented 2 years ago

yep lets get this one merged. The setters would be nice but it think the functionality now ready.

There's currently an outage at CircleCI and all workflows are not running...

However we now this works. Let's merge it in!