Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/materials/src/G4UCNMaterialPropertiesTable.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 
 45 #include "G4UCNMaterialPropertiesTable.hh"
 46 
 47 #include "G4PhysicalConstants.hh"
 48 #include "G4SystemOfUnits.hh"
 49 #include "G4UCNMicroRoughnessHelper.hh"
 50 
 51 #include <fstream>
 52 
 53 G4UCNMaterialPropertiesTable::G4UCNMaterialPropertiesTable()
 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 
 78 G4UCNMaterialPropertiesTable::~G4UCNMaterialPropertiesTable()
 79 {
 80   delete theMicroRoughnessTable;
 81   delete maxMicroRoughnessTable;
 82   delete theMicroRoughnessTransTable;
 83   delete maxMicroRoughnessTransTable;
 84 }
 85 
 86 G4double* G4UCNMaterialPropertiesTable::GetMicroRoughnessTable() { return theMicroRoughnessTable; }
 87 
 88 G4double* G4UCNMaterialPropertiesTable::GetMicroRoughnessTransTable()
 89 {
 90   return theMicroRoughnessTransTable;
 91 }
 92 
 93 void G4UCNMaterialPropertiesTable::LoadMicroRoughnessTables(G4double* pMicroRoughnessTable,
 94   G4double* pmaxMicroRoughnessTable, G4double* pMicroRoughnessTransTable,
 95   G4double* pmaxMicroRoughnessTransTable)
 96 {
 97   theMicroRoughnessTable = pMicroRoughnessTable;
 98   maxMicroRoughnessTable = pmaxMicroRoughnessTable;
 99   theMicroRoughnessTransTable = pMicroRoughnessTransTable;
100   maxMicroRoughnessTransTable = pmaxMicroRoughnessTransTable;
101 }
102 
103 void G4UCNMaterialPropertiesTable::InitMicroRoughnessTables()
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 
135 void G4UCNMaterialPropertiesTable::ComputeMicroRoughnessTables()
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
170   InitMicroRoughnessTables();
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 
222 G4double G4UCNMaterialPropertiesTable::GetMRIntProbability(G4double theta_i, G4double Energy)
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 
246 G4double G4UCNMaterialPropertiesTable::GetMRIntTransProbability(G4double theta_i, G4double Energy)
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 
271 G4double G4UCNMaterialPropertiesTable::GetMRMaxProbability(G4double theta_i, G4double Energy)
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 
296 void G4UCNMaterialPropertiesTable::SetMRMaxProbability(
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 
317 G4double G4UCNMaterialPropertiesTable::GetMRMaxTransProbability(G4double theta_i, G4double Energy)
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 
342 void G4UCNMaterialPropertiesTable::SetMRMaxTransProbability(
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 
363 G4double G4UCNMaterialPropertiesTable::GetMRProbability(
364   G4double theta_i, G4double Energy, G4double fermipot, G4double theta_o, G4double phi_o)
365 {
366   return G4UCNMicroRoughnessHelper::GetInstance()->ProbIplus(
367     Energy, fermipot, theta_i, theta_o, phi_o, b, w, AngCut);
368 }
369 
370 G4double G4UCNMaterialPropertiesTable::GetMRTransProbability(
371   G4double theta_i, G4double Energy, G4double fermipot, G4double theta_o, G4double phi_o)
372 {
373   return G4UCNMicroRoughnessHelper::GetInstance()->ProbIminus(
374     Energy, fermipot, theta_i, theta_o, phi_o, b, w, AngCut);
375 }
376 
377 G4bool G4UCNMaterialPropertiesTable::ConditionsValid(G4double E, G4double VFermi, G4double theta_i)
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 
386 G4bool G4UCNMaterialPropertiesTable::TransConditionsValid(
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 
402 void G4UCNMaterialPropertiesTable::SetMicroRoughnessParameters(G4double ww, G4double bb,
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
495   ComputeMicroRoughnessTables();
496 }
497