-
-
Notifications
You must be signed in to change notification settings - Fork 422
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
distance2boundary: sometimes returns the wrong distance #517
Comments
Sorry for the confusion. The calculated distance seems to always be correct. So the only thing that's strange now is why removing |
@yeganer there is no need to apologize. It's very important to question the code! @tardis-sn/tardis-core to make sure that everyone has a look. |
@ssim did we discuss setting |
@yeganer - is this still relevant? Which your modifications, I thought this issue is resolved. Or am I wrong? |
@unoebauer This is kind of still relevant. There is still a probability > 0 that a packet is outside the outer boundary and misses it. This would result in the package interacting only with lines and continuum. After such an interaction the packet gets a new mu. If it then hits any boundary we are fine but there is again a small possibility that the packet doesn't hit anything and slowly drifts away. The farer away the packet, the bigger the probability that it will miss it's shell again. So in the current code and in my improved version there is the possibility for an endless loop. But this probability is extremely small since every interaction after the first miss of the outer boundary has to have a mu that will again miss the boundary. A fix would be to explicitly set the radius instead of calculating it after moving the packet accross the shell boundary. |
@yeganer I think that it would help me to understand if you can give a specific example of when there's a problem - i.e. can you, step by step, go through a (hypothetical) example where the code would currently do the wrong thing. |
@ssim Sure. Of course it's very unlikely that a packet enters the state that it misses the outer boundary. I did a calculation once and the requirement was something like |
@yeganer I see - yes, that's helpful - I think I understand the point better now. So this is when we are getting (in terms of numerical precision) close to the case where a packet's trajectory is close to being a tangent line to the boundary: i.e. a packet has come down towards a shell boundary (from outside) in such a way that it just skims the boundary of that shell. The way the code deals with this case should be that (in the hypothetical perfect case of no rounding errors) the packet would reach the boundary, be temporarily assigned to the inner zone, but then calculate that the distance to move back into the outer zone would be zero ... so it would immediately transition back. However, if the "crossing point" is numerical calculated to be just outside the boundary (rather than exactly on, or just inside the boundary) the sqrt goes NaN and the distance is handled wrongly. Clearly this is going to be a very rare thing, but I agree with you that we should catch it. My gut instinct (based on making as minimal change as possible) is just to have a check that the value of d_outer on line 160 of cmontecarlo.c (I'm looking at the current master) is finite. If it's not, print a warning out and set it to zero. This should happen very rarely but I think it follows the logic of the method current used and so is a very minimal change. It's interesting that your test for this (in your PR) never trips the check on the determinant being negative. Perhaps that's just luck (it's too unlikely to be that close) or perhaps there's some cleverness in the way that mu is updated when a packets moves that we don't encounter this? |
@ssim: @unoebauer did a quick check on the determinant being negative and he didn't find any. Considering the requirements for that case I come to the conclusion that we ran the test with far to few packets to encounter that. I don't think we will ever encounter that. The questions that are relevant:
|
@yeganer So I would say that we don't care and we don't want to change it. It would still be good, however, to have the code throw a message / error if that determinant is negative, just on principle. After all, maybe people will still be using TARDIS a couple of Hubble times from now and it will save them the trouble of finding this thread when it does happen. Those "clever packets" will get there in the end! ;) |
@ssim In the new version of that function in PR #514 this flag isn't needed anymore. So I think it is safe to merge those changes, including the removal of |
Checking on d_boundary as you suggest sounds fine, provided NaN < something is always false (you know that better than me). Recently_crossed_boundary is still in PR #514 isn't it? But your plan is now to remove it? By the way, I spent quite a long time just now being confused by the meaning of "next_shell_id" however, which appears to be different form what I'd expect. Can you easily change the comment on this quantity in rpacket.h to correctly explain that it is not, in fact, the ID of the next shell but is +1 if the packet is heading outwards and -1 if heading inwards. Or should make a separate issue to have this fixed? (I guess that this use of the variable got changed at some point but the comment wasn't altered.) |
@ssim You are right in your thinking about recently_crossed_boundary. Because we know what circle the packet will hit, we don't have to calculate both distances and compare them but only calculate the one we are hitting. I found that to be quite confusing myself. I'm not sure whether we need that variable anyway. |
@tardis-sn/tardis-core I think we should close this. |
can you open a new issue and close this one? |
Closing this. The followup is #552. |
While looking at the code I came across a weird behaviour in distance2boundary.
I thought the recently_crossed_boundary flag was necessary because the old implementation couldn't handle packets close to the boundary. I was wrong. This flag was implemented to correct numerical errors in the case that moving a packet resulted in a radius outside it's shell boundary. This happens quite a lot actually, around 10% of the invocations to distance2boundary have either
r<r_inner
orr>r_outer
.Most of those cases arer<r_inner
and this is checked for withBut in the other case where
r>r_outer
nothing is checked and the distances are calculated the normal way. For d_outer the formula used isd = sqrt(r_outer ** 2 + (mu**2 - 1) r**2 ) - mu * r
.For r>r_outer this gives the distance to the nearest crossing instead of the farthest.
I think this is not a huge issue but since I haven't found anything contradicting me this can result in a packet crossing the inner boundary multiple times in a row and being absorbed in that process or that the r and shell_id of the packet are messed up and are not synchronised anymore.
In my opinion there are two ways to fix this:
r<r_inner
and return the correct distance. This will leave these numerical errors in the code.r=r_inner|r_outer
when crossing the shell boundary. I'm not sure of the consequences of this approach. @unoebauer might have some experience with this particular problem.The text was updated successfully, but these errors were encountered: