EGSnrc C++ class library
Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs++
estar
estar_dataParser.cpp
1
/*
2
###############################################################################
3
#
4
# EGSnrc estar
5
# Copyright (C) 2026 National Research Council Canada
6
#
7
# This file is part of EGSnrc.
8
#
9
# EGSnrc is free software: you can redistribute it and/or modify it under
10
# the terms of the GNU Affero General Public License as published by the
11
# Free Software Foundation, either version 3 of the License, or (at your
12
# option) any later version.
13
#
14
# EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
15
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
17
# more details.
18
#
19
# You should have received a copy of the GNU Affero General Public License
20
# along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
21
#
22
###############################################################################
23
#
24
# Author: Sehmimul Hoque, 2022
25
#
26
# Contributors: Martin J. Berger
27
# Johnathan S. Coursey
28
# Reid Townson
29
# Ernesto Mainegra-Hing
30
#
31
# Based on the original ESTAR code by Martin J. Berger,
32
# National Institute of Standards and Technology (NIST). Including
33
# modifications by Johnathan S. Coursey.
34
#
35
###############################################################################
36
*/
37
38
#include <iostream>
39
#include <fstream>
40
#include <iomanip>
41
#include <assert.h>
42
#include "estar_dataParser.h"
43
#include "estar_dataTables.h"
44
#include "
egs_functions.h
"
45
46
/*
47
The purpose of this module is to read data from the elementData.h
48
file and then to properly structure the data for usage in other modules.
49
There are 100 sets of data in elementData.h (indexed by atomic number)
50
where each set of data corresponds to each element.
51
* For example: the third set of data in elementData.h is the data for Lithium
52
*/
53
54
ElementOscillatorData
parseData() {
55
ElementOscillatorData
ds;
56
ds.
numLevelsStandard
= 113;
// number of elements in the standard energy grid
57
58
const
int
arr_len = 14532;
59
int
j = 0;
60
61
for
(
int
i = 0; i < 100; i++) {
62
63
ds.
nmax
[i] =
static_cast<
int
>
(elementData[j]);
64
65
if
(ds.
nmax
[i] < 0 || j + 2 + 2*ds.
nmax
[i] + ds.
numLevelsStandard
> arr_len) {
66
egsFatal
(
"estar::parseData: Data layout for element %d would read past end "
67
"of elementData array (j=%d, nmax=%d, arr_len=%d).\n"
,
68
i, j, ds.
nmax
[i], arr_len);
69
}
70
71
// The second element of each set is 113 (numLevelsStandard) and is skipped
72
int
k = j + 2;
73
74
/*
75
Read nc values directly into ds.nc.
76
ds.nmax[i] is the number of oscillators for this element.
77
*/
78
for
(
int
a = 0; a < ds.
nmax
[i]; a++) {
79
if
(a >= 26) {
80
egsFatal
(
"estar::parseData: Oscillator index %d exceeds nc "
81
"maximum of 25 for element index %d.\n"
, a, i);
82
}
83
ds.
nc
[i][a] =
static_cast<
int
>
(elementData[k]);
84
k++;
85
}
86
87
/*
88
Read bd values directly into ds.bd.
89
*/
90
for
(
int
a = 0; a < ds.
nmax
[i]; a++) {
91
if
(a >= 26) {
92
egsFatal
(
"estar::parseData: Oscillator index %d exceeds bd "
93
"maximum of 25 for element index %d.\n"
, a, i);
94
}
95
ds.
bd
[i][a] = elementData[k];
96
k++;
97
}
98
99
// rlos (loss function) values are present in elementData but are not used
100
// by the ESTAR density correction calculation. We advance k past them
101
// to keep j correctly positioned for the next element's data block.
102
k += ds.
numLevelsStandard
;
103
104
j = k;
105
}
106
107
return
ds;
108
}
109
110
/*
111
The output of parse() below is a parseformula object. It takes input a formula string
112
and produces the object or an error message
113
for example: for MgCl2
114
we will get: str_arr = ["Mg", "Cl"]
115
num_arr = [1,2]
116
mmax = 2
117
*/
118
parseformula
parse(
string
str) {
119
parseformula
pf;
120
pf.elem_types = 0;
121
int
str_len = str.length();
// length of formula
122
int
i = 0;
123
int
j = 0;
124
while
(i < str_len) {
125
if
(j >= 100) {
126
egsFatal
(
"estar::parse: Element type count exceeded maximum of 100"
127
" while parsing formula '%s'.\n"
, str.c_str());
128
}
129
130
if
(isupper(
static_cast<
unsigned
char
>
(str[i])) != 0) {
// means str[i] is uppercase
131
if
(i + 1 < str_len && islower(
static_cast<
unsigned
char
>
(str[i+1])) != 0) {
132
pf.str_arr[j] = str.substr(i,2);
133
i = i+2;
134
}
135
else
{
136
pf.str_arr[j] = str.substr(i,1);
137
i = i+1;
138
}
139
}
140
else
{
141
egsFatal
(
"estar::parse: Formula '%s' is malformed at character '%c' (index %d).\n"
142
"Element symbols must begin with an uppercase letter.\n"
,
143
str.c_str(), str[i], i);
144
}
145
146
if
(i < str_len && isdigit(
static_cast<
unsigned
char
>
(str[i])) != 0) {
147
int
digit_start = i;
148
while
(i < str_len && isdigit(
static_cast<
unsigned
char
>
(str[i])) != 0) {
149
i = i + 1;
150
}
151
int
digit_len = i - digit_start;
152
153
// Guard against absurdly large numbers that would overflow strtol
154
if
(digit_len > 9) {
155
egsFatal
(
"estar::parse: Atom count in formula '%s' has %d digits which "
156
"exceeds the maximum of 9.\n"
, str.c_str(), digit_len);
157
}
158
159
std::string digit_str = str.substr(digit_start, digit_len);
160
char
*end;
161
errno = 0;
162
long
val = std::strtol(digit_str.c_str(), &end, 10);
163
164
if
(errno != 0 || end == digit_str.c_str() || val <= 0 || val > 99) {
165
egsFatal
(
"estar::parse: Invalid atom count '%s' in formula '%s'.\n"
166
"Atom count must be a positive integer no greater than 99.\n"
,
167
digit_str.c_str(), str.c_str());
168
}
169
170
pf.num_arr[j] =
static_cast<
int
>
(val);
171
}
172
else
{
173
pf.num_arr[j] = 1;
174
}
175
j = j + 1;
176
}
177
pf.elem_types = j;
178
return
pf;
179
};
180
egs_functions.h
Global egspp functions header file.
egsFatal
EGS_InfoFunction EGS_EXPORT egsFatal
Always use this function for reporting fatal errors.
Definition:
egs_functions.cpp:137
ElementOscillatorData
Holds the dispersion oscillator data for all 100 elements.
Definition:
estar_dataParser.h:55
ElementOscillatorData::nc
int nc[100][26]
Number of electrons in each subshell for each element.
Definition:
estar_dataParser.h:78
ElementOscillatorData::bd
double bd[100][26]
Absorption edge energies (in units of hbar) for each oscillator.
Definition:
estar_dataParser.h:87
ElementOscillatorData::numLevelsStandard
int numLevelsStandard
Number of elements in the standard energy grid.
Definition:
estar_dataParser.h:68
ElementOscillatorData::nmax
int nmax[100]
Number of dispersion oscillators for each element.
Definition:
estar_dataParser.h:65
parseformula
Holds the parsed representation of a chemical formula.
Definition:
estar_dataParser.h:114
Generated by
1.9.1