From d93df33dfb29e314df08ae1def3de4d2141be388 Mon Sep 17 00:00:00 2001 From: Olaf Schumann Date: Tue, 28 Dec 2021 12:30:15 +0100 Subject: [PATCH 1/5] Implementation of time distribution for the source --- include/openmc/source.h | 6 ++++-- openmc/source.py | 25 ++++++++++++++++++++++++- src/source.cpp | 25 ++++++++++++++++++++----- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/include/openmc/source.h b/include/openmc/source.h index cc644577ed..6866655c18 100644 --- a/include/openmc/source.h +++ b/include/openmc/source.h @@ -42,13 +42,13 @@ public: }; //============================================================================== -//! Source composed of independent spatial, angle, and energy distributions +//! Source composed of independent spatial, angle, energy, and time distributions //============================================================================== class IndependentSource : public Source { public: // Constructors - IndependentSource(UPtrSpace space, UPtrAngle angle, UPtrDist energy); + IndependentSource(UPtrSpace space, UPtrAngle angle, UPtrDist energy, UPtrDist time); explicit IndependentSource(pugi::xml_node node); //! Sample from the external source distribution @@ -64,6 +64,7 @@ public: SpatialDistribution* space() const { return space_.get(); } UnitSphereDistribution* angle() const { return angle_.get(); } Distribution* energy() const { return energy_.get(); } + Distribution* time() const { return time_.get(); } private: ParticleType particle_ {ParticleType::neutron}; //!< Type of particle emitted @@ -71,6 +72,7 @@ private: UPtrSpace space_; //!< Spatial distribution UPtrAngle angle_; //!< Angular distribution UPtrDist energy_; //!< Energy distribution + UPtrDist time_; //!< Time distribution }; //============================================================================== diff --git a/openmc/source.py b/openmc/source.py index 8f25bcab07..493da9429b 100644 --- a/openmc/source.py +++ b/openmc/source.py @@ -22,6 +22,8 @@ class Source: Angular distribution of source sites energy : openmc.stats.Univariate Energy distribution of source sites + time : openmc.stats.Univariate + time distribution of source sites filename : str Source file from which sites should be sampled library : str @@ -43,6 +45,8 @@ class Source: Angular distribution of source sites energy : openmc.stats.Univariate or None Energy distribution of source sites + time : openmc.stats.Univariate or None + time distribution of source sites file : str or None Source file from which sites should be sampled library : str or None @@ -56,11 +60,12 @@ class Source: """ - def __init__(self, space=None, angle=None, energy=None, filename=None, + def __init__(self, space=None, angle=None, energy=None, time=None, filename=None, library=None, parameters=None, strength=1.0, particle='neutron'): self._space = None self._angle = None self._energy = None + self._time = None self._file = None self._library = None self._parameters = None @@ -71,6 +76,8 @@ class Source: self.angle = angle if energy is not None: self.energy = energy + if time is not None: + self.time = time if filename is not None: self.file = filename if library is not None: @@ -104,6 +111,10 @@ class Source: def energy(self): return self._energy + @property + def time(self): + return self._time + @property def strength(self): return self._strength @@ -142,6 +153,11 @@ class Source: cv.check_type('energy distribution', energy, Univariate) self._energy = energy + @time.setter + def time(self, time): + cv.check_type('time distribution', time, Univariate) + self._time = time + @strength.setter def strength(self, strength): cv.check_type('source strength', strength, Real) @@ -178,6 +194,8 @@ class Source: element.append(self.angle.to_xml_element()) if self.energy is not None: element.append(self.energy.to_xml_element('energy')) + if self.time is not None: + element.append(self.time.to_xml_element('time')) return element @classmethod @@ -229,6 +247,11 @@ class Source: if energy is not None: source.energy = Univariate.from_xml_element(energy) + time = elem.find('time') + if time is not None: + source.time = Univariate.from_xml_element(time) + + return source diff --git a/src/source.cpp b/src/source.cpp index be4270b512..af361e199e 100644 --- a/src/source.cpp +++ b/src/source.cpp @@ -46,11 +46,12 @@ vector> external_sources; // IndependentSource implementation //============================================================================== -IndependentSource::IndependentSource( - UPtrSpace space, UPtrAngle angle, UPtrDist energy) - : space_ {std::move(space)}, angle_ {std::move(angle)}, energy_ { - std::move(energy)} -{} +IndependentSource::IndependentSource(UPtrSpace space, UPtrAngle angle, UPtrDist energy, UPtrDist time) + : space_{std::move(space)}, + angle_{std::move(angle)}, + energy_{std::move(energy)}, + time_{std::move(time)} +{ } IndependentSource::IndependentSource(pugi::xml_node node) { @@ -140,6 +141,17 @@ IndependentSource::IndependentSource(pugi::xml_node node) // Default to a Watt spectrum with parameters 0.988 MeV and 2.249 MeV^-1 energy_ = UPtrDist {new Watt(0.988e6, 2.249e-6)}; } + + // Determine external source time distribution + if (check_for_node(node, "time")) { + pugi::xml_node node_dist = node.child("time"); + time_ = distribution_from_xml(node_dist); + } else { + // Default to a Constant time T=0 + double T[] {0.0}; + double p[] {1.0}; + time_ = UPtrDist {new Discrete{T, p, 1}}; + } } } @@ -224,6 +236,9 @@ SourceSite IndependentSource::sample(uint64_t* seed) const break; } + // Sample particle creation time + site.time = time_->sample(seed); + return site; } From 3e79b55ae46ff0d49e4939c22aae6438f3d60b66 Mon Sep 17 00:00:00 2001 From: Olaf Schumann Date: Wed, 29 Dec 2021 13:05:18 +0100 Subject: [PATCH 2/5] Update Documentation --- docs/source/usersguide/settings.rst | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/source/usersguide/settings.rst b/docs/source/usersguide/settings.rst index 95b7fdf453..dabad32bd5 100644 --- a/docs/source/usersguide/settings.rst +++ b/docs/source/usersguide/settings.rst @@ -174,10 +174,11 @@ create an instance of :class:`openmc.Source` and use it to set the varying source strengths, :attr:`Settings.source` should be set to a list of :class:`openmc.Source` objects. -The :class:`openmc.Source` class has three main attributes that one can set: +The :class:`openmc.Source` class has four main attributes that one can set: :attr:`Source.space`, which defines the spatial distribution, -:attr:`Source.angle`, which defines the angular distribution, and -:attr:`Source.energy`, which defines the energy distribution. +:attr:`Source.angle`, which defines the angular distribution, +:attr:`Source.energy`, which defines the energy distribution, and +:attr:`Source.time`, which defines the time distribution. The spatial distribution can be set equal to a sub-class of :class:`openmc.stats.Spatial`; common choices are :class:`openmc.stats.Point` or @@ -210,14 +211,23 @@ distribution. This could be a probability mass function specified, a Watt fission spectrum with :math:`a` = 0.988 MeV and :math:`b` = 2.249 MeV :sup:`-1` is used. +The time distribution can be set equal to any univariate probability +distribution. This could be a probability mass function +(:class:`openmc.stats.Discrete`), a uniform distribution +(:class:`openmc.stats.Uniform`), or a tabular distribution +(:class:`openmc.stats.Tabular`). By default, if no time distribution is +specified, particles are started at :math:`t=0`. + As an example, to create an isotropic, 10 MeV monoenergetic source uniformly -distributed over a cube centered at the origin with an edge length of 10 cm, one +distributed over a cube centered at the origin with an edge length of 10 cm, and +emitting a pulse of particles from 0 to 10 µs, one would run:: source = openmc.Source() source.space = openmc.stats.Box((-5, -5, -5), (5, 5, 5)) source.angle = openmc.stats.Isotropic() source.energy = openmc.stats.Discrete([10.0e6], [1.0]) + source.time = openmc.stats.Uniform(0, 1e-6) settings.source = source The :class:`openmc.Source` class also has a :attr:`Source.strength` attribute From 23f8cfb4f0c2bd5d4ec9e5c294db9ab80130d475 Mon Sep 17 00:00:00 2001 From: Olaf Schumann Date: Wed, 29 Dec 2021 13:06:52 +0100 Subject: [PATCH 3/5] Add time distribution to one test This doesn not change the results, only the settings.xml. A better test hast to be made --- tests/regression_tests/source/inputs_true.dat | 2 ++ tests/regression_tests/source/test.py | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/regression_tests/source/inputs_true.dat b/tests/regression_tests/source/inputs_true.dat index 0568b65434..131d20ac12 100644 --- a/tests/regression_tests/source/inputs_true.dat +++ b/tests/regression_tests/source/inputs_true.dat @@ -121,6 +121,7 @@ +