Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4UCNMaterialPropertiesTable.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28//
29//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
30//
31// G4UCNMaterialPropertiesTable
32// ----------------------------
33//
34// Derives from G4MaterialPropertiesTable and adds a double pointer to the
35// MicroRoughnessTable
36//
37// This file includes the initialization and calculation of the mr-lookup
38// tables. It also provides the functions to read from these tables and to
39// calculate the probability for certain angles.
40//
41// For a closer description see the header file
42//
43//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
44
46
48#include "G4SystemOfUnits.hh"
50
51#include <fstream>
52
54{
55 theMicroRoughnessTable = nullptr;
56 maxMicroRoughnessTable = nullptr;
57 theMicroRoughnessTransTable = nullptr;
58 maxMicroRoughnessTransTable = nullptr;
59
60 theta_i_min = 0. * degree;
61 theta_i_max = 90. * degree;
62
63 Emin = 0.e-9 * eV;
64 Emax = 1000.e-9 * eV;
65
66 no_theta_i = 90;
67 noE = 100;
68
69 theta_i_step = (theta_i_max - theta_i_min) / (no_theta_i - 1);
70 E_step = (Emax - Emin) / (noE - 1);
71
72 b = 1 * nm;
73 w = 30 * nm;
74
75 AngCut = 0.01 * degree;
76}
77
79{
80 delete theMicroRoughnessTable;
81 delete maxMicroRoughnessTable;
82 delete theMicroRoughnessTransTable;
83 delete maxMicroRoughnessTransTable;
84}
85
87
89{
90 return theMicroRoughnessTransTable;
91}
92
94 G4double* pmaxMicroRoughnessTable, G4double* pMicroRoughnessTransTable,
95 G4double* pmaxMicroRoughnessTransTable)
96{
97 theMicroRoughnessTable = pMicroRoughnessTable;
98 maxMicroRoughnessTable = pmaxMicroRoughnessTable;
99 theMicroRoughnessTransTable = pMicroRoughnessTransTable;
100 maxMicroRoughnessTransTable = pmaxMicroRoughnessTransTable;
101}
102
104{
105 G4int NEdim = 0;
106 G4int Nthetadim = 0;
107
108 // Checks if the number of angles is available and stores it
109
110 if (ConstPropertyExists("MR_NBTHETA")) {
111 Nthetadim = G4int(GetConstProperty("MR_NBTHETA") + 0.1);
112 }
113
114 // Checks if the number of energies is available and stores it
115
116 if (ConstPropertyExists("MR_NBE")) {
117 NEdim = G4int(GetConstProperty("MR_NBE") + 0.1);
118 }
119
120 // If both dimensions of the lookup-table are non-trivial:
121 // delete old tables if existing and allocate memory for new tables
122
123 if (Nthetadim * NEdim > 0) {
124 delete theMicroRoughnessTable;
125 theMicroRoughnessTable = new G4double[Nthetadim * NEdim];
126 delete maxMicroRoughnessTable;
127 maxMicroRoughnessTable = new G4double[Nthetadim * NEdim];
128 delete theMicroRoughnessTransTable;
129 theMicroRoughnessTransTable = new G4double[Nthetadim * NEdim];
130 delete maxMicroRoughnessTransTable;
131 maxMicroRoughnessTransTable = new G4double[Nthetadim * NEdim];
132 }
133}
134
136{
137 // Reads the parameters for the mr-probability computation from the
138 // corresponding material properties and stores it in the appropriate
139 // variables
140
141 b = GetConstProperty("MR_RRMS");
142 G4double b2 = b * b;
143 w = GetConstProperty("MR_CORRLEN");
144 G4double w2 = w * w;
145
146 no_theta_i = G4int(GetConstProperty("MR_NBTHETA") + 0.1);
147 noE = G4int(GetConstProperty("MR_NBE") + 0.1);
148
149 theta_i_min = GetConstProperty("MR_THETAMIN");
150 theta_i_max = GetConstProperty("MR_THETAMAX");
151 Emin = GetConstProperty("MR_EMIN");
152 Emax = GetConstProperty("MR_EMAX");
153 auto AngNoTheta = G4int(GetConstProperty("MR_ANGNOTHETA") + 0.1);
154 auto AngNoPhi = G4int(GetConstProperty("MR_ANGNOPHI") + 0.1);
155 AngCut = GetConstProperty("MR_ANGCUT");
156
157 // The Fermi potential was saved in neV by P.F.
158
159 G4double fermipot = GetConstProperty("FERMIPOT") * (1.e-9 * eV);
160
161 G4double theta_i, E;
162
163 // Calculates the increment in theta_i in the lookup-table
164 theta_i_step = (theta_i_max - theta_i_min) / (no_theta_i - 1);
165
166 // Calculates the increment in energy in the lookup-table
167 E_step = (Emax - Emin) / (noE - 1);
168
169 // Runs the lookup-table memory allocation
171
172 G4int counter = 0;
173
174 // Writes the mr-lookup-tables to files for immediate control
175 std::ofstream dateir("MRrefl.dat", std::ios::out);
176 std::ofstream dateit("MRtrans.dat", std::ios::out);
177
178 // G4cout << theMicroRoughnessTable << G4endl;
179
180 for (theta_i = theta_i_min; theta_i <= theta_i_max + 1e-6; theta_i += theta_i_step) {
181 // Calculation for each cell in the lookup-table
182 for (E = Emin; E <= Emax; E += E_step) {
183 *(theMicroRoughnessTable + counter) = G4UCNMicroRoughnessHelper::GetInstance()->IntIplus(E,
184 fermipot, theta_i, AngNoTheta, AngNoPhi, b2, w2, maxMicroRoughnessTable + counter, AngCut);
185
186 *(theMicroRoughnessTransTable + counter) =
187 G4UCNMicroRoughnessHelper::GetInstance()->IntIminus(E, fermipot, theta_i, AngNoTheta,
188 AngNoPhi, b2, w2, maxMicroRoughnessTransTable + counter, AngCut);
189
190 dateir << *(theMicroRoughnessTable + counter) << G4endl;
191 dateit << *(theMicroRoughnessTransTable + counter) << G4endl;
192
193 counter++;
194 }
195 }
196
197 dateir.close();
198 dateit.close();
199
200 // Writes the mr-lookup-tables to files for immediate control
201
202 std::ofstream dateic("MRcheck.dat", std::ios::out);
203 std::ofstream dateimr("MRmaxrefl.dat", std::ios::out);
204 std::ofstream dateimt("MRmaxtrans.dat", std::ios::out);
205
206 for (theta_i = theta_i_min; theta_i <= theta_i_max + 1e-6; theta_i += theta_i_step) {
207 for (E = Emin; E <= Emax; E += E_step) {
208 // tests the GetXXProbability functions by writing the entries
209 // of the lookup tables to files
210
211 dateic << GetMRIntProbability(theta_i, E) << G4endl;
212 dateimr << GetMRMaxProbability(theta_i, E) << G4endl;
213 dateimt << GetMRMaxTransProbability(theta_i, E) << G4endl;
214 }
215 }
216
217 dateic.close();
218 dateimr.close();
219 dateimt.close();
220}
221
223{
224 if (theMicroRoughnessTable == nullptr) {
225 G4cout << "Do not have theMicroRoughnessTable" << G4endl;
226 return 0.;
227 }
228
229 // if theta_i or energy outside the range for which the lookup table is
230 // calculated, the probability is set to zero
231 if (theta_i < theta_i_min || theta_i > theta_i_max || Energy < Emin || Energy > Emax) {
232 return 0.;
233 }
234
235 // Determines the nearest cell in the lookup table which contains
236 // the probability
237
238 auto theta_i_pos = G4int((theta_i - theta_i_min) / theta_i_step + 0.5);
239 auto E_pos = G4int((Energy - Emin) / E_step + 0.5);
240
241 // lookup table is onedimensional (1 row), energy is in rows,
242 // theta_i in columns
243 return *(theMicroRoughnessTable + E_pos + theta_i_pos * (noE - 1));
244}
245
247{
248 if (theMicroRoughnessTransTable == nullptr) {
249 return 0.;
250 }
251
252 // if theta_i or energy outside the range for which the lookup table
253 // is calculated, the probability is set to zero
254
255 if (theta_i < theta_i_min || theta_i > theta_i_max || Energy < Emin || Energy > Emax) {
256 return 0.;
257 }
258
259 // Determines the nearest cell in the lookup table which contains
260 // the probability
261
262 auto theta_i_pos = G4int((theta_i - theta_i_min) / theta_i_step + 0.5);
263 auto E_pos = G4int((Energy - Emin) / E_step + 0.5);
264
265 // lookup table is onedimensional (1 row), energy is in rows,
266 // theta_i in columns
267
268 return *(theMicroRoughnessTransTable + E_pos + theta_i_pos * (noE - 1));
269}
270
272{
273 if (maxMicroRoughnessTable == nullptr) {
274 return 0.;
275 }
276
277 // if theta_i or energy outside the range for which the lookup table
278 // is calculated, the probability is set to zero
279
280 if (theta_i < theta_i_min || theta_i > theta_i_max || Energy < Emin || Energy > Emax) {
281 return 0.;
282 }
283
284 // Determines the nearest cell in the lookup table which contains
285 // the probability
286
287 auto theta_i_pos = G4int((theta_i - theta_i_min) / theta_i_step + 0.5);
288 auto E_pos = G4int((Energy - Emin) / E_step + 0.5);
289
290 // lookup table is onedimensional (1 row), energy is in rows,
291 // theta_i in columns
292
293 return *(maxMicroRoughnessTable + E_pos + theta_i_pos * noE);
294}
295
297 G4double theta_i, G4double Energy, G4double value)
298{
299 if (maxMicroRoughnessTable != nullptr) {
300 if (theta_i < theta_i_min || theta_i > theta_i_max || Energy < Emin || Energy > Emax) {
301 }
302 else {
303 // Determines the nearest cell in the lookup table which contains
304 // the probability
305
306 auto theta_i_pos = G4int((theta_i - theta_i_min) / theta_i_step + 0.5);
307 auto E_pos = G4int((Energy - Emin) / E_step + 0.5);
308
309 // lookup table is onedimensional (1 row), energy is in rows,
310 // theta_i in columns
311
312 *(maxMicroRoughnessTable + E_pos + theta_i_pos * noE) = value;
313 }
314 }
315}
316
318{
319 if (maxMicroRoughnessTransTable == nullptr) {
320 return 0.;
321 }
322
323 // if theta_i or energy outside the range for which the lookup table
324 // is calculated, the probability is set to zero
325
326 if (theta_i < theta_i_min || theta_i > theta_i_max || Energy < Emin || Energy > Emax) {
327 return 0.;
328 }
329
330 // Determines the nearest cell in the lookup table which contains
331 // the probability
332
333 auto theta_i_pos = G4int((theta_i - theta_i_min) / theta_i_step + 0.5);
334 auto E_pos = G4int((Energy - Emin) / E_step + 0.5);
335
336 // lookup table is onedimensional (1 row), energy is in rows,
337 // theta_i in columns
338
339 return *(maxMicroRoughnessTransTable + E_pos + theta_i_pos * noE);
340}
341
343 G4double theta_i, G4double Energy, G4double value)
344{
345 if (maxMicroRoughnessTransTable != nullptr) {
346 if (theta_i < theta_i_min || theta_i > theta_i_max || Energy < Emin || Energy > Emax) {
347 }
348 else {
349 // Determines the nearest cell in the lookup table which contains
350 // the probability
351
352 auto theta_i_pos = G4int((theta_i - theta_i_min) / theta_i_step + 0.5);
353 auto E_pos = G4int((Energy - Emin) / E_step + 0.5);
354
355 // lookup table is onedimensional (1 row), energy is in rows,
356 // theta_i in columns
357
358 *(maxMicroRoughnessTransTable + E_pos + theta_i_pos * noE) = value;
359 }
360 }
361}
362
364 G4double theta_i, G4double Energy, G4double fermipot, G4double theta_o, G4double phi_o)
365{
367 Energy, fermipot, theta_i, theta_o, phi_o, b, w, AngCut);
368}
369
371 G4double theta_i, G4double Energy, G4double fermipot, G4double theta_o, G4double phi_o)
372{
374 Energy, fermipot, theta_i, theta_o, phi_o, b, w, AngCut);
375}
376
378{
379 G4double k = std::sqrt(2 * neutron_mass_c2 * E / hbarc_squared);
380 G4double k_l = std::sqrt(2 * neutron_mass_c2 * VFermi / hbarc_squared);
381
382 // see eq. 17 of the Steyerl paper
383 return 2 * b * k * std::cos(theta_i) < 1 && 2 * b * k_l < 1;
384}
385
387 G4double E, G4double VFermi, G4double theta_i)
388{
389 G4double k2 = 2 * neutron_mass_c2 * E / hbarc_squared;
390 G4double k_l2 = 2 * neutron_mass_c2 * VFermi / hbarc_squared;
391
392 if (E * (std::cos(theta_i) * std::cos(theta_i)) < VFermi) {
393 return false;
394 }
395
396 G4double kS2 = k_l2 - k2;
397
398 // see eq. 18 of the Steyerl paper
399 return 2 * b * std::sqrt(kS2) * std::cos(theta_i) < 1 && 2 * b * std::sqrt(k_l2) < 1;
400}
401
403 G4int no_theta, G4int no_E, G4double theta_min, G4double theta_max, G4double E_min,
404 G4double E_max, G4int AngNoTheta, G4int AngNoPhi, G4double AngularCut)
405{
406 // Removes an existing RMS roughness
407 if (ConstPropertyExists("MR_RRMS")) {
408 RemoveConstProperty("MR_RRMS");
409 }
410
411 // Adds a new RMS roughness
412 AddConstProperty("MR_RRMS", bb);
413
414 // Removes an existing correlation length
415 if (ConstPropertyExists("MR_CORRLEN")) {
416 RemoveConstProperty("MR_CORRLEN");
417 }
418
419 // Adds a new correlation length
420 AddConstProperty("MR_CORRLEN", ww);
421
422 // Removes an existing number of thetas
423 if (ConstPropertyExists("MR_NBTHETA")) {
424 RemoveConstProperty("MR_NBTHETA");
425 }
426
427 // Adds a new number of thetas
428 AddConstProperty("MR_NBTHETA", (G4double)no_theta);
429
430 // Removes an existing number of Energies
431 if (ConstPropertyExists("MR_NBE")) {
432 RemoveConstProperty("MR_NBE");
433 }
434
435 // Adds a new number of Energies
436 AddConstProperty("MR_NBE", (G4double)no_E);
437
438 // Removes an existing minimum theta
439 if (ConstPropertyExists("MR_THETAMIN")) {
440 RemoveConstProperty("MR_THETAMIN");
441 }
442
443 // Adds a new minimum theta
444 AddConstProperty("MR_THETAMIN", theta_min);
445
446 // Removes an existing maximum theta
447 if (ConstPropertyExists("MR_THETAMAX")) {
448 RemoveConstProperty("MR_THETAMAX");
449 }
450
451 // Adds a new maximum theta
452 AddConstProperty("MR_THETAMAX", theta_max);
453
454 // Removes an existing minimum energy
455 if (ConstPropertyExists("MR_EMIN")) {
456 RemoveConstProperty("MR_EMIN");
457 }
458
459 // Adds a new minimum energy
460 AddConstProperty("MR_EMIN", E_min);
461
462 // Removes an existing maximum energy
463 if (ConstPropertyExists("MR_EMAX")) {
464 RemoveConstProperty("MR_EMAX");
465 }
466
467 // Adds a new maximum energy
468 AddConstProperty("MR_EMAX", E_max);
469
470 // Removes an existing Theta angle number
471 if (ConstPropertyExists("MR_ANGNOTHETA")) {
472 RemoveConstProperty("MR_ANGNOTHETA");
473 }
474
475 // Adds a new Theta angle number
476 AddConstProperty("MR_ANGNOTHETA", (G4double)AngNoTheta);
477
478 // Removes an existing Phi angle number
479 if (ConstPropertyExists("MR_ANGNOPHI")) {
480 RemoveConstProperty("MR_ANGNOPHI");
481 }
482
483 // Adds a new Phi angle number
484 AddConstProperty("MR_ANGNOPHI", (G4double)AngNoPhi);
485
486 // Removes an existing angular cut
487 if (ConstPropertyExists("MR_ANGCUT")) {
488 RemoveConstProperty("MR_ANGCUT");
489 }
490
491 // Adds a new angle number
492 AddConstProperty("MR_ANGCUT", AngularCut);
493
494 // Starts the lookup table calculation
496}
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
void AddConstProperty(const G4String &key, G4double propertyValue, G4bool createNewKey=false)
G4bool ConstPropertyExists(const G4String &key) const
G4double GetConstProperty(const G4String &key) const
void RemoveConstProperty(const G4String &key)
G4double GetMRMaxTransProbability(G4double, G4double)
void SetMicroRoughnessParameters(G4double, G4double, G4int, G4int, G4double, G4double, G4double, G4double, G4int, G4int, G4double)
G4double GetMRProbability(G4double, G4double, G4double, G4double, G4double)
G4bool ConditionsValid(G4double E, G4double VFermi, G4double theta_i)
void LoadMicroRoughnessTables(G4double *, G4double *, G4double *, G4double *)
G4bool TransConditionsValid(G4double E, G4double VFermi, G4double theta_i)
void SetMRMaxProbability(G4double, G4double, G4double)
void SetMRMaxTransProbability(G4double, G4double, G4double)
G4double GetMRIntTransProbability(G4double, G4double)
G4double GetMRMaxProbability(G4double, G4double)
G4double GetMRTransProbability(G4double, G4double, G4double, G4double, G4double)
G4double GetMRIntProbability(G4double, G4double)
G4double ProbIplus(G4double, G4double, G4double, G4double, G4double, G4double, G4double, G4double) const
G4double IntIminus(G4double, G4double, G4double, G4int, G4int, G4double, G4double, G4double *, G4double) const
static G4UCNMicroRoughnessHelper * GetInstance()
G4double ProbIminus(G4double, G4double, G4double, G4double, G4double, G4double, G4double, G4double) const
G4double IntIplus(G4double, G4double, G4double, G4int, G4int, G4double, G4double, G4double *, G4double) const