44#ifndef OPENMC_SOURCE_H
55#define OPENMC_SOURCE_H
66
7+ #include < limits>
78#include < unordered_set>
89
910#include " pugixml.hpp"
@@ -39,19 +40,72 @@ extern vector<unique_ptr<Source>> external_sources;
3940
4041// ==============================================================================
4142// ! Abstract source interface
43+ //
44+ // ! The Source class provides the interface that must be implemented by derived
45+ // ! classes, namely the sample() method that returns a sampled source site. From
46+ // ! this base class, source rejection is handled within the
47+ // ! sample_with_constraints() method. However, note that some classes directly
48+ // ! check for constraints for efficiency reasons (like IndependentSource), in
49+ // ! which case the constraints_applied() method indicates that constraints
50+ // ! should not be checked a second time from the base class.
4251// ==============================================================================
4352
4453class Source {
4554public:
55+ // Constructors, destructors
56+ Source () = default ;
57+ explicit Source (pugi::xml_node node);
4658 virtual ~Source () = default ;
4759
48- // Methods that must be implemented
49- virtual SourceSite sample (uint64_t * seed) const = 0;
50-
5160 // Methods that can be overridden
52- virtual double strength () const { return 1.0 ; }
61+ virtual double strength () const { return strength_; }
62+
63+ // ! Sample a source site and apply constraints
64+ //
65+ // ! \param[inout] seed Pseudorandom seed pointer
66+ // ! \return Sampled site
67+ SourceSite sample_with_constraints (uint64_t * seed) const ;
68+
69+ // ! Sample a source site (without applying constraints)
70+ //
71+ // ! Sample from the external source distribution
72+ // ! \param[inout] seed Pseudorandom seed pointer
73+ // ! \return Sampled site
74+ virtual SourceSite sample (uint64_t * seed) const = 0;
5375
5476 static unique_ptr<Source> create (pugi::xml_node node);
77+
78+ protected:
79+ // Domain types
80+ enum class DomainType { UNIVERSE , MATERIAL , CELL };
81+
82+ // Strategy used for rejecting sites when constraints are applied. KILL means
83+ // that sites are always accepted but if they don't satisfy constraints, they
84+ // are given weight 0. RESAMPLE means that a new source site will be sampled
85+ // until constraints are met.
86+ enum class RejectionStrategy { KILL , RESAMPLE };
87+
88+ // Indicates whether derived class already handles constraints
89+ virtual bool constraints_applied () const { return false ; }
90+
91+ // Methods for constraints
92+ void read_constraints (pugi::xml_node node);
93+ bool satisfies_spatial_constraints (Position r) const ;
94+ bool satisfies_energy_constraints (double E) const ;
95+ bool satisfies_time_constraints (double time) const ;
96+
97+ // Data members
98+ double strength_ {1.0 }; // !< Source strength
99+ std::unordered_set<int32_t > domain_ids_; // !< Domains to reject from
100+ DomainType domain_type_; // !< Domain type for rejection
101+ std::pair<double , double > time_bounds_ {-std::numeric_limits<double >::max (),
102+ std::numeric_limits<double >::max ()}; // !< time limits
103+ std::pair<double , double > energy_bounds_ {
104+ 0 , std::numeric_limits<double >::max ()}; // !< energy limits
105+ bool only_fissionable_ {
106+ false }; // !< Whether site must be in fissionable material
107+ RejectionStrategy rejection_strategy_ {
108+ RejectionStrategy::RESAMPLE }; // !< Procedure for rejecting
55109};
56110
57111// ==============================================================================
@@ -73,27 +127,24 @@ class IndependentSource : public Source {
73127
74128 // Properties
75129 ParticleType particle_type () const { return particle_; }
76- double strength () const override { return strength_; }
77130
78131 // Make observing pointers available
79132 SpatialDistribution* space () const { return space_.get (); }
80133 UnitSphereDistribution* angle () const { return angle_.get (); }
81134 Distribution* energy () const { return energy_.get (); }
82135 Distribution* time () const { return time_.get (); }
83136
84- private :
85- // Domain types
86- enum class DomainType { UNIVERSE , MATERIAL , CELL };
137+ protected :
138+ // Indicates whether derived class already handles constraints
139+ bool constraints_applied () const override { return true ; }
87140
141+ private:
88142 // Data members
89143 ParticleType particle_ {ParticleType::neutron}; // !< Type of particle emitted
90- double strength_ {1.0 }; // !< Source strength
91144 UPtrSpace space_; // !< Spatial distribution
92145 UPtrAngle angle_; // !< Angular distribution
93146 UPtrDist energy_; // !< Energy distribution
94147 UPtrDist time_; // !< Time distribution
95- DomainType domain_type_; // !< Domain type for rejection
96- std::unordered_set<int32_t > domain_ids_; // !< Domains to reject from
97148};
98149
99150// ==============================================================================
@@ -107,9 +158,12 @@ class FileSource : public Source {
107158 explicit FileSource (const std::string& path);
108159
109160 // Methods
110- SourceSite sample (uint64_t * seed) const override ;
111161 void load_sites_from_file (
112162 const std::string& path); // !< Load source sites from file
163+
164+ protected:
165+ SourceSite sample (uint64_t * seed) const override ;
166+
113167private:
114168 vector<SourceSite> sites_; // !< Source sites from a file
115169};
@@ -124,16 +178,17 @@ class CompiledSourceWrapper : public Source {
124178 CompiledSourceWrapper (pugi::xml_node node);
125179 ~CompiledSourceWrapper ();
126180
181+ double strength () const override { return compiled_source_->strength (); }
182+
183+ void setup (const std::string& path, const std::string& parameters);
184+
185+ protected:
127186 // Defer implementation to custom source library
128187 SourceSite sample (uint64_t * seed) const override
129188 {
130189 return compiled_source_->sample (seed);
131190 }
132191
133- double strength () const override { return compiled_source_->strength (); }
134-
135- void setup (const std::string& path, const std::string& parameters);
136-
137192private:
138193 void * shared_library_; // !< library from dlopen
139194 unique_ptr<Source> compiled_source_;
@@ -164,6 +219,9 @@ class MeshSource : public Source {
164219 return sources_.size () == 1 ? sources_[0 ] : sources_[i];
165220 }
166221
222+ protected:
223+ bool constraints_applied () const override { return true ; }
224+
167225private:
168226 // Data members
169227 unique_ptr<MeshSpatial> space_; // !< Mesh spatial
0 commit comments