145{
146 const G4Track* aTrack = fParticleChange->GetCurrentTrack();
147
148
149 fParticleChange->SetProposedKineticEnergy(0.);
151
152
154
155 if(PositKinEnergy == 0.0)
156 {
158 G4double sinTeta = std::sqrt((1.0 - cosTeta) * (1.0 + cosTeta));
160 G4ThreeVector dir(sinTeta * std::cos(phi), sinTeta * std::sin(phi),
161 cosTeta);
162 fvect->push_back(
164 fvect->push_back(
166 return;
167 }
168
169
170 G4PolarizationManager* polarizationManager =
172
173
175
176
177 G4VPhysicalVolume* aPVolume = aTrack->
GetVolume();
181
182 if(fVerboseLevel >= 1)
183 {
184 G4cout <<
"G4PolarizedComptonModel::SampleSecondaries in "
186 }
187
188
189 if(targetIsPolarized)
191
193
194
195 G4double polarization = fBeamPolarization.p3() * fTargetPolarization.p3();
196
197 G4double gamam1 = PositKinEnergy / electron_mass_c2;
198 G4double gama = gamam1 + 1., gamap1 = gamam1 + 2.;
199 G4double sqgrate = std::sqrt(gamam1 / gamap1) / 2.,
200 sqg2m1 = std::sqrt(gamam1 * gamap1);
201
202
203 G4double epsilmin = 0.5 - sqgrate, epsilmax = 0.5 + sqgrate;
204 G4double epsilqot = epsilmax / epsilmin;
205
206
207
208
210 G4double gmax = 1. + std::fabs(polarization);
211
212 fCrossSectionCalculator->Initialize(epsilmin, gama, 0., fBeamPolarization,
213 fTargetPolarization);
214 if(fCrossSectionCalculator->DiceEpsilon() < 0.)
215 {
217 ed << "ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
218 << "epsilmin DiceRoutine not appropriate ! "
219 << fCrossSectionCalculator->DiceEpsilon() <<
G4endl;
220 G4Exception(
"G4PolarizedAnnihilationModel::SampleSecondaries",
"pol006",
222 }
223
224 fCrossSectionCalculator->Initialize(epsilmax, gama, 0., fBeamPolarization,
225 fTargetPolarization);
226 if(fCrossSectionCalculator->DiceEpsilon() < 0)
227 {
229 ed << "ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
230 << "epsilmax DiceRoutine not appropriate ! "
231 << fCrossSectionCalculator->DiceEpsilon() <<
G4endl;
232 G4Exception(
"G4PolarizedAnnihilationModel::SampleSecondaries",
"pol007",
234 }
235
239
240 do
241 {
243
244 fCrossSectionCalculator->Initialize(epsil, gama, 0., fBeamPolarization,
245 fTargetPolarization, 1);
246
247 treject = fCrossSectionCalculator->DiceEpsilon();
248 treject *= epsil;
249
250 if(treject > gmax || treject < 0.)
251 {
253 ed << "ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
254 << " eps (" << epsil
255 <<
") rejection does not work properly: " << treject <<
G4endl;
256 G4Exception(
"G4PolarizedAnnihilationModel::SampleSecondaries",
"pol008",
258 }
259 ++ncount;
260 if(treject > trejectmax)
261 trejectmax = treject;
262 if(ncount > 1000)
263 {
265 ed << "WARNING in PolarizedAnnihilationPS::PostStepDoIt\n"
266 << "eps dicing very inefficient =" << trejectmax / gmax << ", "
267 << treject / gmax << ". For secondary energy = " << epsil << " "
269 G4Exception(
"G4PolarizedAnnihilationModel::SampleSecondaries",
"pol009",
271 break;
272 }
273
274
276
277
278 G4double cost = (epsil * gamap1 - 1.) / (epsil * sqg2m1);
279 G4double sint = std::sqrt((1. + cost) * (1. - cost));
282 std::sqrt(
sqr(fBeamPolarization.p1()) +
sqr(fBeamPolarization.p2()));
284 std::sqrt(
sqr(fTargetPolarization.p1()) +
sqr(fTargetPolarization.p2()));
285
286 do
287 {
289 fCrossSectionCalculator->Initialize(epsil, gama, 0., fBeamPolarization,
290 fTargetPolarization, 2);
291
292 G4double gdiced = fCrossSectionCalculator->getVar(0);
293 gdiced += fCrossSectionCalculator->getVar(3) * fBeamPolarization.p3() *
294 fTargetPolarization.p3();
295 gdiced += 1. *
296 (std::fabs(fCrossSectionCalculator->getVar(1)) +
297 std::fabs(fCrossSectionCalculator->getVar(2))) *
298 beamTrans * targetTrans;
299 gdiced += 1. * std::fabs(fCrossSectionCalculator->getVar(4)) *
300 (std::fabs(fBeamPolarization.p3()) * targetTrans +
301 std::fabs(fTargetPolarization.p3()) * beamTrans);
302
303 G4double gdist = fCrossSectionCalculator->getVar(0);
304 gdist += fCrossSectionCalculator->getVar(3) * fBeamPolarization.p3() *
305 fTargetPolarization.p3();
306 gdist += fCrossSectionCalculator->getVar(1) *
307 (std::cos(phi) * fBeamPolarization.p1() +
308 std::sin(phi) * fBeamPolarization.p2()) *
309 (std::cos(phi) * fTargetPolarization.p1() +
310 std::sin(phi) * fTargetPolarization.p2());
311 gdist += fCrossSectionCalculator->getVar(2) *
312 (std::cos(phi) * fBeamPolarization.p2() -
313 std::sin(phi) * fBeamPolarization.p1()) *
314 (std::cos(phi) * fTargetPolarization.p2() -
315 std::sin(phi) * fTargetPolarization.p1());
316 gdist +=
317 fCrossSectionCalculator->getVar(4) *
318 (std::cos(phi) * fBeamPolarization.p3() * fTargetPolarization.p1() +
319 std::cos(phi) * fBeamPolarization.p1() * fTargetPolarization.p3() +
320 std::sin(phi) * fBeamPolarization.p3() * fTargetPolarization.p2() +
321 std::sin(phi) * fBeamPolarization.p2() * fTargetPolarization.p3());
322
323 treject = gdist / gdiced;
324 if(treject > 1. + 1.e-10 || treject < 0)
325 {
327 ed << "!!!ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
328 <<
" phi rejection does not work properly: " << treject <<
G4endl;
332 G4Exception(
"G4PolarizedAnnihilationModel::SampleSecondaries",
"pol009",
334 }
335
336 if(treject < 1.e-3)
337 {
339 ed << "!!!ERROR in PolarizedAnnihilationPS::PostStepDoIt\n"
340 << " phi rejection does not work properly: " << treject << "\n";
341 G4cout <<
" gdiced=" << gdiced <<
" gdist=" << gdist <<
"\n";
343 G4Exception(
"G4PolarizedAnnihilationModel::SampleSecondaries",
"pol010",
345 }
346
347
349
350 G4double dirx = sint * std::cos(phi);
351 G4double diry = sint * std::sin(phi);
353
354
355 G4double TotalAvailableEnergy = PositKinEnergy + 2 * electron_mass_c2;
356 G4double Phot1Energy = epsil * TotalAvailableEnergy;
357 G4double Phot2Energy = (1. - epsil) * TotalAvailableEnergy;
358
359
361
362
365
366
367 fBeamPolarization.InvRotateAz(nInteractionFrame, PositDirection);
368 fTargetPolarization.InvRotateAz(nInteractionFrame, PositDirection);
369
370
371
372 fCrossSectionCalculator->Initialize(epsil, gama, phi, fBeamPolarization,
373 fTargetPolarization, 2);
374
375 Phot1Direction.rotateUz(PositDirection);
376
377 G4DynamicParticle* aParticle1 =
378 new G4DynamicParticle(
G4Gamma::Gamma(), Phot1Direction, Phot1Energy);
379 fFinalGamma1Polarization = fCrossSectionCalculator->GetPol2();
380 G4double n1 = fFinalGamma1Polarization.mag2();
381 if(n1 > 1.)
382 {
384 ed << "ERROR: PolarizedAnnihilation Polarization Vector at epsil = "
385 << epsil << " is too large!!! \n"
386 << "annihi pol1= " << fFinalGamma1Polarization << ", (" << n1 << ")\n";
387 fFinalGamma1Polarization *= 1. / std::sqrt(n1);
388 G4Exception(
"G4PolarizedAnnihilationModel::SampleSecondaries",
"pol011",
390 }
391
392
393 fFinalGamma1Polarization.SetPhoton();
394 fFinalGamma1Polarization.RotateAz(nInteractionFrame, Phot1Direction);
396 fFinalGamma1Polarization.p2(),
397 fFinalGamma1Polarization.p3());
398
399 fvect->push_back(aParticle1);
400
401
402
403 G4double Eratio = Phot1Energy / Phot2Energy;
405 std::sqrt(PositKinEnergy * (PositKinEnergy + 2. * electron_mass_c2));
407 (PositP - dirz * Phot1Energy) / Phot2Energy);
408 Phot2Direction.rotateUz(PositDirection);
409
410 G4DynamicParticle* aParticle2 =
411 new G4DynamicParticle(
G4Gamma::Gamma(), Phot2Direction, Phot2Energy);
412
413
414 fFinalGamma2Polarization = fCrossSectionCalculator->GetPol3();
415 G4double n2 = fFinalGamma2Polarization.mag2();
416 if(n2 > 1.)
417 {
419 ed << "ERROR: PolarizedAnnihilation Polarization Vector at epsil = "
420 << epsil << " is too large!!! \n";
421 ed << "annihi pol2= " << fFinalGamma2Polarization << ", (" << n2 << ")\n";
422
423 G4Exception(
"G4PolarizedAnnihilationModel::SampleSecondaries",
"pol012",
425 fFinalGamma2Polarization *= 1. / std::sqrt(n2);
426 }
427 fFinalGamma2Polarization.SetPhoton();
428 fFinalGamma2Polarization.RotateAz(nInteractionFrame, Phot2Direction);
430 fFinalGamma2Polarization.p2(),
431 fFinalGamma2Polarization.p3());
432
433 fvect->push_back(aParticle2);
434}
G4ThreeVector G4ParticleMomentum
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
Hep3Vector & rotateUz(const Hep3Vector &)
void SetPolarization(const G4ThreeVector &)
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
const G4String & GetName() const
static G4ThreeVector GetFrame(const G4ThreeVector &, const G4ThreeVector &)
bool IsPolarized(G4LogicalVolume *lVol) const
const G4StokesVector GetVolumePolarization(G4LogicalVolume *lVol) const
static G4PolarizationManager * GetInstance()
G4VPhysicalVolume * GetVolume() const
const G4ThreeVector & GetPolarization() const
G4LogicalVolume * GetLogicalVolume() const