mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 21:55:41 -04:00
Merge pull request #1940 from ojschumann/time-src
Time distribution for source.
This commit is contained in:
commit
34ec14c5ee
7 changed files with 71 additions and 15 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
|||
|
|
@ -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,10 @@ 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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -459,9 +459,12 @@ void read_settings_xml()
|
|||
// If no source specified, default to isotropic point source at origin with
|
||||
// Watt spectrum
|
||||
if (model::external_sources.empty()) {
|
||||
double T[] {0.0};
|
||||
double p[] {1.0};
|
||||
model::external_sources.push_back(make_unique<IndependentSource>(
|
||||
UPtrSpace {new SpatialPoint({0.0, 0.0, 0.0})},
|
||||
UPtrAngle {new Isotropic()}, UPtrDist {new Watt(0.988e6, 2.249e-6)}));
|
||||
UPtrAngle {new Isotropic()}, UPtrDist {new Watt(0.988e6, 2.249e-6)},
|
||||
UPtrDist {new Discrete(T, p, 1)}));
|
||||
}
|
||||
|
||||
// Check if we want to write out source
|
||||
|
|
|
|||
|
|
@ -46,11 +46,12 @@ vector<unique_ptr<Source>> 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@
|
|||
</dist>
|
||||
</pair>
|
||||
</energy>
|
||||
<time parameters="2 5" type="uniform" />
|
||||
</source>
|
||||
<source strength="0.1">
|
||||
<space origin="1.0 1.0 0.0" type="cylindrical">
|
||||
|
|
@ -144,5 +145,6 @@
|
|||
</dist>
|
||||
</pair>
|
||||
</energy>
|
||||
<time parameters="2 5" type="uniform" />
|
||||
</source>
|
||||
</settings>
|
||||
|
|
|
|||
|
|
@ -65,14 +65,16 @@ class SourceTestHarness(PyAPITestHarness):
|
|||
energy3 = openmc.stats.Tabular(E, p, interpolation='histogram')
|
||||
energy4 = openmc.stats.Mixture([1, 2, 3], [energy1, energy2, energy3])
|
||||
|
||||
time1 = openmc.stats.Uniform(2, 5)
|
||||
|
||||
source1 = openmc.Source(spatial1, angle1, energy1, strength=0.3)
|
||||
source2 = openmc.Source(spatial2, angle2, energy2, strength=0.1)
|
||||
source3 = openmc.Source(spatial3, angle3, energy3, strength=0.1)
|
||||
source4 = openmc.Source(spatial4, angle3, energy3, strength=0.1)
|
||||
source5 = openmc.Source(spatial5, angle3, energy3, strength=0.1)
|
||||
source6 = openmc.Source(spatial5, angle3, energy4, strength=0.1)
|
||||
source7 = openmc.Source(spatial6, angle3, energy4, strength=0.1)
|
||||
source8 = openmc.Source(spatial7, angle3, energy4, strength=0.1)
|
||||
source7 = openmc.Source(spatial6, angle3, energy4, time1, strength=0.1)
|
||||
source8 = openmc.Source(spatial7, angle3, energy4, time1, strength=0.1)
|
||||
|
||||
settings = openmc.Settings()
|
||||
settings.batches = 10
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue