LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
OpBoundaryProcessSimple.cxx
Go to the documentation of this file.
1 // Adapted for LArSoft by Ben Jones, MIT, March 2010
2 //
3 // This class invokes a simplified model of optical reflections at
4 // boundaries between different materials. The relevant reflectivities
5 // are read in by an implementation of the MaterialPropertiesLoader.
6 //
7 // The required parameters are total reflectance and ratio of diffuse
8 // to specular reflectance. Each photon crossing a boundary with a
9 // defined reflectance is randomly either reflected or absorbed and killed
10 // according to the supplied probability.
11 //
12 // Every reflected photon with a defined diffuse reflection fraction
13 // is then randomly either diffusely or specularly reflected according
14 // to the supplied probability. All materials with no defined
15 // reflectance are assumed to be black and
16 // absorb all incident photons.
17 //
18 // This physics process is loaded in the OpticalPhysics physics constructor.
19 //
20 // This class is based on the G4OpBoundaryProcess class in Geant4
21 
22 
23 //
24 // ********************************************************************
25 // * License and Disclaimer *
26 // * *
27 // * The Geant4 software is copyright of the Copyright Holders of *
28 // * the Geant4 Collaboration. It is provided under the terms and *
29 // * conditions of the Geant4 Software License, included in the file *
30 // * LICENSE and available at http://cern.ch/geant4/license . These *
31 // * include a list of copyright holders. *
32 // * *
33 // * Neither the authors of this software system, nor their employing *
34 // * institutes,nor the agencies providing financial support for this *
35 // * work make any representation or warranty, express or implied, *
36 // * regarding this software system or assume any liability for its *
37 // * use. Please see the license in the file LICENSE and URL above *
38 // * for the full disclaimer and the limitation of liability. *
39 // * *
40 // * This code implementation is the result of the scientific and *
41 // * technical work of the GEANT4 collaboration. *
42 // * By using, copying, modifying or distributing the software (or *
43 // * any work based on the software) you agree to acknowledge its *
44 // * use in resulting scientific publications, and indicate your *
45 // * acceptance of all terms of the Geant4 Software license. *
46 // ********************************************************************
47 //
49 // Optical Photon Boundary Process Class Implementation
51 
52 #ifndef LARG4_OPBOUNDARYPROCESSSIMPLE_CXX
53 #define LARG4_OPBOUNDARYPROCESSSIMPLE_CXX 1
54 
55 #include "TH1.h"
56 #include "TTree.h"
57 
58 #include "Geant4/G4ios.hh"
59 #include "Geant4/G4OpProcessSubType.hh"
60 #include "Geant4/G4GeometryTolerance.hh"
61 
64 
65 //#define G4DEBUG_OPTICAL
66 
67 
68 
69 namespace larg4 {
70 
71  //Constructor
72 
74  G4ProcessType type)
75  : G4VDiscreteProcess(processName, type)
76  {
77  if ( 1 > 0) {
78  G4cout << GetProcessName() << " is created " << G4endl;
79  }
80 
81 
82  SetProcessSubType(fOpBoundary);
83 
85 
86  fCarTolerance = G4GeometryTolerance::GetInstance()
87  ->GetSurfaceTolerance();
88 
89  }
90 
91  // OpBoundaryProcessSimple::OpBoundaryProcessSimple(const OpBoundaryProcessSimple &right)
92  // {
93  // }
94 
95 
96  //Destructor
97 
99  {
100  }
101 
102 
103 
104 
105  //Action to take after making each step of an optical photon - described in file header.
106 
107  // PostStepDoIt
108  G4VParticleChange*
109  OpBoundaryProcessSimple::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep)
110  {
111 
112  // Note - these have to be loaded here, since this object
113  // is constructed before LArG4, and hence before the
114  // LArG4 parameters are read from config
115 
117  aParticleChange.Initialize(aTrack);
118 
119 
120  G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
121  G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
122 
123 
124  if (pPostStepPoint->GetStepStatus() != fGeomBoundary){
126  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
127  }
128  if (aTrack.GetStepLength()<=fCarTolerance/2){
130  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
131  }
132 
133  G4Material* Material1 = pPreStepPoint -> GetMaterial();
134  G4Material* Material2 = pPostStepPoint -> GetMaterial();
135 
136 
137  if(Material1 != Material2)
138  {
139 
141 
142  fVerbosity = lgp->OpVerbosity();
143 
144 
145 
146  G4double thePhotonMomentum;
147 
148  G4ThreeVector OldMomentum;
149  G4ThreeVector OldPolarization;
150 
151  G4ThreeVector NewMomentum;
152  G4ThreeVector NewPolarization;
153 
154  G4ThreeVector theGlobalNormal;
155  G4ThreeVector theFacetNormal;
156 
157  std::string Material1Name = Material1->GetName();
158  std::string Material2Name = Material2->GetName();
159 
160  const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
161 
162 
163  thePhotonMomentum = aParticle->GetTotalMomentum();
164  OldMomentum = aParticle->GetMomentumDirection();
165  OldPolarization = aParticle->GetPolarization();
166 
167 
168 
169  if (fVerbosity>9) std::cout<<"OpBoundaryProcessSimple Debug: Photon " <<aTrack.GetTrackID() <<" momentum "<<thePhotonMomentum << " Material1 " << Material1Name.c_str() << " Material 2 " << Material2Name.c_str() << std::endl;
170 
171  G4ThreeVector theGlobalPoint = pPostStepPoint->GetPosition();
172 
173  G4Navigator* theNavigator =
174  G4TransportationManager::GetTransportationManager()->
175  GetNavigatorForTracking();
176 
177  G4ThreeVector theLocalPoint = theNavigator->
178  GetGlobalToLocalTransform().
179  TransformPoint(theGlobalPoint);
180 
181  G4ThreeVector theLocalNormal; // Normal points back into volume
182 
183  G4bool valid;
184  theLocalNormal = theNavigator->GetLocalExitNormal(&valid);
185 
186  if (valid) {
187  theLocalNormal = -theLocalNormal;
188  }
189  else {
190  G4cerr << " OpBoundaryProcessSimple/PostStepDoIt(): "
191  << " The Navigator reports that it returned an invalid normal"
192  << G4endl;
193  }
194 
195  theGlobalNormal = theNavigator->GetLocalToGlobalTransform().
196  TransformAxis(theLocalNormal);
197 
198  if (OldMomentum * theGlobalNormal > 0.0) {
199 #ifdef G4DEBUG_OPTICAL
200  G4cerr << " OpBoundaryProcessSimple/PostStepDoIt(): "
201  << " theGlobalNormal points the wrong direction "
202  << G4endl;
203 #endif
204  theGlobalNormal = -theGlobalNormal;
205  }
206 
207  G4MaterialPropertiesTable* aMaterialPropertiesTable;
208  G4MaterialPropertyVector* Reflectance;
209  G4MaterialPropertyVector* DiffuseReflectanceFraction;
210 
211 
212  aMaterialPropertiesTable = Material1->GetMaterialPropertiesTable();
213 
214 
215  if (aMaterialPropertiesTable) {
216 
217  std::stringstream PropertyName;
218  PropertyName<<"REFLECTANCE_"<<Material2Name.c_str();
219  Reflectance = aMaterialPropertiesTable->GetProperty(PropertyName.str().c_str());
220 
221  PropertyName.str("");
222  PropertyName<<"DIFFUSE_REFLECTANCE_FRACTION_"<<Material2Name.c_str();
223  DiffuseReflectanceFraction=aMaterialPropertiesTable->GetProperty(PropertyName.str().c_str());
224 
225  if (Reflectance)
226  {
227  double theReflectance = Reflectance->Value(thePhotonMomentum);
228  if( G4BooleanRand(theReflectance))
229  {
230  if(DiffuseReflectanceFraction)
231  {
232  double theDiffuseReflectanceFraction = DiffuseReflectanceFraction->Value(thePhotonMomentum);
233  if(G4BooleanRand(theDiffuseReflectanceFraction))
234  {
236  }
237  else
238  {
240  }
241  }
242  else
243  {
245  }
246  }
247  else
248  {
250  }
251 
252  }
253  else
254  {
256  }
257  }
258 
259 
260 
261 
262  // Take action according to track status
263 
264  if ( fTheStatus == SimpleDiffuse ) {
265  NewMomentum = G4LambertianRand(theGlobalNormal);
266  theFacetNormal = (NewMomentum - OldMomentum).unit();
267  }
268 
269  else if (fTheStatus==SimpleSpecular) {
270  theFacetNormal = theGlobalNormal;
271  G4double PdotN = OldMomentum * theFacetNormal;
272  NewMomentum = OldMomentum - (2.*PdotN)*theFacetNormal;
273  }
274 
276  aParticleChange.ProposeTrackStatus(fStopAndKill);
277  }
278 
280  {
281  NewMomentum=OldMomentum;
282  }
283  else aParticleChange.ProposeTrackStatus(fStopAndKill);
284 
285  NewMomentum = NewMomentum.unit();
286  aParticleChange.ProposeMomentumDirection(NewMomentum);
287  }
288  return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
289 
290  }
291 
292 
293 
294  // Compulsary method for G4DiscreteProcesses. Serves no actual function here.
295 
296  // GetMeanFreePath
298  G4double ,
299  G4ForceCondition* condition)
300  {
301  *condition = Forced;
302 
303  return DBL_MAX;
304  }
305 }
306 
307 
308 #endif
309 
310 
Store parameters for running LArG4.
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
Geant4 interface.
OpBoundaryProcessSimpleStatus fTheStatus
int OpVerbosity() const
G4bool G4BooleanRand(const G4double prob) const
G4double GetMeanFreePath(const G4Track &, G4double, G4ForceCondition *condition)
OpBoundaryProcessSimple(const G4String &processName="OpBoundary", G4ProcessType type=fOptical)