File indexing completed on 2025-10-30 08:37:39
0001 
0002 
0003 
0004 
0005 
0006 
0007 #pragma once
0008 
0009 #include <memory>
0010 #include <utility>
0011 #include <vector>
0012 
0013 #include "corecel/Assert.hh"
0014 #include "corecel/Types.hh"
0015 #include "corecel/cont/Range.hh"
0016 #include "corecel/cont/Span.hh"
0017 #include "corecel/data/CollectionMirror.hh"
0018 #include "corecel/data/ParamsDataInterface.hh"
0019 #include "corecel/grid/SplineDerivCalculator.hh"
0020 #include "celeritas/Quantities.hh"
0021 #include "celeritas/Types.hh"
0022 #include "celeritas/Units.hh"
0023 #include "celeritas/global/ActionInterface.hh"
0024 
0025 #include "Model.hh"
0026 #include "PhysicsData.hh"
0027 #include "Process.hh"
0028 
0029 namespace celeritas
0030 {
0031 class ActionRegistry;
0032 class AtomicRelaxationParams;
0033 class MaterialParams;
0034 class ParticleParams;
0035 
0036 
0037 
0038 
0039 
0040 
0041 
0042 
0043 
0044 
0045 
0046 
0047 
0048 
0049 
0050 
0051 
0052 
0053 
0054 
0055 
0056 
0057 
0058 
0059 
0060 
0061 struct ParticleOptions
0062 {
0063     using Energy = units::MevEnergy;
0064 
0065     
0066     
0067     real_type min_range;
0068     real_type max_step_over_range;
0069     
0070 
0071     
0072     
0073     Energy lowest_energy;
0074     
0075 
0076     
0077     
0078     bool displaced;
0079     real_type range_factor;
0080     MscStepLimitAlgorithm step_limit_algorithm;
0081     
0082 
0083     
0084     static ParticleOptions default_light()
0085     {
0086         ParticleOptions opts;
0087         opts.min_range = real_type{1} * units::millimeter;
0088         opts.max_step_over_range = 0.2;
0089         opts.lowest_energy = ParticleOptions::Energy{0.001};
0090         opts.displaced = true;
0091         opts.range_factor = 0.04;
0092         opts.step_limit_algorithm = MscStepLimitAlgorithm::safety;
0093         return opts;
0094     };
0095 
0096     
0097     static ParticleOptions default_heavy()
0098     {
0099         ParticleOptions opts;
0100         opts.min_range = 0.1 * units::millimeter;
0101         opts.max_step_over_range = 0.2;
0102         opts.lowest_energy = ParticleOptions::Energy{0.001};
0103         opts.displaced = false;
0104         opts.range_factor = 0.2;
0105         opts.step_limit_algorithm = MscStepLimitAlgorithm::minimal;
0106         return opts;
0107     };
0108 };
0109 
0110 
0111 
0112 
0113 
0114 
0115 
0116 
0117 
0118 
0119 
0120 
0121 
0122 
0123 
0124 
0125 
0126 
0127 
0128 
0129 
0130 
0131 
0132 
0133 
0134 
0135 
0136 struct PhysicsParamsOptions
0137 {
0138     
0139     
0140     real_type fixed_step_limiter{0};
0141     
0142 
0143     
0144     
0145     real_type min_eprime_over_e{0.8};
0146     real_type linear_loss_limit{0.01};
0147     
0148 
0149     
0150     
0151     real_type lambda_limit{real_type{1} * units::millimeter};
0152     real_type safety_factor{0.6};
0153     
0154 
0155     
0156     
0157     ParticleOptions light{ParticleOptions::default_light()};
0158     ParticleOptions heavy{ParticleOptions::default_heavy()};
0159     
0160 
0161     real_type secondary_stack_factor{3};
0162     bool disable_integral_xs{false};
0163 };
0164 
0165 
0166 
0167 
0168 
0169 
0170 
0171 
0172 
0173 
0174 
0175 
0176 
0177 
0178 
0179 
0180 
0181 
0182 
0183 
0184 
0185 
0186 class PhysicsParams final : public ParamsDataInterface<PhysicsParamsData>
0187 {
0188   public:
0189     
0190     
0191     using SPConstParticles = std::shared_ptr<ParticleParams const>;
0192     using SPConstMaterials = std::shared_ptr<MaterialParams const>;
0193     using SPConstProcess = std::shared_ptr<Process const>;
0194     using SPConstModel = std::shared_ptr<Model const>;
0195     using SPConstRelaxation = std::shared_ptr<AtomicRelaxationParams const>;
0196 
0197     using VecProcess = std::vector<SPConstProcess>;
0198     using SpanConstProcessId = Span<ProcessId const>;
0199     using ActionIdRange = Range<ActionId>;
0200     using Options = PhysicsParamsOptions;
0201     
0202 
0203     
0204     struct Input
0205     {
0206         SPConstParticles particles;
0207         SPConstMaterials materials;
0208         VecProcess processes;
0209         SPConstRelaxation relaxation;  
0210         ActionRegistry* action_registry = nullptr;
0211 
0212         Options options;
0213     };
0214 
0215   public:
0216     
0217     explicit PhysicsParams(Input);
0218 
0219     
0220 
0221     
0222     ModelId::size_type num_models() const { return models_.size(); }
0223 
0224     
0225     ProcessId::size_type num_processes() const { return processes_.size(); }
0226 
0227     
0228     inline ParticleId::size_type num_particles() const;
0229 
0230     
0231     inline ProcessId::size_type max_particle_processes() const;
0232 
0233     
0234     inline SPConstModel const& model(ModelId) const;
0235 
0236     
0237     inline SPConstProcess const& process(ProcessId) const;
0238 
0239     
0240     inline ProcessId process_id(ModelId id) const;
0241 
0242     
0243     inline ActionIdRange model_actions() const;
0244 
0245     
0246     SpanConstProcessId processes(ParticleId) const;
0247 
0248     
0249     HostRef const& host_ref() const final { return data_.host_ref(); }
0250 
0251     
0252     DeviceRef const& device_ref() const final { return data_.device_ref(); }
0253 
0254   private:
0255     using BC = SplineDerivCalculator::BoundaryCondition;
0256     using SPAction = std::shared_ptr<StaticConcreteAction>;
0257     using VecModel = std::vector<std::pair<SPConstModel, ProcessId>>;
0258     using HostValue = celeritas::HostVal<PhysicsParamsData>;
0259 
0260     
0261     SPAction pre_step_action_;
0262     SPAction msc_action_;
0263     SPAction range_action_;
0264     SPAction discrete_action_;
0265     SPAction integral_rejection_action_;
0266     SPAction failure_action_;
0267     SPAction fixed_step_action_;
0268 
0269     
0270     VecProcess processes_;
0271     VecModel models_;
0272     SPConstRelaxation relaxation_;
0273 
0274     
0275     CollectionMirror<PhysicsParamsData> data_;
0276 
0277   private:
0278     VecModel build_models(ActionRegistry*) const;
0279     void build_options(Options const& opts, HostValue* data) const;
0280     void build_particle_options(ParticleOptions const&, ParticleScalars*) const;
0281     void build_ids(ParticleParams const& particles, HostValue* data) const;
0282     void build_xs(Options const& opts,
0283                   MaterialParams const& mats,
0284                   HostValue* data) const;
0285     void build_model_xs(MaterialParams const& mats, HostValue* data) const;
0286 };
0287 
0288 
0289 
0290 
0291 
0292 
0293 
0294 auto PhysicsParams::num_particles() const -> ParticleId::size_type
0295 {
0296     return this->host_ref().process_ids.size();
0297 }
0298 
0299 
0300 
0301 
0302 
0303 auto PhysicsParams::max_particle_processes() const -> ProcessId::size_type
0304 {
0305     return this->host_ref().scalars.max_particle_processes;
0306 }
0307 
0308 
0309 
0310 
0311 
0312 auto PhysicsParams::model(ModelId id) const -> SPConstModel const&
0313 {
0314     CELER_EXPECT(id < this->num_models());
0315     return models_[id.get()].first;
0316 }
0317 
0318 
0319 
0320 
0321 
0322 auto PhysicsParams::process(ProcessId id) const -> SPConstProcess const&
0323 {
0324     CELER_EXPECT(id < this->num_processes());
0325     return processes_[id.get()];
0326 }
0327 
0328 
0329 
0330 
0331 
0332 ProcessId PhysicsParams::process_id(ModelId id) const
0333 {
0334     CELER_EXPECT(id < this->num_models());
0335     return models_[id.get()].second;
0336 }
0337 
0338 
0339 
0340 
0341 
0342 auto PhysicsParams::model_actions() const -> ActionIdRange
0343 {
0344     auto offset = host_ref().scalars.model_to_action;
0345     return {ActionId{offset}, ActionId{offset + this->num_models()}};
0346 }
0347 
0348 
0349 }