Files
geant4/source/processes/hadronic/models/binary_cascade/src/G4GeneratorPrecompoundInterface.cc
T
2016-06-10 14:11:04 +02:00

722 lines
28 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4GeneratorPrecompoundInterface.cc 92692 2015-09-14 07:06:19Z gcosmo $
//
// -----------------------------------------------------------------------------
// GEANT 4 class file
//
// History: first implementation
// HPW, 10DEC 98, the decay part originally written by Gunter Folger
// in his FTF-test-program.
//
// M.Kelsey, 28 Jul 2011 -- Replace loop to decay input secondaries
// with new utility class, simplify cleanup loops
// -----------------------------------------------------------------------------
#include <algorithm>
#include <vector>
#include "G4GeneratorPrecompoundInterface.hh"
#include "G4PhysicalConstants.hh"
#include "G4SystemOfUnits.hh"
#include "G4DynamicParticleVector.hh"
#include "G4KineticTrackVector.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4Deuteron.hh"
#include "G4Triton.hh"
#include "G4He3.hh"
#include "G4Alpha.hh"
#include "G4V3DNucleus.hh"
#include "G4Nucleon.hh"
#include "G4AntiProton.hh"
#include "G4AntiNeutron.hh"
#include "G4AntiDeuteron.hh"
#include "G4AntiTriton.hh"
#include "G4AntiHe3.hh"
#include "G4AntiAlpha.hh"
#include "G4FragmentVector.hh"
#include "G4ReactionProduct.hh"
#include "G4ReactionProductVector.hh"
#include "G4PreCompoundModel.hh"
#include "G4ExcitationHandler.hh"
#include "G4DecayKineticTracks.hh"
#include "G4HadronicInteractionRegistry.hh"
//---------------------------------------------------------------------
#include "Randomize.hh"
#include "G4Log.hh"
//#define debugPrecoInt
G4GeneratorPrecompoundInterface::G4GeneratorPrecompoundInterface(G4VPreCompoundModel* preModel)
: CaptureThreshold(70*MeV) // Uzhi 1.05.2015 10 ->70
{
proton = G4Proton::Proton();
neutron = G4Neutron::Neutron();
deuteron=G4Deuteron::Deuteron();
triton =G4Triton::Triton();
He3 =G4He3::He3();
He4 =G4Alpha::Alpha();
ANTIproton=G4AntiProton::AntiProton();
ANTIneutron=G4AntiNeutron::AntiNeutron();
ANTIdeuteron=G4AntiDeuteron::AntiDeuteron();
ANTItriton =G4AntiTriton::AntiTriton();
ANTIHe3 =G4AntiHe3::AntiHe3();
ANTIHe4 =G4AntiAlpha::AntiAlpha();
if(preModel) { SetDeExcitation(preModel); }
else {
G4HadronicInteraction* hadi =
G4HadronicInteractionRegistry::Instance()->FindModel("PRECO");
G4VPreCompoundModel* pre = static_cast<G4VPreCompoundModel*>(hadi);
if(!pre) { pre = new G4PreCompoundModel(); }
SetDeExcitation(pre);
}
}
G4GeneratorPrecompoundInterface::~G4GeneratorPrecompoundInterface()
{
}
G4ReactionProductVector* G4GeneratorPrecompoundInterface::
Propagate(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus)
{
#ifdef debugPrecoInt
G4cout<<G4endl<<"G4GeneratorPrecompoundInterface::Propagate"<<G4endl;
G4cout<<"Target A and Z "<<theNucleus->GetMassNumber()<<" "<<theNucleus->GetCharge()<<G4endl;
G4cout<<"Directly produced particles number "<<theSecondaries->size()<<G4endl;
#endif
G4ReactionProductVector * theTotalResult = new G4ReactionProductVector;
// decay the strong resonances
G4DecayKineticTracks decay(theSecondaries);
#ifdef debugPrecoInt
G4cout<<"Final stable particles number "<<theSecondaries->size()<<G4endl;
#endif
// prepare the fragment
G4int anA=theNucleus->GetMassNumber();
G4int aZ=theNucleus->GetCharge();
// G4double TargetNucleusMass = G4NucleiProperties::GetNuclearMass(anA, aZ);
G4int numberOfEx = 0;
G4int numberOfCh = 0;
G4int numberOfHoles = 0;
G4double R = theNucleus->GetNuclearRadius();
G4LorentzVector captured4Momentum(0.,0.,0.,0.);
G4LorentzVector Residual4Momentum(0.,0.,0.,0.); // TargetNucleusMass is not need at the moment
G4LorentzVector Secondary4Momentum(0.,0.,0.,0.);
// loop over secondaries
G4KineticTrackVector::iterator iter;
for(iter=theSecondaries->begin(); iter !=theSecondaries->end(); ++iter)
{
const G4ParticleDefinition* part = (*iter)->GetDefinition();
G4double e = (*iter)->Get4Momentum().e();
G4double mass = (*iter)->Get4Momentum().mag();
G4ThreeVector mom = (*iter)->Get4Momentum().vect();
if((part != proton && part != neutron) ||
// Uzhi 2.05.2015 (e > mass + CaptureThreshold) ||
((*iter)->GetPosition().mag() > R)) {
G4ReactionProduct * theNew = new G4ReactionProduct(part);
theNew->SetMomentum(mom);
theNew->SetTotalEnergy(e);
theTotalResult->push_back(theNew);
Secondary4Momentum += (*iter)->Get4Momentum(); // Uzhi 29 April
#ifdef debugPrecoInt
G4cout<<"Secondary 4Mom "<<part->GetParticleName()<<" "<<(*iter)->Get4Momentum()<<" "
<<(*iter)->Get4Momentum().mag()<<G4endl;
#endif
} else {
if( e-mass > -CaptureThreshold*G4Log( G4UniformRand()) ) { // Added by Uzhi 2.05.2015
G4ReactionProduct * theNew = new G4ReactionProduct(part);
theNew->SetMomentum(mom);
theNew->SetTotalEnergy(e);
theTotalResult->push_back(theNew);
Secondary4Momentum += (*iter)->Get4Momentum(); // Uzhi 29 April
#ifdef debugPrecoInt
G4cout<<"Secondary 4Mom "<<part->GetParticleName()<<" "<<(*iter)->Get4Momentum()<<" "
<<(*iter)->Get4Momentum().mag()<<G4endl;
#endif
} else {
// within the nucleus, neutron or proton
// now calculate A, Z of the fragment, momentum, number of exciton states
++anA;
++numberOfEx;
G4int Z = G4int(part->GetPDGCharge()/eplus + 0.1);
aZ += Z;
numberOfCh += Z;
captured4Momentum += (*iter)->Get4Momentum();
#ifdef debugPrecoInt
G4cout<<"Captured 4Mom "<<part->GetParticleName()<<(*iter)->Get4Momentum()<<G4endl;
#endif
}
}
delete (*iter);
}
delete theSecondaries;
// loop over wounded nucleus
G4Nucleon * theCurrentNucleon =
theNucleus->StartLoop() ? theNucleus->GetNextNucleon() : 0;
while(theCurrentNucleon) /* Loop checking, 31.08.2015, G.Folger */
{
if(theCurrentNucleon->AreYouHit()) {
++numberOfHoles;
++numberOfEx;
--anA;
aZ -= G4int(theCurrentNucleon->GetDefinition()->GetPDGCharge()/eplus + 0.1);
Residual4Momentum -= theCurrentNucleon->Get4Momentum();
}
theCurrentNucleon = theNucleus->GetNextNucleon();
}
#ifdef debugPrecoInt
G4cout<<G4endl;
G4cout<<"Secondary 4Mom "<<Secondary4Momentum<<G4endl;
G4cout<<"Captured 4Mom "<<captured4Momentum<<G4endl;
G4cout<<"Sec + Captured "<<Secondary4Momentum+captured4Momentum<<G4endl;
G4cout<<"Residual4Mom "<<Residual4Momentum<<G4endl;
G4cout<<"Sum 4 momenta "
<<Secondary4Momentum + captured4Momentum + Residual4Momentum <<G4endl;
#endif
// Check that we use QGS model; loop over wounded nucleus
G4bool QGSM(false);
theCurrentNucleon = theNucleus->StartLoop() ? theNucleus->GetNextNucleon() : 0;
while(theCurrentNucleon) /* Loop checking, 31.08.2015, G.Folger */
{
if(theCurrentNucleon->AreYouHit())
{
if(theCurrentNucleon->Get4Momentum().mag() <
theCurrentNucleon->GetDefinition()->GetPDGMass()) QGSM=true;
}
theCurrentNucleon = theNucleus->GetNextNucleon();
}
#ifdef debugPrecoInt
if(!QGSM){
G4cout<<G4endl;
G4cout<<"Residual A and Z "<<anA<<" "<<aZ<<G4endl;
G4cout<<"Residual 4Mom "<<Residual4Momentum<<G4endl;
if(numberOfEx == 0)
{G4cout<<"Residual 4Mom = 0 means that there were not wounded and captured nucleons"<<G4endl;}
}
#endif
if(anA == 0) return theTotalResult;
G4LorentzVector exciton4Momentum(0.,0.,0.,0.); // Uzhi 29 April
if(anA >= aZ)
{
if(!QGSM)
{ // FTF model was used
G4double fMass = G4NucleiProperties::GetNuclearMass(anA, aZ);
// G4LorentzVector exciton4Momentum = Residual4Momentum + captured4Momentum;
exciton4Momentum = Residual4Momentum + captured4Momentum;
//exciton4Momentum.setE(std::sqrt(exciton4Momentum.vect().mag2()+sqr(fMass)));
G4double ActualMass = exciton4Momentum.mag();
if(ActualMass <= fMass ) { //E*<=0, Uzhi 5.05.2015
exciton4Momentum.setE(std::sqrt(exciton4Momentum.vect().mag2()+sqr(fMass))); // Uzhi 13.05.2015
}
#ifdef debugPrecoInt
G4double exEnergy = 0.0;
if(ActualMass <= fMass ) {exEnergy = 0.;} // Uzhi 5.05.2015
else {exEnergy = ActualMass - fMass;}
G4cout<<"Ground state residual Mass "<<fMass<<" E* "<<exEnergy<<G4endl;
#endif
}
else
{ // QGS model was used
G4double InitialTargetMass =
G4NucleiProperties::GetNuclearMass(theNucleus->GetMassNumber(), theNucleus->GetCharge());
exciton4Momentum =
GetPrimaryProjectile()->Get4Momentum() + G4LorentzVector(0.,0.,0.,InitialTargetMass)
-Secondary4Momentum;
G4double fMass = G4NucleiProperties::GetNuclearMass(anA, aZ);
G4double ActualMass = exciton4Momentum.mag();
#ifdef debugPrecoInt
G4cout<<G4endl;
G4cout<<"Residual A and Z "<<anA<<" "<<aZ<<G4endl;
G4cout<<"Residual4Momentum "<<exciton4Momentum<<G4endl;
G4cout<<"ResidualMass, GroundStateMass and E* "<<ActualMass<<" "<<fMass<<" "
<<ActualMass - fMass<<G4endl;
#endif
if(ActualMass - fMass < 0.)
{
G4double ResE = std::sqrt(exciton4Momentum.vect().mag2() + sqr(fMass+10*MeV));
exciton4Momentum.setE(ResE);
#ifdef debugPrecoInt
G4cout<<"ActualMass - fMass < 0. "<<ActualMass<<" "<<fMass<<" "<<ActualMass - fMass<<G4endl;
G4int Uzhi; G4cin>>Uzhi;
#endif
}
}
// Need to de-excite the remnant nucleus only if excitation energy > 0.
G4Fragment anInitialState(anA, aZ, exciton4Momentum);
anInitialState.SetNumberOfParticles(numberOfEx-numberOfHoles);
anInitialState.SetNumberOfCharged(numberOfCh);
anInitialState.SetNumberOfHoles(numberOfHoles);
G4ReactionProductVector * aPrecoResult =
theDeExcitation->DeExcite(anInitialState);
// fill pre-compound part into the result, and return
#ifdef debugPrecoInt
G4cout<<"Target fragment number "<<aPrecoResult->size()<<G4endl;
#endif
for(unsigned int ll=0; ll<aPrecoResult->size(); ++ll)
{
theTotalResult->push_back(aPrecoResult->operator[](ll));
#ifdef debugPrecoInt
G4cout<<"Fragment "<<ll<<" "
<<aPrecoResult->operator[](ll)->GetDefinition()->GetParticleName()<<" "
<<aPrecoResult->operator[](ll)->GetMomentum()<<" "
<<aPrecoResult->operator[](ll)->GetTotalEnergy()<<" "
<<aPrecoResult->operator[](ll)->GetDefinition()->GetPDGMass()<<G4endl;
#endif
}
delete aPrecoResult;
}
return theTotalResult;
}
G4HadFinalState* G4GeneratorPrecompoundInterface::
ApplyYourself(const G4HadProjectile &, G4Nucleus & )
{
G4cout << "G4GeneratorPrecompoundInterface: ApplyYourself interface called stand-allone."
<< G4endl;
G4cout << "This class is only a mediator between generator and precompound"<<G4endl;
G4cout << "Please remove from your physics list."<<G4endl;
throw G4HadronicException(__FILE__, __LINE__, "SEVERE: G4GeneratorPrecompoundInterface model interface called stand-allone.");
return new G4HadFinalState;
}
void G4GeneratorPrecompoundInterface::PropagateModelDescription(std::ostream& outFile) const
{
outFile << "G4GeneratorPrecompoundInterface interfaces a high\n"
<< "energy model through the wounded nucleus to precompound de-excition.\n"
<< "Low energy protons and neutron present among secondaries produced by \n"
<< "the high energy generator and within the nucleus are captured. The wounded\n"
<< "nucleus and the captured particles form an excited nuclear fragment. This\n"
<< "fragment is passed to the Geant4 pre-compound model for de-excitation.\n"
<< "Nuclear de-excitation:\n";
// preco
}
// Uzhi Nov. 2012 ------------------------------------------------
G4ReactionProductVector* G4GeneratorPrecompoundInterface::
PropagateNuclNucl(G4KineticTrackVector* theSecondaries, G4V3DNucleus* theNucleus,
G4V3DNucleus* theProjectileNucleus)
{
#ifdef debugPrecoInt
G4cout<<G4endl<<"G4GeneratorPrecompoundInterface::PropagateNuclNucl "<<G4endl;
G4cout<<"Projectile A and Z "<<theProjectileNucleus->GetMassNumber()<<" "
<<theProjectileNucleus->GetCharge()<<G4endl;
G4cout<<"Target A and Z "<<theNucleus->GetMassNumber()<<" "
<<theNucleus->GetCharge()<<G4endl;
G4cout<<"Directly produced particles number "<<theSecondaries->size()<<G4endl;
G4cout<<"Projectile 4Mom and mass "<<GetPrimaryProjectile()->Get4Momentum()<<" "
<<GetPrimaryProjectile()->Get4Momentum().mag()<<G4endl<<G4endl;
#endif
// prepare the target residual
G4int anA=theNucleus->GetMassNumber();
G4int aZ=theNucleus->GetCharge();
G4int numberOfEx = 0;
G4int numberOfCh = 0;
G4int numberOfHoles = 0;
G4double exEnergy = 0.0;
G4double R = theNucleus->GetNuclearRadius();
G4LorentzVector Target4Momentum(0.,0.,0.,0.);
// loop over wounded target nucleus
G4Nucleon * theCurrentNucleon =
theNucleus->StartLoop() ? theNucleus->GetNextNucleon() : 0;
while(theCurrentNucleon) /* Loop checking, 31.08.2015, G.Folger */
{
if(theCurrentNucleon->AreYouHit()) {
++numberOfHoles;
++numberOfEx;
--anA;
aZ -= G4int(theCurrentNucleon->GetDefinition()->GetPDGCharge()/
eplus + 0.1);
exEnergy += theCurrentNucleon->GetBindingEnergy();
Target4Momentum -=theCurrentNucleon->Get4Momentum();
}
theCurrentNucleon = theNucleus->GetNextNucleon();
}
#ifdef debugPrecoInt
G4cout<<"Residual Target A Z E* 4mom "<<anA<<" "<<aZ<<" "<<exEnergy<<" "
<<Target4Momentum<<G4endl;
#endif
// prepare the projectile residual
G4bool ProjectileIsAntiNucleus=
GetPrimaryProjectile()->GetDefinition()->GetBaryonNumber() < -1;
G4ThreeVector bst = GetPrimaryProjectile()->Get4Momentum().boostVector();
G4int anAb=theProjectileNucleus->GetMassNumber();
G4int aZb=theProjectileNucleus->GetCharge();
G4int numberOfExB = 0;
G4int numberOfChB = 0;
G4int numberOfHolesB = 0;
G4double exEnergyB = 0.0;
G4double Rb = theProjectileNucleus->GetNuclearRadius();
G4LorentzVector Projectile4Momentum(0.,0.,0.,0.);
// loop over wounded projectile nucleus
theCurrentNucleon =
theProjectileNucleus->StartLoop() ? theProjectileNucleus->GetNextNucleon() : 0;
while(theCurrentNucleon) /* Loop checking, 31.08.2015, G.Folger */
{
if(theCurrentNucleon->AreYouHit()) {
++numberOfHolesB;
++numberOfExB;
--anAb;
if(!ProjectileIsAntiNucleus) {
aZb -= G4int(theCurrentNucleon->GetDefinition()->GetPDGCharge()/
eplus + 0.1);
} else {
aZb += G4int(theCurrentNucleon->GetDefinition()->GetPDGCharge()/
eplus - 0.1);
}
exEnergyB += theCurrentNucleon->GetBindingEnergy();
Projectile4Momentum -=theCurrentNucleon->Get4Momentum();
}
theCurrentNucleon = theProjectileNucleus->GetNextNucleon();
}
G4bool ExistTargetRemnant = G4double (numberOfHoles) <
0.3* G4double (numberOfHoles + anA);
G4bool ExistProjectileRemnant= G4double (numberOfHolesB) <
0.3*G4double (numberOfHolesB + anAb);
#ifdef debugPrecoInt
G4cout<<"Projectile residual A Z E* 4mom "<<anAb<<" "<<aZb<<" "<<exEnergyB<<" "
<<Projectile4Momentum<<G4endl;
G4cout<<" ExistTargetRemnant ExistProjectileRemnant "
<<ExistTargetRemnant<<" "<< ExistProjectileRemnant<<G4endl;
#endif
//-----------------------------------------------------------------------------
// decay the strong resonances
G4ReactionProductVector * theTotalResult = new G4ReactionProductVector;
G4DecayKineticTracks decay(theSecondaries);
#ifdef debugPrecoInt
G4cout<<"Secondary stable particles number "<<theSecondaries->size()<<G4endl;
#endif
#ifdef debugPrecoInt
G4LorentzVector secondary4Momemtum(0,0,0,0);
G4int SecondrNum(0);
#endif
// loop over secondaries
G4KineticTrackVector::iterator iter;
for(iter=theSecondaries->begin(); iter !=theSecondaries->end(); ++iter)
{
const G4ParticleDefinition* part = (*iter)->GetDefinition();
G4LorentzVector aTrack4Momentum=(*iter)->Get4Momentum();
if( part != proton && part != neutron &&
(part != ANTIproton && ProjectileIsAntiNucleus) &&
(part != ANTIneutron && ProjectileIsAntiNucleus) )
{
G4ReactionProduct * theNew = new G4ReactionProduct(part);
theNew->SetMomentum(aTrack4Momentum.vect());
theNew->SetTotalEnergy(aTrack4Momentum.e());
theTotalResult->push_back(theNew);
#ifdef debugPrecoInt
SecondrNum++;
secondary4Momemtum += (*iter)->Get4Momentum();
G4cout<<"Secondary "<<SecondrNum<<" "
<<theNew->GetDefinition()->GetParticleName()<<" "
<<theNew->GetMomentum()<<" "<<theNew->GetTotalEnergy()<<G4endl;
#endif
delete (*iter);
continue;
}
G4bool CanBeCapturedByTarget = false;
if( part == proton || part == neutron)
{
CanBeCapturedByTarget = ExistTargetRemnant &&
(-CaptureThreshold*G4Log( G4UniformRand()) >
(aTrack4Momentum + Target4Momentum).mag() -
aTrack4Momentum.mag() - Target4Momentum.mag()) &&
((*iter)->GetPosition().mag() < R);
}
// ---------------------------
G4LorentzVector Position((*iter)->GetPosition(), (*iter)->GetFormationTime());
Position.boost(bst);
G4bool CanBeCapturedByProjectile = false;
if( !ProjectileIsAntiNucleus &&
( part == proton || part == neutron))
{
CanBeCapturedByProjectile = ExistProjectileRemnant &&
(-CaptureThreshold*G4Log( G4UniformRand()) >
(aTrack4Momentum + Projectile4Momentum).mag() -
aTrack4Momentum.mag() - Projectile4Momentum.mag()) &&
(Position.vect().mag() < Rb);
}
if( ProjectileIsAntiNucleus &&
( part == ANTIproton || part == ANTIneutron))
{
CanBeCapturedByProjectile = ExistProjectileRemnant &&
(-CaptureThreshold*G4Log( G4UniformRand()) >
(aTrack4Momentum + Projectile4Momentum).mag() -
aTrack4Momentum.mag() - Projectile4Momentum.mag()) &&
(Position.vect().mag() < Rb);
}
if(CanBeCapturedByTarget && CanBeCapturedByProjectile)
{
if(G4UniformRand() < 0.5)
{ CanBeCapturedByTarget = true; CanBeCapturedByProjectile = false;}
else
{ CanBeCapturedByTarget = false; CanBeCapturedByProjectile = true;}
}
if(CanBeCapturedByTarget)
{
// within the target nucleus, neutron or proton
// now calculate A, Z of the fragment, momentum,
// number of exciton states
#ifdef debugPrecoInt
G4cout<<"Track is CapturedByTarget "<<" "<<part->GetParticleName()<<" "
<<aTrack4Momentum<<" "<<aTrack4Momentum.mag()<<G4endl;
#endif
++anA;
++numberOfEx;
G4int Z = G4int(part->GetPDGCharge()/eplus + 0.1);
aZ += Z;
numberOfCh += Z;
Target4Momentum +=aTrack4Momentum;
delete (*iter);
} else if(CanBeCapturedByProjectile)
{
// within the projectile nucleus, neutron or proton
// now calculate A, Z of the fragment, momentum,
// number of exciton states
#ifdef debugPrecoInt
G4cout<<"Track is CapturedByProjectile"<<" "<<part->GetParticleName()<<" "
<<aTrack4Momentum<<" "<<aTrack4Momentum.mag()<<G4endl;
#endif
++anAb;
++numberOfExB;
G4int Z = G4int(part->GetPDGCharge()/eplus + 0.1);
if( ProjectileIsAntiNucleus ) Z=-Z;
aZb += Z;
numberOfChB += Z;
Projectile4Momentum +=aTrack4Momentum;
delete (*iter);
} else
{ // the track is not captured
G4ReactionProduct * theNew = new G4ReactionProduct(part);
theNew->SetMomentum(aTrack4Momentum.vect());
theNew->SetTotalEnergy(aTrack4Momentum.e());
theTotalResult->push_back(theNew);
#ifdef debugPrecoInt
SecondrNum++;
secondary4Momemtum += (*iter)->Get4Momentum();
/*
G4cout<<"Secondary "<<SecondrNum<<" "
<<theNew->GetDefinition()->GetParticleName()<<" "
<<secondary4Momemtum<<G4endl;
*/
#endif
delete (*iter);
continue;
}
}
delete theSecondaries;
//-----------------------------------------------------
#ifdef debugPrecoInt
G4cout<<"Final target residual A Z E* 4mom "<<anA<<" "<<aZ<<" "
<<exEnergy<<" "<<Target4Momentum<<G4endl;
#endif
if(0!=anA )
{
G4double fMass = G4NucleiProperties::GetNuclearMass(anA, aZ);
if((anA == theNucleus->GetMassNumber()) && (exEnergy <= 0.))
{Target4Momentum.setE(fMass);}
G4double RemnMass=Target4Momentum.mag();
if(RemnMass < fMass)
{
RemnMass=fMass + exEnergy;
Target4Momentum.setE(std::sqrt(Target4Momentum.vect().mag2() +
RemnMass*RemnMass));
} else
{ exEnergy=RemnMass-fMass;}
if( exEnergy < 0.) exEnergy=0.;
// Need to de-excite the remnant nucleus
G4Fragment anInitialState(anA, aZ, Target4Momentum);
anInitialState.SetNumberOfParticles(numberOfEx-numberOfHoles);
anInitialState.SetNumberOfCharged(numberOfCh);
anInitialState.SetNumberOfHoles(numberOfHoles);
G4ReactionProductVector * aPrecoResult =
theDeExcitation->DeExcite(anInitialState);
#ifdef debugPrecoInt
G4cout<<"Target fragment number "<<aPrecoResult->size()<<G4endl;
#endif
// fill pre-compound part into the result, and return
for(unsigned int ll=0; ll<aPrecoResult->size(); ++ll)
{
theTotalResult->push_back(aPrecoResult->operator[](ll));
#ifdef debugPrecoInt
G4cout<<"Target fragment "<<ll<<" "
<<aPrecoResult->operator[](ll)->GetDefinition()->GetParticleName()<<" "
<<aPrecoResult->operator[](ll)->GetMomentum()<<" "
<<aPrecoResult->operator[](ll)->GetTotalEnergy()<<" "
<<aPrecoResult->operator[](ll)->GetMass()<<G4endl;
#endif
}
delete aPrecoResult;
}
//-----------------------------------------------------
if((anAb == theProjectileNucleus->GetMassNumber())&& (exEnergyB <= 0.))
{Projectile4Momentum = GetPrimaryProjectile()->Get4Momentum();}
#ifdef debugPrecoInt
G4cout<<"Final projectile residual A Z E* Pmom Pmag2 "<<anAb<<" "<<aZb<<" "
<<exEnergyB<<" "<<Projectile4Momentum<<" "
<<Projectile4Momentum.mag2()<<G4endl;
#endif
if(0!=anAb)
{
// G4ThreeVector bstToCM =Projectile4Momentum.findBoostToCM(); // Uzhi Apr. 2015
// Projectile4Momentum.boost(bstToCM); // Uzhi Apr. 2015
G4double fMass = G4NucleiProperties::GetNuclearMass(anAb, aZb);
G4double RemnMass=Projectile4Momentum.mag();
if(RemnMass < fMass)
{
RemnMass=fMass + exEnergyB;
Projectile4Momentum.setE(std::sqrt(Projectile4Momentum.vect().mag2() + // Uzhi 8.05.2015
RemnMass*RemnMass)); // Uzhi 8.05.2015
} else
{ exEnergyB=RemnMass-fMass;}
if( exEnergyB < 0.) exEnergyB=0.;
G4ThreeVector bstToCM =Projectile4Momentum.findBoostToCM(); // Uzhi Apr. 2015
Projectile4Momentum.boost(bstToCM); // Uzhi Apr. 2015
// Need to de-excite the remnant nucleus
G4Fragment anInitialState(anAb, aZb, Projectile4Momentum);
anInitialState.SetNumberOfParticles(numberOfExB-numberOfHolesB);
anInitialState.SetNumberOfCharged(numberOfChB);
anInitialState.SetNumberOfHoles(numberOfHolesB);
G4ReactionProductVector * aPrecoResult =
theDeExcitation->DeExcite(anInitialState);
#ifdef debugPrecoInt
G4cout<<"Projectile fragment number "<<aPrecoResult->size()<<G4endl;
#endif
// fill pre-compound part into the result, and return
for(unsigned int ll=0; ll<aPrecoResult->size(); ++ll)
{
G4LorentzVector tmp=G4LorentzVector(aPrecoResult->operator[](ll)->GetMomentum(), // Uzhi 2015
aPrecoResult->operator[](ll)->GetTotalEnergy());// Uzhi 2015
tmp.boost(-bstToCM); // Transformation to the system of original remnant // Uzhi 2015
aPrecoResult->operator[](ll)->SetMomentum(tmp.vect()); // Uzhi 2015
aPrecoResult->operator[](ll)->SetTotalEnergy(tmp.e()); // Uzhi 2015
if(ProjectileIsAntiNucleus)
{
const G4ParticleDefinition * aFragment=aPrecoResult->operator[](ll)->GetDefinition();
const G4ParticleDefinition * LastFragment=aFragment;
if (aFragment == proton) {LastFragment=G4AntiProton::AntiProtonDefinition();}
else if(aFragment == neutron) {LastFragment=G4AntiNeutron::AntiNeutronDefinition();}
else if(aFragment == deuteron){LastFragment=G4AntiDeuteron::AntiDeuteronDefinition();}
else if(aFragment == triton) {LastFragment=G4AntiTriton::AntiTritonDefinition();}
else if(aFragment == He3) {LastFragment=G4AntiHe3::AntiHe3Definition();}
else if(aFragment == He4) {LastFragment=G4AntiAlpha::AntiAlphaDefinition();}
else {}
aPrecoResult->operator[](ll)->SetDefinitionAndUpdateE(LastFragment);
}
#ifdef debugPrecoInt
G4cout<<"Projectile fragment "<<ll<<" "
<<aPrecoResult->operator[](ll)->GetDefinition()->GetParticleName()<<" "
<<aPrecoResult->operator[](ll)->GetMomentum()<<" "
<<aPrecoResult->operator[](ll)->GetTotalEnergy()<<" "
<<aPrecoResult->operator[](ll)->GetMass()<<G4endl;
#endif
//Uzhi
theTotalResult->push_back(aPrecoResult->operator[](ll));
}
delete aPrecoResult;
}
return theTotalResult;
}