source: CIVL/examples/xsbench/src/CalculateXS.c

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 3.9 KB
Line 
1#include "XSbench_header.h"
2
3// Calculates the microscopic cross section for a given nuclide & energy
4void calculate_micro_xs( double p_energy, int nuc, long n_isotopes,
5 long n_gridpoints,
6 GridPoint * restrict energy_grid,
7 NuclideGridPoint ** restrict nuclide_grids,
8 int idx, double * restrict xs_vector ){
9
10 // Variables
11 double f;
12 NuclideGridPoint * low, * high;
13
14 // pull ptr from energy grid and check to ensure that
15 // we're not reading off the end of the nuclide's grid
16 if( energy_grid[idx].xs_ptrs[nuc] == n_gridpoints - 1 )
17 low = &nuclide_grids[nuc][energy_grid[idx].xs_ptrs[nuc] - 1];
18 else
19 low = &nuclide_grids[nuc][energy_grid[idx].xs_ptrs[nuc]];
20
21 high = low + 1;
22
23 // calculate the re-useable interpolation factor
24 f = (high->energy - p_energy) / (high->energy - low->energy);
25
26 // Total XS
27 xs_vector[0] = high->total_xs - f * (high->total_xs - low->total_xs);
28
29 // Elastic XS
30 xs_vector[1] = high->elastic_xs - f * (high->elastic_xs - low->elastic_xs);
31
32 // Absorbtion XS
33 xs_vector[2] = high->absorbtion_xs - f * (high->absorbtion_xs - low->absorbtion_xs);
34
35 // Fission XS
36 xs_vector[3] = high->fission_xs - f * (high->fission_xs - low->fission_xs);
37
38 // Nu Fission XS
39 xs_vector[4] = high->nu_fission_xs - f * (high->nu_fission_xs - low->nu_fission_xs);
40
41 //test
42 /*
43 if( omp_get_thread_num() == 0 )
44 {
45 printf("Lookup: Energy = %lf, nuc = %d\n", p_energy, nuc);
46 printf("e_h = %lf e_l = %lf\n", high->energy , low->energy);
47 printf("xs_h = %lf xs_l = %lf\n", high->elastic_xs, low->elastic_xs);
48 printf("total_xs = %lf\n\n", xs_vector[1]);
49 }
50 */
51
52}
53
54// Calculates macroscopic cross section based on a given material & energy
55void calculate_macro_xs( double p_energy, int mat, long n_isotopes,
56 long n_gridpoints, int * restrict num_nucs,
57 double ** restrict concs,
58 GridPoint * restrict energy_grid,
59 NuclideGridPoint ** restrict nuclide_grids,
60 int ** restrict mats,
61 double * restrict macro_xs_vector ){
62 double xs_vector[5];
63 int p_nuc; // the nuclide we are looking up
64 long idx = 0;
65 double conc; // the concentration of the nuclide in the material
66
67 // cleans out macro_xs_vector
68 for( int k = 0; k < 5; k++ )
69 macro_xs_vector[k] = 0;
70
71 // binary search for energy on unionized energy grid (UEG)
72 idx = grid_search( n_isotopes * n_gridpoints, p_energy,
73 energy_grid);
74
75 // Once we find the pointer array on the UEG, we can pull the data
76 // from the respective nuclide grids, as well as the nuclide
77 // concentration data for the material
78 // Each nuclide from the material needs to have its micro-XS array
79 // looked up & interpolatied (via calculate_micro_xs). Then, the
80 // micro XS is multiplied by the concentration of that nuclide
81 // in the material, and added to the total macro XS array.
82 for( int j = 0; j < num_nucs[mat]; j++ )
83 {
84 p_nuc = mats[mat][j];
85 conc = concs[mat][j];
86 calculate_micro_xs( p_energy, p_nuc, n_isotopes,
87 n_gridpoints, energy_grid,
88 nuclide_grids, idx, xs_vector );
89 for( int k = 0; k < 5; k++ )
90 macro_xs_vector[k] += xs_vector[k] * conc;
91 }
92
93 //test
94 /*
95 for( int k = 0; k < 5; k++ )
96 printf("Energy: %lf, Material: %d, XSVector[%d]: %lf\n",
97 p_energy, mat, k, macro_xs_vector[k]);
98 */
99}
100
101
102// (fixed) binary search for energy on unionized energy grid
103// returns lower index
104long grid_search( long n, double quarry, GridPoint * A)
105{
106 long lowerLimit = 0;
107 long upperLimit = n-1;
108 long examinationPoint;
109 long length = upperLimit - lowerLimit;
110
111 while( length > 1 )
112 {
113 examinationPoint = lowerLimit + ( length / 2 );
114
115 if( A[examinationPoint].energy > quarry )
116 upperLimit = examinationPoint;
117 else
118 lowerLimit = examinationPoint;
119
120 length = upperLimit - lowerLimit;
121 }
122
123 return lowerLimit;
124}
Note: See TracBrowser for help on using the repository browser.