磁場中のTrackがboundaryに到達した場合で、chordの方向と本当のTrackの方向がboundaryを挟んで反対側になったときに無限Loopに陥る問題に対する点と、fNoZeroStepが特定の状況でリセットされない問題に対応するPatch。詳細は下の通り。
無限Loopについて
赤が本当のTrack、緑がG4PropagatorInFieldがComputeStep関数の中で定義するChordABである。
1) 正常に動作する場合
2) 無限Loopに陥る場合
右図のように、すでにBoundary上にいて、なおかつChordABとTrackの方向がboundaryを挟んで反対側になったときに起こる。Volume I の中からBoundary Aに到達したとする。
3)改良点
2)の問題を回避するため、Stepが現在所属するVolumeのBoundaryにいる場合には、ChordABの方向とTrackの方向がBoundaryを挟んで反対になっていないかをcheckする。
反対になっていた場合、G4ChordFinderのfDeltaChord(図のF点とE点、ChordとArcの中央までの距離が、最大どれだけの長さ離れることを許すか、というパラメータ。fDeltaChordを小さくすると、ChordとArcの距離は近くなるので、結果的に1回のTryで進める距離は短くなる)を0.1倍して再トライする。
このCheckを、Trackの方向とChordABの方向がBoundaryに対し同じ側になるまでくり返し、うまくこのLoopを抜けることができたら、DeltaChordの値を元に戻す。抜ける前にDeltaChordがkCarToleranceより小さくなってしまった場合には、fParticleIsLoopingを立ててLoopを抜け、fDeltaChordの値を元に戻す。
Geant4開発者グループの推奨は、ArcABを短くすることではなくDeltaChordを小さくするとのことだったので、そのように仕様変更しました。このpatchを使いたい方は、必ずGeant4.4.1へのアップグレードを行い、下のpatchを使用して下さい。
fNoZeroStepのリセットについて
Geant4.4.1の仕様では、上のLoopingの問題が起こった場合にはfParticleIsLoopingという旗を立て、一つ上の階層でこの旗が立っている場合にはこの粒子をStopAndKill(この粒子の追跡を止め、Trackを捨てる)する扱いになっているようである。この場合、それまでにAccumulateされた情報は全てゼロクリアする必要があるが、fNoZeroStep変数のゼロクリアが行われていなかったため、fNoZeroStepが設定された値を超えた瞬間にまともなTrackingを行わなくなる問題を回避した。
Patchは下の通り。
G4PropagatorInField4.4.1JLC.patch
※このPatchの中で、VolumeのBoundaryにいることを確かめるためG4VSolidのInside(p)関数を呼んでいるが、PropagatorInFieldは自分の居場所を知っているはずなので、この手続きは実際には必要ないと思われる。