-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify and fix safety/MSC #434
Conversation
This branch is compiled okay, but has a runtime issue from the demo-loop: #0 0x000000000269ef20 in celeritas::device_debug_error () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, this approach should be a correct assumption if the safety is always akin to the current geometry state. However, how can I find the safety in the previous position (just as a user case) unless it is saved as a cached data? - So, should we add the safety at the last calculated position too? The safety in UrbanMscStepLimit should be the safety in the pre-step position while the safety in UrbanMscScatter should be calculated at the updated position after the field propagator - Nevertheless, the proposed implementation should be okay as we do not update the geometry after the range limiter.
Anyway, the MR is good to merge once the demo-loop issue is resolved.
@@ -97,8 +97,8 @@ class VecgeomTrackView | |||
// Find the distance to the next boundary, up to and including a step | |||
inline CELER_FUNCTION Propagation find_next_step(real_type max_step); | |||
|
|||
// Find the safety at a given position within the current volume | |||
inline CELER_FUNCTION real_type find_safety(const Real3& pos); | |||
// Find the safety at a the current position within the current volume |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drop 'a'
Apparently, the following line in UrbanMscStepLimit is causing the problem; |
Yes I should be.
I think if users need a "previous position" safety then we should work with them to cache it as part of their workflow... if it's not always needed, then people who don't need it shouldn't have to pay for it.
Yes, since the geometry
Ugh, it looks like we never previously checked that the safety was nonnegative... so something in VecGeom (I assume that' you have it enabled?) is giving us negative safety distances... I'll check it out. |
@whokion Shall I also add to this PR the fix for the "increment step" being in the wrong place? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sethrj There is a test failure from UrbanMsc.test.cc (i.e., celeritas_em_UrbanMsc) due to the negative safety protection (so sampling changes) which needs to be addressed before merging - my msc validation test with respect to Geant4 TestEM15 (which has not been committed yet) looks good with this MR as it statistically compare results between Geant4 and celeritas, so this MR itself should be good to merge.
Yes, please. Thanks. |
The test failure is because if (result.true_path < shared_.params.limit_min_fix()
|| (!on_boundary_ && distance < safety_))
{
result.is_displaced = false;
auto temp = this->calc_geom_path(result.true_path);
result.geom_path = temp.geom_path;
return result;
} or if (result.true_path < shared_.params.limit_min_fix()
|| (safety_ > 0 && distance < safety_))
{
result.is_displaced = false;
auto temp = this->calc_geom_path(result.true_path);
result.geom_path = temp.geom_path;
return result;
} |
I guess that the later should be closer to the original (Gean4) logic. |
So then the difference is that this conditional is about the physical distance from the boundary, whereas the other flag is about entering a new volume? Instead of |
Also the current definition of on_boundary_ which includes the first step is also miss-leading as the vertex can be anywhere. |
Well, the material ID can be same for different logical/physical volumes. |
@@ -234,6 +235,9 @@ inline CELER_FUNCTION void along_step_track(CoreTrackView const& track) | |||
|
|||
// Override step limit with whatever action/step changes we applied here | |||
sim.force_step_limit(step_limit); | |||
|
|||
// Increment the step counter | |||
sim.increment_num_steps(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure whether this is the right place to increase the step counter since any of along step actions (either
range limiter or msc) may not be selected for the process governing the current step - well the range limiter is a part of pre-step though in our implementation. So, should it be increased either when msc is selected, or inside somewhere discrete_select_track if msc (and the range limiter?) is not select.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The end of "along step" seems like the right place to step counter, right? Any track that is active needs to have its step counter incremented, and (aside from the "zero step" special case where we now increment it) this will be called for every active track.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me, places where we should increase the step counter (exclusively) are 1) when msc is selected, i.e, inside the block and 2) when the geometry limited step is selected, i.e, inside the block, and 3) the inside discrete_select_track. Of course, it also need to check whether either msc or geometry limited step is selected at the line. So, not sure whether putting the increment_num_steps()
at the end of along step is equivalent to the logic above, i.e, make sure whether the step counter is neither over counted nor under counted, but increased once and only once per alived step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the end of AlongStep is going to be the cleanest place to put it: it's the only place (barring the one "return if zero step length") that is going to be guaranteed to be called before the final particle processing... having to put it in multiple different kernels risks forgetting to put it somewhere. Adding it to more locations (such as when the step limiter is selected, which at that point can still be overridden by slowing down) increases the risk of errors.
I guess it really matters most depending on what actually uses the step counter: and since the only things right now are the diagnostics and the MSC "first step" exception, and nothing in physics (or boundary crossing) does. So let's leave it here as the last thing that happens in "along step", and we can make sure it's documented and can later change it as needed.
As we discussed, the original
find_safety
track function was slightly over-engineered: we only ever calculate the safety from the current position. Simplify the interfaces forfind_safety
as well as theUrbanMscStepLimit
class.Additionally, prevent negative safety distances from VecGeom (this was apparently happening: we need more assertions!) and update
UrbanMscStepLimit
so that if we do get negatives they'll implicitly be treated like zeros.