Hello Emilio,
thanks a lot for your answer. Here is my understanding of the situation. Effectively around line 243 and successive the target isotope is chosen. We enter this code only when the step is limited by a neutron interaction. If it is fission, elastic or capture, the matter is handled differently, if it is inelastic, this is done (AFAIU) in the following way:
in G4ParticleHPChannelList
there is a first double for where the data for each isotope and all the inelastic channels are summed. Then the isotope is chosen from the weighted (i.e. macroscopic) total inelastic x-sec, obtained via the sum of individual inelastic cross sections via G4ParticleHPChannel. It is not entirely clear why this is necessary, since each isotope has its own inelastic x-section already stored in the G4ParticleHPInelasticData, which could be used to select the isotope. Even better, one could select the isotope at the time of checking the path-length and remember the selection.
Then, once the isotope is chosen, the channel is selected with the same procedure. Note that storing all the channels x-sec for all the isotopes when selecting the isotope would avoid the costly procedure to recalculate the x-section at the price of few tens of floats. There are fast-paths to not recalculate the x-sections if all stays the same, but still a lot of overhead would be avoided. The fact that the first time the x-sec are macroscopic would not alter the selection process if properly normalized, since there will be the same constant for all channels of one isotope.
The way the x-sec os calculated for each isotope (in principle)
-
Sample the (biased) thermal velocity of the nucleus according to the Maxwell distribution;
-
Boost the neutron in the reference frame of the nucleus
-
Calculate the x-section at 0 degrees;
-
Sum all x-sections;
I see at least three problems with this code.
-
Minor. Sampling of the Maxwell distribution is done sampling px, py and pz and using rejection. It would have probably been better to sample the velocity and then rotate randomly.
-
Major. For some reason that I do not (yet) understand, the choice of the nucleus is “biased” toward nuclei moving in the same direction of the neutron, reducing the relative energy. I see no reason for this. The choice should be biased indeed, but by the cross section under consideration. If the energy of the neutron is just “below” a resonance, the neutron will “prefer” nuclei moving toward it, while if the energy of the neutron is just “above” a resonance, the neutron will indeed prefer nuclei moving “along” or away with it. There is no good way to do this in fact. Unless I am missing something…
The problem is that the information on the chosen channel is lost in G4ParticleHPChannelList. One way to make it “go back” would be to store it in G4HadFinalState, which is returned, but not really readily accessible. Another way would be to store it (in some way) into G4HadronicProcess, like the target nucleus.
To access the channel by channel x-sec is perhaps less cumbersome. G4HPChannelList is a static class. If one would add a getter like
G4ParticleHPChannel ** HPChannel() const {return theChannels;}
it would be possible to access the x-secs. Let me know what you think. Really sorry for the long mail!
The Transmutex Coder
Transmutex SA