Import Geant4 9.5.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 16:46:55 +02:00
parent 89a9605df1
commit b1eb5424d2
10957 changed files with 888481 additions and 160139 deletions
@@ -0,0 +1,380 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// Author: Mathieu Karamitros (kara@cenbg.in2p3.fr)
//
// WARNING : This class is released as a prototype.
// It might strongly evolve or even disapear in the next releases.
//
// History:
// -----------
// 10 Oct 2011 M.Karamitros created
//
// -------------------------------------------------------------------
#include "G4DNAMoleculeEncounterStepper.hh"
#include "G4VDNAReactionModel.hh"
#include "G4DNAMolecularReactionTable.hh"
#include "G4H2O.hh"
#include "G4UnitsTable.hh"
using namespace std;
G4DNAMoleculeEncounterStepper::G4DNAMoleculeEncounterStepper() :
G4VITTimeStepper(),
fMolecularReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fReactionTable)),
fReactionModel(0),fVerbose(0)
{}
G4DNAMoleculeEncounterStepper& G4DNAMoleculeEncounterStepper::operator=(const G4DNAMoleculeEncounterStepper& rhs)
{
if(this == &rhs) return *this;
fReactionModel = 0;
fVerbose = rhs.fVerbose;
fMolecularReactionTable = rhs.fMolecularReactionTable;
return *this;
}
G4DNAMoleculeEncounterStepper::~G4DNAMoleculeEncounterStepper()
{}
G4DNAMoleculeEncounterStepper::G4DNAMoleculeEncounterStepper(const G4DNAMoleculeEncounterStepper& right) :
G4VITTimeStepper(right),
fMolecularReactionTable(reference_cast<const G4DNAMolecularReactionTable*>(fReactionTable))
{
fVerbose = right.fVerbose ;
fMolecularReactionTable = right.fMolecularReactionTable;
fReactionModel = 0;
}
void G4DNAMoleculeEncounterStepper::PrepareForAllProcessors()
{
// DEBUG
// G4cout << "G4DNAMoleculeEncounterStepper::PrepareForAllProcessors" << G4endl;
G4ITManager<G4Molecule>::Instance()->UpdatePositionMap();
}
G4double G4DNAMoleculeEncounterStepper::CalculateStep(const G4Track& trackA, const G4double& userMinTimeStep)
{
// DEBUG
// G4cout << "G4MoleculeEncounterStepper::CalculateStep, time :" << G4ITStepManager::Instance()->GetGlobalTime() << G4endl;
G4Molecule* moleculeA = GetMolecule(trackA);
#ifdef G4VERBOSE
if(fVerbose)
{
G4cout << "_______________________________________________________________________" << G4endl;
G4cout << "G4DNAMoleculeEncounterStepper::CalculateStep" << G4endl;
G4cout << "Incident molecule : " << moleculeA->GetName()
<< " (" << trackA.GetTrackID() << ") "
<< G4endl;
}
#endif
//__________________________________________________________________
// Retrieve general informations for making reactions
const vector<const G4Molecule*>* reactivesVector =
fMolecularReactionTable -> CanReactWith(moleculeA);
if(!reactivesVector)
{
#ifdef G4VERBOSE
// DEBUG
if(fVerbose > 1)
{
G4cout << "!!!!!!!!!!!!!!!!!!!!"<<G4endl;
G4cout << "!!! WARNING" << G4endl;
G4cout << "G4MoleculeEncounterStepper::CalculateStep will return infinity for the reaction because the molecule "
<< moleculeA->GetName()
<< " does not have any reactants given in the reaction table."
<< G4endl;
G4cout << "!!!!!!!!!!!!!!!!!!!!"<<G4endl;
}
#endif
return DBL_MAX;
}
G4int nbReactives = reactivesVector->size();
if(nbReactives == 0)
{
#ifdef G4VERBOSE
// DEBUG
if(fVerbose)
{
G4cout << "!!!!!!!!!!!!!!!!!!!!"<<G4endl;
G4cout << "!!! WARNING" << G4endl;
G4cout << "G4MoleculeEncounterStepper::CalculateStep will return infinity for the reaction because the molecule "
<< moleculeA->GetName()
<< " does not have any reactants given in the reaction table."
<< "This message can also result from a wrong implementation of the reaction table."
<< G4endl;
G4cout << "!!!!!!!!!!!!!!!!!!!!"<<G4endl;
}
#endif
return DBL_MAX;
}
// DEBUG
// else
// {
// G4cout << "nb reactants : " << nbReactives << " pour mol "<< moleculeA -> GetName () << G4endl;
// for(int k=0 ; k < nbReactives ; k++)
// {
// G4cout << (*reactivesVector)[k]->GetName() << G4endl;
// }
// }
fUserMinTimeStep = userMinTimeStep ;
if(fReactants) fReactants = 0 ;
fReactants = new vector<G4Track*>();
fSampledMinTimeStep = DBL_MAX;
fHasAlreadyReachedNullTime = false;
fReactionModel -> Initialise(moleculeA, trackA) ;
//__________________________________________________________________
// Start looping on possible reactants
for (G4int i=0 ; i<nbReactives ; i++)
{
const G4Molecule* moleculeB = (*reactivesVector)[i];
//______________________________________________________________
// Retrieve reaction range
G4double R = -1 ; // reaction Range
R = fReactionModel -> GetReactionRadius(i);
//______________________________________________________________
// Use KdTree algorithm to find closest reactants
G4KDTreeResultHandle results (G4ITManager<G4Molecule>::Instance()
-> FindNearest(moleculeA, moleculeB));
RetrieveResults(trackA,moleculeA,moleculeB,R,results, true);
}
#ifdef G4VERBOSE
// DEBUG
if(fVerbose)
{
G4cout << "G4MoleculeEncounterStepper::CalculateStep will finally return :"
<< G4BestUnit(fSampledMinTimeStep, "Time")<< G4endl;
if(fVerbose > 1)
{
G4cout << "TrackA: " << moleculeA->GetName() << " (" << trackA.GetTrackID() << ") can react with: ";
vector<G4Track*>::iterator it;
for(it = fReactants->begin() ; it != fReactants->end() ; it++)
{
G4Track* trackB = *it;
G4cout << GetMolecule(trackB)->GetName() << " ("
<< trackB->GetTrackID() << ") \t ";
}
G4cout << G4endl;
}
}
#endif
return fSampledMinTimeStep ;
}
void G4DNAMoleculeEncounterStepper::RetrieveResults(const G4Track& trackA, const G4Molecule* moleculeA,
const G4Molecule* moleculeB, const G4double R,
G4KDTreeResultHandle& results, G4bool iterate)
{
if(!results)
{
#ifdef G4VERBOSE
// DEBUG
if(fVerbose > 1)
{
G4cout << "No molecule " << moleculeB->GetName()
<< " found to react with "
<< moleculeA->GetName()
<< G4endl;
}
#endif
return ;
}
G4double DA = moleculeA->GetDiffusionCoefficient() ;
G4double DB = moleculeB->GetDiffusionCoefficient() ;
for(results->Rewind();
!results->End();
results->Next())
{
G4IT* reactiveB = (G4IT*) results->GetItemData() ;
if (reactiveB==0)
{
// DEBUG
// G4cout<<"Continue 1"<<G4endl;
continue ;
}
G4Track *trackB = reactiveB->GetTrack();
if(trackB == 0)
{
G4ExceptionDescription exceptionDescription ;
exceptionDescription << "The reactant B found using the ITManager does not have a valid track "
<< " attached to it. If this is done on purpose, please do not record this "
<< " molecule in the ITManager."
<< G4endl;
G4Exception("G4DNAMoleculeEncounterStepper::RetrieveResults","MoleculeEncounterStepper001",
FatalErrorInArgument,exceptionDescription);
continue ;
}
if (trackB->GetTrackStatus() != fAlive)
{
G4ExceptionDescription exceptionDescription ;
exceptionDescription << "The track status of one of the nearby reactants is not fAlive" << G4endl;
exceptionDescription << "The incomming trackID "
<< "(trackA entering in G4DNAMoleculeEncounterStepper and "
<< "for which you are looking reactant for) is : "
<< trackA.GetTrackID() << G4endl;
exceptionDescription << "And the trackID of the reactant (trackB) is: "
<< trackB->GetTrackID() << G4endl;
G4Exception("G4DNAMoleculeEncounterStepper::RetrieveResults","MoleculeEncounterStepper002",
FatalErrorInArgument,exceptionDescription);
continue ;
}
if(trackB == &trackA)
{
// DEBUG
G4ExceptionDescription exceptionDescription ;
exceptionDescription << "A track is reacting with itself (which is impossible) ie trackA == trackB"
<< G4endl ;
exceptionDescription << "Molecule A (and B) is of type : "
<< moleculeA->GetName()
<< " with trackID : "
<< trackA.GetTrackID() << G4endl;
G4Exception("G4DNAMoleculeEncounterStepper::RetrieveResults","MoleculeEncounterStepper003",
FatalErrorInArgument,exceptionDescription);
}
if(fabs(trackB->GetGlobalTime() - trackA.GetGlobalTime()) > trackA.GetGlobalTime()*(1-1/100) )
{
// DEBUG
G4ExceptionDescription exceptionDescription;
exceptionDescription << "The interacting tracks are not synchronized in time"<< G4endl;
exceptionDescription<< "trackB->GetGlobalTime() != trackA.GetGlobalTime()"
<< G4endl;
exceptionDescription << "trackA : trackID : " << trackA.GetTrackID()
<< "\t Name :" << moleculeA->GetName()
<<"\t trackA->GetGlobalTime() = "
<< G4BestUnit(trackA.GetGlobalTime(), "Time") << G4endl;
exceptionDescription << "trackB : trackID : " << trackB->GetTrackID()
<< "\t Name :" << moleculeB->GetName()
<< "\t trackB->GetGlobalTime() = "
<< G4BestUnit(trackB->GetGlobalTime(), "Time")<< G4endl;
G4Exception("G4DNAMoleculeEncounterStepper::RetrieveResults","MoleculeEncounterStepper004",
FatalErrorInArgument,exceptionDescription);
}
G4double r2 = results->GetDistanceSqr() ;
#ifdef G4VERBOSE
if(fVerbose > 1)
{
G4cout << "\t ************************************************** " << G4endl;
G4cout <<"\t Reaction between "
<< moleculeA->GetName() << " (" << trackA.GetTrackID() << ") "
<< " & " << moleculeB->GetName() << " (" << trackB->GetTrackID() << "), "
<< "Interaction Range = "
<< G4BestUnit(R, "Length")<<G4endl;
G4cout <<"\t Real distance between reactants = "
<< G4BestUnit((trackA.GetPosition() - trackB->GetPosition()).mag(), "Length")<<G4endl;
G4cout <<"\t Distance between reactants calculated by nearest neighbor algorithm = "
<< G4BestUnit(sqrt(r2), "Length")<<G4endl;
// G4cout << " ***** " << G4endl;
}
#endif
if(r2 <= R*R)
{
// Entering in this condition may due to the fact that molecules are very close
// to each other
// Therefore, if we consider only the nearby reactant, this one may have already
// react. Instead, we will take all possible reactants that satisfy the condition r<R
if(fHasAlreadyReachedNullTime == false)
{
fReactants->clear();
fHasAlreadyReachedNullTime = true;
}
if(iterate) // First call (call from outside this method)
{
fSampledMinTimeStep = 0.;
G4KDTreeResultHandle results2 (G4ITManager<G4Molecule>::Instance()
-> FindNearestInRange(moleculeA, moleculeB,R));
RetrieveResults(trackA, moleculeA, moleculeB, R, results2, false);
}
else // Other calls (call from this method)
{
fReactants->push_back(trackB);
}
continue;
}
else
{
G4double r = sqrt(r2);
G4double tempMinET = pow(r - R,2)
/(16 * (DA + DB + 2*sqrt(DA*DB)));
if(tempMinET <= fSampledMinTimeStep)
{
if(tempMinET <= fUserMinTimeStep)
{
if(fSampledMinTimeStep > fUserMinTimeStep)
fReactants->clear();
fSampledMinTimeStep = fUserMinTimeStep;
fReactants->push_back(trackB);
}
else
{
fSampledMinTimeStep = tempMinET;
if(tempMinET < fSampledMinTimeStep)
fReactants->clear();
fReactants->push_back(trackB);
}
}
}
}
}