Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PolarizedIonisation.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// Geant4 Class file
29//
30// File name: G4PolarizedIonisation
31//
32// Author: A.Schaelicke on base of Vladimir Ivanchenko code
33
35
36#include "G4Electron.hh"
37#include "G4EmParameters.hh"
42#include "G4Positron.hh"
44#include "G4StokesVector.hh"
45#include "G4SystemOfUnits.hh"
46#include "G4UnitsTable.hh"
48
49//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
52 , fAsymmetryTable(nullptr)
53 , fTransverseAsymmetryTable(nullptr)
54 , fIsElectron(true)
55 , fIsInitialised(false)
56{
57 verboseLevel = 0;
60 fFlucModel = nullptr;
61 fEmModel = nullptr;
62}
63
64//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
66
67//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
68void G4PolarizedIonisation::ProcessDescription(std::ostream& out) const
69{
70 out << "Polarized version of G4eIonisation.\n";
71
73}
74
75//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
76void G4PolarizedIonisation::CleanTables()
77{
78 if(fAsymmetryTable)
79 {
80 fAsymmetryTable->clearAndDestroy();
81 delete fAsymmetryTable;
82 fAsymmetryTable = nullptr;
83 }
84 if(fTransverseAsymmetryTable)
85 {
86 fTransverseAsymmetryTable->clearAndDestroy();
87 delete fTransverseAsymmetryTable;
88 fTransverseAsymmetryTable = nullptr;
89 }
90}
91
92//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
94 const G4Material*,
95 G4double cut)
96{
97 G4double x = cut;
98 if(fIsElectron)
99 {
100 x += cut;
101 }
102 return x;
103}
104
105//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
107{
108 return (&p == G4Electron::Electron() || &p == G4Positron::Positron());
109}
110//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
112 const G4ParticleDefinition* part, const G4ParticleDefinition*)
113{
114 if(!fIsInitialised)
115 {
116 if(part == G4Positron::Positron())
117 {
118 fIsElectron = false;
119 }
120
121 if(!FluctModel())
122 {
124 }
125 fFlucModel = FluctModel();
126
127 fEmModel = new G4PolarizedIonisationModel();
128 SetEmModel(fEmModel);
130 fEmModel->SetLowEnergyLimit(param->MinKinEnergy());
131 fEmModel->SetHighEnergyLimit(param->MaxKinEnergy());
132 AddEmModel(1, fEmModel, fFlucModel);
133
134 fIsInitialised = true;
135 }
136}
137
138//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
140 G4double step,
141 G4ForceCondition* cond)
142{
143 // *** get unploarised mean free path from lambda table ***
144 G4double mfp = G4VEnergyLossProcess::GetMeanFreePath(track, step, cond);
145 if(fAsymmetryTable && fTransverseAsymmetryTable && mfp < DBL_MAX)
146 {
147 mfp *= ComputeSaturationFactor(track);
148 }
149 if(verboseLevel >= 2)
150 {
151 G4cout << "G4PolarizedIonisation::MeanFreePath: " << mfp / mm << " mm "
152 << G4endl;
153 }
154 return mfp;
155}
156
157//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
159 const G4Track& track, G4double step, G4ForceCondition* cond)
160{
161 // save previous values
164
165 // *** get unpolarised mean free path from lambda table ***
166 // this changes theNumberOfInteractionLengthLeft and currentInteractionLength
168 track, step, cond);
169 G4double x0 = x;
170 G4double satFact = 1.;
171
172 // *** add corrections on polarisation ***
173 if(fAsymmetryTable && fTransverseAsymmetryTable && x < DBL_MAX)
174 {
175 satFact = ComputeSaturationFactor(track);
176 G4double curLength = currentInteractionLength * satFact;
177 G4double prvLength = iLength * satFact;
178 if(nLength > 0.0)
179 {
181 std::max(nLength - step / prvLength, 0.0);
182 }
183 x = theNumberOfInteractionLengthLeft * curLength;
184 }
185 if(verboseLevel >= 2)
186 {
187 G4cout << "G4PolarizedIonisation::PostStepGPIL: " << std::setprecision(8)
188 << x / mm << " mm;" << G4endl
189 << " unpolarized value: " << std::setprecision(8)
190 << x0 / mm << " mm." << G4endl;
191 }
192 return x;
193}
194
195//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
196G4double G4PolarizedIonisation::ComputeSaturationFactor(const G4Track& track)
197{
198 const G4Material* aMaterial = track.GetMaterial();
199 G4VPhysicalVolume* aPVolume = track.GetVolume();
200 G4LogicalVolume* aLVolume = aPVolume->GetLogicalVolume();
201
202 G4PolarizationManager* polarizationManager =
204
205 const G4bool volumeIsPolarized = polarizationManager->IsPolarized(aLVolume);
206 G4StokesVector volPolarization =
207 polarizationManager->GetVolumePolarization(aLVolume);
208
209 G4double factor = 1.0;
210
211 if(volumeIsPolarized && !volPolarization.IsZero())
212 {
213 // *** get asymmetry, if target is polarized ***
214 const G4DynamicParticle* aDynamicPart = track.GetDynamicParticle();
215 const G4double energy = aDynamicPart->GetKineticEnergy();
216 const G4StokesVector polarization = G4StokesVector(track.GetPolarization());
217 const G4ParticleMomentum direction0 = aDynamicPart->GetMomentumDirection();
218
219 if(verboseLevel >= 2)
220 {
221 G4cout << "G4PolarizedIonisation::ComputeSaturationFactor: " << G4endl;
222 G4cout << " Energy(MeV) " << energy / MeV << G4endl;
223 G4cout << " Direction " << direction0 << G4endl;
224 G4cout << " Polarization " << polarization << G4endl;
225 G4cout << " MaterialPol. " << volPolarization << G4endl;
226 G4cout << " Phys. Volume " << aPVolume->GetName() << G4endl;
227 G4cout << " Log. Volume " << aLVolume->GetName() << G4endl;
228 G4cout << " Material " << aMaterial << G4endl;
229 }
230
231 std::size_t midx = CurrentMaterialCutsCoupleIndex();
232 const G4PhysicsVector* aVector = nullptr;
233 const G4PhysicsVector* bVector = nullptr;
234 if(midx < fAsymmetryTable->size())
235 {
236 aVector = (*fAsymmetryTable)(midx);
237 }
238 if(midx < fTransverseAsymmetryTable->size())
239 {
240 bVector = (*fTransverseAsymmetryTable)(midx);
241 }
242 if(aVector && bVector)
243 {
244 G4double lAsymmetry = aVector->Value(energy);
245 G4double tAsymmetry = bVector->Value(energy);
246 G4double polZZ = polarization.z() * (volPolarization * direction0);
247 G4double polXX =
248 polarization.x() *
249 (volPolarization * G4PolarizationHelper::GetParticleFrameX(direction0));
250 G4double polYY =
251 polarization.y() *
252 (volPolarization * G4PolarizationHelper::GetParticleFrameY(direction0));
253
254 factor /= (1. + polZZ * lAsymmetry + (polXX + polYY) * tAsymmetry);
255
256 if(verboseLevel >= 2)
257 {
258 G4cout << " Asymmetry: " << lAsymmetry << ", " << tAsymmetry
259 << G4endl;
260 G4cout << " PolProduct: " << polXX << ", " << polYY << ", " << polZZ
261 << G4endl;
262 G4cout << " Factor: " << factor << G4endl;
263 }
264 }
265 else
266 {
268 ed << "Problem with asymmetry tables: material index " << midx
269 << " is out of range or tables are not filled";
270 G4Exception("G4PolarizedIonisation::ComputeSaturationFactor", "em0048",
271 JustWarning, ed, "");
272 }
273 }
274 return factor;
275}
276
277//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
279{
280 // *** build DEDX and (unpolarized) cross section tables
282 G4bool master = true;
283 const G4PolarizedIonisation* masterProcess =
284 static_cast<const G4PolarizedIonisation*>(GetMasterProcess());
285 if(masterProcess && masterProcess != this)
286 {
287 master = false;
288 }
289 if(master)
290 {
291 BuildAsymmetryTables(part);
292 }
293}
294
295//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
296void G4PolarizedIonisation::BuildAsymmetryTables(
297 const G4ParticleDefinition& part)
298{
299 // cleanup old, initialise new table
300 CleanTables();
301 fAsymmetryTable = G4PhysicsTableHelper::PreparePhysicsTable(fAsymmetryTable);
302 fTransverseAsymmetryTable =
303 G4PhysicsTableHelper::PreparePhysicsTable(fTransverseAsymmetryTable);
304
305 const G4ProductionCutsTable* theCoupleTable =
307 G4int numOfCouples = (G4int)theCoupleTable->GetTableSize();
308
309 for(G4int j = 0; j < numOfCouples; ++j)
310 {
311 // get cut value
312 const G4MaterialCutsCouple* couple =
313 theCoupleTable->GetMaterialCutsCouple(j);
314
315 G4double cut = (*theCoupleTable->GetEnergyCutsVector(1))[j];
316
317 // create physics vectors then fill it (same parameters as lambda vector)
318 G4PhysicsVector* ptrVectorA = LambdaPhysicsVector(couple, cut);
319 G4PhysicsVector* ptrVectorB = LambdaPhysicsVector(couple, cut);
320 std::size_t bins = ptrVectorA->GetVectorLength();
321
322 for(std::size_t i = 0; i < bins; ++i)
323 {
324 G4double lowEdgeEnergy = ptrVectorA->Energy(i);
325 G4double tasm = 0.;
326 G4double asym = ComputeAsymmetry(lowEdgeEnergy, couple, part, cut, tasm);
327 ptrVectorA->PutValue(i, asym);
328 ptrVectorB->PutValue(i, tasm);
329 }
330 fAsymmetryTable->insertAt(j, ptrVectorA);
331 fTransverseAsymmetryTable->insertAt(j, ptrVectorB);
332 }
333}
334
335//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
336G4double G4PolarizedIonisation::ComputeAsymmetry(
337 G4double energy, const G4MaterialCutsCouple* couple,
338 const G4ParticleDefinition& aParticle, G4double cut, G4double& tAsymmetry)
339{
340 G4double lAsymmetry = 0.0;
341 tAsymmetry = 0.0;
342 if(fIsElectron)
343 {
344 lAsymmetry = tAsymmetry = -1.0;
345 }
346
347 // calculate polarized cross section
348 G4ThreeVector targetPolarization = G4ThreeVector(0., 0., 1.);
349 fEmModel->SetTargetPolarization(targetPolarization);
350 fEmModel->SetBeamPolarization(targetPolarization);
351 G4double sigma2 =
352 fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
353
354 // calculate transversely polarized cross section
355 targetPolarization = G4ThreeVector(1., 0., 0.);
356 fEmModel->SetTargetPolarization(targetPolarization);
357 fEmModel->SetBeamPolarization(targetPolarization);
358 G4double sigma3 =
359 fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
360
361 // calculate unpolarized cross section
362 targetPolarization = G4ThreeVector();
363 fEmModel->SetTargetPolarization(targetPolarization);
364 fEmModel->SetBeamPolarization(targetPolarization);
365 G4double sigma0 =
366 fEmModel->CrossSection(couple, &aParticle, energy, cut, energy);
367 // determine asymmetries
368 if(sigma0 > 0.)
369 {
370 lAsymmetry = sigma2 / sigma0 - 1.;
371 tAsymmetry = sigma3 / sigma0 - 1.;
372 }
373 if(std::fabs(lAsymmetry) > 1.)
374 {
376 ed << "G4PolarizedIonisation::ComputeAsymmetry : E(MeV)= " << energy
377 << " lAsymmetry= " << lAsymmetry << " (" << std::fabs(lAsymmetry) - 1.
378 << ")";
379 G4Exception("G4PolarizedIonisation::ComputeAsymmetry", "pol002",
380 JustWarning, ed);
381 }
382 if(std::fabs(tAsymmetry) > 1.)
383 {
385 ed << "G4PolarizedIonisation::ComputeAsymmetry : E(MeV)= " << energy
386 << " tAsymmetry= " << tAsymmetry << " (" << std::fabs(tAsymmetry) - 1.
387 << ")";
388 G4Exception("G4PolarizedIonisation::ComputeAsymmetry", "pol003",
389 JustWarning, ed);
390 }
391 return lAsymmetry;
392}
@ fIonisation
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4ForceCondition
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
double z() const
double x() const
double y() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
static G4Electron * Electron()
Definition: G4Electron.cc:93
static G4EmParameters * Instance()
G4double MinKinEnergy() const
G4double MaxKinEnergy() const
const G4String & GetName() const
static G4PhysicsTable * PreparePhysicsTable(G4PhysicsTable *physTable)
void clearAndDestroy()
void insertAt(std::size_t, G4PhysicsVector *)
void PutValue(const std::size_t index, const G4double value)
G4double Energy(const std::size_t index) const
G4double Value(const G4double energy, std::size_t &lastidx) const
std::size_t GetVectorLength() const
static G4ThreeVector GetParticleFrameY(const G4ThreeVector &)
static G4ThreeVector GetParticleFrameX(const G4ThreeVector &)
bool IsPolarized(G4LogicalVolume *lVol) const
const G4StokesVector GetVolumePolarization(G4LogicalVolume *lVol) const
static G4PolarizationManager * GetInstance()
void SetTargetPolarization(const G4ThreeVector &pTarget)
void SetBeamPolarization(const G4ThreeVector &pBeam)
virtual G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
virtual G4double MinPrimaryEnergy(const G4ParticleDefinition *, const G4Material *, G4double cut) override
G4PolarizedIonisation(const G4String &name="pol-eIoni")
virtual void ProcessDescription(std::ostream &) const override
virtual void BuildPhysicsTable(const G4ParticleDefinition &) override
virtual ~G4PolarizedIonisation() override
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
virtual void InitialiseEnergyLossProcess(const G4ParticleDefinition *, const G4ParticleDefinition *) override
virtual G4bool IsApplicable(const G4ParticleDefinition &p) override
static G4Positron * Positron()
Definition: G4Positron.cc:93
const G4MaterialCutsCouple * GetMaterialCutsCouple(G4int i) const
std::size_t GetTableSize() const
const std::vector< G4double > * GetEnergyCutsVector(std::size_t pcIdx) const
static G4ProductionCutsTable * GetProductionCutsTable()
G4bool IsZero() const
G4VPhysicalVolume * GetVolume() const
G4Material * GetMaterial() const
const G4DynamicParticle * GetDynamicParticle() const
const G4ThreeVector & GetPolarization() const
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:746
void SetLowEnergyLimit(G4double)
Definition: G4VEmModel.hh:753
G4double CrossSection(const G4MaterialCutsCouple *, const G4ParticleDefinition *, G4double kineticEnergy, G4double cutEnergy=0.0, G4double maxEnergy=DBL_MAX)
Definition: G4VEmModel.hh:520
void AddEmModel(G4int, G4VEmModel *, G4VEmFluctuationModel *fluc=nullptr, const G4Region *region=nullptr)
void SetFluctModel(G4VEmFluctuationModel *)
G4PhysicsVector * LambdaPhysicsVector(const G4MaterialCutsCouple *, G4double cut)
void ProcessDescription(std::ostream &outFile) const override
std::size_t CurrentMaterialCutsCoupleIndex() const
G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
void SetEmModel(G4VEmModel *, G4int index=0)
G4double GetMeanFreePath(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition) override
G4VEmFluctuationModel * FluctModel() const
void BuildPhysicsTable(const G4ParticleDefinition &) override
void SetSecondaryParticle(const G4ParticleDefinition *p)
G4LogicalVolume * GetLogicalVolume() const
const G4String & GetName() const
G4double currentInteractionLength
Definition: G4VProcess.hh:339
const G4VProcess * GetMasterProcess() const
Definition: G4VProcess.hh:522
G4int verboseLevel
Definition: G4VProcess.hh:360
G4double theNumberOfInteractionLengthLeft
Definition: G4VProcess.hh:335
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:410
G4double energy(const ThreeVector &p, const G4double m)
#define DBL_MAX
Definition: templates.hh:62