Import Geant4 9.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 15:37:50 +02:00
parent a8e9364cea
commit 96c8bcd0af
6923 changed files with 198390 additions and 41849 deletions
@@ -0,0 +1,770 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "G4QMDCollision.hh"
#include "G4ParticleDefinition.hh"
#include "G4Scatterer.hh"
#include "Randomize.hh"
#include "G4PionZero.hh"
G4QMDCollision::G4QMDCollision()
: deltar ( 4 )
, bcmax0 ( 1.323142 ) // NN maximum impact parameter
, bcmax1 ( 2.523 ) // others maximum impact parameter
, sig0 ( 55 ) // NN cross section
, sig1 ( 200 ) // others cross section
, epse ( 0.0001 )
{
theScatterer = new G4Scatterer();
}
G4QMDCollision::~G4QMDCollision()
{
delete theScatterer;
}
void G4QMDCollision::CalKinematicsOfBinaryCollisions()
{
G4int n = theSystem->GetTotalNumberOfParticipant();
//071101
for ( G4int i = 0 ; i < n ; i++ )
{
//std::cout << i << " " << theSystem->GetParticipant( i )->GetDefinition()->GetParticleName() << " " << theSystem->GetParticipant( i )->GetPosition() << std::endl;
if ( theSystem->GetParticipant( i )->GetDefinition()->IsShortLived() )
{
G4ParticleDefinition* pd0 = theSystem->GetParticipant( i )->GetDefinition();
G4ThreeVector p0 = theSystem->GetParticipant( i )->GetMomentum();
G4ThreeVector r0 = theSystem->GetParticipant( i )->GetPosition();
G4LorentzVector p40 = theSystem->GetParticipant( i )->Get4Momentum();
G4double epot = theMeanField->GetTotalPotential();
G4double eini = epot + p40.e();
G4int n0 = theSystem->GetTotalNumberOfParticipant();
G4int i0 = 0;
G4bool isThisEnergyOK = false;
for ( G4int ii = 0 ; ii < 4 ; ii++ )
{
//G4LorentzVector p4 = theSystem->GetParticipant( i )->Get4Momentum();
G4LorentzVector p400 = p40;
p400 *= GeV;
//G4KineticTrack kt( theSystem->GetParticipant( i )->GetDefinition() , 0.0 , (theSystem->GetParticipant( i )->GetPosition())*fermi , p4 );
G4KineticTrack kt( pd0 , 0.0 , r0*fermi , p400 );
// std::cout << "G4KineticTrack " << i << " " << kt.GetDefinition()->GetParticleName() << kt.GetPosition() << std::endl;
G4KineticTrackVector* secs = NULL;
secs = kt.Decay();
G4int id = 0;
G4double et = 0;
if ( secs )
{
for ( G4KineticTrackVector::iterator it
= secs->begin() ; it != secs->end() ; it++ )
{
// std::cout << "G4KineticTrack"
// << " " << (*it)->GetDefinition()->GetParticleName()
// << " " << (*it)->Get4Momentum()
// << " " << (*it)->GetPosition()/fermi
// << std::endl;
if ( id == 0 )
{
theSystem->GetParticipant( i )->SetDefinition( (*it)->GetDefinition() );
theSystem->GetParticipant( i )->SetMomentum( (*it)->Get4Momentum().v()/GeV );
theSystem->GetParticipant( i )->SetPosition( (*it)->GetPosition()/fermi );
//theMeanField->Cal2BodyQuantities( i );
et += (*it)->Get4Momentum().e()/GeV;
}
if ( id > 0 )
{
// Append end;
theSystem->SetParticipant ( new G4QMDParticipant ( (*it)->GetDefinition() , (*it)->Get4Momentum().v()/GeV , (*it)->GetPosition()/fermi ) );
et += (*it)->Get4Momentum().e()/GeV;
if ( id > 1 )
{
// std::cout << "NAGISA id >2; id= " << id << std::endl;
}
}
id++;
delete *it;
}
theMeanField->SetSystem ( theSystem );
i0 = id-1; // 0 enter to i
}
// EnergyCheck
G4double epot = theMeanField->GetTotalPotential();
G4double efin = epot + et;
//std::cout << std::abs ( eini - efin ) - epse << std::endl;
// std::cout << std::abs ( eini - efin ) - epse*10 << std::endl;
//071031
// *10 TK
if ( std::abs ( eini - efin ) < epse*10 )
{
// Energy OK
// std::cout << "Decay Succeeded Energy OK" << std::endl;
isThisEnergyOK = true;
break;
}
else
{
for ( G4int i0i = 0 ; i0i < id-1 ; i0i++ )
{
// std::cout << "Decay Energitically Blocked deleteing " << i0i+n0 << std::endl;
theSystem->DeleteParticipant( i0i+n0 );
}
}
}
// Pauli Check
if ( isThisEnergyOK == true )
{
// if ( theMeanField->IsPauliBlocked ( i ) != true )
{
bool allOK = true;
for ( G4int i0i = 0 ; i0i < i0 ; i0i++ )
{
if ( theMeanField->IsPauliBlocked ( i0i+n0 ) == true )
{
allOK = false;
break;
}
}
// if ( allOK ) std::cout << "Decay Succeeded" << std::endl;
if ( allOK ) continue; //Do not Pauli Blocked
}
}
//
// std::cout << "Decay Blocked" << std::endl;
theSystem->GetParticipant( i )->SetDefinition( pd0 );
theSystem->GetParticipant( i )->SetPosition( r0 );
theSystem->GetParticipant( i )->SetMomentum( p0 );
if ( isThisEnergyOK == true )
{
for ( G4int i0i = 0 ; i0i < i0 ; i0i++ )
{
// std::cout << "Decay Blocked deleteing " << i0i+n0 << std::endl;
theSystem->DeleteParticipant( i0i+n0 );
}
}
}
}
//071101
n = theSystem->GetTotalNumberOfParticipant();
//std::cout << "Collision n " << n << std::endl;
std::vector< G4bool > isCollided ( n , false );
for ( G4int i = 1 ; i < n ; i++ )
{
//std::cout << "Collision i " << i << std::endl;
G4ThreeVector ri = theSystem->GetParticipant( i )->GetPosition();
G4LorentzVector p4i = theSystem->GetParticipant( i )->Get4Momentum();
G4double rmi = theSystem->GetParticipant( i )->GetMass();
G4ParticleDefinition* pdi = theSystem->GetParticipant( i )->GetDefinition();
//std::cout << " p4i00 " << p4i << std::endl;
for ( G4int j = 0 ; j < i ; j++ )
{
// std::cout << "Collision " << i << " " << j << std::endl;
/*
std::cout << "Collision " << i << " " << theSystem->GetParticipant( i )->IsThisProjectile() << std::endl;
std::cout << "Collision " << j << " " << theSystem->GetParticipant( j )->IsThisProjectile() << std::endl;
std::cout << "Collision " << i << " " << theSystem->GetParticipant( i )->IsThisTarget() << std::endl;
std::cout << "Collision " << j << " " << theSystem->GetParticipant( j )->IsThisTarget() << std::endl;
*/
// Only 1 Collision allowed for each particle in a time step.
if ( isCollided[ i ] == true ) continue;
if ( isCollided[ j ] == true ) continue;
// Do not allow collision between nucleons in target/projectile til its first collision.
if ( theSystem->GetParticipant( i )->IsThisProjectile() )
{
if ( theSystem->GetParticipant( j )->IsThisProjectile() ) continue;
}
else if ( theSystem->GetParticipant( i )->IsThisTarget() )
{
if ( theSystem->GetParticipant( j )->IsThisTarget() ) continue;
}
G4ThreeVector rj = theSystem->GetParticipant( j )->GetPosition();
G4LorentzVector p4j = theSystem->GetParticipant( j )->Get4Momentum();
G4double rmj = theSystem->GetParticipant( j )->GetMass();
G4ParticleDefinition* pdj = theSystem->GetParticipant( j )->GetDefinition();
G4double rr2 = theMeanField->GetRR2( i , j );
// Here we assume elab (beam momentum less than 5 GeV/n )
if ( rr2 > deltar*deltar ) continue;
G4double s = (p4i+p4j)*(p4i+p4j);
G4double srt = std::sqrt ( s );
G4double cutoff = 0.0;
G4double bcmax = 0.0;
G4double sig = 0.0;
if ( rmi < 0.94 && rmj < 0.94 )
{
// nucleon or pion case
cutoff = rmi + rmj + 0.02;
bcmax = bcmax0;
sig = sig0;
}
else
{
cutoff = rmi + rmj;
bcmax = bcmax1;
sig = sig1;
}
//std::cout << "Collision cutoff " << i << " " << j << " " << cutoff << std::endl;
if ( srt < cutoff ) continue;
G4ThreeVector dr = ri - rj;
G4double rsq = dr*dr;
G4double pij = p4i*p4j;
G4double pidr = p4i.vect()*dr;
G4double pjdr = p4j.vect()*dr;
G4double aij = 1.0 - ( rmi*rmj /pij ) * ( rmi*rmj /pij );
G4double bij = pidr / rmi - pjdr*rmi/pij;
G4double cij = rsq + ( pidr / rmi ) * ( pidr / rmi );
G4double brel = std::sqrt ( std::abs ( cij - bij*bij/aij ) );
if ( brel > bcmax ) continue;
//std::cout << "collisions3 " << std::endl;
G4double bji = -pjdr/rmj + pidr * rmj /pij;
G4double ti = ( pidr/rmi - bij / aij ) * p4i.e() / rmi;
G4double tj = (-pjdr/rmj - bji / aij ) * p4j.e() / rmj;
G4double deltaT = 0.0;
deltaT = 1.0; // TK
/*
std::cout << "collisions4 p4i " << p4i << std::endl;
std::cout << "collisions4 ri " << ri << std::endl;
std::cout << "collisions4 p4j " << p4j << std::endl;
std::cout << "collisions4 rj " << rj << std::endl;
std::cout << "collisions4 dr " << dr << std::endl;
std::cout << "collisions4 pij " << pij << std::endl;
std::cout << "collisions4 aij " << aij << std::endl;
std::cout << "collisions4 bij bji " << bij << " " << bji << std::endl;
std::cout << "collisions4 pidr pjdr " << pidr << " " << pjdr << std::endl;
std::cout << "collisions4 p4i.e() p4j.e() " << p4i.e() << " " << p4j.e() << std::endl;
std::cout << "collisions4 rmi rmj " << rmi << " " << rmj << std::endl;
std::cout << "collisions4 " << ti << " " << tj << std::endl;
*/
if ( std::abs ( ti + tj ) > deltaT ) continue;
//std::cout << "collisions4 " << std::endl;
G4ThreeVector beta = ( p4i + p4j ).boostVector();
G4LorentzVector p = p4i;
G4LorentzVector p4icm = p.boost( p.findBoostToCM ( p4j ) );
G4ThreeVector pcm = p4icm.vect();
G4double prcm = pcm.mag();
if ( prcm <= 0.00001 ) continue;
//std::cout << "collisions5 " << std::endl;
G4bool energetically_forbidden = !( CalFinalStateOfTheBinaryCollision ( i , j ) ); // Use Geant4 Collision Library
//G4bool energetically_forbidden = !( CalFinalStateOfTheBinaryCollisionJQMD ( sig , cutoff , pcm , prcm , srt, beta , gamma , i , j ) ); // JQMD Elastic
G4bool pauli_blocked = false;
if ( energetically_forbidden != true )
{
if ( theMeanField->IsPauliBlocked ( i ) == true || theMeanField->IsPauliBlocked ( j ) == true )
{
pauli_blocked = true;
//std::cout << "G4QMDRESULT Collsion Pauli Blocked " << std::endl;
}
}
else
{
//std::cout << "G4QMDRESULT Collsion Blocked " << std::endl;
}
/*
std::cout << "G4QMDRESULT Collsion initial p4 i and j "
<< p4i << " " << p4j
<< std::endl;
*/
if ( energetically_forbidden == true || pauli_blocked == true )
{
// Collsion not allowed then re enter orginal participants
// Now only momentum, becasuse we only consider elastic scattering of nucleons
theSystem->GetParticipant( i )->SetMomentum( p4i.vect() );
theSystem->GetParticipant( i )->SetDefinition( pdi );
theSystem->GetParticipant( i )->SetPosition( ri );
theSystem->GetParticipant( j )->SetMomentum( p4j.vect() );
theSystem->GetParticipant( j )->SetDefinition( pdj );
theSystem->GetParticipant( j )->SetPosition( rj );
}
else
{
// Collsion allowed (really happened)
// Unset Projectile/Target flag
theSystem->GetParticipant( i )->UnsetInitialMark();
theSystem->GetParticipant( j )->UnsetInitialMark();
isCollided[ i ] = true;
isCollided[ j ] = true;
theSystem->IncrementCollisionCounter();
/*
std::cout << "G4QMDRESULT Collsion Really Happened between "
<< i << " and " << j
<< std::endl;
std::cout << "G4QMDRESULT Collsion initial p4 i and j "
<< p4i << " " << p4j
<< std::endl;
std::cout << "G4QMDRESULT Collsion after p4 i and j "
<< theSystem->GetParticipant( i )->Get4Momentum()
<< " "
<< theSystem->GetParticipant( j )->Get4Momentum()
<< std::endl;
std::cout << "G4QMDRESULT Collsion Diff "
<< p4i + p4j - theSystem->GetParticipant( i )->Get4Momentum() - theSystem->GetParticipant( j )->Get4Momentum()
<< std::endl;
std::cout << "G4QMDRESULT Collsion initial r i and j "
<< ri << " " << rj
<< std::endl;
std::cout << "G4QMDRESULT Collsion after r i and j "
<< theSystem->GetParticipant( i )->GetPosition()
<< " "
<< theSystem->GetParticipant( j )->GetPosition()
<< std::endl;
*/
}
// theMeanField
}
}
//071106
n = theSystem->GetTotalNumberOfParticipant();
G4bool isThisModefied = false;
for ( G4int i = 0 ; i < n ; i++ )
{
if ( theSystem->GetParticipant( i )->GetDefinition() == G4PionZero::PionZero() )
{
if ( theSystem->GetParticipant( i )->GetPosition().mag() > 1.0e9 )
{
// std::cout << "Deleting " << i << " " << theSystem->GetParticipant( i )->GetPosition().mag() << std::endl;
theSystem->DeleteParticipant( i );
isThisModefied = true;
}
}
}
if ( isThisModefied == true ) theMeanField->SetSystem ( theSystem );
//071106
}
G4bool G4QMDCollision::CalFinalStateOfTheBinaryCollision( G4int i , G4int j )
{
//G4cout << "CalFinalStateOfTheBinaryCollision " << G4endl;
G4bool result = true;
G4LorentzVector p4i = theSystem->GetParticipant( i )->Get4Momentum();
G4LorentzVector p4j = theSystem->GetParticipant( j )->Get4Momentum();
//071031
// will use KineticTrack
G4LorentzVector p4ix = p4i*GeV;
G4LorentzVector p4jx = p4j*GeV;
G4ThreeVector rix = (theSystem->GetParticipant( i )->GetPosition())*fermi;
G4ThreeVector rjx = (theSystem->GetParticipant( j )->GetPosition())*fermi;
//071031
G4double epot = theMeanField->GetTotalPotential();
G4double eini = epot + p4i.e() + p4j.e();
//071031
G4ParticleDefinition* pdi0 =theSystem->GetParticipant( i )->GetDefinition();
G4ParticleDefinition* pdj0 =theSystem->GetParticipant( j )->GetDefinition();
G4ThreeVector ri0 =(theSystem->GetParticipant( i )->GetPosition())*fermi;
G4ThreeVector rj0 =(theSystem->GetParticipant( j )->GetPosition())*fermi;
for ( G4int iitry = 0 ; iitry < 4 ; iitry++ )
{
G4KineticTrack kt1( pdi0 , 0.0 , ri0 , p4ix );
G4KineticTrack kt2( pdj0 , 0.0 , rj0 , p4jx );
G4LorentzVector p4ix_new;
G4LorentzVector p4jx_new;
G4KineticTrackVector* secs = NULL;
secs = theScatterer->Scatter( kt1 , kt2 );
//std::cout << "G4QMDSCATTERER BEFORE " << kt1.GetDefinition()->GetParticleName() << " " << kt1.Get4Momentum()/GeV << " " << kt1.GetPosition()/fermi << std::endl;
//std::cout << "G4QMDSCATTERER BEFORE " << kt2.GetDefinition()->GetParticleName() << " " << kt2.Get4Momentum()/GeV << " " << kt2.GetPosition()/fermi << std::endl;
//std::cout << "THESCATTERER " << theScatterer->GetCrossSection ( kt1 , kt2 )/millibarn << " " << elastic << " " << sig << std::endl;
if ( secs )
{
G4int iti = 0;
if ( secs->size() == 2 )
{
for ( G4KineticTrackVector::iterator it
= secs->begin() ; it != secs->end() ; it++ )
{
if ( iti == 0 )
{
theSystem->GetParticipant( i )->SetDefinition( (*it)->GetDefinition() );
p4ix_new = (*it)->Get4Momentum()/GeV;
//std::cout << "THESCATTERER " << (*it)->GetDefinition()->GetParticleName() << std::endl;
theSystem->GetParticipant( i )->SetMomentum( p4ix_new.v() );
}
if ( iti == 1 )
{
theSystem->GetParticipant( j )->SetDefinition( (*it)->GetDefinition() );
p4jx_new = (*it)->Get4Momentum()/GeV;
//std::cout << "THESCATTERER " << p4jx_new.e()-p4jx_new.m() << std::endl;
theSystem->GetParticipant( j )->SetMomentum( p4jx_new.v() );
}
//std::cout << "G4QMDSCATTERER AFTER " << (*it)->GetDefinition()->GetParticleName() << " " << (*it)->Get4Momentum()/GeV << std::endl;
iti++;
}
}
else
{
//std::cout << "NAGISA pion absrorption " << secs->front()->GetDefinition()->GetParticleName() << std::endl;
//secs->front()->Decay();
theSystem->GetParticipant( i )->SetDefinition( secs->front()->GetDefinition() );
p4ix_new = secs->front()->Get4Momentum()/GeV;
theSystem->GetParticipant( i )->SetMomentum( p4ix_new.v() );
//std::cout << "THESCATTERER " << (*it)->GetDefinition()->GetParticleName() << std::endl;
p4jx_new( 0 );
//theSystem->GetParticipant( j )->SetDefinition( G4Gamma::Gamma() );
//theSystem->GetParticipant( j )->SetDefinition( G4Neutron::Neutron() );
theSystem->GetParticipant( j )->SetDefinition( G4PionZero::PionZero() );
theSystem->GetParticipant( j )->SetMomentum( G4ThreeVector( G4UniformRand() )*eV );
theSystem->GetParticipant( j )->SetPosition( G4ThreeVector( 1000, 1000, 1000 )*km );
}
if ( secs->size() > 2 ) std::cout << "NAGISA secs size > 2; " << secs->size() << std::endl;
// deleteing KineticTrack
for ( G4KineticTrackVector::iterator it
= secs->begin() ; it != secs->end() ; it++ )
{
delete *it;
}
}
//071031
theMeanField->Cal2BodyQuantities( i );
theMeanField->Cal2BodyQuantities( j );
epot = theMeanField->GetTotalPotential();
G4double efin = epot + p4ix_new.e() + p4jx_new.e();
//std::cout << "Collision NEW epot " << i << " " << j << " " << epot << " " << std::abs ( eini - efin ) - epse << std::endl;
/*
std::cout << "Collision efin " << i << " " << j << " " << efin << std::endl;
std::cout << "Collision " << i << " " << j << " " << std::abs ( eini - efin ) << " " << epse << std::endl;
std::cout << "Collision " << std::abs ( eini - efin ) << " " << epse << std::endl;
*/
//071031
if ( std::abs ( eini - efin ) < epse )
{
// Collison OK
//std::cout << "collisions6" << std::endl;
//std::cout << "collisions before " << p4i << " " << p4j << std::endl;
//std::cout << "collisions after " << theSystem->GetParticipant( i )->Get4Momentum() << " " << theSystem->GetParticipant( j )->Get4Momentum() << std::endl;
//std::cout << "collisions dif " << ( p4i + p4j ) - ( theSystem->GetParticipant( i )->Get4Momentum() + theSystem->GetParticipant( j )->Get4Momentum() ) << std::endl;
//std::cout << "collisions before " << rix/fermi << " " << rjx/fermi << std::endl;
//std::cout << "collisions after " << theSystem->GetParticipant( i )->GetPosition() << " " << theSystem->GetParticipant( j )->GetPosition() << std::endl;
}
//071031
if ( std::abs ( eini - efin ) < epse ) return result; // Collison OK
}
// Energetically forbidden collision
result = false;
return result;
}
G4bool G4QMDCollision::CalFinalStateOfTheBinaryCollisionJQMD( G4double sig , G4double cutoff , G4ThreeVector pcm , G4double prcm , G4double srt , G4ThreeVector beta , G4double gamma , G4int i , G4int j )
{
//G4cout << "CalFinalStateOfTheBinaryCollisionJQMD" << G4endl;
G4bool result = true;
G4LorentzVector p4i = theSystem->GetParticipant( i )->Get4Momentum();
G4double rmi = theSystem->GetParticipant( i )->GetMass();
G4int zi = theSystem->GetParticipant( i )->GetChargeInUnitOfEplus();
G4LorentzVector p4j = theSystem->GetParticipant( j )->Get4Momentum();
G4double rmj = theSystem->GetParticipant( j )->GetMass();
G4int zj = theSystem->GetParticipant( j )->GetChargeInUnitOfEplus();
G4double pr = prcm;
G4double c2 = pcm.z()/pr;
G4double csrt = srt - cutoff;
//G4double pri = prcm;
//G4double prf = sqrt ( 0.25 * srt*srt -rm2 );
G4double asrt = srt - rmi - rmj;
G4double pra = prcm;
G4double elastic = 0.0;
if ( zi == zj )
{
if ( csrt < 0.4286 )
{
elastic = 35.0 / ( 1. + csrt * 100.0 ) + 20.0;
}
else
{
elastic = ( - std::atan( ( csrt - 0.4286 ) * 1.5 - 0.8 )
* 2. / pi + 1.0 ) * 9.65 + 7.0;
}
}
else
{
if ( csrt < 0.4286 )
{
elastic = 28.0 / ( 1. + csrt * 100.0 ) + 27.0;
}
else
{
elastic = ( - std::atan( ( csrt - 0.4286 ) * 1.5 - 0.8 )
* 2. / pi + 1.0 ) * 12.34 + 10.0;
}
}
// std::cout << "Collision csrt " << i << " " << j << " " << csrt << std::endl;
// std::cout << "Collision elstic " << i << " " << j << " " << elastic << std::endl;
// std::cout << "Collision sig " << i << " " << j << " " << sig << std::endl;
if ( G4UniformRand() > elastic / sig )
{
//std::cout << "Inelastic " << std::endl;
//std::cout << "elastic/sig " << elastic/sig << std::endl;
return result;
}
else
{
//std::cout << "Elastic " << std::endl;
}
// std::cout << "Collision ELSTIC " << i << " " << j << std::endl;
G4double as = std::pow ( 3.65 * asrt , 6 );
G4double a = 6.0 * as / (1.0 + as);
G4double ta = -2.0 * pra*pra;
G4double x = G4UniformRand();
G4double t1 = std::log( (1-x) * std::exp(2.*a*ta) + x ) / a;
G4double c1 = 1.0 - t1/ta;
if( std::abs(c1) > 1.0 ) c1 = 2.0 * x - 1.0;
/*
std::cout << "Collision as " << i << " " << j << " " << as << std::endl;
std::cout << "Collision a " << i << " " << j << " " << a << std::endl;
std::cout << "Collision ta " << i << " " << j << " " << ta << std::endl;
std::cout << "Collision x " << i << " " << j << " " << x << std::endl;
std::cout << "Collision t1 " << i << " " << j << " " << t1 << std::endl;
std::cout << "Collision c1 " << i << " " << j << " " << c1 << std::endl;
*/
t1 = 2.0*pi*G4UniformRand();
// std::cout << "Collision t1 " << i << " " << j << " " << t1 << std::endl;
G4double t2 = 0.0;
if ( pcm.x() == 0.0 && pcm.y() == 0 )
{
t2 = 0.0;
}
else
{
t2 = std::atan2( pcm.y() , pcm.x() );
}
// std::cout << "Collision t2 " << i << " " << j << " " << t2 << std::endl;
G4double s1 = std::sqrt ( 1.0 - c1*c1 );
G4double s2 = std::sqrt ( 1.0 - c2*c2 );
G4double ct1 = std::cos(t1);
G4double st1 = std::sin(t1);
G4double ct2 = std::cos(t2);
G4double st2 = std::sin(t2);
G4double ss = c2*s1*ct1 + s2*c1;
pcm.setX( pr * ( ss*ct2 - s1*st1*st2) );
pcm.setY( pr * ( ss*st2 + s1*st1*ct2) );
pcm.setZ( pr * ( c1*c2 - s1*s2*ct1) );
// std::cout << "Collision pcm " << i << " " << j << " " << pcm << std::endl;
G4double epot = theMeanField->GetTotalPotential();
G4double eini = epot + p4i.e() + p4j.e();
G4double etwo = p4i.e() + p4j.e();
/*
std::cout << "Collision epot " << i << " " << j << " " << epot << std::endl;
std::cout << "Collision eini " << i << " " << j << " " << eini << std::endl;
std::cout << "Collision etwo " << i << " " << j << " " << etwo << std::endl;
*/
for ( G4int itry = 0 ; itry < 4 ; itry++ )
{
G4double eicm = std::sqrt ( rmi*rmi + pcm*pcm );
G4double pibeta = pcm*beta;
G4double trans = gamma * ( gamma * pibeta / ( gamma + 1 ) + eicm );
G4ThreeVector pi_new = beta*trans + pcm;
G4double ejcm = std::sqrt ( rmj*rmj + pcm*pcm );
trans = gamma * ( gamma * pibeta / ( gamma + 1 ) + ejcm );
G4ThreeVector pj_new = beta*trans - pcm;
//
// Delete old
// Add new Particitipants
//
// Now only change momentum ( Beacuse we only have elastic sctter of nucleon
// In future Definition also will be change
//
theSystem->GetParticipant( i )->SetMomentum( pi_new );
theSystem->GetParticipant( j )->SetMomentum( pj_new );
G4double pi_new_e = (theSystem->GetParticipant( i )->Get4Momentum()).e();
G4double pj_new_e = (theSystem->GetParticipant( j )->Get4Momentum()).e();
theMeanField->Cal2BodyQuantities( i );
theMeanField->Cal2BodyQuantities( j );
epot = theMeanField->GetTotalPotential();
G4double efin = epot + pi_new_e + pj_new_e ;
//std::cout << "Collision NEW epot " << i << " " << j << " " << epot << " " << std::abs ( eini - efin ) - epse << std::endl;
/*
std::cout << "Collision efin " << i << " " << j << " " << efin << std::endl;
std::cout << "Collision " << i << " " << j << " " << std::abs ( eini - efin ) << " " << epse << std::endl;
std::cout << "Collision " << std::abs ( eini - efin ) << " " << epse << std::endl;
*/
//071031
if ( std::abs ( eini - efin ) < epse )
{
// Collison OK
//std::cout << "collisions6" << std::endl;
//std::cout << "collisions before " << p4i << " " << p4j << std::endl;
//std::cout << "collisions after " << theSystem->GetParticipant( i )->Get4Momentum() << " " << theSystem->GetParticipant( j )->Get4Momentum() << std::endl;
//std::cout << "collisions dif " << ( p4i + p4j ) - ( theSystem->GetParticipant( i )->Get4Momentum() + theSystem->GetParticipant( j )->Get4Momentum() ) << std::endl;
//std::cout << "collisions before " << rix/fermi << " " << rjx/fermi << std::endl;
//std::cout << "collisions after " << theSystem->GetParticipant( i )->GetPosition() << " " << theSystem->GetParticipant( j )->GetPosition() << std::endl;
}
//071031
if ( std::abs ( eini - efin ) < epse ) return result; // Collison OK
G4double cona = ( eini - efin + etwo ) / gamma;
G4double fac2 = 1.0 / ( 4.0 * cona*cona * pr*pr ) *
( ( cona*cona - ( rmi*rmi + rmj*rmj ) )*( cona*cona - ( rmi*rmi + rmj*rmj ) )
- 4.0 * rmi*rmi * rmj*rmj );
if ( fac2 > 0 )
{
G4double fact = std::sqrt ( fac2 );
pcm = fact*pcm;
}
}
// Energetically forbidden collision
result = false;
return result;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,894 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "G4QMDMeanField.hh"
#include "G4QMDParameters.hh"
#include "Randomize.hh"
#include <CLHEP/Random/Stat.h>
#include <map>
#include <algorithm>
#include <numeric>
G4QMDMeanField::G4QMDMeanField()
: rclds ( 4.0 ) // distance for cluster judgement
, epsx ( -20.0 ) // gauss term
, epscl ( 0.0001 ) // coulomb term
, irelcr ( 1 )
{
G4QMDParameters* parameters = G4QMDParameters::GetInstance();
wl = parameters->Get_wl();
cl = parameters->Get_cl();
rho0 = parameters->Get_rho0();
hbc = parameters->Get_hbc();
gamm = parameters->Get_gamm();
cpw = parameters->Get_cpw();
cph = parameters->Get_cph();
cpc = parameters->Get_cpc();
c0 = parameters->Get_c0();
c3 = parameters->Get_c3();
cs = parameters->Get_cs();
// distance
c0w = 1.0/4.0/wl;
//c3w = 1.0/4.0/wl; //no need
c0sw = std::sqrt( c0w );
clw = 2.0 / std::sqrt ( 4.0 * pi * wl );
// graduate
c0g = - c0 / ( 2.0 * wl );
c3g = - c3 / ( 4.0 * wl ) * gamm;
csg = - cs / ( 2.0 * wl );
pag = gamm - 1;
}
G4QMDMeanField::~G4QMDMeanField()
{
;
}
void G4QMDMeanField::SetSystem ( G4QMDSystem* aSystem )
{
//std::cout << "QMDMeanField SetSystem" << std::endl;
system = aSystem;
G4int n = system->GetTotalNumberOfParticipant();
pp2.clear();
rr2.clear();
rbij.clear();
rha.clear();
rhe.clear();
rhc.clear();
rr2.resize( n );
pp2.resize( n );
rbij.resize( n );
rha.resize( n );
rhe.resize( n );
rhc.resize( n );
for ( int i = 0 ; i < n ; i++ )
{
rr2[i].resize( n );
pp2[i].resize( n );
rbij[i].resize( n );
rha[i].resize( n );
rhe[i].resize( n );
rhc[i].resize( n );
}
ffr.clear();
ffp.clear();
rh3d.clear();
ffr.resize( n );
ffp.resize( n );
rh3d.resize( n );
Cal2BodyQuantities();
}
void G4QMDMeanField::SetNucleus ( G4QMDNucleus* aNucleus )
{
//std::cout << "QMDMeanField SetNucleus" << std::endl;
SetSystem( aNucleus );
G4double totalPotential = GetTotalPotential();
aNucleus->SetTotalPotential( totalPotential );
aNucleus->CalEnergyAndAngularMomentumInCM();
}
void G4QMDMeanField::Cal2BodyQuantities()
{
if ( system->GetTotalNumberOfParticipant() < 2 ) return;
for ( G4int j = 1 ; j < system->GetTotalNumberOfParticipant() ; j++ )
{
G4ThreeVector rj = system->GetParticipant( j )->GetPosition();
G4LorentzVector p4j = system->GetParticipant( j )->Get4Momentum();
for ( G4int i = 0 ; i < j ; i++ )
{
G4ThreeVector ri = system->GetParticipant( i )->GetPosition();
G4LorentzVector p4i = system->GetParticipant( i )->Get4Momentum();
G4ThreeVector rij = ri - rj;
G4ThreeVector pij = (p4i - p4j).v();
G4LorentzVector p4ij = p4i - p4j;
G4ThreeVector bij = ( p4i + p4j ).boostVector();
G4double gammaij = ( p4i + p4j ).gamma();
G4double eij = ( p4i + p4j ).e();
G4double rbrb = rij*bij;
// G4double bij2 = bij*bij;
G4double rij2 = rij*rij;
G4double pij2 = pij*pij;
rbrb = irelcr * rbrb;
G4double gamma2_ij = gammaij*gammaij;
rr2[i][j] = rij2 + gamma2_ij * rbrb*rbrb;
rr2[j][i] = rr2[i][j];
rbij[i][j] = gamma2_ij * rbrb;
rbij[j][i] = - rbij[i][j];
pp2[i][j] = pij2
+ irelcr * ( - std::pow ( p4i.e() - p4j.e() , 2 )
+ gamma2_ij * std::pow ( ( ( p4i.m2() - p4j.m2() ) / eij ) , 2 ) );
pp2[j][i] = pp2[i][j];
// Gauss term
G4double expa1 = - rr2[i][j] * c0w;
G4double rh1;
if ( expa1 > epsx )
{
rh1 = std::exp( expa1 );
}
else
{
rh1 = 0.0;
}
G4int ibry = system->GetParticipant(i)->GetBaryonNumber();
G4int jbry = system->GetParticipant(j)->GetBaryonNumber();
rha[i][j] = ibry*jbry*rh1;
rha[j][i] = rha[i][j];
// Coulomb terms
G4double rrs2 = rr2[i][j] + epscl;
G4double rrs = std::sqrt ( rrs2 );
G4int icharge = system->GetParticipant(i)->GetChargeInUnitOfEplus();
G4int jcharge = system->GetParticipant(j)->GetChargeInUnitOfEplus();
G4double erf = 0.0;
// T. K. add this protection. 5.8 is good enough for double
if ( rrs*c0sw < 5.8 )
erf = CLHEP::HepStat::erf ( rrs*c0sw );
else
erf = 1.0;
G4double erfij = erf/rrs;
rhe[i][j] = icharge*jcharge * erfij;
rhe[j][i] = rhe[i][j];
rhc[i][j] = icharge*jcharge * ( - erfij + clw * rh1 ) / rrs2;
rhc[j][i] = rhc[i][j];
} // i
} // j
}
void G4QMDMeanField::Cal2BodyQuantities( G4int i )
{
//std::cout << "Cal2BodyQuantities " << i << std::endl;
G4ThreeVector ri = system->GetParticipant( i )->GetPosition();
G4LorentzVector p4i = system->GetParticipant( i )->Get4Momentum();
for ( G4int j = 0 ; j < system->GetTotalNumberOfParticipant() ; j ++ )
{
if ( j == i ) continue;
G4ThreeVector rj = system->GetParticipant( j )->GetPosition();
G4LorentzVector p4j = system->GetParticipant( j )->Get4Momentum();
G4ThreeVector rij = ri - rj;
G4ThreeVector pij = (p4i - p4j).v();
G4LorentzVector p4ij = p4i - p4j;
G4ThreeVector bij = ( p4i + p4j ).boostVector();
G4double gammaij = ( p4i + p4j ).gamma();
G4double eij = ( p4i + p4j ).e();
G4double rbrb = rij*bij;
// G4double bij2 = bij*bij;
G4double rij2 = rij*rij;
G4double pij2 = pij*pij;
rbrb = irelcr * rbrb;
G4double gamma2_ij = gammaij*gammaij;
/*
G4double rbrb = 0.0;
G4double beta2_ij = 0.0;
G4double rij2 = 0.0;
G4double pij2 = 0.0;
//
G4LorentzVector p4ip4j = p4i + p4j;
G4double eij = p4ip4j.e();
G4ThreeVector r = ri - rj;
G4LorentzVector p4 = p4i - p4j;
rbrb = r.x()*p4ip4j.x()/eij
+ r.y()*p4ip4j.y()/eij
+ r.z()*p4ip4j.z()/eij;
beta2_ij = ( p4ip4j.x()*p4ip4j.x() + p4ip4j.y()*p4ip4j.y() + p4ip4j.z()*p4ip4j.z() ) / ( eij*eij );
rij2 = r*r;
pij2 = p4.v()*p4.v();
rbrb = irelcr * rbrb;
G4double gamma2_ij = 1 / ( 1 - beta2_ij );
*/
rr2[i][j] = rij2 + gamma2_ij * rbrb*rbrb;
rr2[j][i] = rr2[i][j];
rbij[i][j] = gamma2_ij * rbrb;
rbij[j][i] = - rbij[i][j];
pp2[i][j] = pij2
+ irelcr * ( - std::pow ( p4i.e() - p4j.e() , 2 )
+ gamma2_ij * std::pow ( ( ( p4i.m2() - p4j.m2() ) / eij ) , 2 ) );
pp2[j][i] = pp2[i][j];
// Gauss term
G4double expa1 = - rr2[i][j] * c0w;
G4double rh1;
if ( expa1 > epsx )
{
rh1 = std::exp( expa1 );
}
else
{
rh1 = 0.0;
}
G4int ibry = system->GetParticipant(i)->GetBaryonNumber();
G4int jbry = system->GetParticipant(j)->GetBaryonNumber();
rha[i][j] = ibry*jbry*rh1;
rha[j][i] = rha[i][j];
// Coulomb terms
G4double rrs2 = rr2[i][j] + epscl;
G4double rrs = std::sqrt ( rrs2 );
G4int icharge = system->GetParticipant(i)->GetChargeInUnitOfEplus();
G4int jcharge = system->GetParticipant(j)->GetChargeInUnitOfEplus();
G4double erf = 0.0;
// T. K. add this protection. 5.8 is good enough for double
if ( rrs*c0sw < 5.8 )
erf = CLHEP::HepStat::erf ( rrs*c0sw );
else
erf = 1.0;
G4double erfij = erf/rrs;
rhe[i][j] = icharge*jcharge * erfij;
rhe[j][i] = rhe[i][j];
// G4double clw;
rhc[i][j] = icharge*jcharge * ( - erfij + clw * rh1 ) / rrs2;
rhc[j][i] = rhc[i][j];
}
}
void G4QMDMeanField::CalGraduate()
{
ffr.resize( system->GetTotalNumberOfParticipant() );
ffp.resize( system->GetTotalNumberOfParticipant() );
rh3d.resize( system->GetTotalNumberOfParticipant() );
for ( G4int i = 0 ; i < system->GetTotalNumberOfParticipant() ; i ++ )
{
G4double rho3 = 0.0;
for ( G4int j = 0 ; j < system->GetTotalNumberOfParticipant() ; j ++ )
{
rho3 += rha[j][i];
}
rh3d[i] = std::pow ( rho3 , pag );
}
for ( G4int i = 0 ; i < system->GetTotalNumberOfParticipant() ; i ++ )
{
G4ThreeVector ri = system->GetParticipant( i )->GetPosition();
G4LorentzVector p4i = system->GetParticipant( i )->Get4Momentum();
G4ThreeVector betai = p4i.v()/p4i.e();
ffr[i] = betai;
ffp[i] = G4ThreeVector( 0.0 );
for ( G4int j = 0 ; j < system->GetTotalNumberOfParticipant() ; j ++ )
{
G4ThreeVector rj = system->GetParticipant( j )->GetPosition();
G4LorentzVector p4j = system->GetParticipant( j )->Get4Momentum();
G4double eij = p4i.e() + p4j.e();
G4int icharge = system->GetParticipant(i)->GetChargeInUnitOfEplus();
G4int jcharge = system->GetParticipant(j)->GetChargeInUnitOfEplus();
G4int inuc = system->GetParticipant(i)->GetNuc();
G4int jnuc = system->GetParticipant(j)->GetNuc();
G4double ccpp = c0g * rha[j][i]
+ c3g * rha[j][i] * ( rh3d[j] + rh3d[i] )
+ csg * rha[j][i] * jnuc * inuc
* ( 1. - 2. * std::abs( jcharge - icharge ) )
+ cl * rhc[j][i];
/*
std::cout << c0g << " " << c3g << " " << csg << " " << cl << std::endl;
std::cout << "ccpp " << i << " " << j << " " << ccpp << std::endl;
std::cout << "rha[j][i] " << rha[j][i] << std::endl;
std::cout << "rh3d " << rh3d[j] << " " << rh3d[i] << std::endl;
std::cout << "rhc[j][i] " << rhc[j][i] << std::endl;
*/
G4double grbb = - rbij[j][i];
G4double ccrr = grbb * ccpp / eij;
/*
std::cout << "ccrr " << ccrr << std::endl;
std::cout << "grbb " << grbb << std::endl;
*/
G4ThreeVector rij = ri - rj;
G4ThreeVector betaij = ( p4i + p4j ).v()/eij;
G4ThreeVector cij = betaij - betai;
ffr[i] = ffr[i] + 2*ccrr* ( rij + grbb*cij );
ffp[i] = ffp[i] - 2*ccpp* ( rij + grbb*betaij );
}
}
//std::cout << "gradu 0 " << ffr[0] << " " << ffp[0] << std::endl;
//std::cout << "gradu 1 " << ffr[1] << " " << ffp[1] << std::endl;
}
G4double G4QMDMeanField::GetTotalPotential()
{
G4int n = system->GetTotalNumberOfParticipant();
std::vector < G4double > rhoa ( n , 0.0 );
std::vector < G4double > rho3 ( n , 0.0 );
std::vector < G4double > rhos ( n , 0.0 );
std::vector < G4double > rhoc ( n , 0.0 );
for ( G4int i = 0 ; i < n ; i ++ )
{
G4int icharge = system->GetParticipant(i)->GetChargeInUnitOfEplus();
G4int inuc = system->GetParticipant(i)->GetNuc();
for ( G4int j = 0 ; j < n ; j ++ )
{
G4int jcharge = system->GetParticipant(j)->GetChargeInUnitOfEplus();
G4int jnuc = system->GetParticipant(j)->GetNuc();
rhoa[i] += rha[j][i];
rhoc[i] += rhe[j][i];
rhos[i] += rha[j][i] * jnuc * inuc
* ( 1 - 2 * std::abs ( jcharge - icharge ) );
}
rho3[i] = std::pow ( rhoa[i] , gamm );
}
G4double potential = c0 * std::accumulate( rhoa.begin() , rhoa.end() , 0.0 )
+ c3 * std::accumulate( rho3.begin() , rho3.end() , 0.0 )
+ cs * std::accumulate( rhos.begin() , rhos.end() , 0.0 )
+ cl * std::accumulate( rhoc.begin() , rhoc.end() , 0.0 );
return potential;
}
G4double G4QMDMeanField::calPauliBlockingFactor( G4int i )
{
G4double pf = 0.0;
// i is supposed beyond total number of Participant()
G4int icharge = system->GetParticipant(i)->GetChargeInUnitOfEplus();
for ( G4int j = 0 ; j < system->GetTotalNumberOfParticipant() ; j++ )
{
G4int jcharge = system->GetParticipant(j)->GetChargeInUnitOfEplus();
G4int jnuc = system->GetParticipant(j)->GetNuc();
if ( jcharge == icharge && jnuc == 1 )
{
/*
std::cout << "Pauli i j " << i << " " << j << std::endl;
std::cout << "Pauli icharge " << icharge << std::endl;
std::cout << "Pauli jcharge " << jcharge << std::endl;
*/
G4double expa = -rr2[i][j]*cpw;
if ( expa > epsx )
{
expa = expa - pp2[i][j]*cph;
/*
std::cout << "Pauli cph " << cph << std::endl;
std::cout << "Pauli pp2 " << pp2[i][j] << std::endl;
std::cout << "Pauli expa " << expa << std::endl;
std::cout << "Pauli epsx " << epsx << std::endl;
*/
if ( expa > epsx )
{
// std::cout << "Pauli phase " << pf << std::endl;
pf = pf + std::exp ( expa );
}
}
}
}
pf = ( pf - 1.0 ) * cpc;
//std::cout << "Pauli pf " << pf << std::endl;
return pf;
}
G4bool G4QMDMeanField::IsPauliBlocked( G4int i )
{
G4bool result = false;
if ( system->GetParticipant( i )->GetNuc() == 1 )
{
G4double pf = calPauliBlockingFactor( i );
G4double rand = G4UniformRand();
if ( pf > rand ) result = true;
}
return result;
}
void G4QMDMeanField::DoPropagation( G4double dt )
{
G4double c2 = 1.0;
G4double c1 = 1.0 - c2;
G4double c3 = 1.0 / 2.0 / c2;
G4double dt3 = dt * c3;
G4double dt1 = dt * ( c1 - c3 );
G4double dt2 = dt * c2;
CalGraduate();
G4int n = system->GetTotalNumberOfParticipant();
// 1st Step
std::vector< G4ThreeVector > f0r, f0p;
f0r.resize( n );
f0p.resize( n );
for ( G4int i = 0 ; i < n ; i++ )
{
G4ThreeVector ri = system->GetParticipant( i )->GetPosition();
G4ThreeVector p3i = system->GetParticipant( i )->GetMomentum();
ri += dt3* ffr[i];
p3i += dt3* ffp[i];
f0r[i] = ffr[i];
f0p[i] = ffp[i];
system->GetParticipant( i )->SetPosition( ri );
system->GetParticipant( i )->SetMomentum( p3i );
// we do not need set total momentum by ourselvs
}
// 2nd Step
Cal2BodyQuantities();
CalGraduate();
for ( G4int i = 0 ; i < n ; i++ )
{
G4ThreeVector ri = system->GetParticipant( i )->GetPosition();
G4ThreeVector p3i = system->GetParticipant( i )->GetMomentum();
ri += dt1* f0r[i] + dt2* ffr[i];
p3i += dt1* f0p[i] + dt2* ffp[i];
system->GetParticipant( i )->SetPosition( ri );
system->GetParticipant( i )->SetMomentum( p3i );
// we do not need set total momentum by ourselvs
}
Cal2BodyQuantities();
}
std::vector< G4QMDNucleus* > G4QMDMeanField::DoClusterJudgment()
{
//std::cout << "MeanField DoClusterJudgemnt" << std::endl;
Cal2BodyQuantities();
G4double cpf2 = std::pow ( 1.5 * pi*pi * std::pow ( 4.0 * pi * wl , -1.5 )
,
2./3. )
* hbc * hbc;
G4double rcc2 = rclds*rclds;
G4int n = system->GetTotalNumberOfParticipant();
std::vector < G4double > rhoa;
rhoa.resize ( n );
for ( G4int i = 0 ; i < n ; i++ )
{
rhoa[i] = 0.0;
if ( system->GetParticipant( i )->GetBaryonNumber() == 1 )
{
for ( G4int j = 0 ; j < n ; j++ )
{
if ( system->GetParticipant( j )->GetBaryonNumber() == 1 )
rhoa[i] += rha[i][j];
}
}
rhoa[i] = std::pow ( rhoa[i] + 1 , 1.0/3.0 );
}
// identification of the cluster
std::map < G4int , std::vector < G4int > > cluster_map;
std::vector < G4bool > is_already_belong_some_cluster;
// cluster_id participant_id
std::multimap < G4int , G4int > comb_map;
std::multimap < G4int , G4int > assign_map;
assign_map.clear();
std::vector < G4int > mascl;
std::vector < G4int > num;
mascl.resize ( n );
num.resize ( n );
is_already_belong_some_cluster.resize ( n );
std::vector < G4int > is_assigned_to ( n , -1 );
std::multimap < G4int , G4int > clusters;
for ( G4int i = 0 ; i < n ; i++ )
{
mascl[i] = 1;
num[i] = 1;
is_already_belong_some_cluster[i] = false;
}
G4int nclst = 1;
G4int ichek = 1;
G4int id = 0;
G4int cluster_id = -1;
for ( G4int i = 0 ; i < n-1 ; i++ )
{
G4bool hasThisCompany = false;
// Check only for bryons?
// std::cout << "Check Baryon " << i << std::endl;
if ( system->GetParticipant( i )->GetBaryonNumber() == 1 )
{
// if ( is_already_belong_some_cluster[i] != true )
// {
//G4int j1 = ichek + 1;
G4int j1 = i + 1;
for ( G4int j = j1 ; j < n ; j++ )
{
std::vector < G4int > cluster_participants;
if ( system->GetParticipant( j )->GetBaryonNumber() == 1 )
{
G4double rdist2 = rr2[ i ][ j ];
G4double pdist2 = pp2[ i ][ j ];
//G4double rdist2 = rr2[ num[i] ][ num[j] ];
//G4double pdist2 = pp2[ num[i] ][ num[j] ];
G4double pcc2 = cpf2
* ( rhoa[ i ] + rhoa[ j ] )
* ( rhoa[ i ] + rhoa[ j ] );
// Check phase space: close enough?
if ( rdist2 < rcc2 && pdist2 < pcc2 )
{
/*
std::cout << "G4QMDRESULT "
<< i << " " << j << " " << id << " "
<< is_assigned_to [ i ] << " " << is_assigned_to [ j ]
<< std::endl;
*/
if ( is_assigned_to [ j ] == -1 )
{
if ( is_assigned_to [ i ] == -1 )
{
if ( clusters.size() != 0 )
{
id = clusters.rbegin()->first + 1;
//std::cout << "id is increare " << id << std::endl;
}
else
{
id = 0;
}
clusters.insert ( std::multimap<G4int,G4int>::value_type ( id , i ) );
is_assigned_to [ i ] = id;
clusters.insert ( std::multimap<G4int,G4int>::value_type ( id , j ) );
is_assigned_to [ j ] = id;
}
else
{
clusters.insert ( std::multimap<G4int,G4int>::value_type ( is_assigned_to [ i ] , j ) );
is_assigned_to [ j ] = is_assigned_to [ i ];
}
}
else
{
// j is already belong to some cluester
if ( is_assigned_to [ i ] == -1 )
{
clusters.insert ( std::multimap<G4int,G4int>::value_type ( is_assigned_to [ j ] , i ) );
is_assigned_to [ i ] = is_assigned_to [ j ];
}
else
{
// i has companion
if ( is_assigned_to [ i ] != is_assigned_to [ j ] )
{
// move companions to the cluster
//
//std::cout << "combine " << is_assigned_to [ i ] << " to " << is_assigned_to [ j ] << std::endl;
std::multimap< G4int , G4int > clusters_tmp;
G4int target_cluster_id;
if ( is_assigned_to [ i ] > is_assigned_to [ j ] )
target_cluster_id = is_assigned_to [ i ];
else
target_cluster_id = is_assigned_to [ j ];
for ( std::multimap< G4int , G4int >::iterator it
= clusters.begin() ; it != clusters.end() ; it++ )
{
//std::cout << it->first << " " << it->second << " " << target_cluster_id << std::endl;
if ( it->first == target_cluster_id )
{
//std::cout << "move " << it->first << " " << it->second << std::endl;
is_assigned_to [ it->second ] = is_assigned_to [ j ];
clusters_tmp.insert ( std::multimap<G4int,G4int>::value_type ( is_assigned_to [ j ] , it->second ) );
}
else
{
clusters_tmp.insert ( std::multimap<G4int,G4int>::value_type ( it->first , it->second ) );
}
}
clusters = clusters_tmp;
//id = clusters.rbegin()->first;
//id = target_cluster_id;
//std::cout << "id " << id << std::endl;
}
}
}
//std::cout << "combination " << i << " " << j << std::endl;
comb_map.insert( std::multimap<G4int,G4int>::value_type ( i , j ) );
cluster_participants.push_back ( j );
if ( assign_map.find( cluster_id ) == assign_map.end() )
{
is_already_belong_some_cluster[i] = true;
assign_map.insert ( std::multimap<G4int,G4int>::value_type ( cluster_id , i ) );
hasThisCompany = true;
}
assign_map.insert ( std::multimap<G4int,G4int>::value_type ( cluster_id , j ) );
is_already_belong_some_cluster[j] = true;
}
if ( ichek == i )
{
nclst++;
ichek++;
}
}
if ( cluster_participants.size() > 0 )
{
// cluster , participant
cluster_map.insert ( std::pair < G4int , std::vector < G4int > > ( i , cluster_participants ) );
}
}
// }
}
if ( hasThisCompany == true ) cluster_id++;
}
//std::cout << " id " << id << std::endl;
// sort
// Heavy cluster comes first
// size cluster_id
std::multimap< G4int , G4int > sorted_cluster_map;
for ( G4int i = 0 ; i <= id ; i++ ) // << "<=" because id is highest cluster nubmer.
{
//std::cout << i << " cluster has " << clusters.count( i ) << " nucleons." << std::endl;
sorted_cluster_map.insert ( std::multimap<G4int,G4int>::value_type ( clusters.count( i ) , i ) );
}
// create nucleus from devided clusters
std::vector < G4QMDNucleus* > result;
for ( std::multimap < G4int , G4int >::reverse_iterator it
= sorted_cluster_map.rbegin() ; it != sorted_cluster_map.rend() ; it ++)
{
//std::cout << "Add Participants to cluseter " << it->second << std::endl;
if ( it->first != 0 )
{
G4QMDNucleus* nucleus = new G4QMDNucleus();
for ( std::multimap < G4int , G4int >::iterator itt
= clusters.begin() ; itt != clusters.end() ; itt ++)
{
if ( it->second == itt->first )
{
nucleus->SetParticipant( system->GetParticipant ( itt->second ) );
//std::cout << "Add Participants " << itt->second << " " << system->GetParticipant ( itt->second )->GetPosition() << std::endl;
}
}
result.push_back( nucleus );
}
}
// delete participants from current system
for ( std::vector < G4QMDNucleus* > ::iterator it
= result.begin() ; it != result.end() ; it++ )
{
system->SubtractSystem ( *it );
}
return result;
}
@@ -0,0 +1,222 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "G4QMDNucleus.hh"
#include "G4Proton.hh"
#include "G4Neutron.hh"
#include "G4NucleiProperties.hh"
#include <numeric>
G4QMDNucleus::G4QMDNucleus()
{
G4QMDParameters* parameters = G4QMDParameters::GetInstance();
hbc = parameters->Get_hbc();
}
G4QMDNucleus::~G4QMDNucleus()
{
;
}
G4LorentzVector G4QMDNucleus::Get4Momentum()
{
G4LorentzVector p( 0 );
std::vector< G4QMDParticipant* >::iterator it;
for ( it = participants.begin() ; it != participants.end() ; it++ )
p += (*it)->Get4Momentum();
return p;
}
G4int G4QMDNucleus::GetMassNumber()
{
G4int A = 0;
std::vector< G4QMDParticipant* >::iterator it;
for ( it = participants.begin() ; it != participants.end() ; it++ )
{
if ( (*it)->GetDefinition() == G4Proton::Proton()
|| (*it)->GetDefinition() == G4Neutron::Neutron() )
A++;
}
return A;
}
G4int G4QMDNucleus::GetAtomicNumber()
{
G4int Z = 0;
std::vector< G4QMDParticipant* >::iterator it;
for ( it = participants.begin() ; it != participants.end() ; it++ )
{
if ( (*it)->GetDefinition() == G4Proton::Proton() )
Z++;
}
return Z;
}
G4double G4QMDNucleus::GetNuclearMass()
{
G4double mass = G4NucleiPropertiesTable::GetNuclearMass( GetAtomicNumber() , GetMassNumber() );
if ( mass == 0.0 )
{
G4int Z = GetAtomicNumber();
G4int A = GetMassNumber();
G4int N = A - Z;
// Weizsacker-Bethe
G4double Av = 16*MeV;
G4double As = 17*MeV;
G4double Ac = 0.7*MeV;
G4double Asym = 23*MeV;
G4double BE = Av * A
- As * std::pow ( G4double ( A ) , 2.0/3.0 )
- Ac * Z*Z/std::pow ( G4double ( A ) , 1.0/3.0 )
- Asym * ( N - Z )* ( N - Z ) / A;
mass = Z * G4Proton::Proton()->GetPDGMass()
+ N * G4Neutron::Neutron()->GetPDGMass()
- BE;
}
return mass;
}
void G4QMDNucleus::CalEnergyAndAngularMomentumInCM()
{
//G4cout << "CalEnergyAndAngularMomentumInCM " << this->GetAtomicNumber() << " " << GetMassNumber() << G4endl;
G4double gamma = Get4Momentum().gamma();
G4ThreeVector beta = Get4Momentum().v()/ Get4Momentum().e();
G4ThreeVector pcm0( 0.0 ) ;
G4int n = GetTotalNumberOfParticipant();
pcm.resize( n );
for ( G4int i= 0; i < n ; i++ )
{
G4ThreeVector p_i = GetParticipant( i )->GetMomentum();
G4double trans = gamma / ( gamma + 1.0 ) * p_i * beta;
pcm[i] = p_i - trans*beta;
pcm0 += pcm[i];
}
pcm0 = pcm0 / double ( n );
//G4cout << "pcm0 " << pcm0 << G4endl;
for ( G4int i= 0; i < n ; i++ )
{
pcm[i] += -pcm0;
//G4cout << "pcm " << i << " " << pcm[i] << G4endl;
}
G4double tmass = 0;
G4ThreeVector rcm0( 0.0 ) ;
rcm.resize( n );
es.resize( n );
for ( G4int i= 0; i < n ; i++ )
{
G4ThreeVector ri = GetParticipant( i )->GetPosition();
G4double trans = gamma / ( gamma + 1.0 ) * ri * beta;
es[i] = std::sqrt ( std::pow ( GetParticipant( i )->GetMass() , 2 ) + pcm[i]*pcm[i] );
rcm[i] = ri + trans*beta;
rcm0 += rcm[i]*es[i];
tmass += es[i];
}
rcm0 = rcm0/tmass;
for ( G4int i= 0; i < n ; i++ )
{
rcm[i] += -rcm0;
//G4cout << "rcm " << i << " " << rcm[i] << G4endl;
}
// Angluar momentum
G4ThreeVector rl ( 0.0 );
for ( G4int i= 0; i < n ; i++ )
{
rl += rcm[i].cross ( pcm[i] );
}
jj = int ( std::sqrt ( rl*rl / hbc ) + 0.5 );
// kinetic energy per nucleon in CM
G4double totalMass = 0.0;
for ( G4int i= 0; i < n ; i++ )
{
// following two lines are equivalent
//totalMass += GetParticipant( i )->GetDefinition()->GetPDGMass()/GeV;
totalMass += GetParticipant( i )->GetMass();
}
kineticEnergyPerNucleon = ( std::accumulate ( es.begin() , es.end() , 0.0 ) - totalMass )/n;
// Total (not per nucleion ) Binding Energy
bindingEnergy = ( std::accumulate ( es.begin() , es.end() , 0.0 ) -totalMass ) + potentialEnergy;
//G4cout << "KineticEnergyPerNucleon in GeV " << kineticEnergyPerNucleon << G4endl;
//G4cout << "KineticEnergySum in GeV " << std::accumulate ( es.begin() , es.end() , 0.0 ) - totalMass << G4endl;
//G4cout << "PotentialEnergy in GeV " << potentialEnergy << G4endl;
//G4cout << "BindingEnergy in GeV " << bindingEnergy << G4endl;
//G4cout << "G4BindingEnergy in GeV " << G4NucleiPropertiesTable::GetBindingEnergy( GetAtomicNumber() , GetMassNumber() )/GeV << G4endl;
excitationEnergy = bindingEnergy + G4NucleiPropertiesTable::GetBindingEnergy( GetAtomicNumber() , GetMassNumber() )/GeV;
//G4cout << "excitationEnergy in GeV " << excitationEnergy << G4endl;
if ( excitationEnergy < 0 ) excitationEnergy = 0.0;
}
@@ -0,0 +1,102 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
// Parameters comes from JQMD
// Niita et al., JAERI-Data/Code 99-042
#include "G4QMDParameters.hh"
G4QMDParameters* G4QMDParameters::parameters = NULL;
G4QMDParameters::G4QMDParameters()
{
wl = 2.0; // width of wave packet [fm]
hbc = 0.1973; // h-bar c in GeVfm
//Pauli
cpw = 1.0 / 2.0 / wl;
cph = 2.0 * wl / (hbc*hbc);
cpc = 4.0;
epsx = -20.0 ;
rho0 = 0.168; // satulation density
// Skyrme
G4double rpot = 1.0/3.0;
G4double ebinm = -16.0; // bounding energy [MeV]
G4double ebin = ebinm * 0.001;
G4double pfer = hbc * std::pow ( 3./2. *pi*pi * rho0 , 1./3. );
G4double rmass = 0.938;
G4double efer = pfer*pfer / 2. / rmass;
G4double t3 = 8. / 3. / rpot / std::pow( rho0 , ( 1.+rpot ) ) * ( efer / 5. - ebin );
G4double t0 = -16./15. * efer / rho0 - ( 1.+rpot ) * t3 * std::pow( rho0 , rpot );
G4double aaa = 3./4. * t0 * rho0;
G4double bbb = 3./8. * t3 * ( 2.+rpot ) * std::pow( rho0 , ( 1.+rpot ) );
G4double esymm = 25 * 0.001; // symetric potential 25 [MeV] -> GeV
gamm = rpot + 1.0;
// Local Potenials
c0 = aaa / ( rho0 * std::pow( 4 * pi * wl , 1.5 ) * 2.0 );
c3 = bbb / ( std::pow( rho0 , gamm ) * std::pow ( (4.0*pi*wl) , (1.5*gamm) ) * ( gamm+1.0) );
cs = esymm / ( rho0 * std::pow( (4.0*pi*wl) , 1.5 ) * 2.0 );
G4double ccoul = 0.001439767;
cl = ccoul/2.0 * 1; // Include Coulomb interaction
//cl = ccoul/2.0 * 0; // Not Include Coulomb interaction
// GroundStateNucleus
cdp = 1.0 / std::pow ( ( 4.0 * pi * wl ) , 1.5 );
c0p = c0 * 2.0;
c3p = c3 * ( gamm + 1.0 );
csp = cs * 2.0;
clp = cl * 2.0;
}
G4QMDParameters::~G4QMDParameters()
{
;
}
@@ -0,0 +1,51 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "G4QMDParticipant.hh"
G4QMDParticipant::G4QMDParticipant( G4ParticleDefinition* pd , G4ThreeVector p , G4ThreeVector r )
: definition ( pd )
, momentum ( p )
, position ( r )
, projectile ( false )
, target ( false )
{
;
}
G4QMDParticipant::~G4QMDParticipant()
{
;
}
G4LorentzVector G4QMDParticipant::Get4Momentum()
{
G4LorentzVector p4 ( momentum , std::sqrt ( std::pow ( definition->GetPDGMass()/GeV , 2 ) + momentum*momentum ) );
return p4;
}
@@ -0,0 +1,667 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "G4QMDReaction.hh"
#include "G4QMDNucleus.hh"
#include "G4QMDGroundStateNucleus.hh"
#include "G4Fancy3DNucleus.hh"
#include "G4NistManager.hh"
G4QMDReaction::G4QMDReaction()
:system ( 0 )
, deltaT ( 1 ) // in fsec
, maxTime ( 100 ) // will have maxTime-th time step
{
meanField = new G4QMDMeanField();
collision = new G4QMDCollision();
evaporation = new G4Evaporation;
evaporation->SetGEMChannel();
excitationHandler = new G4ExcitationHandler;
excitationHandler->SetEvaporation( evaporation );
// preco = new G4PreCompoundModel( excitationHandler );
}
G4QMDReaction::~G4QMDReaction()
{
delete evaporation;
delete collision;
delete meanField;
}
void G4QMDReaction::setInitialCondition( G4QMDSystem* , G4QMDSystem* )
{
;
}
void G4QMDReaction::doPropagation()
{
;
}
G4HadFinalState* G4QMDReaction::ApplyYourself( const G4HadProjectile & projectile , G4Nucleus & target )
{
//G4cout << "G4QMDReaction::ApplyYourself" << G4endl;
theParticleChange.Clear();
system = new G4QMDSystem;
G4int proj_Z = 0;
G4int proj_A = 0;
G4ParticleDefinition* proj_pd = ( G4ParticleDefinition* ) projectile.GetDefinition();
if ( proj_pd->GetParticleType() == "nucleus" )
{
proj_Z = proj_pd->GetAtomicNumber();
proj_A = proj_pd->GetAtomicMass();
}
else
{
proj_Z = (int)( proj_pd->GetPDGCharge()/eplus );
proj_A = 1;
}
G4int targ_Z = int ( target.GetZ() + 0.5 );
G4int targ_A = int ( target.GetN() + 0.5 );
G4ParticleDefinition* targ_pd = G4ParticleTable::GetParticleTable()->GetIon( targ_Z , targ_A , 0.0 );
G4NistManager* nistMan = G4NistManager::Instance();
// G4Element* G4NistManager::FindOrBuildElement( targ_Z );
const G4DynamicParticle* proj_dp = new G4DynamicParticle ( proj_pd , projectile.Get4Momentum() );
const G4Element* targ_ele = nistMan->FindOrBuildElement( targ_Z );
G4double aTemp = projectile.GetMaterial()->GetTemperature();
//G4double xs_0 = shenXS.GetCrossSection ( proj_dp , targ_ele , aTemp );
G4double xs_0 = genspaXS.GetCrossSection ( proj_dp , targ_ele , aTemp );
G4double bmax_0 = std::sqrt( xs_0 )/pi*2;
//std::cout << "bmax_0 in fm (fermi) " << bmax_0/fermi << std::endl;
//delete proj_dp;
G4bool elastic = true;
std::vector< G4QMDNucleus* > nucleuses; // Secondary nuceluses
G4ThreeVector boostToReac; // ReactionSystem (CM or NN);
G4ThreeVector boostBackToLAB; // Reaction System to LAB;
G4LorentzVector targ4p( G4ThreeVector( 0.0 ) , targ_pd->GetPDGMass()/GeV );
G4ThreeVector boostLABtoCM = targ4p.findBoostToCM( proj_dp->Get4Momentum()/GeV ); // CM of target and proj;
G4double p1 = proj_dp->GetMomentum().mag()/GeV/proj_A;
G4double m1 = proj_dp->GetDefinition()->GetPDGMass()/GeV/proj_A;
G4double e1 = std::sqrt( p1*p1 + m1*m1 );
G4double e2 = targ_pd->GetPDGMass()/GeV/targ_A;
G4double beta_nn = -p1 / ( e1+e2 );
G4ThreeVector boostLABtoNN ( 0. , 0. , beta_nn ); // CM of NN;
G4double beta_nncm = ( - boostLABtoCM.beta() + boostLABtoNN.beta() ) / ( 1 - boostLABtoCM.beta() * boostLABtoNN.beta() ) ;
//std::cout << targ4p << std::endl;
//std::cout << proj_dp->Get4Momentum()<< std::endl;
//std::cout << beta_nncm << std::endl;
G4ThreeVector boostNNtoCM( 0. , 0. , beta_nncm ); //
G4ThreeVector boostCMtoNN( 0. , 0. , -beta_nncm ); //
boostToReac = boostLABtoNN;
boostBackToLAB = -boostLABtoNN;
delete proj_dp;
while ( elastic )
{
// impact parameter
G4double bmax = 1.05*(bmax_0/fermi); // 10% for Peripheral reactions
G4double b = bmax * G4UniformRand();
//071112
//G4double b = 0;
//G4double b = bmax;
//G4double b = bmax/1.05 * 0.7 * G4UniformRand();
//G4cout << "G4QMDRESULT bmax_0 = " << bmax_0/fermi << " fm, bmax = " << bmax << " fm , b = " << b << " fm " << G4endl;
G4double plab = projectile.GetTotalMomentum()/GeV;
G4double elab = (projectile.GetKineticEnergy() + proj_pd->GetPDGMass() + targ_pd->GetPDGMass() )/GeV;
calcOffSetOfCollision( b , proj_pd , targ_pd , plab , elab , bmax , boostCMtoNN );
// Projectile
G4LorentzVector proj4pLAB = projectile.Get4Momentum()/GeV;
G4QMDNucleus* proj(NULL);
if ( projectile.GetDefinition()->GetParticleType() == "nucleus" )
{
proj = new G4QMDNucleus;
proj_Z = proj_pd->GetAtomicNumber();
proj_A = proj_pd->GetAtomicMass();
proj = new G4QMDGroundStateNucleus( proj_Z , proj_A );
//proj->ShowParticipants();
}
meanField->SetSystem ( proj );
proj->SetTotalPotential( meanField->GetTotalPotential() );
proj->CalEnergyAndAngularMomentumInCM();
// Target
G4int iz = int ( target.GetZ() );
G4int ia = int ( target.GetN() );
//G4QMDNucleus* targ = new G4QMDNucleus;
G4QMDNucleus* targ = new G4QMDGroundStateNucleus( iz , ia );
meanField->SetSystem (targ );
targ->SetTotalPotential( meanField->GetTotalPotential() );
targ->CalEnergyAndAngularMomentumInCM();
//G4LorentzVector targ4p( G4ThreeVector( 0.0 ) , targ->GetNuclearMass()/GeV );
// Boost Vector to CM
//boostToCM = targ4p.findBoostToCM( proj4pLAB );
// Target
for ( G4int i = 0 ; i < targ->GetTotalNumberOfParticipant() ; i++ )
{
G4ThreeVector p0 = targ->GetParticipant( i )->GetMomentum();
G4ThreeVector r0 = targ->GetParticipant( i )->GetPosition();
G4ThreeVector p ( p0.x() + coulomb_collision_px_targ
, p0.y()
, p0.z() * coulomb_collision_gamma_targ + coulomb_collision_pz_targ );
G4ThreeVector r ( r0.x() + coulomb_collision_rx_targ
, r0.y()
, r0.z() / coulomb_collision_gamma_targ + coulomb_collision_rz_targ );
system->SetParticipant( new G4QMDParticipant( targ->GetParticipant( i )->GetDefinition() , p , r ) );
system->GetParticipant( i )->SetTarget();
}
G4LorentzVector proj4pCM = CLHEP::boostOf ( proj4pLAB , boostToReac );
G4LorentzVector targ4pCM = CLHEP::boostOf ( targ4p , boostToReac );
// Projectile
if ( proj != NULL )
{
// projectile is nucleus
for ( G4int i = 0 ; i < proj->GetTotalNumberOfParticipant() ; i++ )
{
G4ThreeVector p0 = proj->GetParticipant( i )->GetMomentum();
G4ThreeVector r0 = proj->GetParticipant( i )->GetPosition();
G4ThreeVector p ( p0.x() + coulomb_collision_px_proj
, p0.y()
, p0.z() * coulomb_collision_gamma_proj + coulomb_collision_pz_proj );
G4ThreeVector r ( r0.x() + coulomb_collision_rx_proj
, r0.y()
, r0.z() / coulomb_collision_gamma_proj + coulomb_collision_rz_proj );
system->SetParticipant( new G4QMDParticipant( proj->GetParticipant( i )->GetDefinition() , p , r ) );
system->GetParticipant ( i + targ->GetTotalNumberOfParticipant() )->SetProjectile();
}
}
else
{
// projectile is particle
G4int i = targ->GetTotalNumberOfParticipant();
G4ThreeVector p0( 0 );
G4ThreeVector r0( 0 );
G4ThreeVector p ( p0.x() + coulomb_collision_px_proj
, p0.y()
, p0.z() * coulomb_collision_gamma_proj + coulomb_collision_pz_proj );
G4ThreeVector r ( r0.x() + coulomb_collision_rx_proj
, r0.y()
, r0.z() / coulomb_collision_gamma_proj + coulomb_collision_rz_proj );
system->SetParticipant( new G4QMDParticipant( (G4ParticleDefinition*)projectile.GetDefinition() , p , r ) );
system->GetParticipant ( i )->SetProjectile();
}
delete targ;
delete proj;
meanField->SetSystem ( system );
collision->SetMeanField ( meanField );
// Time Evolution
//std::cout << "Start time evolution " << std::endl;
//system->ShowParticipants();
for ( G4int i = 0 ; i < maxTime ; i++ )
{
//G4cout << " do Paropagate " << i << " th time step. " << G4endl;
meanField->DoPropagation( deltaT );
//system->ShowParticipants();
collision->CalKinematicsOfBinaryCollisions();
if ( i / 10 * 10 == i )
{
//G4cout << i << " th time step. " << G4endl;
//system->ShowParticipants();
}
//system->ShowParticipants();
}
//system->ShowParticipants();
//std::cout << "Doing Cluster Judgment " << std::endl;
nucleuses = meanField->DoClusterJudgment();
// Elastic Judgment
G4int numberOfSecondary = int ( nucleuses.size() ) + system->GetTotalNumberOfParticipant();
G4int sec_a_Z = 0;
G4int sec_a_A = 0;
G4ParticleDefinition* sec_a_pd = NULL;
G4int sec_b_Z = 0;
G4int sec_b_A = 0;
G4ParticleDefinition* sec_b_pd = NULL;
if ( numberOfSecondary == 2 )
{
G4bool elasticLike_system = false;
if ( nucleuses.size() == 2 )
{
sec_a_Z = nucleuses[0]->GetAtomicNumber();
sec_a_A = nucleuses[0]->GetMassNumber();
sec_b_Z = nucleuses[1]->GetAtomicNumber();
sec_b_A = nucleuses[1]->GetMassNumber();
if ( ( sec_a_Z == proj_Z && sec_a_A == proj_A && sec_b_Z == targ_Z && sec_b_A == targ_A )
|| ( sec_a_Z == targ_Z && sec_a_A == targ_A && sec_b_Z == proj_Z && sec_b_A == proj_A ) )
{
elasticLike_system = true;
}
}
else if ( nucleuses.size() == 1 )
{
sec_a_Z = nucleuses[0]->GetAtomicNumber();
sec_a_A = nucleuses[0]->GetMassNumber();
sec_b_pd = system->GetParticipant( 0 )->GetDefinition();
if ( ( sec_a_Z == proj_Z && sec_a_A == proj_A && sec_b_pd == targ_pd )
|| ( sec_a_Z == targ_Z && sec_a_A == targ_A && sec_b_pd == proj_pd ) )
{
elasticLike_system = true;
}
}
else
{
sec_a_pd = system->GetParticipant( 0 )->GetDefinition();
sec_b_pd = system->GetParticipant( 1 )->GetDefinition();
if ( ( sec_a_pd == proj_pd && sec_b_pd == targ_pd )
|| ( sec_a_pd == targ_pd && sec_b_pd == proj_pd ) )
{
elasticLike_system = true;
}
}
if ( elasticLike_system == true )
{
G4bool elasticLike_energy = true;
// Cal ExcitationEnergy
for ( G4int i = 0 ; i < int ( nucleuses.size() ) ; i++ )
{
//meanField->SetSystem( nucleuses[i] );
meanField->SetNucleus( nucleuses[i] );
//nucleuses[i]->SetTotalPotential( meanField->GetTotalPotential() );
//nucleuses[i]->CalEnergyAndAngularMomentumInCM();
if ( nucleuses[i]->GetExcitationEnergy()*GeV > 1.0*MeV ) elasticLike_energy = false;
}
// Check Collision
G4bool withCollision = true;
if ( system->GetNOCollision() == 0 ) withCollision = false;
// Final judegement for Inelasitc or Elastic;
//
// ElasticLike without Collision
//if ( elasticLike_energy == true && withCollision == false ) elastic = true; // ielst = 0
// ElasticLike with Collision
//if ( elasticLike_energy == true && withCollision == true ) elastic = true; // ielst = 1
// InelasticLike without Collision
if ( elasticLike_energy == false ) elastic = false; // ielst = 2
// InelasticLike with Collision
//if ( elasticLike_energy == false && withCollision == true ) elastic = false; // ielst = 3
}
}
else
{
// numberOfSecondary != 2
elastic = false;
}
//071115
//G4cout << elastic << G4endl;
// if elastic is true try again from sampling of impact parameter
}
// Statical Decay Phase
for ( std::vector< G4QMDNucleus* >::iterator it
= nucleuses.begin() ; it != nucleuses.end() ; it++ )
{
/*
std::cout << "G4QMDRESULT "
<< (*it)->GetAtomicNumber()
<< " "
<< (*it)->GetMassNumber()
<< " "
<< (*it)->Get4Momentum()
<< " "
<< (*it)->Get4Momentum().vect()
<< " "
<< (*it)->Get4Momentum().restMass()
<< " "
<< (*it)->GetNuclearMass()/GeV
<< std::endl;
*/
meanField->SetNucleus ( *it );
if ( (*it)->GetAtomicNumber() == 0 // neutron cluster
|| (*it)->GetAtomicNumber() == (*it)->GetMassNumber() ) // proton cluster
{
// push back system
for ( G4int i = 0 ; i < (*it)->GetTotalNumberOfParticipant() ; i++ )
{
system->SetParticipant ( (*it)->GetParticipant( i ) );
}
continue;
}
G4double nucleus_e = std::sqrt ( std::pow ( (*it)->GetNuclearMass()/GeV , 2 ) + std::pow ( (*it)->Get4Momentum().vect().mag() , 2 ) );
G4LorentzVector nucleus_p4CM ( (*it)->Get4Momentum().vect() , nucleus_e );
// std::cout << "G4QMDRESULT nucleus deltaQ " << deltaQ << std::endl;
G4int ia = (*it)->GetMassNumber();
G4int iz = (*it)->GetAtomicNumber();
G4LorentzVector lv ( G4ThreeVector( 0.0 ) , (*it)->GetExcitationEnergy()*GeV + G4ParticleTable::GetParticleTable()->GetIonTable()->GetIonMass( iz , ia ) );
G4Fragment* aFragment = new G4Fragment( ia , iz , lv );
G4ReactionProductVector* rv;
rv = excitationHandler->BreakItUp( *aFragment );
G4bool notBreak = true;
for ( G4ReactionProductVector::iterator itt
= rv->begin() ; itt != rv->end() ; itt++ )
{
notBreak = false;
// Secondary from this nucleus (*it)
G4ParticleDefinition* pd = (*itt)->GetDefinition();
G4LorentzVector p4 ( (*itt)->GetMomentum()/GeV , (*itt)->GetTotalEnergy()/GeV ); //in nucleus(*it) rest system
G4LorentzVector p4_CM = CLHEP::boostOf( p4 , -nucleus_p4CM.findBoostToCM() ); // Back to CM
G4LorentzVector p4_LAB = CLHEP::boostOf( p4_CM , boostBackToLAB ); // Back to LAB
G4DynamicParticle* dp = new G4DynamicParticle( pd , p4_LAB*GeV );
theParticleChange.AddSecondary( dp );
/*
std::cout
<< "Regist Secondary "
<< (*itt)->GetDefinition()->GetParticleName()
<< " "
<< (*itt)->GetMomentum()/GeV
<< " "
<< (*itt)->GetKineticEnergy()/GeV
<< " "
<< (*itt)->GetMass()/GeV
<< " "
<< (*itt)->GetTotalEnergy()/GeV
<< " "
<< (*itt)->GetTotalEnergy()/GeV * (*itt)->GetTotalEnergy()/GeV
- (*itt)->GetMomentum()/GeV * (*itt)->GetMomentum()/GeV
<< " "
<< nucleus_p4CM.findBoostToCM()
<< " "
<< p4
<< " "
<< p4_CM
<< " "
<< p4_LAB
<< std::endl;
*/
}
if ( notBreak == true )
{
G4ParticleDefinition* pd = G4ParticleTable::GetParticleTable()->GetIon( (*it)->GetAtomicNumber() , (*it)->GetMassNumber(), (*it)->GetExcitationEnergy()*GeV );
G4LorentzVector p4_CM = nucleus_p4CM;
G4LorentzVector p4_LAB = CLHEP::boostOf( p4_CM , boostBackToLAB ); // Back to LAB
G4DynamicParticle* dp = new G4DynamicParticle( pd , p4_LAB*GeV );
theParticleChange.AddSecondary( dp );
}
delete aFragment;
delete *it; // delete nulceuse
}
for ( G4int i = 0 ; i < system->GetTotalNumberOfParticipant() ; i++ )
{
// Secondary particles
G4ParticleDefinition* pd = system->GetParticipant( i )->GetDefinition();
G4LorentzVector p4_CM = system->GetParticipant( i )->Get4Momentum();
G4LorentzVector p4_LAB = CLHEP::boostOf( p4_CM , boostBackToLAB );
G4DynamicParticle* dp = new G4DynamicParticle( pd , p4_LAB*GeV );
theParticleChange.AddSecondary( dp );
/*
G4cout << "G4QMDRESULT "
<< "r" << i << " " << system->GetParticipant ( i ) -> GetPosition() << " "
<< "p" << i << " " << system->GetParticipant ( i ) -> Get4Momentum()
<< G4endl;
*/
}
system->Clear();
delete system;
theParticleChange.SetStatusChange( stopAndKill );
return &theParticleChange;
}
void G4QMDReaction::calcOffSetOfCollision( G4double b ,
G4ParticleDefinition* pd_proj ,
G4ParticleDefinition* pd_targ ,
G4double ptot , G4double etot , G4double bmax , G4ThreeVector boostToCM )
{
G4double mass_proj = pd_proj->GetPDGMass()/GeV;
G4double mass_targ = pd_targ->GetPDGMass()/GeV;
G4double stot = std::sqrt ( etot*etot - ptot*ptot );
G4double pstt = std::sqrt ( ( stot*stot - ( mass_proj + mass_targ ) * ( mass_proj + mass_targ )
) * ( stot*stot - ( mass_proj - mass_targ ) * ( mass_proj - mass_targ ) ) )
/ ( 2.0 * stot );
G4double pzcc = pstt;
G4double eccm = stot - ( mass_proj + mass_targ );
G4int zp = pd_proj->GetAtomicNumber();
G4int ap = pd_proj->GetAtomicMass();
G4int zt = pd_targ->GetAtomicNumber();
G4int at = pd_targ->GetAtomicMass();
//G4double rmax0 = 8.0; // T.K dicide parameter value // for low energy
G4double rmax0 = bmax + 4.0;
G4double rmax = std::sqrt( rmax0*rmax0 + b*b );
G4double ccoul = 0.001439767;
G4double pcca = 1.0 - double ( zp * zt ) * ccoul / eccm / rmax - ( b / rmax )*( b / rmax );
G4double pccf = std::sqrt( pcca );
G4double aas = 2.0 * eccm * b / double ( zp * zt ) / ccoul;
G4double bbs = 1.0 / std::sqrt ( 1.0 + aas*aas );
G4double aas1 = ( 1.0 + aas * b / rmax ) * bbs;
G4double cost = 0.0;
G4double sint = 0.0;
G4double thet1 = 0.0;
G4double thet2 = 0.0;
if ( 1.0 - aas1*aas1 <= 0 || 1.0 - bbs*bbs <= 0.0 )
{
cost = 1.0;
sint = 0.0;
}
else
{
G4double aat1 = aas1 / std::sqrt ( 1.0 - aas1*aas1 );
G4double aat2 = bbs / std::sqrt ( 1.0 - bbs*bbs );
thet1 = std::atan ( aat1 );
thet2 = std::atan ( aat2 );
// TK enter to else block
G4double theta = thet1 - thet2;
cost = std::cos( theta );
sint = std::sin( theta );
}
G4double rzpr = -rmax * cost * ( mass_targ ) / ( mass_proj + mass_targ );
G4double rzta = rmax * cost * ( mass_proj ) / ( mass_proj + mass_targ );
G4double rxpr = rmax / 2.0 * sint;
G4double rxta = -rxpr;
G4double pzpc = pzcc * ( cost * pccf + sint * b / rmax );
G4double pxpr = pzcc * ( -sint * pccf + cost * b / rmax );
G4double pztc = - pzpc;
G4double pxta = - pxpr;
G4double epc = std::sqrt ( pzpc*pzpc + pxpr*pxpr + mass_proj*mass_proj );
G4double etc = std::sqrt ( pztc*pztc + pxta*pxta + mass_targ*mass_targ );
G4double pzpr = pzpc;
G4double pzta = pztc;
G4double epr = epc;
G4double eta = etc;
// CM -> NN
G4double gammacm = boostToCM.gamma();
//G4double betacm = -boostToCM.beta();
G4double betacm = boostToCM.z();
pzpr = pzpc + betacm * gammacm * ( gammacm / ( 1. + gammacm ) * pzpc * betacm + epc );
pzta = pztc + betacm * gammacm * ( gammacm / ( 1. + gammacm ) * pztc * betacm + etc );
epr = gammacm * ( epc + betacm * pzpc );
eta = gammacm * ( etc + betacm * pztc );
//G4double betpr = pzpr / epr;
//G4double betta = pzta / eta;
G4double gammpr = epr / ( mass_proj );
G4double gammta = eta / ( mass_targ );
pzta = pzta / double ( at );
pxta = pxta / double ( at );
pzpr = pzpr / double ( ap );
pxpr = pxpr / double ( ap );
G4double zeroz = 0.0;
rzpr = rzpr -zeroz;
rzta = rzta -zeroz;
// Set results
coulomb_collision_gamma_proj = gammpr;
coulomb_collision_rx_proj = rxpr;
coulomb_collision_rz_proj = rzpr;
coulomb_collision_px_proj = pxpr;
coulomb_collision_pz_proj = pzpr;
coulomb_collision_gamma_targ = gammta;
coulomb_collision_rx_targ = rxta;
coulomb_collision_rz_targ = rzta;
coulomb_collision_px_targ = pxta;
coulomb_collision_pz_targ = pzta;
}
@@ -0,0 +1,98 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
#include "G4QMDSystem.hh"
#include <iomanip>
G4QMDSystem::G4QMDSystem()
{
participants.clear();
numberOfCollision = 0;
}
G4QMDSystem::~G4QMDSystem()
{
this->Clear();
}
// Insert nucleus to current system;
void G4QMDSystem::SetSystem ( G4QMDSystem* nucleus , G4ThreeVector dp , G4ThreeVector dr )
{
std::vector< G4QMDParticipant* >::iterator it;
for ( it = nucleus->participants.begin() ; it != nucleus->participants.end() ; it++ )
{
G4ThreeVector r = (*it)->GetPosition() + dr;
(*it)->SetPosition ( r );
G4ThreeVector p = (*it)->GetMomentum() + dp;
(*it)->SetMomentum ( p );
this->SetParticipant( *it );
}
}
void G4QMDSystem::SubtractSystem ( G4QMDSystem* nucleus )
{
for ( G4int i = 0 ; i < nucleus->GetTotalNumberOfParticipant() ; i++ )
{
participants.erase ( std::find ( participants.begin() , participants.end() , nucleus->GetParticipant( i ) ) );
}
}
void G4QMDSystem::Clear ()
{
for ( G4int i = 0 ; i < this->GetTotalNumberOfParticipant() ; i++ )
{
delete participants[i];
}
participants.clear();
}
void G4QMDSystem::ShowParticipants()
{
G4ThreeVector p_sum( 0.0 );
std::vector< G4QMDParticipant* >::iterator it;
G4cout << "Momentum and Position of each participant " << G4endl;
G4int i = 0;
for ( it = participants.begin() ; it != participants.end() ; it++ )
{
G4cout << i
<< " "
<< (*it)->GetDefinition()->GetParticleName()
<< " "
<< std::setprecision( 8 )
<< (*it)->GetMomentum()
<< " "
<< (*it)->GetPosition()
<< G4endl;
p_sum += (*it)->GetMomentum();
i++;
}
G4cout << "Sum upped Momentum and mag " << p_sum << " " << p_sum.mag() << G4endl;
}