File indexing completed on 2025-09-16 08:52:27
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Macros.hh"
0011 #include "celeritas/global/ActionInterface.hh"
0012 #include "celeritas/global/CoreTrackView.hh"
0013
0014 #include "../SimTrackView.hh"
0015
0016 #if !CELER_DEVICE_COMPILE
0017 # include "corecel/io/Logger.hh"
0018 # include "celeritas/global/Debug.hh"
0019 #endif
0020
0021 #include "../StatusCheckData.hh"
0022
0023 namespace celeritas
0024 {
0025 namespace detail
0026 {
0027
0028 #if !CELER_DEVICE_COMPILE
0029
0030 # define CELER_PRINT_TRACK(MSG, TRACK) \
0031 CELER_LOG_LOCAL(error) \
0032 << MSG << ": " << ::celeritas::StreamableTrack{TRACK};
0033 #else
0034 # define CELER_PRINT_TRACK(MSG, TRACK)
0035 #endif
0036
0037
0038
0039
0040
0041
0042
0043 #define CELER_FAIL_IF(COND, MSG) \
0044 do \
0045 { \
0046 if (CELER_UNLIKELY((COND))) \
0047 { \
0048 CELER_PRINT_TRACK(MSG, track) \
0049 CELER_DEBUG_THROW_(MSG ": '" #COND "'", internal); \
0050 } \
0051 } while (0)
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064 struct StatusCheckExecutor
0065 {
0066 inline CELER_FUNCTION void operator()(CoreTrackView const& track);
0067
0068 NativeCRef<StatusCheckParamsData> const params;
0069 NativeRef<StatusCheckStateData> const state;
0070 };
0071
0072
0073
0074
0075 CELER_FUNCTION void StatusCheckExecutor::operator()(CoreTrackView const& track)
0076 {
0077 CELER_EXPECT(state.order != StepActionOrder::size_);
0078 CELER_EXPECT(state.action);
0079
0080 auto tsid = track.track_slot_id();
0081 auto sim = track.sim();
0082
0083 if (state.order > StepActionOrder::start
0084 && state.order < StepActionOrder::end)
0085 {
0086 auto prev_status = state.status[tsid];
0087 CELER_FAIL_IF(sim.status() < prev_status,
0088 "status was improperly reverted");
0089 }
0090 if (state.order >= StepActionOrder::pre
0091 && state.order < StepActionOrder::end)
0092 {
0093
0094
0095
0096
0097 CELER_FAIL_IF(sim.status() == TrackStatus::initializing,
0098 "status cannot be 'initializing' after pre-step");
0099 }
0100 if (sim.status() == TrackStatus::inactive)
0101 {
0102
0103 return;
0104 }
0105 if (state.order < StepActionOrder::pre
0106 || state.order == StepActionOrder::end)
0107 {
0108
0109 return;
0110 }
0111
0112 if (sim.step_length() != numeric_limits<real_type>::infinity())
0113 {
0114
0115
0116
0117
0118
0119
0120 CELER_FAIL_IF(!sim.post_step_action(), "missing post-step action");
0121 }
0122
0123 if (sim.status() == TrackStatus::alive)
0124 {
0125
0126
0127 CELER_FAIL_IF(!sim.along_step_action(), "missing along-step action");
0128
0129
0130 CELER_FAIL_IF(track.geometry().is_outside(),
0131 "track is outside the geometry but still 'alive'");
0132 }
0133
0134 ActionId const prev_along_step = state.along_step_action[tsid];
0135 ActionId const next_along_step = sim.along_step_action();
0136 if (state.order > StepActionOrder::pre && next_along_step)
0137 {
0138 CELER_FAIL_IF(prev_along_step != next_along_step,
0139 "along-step action cannot yet change");
0140 }
0141
0142 ActionId const prev_post_step = state.post_step_action[tsid];
0143 ActionId const next_post_step = sim.post_step_action();
0144 if (state.order > StepActionOrder::pre && prev_post_step
0145 && prev_post_step != next_post_step)
0146 {
0147
0148 auto prev_order = params.orders[prev_post_step];
0149 auto next_order = params.orders[next_post_step];
0150 CELER_FAIL_IF(!(prev_order == params.implicit_order
0151 || next_order == params.implicit_order
0152 || OrderedAction{prev_order, prev_post_step}
0153 < OrderedAction{next_order, next_post_step}),
0154 "new post-step action is out of order");
0155 }
0156 }
0157
0158
0159 }
0160 }