Skip to content

Commit fd47401

Browse files
committed
initial implementation wip
1 parent d1df80a commit fd47401

File tree

17 files changed

+190
-24
lines changed

17 files changed

+190
-24
lines changed

include/openmc/particle.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ class Particle : public ParticleData {
6262
//! site may have been produced from an external source, from fission, or
6363
//! simply as a secondary particle.
6464
//! \param src Source site data
65-
void from_source(const SourceSite* src);
65+
//! \param particle ParticleType incident particle type
66+
void from_source(const SourceSite* src, ParticleType particle);
6667

6768
// Coarse-grained particle events
6869
void event_calculate_xs();

include/openmc/particle_data.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ class ParticleData : public GeometryState {
469469
CacheDataMG mg_xs_cache_;
470470

471471
ParticleType type_ {ParticleType::neutron};
472+
ParticleType type_last_ {ParticleType::neutron};
472473

473474
double E_;
474475
double E_last_;
@@ -566,6 +567,8 @@ class ParticleData : public GeometryState {
566567
// Particle type (n, p, e, gamma, etc)
567568
ParticleType& type() { return type_; }
568569
const ParticleType& type() const { return type_; }
570+
ParticleType& type_last() { return type_last_; }
571+
const ParticleType& type_last() const { return type_last_; }
569572

570573
// Current particle energy, energy before collision,
571574
// and corresponding multigroup group indices. Energy

include/openmc/tallies/filter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ enum class FilterType {
3939
MUSURFACE,
4040
PARENT_NUCLIDE,
4141
PARTICLE,
42+
PARTICLE_OUT,
4243
POLAR,
4344
SPHERICAL_HARMONICS,
4445
SPATIAL_LEGENDRE,

include/openmc/tallies/filter_particle.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,45 @@ class ParticleFilter : public Filter {
4848
vector<ParticleType> particles_;
4949
};
5050

51+
//==============================================================================
52+
//! Bins by type of outgoing particle (e.g. neutron, photon).
53+
//==============================================================================
54+
55+
class ParticleOutFilter : public Filter {
56+
public:
57+
//----------------------------------------------------------------------------
58+
// Constructors, destructors
59+
60+
~ParticleOutFilter() = default;
61+
62+
//----------------------------------------------------------------------------
63+
// Methods
64+
65+
std::string type_str() const override { return "particleout"; }
66+
FilterType type() const override { return FilterType::PARTICLE_OUT; }
67+
68+
void from_xml(pugi::xml_node node) override;
69+
70+
void get_all_bins(const Particle& p, TallyEstimator estimator,
71+
FilterMatch& match) const override;
72+
73+
void to_statepoint(hid_t filter_group) const override;
74+
75+
std::string text_label(int bin) const override;
76+
77+
//----------------------------------------------------------------------------
78+
// Accessors
79+
80+
const vector<ParticleType>& particles() const { return particles_; }
81+
82+
void set_particles(span<ParticleType> particles);
83+
84+
private:
85+
//----------------------------------------------------------------------------
86+
// Data members
87+
88+
vector<ParticleType> particles_;
89+
};
90+
5191
} // namespace openmc
5292
#endif // OPENMC_TALLIES_FILTER_PARTICLE_H

include/openmc/tallies/tally.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ extern std::unordered_map<int, int> tally_map;
202202
extern vector<unique_ptr<Tally>> tallies;
203203
extern vector<int> active_tallies;
204204
extern vector<int> active_analog_tallies;
205+
extern vector<int> active_particleout_analog_tallies;
205206
extern vector<int> active_tracklength_tallies;
206207
extern vector<int> active_collision_tallies;
207208
extern vector<int> active_meshsurf_tallies;

include/openmc/tallies/tally_scoring.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,16 @@ void score_collision_tally(Particle& p);
7272
//! Analog tallies are triggered at every collision, not every event.
7373
//
7474
//! \param p The particle being tracked
75-
void score_analog_tally_ce(Particle& p);
75+
//! \param tallies A vector of the indices of the tallies to score to
76+
void score_analog_tally_ce(Particle& p, const vector<int>& tallies);
7677

7778
//! Score tallies based on a simple count of events (for multigroup).
7879
//
7980
//! Analog tallies are triggered at every collision, not every event.
8081
//
8182
//! \param p The particle being tracked
82-
void score_analog_tally_mg(Particle& p);
83+
//! \param tallies A vector of the indices of the tallies to score to
84+
void score_analog_tally_mg(Particle& p, const vector<int>& tallies);
8385

8486
//! Score tallies using a tracklength estimate of the flux.
8587
//

openmc/filter.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
'universe', 'material', 'cell', 'cellborn', 'surface', 'mesh', 'energy',
2525
'energyout', 'mu', 'musurface', 'polar', 'azimuthal', 'distribcell', 'delayedgroup',
2626
'energyfunction', 'cellfrom', 'materialfrom', 'legendre', 'spatiallegendre',
27-
'sphericalharmonics', 'zernike', 'zernikeradial', 'particle', 'cellinstance',
28-
'collision', 'time', 'parentnuclide', 'weight', 'meshborn', 'meshsurface',
29-
'meshmaterial',
27+
'sphericalharmonics', 'zernike', 'zernikeradial', 'particle', 'particleout',
28+
'cellinstance', 'collision', 'time', 'parentnuclide', 'weight', 'meshborn',
29+
'meshsurface', 'meshmaterial',
3030
)
3131

3232
_CURRENT_NAMES = (
@@ -785,6 +785,29 @@ def from_xml_element(cls, elem, **kwargs):
785785
filter_id = int(get_text(elem, "id"))
786786
bins = get_elem_list(elem, "bins", str) or []
787787
return cls(bins, filter_id=filter_id)
788+
789+
790+
class ParticleoutFilter(ParticleFilter):
791+
"""Bins tally events based on the outgoing particle type.
792+
793+
Parameters
794+
----------
795+
bins : str, or sequence of str
796+
The particles to tally represented as strings ('neutron', 'photon',
797+
'electron', 'positron').
798+
filter_id : int
799+
Unique identifier for the filter
800+
801+
Attributes
802+
----------
803+
bins : sequence of str
804+
The particles to tally
805+
id : int
806+
Unique identifier for the filter
807+
num_bins : Integral
808+
The number of filter bins
809+
810+
"""
788811

789812

790813
class ParentNuclideFilter(ParticleFilter):

openmc/lib/filter.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
'EnergyFilter', 'EnergyoutFilter', 'EnergyFunctionFilter', 'LegendreFilter',
2323
'MaterialFilter', 'MaterialFromFilter', 'MeshFilter', 'MeshBornFilter',
2424
'MeshMaterialFilter', 'MeshSurfaceFilter', 'MuFilter', 'MuSurfaceFilter',
25-
'ParentNuclideFilter', 'ParticleFilter', 'PolarFilter', 'SphericalHarmonicsFilter',
26-
'SpatialLegendreFilter', 'SurfaceFilter', 'TimeFilter', 'UniverseFilter',
27-
'WeightFilter', 'ZernikeFilter', 'ZernikeRadialFilter', 'filters'
25+
'ParentNuclideFilter', 'ParticleFilter', 'ParticleoutFilter', 'PolarFilter',
26+
'SphericalHarmonicsFilter', 'SpatialLegendreFilter', 'SurfaceFilter', 'TimeFilter',
27+
'UniverseFilter', 'WeightFilter', 'ZernikeFilter', 'ZernikeRadialFilter', 'filters'
2828
]
2929

3030
# Tally functions
@@ -564,6 +564,10 @@ def bins(self):
564564
return [ParticleType(i) for i in particle_i]
565565

566566

567+
class ParticleoutFilter(ParticleFilter):
568+
filter_type = 'particleout'
569+
570+
567571
class PolarFilter(Filter):
568572
filter_type = 'polar'
569573

src/mesh.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ void Mesh::material_volumes(int nx, int ny, int nz, int table_size,
358358
site.r[ax1] = min1 + (i1 + 0.5) * d1;
359359
site.r[ax2] = min2 + (i2 + 0.5) * d2;
360360

361-
p.from_source(&site);
361+
p.from_source(&site, site.particle);
362362

363363
// Determine particle's location
364364
if (!exhaustive_find_cell(p)) {

src/particle.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ void Particle::split(double wgt)
110110
}
111111
}
112112

113-
void Particle::from_source(const SourceSite* src)
113+
void Particle::from_source(const SourceSite* src, ParticleType particle)
114114
{
115115
// Reset some attributes
116116
clear();
@@ -141,6 +141,7 @@ void Particle::from_source(const SourceSite* src)
141141
E() = data::mg.energy_bin_avg_[g()];
142142
}
143143
E_last() = E();
144+
type_last() = particle;
144145
time() = src->time;
145146
time_last() = src->time;
146147
parent_nuclide() = src->parent_nuclide;
@@ -160,6 +161,7 @@ void Particle::event_calculate_xs()
160161
// Store pre-collision particle properties
161162
wgt_last() = wgt();
162163
E_last() = E();
164+
type_last() = type();
163165
u_last() = u();
164166
r_last() = r();
165167
time_last() = time();
@@ -348,9 +350,9 @@ void Particle::event_collide()
348350
score_collision_tally(*this);
349351
if (!model::active_analog_tallies.empty()) {
350352
if (settings::run_CE) {
351-
score_analog_tally_ce(*this);
353+
score_analog_tally_ce(*this, model::active_analog_tallies);
352354
} else {
353-
score_analog_tally_mg(*this);
355+
score_analog_tally_mg(*this, model::active_analog_tallies);
354356
}
355357
}
356358

@@ -408,6 +410,8 @@ void Particle::event_revive_from_secondary()
408410
wgt() = 0.0;
409411
}
410412

413+
auto type = this->type();
414+
411415
// Check for secondary particles if this particle is dead
412416
if (!alive()) {
413417
// Write final position for this particle
@@ -419,11 +423,20 @@ void Particle::event_revive_from_secondary()
419423
if (secondary_bank().empty())
420424
return;
421425

422-
from_source(&secondary_bank().back());
426+
from_source(&secondary_bank().back(), type);
423427
secondary_bank().pop_back();
424428
n_event() = 0;
425429
bank_second_E() = 0.0;
426430

431+
// Score tallies affected by secondary particles
432+
if (!model::active_particleout_analog_tallies.empty()) {
433+
if (settings::run_CE) {
434+
score_analog_tally_ce(*this, model::active_particleout_analog_tallies);
435+
} else {
436+
score_analog_tally_mg(*this, model::active_particleout_analog_tallies);
437+
}
438+
}
439+
427440
// Subtract secondary particle energy from interim pulse-height results
428441
if (!model::active_pulse_height_tallies.empty() &&
429442
this->type() == ParticleType::photon) {

0 commit comments

Comments
 (0)