Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-23 08:28:58

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file GB01/src/GB01BOptrChangeCrossSection.cc
0027 /// \brief Implementation of the GB01BOptrChangeCrossSection class
0028 //
0029 #include "GB01BOptrChangeCrossSection.hh"
0030 
0031 #include "G4BOptnChangeCrossSection.hh"
0032 #include "G4BiasingProcessInterface.hh"
0033 #include "G4InteractionLawPhysical.hh"
0034 #include "G4ParticleDefinition.hh"
0035 #include "G4ParticleTable.hh"
0036 #include "G4VProcess.hh"
0037 #include "Randomize.hh"
0038 
0039 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0040 
0041 GB01BOptrChangeCrossSection::GB01BOptrChangeCrossSection(G4String particleName, G4String name)
0042   : G4VBiasingOperator(name), fSetup(true)
0043 {
0044   fParticleToBias = G4ParticleTable::GetParticleTable()->FindParticle(particleName);
0045 
0046   if (fParticleToBias == nullptr) {
0047     G4ExceptionDescription ed;
0048     ed << "Particle `" << particleName << "' not found !" << G4endl;
0049     G4Exception("GB01BOptrChangeCrossSection(...)", "exGB01.01", JustWarning, ed);
0050   }
0051 }
0052 
0053 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0054 
0055 GB01BOptrChangeCrossSection::~GB01BOptrChangeCrossSection()
0056 {
0057   for (auto it = fChangeCrossSectionOperations.begin(); it != fChangeCrossSectionOperations.end();
0058        it++)
0059     delete (*it).second;
0060 }
0061 
0062 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0063 
0064 void GB01BOptrChangeCrossSection::StartRun()
0065 {
0066   // --------------
0067   // -- Setup stage:
0068   // ---------------
0069   // -- Start by collecting processes under biasing, create needed biasing
0070   // -- operations and associate these operations to the processes:
0071   if (fSetup) {
0072     const G4ProcessManager* processManager = fParticleToBias->GetProcessManager();
0073     const G4BiasingProcessSharedData* sharedData =
0074       G4BiasingProcessInterface::GetSharedData(processManager);
0075     if (sharedData)  // -- sharedData tested, as is can happen a user attaches an operator to a
0076                      // -- volume but without defined BiasingProcessInterface processes.
0077     {
0078       for (size_t i = 0; i < (sharedData->GetPhysicsBiasingProcessInterfaces()).size(); i++) {
0079         const G4BiasingProcessInterface* wrapperProcess =
0080           (sharedData->GetPhysicsBiasingProcessInterfaces())[i];
0081         G4String operationName =
0082           "XSchange-" + wrapperProcess->GetWrappedProcess()->GetProcessName();
0083         fChangeCrossSectionOperations[wrapperProcess] =
0084           new G4BOptnChangeCrossSection(operationName);
0085       }
0086     }
0087     fSetup = false;
0088   }
0089 }
0090 
0091 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0092 
0093 G4VBiasingOperation* GB01BOptrChangeCrossSection::ProposeOccurenceBiasingOperation(
0094   const G4Track* track, const G4BiasingProcessInterface* callingProcess)
0095 {
0096   // -----------------------------------------------------
0097   // -- Check if current particle type is the one to bias:
0098   // -----------------------------------------------------
0099   if (track->GetDefinition() != fParticleToBias) return nullptr;
0100 
0101   // ---------------------------------------------------------------------
0102   // -- select and setup the biasing operation for current callingProcess:
0103   // ---------------------------------------------------------------------
0104   // -- Check if the analog cross-section well defined : for example, the conversion
0105   // -- process for a gamma below e+e- creation threshold has an DBL_MAX interaction
0106   // -- length. Nothing is done in this case (ie, let analog process to deal with the case)
0107   G4double analogInteractionLength =
0108     callingProcess->GetWrappedProcess()->GetCurrentInteractionLength();
0109   if (analogInteractionLength > DBL_MAX / 10.) return nullptr;
0110 
0111   // -- Analog cross-section is well-defined:
0112   G4double analogXS = 1. / analogInteractionLength;
0113 
0114   // -- Choose a constant cross-section bias. But at this level, this factor can be made
0115   // -- direction dependent, like in the exponential transform MCNP case, or it
0116   // -- can be chosen differently, depending on the process, etc.
0117   G4double XStransformation = 2.0;
0118 
0119   // -- fetch the operation associated to this callingProcess:
0120   G4BOptnChangeCrossSection* operation = fChangeCrossSectionOperations[callingProcess];
0121   // -- get the operation that was proposed to the process in the previous step:
0122   G4VBiasingOperation* previousOperation = callingProcess->GetPreviousOccurenceBiasingOperation();
0123 
0124   // -- now setup the operation to be returned to the process: this
0125   // -- consists in setting the biased cross-section, and in asking
0126   // -- the operation to sample its exponential interaction law.
0127   // -- To do this, to first order, the two lines:
0128   //        operation->SetBiasedCrossSection( XStransformation * analogXS );
0129   //        operation->Sample();
0130   // -- are correct and sufficient.
0131   // -- But, to avoid having to shoot a random number each time, we sample
0132   // -- only on the first time the operation is proposed, or if the interaction
0133   // -- occured. If the interaction did not occur for the process in the previous,
0134   // -- we update the number of interaction length instead of resampling.
0135   if (previousOperation == nullptr) {
0136     operation->SetBiasedCrossSection(XStransformation * analogXS);
0137     operation->Sample();
0138   }
0139   else {
0140     if (previousOperation != operation) {
0141       // -- should not happen !
0142       G4ExceptionDescription ed;
0143       ed << " Logic problem in operation handling !" << G4endl;
0144       G4Exception("GB01BOptrChangeCrossSection::ProposeOccurenceBiasingOperation(...)", "exGB01.02",
0145                   JustWarning, ed);
0146       return nullptr;
0147     }
0148     if (operation->GetInteractionOccured()) {
0149       operation->SetBiasedCrossSection(XStransformation * analogXS);
0150       operation->Sample();
0151     }
0152     else {
0153       // -- update the 'interaction length' and underneath 'number of interaction lengths'
0154       // -- for past step  (this takes into accout the previous step cross-section value)
0155       operation->UpdateForStep(callingProcess->GetPreviousStepSize());
0156       // -- update the cross-section value:
0157       operation->SetBiasedCrossSection(XStransformation * analogXS);
0158       // -- forces recomputation of the 'interaction length' taking into account above
0159       // -- new cross-section value [tricky : to be improved]
0160       operation->UpdateForStep(0.0);
0161     }
0162   }
0163 
0164   return operation;
0165 }
0166 
0167 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0168 
0169 void GB01BOptrChangeCrossSection::OperationApplied(const G4BiasingProcessInterface* callingProcess,
0170                                                    G4BiasingAppliedCase,
0171                                                    G4VBiasingOperation* occurenceOperationApplied,
0172                                                    G4double, G4VBiasingOperation*,
0173                                                    const G4VParticleChange*)
0174 {
0175   G4BOptnChangeCrossSection* operation = fChangeCrossSectionOperations[callingProcess];
0176   if (operation == occurenceOperationApplied) operation->SetInteractionOccured();
0177 }
0178 
0179 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......