Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:31

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file celeritas/track/detail/StatusCheckExecutor.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Assert.hh"
0011 #include "corecel/Macros.hh"
0012 #include "celeritas/global/ActionInterface.hh"
0013 #include "celeritas/global/CoreTrackView.hh"
0014 #include "celeritas/track/SimTrackView.hh"
0015 
0016 #include "../StatusCheckData.hh"
0017 
0018 namespace celeritas
0019 {
0020 namespace detail
0021 {
0022 //---------------------------------------------------------------------------//
0023 /*!
0024  * Check that the condition is true, otherwise throw an error/assertion.
0025  *
0026  * \note This macro is defined so that the condition is still checked in
0027  * "release" mode.
0028  */
0029 #define CELER_FAIL_IF(COND, MSG)                                      \
0030     do                                                                \
0031     {                                                                 \
0032         if (CELER_UNLIKELY(!(COND)))                                  \
0033         {                                                             \
0034             CELER_DEBUG_THROW_(MSG ": '" #COND "' failed", internal); \
0035         }                                                             \
0036     } while (0)
0037 
0038 //---------------------------------------------------------------------------//
0039 /*!
0040  * Assert that a track's status and actions are valid.
0041  *
0042  * When enabled as a debug option, this is called after every action is
0043  * executed. The state's "action" and "order" are for the last executed action.
0044  * The status, post-step, and along-step action are from *before* the last
0045  * executed action.
0046  *
0047  * See \c StepActionOrder, \c TrackStatus .
0048  */
0049 struct StatusCheckExecutor
0050 {
0051     inline CELER_FUNCTION void operator()(CoreTrackView const& track);
0052 
0053     NativeCRef<StatusCheckParamsData> const params;
0054     NativeRef<StatusCheckStateData> const state;
0055 };
0056 
0057 //---------------------------------------------------------------------------//
0058 // INLINE DEFINITIONS
0059 //---------------------------------------------------------------------------//
0060 CELER_FUNCTION void StatusCheckExecutor::operator()(CoreTrackView const& track)
0061 {
0062     CELER_EXPECT(state.order != StepActionOrder::size_);
0063     CELER_EXPECT(state.action);
0064 
0065     auto tsid = track.track_slot_id();
0066     auto sim = track.make_sim_view();
0067 
0068     if (state.order > StepActionOrder::start
0069         && state.order < StepActionOrder::end)
0070     {
0071         auto prev_status = state.status[tsid];
0072         CELER_FAIL_IF(sim.status() >= prev_status,
0073                       "status was improperly reverted");
0074     }
0075     if (state.order >= StepActionOrder::pre
0076         && state.order < StepActionOrder::end)
0077     {
0078         // Initializing takes place *either* at the very beginning of the
0079         // stepping loop *or* at the very end (in the case where a track is
0080         // initialized in-place from a secondary). It should be cleared in
0081         // pre-step
0082         CELER_FAIL_IF(sim.status() != TrackStatus::initializing,
0083                       "status cannot be 'initializing' after pre-step");
0084     }
0085     if (sim.status() == TrackStatus::inactive)
0086     {
0087         // Remaining tests only apply to active tracks
0088         return;
0089     }
0090     if (state.order < StepActionOrder::pre
0091         || state.order == StepActionOrder::end)
0092     {
0093         // Skip remaining tests since step actions get reset in "pre-step"
0094         return;
0095     }
0096 
0097     if (sim.step_length() != numeric_limits<real_type>::infinity())
0098     {
0099         /*!
0100          * It's allowable to have *no* post step action if there are no physics
0101          * processes for the current particle type.
0102          * \todo Change this behavior to be a *tracking cut* rather than lost
0103          * energy.
0104          */
0105         CELER_FAIL_IF(sim.post_step_action(), "missing post-step action");
0106     }
0107 
0108     if (sim.status() == TrackStatus::alive)
0109     {
0110         // If the track fails during initialization, it won't get an
0111         // along-step action, so only check this if alive
0112         CELER_FAIL_IF(sim.along_step_action(), "missing along-step action");
0113     }
0114 
0115     ActionId const prev_along_step = state.along_step_action[tsid];
0116     ActionId const next_along_step = sim.along_step_action();
0117     if (state.order > StepActionOrder::pre && next_along_step)
0118     {
0119         CELER_FAIL_IF(prev_along_step == next_along_step,
0120                       "along-step action cannot yet change");
0121     }
0122 
0123     ActionId const prev_post_step = state.post_step_action[tsid];
0124     ActionId const next_post_step = sim.post_step_action();
0125     if (state.order > StepActionOrder::pre && prev_post_step
0126         && prev_post_step != next_post_step)
0127     {
0128         // Check that order is increasing if not an "implicit" action
0129         auto prev_order = params.orders[prev_post_step];
0130         auto next_order = params.orders[next_post_step];
0131         CELER_FAIL_IF((prev_order == params.implicit_order
0132                        || next_order == params.implicit_order
0133                        || OrderedAction{prev_order, prev_post_step}
0134                               < OrderedAction{next_order, next_post_step}),
0135                       "new post-step action is out of order");
0136     }
0137 }
0138 
0139 //---------------------------------------------------------------------------//
0140 }  // namespace detail
0141 }  // namespace celeritas