mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-21 14:35:27 -04:00
making use of endf-python package more (#3786)
Co-authored-by: GuySten <guyste@post.bgu.ac.il>
This commit is contained in:
parent
4f4930b633
commit
8053111f2d
2 changed files with 24 additions and 272 deletions
|
|
@ -24,7 +24,7 @@ import numpy as np
|
|||
import openmc.checkvalue as cv
|
||||
from openmc.mixin import EqualityMixin
|
||||
from .data import ATOMIC_SYMBOL, gnds_name, EV_PER_MEV, K_BOLTZMANN
|
||||
from .endf import ENDF_FLOAT_RE
|
||||
from endf.records import ENDF_FLOAT_RE
|
||||
|
||||
|
||||
def get_metadata(zaid, metastable_scheme='nndc'):
|
||||
|
|
|
|||
|
|
@ -10,11 +10,31 @@ import io
|
|||
from pathlib import PurePath
|
||||
import re
|
||||
|
||||
import numpy as np
|
||||
|
||||
from .data import gnds_name
|
||||
from .function import Tabulated1D
|
||||
from endf.records import float_endf
|
||||
from endf.records import (
|
||||
float_endf,
|
||||
py_float_endf,
|
||||
int_endf,
|
||||
get_text_record,
|
||||
get_cont_record,
|
||||
get_head_record,
|
||||
get_list_record,
|
||||
get_tab1_record as _get_tab1_record,
|
||||
get_tab2_record,
|
||||
get_intg_record,
|
||||
)
|
||||
|
||||
|
||||
def get_tab1_record(file_obj):
|
||||
"""Return data from a TAB1 record in an ENDF-6 file.
|
||||
|
||||
This wraps the endf package's get_tab1_record to return an
|
||||
openmc.data.Tabulated1D (which has HDF5 support and is a Function1D)
|
||||
instead of endf.Tabulated1D.
|
||||
"""
|
||||
params, tab = _get_tab1_record(file_obj)
|
||||
return params, Tabulated1D(tab.x, tab.y, tab.breakpoints, tab.interpolation)
|
||||
|
||||
|
||||
_LIBRARY = {0: 'ENDF/B', 1: 'ENDF/A', 2: 'JEFF', 3: 'EFF',
|
||||
|
|
@ -61,274 +81,6 @@ SUM_RULES = {1: [2, 3],
|
|||
106: list(range(750, 800)),
|
||||
107: list(range(800, 850))}
|
||||
|
||||
ENDF_FLOAT_RE = re.compile(r'([\s\-\+]?\d*\.\d+)([\+\-]) ?(\d+)')
|
||||
|
||||
|
||||
def py_float_endf(s):
|
||||
"""Convert string of floating point number in ENDF to float.
|
||||
|
||||
The ENDF-6 format uses an 'e-less' floating point number format,
|
||||
e.g. -1.23481+10. Trying to convert using the float built-in won't work
|
||||
because of the lack of an 'e'. This function allows such strings to be
|
||||
converted while still allowing numbers that are not in exponential notation
|
||||
to be converted as well.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
s : str
|
||||
Floating-point number from an ENDF file
|
||||
|
||||
Returns
|
||||
-------
|
||||
float
|
||||
The number
|
||||
|
||||
"""
|
||||
return float(ENDF_FLOAT_RE.sub(r'\1e\2\3', s))
|
||||
|
||||
|
||||
def int_endf(s):
|
||||
"""Convert string of integer number in ENDF to int.
|
||||
|
||||
The ENDF-6 format technically allows integers to be represented by a field
|
||||
of all blanks. This function acts like int(s) except when s is a string of
|
||||
all whitespace, in which case zero is returned.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
s : str
|
||||
Integer or spaces
|
||||
|
||||
Returns
|
||||
-------
|
||||
integer
|
||||
The number or 0
|
||||
"""
|
||||
return 0 if s.isspace() else int(s)
|
||||
|
||||
|
||||
def get_text_record(file_obj):
|
||||
"""Return data from a TEXT record in an ENDF-6 file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
file_obj : file-like object
|
||||
ENDF-6 file to read from
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
Text within the TEXT record
|
||||
|
||||
"""
|
||||
return file_obj.readline()[:66]
|
||||
|
||||
|
||||
def get_cont_record(file_obj, skip_c=False):
|
||||
"""Return data from a CONT record in an ENDF-6 file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
file_obj : file-like object
|
||||
ENDF-6 file to read from
|
||||
skip_c : bool
|
||||
Determine whether to skip the first two quantities (C1, C2) of the CONT
|
||||
record.
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple
|
||||
The six items within the CONT record
|
||||
|
||||
"""
|
||||
line = file_obj.readline()
|
||||
if skip_c:
|
||||
C1 = None
|
||||
C2 = None
|
||||
else:
|
||||
C1 = float_endf(line[:11])
|
||||
C2 = float_endf(line[11:22])
|
||||
L1 = int_endf(line[22:33])
|
||||
L2 = int_endf(line[33:44])
|
||||
N1 = int_endf(line[44:55])
|
||||
N2 = int_endf(line[55:66])
|
||||
return (C1, C2, L1, L2, N1, N2)
|
||||
|
||||
|
||||
def get_head_record(file_obj):
|
||||
"""Return data from a HEAD record in an ENDF-6 file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
file_obj : file-like object
|
||||
ENDF-6 file to read from
|
||||
|
||||
Returns
|
||||
-------
|
||||
tuple
|
||||
The six items within the HEAD record
|
||||
|
||||
"""
|
||||
line = file_obj.readline()
|
||||
ZA = int(float_endf(line[:11]))
|
||||
AWR = float_endf(line[11:22])
|
||||
L1 = int_endf(line[22:33])
|
||||
L2 = int_endf(line[33:44])
|
||||
N1 = int_endf(line[44:55])
|
||||
N2 = int_endf(line[55:66])
|
||||
return (ZA, AWR, L1, L2, N1, N2)
|
||||
|
||||
|
||||
def get_list_record(file_obj):
|
||||
"""Return data from a LIST record in an ENDF-6 file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
file_obj : file-like object
|
||||
ENDF-6 file to read from
|
||||
|
||||
Returns
|
||||
-------
|
||||
list
|
||||
The six items within the header
|
||||
list
|
||||
The values within the list
|
||||
|
||||
"""
|
||||
# determine how many items are in list
|
||||
items = get_cont_record(file_obj)
|
||||
NPL = items[4]
|
||||
|
||||
# read items
|
||||
b = []
|
||||
for i in range((NPL - 1)//6 + 1):
|
||||
line = file_obj.readline()
|
||||
n = min(6, NPL - 6*i)
|
||||
for j in range(n):
|
||||
b.append(float_endf(line[11*j:11*(j + 1)]))
|
||||
|
||||
return (items, b)
|
||||
|
||||
|
||||
def get_tab1_record(file_obj):
|
||||
"""Return data from a TAB1 record in an ENDF-6 file.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
file_obj : file-like object
|
||||
ENDF-6 file to read from
|
||||
|
||||
Returns
|
||||
-------
|
||||
list
|
||||
The six items within the header
|
||||
openmc.data.Tabulated1D
|
||||
The tabulated function
|
||||
|
||||
"""
|
||||
# Determine how many interpolation regions and total points there are
|
||||
line = file_obj.readline()
|
||||
C1 = float_endf(line[:11])
|
||||
C2 = float_endf(line[11:22])
|
||||
L1 = int_endf(line[22:33])
|
||||
L2 = int_endf(line[33:44])
|
||||
n_regions = int_endf(line[44:55])
|
||||
n_pairs = int_endf(line[55:66])
|
||||
params = [C1, C2, L1, L2]
|
||||
|
||||
# Read the interpolation region data, namely NBT and INT
|
||||
breakpoints = np.zeros(n_regions, dtype=int)
|
||||
interpolation = np.zeros(n_regions, dtype=int)
|
||||
m = 0
|
||||
for i in range((n_regions - 1)//3 + 1):
|
||||
line = file_obj.readline()
|
||||
to_read = min(3, n_regions - m)
|
||||
for j in range(to_read):
|
||||
breakpoints[m] = int_endf(line[0:11])
|
||||
interpolation[m] = int_endf(line[11:22])
|
||||
line = line[22:]
|
||||
m += 1
|
||||
|
||||
# Read tabulated pairs x(n) and y(n)
|
||||
x = np.zeros(n_pairs)
|
||||
y = np.zeros(n_pairs)
|
||||
m = 0
|
||||
for i in range((n_pairs - 1)//3 + 1):
|
||||
line = file_obj.readline()
|
||||
to_read = min(3, n_pairs - m)
|
||||
for j in range(to_read):
|
||||
x[m] = float_endf(line[:11])
|
||||
y[m] = float_endf(line[11:22])
|
||||
line = line[22:]
|
||||
m += 1
|
||||
|
||||
return params, Tabulated1D(x, y, breakpoints, interpolation)
|
||||
|
||||
|
||||
def get_tab2_record(file_obj):
|
||||
# Determine how many interpolation regions and total points there are
|
||||
params = get_cont_record(file_obj)
|
||||
n_regions = params[4]
|
||||
|
||||
# Read the interpolation region data, namely NBT and INT
|
||||
breakpoints = np.zeros(n_regions, dtype=int)
|
||||
interpolation = np.zeros(n_regions, dtype=int)
|
||||
m = 0
|
||||
for i in range((n_regions - 1)//3 + 1):
|
||||
line = file_obj.readline()
|
||||
to_read = min(3, n_regions - m)
|
||||
for j in range(to_read):
|
||||
breakpoints[m] = int(line[0:11])
|
||||
interpolation[m] = int(line[11:22])
|
||||
line = line[22:]
|
||||
m += 1
|
||||
|
||||
return params, Tabulated2D(breakpoints, interpolation)
|
||||
|
||||
|
||||
def get_intg_record(file_obj):
|
||||
"""
|
||||
Return data from an INTG record in an ENDF-6 file. Used to store the
|
||||
covariance matrix in a compact format.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
file_obj : file-like object
|
||||
ENDF-6 file to read from
|
||||
|
||||
Returns
|
||||
-------
|
||||
numpy.ndarray
|
||||
The correlation matrix described in the INTG record
|
||||
"""
|
||||
# determine how many items are in list and NDIGIT
|
||||
items = get_cont_record(file_obj)
|
||||
ndigit = items[2]
|
||||
npar = items[3] # Number of parameters
|
||||
nlines = items[4] # Lines to read
|
||||
NROW_RULES = {2: 18, 3: 12, 4: 11, 5: 9, 6: 8}
|
||||
nrow = NROW_RULES[ndigit]
|
||||
|
||||
# read lines and build correlation matrix
|
||||
corr = np.identity(npar)
|
||||
for i in range(nlines):
|
||||
line = file_obj.readline()
|
||||
ii = int_endf(line[:5]) - 1 # -1 to account for 0 indexing
|
||||
jj = int_endf(line[5:10]) - 1
|
||||
factor = 10**ndigit
|
||||
for j in range(nrow):
|
||||
if jj+j >= ii:
|
||||
break
|
||||
element = int_endf(line[11+(ndigit+1)*j:11+(ndigit+1)*(j+1)])
|
||||
if element > 0:
|
||||
corr[ii, jj] = (element+0.5)/factor
|
||||
elif element < 0:
|
||||
corr[ii, jj] = (element-0.5)/factor
|
||||
|
||||
# Symmetrize the correlation matrix
|
||||
corr = corr + corr.T - np.diag(corr.diagonal())
|
||||
return corr
|
||||
|
||||
|
||||
def get_evaluations(filename):
|
||||
"""Return a list of all evaluations within an ENDF file.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue