Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4AdjointPrimaryGeneratorAction.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27/////////////////////////////////////////////////////////////////////////////
28// Class Name: G4AdjointPrimaryGeneratorAction
29// Author: L. Desorgher
30// Organisation: SpaceIT GmbH
31// Contract: ESA contract 21435/08/NL/AT
32// Customer: ESA/ESTEC
33/////////////////////////////////////////////////////////////////////////////
34
36
39#include "G4Event.hh"
40#include "G4Gamma.hh"
42#include "G4ParticleTable.hh"
44
45/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46//
48 : Emin(0.)
49 , Emax(0.)
50 , EminIon(0.)
51 , EmaxIon(0.)
52 , index_particle(100000)
53 , radius_spherical_source(0.)
54 , fwd_ion(0)
55 , adj_ion(0)
56 , ion_name("not_defined")
57{
58 theAdjointPrimaryGenerator = new G4AdjointPrimaryGenerator();
59
60 PrimariesConsideredInAdjointSim[G4String("e-")] = false;
61 PrimariesConsideredInAdjointSim[G4String("gamma")] = false;
62 PrimariesConsideredInAdjointSim[G4String("proton")] = false;
63 PrimariesConsideredInAdjointSim[G4String("ion")] = false;
64
65 ListOfPrimaryFwdParticles.clear();
66 ListOfPrimaryAdjParticles.clear();
67 nb_fwd_gammas_per_event = 1;
68 nb_adj_primary_gammas_per_event = 1;
69 nb_adj_primary_electrons_per_event = 1;
70}
71/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
72//
74{
75 delete theAdjointPrimaryGenerator;
76}
77/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
78//
80{
81 G4int evt_id = anEvent->GetEventID();
82 size_t n = ListOfPrimaryAdjParticles.size();
83 index_particle = size_t(evt_id) - n * (size_t(evt_id) / n);
84
85 G4double E1 = Emin;
86 G4double E2 = Emax;
87 if(!ListOfPrimaryAdjParticles[index_particle])
88 UpdateListOfPrimaryParticles(); // ion has not been created yet
89
90 if(ListOfPrimaryAdjParticles[index_particle]->GetParticleName() ==
91 "adj_proton")
92 {
93 E1 = EminIon;
94 E2 = EmaxIon;
95 }
96 if(ListOfPrimaryAdjParticles[index_particle]->GetParticleType() ==
97 "adjoint_nucleus")
98 {
99 G4int A = ListOfPrimaryAdjParticles[index_particle]->GetAtomicMass();
100 E1 = EminIon * A;
101 E2 = EmaxIon * A;
102 }
103 // Generate first the forwrad primaries
104 theAdjointPrimaryGenerator->GenerateFwdPrimaryVertex(
105 anEvent, ListOfPrimaryFwdParticles[index_particle], E1, E2);
106 G4PrimaryVertex* fwdPrimVertex = anEvent->GetPrimaryVertex();
107
108 p = fwdPrimVertex->GetPrimary()->GetMomentum();
109 pos = fwdPrimVertex->GetPosition();
110 G4double pmag = p.mag();
111 G4double m0 = ListOfPrimaryFwdParticles[index_particle]->GetPDGMass();
112 G4double ekin = std::sqrt(m0 * m0 + pmag * pmag) - m0;
113
114 G4double weight_correction = 1.;
115 // For gamma generate the particle along the backward ray
116 G4ThreeVector dir = -p / p.mag();
117
118 /*if (ListOfPrimaryAdjParticles[index_particle]->GetParticleName() ==
119 "adj_gamma"){
120
121 theAdjointPrimaryGenerator
122 ->ComputeAccumulatedDepthVectorAlongBackRay(pos,dir,ekin,ListOfPrimaryAdjParticles[index_particle]);
123
124
125 G4double distance = theAdjointPrimaryGenerator
126 ->SampleDistanceAlongBackRayAndComputeWeightCorrection(weight_correction);
127
128 //pos=pos+dir*distance;
129 //fwdPrimVertex->SetPosition(pos[0],pos[1],pos[2]);
130 }
131 */
132 weight_correction = 1.;
133
134 if(ListOfPrimaryFwdParticles[index_particle] == G4Gamma::Gamma() &&
135 nb_fwd_gammas_per_event > 1)
136 {
137 G4double weight = (1. / nb_fwd_gammas_per_event);
138 fwdPrimVertex->SetWeight(weight);
139 for(int i = 0; i < nb_fwd_gammas_per_event - 1; i++)
140 {
141 G4PrimaryVertex* newFwdPrimVertex = new G4PrimaryVertex();
142 newFwdPrimVertex->SetPosition(pos.x(), pos.y(), pos.z());
143 newFwdPrimVertex->SetT0(0.);
144 G4PrimaryParticle* aPrimParticle = new G4PrimaryParticle(
145 ListOfPrimaryFwdParticles[index_particle], p.x(), p.y(), p.z());
146 newFwdPrimVertex->SetPrimary(aPrimParticle);
147 newFwdPrimVertex->SetWeight(weight);
148 anEvent->AddPrimaryVertex(newFwdPrimVertex);
149 }
150 }
151
152 // Now generate the adjoint primaries
153 G4PrimaryVertex* adjPrimVertex = new G4PrimaryVertex();
154 adjPrimVertex->SetPosition(pos.x(), pos.y(), pos.z());
155 adjPrimVertex->SetT0(0.);
156 G4PrimaryParticle* aPrimParticle = new G4PrimaryParticle(
157 ListOfPrimaryAdjParticles[index_particle], -p.x(), -p.y(), -p.z());
158
159 adjPrimVertex->SetPrimary(aPrimParticle);
160 anEvent->AddPrimaryVertex(adjPrimVertex);
161
162 // The factor pi is to normalise the weight to the directional flux
163 G4double adjoint_source_area =
165 G4double adjoint_weight = weight_correction *
166 ComputeEnergyDistWeight(ekin, E1, E2) *
167 adjoint_source_area * pi;
168 // if (ListOfPrimaryFwdParticles[index_particle] ==G4Gamma::Gamma())
169 // adjoint_weight = adjoint_weight/3.;
170 if(ListOfPrimaryAdjParticles[index_particle]->GetParticleName() ==
171 "adj_gamma")
172 {
173 // The weight will be corrected at the end of the track if splitted tracks
174 // are used
175 adjoint_weight = adjoint_weight / nb_adj_primary_gammas_per_event;
176 for(int i = 0; i < nb_adj_primary_gammas_per_event - 1; i++)
177 {
178 G4PrimaryVertex* newAdjPrimVertex = new G4PrimaryVertex();
179 newAdjPrimVertex->SetPosition(pos.x(), pos.y(), pos.z());
180 newAdjPrimVertex->SetT0(0.);
181 aPrimParticle = new G4PrimaryParticle(
182 ListOfPrimaryAdjParticles[index_particle], -p.x(), -p.y(), -p.z());
183 newAdjPrimVertex->SetPrimary(aPrimParticle);
184 newAdjPrimVertex->SetWeight(adjoint_weight);
185 anEvent->AddPrimaryVertex(newAdjPrimVertex);
186 }
187 }
188 else if(ListOfPrimaryAdjParticles[index_particle]->GetParticleName() ==
189 "adj_electron")
190 {
191 // The weight will be corrected at the end of the track if splitted tracks
192 // are used
193 adjoint_weight = adjoint_weight / nb_adj_primary_electrons_per_event;
194 for(int i = 0; i < nb_adj_primary_electrons_per_event - 1; i++)
195 {
196 G4PrimaryVertex* newAdjPrimVertex = new G4PrimaryVertex();
197 newAdjPrimVertex->SetPosition(pos.x(), pos.y(), pos.z());
198 newAdjPrimVertex->SetT0(0.);
199 aPrimParticle = new G4PrimaryParticle(
200 ListOfPrimaryAdjParticles[index_particle], -p.x(), -p.y(), -p.z());
201 newAdjPrimVertex->SetPrimary(aPrimParticle);
202 newAdjPrimVertex->SetWeight(adjoint_weight);
203 anEvent->AddPrimaryVertex(newAdjPrimVertex);
204 }
205 }
206 adjPrimVertex->SetWeight(adjoint_weight);
207
208 // Call some methods of G4AdjointSimManager
213
214 /* if ( !last_generated_part_was_adjoint ) {
215
216 index_particle++;
217 if (index_particle >= ListOfPrimaryAdjParticles.size()) index_particle =0;
218
219
220 G4double E1=Emin;
221 G4double E2=Emax;
222 if (!ListOfPrimaryAdjParticles[index_particle])
223 UpdateListOfPrimaryParticles();//ion has not been created yet
224
225 if (ListOfPrimaryAdjParticles[index_particle]->GetParticleName() ==
226 "adj_proton") { E1=EminIon; E2=EmaxIon;
227 }
228 if (ListOfPrimaryAdjParticles[index_particle]->GetParticleType() ==
229 "adjoint_nucleus") { G4int A=
230 ListOfPrimaryAdjParticles[index_particle]->GetAtomicMass(); E1=EminIon*A;
231 E2=EmaxIon*A;
232 }
233 theAdjointPrimaryGenerator->GenerateAdjointPrimaryVertex(anEvent,
234 ListOfPrimaryAdjParticles[index_particle],
235 E1,E2);
236 G4PrimaryVertex* aPrimVertex = anEvent->GetPrimaryVertex();
237
238
239 p=aPrimVertex->GetPrimary()->GetMomentum();
240 pos=aPrimVertex->GetPosition();
241 G4double pmag=p.mag();
242
243 G4double m0=ListOfPrimaryAdjParticles[index_particle]->GetPDGMass();
244 G4double ekin=std::sqrt( m0*m0 + pmag*pmag) -m0;
245
246
247 //The factor pi is to normalise the weight to the directional flux
248 G4double adjoint_source_area =
249 G4AdjointSimManager::GetInstance()->GetAdjointSourceArea(); G4double
250 adjoint_weight = ComputeEnergyDistWeight(ekin,E1,E2)*adjoint_source_area*pi;
251
252 aPrimVertex->SetWeight(adjoint_weight);
253
254 last_generated_part_was_adjoint =true;
255 G4AdjointSimManager::GetInstance()->SetAdjointTrackingMode(true);
256 G4AdjointSimManager::GetInstance()->RegisterAdjointPrimaryWeight(adjoint_weight);
257 }
258 else {
259 //fwd particle equivalent to the last generated adjoint particle ios
260 generated G4PrimaryVertex* aPrimVertex = new G4PrimaryVertex();
261 aPrimVertex->SetPosition(pos.x(),pos.y(),pos.z());
262 aPrimVertex->SetT0(0.);
263 G4PrimaryParticle* aPrimParticle = new
264 G4PrimaryParticle(ListOfPrimaryFwdParticles[index_particle],
265 -p.x(),-p.y(),-p.z());
266
267 aPrimVertex->SetPrimary(aPrimParticle);
268 anEvent->AddPrimaryVertex(aPrimVertex);
269 last_generated_part_was_adjoint =false;
270 G4AdjointSimManager::GetInstance()->SetAdjointTrackingMode(false);
271 */
272}
273/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
274//
276{
277 Emin = val;
278 EminIon = val;
279}
280/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
281//
283{
284 Emax = val;
285 EmaxIon = val;
286}
287/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
288//
290{
291 EminIon = val;
292}
293/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
294//
296{
297 EmaxIon = val;
298}
299/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
300//
301G4double G4AdjointPrimaryGeneratorAction::ComputeEnergyDistWeight(G4double E,
302 G4double E1,
303 G4double E2)
304{
305 // We generate N numbers of primaries with a 1/E energy law distribution.
306 // We have therefore an energy distribution function
307 // f(E)=C/E (1)
308 // with C a constant that is such that
309 // N=Integral(f(E),E1,E2)=C.std::log(E2/E1) (2)
310 // Therefore from (2) we get
311 // C=N/ std::log(E2/E1) (3)
312 // and
313 // f(E)=N/ std::log(E2/E1)/E (4)
314 // For the adjoint simulation we need a energy distribution f'(E)=1..
315 // To get that we need therefore to apply a weight to the primary
316 // W=1/f(E)=E*std::log(E2/E1)/N
317 //
318 return std::log(E2 / E1) * E /
320}
321/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
322//
324 G4double radius, G4ThreeVector center_pos)
325{
326 radius_spherical_source = radius;
327 center_spherical_source = center_pos;
328 type_of_adjoint_source = "Spherical";
329 theAdjointPrimaryGenerator->SetSphericalAdjointPrimarySource(radius,
330 center_pos);
331}
332/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
333//
336{
337 type_of_adjoint_source = "ExternalSurfaceOfAVolume";
338 theAdjointPrimaryGenerator->SetAdjointPrimarySourceOnAnExtSurfaceOfAVolume(
339 volume_name);
340}
341/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
342//
344 const G4String& particle_name)
345{
346 if(PrimariesConsideredInAdjointSim.find(particle_name) !=
347 PrimariesConsideredInAdjointSim.end())
348 {
349 PrimariesConsideredInAdjointSim[particle_name] = true;
350 }
352}
353/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
354//
356 const G4String& particle_name)
357{
358 if(PrimariesConsideredInAdjointSim.find(particle_name) !=
359 PrimariesConsideredInAdjointSim.end())
360 {
361 PrimariesConsideredInAdjointSim[particle_name] = false;
362 }
364}
365/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
366//
368{
370 ListOfPrimaryFwdParticles.clear();
371 ListOfPrimaryAdjParticles.clear();
372 std::map<G4String, G4bool>::iterator iter;
373 for(iter = PrimariesConsideredInAdjointSim.begin();
374 iter != PrimariesConsideredInAdjointSim.end(); ++iter)
375 {
376 if(iter->second)
377 {
378 G4String fwd_particle_name = iter->first;
379 if(fwd_particle_name != "ion")
380 {
381 G4String adj_particle_name = G4String("adj_") + fwd_particle_name;
382 ListOfPrimaryFwdParticles.push_back(
383 theParticleTable->FindParticle(fwd_particle_name));
384 ListOfPrimaryAdjParticles.push_back(
385 theParticleTable->FindParticle(adj_particle_name));
386 /*
387 if ( fwd_particle_name == "gamma") {
388 for (G4int i=0;i<2;i++){
389 ListOfPrimaryFwdParticles.push_back(theParticleTable->FindParticle(fwd_particle_name));
390 ListOfPrimaryAdjParticles.push_back(theParticleTable->FindParticle(adj_particle_name));
391 }
392 }
393 */
394 }
395 else
396 {
397 if(fwd_ion)
398 {
399 ion_name = fwd_ion->GetParticleName();
400 G4String adj_ion_name = G4String("adj_") + ion_name;
401 ListOfPrimaryFwdParticles.push_back(fwd_ion);
402 ListOfPrimaryAdjParticles.push_back(adj_ion);
403 }
404 else
405 {
406 ListOfPrimaryFwdParticles.push_back(0);
407 ListOfPrimaryAdjParticles.push_back(0);
408 }
409 }
410 }
411 }
412}
413/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
414//
416 G4ParticleDefinition* adjointIon, G4ParticleDefinition* fwdIon)
417{
418 fwd_ion = fwdIon;
419 adj_ion = adjointIon;
421}
double A(double temperature)
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
double z() const
double x() const
double y() const
double mag() const
void ConsiderParticleAsPrimary(const G4String &particle_name)
void SetAdjointPrimarySourceOnAnExtSurfaceOfAVolume(const G4String &volume_name)
void SetSphericalAdjointPrimarySource(G4double radius, G4ThreeVector pos)
void NeglectParticleAsPrimary(const G4String &particle_name)
void SetPrimaryIon(G4ParticleDefinition *adjointIon, G4ParticleDefinition *fwdIon)
void SetSphericalAdjointPrimarySource(G4double radius, G4ThreeVector pos)
void SetAdjointPrimarySourceOnAnExtSurfaceOfAVolume(const G4String &v_name)
void GenerateFwdPrimaryVertex(G4Event *anEvt, G4ParticleDefinition *adj_part, G4double E1, G4double E2)
void SetAdjointTrackingMode(G4bool aBool)
void ResetDidOneAdjPartReachExtSourceDuringEvent()
static G4AdjointSimManager * GetInstance()
G4PrimaryVertex * GetPrimaryVertex(G4int i=0) const
Definition: G4Event.hh:137
G4int GetEventID() const
Definition: G4Event.hh:118
void AddPrimaryVertex(G4PrimaryVertex *aPrimaryVertex)
Definition: G4Event.hh:121
static G4Gamma * Gamma()
Definition: G4Gamma.cc:85
const G4String & GetParticleName() const
G4ParticleDefinition * FindParticle(G4int PDGEncoding)
static G4ParticleTable * GetParticleTable()
G4ThreeVector GetMomentum() const
void SetPosition(G4double x0, G4double y0, G4double z0)
G4ThreeVector GetPosition() const
void SetPrimary(G4PrimaryParticle *pp)
void SetWeight(G4double w)
void SetT0(G4double t0)
G4PrimaryParticle * GetPrimary(G4int i=0) const
std::size_t first(char) const