Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4EnergySplitter Class Reference

#include <G4EnergySplitter.hh>

Public Member Functions

 G4EnergySplitter ()
virtual ~G4EnergySplitter ()
G4int SplitEnergyInVolumes (const G4Step *aStep)
void GetLastVoxelID (G4int &voxelID)
void GetFirstVoxelID (G4int &voxelID)
void GetVoxelID (G4int stepNo, G4int &voxelID)
void GetVoxelIDAndLength (G4int stepNo, G4int &voxelID, G4double &stepLength)
void GetLengthAndEnergyDeposited (G4int stepNo, G4int &voxelID, G4double &stepLength, G4double &energyLoss)
void GetLengthAndInitialEnergy (G4double &preStepEnergy, G4int stepNo, G4int &voxelID, G4double &stepLength, G4double &initialEnergy)
void SetNIterations (G4int niter)
G4MaterialGetVoxelMaterial (G4int stepNo)

Detailed Description

Definition at line 49 of file G4EnergySplitter.hh.

Constructor & Destructor Documentation

◆ G4EnergySplitter()

G4EnergySplitter::G4EnergySplitter ( )

Definition at line 44 of file G4EnergySplitter.cc.

45{
46 theElossExt = new G4EnergyLossForExtrapolator(0);
47 thePhantomParam = nullptr;
48 theNIterations = 2;
49}

◆ ~G4EnergySplitter()

G4EnergySplitter::~G4EnergySplitter ( )
virtual

Definition at line 51 of file G4EnergySplitter.cc.

52{
53 delete theElossExt;
54}

Member Function Documentation

◆ GetFirstVoxelID()

void G4EnergySplitter::GetFirstVoxelID ( G4int & voxelID)

Definition at line 307 of file G4EnergySplitter.cc.

308{
309 voxelID = (*(G4RegularNavigationHelper::Instance()->GetStepLengths().crbegin())).first;
310}
const std::vector< std::pair< G4int, G4double > > & GetStepLengths()
static G4RegularNavigationHelper * Instance()

◆ GetLastVoxelID()

void G4EnergySplitter::GetLastVoxelID ( G4int & voxelID)

Definition at line 301 of file G4EnergySplitter.cc.

302{
303 voxelID = (*(G4RegularNavigationHelper::Instance()->GetStepLengths().cbegin())).first;
304}

◆ GetLengthAndEnergyDeposited()

void G4EnergySplitter::GetLengthAndEnergyDeposited ( G4int stepNo,
G4int & voxelID,
G4double & stepLength,
G4double & energyLoss )
inline

◆ GetLengthAndInitialEnergy()

void G4EnergySplitter::GetLengthAndInitialEnergy ( G4double & preStepEnergy,
G4int stepNo,
G4int & voxelID,
G4double & stepLength,
G4double & initialEnergy )
inline

◆ GetVoxelID()

void G4EnergySplitter::GetVoxelID ( G4int stepNo,
G4int & voxelID )

Definition at line 313 of file G4EnergySplitter.cc.

314{
315 if (stepNo < 0 || stepNo >= G4int(G4RegularNavigationHelper::Instance()->GetStepLengths().size()))
316 {
317 G4Exception("G4EnergySplitter::GetVoxelID",
318 "Invalid stepNo, smaller than 0 or bigger or equal to number of voxels traversed",
320 G4String("stepNo = " + G4UIcommand::ConvertToString(stepNo)
321 + ", number of voxels = "
323 G4int(G4RegularNavigationHelper::Instance()->GetStepLengths().size())))
324 .c_str());
325 }
327 advance(ite, stepNo);
328 voxelID = (*ite).first;
329}
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
int G4int
Definition G4Types.hh:85
static G4String ConvertToString(G4bool boolVal)

◆ GetVoxelIDAndLength()

void G4EnergySplitter::GetVoxelIDAndLength ( G4int stepNo,
G4int & voxelID,
G4double & stepLength )
inline

◆ GetVoxelMaterial()

G4Material * G4EnergySplitter::GetVoxelMaterial ( G4int stepNo)
inline

◆ SetNIterations()

void G4EnergySplitter::SetNIterations ( G4int niter)
inline

◆ SplitEnergyInVolumes()

G4int G4EnergySplitter::SplitEnergyInVolumes ( const G4Step * aStep)

Definition at line 56 of file G4EnergySplitter.cc.

57{
58 theEnergies.clear();
59
60 if (aStep == nullptr) return false; // it is 0 when called by GmScoringMgr after last event
61
62 G4double edep = aStep->GetTotalEnergyDeposit();
63
64 if( edep == 0. ) {
65 return 0;
66 }
67
68#ifdef VERBOSE_ENERSPLIT
69 G4bool verbose = 1;
70 if (verbose)
71 G4cout << "G4EnergySplitter::SplitEnergyInVolumes totalEdepo " << aStep->GetTotalEnergyDeposit()
72 << " Nsteps " << G4RegularNavigationHelper::Instance()->GetStepLengths().size()
73 << G4endl;
74#endif
75 if (G4RegularNavigationHelper::Instance()->GetStepLengths().empty()
76 || aStep->GetTrack()->GetDefinition()->GetPDGCharge() == 0)
77 { // we are only counting dose deposit
78 return (G4int)theEnergies.size();
79 }
80 if (G4RegularNavigationHelper::Instance()->GetStepLengths().size() == 1) {
81 theEnergies.push_back(edep);
82 return (G4int)theEnergies.size();
83 }
84
85 //----- Get the phantom parameterisation from the G4Step
86 auto preStepPhysVol = aStep->GetPreStepPoint()->GetPhysicalVolume();
87 if (!IsPhantomVolume(preStepPhysVol)) {
88 G4Exception("G4EnergySplitter::SplitEnergyInVolumes", "PhantomParamError", FatalException,
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 //----- Distribute energy deposited in voxels
95 std::vector<std::pair<G4int, G4double>> rnsl =
97
98 const G4ParticleDefinition* part = aStep->GetTrack()->GetDefinition();
99 G4double kinEnergyPreOrig = aStep->GetPreStepPoint()->GetKineticEnergy();
100 G4double kinEnergyPre = kinEnergyPreOrig;
101
102 G4double stepLength = aStep->GetStepLength();
103 G4double slSum = 0.;
104 unsigned int ii;
105 for (ii = 0; ii < rnsl.size(); ++ii) {
106 G4double sl = rnsl[ii].second;
107 slSum += sl;
108#ifdef VERBOSE_ENERSPLIT
109 if (verbose)
110 G4cout << "G4EnergySplitter::SplitEnergyInVolumes" << ii << " RN: iter1 step length geom "
111 << sl << G4endl;
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 "
119 << aStep->GetPreStepPoint()->GetKineticEnergy() << " Material "
120 << aStep->GetPreStepPoint()->GetMaterial()->GetName() << " Number of geom steps "
121 << rnsl.size() << G4endl;
122#endif
123 //----- No iterations to correct elost and msc => distribute energy deposited according to
124 // geometrical step length in each voxel
125 if (theNIterations == 0) {
126 for (ii = 0; ii < rnsl.size(); ++ii) {
127 G4double sl = rnsl[ii].second;
128 G4double edepStep = edep * sl / slSum; // divide edep along steps, proportional to step
129 // length
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 { // 1 or more iterations demanded
139
140#ifdef VERBOSE_ENERSPLIT
141 // print corrected energy at iteration 0
142 if (verbose) {
143 G4double slSum = 0.;
144 for (ii = 0; ii < rnsl.size(); ++ii) {
145 G4double sl = rnsl[ii].second;
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
159 << G4endl;
160#endif
161
162 //--- energy at each interaction
163 G4EmCalculator emcalc;
164 G4double totalELost = 0.;
165 std::vector<G4double> stepLengths;
166 for (G4int iiter = 1; iiter <= theNIterations; ++iiter) {
167 //--- iter1: distribute true step length in each voxel: geom SL in each voxel is multiplied by
168 // a constant so that the sum gives the total true step length
169 if (iiter == 1) {
170 for (ii = 0; ii < rnsl.size(); ++ii) {
171 G4double sl = rnsl[ii].second;
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);
182 G4double dEdx = 0.;
183 if (kinEnergyPre > 0.) { // t check this
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 //------ 2nd and other iterations
201 //----- Get step lengths corrected by changing geom2true correction
202 //-- Get ratios for each energy
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 // Correct step lengths so that they sum the total step length
221 G4double slratio = aStep->GetStepLength() / slSum;
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 //---- Recalculate energy lost with this new step lengths
237 kinEnergyPre = aStep->GetPreStepPoint()->GetKineticEnergy();
238 totalELost = 0.;
239 for (ii = 0; ii < rnsl.size(); ++ii) {
240 const G4Material* mate = thePhantomParam->GetMaterial(rnsl[ii].first);
241 G4double dEdx = 0.;
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 // correct energies so that they reproduce the real step energy lost
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
268 G4double elostTot = 0.;
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}
@ FatalException
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
#define G4endl
Definition G4ios.hh:67
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)
G4Material * GetMaterial() const
G4VPhysicalVolume * GetPhysicalVolume() const
G4double GetKineticEnergy() const
G4Track * GetTrack() const
G4StepPoint * GetPreStepPoint() const
G4double GetStepLength() const
G4double GetTotalEnergyDeposit() const
G4ParticleDefinition * GetDefinition() const

The documentation for this class was generated from the following files: