57{
58 theEnergies.clear();
59
60 if (aStep == nullptr) return false;
61
63
64 if( edep == 0. ) {
65 return 0;
66 }
67
68#ifdef VERBOSE_ENERSPLIT
70 if (verbose)
74#endif
77 {
78 return (
G4int)theEnergies.size();
79 }
81 theEnergies.push_back(edep);
82 return (
G4int)theEnergies.size();
83 }
84
85
87 if (!IsPhantomVolume(preStepPhysVol)) {
89 "SplitEnergyInVolumes() called for a step not in a phantom volume");
90 }
91 auto phantomVol = static_cast<G4PVParameterised*>(preStepPhysVol);
92 thePhantomParam = static_cast<G4PhantomParameterisation*>(phantomVol->GetParameterisation());
93
94
95 std::vector<std::pair<G4int, G4double>> rnsl =
97
100 G4double kinEnergyPre = kinEnergyPreOrig;
101
104 unsigned int ii;
105 for (ii = 0; ii < rnsl.size(); ++ii) {
107 slSum += sl;
108#ifdef VERBOSE_ENERSPLIT
109 if (verbose)
110 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes" << ii <<
" RN: iter1 step length geom "
112#endif
113 }
114
115#ifdef VERBOSE_ENERSPLIT
116 if (verbose)
117 G4cout <<
"G4EnergySplitter RN: step length geom TOTAL " << slSum <<
" true TOTAL "
118 << stepLength << " ratio " << stepLength / slSum << " Energy "
122#endif
123
124
125 if (theNIterations == 0) {
126 for (ii = 0; ii < rnsl.size(); ++ii) {
128 G4double edepStep = edep * sl / slSum;
129
130#ifdef VERBOSE_ENERSPLIT
131 if (verbose)
132 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes" << ii <<
" edep " << edepStep <<
G4endl;
133#endif
134
135 theEnergies.push_back(edepStep);
136 }
137 }
138 else {
139
140#ifdef VERBOSE_ENERSPLIT
141
142 if (verbose) {
144 for (ii = 0; ii < rnsl.size(); ++ii) {
146 slSum += sl;
147 }
148 for (ii = 0; ii < rnsl.size(); ii++) {
149 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes " << ii
150 <<
" RN: iter0 corrected energy lost " << edep * rnsl[ii].second / slSum <<
G4endl;
151 }
152 }
153#endif
154
155 G4double slRatio = stepLength / slSum;
156#ifdef VERBOSE_ENERSPLIT
157 if (verbose)
158 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes RN: iter 0, step ratio " << slRatio
160#endif
161
162
163 G4EmCalculator emcalc;
165 std::vector<G4double> stepLengths;
166 for (
G4int iiter = 1; iiter <= theNIterations; ++iiter) {
167
168
169 if (iiter == 1) {
170 for (ii = 0; ii < rnsl.size(); ++ii) {
172 stepLengths.push_back(sl * slRatio);
173#ifdef VERBOSE_ENERSPLIT
174 if (verbose)
175 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes" << ii <<
" RN: iter" << iiter
176 <<
" corrected step length " << sl * slRatio <<
G4endl;
177#endif
178 }
179
180 for (ii = 0; ii < rnsl.size(); ++ii) {
181 const G4Material* mate = thePhantomParam->GetMaterial(rnsl[ii].first);
183 if (kinEnergyPre > 0.) {
184 dEdx = emcalc.
GetDEDX(kinEnergyPre, part, mate);
185 }
186 G4double elost = stepLengths[ii] * dEdx;
187
188#ifdef VERBOSE_ENERSPLIT
189 if (verbose)
190 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes" << ii <<
" RN: iter1 energy lost "
191 << elost << " energy at interaction " << kinEnergyPre << " = stepLength "
192 << stepLengths[ii] <<
" * dEdx " << dEdx <<
G4endl;
193#endif
194 kinEnergyPre -= elost;
195 theEnergies.push_back(elost);
196 totalELost += elost;
197 }
198 }
199 else {
200
201
202
203 slSum = 0.;
204 kinEnergyPre = kinEnergyPreOrig;
205 for (ii = 0; ii < rnsl.size(); ++ii) {
206 const G4Material* mate = thePhantomParam->
GetMaterial(rnsl[ii].first);
207 stepLengths[ii] = theElossExt->TrueStepLength(kinEnergyPre, rnsl[ii].second, mate, part);
208 kinEnergyPre -= theEnergies[ii];
209
210#ifdef VERBOSE_ENERSPLIT
211 if (verbose)
212 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes" << ii <<
" RN: iter" << iiter
213 << " step length geom " << stepLengths[ii] << " geom2true "
214 << rnsl[ii].second / stepLengths[ii] <<
G4endl;
215#endif
216
217 slSum += stepLengths[ii];
218 }
219
220
222#ifdef VERBOSE_ENERSPLIT
223 if (verbose)
224 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes" << ii <<
" RN: iter" << iiter
225 <<
" step ratio " << slRatio <<
G4endl;
226#endif
227 for (ii = 0; ii < rnsl.size(); ++ii) {
228 stepLengths[ii] *= slratio;
229#ifdef VERBOSE_ENERSPLIT
230 if (verbose)
231 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes" << ii <<
" RN: iter" << iiter
232 <<
" corrected step length " << stepLengths[ii] <<
G4endl;
233#endif
234 }
235
236
238 totalELost = 0.;
239 for (ii = 0; ii < rnsl.size(); ++ii) {
240 const G4Material* mate = thePhantomParam->
GetMaterial(rnsl[ii].first);
242 if (kinEnergyPre > 0.) {
243 dEdx = emcalc.
GetDEDX(kinEnergyPre, part, mate);
244 }
245 G4double elost = stepLengths[ii] * dEdx;
246#ifdef VERBOSE_ENERSPLIT
247 if (verbose)
248 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes" << ii <<
" RN: iter" << iiter
249 << " energy lost " << elost << " energy at interaction " << kinEnergyPre
250 <<
" = stepLength " << stepLengths[ii] <<
" * dEdx " << dEdx <<
G4endl;
251#endif
252 kinEnergyPre -= elost;
253 theEnergies[ii] = elost;
254 totalELost += elost;
255 }
256 }
257
258
259 G4double enerRatio = (edep / totalELost);
260
261#ifdef VERBOSE_ENERSPLIT
262 if (verbose)
263 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes" << ii <<
" RN: iter" << iiter
264 <<
" energy ratio " << enerRatio <<
G4endl;
265#endif
266
267#ifdef VERBOSE_ENERSPLIT
269#endif
270 for (ii = 0; ii < theEnergies.size(); ++ii) {
271 theEnergies[ii] *= enerRatio;
272#ifdef VERBOSE_ENERSPLIT
273 elostTot += theEnergies[ii];
274 if (verbose)
275 G4cout <<
"G4EnergySplitter::SplitEnergyInVolumes " << ii <<
" RN: iter" << iiter
276 << " corrected energy lost " << theEnergies[ii] << " orig elost "
277 << theEnergies[ii] / enerRatio << " energy before interaction "
278 << kinEnergyPreOrig - elostTot + theEnergies[ii] << " energy after interaction "
279 << kinEnergyPreOrig - elostTot <<
G4endl;
280#endif
281 }
282 }
283 }
284
285 return (
G4int)theEnergies.size();
286}
G4GLOB_DLL std::ostream G4cout
G4double GetDEDX(G4double kinEnergy, const G4ParticleDefinition *, const G4Material *, const G4Region *r=nullptr)
const G4String & GetName() const
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
G4double GetPDGCharge() const
G4Material * GetMaterial() const
G4VPhysicalVolume * GetPhysicalVolume() const
G4double GetKineticEnergy() const
G4Track * GetTrack() const
G4StepPoint * GetPreStepPoint() const
G4double GetStepLength() const
G4double GetTotalEnergyDeposit() const
G4ParticleDefinition * GetDefinition() const