Geant4  10.01.p02
G4HadronicProcess.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 // $Id: G4HadronicProcess.cc 86863 2014-11-19 14:39:31Z gcosmo $
27 //
28 // -------------------------------------------------------------------
29 //
30 // GEANT4 Class source file
31 //
32 // G4HadronicProcess
33 //
34 // original by H.P.Wellisch
35 // J.L. Chuma, TRIUMF, 10-Mar-1997
36 //
37 // Modifications:
38 // 05-Jul-2010 V.Ivanchenko cleanup commented lines
39 // 20-Jul-2011 M.Kelsey -- null-pointer checks in DumpState()
40 // 24-Sep-2011 M.Kelsey -- Use envvar G4HADRONIC_RANDOM_FILE to save random
41 // engine state before each model call
42 // 18-Oct-2011 M.Kelsey -- Handle final-state cases in conservation checks.
43 // 14-Mar-2012 G.Folger -- enhance checks for conservation of energy, etc.
44 // 28-Jul-2012 M.Maire -- add function GetTargetDefinition()
45 // 14-Sep-2012 Inherit from RestDiscrete, use subtype code (now in ctor) to
46 // configure base-class
47 // 28-Sep-2012 Restore inheritance from G4VDiscreteProcess, remove enable-flag
48 // changing, remove warning message from original ctor.
49 
50 #include "G4HadronicProcess.hh"
51 
52 #include "G4Types.hh"
53 #include "G4SystemOfUnits.hh"
54 #include "G4HadProjectile.hh"
55 #include "G4ElementVector.hh"
56 #include "G4Track.hh"
57 #include "G4Step.hh"
58 #include "G4Element.hh"
59 #include "G4ParticleChange.hh"
61 #include "G4Navigator.hh"
62 #include "G4ProcessVector.hh"
63 #include "G4ProcessManager.hh"
64 #include "G4StableIsotopes.hh"
65 #include "G4HadTmpUtil.hh"
66 #include "G4NucleiProperties.hh"
67 
68 #include "G4HadronicException.hh"
70 
71 #include <typeinfo>
72 #include <sstream>
73 #include <iostream>
74 
75 #include <stdlib.h>
76 
77 // File-scope variable to capture environment variable at startup
78 
79 static const char* G4Hadronic_Random_File = getenv("G4HADRONIC_RANDOM_FILE");
80 
82 
84  G4ProcessType procType)
85  : G4VDiscreteProcess(processName, procType)
86 {
87  SetProcessSubType(fHadronInelastic); // Default unless subclass changes
88 
91  theInteraction = 0;
94  aScaleFactor = 1;
95  xBiasOn = false;
98 }
99 
101 
103  G4HadronicProcessType aHadSubType)
104  : G4VDiscreteProcess(processName, fHadronic)
105 {
106  SetProcessSubType(aHadSubType);
107 
110  theInteraction = 0;
113  aScaleFactor = 1;
114  xBiasOn = false;
117 }
118 
119 
121 {
123  delete theTotalResult;
125 }
126 
128  levelsSetByProcess = false;
129 
130  epReportLevel = getenv("G4Hadronic_epReportLevel") ?
131  strtol(getenv("G4Hadronic_epReportLevel"),0,10) : 0;
132 
133  epCheckLevels.first = getenv("G4Hadronic_epCheckRelativeLevel") ?
134  strtod(getenv("G4Hadronic_epCheckRelativeLevel"),0) : DBL_MAX;
135 
136  epCheckLevels.second = getenv("G4Hadronic_epCheckAbsoluteLevel") ?
137  strtod(getenv("G4Hadronic_epCheckAbsoluteLevel"),0) : DBL_MAX;
138 }
139 
141 {
142  if(!a) { return; }
143  try{ theEnergyRangeManager.RegisterMe( a ); }
144  catch(G4HadronicException & aE)
145  {
147  aE.Report(ed);
148  ed << "Unrecoverable error in " << GetProcessName()
149  << " to register " << a->GetModelName() << G4endl;
150  G4Exception("G4HadronicProcess::RegisterMe", "had001", FatalException,
151  ed);
152  }
154 }
155 
157 {
158  if(getenv("G4HadronicProcess_debug")) {
160  }
162 }
163 
165 {
166  try
167  {
170  }
171  catch(G4HadronicException aR)
172  {
174  aR.Report(ed);
175  ed << " hadronic initialisation fails" << G4endl;
176  G4Exception("G4HadronicProcess::BuildPhysicsTable", "had000",
177  FatalException,ed);
178  }
180 }
181 
184 {
185  //G4cout << "GetMeanFreePath " << aTrack.GetDefinition()->GetParticleName()
186  // << " Ekin= " << aTrack.GetKineticEnergy() << G4endl;
187  try
188  {
191  aTrack.GetMaterial());
192  }
193  catch(G4HadronicException aR)
194  {
196  aR.Report(ed);
197  DumpState(aTrack,"GetMeanFreePath",ed);
198  ed << " Cross section is not available" << G4endl;
199  G4Exception("G4HadronicProcess::GetMeanFreePath", "had002", FatalException,
200  ed);
201  }
202  G4double res = DBL_MAX;
203  if( theLastCrossSection > 0.0 ) { res = 1.0/theLastCrossSection; }
204  //G4cout << " xsection= " << res << G4endl;
205  return res;
206 }
207 
210 {
211  //G4cout << "PostStepDoIt " << aTrack.GetDefinition()->GetParticleName()
212  // << " Ekin= " << aTrack.GetKineticEnergy() << G4endl;
213  // if primary is not Alive then do nothing
215  theTotalResult->Initialize(aTrack);
217  if(aTrack.GetTrackStatus() != fAlive) { return theTotalResult; }
218 
219  // Find cross section at end of step and check if <= 0
220  //
221  const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
222  G4Material* aMaterial = aTrack.GetMaterial();
223 
224  G4Element* anElement = 0;
225  try
226  {
227  anElement = theCrossSectionDataStore->SampleZandA(aParticle,
228  aMaterial,
229  targetNucleus);
230  }
231  catch(G4HadronicException & aR)
232  {
234  aR.Report(ed);
235  DumpState(aTrack,"SampleZandA",ed);
236  ed << " PostStepDoIt failed on element selection" << G4endl;
237  G4Exception("G4HadronicProcess::PostStepDoIt", "had003", FatalException,
238  ed);
239  }
240 
241  // check only for charged particles
242  if(aParticle->GetDefinition()->GetPDGCharge() != 0.0) {
243  if (GetElementCrossSection(aParticle, anElement, aMaterial) <= 0.0) {
244  // No interaction
245  return theTotalResult;
246  }
247  }
248 
249  // Next check for illegal track status
250  //
251  if (aTrack.GetTrackStatus() != fAlive &&
252  aTrack.GetTrackStatus() != fSuspend) {
253  if (aTrack.GetTrackStatus() == fStopAndKill ||
255  aTrack.GetTrackStatus() == fPostponeToNextEvent) {
257  ed << "G4HadronicProcess: track in unusable state - "
258  << aTrack.GetTrackStatus() << G4endl;
259  ed << "G4HadronicProcess: returning unchanged track " << G4endl;
260  DumpState(aTrack,"PostStepDoIt",ed);
261  G4Exception("G4HadronicProcess::PostStepDoIt", "had004", JustWarning, ed);
262  }
263  // No warning for fStopButAlive which is a legal status here
264  return theTotalResult;
265  }
266 
267  // Initialize the hadronic projectile from the track
268  thePro.Initialise(aTrack);
269 
270  try
271  {
273  ChooseHadronicInteraction( thePro, targetNucleus, aMaterial, anElement );
274  }
275  catch(G4HadronicException & aE)
276  {
278  aE.Report(ed);
279  ed << "Target element "<<anElement->GetName()<<" Z= "
280  << targetNucleus.GetZ_asInt() << " A= "
282  DumpState(aTrack,"ChooseHadronicInteraction",ed);
283  ed << " No HadronicInteraction found out" << G4endl;
284  G4Exception("G4HadronicProcess::PostStepDoIt", "had005", FatalException,
285  ed);
286  }
287 
288  G4HadFinalState* result = 0;
289  G4int reentryCount = 0;
290 
291  do
292  {
293  try
294  {
295  // Save random engine if requested for debugging
297  CLHEP::HepRandom::saveEngineStatus(G4Hadronic_Random_File);
298  }
299  // Call the interaction
301  ++reentryCount;
302  }
303  catch(G4HadronicException aR)
304  {
306  aR.Report(ed);
307  ed << "Call for " << theInteraction->GetModelName() << G4endl;
308  ed << "Target element "<<anElement->GetName()<<" Z= "
310  << " A= " << targetNucleus.GetA_asInt() << G4endl;
311  DumpState(aTrack,"ApplyYourself",ed);
312  ed << " ApplyYourself failed" << G4endl;
313  G4Exception("G4HadronicProcess::PostStepDoIt", "had006", FatalException,
314  ed);
315  }
316 
317  // Check the result for catastrophic energy non-conservation
318  CheckResult(thePro, targetNucleus, result);
319 
320  if(reentryCount>100) {
322  ed << "Call for " << theInteraction->GetModelName() << G4endl;
323  ed << "Target element "<<anElement->GetName()<<" Z= "
325  << " A= " << targetNucleus.GetA_asInt() << G4endl;
326  DumpState(aTrack,"ApplyYourself",ed);
327  ed << " ApplyYourself does not completed after 100 attempts" << G4endl;
328  G4Exception("G4HadronicProcess::PostStepDoIt", "had006", FatalException,
329  ed);
330  }
331  }
332  while(!result);
333 
335 
337 
338  FillResult(result, aTrack);
339 
340  if (epReportLevel != 0) {
342  }
343  //G4cout << "PostStepDoIt done " << G4endl;
344  return theTotalResult;
345 }
346 
347 
348 void G4HadronicProcess::ProcessDescription(std::ostream& outFile) const
349 {
350  outFile << "The description for this process has not been written yet.\n";
351 }
352 
353 
355 {
356  G4double result = 0;
358  G4double biasedProbability = 1.-std::exp(-nLTraversed);
359  G4double realProbability = 1-std::exp(-nLTraversed/aScaleFactor);
360  result = (biasedProbability-realProbability)/biasedProbability;
361  return result;
362 }
363 
365 {
366  G4double result = 0;
368  result =
369  1./aScaleFactor*std::exp(-nLTraversed/aScaleFactor*(1-1./aScaleFactor));
370  return result;
371 }
372 
373 void
375 {
377 
378  G4double rotation = CLHEP::twopi*G4UniformRand();
379  G4ThreeVector it(0., 0., 1.);
380 
381  G4double efinal = aR->GetEnergyChange();
382  if(efinal < 0.0) { efinal = 0.0; }
383 
384  // check status of primary
385  if(aR->GetStatusChange() == stopAndKill) {
388 
389  // check its final energy
390  } else if(0.0 == efinal) {
393  ->GetAtRestProcessVector()->size() > 0)
396 
397  // primary is not killed apply rotation and Lorentz transformation
398  } else {
401  G4double newE = efinal + mass;
402  G4double newP = std::sqrt(efinal*(efinal + 2*mass));
403  G4ThreeVector newPV = newP*aR->GetMomentumChange();
404  G4LorentzVector newP4(newE, newPV);
405  newP4.rotate(rotation, it);
406  newP4 *= aR->GetTrafoToLab();
407  theTotalResult->ProposeMomentumDirection(newP4.vect().unit());
408  newE = newP4.e() - mass;
409  if(G4HadronicProcess_debug_flag && newE <= 0.0) {
411  DumpState(aT,"Primary has zero energy after interaction",ed);
412  G4Exception("G4HadronicProcess::FillResults", "had011", JustWarning, ed);
413  }
414  if(newE < 0.0) { newE = 0.0; }
415  theTotalResult->ProposeEnergy( newE );
416  }
417  //G4cout << "FillResult: Efinal= " << efinal << " status= "
418  // << theTotalResult->GetTrackStatus()
419  // << " fKill= " << fStopAndKill << G4endl;
420 
421  // check secondaries: apply rotation and Lorentz transformation
422  G4int nSec = aR->GetNumberOfSecondaries();
424  G4double weight = aT.GetWeight();
425 
426  if (nSec > 0) {
427  G4double time0 = aT.GetGlobalTime();
428  for (G4int i = 0; i < nSec; ++i) {
430  theM.rotate(rotation, it);
431  theM *= aR->GetTrafoToLab();
432  aR->GetSecondary(i)->GetParticle()->Set4Momentum(theM);
433 
434  // time of interaction starts from zero
435  G4double time = aR->GetSecondary(i)->GetTime();
436  if (time < 0.0) { time = 0.0; }
437 
438  // take into account global time
439  time += time0;
440 
441  G4Track* track = new G4Track(aR->GetSecondary(i)->GetParticle(),
442  time, aT.GetPosition());
444  G4double newWeight = weight*aR->GetSecondary(i)->GetWeight();
445  // G4cout << "#### ParticleDebug "
446  // <<GetProcessName()<<" "
447  //<<aR->GetSecondary(i)->GetParticle()->GetDefinition()->GetParticleName()<<" "
448  // <<aScaleFactor<<" "
449  // <<XBiasSurvivalProbability()<<" "
450  // <<XBiasSecondaryWeight()<<" "
451  // <<aT.GetWeight()<<" "
452  // <<aR->GetSecondary(i)->GetWeight()<<" "
453  // <<aR->GetSecondary(i)->GetParticle()->Get4Momentum()<<" "
454  // <<G4endl;
455  track->SetWeight(newWeight);
459  G4double e = track->GetKineticEnergy();
460  if (e <= 0.0) {
462  DumpState(aT,"Secondary has zero energy",ed);
463  ed << "Secondary " << track->GetDefinition()->GetParticleName()
464  << G4endl;
465  G4Exception("G4HadronicProcess::FillResults", "had011",
466  JustWarning,ed);
467  }
468  }
469  }
470  }
471 
472  aR->Clear();
473 }
474 
476 {
477  xBiasOn = true;
478  aScaleFactor = aScale;
479  G4String it = GetProcessName();
480  if( (it != "PhotonInelastic") &&
481  (it != "ElectroNuclear") &&
482  (it != "PositronNuclear") )
483  {
485  G4Exception("G4HadronicProcess::BiasCrossSectionByFactor", "had009",
486  FatalException, ed,
487  "Cross-section biasing available only for gamma and electro nuclear reactions.");
488  }
489  if(aScale<100)
490  {
492  G4Exception("G4HadronicProcess::BiasCrossSectionByFactor", "had010", JustWarning,ed,
493  "Cross-section bias readjusted to be above safe limit. New value is 100");
494  aScaleFactor = 100.;
495  }
496 }
497 
499  const G4Nucleus &aNucleus,
500  G4HadFinalState * result)
501 {
502  // check for catastrophic energy non-conservation
503  // to re-sample the interaction
504 
506  G4double nuclearMass(0);
507  if (theModel) {
508 
509  // Compute final-state total energy
510  G4double finalE(0.);
511  G4int nSec = result->GetNumberOfSecondaries();
512 
513  nuclearMass = G4NucleiProperties::GetNuclearMass(aNucleus.GetA_asInt(),
514  aNucleus.GetZ_asInt());
515  if (result->GetStatusChange() != stopAndKill) {
516  // Interaction didn't complete, returned "do nothing" state
517  // and reset nucleus or the primary survived the interaction
518  // (e.g. electro-nuclear ) => keep nucleus
519  finalE=result->GetLocalEnergyDeposit() +
520  aPro.GetDefinition()->GetPDGMass() + result->GetEnergyChange();
521  if( nSec == 0 ){
522  // Since there are no secondaries, there is no recoil nucleus.
523  // To check energy balance we must neglect the initial nucleus too.
524  nuclearMass=0.0;
525  }
526  }
527  for (G4int i = 0; i < nSec; i++) {
528  G4DynamicParticle *pdyn=result->GetSecondary(i)->GetParticle();
529  finalE += pdyn->GetTotalEnergy();
530  G4double mass_pdg=pdyn->GetDefinition()->GetPDGMass();
531  G4double mass_dyn=pdyn->GetMass();
532  if ( std::abs(mass_pdg - mass_dyn) > 0.1*mass_pdg + 1.*MeV){
533  result->Clear();
534  result = 0;
536  desc << "Warning: Secondary with off-shell dynamic mass detected: " << G4endl
537  << " " << pdyn->GetDefinition()->GetParticleName()
538  << ", PDG mass: " << mass_pdg << ", dynamic mass: "<< mass_dyn << G4endl
539  << (epReportLevel<0 ? "abort the event" : "re-sample the interaction") << G4endl
540  << " Process / Model: " << GetProcessName()<< " / "
541  << theModel->GetModelName() << G4endl
542  << " Primary: " << aPro.GetDefinition()->GetParticleName()
543  << " (" << aPro.GetDefinition()->GetPDGEncoding() << "), "
544  << " E= " << aPro.Get4Momentum().e()
545  << ", target nucleus (" << aNucleus.GetZ_asInt() << ", "
546  << aNucleus.GetA_asInt() << ")" << G4endl;
547  G4Exception("G4HadronicProcess:CheckResult()", "had012",
549  // must return here.....
550  return result;
551  }
552  }
553  G4double deltaE= nuclearMass + aPro.GetTotalEnergy() - finalE;
554 
555  std::pair<G4double, G4double> checkLevels =
556  theModel->GetFatalEnergyCheckLevels(); // (relative, absolute)
557  if (std::abs(deltaE) > checkLevels.second &&
558  std::abs(deltaE) > checkLevels.first*aPro.GetKineticEnergy()){
559  // do not delete result, this is a pointer to a data member;
560  result->Clear();
561  result = 0;
563  desc << "Warning: Bad energy non-conservation detected, will "
564  << (epReportLevel<0 ? "abort the event" : "re-sample the interaction") << G4endl
565  << " Process / Model: " << GetProcessName()<< " / "
566  << theModel->GetModelName() << G4endl
567  << " Primary: " << aPro.GetDefinition()->GetParticleName()
568  << " (" << aPro.GetDefinition()->GetPDGEncoding() << "), "
569  << " E= " << aPro.Get4Momentum().e()
570  << ", target nucleus (" << aNucleus.GetZ_asInt() << ", "
571  << aNucleus.GetA_asInt() << ")" << G4endl
572  << " E(initial - final) = " << deltaE << " MeV." << G4endl;
573  G4Exception("G4HadronicProcess:CheckResult()", "had012",
575  }
576  }
577  return result;
578 }
579 
580 void
582  const G4Nucleus& aNucleus)
583 {
584  G4int target_A=aNucleus.GetA_asInt();
585  G4int target_Z=aNucleus.GetZ_asInt();
586  G4double targetMass = G4NucleiProperties::GetNuclearMass(target_A,target_Z);
587  G4LorentzVector target4mom(0, 0, 0, targetMass);
588 
589  G4LorentzVector projectile4mom = aTrack.GetDynamicParticle()->Get4Momentum();
590  G4int track_A = aTrack.GetDefinition()->GetBaryonNumber();
591  G4int track_Z = G4lrint(aTrack.GetDefinition()->GetPDGCharge());
592 
593  G4int initial_A = target_A + track_A;
594  G4int initial_Z = target_Z + track_Z;
595 
596  G4LorentzVector initial4mom = projectile4mom + target4mom;
597 
598  // Compute final-state momentum for scattering and "do nothing" results
599  G4LorentzVector final4mom;
600  G4int final_A(0), final_Z(0);
601 
603  if (theTotalResult->GetTrackStatus() != fStopAndKill) { // If it is Alive
604  // Either interaction didn't complete, returned "do nothing" state
605  // or the primary survived the interaction (e.g. electro-nucleus )
606  G4Track temp(aTrack);
607 
608  // Use the final energy / momentum
611 
612  if( nSec == 0 ){
613  // Interaction didn't complete, returned "do nothing" state
614  // - or suppressed recoil (e.g. Neutron elastic )
615  final4mom = temp.GetDynamicParticle()->Get4Momentum() + target4mom;
616  final_A = initial_A;
617  final_Z = initial_Z;
618  }else{
619  // The primary remains in final state (e.g. electro-nucleus )
620  final4mom = temp.GetDynamicParticle()->Get4Momentum();
621  final_A = track_A;
622  final_Z = track_Z;
623  // Expect that the target nucleus will have interacted,
624  // and its products, including recoil, will be included in secondaries.
625  }
626  }
627  if( nSec > 0 ) {
628  G4Track* sec;
629 
630  for (G4int i = 0; i < nSec; i++) {
631  sec = theTotalResult->GetSecondary(i);
632  final4mom += sec->GetDynamicParticle()->Get4Momentum();
633  final_A += sec->GetDefinition()->GetBaryonNumber();
634  final_Z += G4lrint(sec->GetDefinition()->GetPDGCharge());
635  }
636  }
637 
638  // Get level-checking information (used to cut-off relative checks)
639  G4String processName = GetProcessName();
641  G4String modelName("none");
642  if (theModel) modelName = theModel->GetModelName();
643  std::pair<G4double, G4double> checkLevels = epCheckLevels;
644  if (!levelsSetByProcess) {
645  if (theModel) checkLevels = theModel->GetEnergyMomentumCheckLevels();
646  checkLevels.first= std::min(checkLevels.first, epCheckLevels.first);
647  checkLevels.second=std::min(checkLevels.second, epCheckLevels.second);
648  }
649 
650  // Compute absolute total-energy difference, and relative kinetic-energy
651  G4bool checkRelative = (aTrack.GetKineticEnergy() > checkLevels.second);
652 
653  G4LorentzVector diff = initial4mom - final4mom;
654  G4double absolute = diff.e();
655  G4double relative = checkRelative ? absolute/aTrack.GetKineticEnergy() : 0.;
656 
657  G4double absolute_mom = diff.vect().mag();
658  G4double relative_mom = checkRelative ? absolute_mom/aTrack.GetMomentum().mag() : 0.;
659 
660  // Evaluate relative and absolute conservation
661  G4bool relPass = true;
662  G4String relResult = "pass";
663  if ( std::abs(relative) > checkLevels.first
664  || std::abs(relative_mom) > checkLevels.first) {
665  relPass = false;
666  relResult = checkRelative ? "fail" : "N/A";
667  }
668 
669  G4bool absPass = true;
670  G4String absResult = "pass";
671  if ( std::abs(absolute) > checkLevels.second
672  || std::abs(absolute_mom) > checkLevels.second ) {
673  absPass = false ;
674  absResult = "fail";
675  }
676 
677  G4bool chargePass = true;
678  G4String chargeResult = "pass";
679  if ( (initial_A-final_A)!=0
680  || (initial_Z-final_Z)!=0 ) {
681  chargePass = checkLevels.second < DBL_MAX ? false : true;
682  chargeResult = "fail";
683  }
684 
685  G4bool conservationPass = (relPass || absPass) && chargePass;
686 
687  std::stringstream Myout;
688  G4bool Myout_notempty(false);
689  // Options for level of reporting detail:
690  // 0. off
691  // 1. report only when E/p not conserved
692  // 2. report regardless of E/p conservation
693  // 3. report only when E/p not conserved, with model names, process names, and limits
694  // 4. report regardless of E/p conservation, with model names, process names, and limits
695  // negative -1.., as above, but send output to stderr
696 
697  if( std::abs(epReportLevel) == 4
698  || ( std::abs(epReportLevel) == 3 && ! conservationPass ) ){
699  Myout << " Process: " << processName << " , Model: " << modelName << G4endl;
700  Myout << " Primary: " << aTrack.GetParticleDefinition()->GetParticleName()
701  << " (" << aTrack.GetParticleDefinition()->GetPDGEncoding() << "),"
702  << " E= " << aTrack.GetDynamicParticle()->Get4Momentum().e()
703  << ", target nucleus (" << aNucleus.GetZ_asInt() << ","
704  << aNucleus.GetA_asInt() << ")" << G4endl;
705  Myout_notempty=true;
706  }
707  if ( std::abs(epReportLevel) == 4
708  || std::abs(epReportLevel) == 2
709  || ! conservationPass ){
710 
711  Myout << " "<< relResult <<" relative, limit " << checkLevels.first << ", values E/T(0) = "
712  << relative << " p/p(0)= " << relative_mom << G4endl;
713  Myout << " "<< absResult << " absolute, limit (MeV) " << checkLevels.second/MeV << ", values E / p (MeV) = "
714  << absolute/MeV << " / " << absolute_mom/MeV << " 3mom: " << (diff.vect())*1./MeV << G4endl;
715  Myout << " "<< chargeResult << " charge/baryon number balance " << (initial_Z-final_Z) << " / " << (initial_A-final_A) << " "<< G4endl;
716  Myout_notempty=true;
717 
718  }
719  Myout.flush();
720  if ( Myout_notempty ) {
721  if (epReportLevel > 0) G4cout << Myout.str()<< G4endl;
722  else if (epReportLevel < 0) G4cerr << Myout.str()<< G4endl;
723  }
724 }
725 
726 
728  const G4String& method,
730 {
731  ed << "Unrecoverable error in the method " << method << " of "
732  << GetProcessName() << G4endl;
733  ed << "TrackID= "<< aTrack.GetTrackID() << " ParentID= "
734  << aTrack.GetParentID()
735  << " " << aTrack.GetParticleDefinition()->GetParticleName()
736  << G4endl;
737  ed << "Ekin(GeV)= " << aTrack.GetKineticEnergy()/CLHEP::GeV
738  << "; direction= " << aTrack.GetMomentumDirection() << G4endl;
739  ed << "Position(mm)= " << aTrack.GetPosition()/CLHEP::mm << ";";
740 
741  if (aTrack.GetMaterial()) {
742  ed << " material " << aTrack.GetMaterial()->GetName();
743  }
744  ed << G4endl;
745 
746  if (aTrack.GetVolume()) {
747  ed << "PhysicalVolume <" << aTrack.GetVolume()->GetName()
748  << ">" << G4endl;
749  }
750 }
751 /*
752 G4ParticleDefinition* G4HadronicProcess::GetTargetDefinition()
753 {
754  const G4Nucleus* nuc = GetTargetNucleus();
755  G4int Z = nuc->GetZ_asInt();
756  G4int A = nuc->GetA_asInt();
757  return G4ParticleTable::GetParticleTable()->GetIon(Z,A,0*eV);
758 }
759 */
760 /* end of file */
G4ParticleDefinition * GetDefinition() const
G4int GetA_asInt() const
Definition: G4Nucleus.hh:109
G4int GetParentID() const
static const double MeV
Definition: G4SIunits.hh:193
static G4double GetNuclearMass(const G4double A, const G4double Z)
G4int GetNumberOfSecondaries() const
void RegisterMe(G4HadronicInteraction *a)
G4Track * GetSecondary(G4int anIndex) const
void RegisterInteraction(G4HadronicProcess *, G4HadronicInteraction *)
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
G4HadSecondary * GetSecondary(size_t i)
CLHEP::Hep3Vector G4ThreeVector
G4double GetTotalEnergy() const
G4LorentzRotation & GetTrafoToLab()
void BiasCrossSectionByFactor(G4double aScale)
static G4HadronicProcessStore * Instance()
const G4DynamicParticle * GetDynamicParticle() const
G4int first(char) const
virtual const std::pair< G4double, G4double > GetFatalEnergyCheckLevels() const
const G4String & GetName() const
Definition: G4Material.hh:178
G4HadronicInteraction * theInteraction
const G4ThreeVector & GetMomentumChange() const
const G4ThreeVector & GetPosition() const
G4TrackStatus GetTrackStatus() const
G4EnergyRangeManager theEnergyRangeManager
virtual void PreparePhysicsTable(const G4ParticleDefinition &)
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4HadProjectile thePro
G4double GetEnergyChange() const
G4ParticleDefinition * GetDefinition() const
G4double a
Definition: TRTMaterials.hh:39
const G4ThreeVector * GetMomentumDirection() const
void CheckEnergyMomentumConservation(const G4Track &, const G4Nucleus &)
const G4String & GetModelName() const
G4double GetTime() const
void ClearNumberOfInteractionLengthLeft()
Definition: G4VProcess.hh:447
G4ProcessManager * GetProcessManager() const
int G4int
Definition: G4Types.hh:78
G4HadronicProcessType
const G4String & GetParticleName() const
std::pair< G4double, G4double > epCheckLevels
G4int GetCreatorModelType() const
void SetWeight(G4double aValue)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void GetEnergyMomentumCheckEnvvars()
void SetCreatorModelIndex(G4int idx)
void RegisterMe(G4HadronicInteraction *a)
void ProposeWeight(G4double finalWeight)
virtual void BuildPhysicsTable(const G4ParticleDefinition &)
const G4LorentzRotation & GetTrafoToLab() const
void SetSecondaryWeightByProcess(G4bool)
G4CrossSectionDataStore * theCrossSectionDataStore
void DumpState(const G4Track &, const G4String &, G4ExceptionDescription &)
void SetTrafoToLab(const G4LorentzRotation &aT)
G4ProcessVector * GetAtRestProcessVector(G4ProcessVectorTypeIndex typ=typeGPIL) const
G4double GetKineticEnergy() const
void FillResult(G4HadFinalState *aR, const G4Track &aT)
#define G4UniformRand()
Definition: Randomize.hh:93
G4GLOB_DLL std::ostream G4cout
G4double GetTotalNumberOfInteractionLengthTraversed() const
Definition: G4VProcess.hh:458
G4ParticleChange * theTotalResult
const G4ParticleDefinition * GetDefinition() const
void Register(G4HadronicProcess *)
const G4String & GetName() const
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *)
G4double GetMass() const
G4double XBiasSurvivalProbability()
bool G4bool
Definition: G4Types.hh:79
virtual std::pair< G4double, G4double > GetEnergyMomentumCheckLevels() const
G4double GetKineticEnergy() const
G4double GetCrossSection(const G4DynamicParticle *, const G4Material *)
const G4ParticleDefinition * GetParticleDefinition() const
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:432
static const double GeV
Definition: G4SIunits.hh:196
Definition: G4Step.hh:76
G4int GetTrackID() const
virtual void ProcessDescription(std::ostream &outFile) const
G4double GetGlobalTime() const
static const char * G4Hadronic_Random_File
void RegisterParticle(G4HadronicProcess *, const G4ParticleDefinition *)
const G4String & GetProcessName() const
Definition: G4VProcess.hh:408
const G4LorentzVector & Get4Momentum() const
void DeRegister(G4HadronicProcess *)
const G4TouchableHandle & GetTouchableHandle() const
G4LorentzVector Get4Momentum() const
G4Material * GetMaterial() const
void Initialise(const G4Track &aT)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
void Set4Momentum(const G4LorentzVector &momentum)
G4int size() const
void BuildPhysicsTable(const G4ParticleDefinition &)
G4ThreeVector GetMomentum() const
virtual void Initialize(const G4Track &)
G4double GetElementCrossSection(const G4DynamicParticle *part, const G4Element *elm, const G4Material *mat=0)
const G4ThreeVector & GetMomentumDirection() const
G4HadronicInteraction * GetHadronicInteraction() const
G4double GetPDGMass() const
G4double XBiasSecondaryWeight()
int G4lrint(double ad)
Definition: templates.hh:163
void SetNumberOfSecondaries(G4int totSecondaries)
G4DynamicParticle * GetParticle()
void BuildPhysicsTable(const G4ParticleDefinition &)
G4int GetZ_asInt() const
Definition: G4Nucleus.hh:115
void ProposeEnergy(G4double finalEnergy)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
G4VPhysicalVolume * GetVolume() const
void AddSecondary(G4Track *aSecondary)
G4double GetWeight() const
G4HadronicInteraction * ChooseHadronicInteraction(const G4HadProjectile &aHadProjectile, G4Nucleus &aTargetNucleus, G4Material *aMaterial, G4Element *anElement)
G4double GetEnergy() const
#define G4endl
Definition: G4ios.hh:61
G4HadronicProcess(const G4String &processName="Hadronic", G4ProcessType procType=fHadronic)
G4TrackStatus GetTrackStatus() const
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4Element * SampleZandA(const G4DynamicParticle *, const G4Material *, G4Nucleus &target)
void SetKineticEnergy(const G4double aValue)
double G4double
Definition: G4Types.hh:76
void ProposeTrackStatus(G4TrackStatus status)
const G4String & GetName() const
Definition: G4Element.hh:127
virtual G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
G4ForceCondition
G4double GetPDGCharge() const
#define DBL_MAX
Definition: templates.hh:83
static const double mm
Definition: G4SIunits.hh:102
void Report(std::ostream &aS)
G4int GetNumberOfSecondaries() const
virtual G4HadFinalState * ApplyYourself(const G4HadProjectile &aTrack, G4Nucleus &targetNucleus)=0
G4double GetLocalEnergyDeposit() const
void SetMomentumDirection(const G4ThreeVector &aValue)
G4HadFinalState * CheckResult(const G4HadProjectile &thePro, const G4Nucleus &targetNucleus, G4HadFinalState *result)
G4GLOB_DLL std::ostream G4cerr
G4HadFinalStateStatus GetStatusChange() const
void PrintInfo(const G4ParticleDefinition *)
G4double GetTotalEnergy() const
CLHEP::HepLorentzVector G4LorentzVector
G4ProcessType
G4double GetWeight() const