111{
114
115
116
117
118
119 const G4Step* pStep = &aStep;
120
122
123 if (hStep) pStep = hStep;
124
127
128 if (isOnBoundary) {
131 } else {
135 }
136
141 }
142
144 GetMaterialPropertiesTable();
146 GetMaterialPropertiesTable();
147
150
153 G4cout <<
" vol1: " << volnam1 <<
", vol2: " << volnam2 <<
G4endl;
156 }
157
158 if (Material1 == Material2) {
162 }
163
165
167
168
169
170
171
173 std::vector<G4Navigator*>::iterator iNav =
175 GetActiveNavigatorsIterator();
176
178 (iNav[hNavId])->GetGlobalExitNormal(theGlobalPoint,&valid);
179
180 if (valid) {
181 theGlobalNormal = -theGlobalNormal;
182 }
183 else
184 {
186 ed << " G4UCNBoundaryProcess/PostStepDoIt(): "
187 << " The Navigator reports that it returned an invalid normal"
189 G4Exception(
"G4UCNBoundaryProcess::PostStepDoIt",
"UCNBoun01",
191 "Invalid Surface Normal - Geometry must return valid surface normal");
192 }
193
195
197
198 if (OldMomentum * theGlobalNormal > 0.0) {
199#ifdef G4OPTICAL_DEBUG
201 ed << " G4UCNBoundaryProcess/PostStepDoIt(): "
202 << " theGlobalNormal points in a wrong direction. "
204 ed << " The momentum of the photon arriving at interface (oldMomentum)"
205 <<
" must exit the volume cross in the step. " <<
G4endl;
206 ed <<
" So it MUST have dot < 0 with the normal that Exits the new volume (globalNormal)." <<
G4endl;
207 ed <<
" >> The dot product of oldMomentum and global Normal is " << OldMomentum*theGlobalNormal <<
G4endl;
208 ed <<
" Old Momentum (during step) = " << OldMomentum <<
G4endl;
209 ed <<
" Global Normal (Exiting New Vol) = " << theGlobalNormal <<
G4endl;
211 G4Exception(
"G4UCNBoundaryProcess::PostStepDoIt",
"UCNBoun02",
213 ed,
214 "Invalid Surface Normal - Geometry must return valid surface normal pointing in the right direction");
215#else
216 theGlobalNormal = -theGlobalNormal;
217#endif
218 }
219
221
222 G4double theMomentumNormal = theNeutronMomentum*theGlobalNormal;
224 (OldMomentum * theGlobalNormal);
225
226 G4double Enormal = theMomentumNormal*theMomentumNormal/2./neutron_mass_c2;
228
233
234 if (aMaterialPropertiesTable2) {
239 }
240
242 if (aMaterialPropertiesTable1)
244
245 G4double FermiPotDiff = FermiPot2 - FermiPot1;
246
248 G4cout <<
"UCNBoundaryProcess: new FermiPot: " << FermiPot2/neV
249 <<
"neV, old FermiPot:" << FermiPot1/neV <<
"neV" <<
G4endl;
250
251
252
253 DoMicroRoughnessReflection = UseMicroRoughnessReflection;
254
256
257 if (!aMaterialPropertiesTable2) {
258
259 nNoMPT++;
262 DoMicroRoughnessReflection = false;
263
264 } else {
265
267
268 nNoMRT++;
271
272 DoMicroRoughnessReflection = false;
273 }
274
275
276
277
278 theta_i = OldMomentum.
angle(-theGlobalNormal);
279
280
281
282 if (!aMaterialPropertiesTable2->
283 ConditionsValid(Energy, FermiPotDiff, theta_i)) {
284
285 nNoMRCondition++;
288
289 DoMicroRoughnessReflection = false;
290 }
291 }
292
295
296
297
298 if (DoMicroRoughnessReflection) {
299
300
301
302 MRpDiffuse = aMaterialPropertiesTable2->
303 GetMRIntProbability(theta_i, Energy);
304
305
306
307 MRpDiffuseTrans = aMaterialPropertiesTable2->
308 GetMRIntTransProbability(theta_i, Energy);
309
311 G4cout <<
"theta: " << theta_i/degree <<
"degree" <<
G4endl;
312 G4cout <<
"Energy: " << Energy/neV <<
"neV"
313 <<
", Enormal: " << Enormal/neV <<
"neV" <<
G4endl;
314 G4cout <<
"FermiPotDiff: " << FermiPotDiff/neV <<
"neV " <<
G4endl;
315 G4cout <<
"Reflection_prob: " << MRpDiffuse
316 <<
", Transmission_prob: " << MRpDiffuseTrans <<
G4endl;
317 }
318 }
319
320 if (!High(Enormal, FermiPotDiff)) {
321
322
323
325
326
327
328 if (Loss(pUpScatter, theVelocityNormal, FermiPotDiff)) {
329
330
333
334 nAbsorption++;
337
339 }
340
341
342
343 if (SpinFlip(pSpinFlip)) {
344 nFlip++;
347
350 }
351
352
353
355
356
357
358 if (DoMicroRoughnessReflection)
359 NewMomentum =
MRreflect(MRpDiffuse, OldMomentum, theGlobalNormal,
360 Energy, FermiPotDiff);
361 else
362
363
364
365 NewMomentum = Reflect(pDiffuse, OldMomentum, theGlobalNormal);
366
368
369 } else {
370
371
372
374
375
376
377
378
379
380
382
383 if (DoMicroRoughnessReflection) {
384
386
387 NewMomentum =
389 theGlobalNormal, Energy, FermiPotDiff, Enew);
390
391 if (Enew == 0.) {
395 } else {
400 }
401
402 } else {
403
404 G4double reflectivity = Reflectivity(FermiPotDiff, Enormal);
405
407 << reflectivity <<
G4endl;
408
410
411
412
413 NewMomentum = Reflect(pDiffuse, OldMomentum, theGlobalNormal);
415
416 } else {
417
418
419
420 G4double Enew = Transmit(FermiPotDiff, Energy);
421
422
423
424
425 G4double mass = -std::sqrt(theMomentumNormal*theMomentumNormal -
426 neutron_mass_c2*2.*FermiPotDiff);
427
428
429
430 NewMomentum =
431 theNeutronMomentum - (theMomentumNormal-mass)*theGlobalNormal;
432
433 nSnellTransmit++;
436
441
443 G4cout <<
"Energy: " << Energy/neV <<
"neV, Enormal: "
444 << Enormal/neV << "neV, fpdiff " << FermiPotDiff/neV
445 <<
"neV, Enew " << Enew/neV <<
"neV" <<
G4endl;
446 G4cout <<
"UCNBoundaryProcess: Transmit and set the new Energy "
448 }
449 }
450 }
451 }
452
454}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
double angle(const Hep3Vector &) const
const G4ThreeVector & GetMomentumDirection() const
const G4ThreeVector & GetPolarization() const
G4double GetConstProperty(const G4String &key) const
static const G4Step * GetHyperStep()
static G4int GetHypNavigatorID()
void ProposePolarization(G4double Px, G4double Py, G4double Pz)
G4double GetEnergy() const
void Initialize(const G4Track &) override
void ProposeVelocity(G4double finalVelocity)
void ProposeEnergy(G4double finalEnergy)
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4StepStatus GetStepStatus() const
G4Material * GetMaterial() const
const G4ThreeVector & GetPosition() const
G4VPhysicalVolume * GetPhysicalVolume() const
G4StepPoint * GetPreStepPoint() const
G4StepPoint * GetPostStepPoint() const
G4double GetVelocity() const
G4ThreeVector GetMomentum() const
const G4DynamicParticle * GetDynamicParticle() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
G4double GetStepLength() const
static G4TransportationManager * GetTransportationManager()
G4ThreeVector MRreflectHigh(G4double, G4double, G4double, G4ThreeVector, G4ThreeVector, G4double, G4double, G4double &)
G4ThreeVector MRreflect(G4double, G4ThreeVector, G4ThreeVector, G4double, G4double)
G4double * GetMicroRoughnessTable()
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
const G4String & GetName() const
G4ParticleChange aParticleChange