Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding code coverage to FIXSRC code #1742

Merged
merged 2 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions armi/nuclearDataIO/cccc/cccc.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
# limitations under the License.

"""
Defines containers for the reading and writing standard interface files
for reactor physics codes.
Defines containers for the reading and writing standard interface files for reactor physics codes.

.. impl:: Generic tool for reading and writing Committee on Computer Code Coordination (CCCC) format
files for reactor physics codes
Expand Down Expand Up @@ -73,8 +72,8 @@ class that is subclassed for each CCCC file. It is subclassed directly for the C
"""
import io
import itertools
import struct
import os
import struct
from copy import deepcopy
from typing import List

Expand All @@ -84,7 +83,7 @@ class that is subclassed for each CCCC file. It is subclassed directly for the C
from armi.nuclearDataIO import nuclearFileMetadata

IMPLICIT_INT = "IJKLMN"
"""Letters that trigger implicit integer types in old FORTRAN 77 codes"""
"""Letters that trigger implicit integer types in old FORTRAN 77 codes."""


class IORecord:
Expand Down Expand Up @@ -174,7 +173,6 @@ def rwInt(self, val):
The method has a seemingly odd signature, because it is used for both reading and writing.
When writing, the :code:`val` should have value, but when the record is being read,
:code:`val` can be :code:`None` or anything else; it is ignored.

"""
raise NotImplementedError()

Expand All @@ -191,7 +189,6 @@ def rwFloat(self, val):
The method has a seemingly odd signature, because it is used for both reading and writing.
When writing, the :code:`val` should have value, but when the record is being read,
:code:`val` can be :code:`None` or anything else; it is ignored.

"""
raise NotImplementedError()

Expand All @@ -203,7 +200,6 @@ def rwDouble(self, val):
The method has a seemingly odd signature, because it is used for both reading and writing.
When writing, the :code:`val` should have value, but when the record is being read,
:code:`val` can be :code:`None` or anything else; it is ignored.

"""
raise NotImplementedError()

Expand All @@ -215,7 +211,6 @@ def rwString(self, val, length):
The method has a seemingly odd signature, because it is used for both reading and writing.
When writing, the :code:`val` should have value, but when the record is being read,
:code:`val` can be :code:`None` or anything else; it is ignored.

"""
raise NotImplementedError()

Expand Down Expand Up @@ -337,7 +332,6 @@ class BinaryRecordReader(IORecord):
This class reads a single CCCC record in binary format. A CCCC record consists of a leading and
ending integer indicating how many bytes the record is. The data contained within the record may
be integer, float, double, or string.

"""

def open(self):
Expand Down Expand Up @@ -401,7 +395,7 @@ def rwString(self, val, length):


class BinaryRecordWriter(IORecord):
r"""
"""
Reads a single CCCC record in binary format.

Reads binary information sequentially.
Expand Down Expand Up @@ -561,7 +555,9 @@ class Stream:
"""
An abstract CCCC IO stream.

.. warning:: This is more of a stream Parser/Serializer than an actual stream.
Warning
-------
This is more of a stream Parser/Serializer than an actual stream.

Notes
-----
Expand Down Expand Up @@ -668,7 +664,9 @@ class StreamWithDataContainer(Stream):
This is a relatively common pattern so some of the boilerplate
is handled here.

.. warning:: This is more of a stream Parser/Serializer than an actual stream.
Warning
-------
This is more of a stream Parser/Serializer than an actual stream.

Notes
-----
Expand Down
32 changes: 15 additions & 17 deletions armi/nuclearDataIO/cccc/fixsrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,16 @@ def writeBinary(fileName, fixSrcArray):


class FIXSRC(cccc.Stream):
r"""Read or write a binary FIXSRC file from DIF3D fixed source input."""
"""Read or write a binary FIXSRC file from DIF3D fixed source input."""

def __init__(self, fileName, fileMode, fixSrc):
r"""
Initialize a gamma FIXSRC class for reading or writing a binary FIXSRC file for DIF3D gamma fixed source input.
If the intent is to write a gamma FIXSRC file, the variable FIXSRC.fixSrc, which contains to-be-written
core-wide multigroup gamma fixed source data, is constructed from an existing neutron RTFLUX file.
"""
Initialize a gamma FIXSRC class for reading or writing a binary FIXSRC file for DIF3D gamma
fixed source input.

If the intent is to write a gamma FIXSRC file, the variable FIXSRC.fixSrc, which contains
to-be-written core-wide multigroup gamma fixed source data, is constructed from an existing
neutron RTFLUX file.

Parameters
----------
Expand All @@ -57,20 +60,17 @@ def __init__(self, fileName, fileMode, fixSrc):
If 'wb', this class writes a FIXSRC binary file.
If 'rb', this class reads a preexisting FIXSRC binary file.

o : Operator object, optional
If fileMode='wb', an ARMI operator must be specified in order to construct gamma fixed source data
from a neutron RTFLUX file (requires reactor geometry and settings).

fixSrc : numpy array
Core-wide multigroup gamma fixed-source data.
"""
cccc.Stream.__init__(self, fileName, fileMode)

# copied from a sample FIXSRC output from "type 19" DIF3D input
self.label = "FIXSRC "
self.fileId = 1

self.fixSrc = fixSrc
ni, nj, nz, ng = self.fixSrc.shape

ni, nj, nz, ng = self.fixSrc.shape
self.fc = collections.OrderedDict(
[
("itype", 0),
Expand All @@ -90,7 +90,7 @@ def __init__(self, fileName, fileMode, fixSrc):
)

def readWrite(self):
r"""Read or write a binary FIXSRC file for DIF3D fixed source input."""
"""Read or write a binary FIXSRC file for DIF3D fixed source input."""
runLog.info(
"{} gamma fixed source file {}".format(
"Reading" if "r" in self._fileMode else "Writing", self
Expand All @@ -107,19 +107,19 @@ def readWrite(self):
self._rw3DRecord(g, z)

def _rwFileID(self):
r"""Read file identification information."""
"""Read file identification information."""
with self.createRecord() as fileIdRecord:
self.label = fileIdRecord.rwString(self.label, 24)
self.fileId = fileIdRecord.rwInt(self.fileId)

def _rw1DRecord(self):
r"""Read/write parameters from/to the FIXSRC 1D block (file control)."""
"""Read/write parameters from/to the FIXSRC 1D block (file control)."""
with self.createRecord() as record:
for var in self.fc.keys():
self.fc[var] = record.rwInt(self.fc[var])

def _rw3DRecord(self, g, z):
r"""
"""
Read/write fixed source data from 3D block records.

Parameters
Expand All @@ -129,10 +129,8 @@ def _rw3DRecord(self, g, z):

z : int
The DIF3D axial node index.

"""
with self.createRecord() as record:

ni = self.fc["ninti"]
nj = self.fc["nintj"]

Expand Down
41 changes: 41 additions & 0 deletions armi/nuclearDataIO/cccc/tests/test_fixsrc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2024 TerraPower, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Test the reading and writing of the DIF3D FIXSRC file format."""
import numpy as np
import os
import unittest

from armi.nuclearDataIO.cccc import fixsrc
from armi.utils.directoryChangers import TemporaryDirectoryChanger

# ruff: noqa: E501
FIXSRC_ASCII = """0 0 0 0 0 0 0.4008E+10 0.4210E+10 0.4822E+10 0.5154E+10 0.4926E+10 0.4621E+10
0.4246E+10 0.3757E+10 0.3311E+10 0.3479E+10 0.357E+10 0.324E+10 0.2942E+10 0.2903E+10 0.2925E+10 0.2763E+10 0.2414E+10 0.2036E+10
0.1656E+10 0.1477E+10 0.1455E+10 0.1434E+10 0.1297E+10 0.1153E+10 0.101E+10 0.8841E+9 0.7923E+9 0.7266E+9 0.6575E+9 0.589E+9
0.5027E+9 0.4146E+9 0.3474E+9 0.3015E+9 0.2403E+9 0.2356E+9 0.1634E+9 0.1521E+9 0.1258E+9 0.9032E+8 0.6156E+8 0.3983E+8
0.3134E+8 0.303E+8 0.2983E+8 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0"""
FIXSRC_ARRAY = np.array(FIXSRC_ASCII.split(), dtype=np.float32).reshape((3, 3, 2, 4))


class TestFixsrc(unittest.TestCase):
def test_writeReadBinaryLoop(self):
with TemporaryDirectoryChanger() as newDir:
fileName = "fixsrc_writeBinary.bin"
binaryFilePath = os.path.join(newDir.destination, fileName)
fixsrc.writeBinary(binaryFilePath, FIXSRC_ARRAY)

self.assertIn(fileName, os.listdir(newDir.destination))
self.assertGreater(os.path.getsize(binaryFilePath), 0)
Loading