Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/keckler/armi into unshape…
Browse files Browse the repository at this point in the history
…dComponent
  • Loading branch information
keckler committed Mar 15, 2022
2 parents 4ba84c7 + a7b26d7 commit 919b79f
Show file tree
Hide file tree
Showing 80 changed files with 3,149 additions and 1,459 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:
run: sudo apt-get -y install pandoc
- name: Install Tox and any other packages
run: pip install tox
- name: Setup Graphviz
uses: ts-graphviz/setup-graphviz@v1
- name: Make HTML Docs
run: tox -e doc
- name: deploy
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# How to contribute

The ARMI framework project strongly encourages developers to help contribute to and build the code.
The ARMI framework project strongly encourages developers to help contribute to the codebase.

The ARMI framework code is open source, and your contributions will become open source.
Although fewer laws apply to open source materials because they are publicly-available, you still
Expand All @@ -13,16 +13,16 @@ There are a lot of things we need help with right off the bat, to get your feet
* Many more type annotations are desired. Type issues cause lots of bugs.
* Fewer Pylint warnings
* Better documentation
* Additional relevance to thermal reactors
* Better test coverage
* Targeted speedups (e.g. informed by a profiler)
* Additional relevance to thermal reactors

Naturally, we encourage other kinds of contributions as well.

## Testing

Any contribution must pass all included unit tests. The tests are built and run with the
pytest system. Please add new tests if you add new functionality. You can generally just run
`pytest` system. Please add new tests if you add new functionality. You can generally just run
`tox` to build the testing environment and execute all the tests and pylint checks.

## Submitting changes
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,6 @@ only use third-party Python libraries that have MIT or BSD licenses.
.. |Build Status| image:: https://github.com/terrapower/armi/actions/workflows/unittests.yaml/badge.svg?branch=master
:target: https://github.com/terrapower/armi/actions/workflows/unittests.yaml

.. |Code Coverage| image:: https://coveralls.io/repos/github/terrapower/armi/badge.svg?branch=master&kill_cache=1
.. |Code Coverage| image:: https://coveralls.io/repos/github/terrapower/armi/badge.svg?branch=master&kill_cache=2
:target: https://coveralls.io/github/terrapower/armi?branch=master

2 changes: 1 addition & 1 deletion armi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def configure(app: Optional[apps.App] = None, permissive=False):
app = app or apps.App()

if _app is not None:
if permissive and type(_app) is type(app):
if permissive and isinstance(app, apps.App):
return
else:
raise RuntimeError(
Expand Down
2 changes: 1 addition & 1 deletion armi/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
import collections

from armi import plugins, pluginManager, meta, settings
from armi.reactor import parameters
from armi.settings import Setting
from armi.settings import fwSettings
from armi.reactor import parameters


class App:
Expand Down
10 changes: 1 addition & 9 deletions armi/bookkeeping/db/database3.py
Original file line number Diff line number Diff line change
Expand Up @@ -1480,15 +1480,7 @@ def getHistoriesByLocation(
)

lLocation = layout.location
# filter for objects that live under the desired ancestor and at a desired
# location
# TODO: There might be a numpy way of doing this faster, were we to treat
# the locations as a numpy array. The elements are tuple of int, tuple of
# float, or sometimes even None, as determined by the pack/unpackLocations
# implementations, so it might not be possible, let alone trivial to do
# this. One approach could be to go back to the locations in their raw
# HDF5 form, then list index into that, along with locationType, and
# re-unpack them. 🤔
# filter for objects that live under the desired ancestor and at a desired location
objectIndicesInLayout = numpy.array(
[
i
Expand Down
127 changes: 0 additions & 127 deletions armi/bookkeeping/historyTracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,133 +279,6 @@ def filterTimeIndices(self, timeIndices, boc=False, moc=False, eoc=False):

return filtered

def getTimeIndices(self, a=None, boc=False, moc=False, eoc=False):
r"""
Generate a list of timestep indices where valid history data exist for the given criteria.
Parameters
----------
a : Assembly, optional
If given, only generate time indices where the assembly `a` is in the core. Default: All assemblies.
boc, moc, eoc : bool, optional
Will return boc/moc/eoc timenodes in every cycle. If any of these are true, allNodes becomes False
Returns
-------
timeIndices : list
A list of integers where history data exists.
Examples
--------
If there are 5 nodes per cycle (burnSteps = 4),
0 1 2 3 4 | 5 6 7 8 9 | 10 11 12 13 14 | ...:
>>> getTimeIndices(moc=True):
[2, 7, 12, ...]
Warning
-------
This is no longer functional, as much of the old history tracking was based on
implementation details of the Database, version 2. We now directly support
history tracking through the Database, version 3. At some point this code should
be removed.
See Also
--------
getTimeSteps : gets time in years where the assembly is in the core
"""
timeIndices = []
coreGrid = self.r.core.spatialGrid
for globalNode in range(
utils.getTimeStepNum(self.r.p.cycle, self.r.p.timeNode, self.cs) + 1
):
if a is None:
timeIndices.append(globalNode)
else:
fBlock = a.getFirstBlock(Flags.FUEL)
if fBlock is None:
blockLocationLabel = None
else:
blockLocationLabel = self._blockLocationAtTimenode(
fBlock, globalNode
)
runLog.info(
"Location label of {} at timestep {} is {}".format(
fBlock, globalNode, blockLocationLabel
)
)
# only add this timestep if it's around for this assembly.
if blockLocationLabel is not None:
# this label doesn't actually properly correspond to the block
# location label determined by _blockLocationAtTimenode.
# blockLocationLabel is supposed to be coming from a previous time
# state in the database.
if a.spatialLocator.grid is coreGrid:
timeIndices.append(globalNode)

return self.filterTimeIndices(timeIndices, boc, moc, eoc)

def getBOCEOCTimeIndices(self, assem=None):
r"""returns a list of time step indices that only include BOC and EOC, no intermediate ones."""
tIndices = self.getTimeIndices(assem) # list of times in years
counter = 0
filtered = []
for tIndex in tIndices:
if counter == 0:
# boc. add it.
filtered.append(tIndex)
counter += 1
elif counter == self.cs["burnSteps"]:
# eoc. add it.
filtered.append(tIndex)
counter = 0
else:
# not boc or eoc. Just increment counter. tick, tick, tick
counter += 1

return filtered

def getAssemParamHistory(self, a, neededParams):
"""Gets the history typically used for the Alchemy Writer
Returns
-------
assemHistory : dict, nested with 3 levels,
e.g. assemHistory[block][time_step][parameter] = value of parameter at time step on block
Raises
------
RuntimeError
When the assembly has no history.
"""
timeSteps = self.getTimeIndices(a)
if not timeSteps:
raise RuntimeError(
"Time steps empty. Cannot get assembly history for {}".format(a)
)

# assemHistory[block][time_step][parameter] = value of parameter at time step on block
assemHistory = OrderedDict([(block, None) for block in a.getBlocks(Flags.FUEL)])
for block in assemHistory:
assemHistory[block] = OrderedDict([(ts, None) for ts in timeSteps])

for ts in assemHistory[block]:
assemHistory[block][ts] = OrderedDict(
[(param, None) for param in neededParams]
)

for param in assemHistory[block][ts]:
val = self.getBlockHistoryVal(block.getName(), param, ts)
assemHistory[block][ts][param] = val
assemHistory[block][ts]["location"] = self.getBlockHistoryVal(
block.getName(), "loc", ts
)

return assemHistory

def writeAssemHistory(self, a, fName=""):
"""Write the assembly history report to a text file."""
fName = fName or self._getAssemHistoryFileName(a)
Expand Down
15 changes: 7 additions & 8 deletions armi/bookkeeping/report/reportingUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@

import armi
from armi import runLog
from armi import utils
from armi.utils import getFileSHA1Hash
from armi.utils import iterables
from armi.utils import units
from armi.utils import textProcessors
from armi.utils import plotting
from armi.utils.mathematics import findClosest
from armi import interfaces
from armi.bookkeeping import report
from armi.reactor.flags import Flags
Expand Down Expand Up @@ -131,7 +132,7 @@ def _listInputFiles(cs):
shaHash = (
"MISSING"
if (not fName or not os.path.exists(fName))
else utils.getFileSHA1Hash(fName, digits=10)
else getFileSHA1Hash(fName, digits=10)
)
inputInfo.append((label, fName, shaHash))

Expand Down Expand Up @@ -382,7 +383,7 @@ def writeCycleSummary(core):
core: armi.reactor.reactors.Core
cs: armi.settings.caseSettings.Settings
"""
## would io be worth considering for this?
# would io be worth considering for this?
cycle = core.r.p.cycle
str_ = []
runLog.important("Cycle {0} Summary:".format(cycle))
Expand Down Expand Up @@ -582,7 +583,7 @@ def summarizePower(core):

# calculate total power
tot = sum(sums.values()) or float("inf")
## NOTE: if tot is 0.0, set to infinity to prevent ZeroDivisionError
# NOTE: if tot is 0.0, set to infinity to prevent ZeroDivisionError

runLog.important("Power summary")
for atype, val in sums.items():
Expand Down Expand Up @@ -649,9 +650,8 @@ def summarizeZones(core, cs):
peakAssem = highPow[peakIndex]

avgPFrac = sum(pFracList) / len(pFracList) # true mean power fraction
_avgAssemPFrac, avgIndex = utils.findClosest(
pFracList, avgPFrac, indx=True
) # the closest-to-average pfrac in the list
# the closest-to-average pfrac in the list
_avgAssemPFrac, avgIndex = findClosest(pFracList, avgPFrac, indx=True)
avgAssem = highPow[avgIndex] # the actual average assembly

# ok, now need counts, and peak and avg. flow and power in high power region.
Expand Down Expand Up @@ -870,7 +870,6 @@ def _setGeneralSimulationData(core, cs, coreDesignTable):
)


## Block Design Report
def makeBlockDesignReport(r):
r"""Summarize the block designs from the loading file
Expand Down
5 changes: 1 addition & 4 deletions armi/bookkeeping/report/tests/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,7 @@ def test_setData(self):
self.assertEqual(filled_instance["banana_3"], ["sundae", "chocolate"])

def test_printReports(self):
"""testing testing
:ref:`REQ86d884bb-6133-4078-8804-5a334c935338`
"""
"""testing printReports method"""
repInt = reportInterface.ReportInterface(None, None)
rep = repInt.printReports()

Expand Down
4 changes: 2 additions & 2 deletions armi/cases/inputModifiers/tests/test_inputModifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import unittest
import os
import io
import yaml
from ruamel import yaml

from armi.utils import directoryChangers
from armi import cases
Expand Down Expand Up @@ -201,7 +201,7 @@ def SuiteNaming(index, _case, _mods):
f"case-suite-testBPBM/000{case_nbr}/armi-000{case_nbr}-blueprints.yaml",
"r",
)
bp_dict = yaml.safe_load(yamlfile)
bp_dict = yaml.load(yamlfile)
yamlfile.close()

self.assertEqual(bp_dict["blocks"]["fuel 1"]["clad"]["od"], 3.14)
Expand Down
16 changes: 13 additions & 3 deletions armi/cases/tests/test_suiteBuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,23 @@
"""
Unit tests for the SuiteBuilder
"""
import os
import unittest
from armi.cases.inputModifiers.inputModifiers import SamplingInputModifier

from armi import cases, settings
from armi.cases.inputModifiers.inputModifiers import SamplingInputModifier
from armi.cases.suiteBuilder import LatinHyperCubeSuiteBuilder


cs = settings.Settings("armi/tests/tutorials/anl-afci-177.yaml")
cs = settings.Settings(
os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"..",
"..",
"tests",
"tutorials",
"anl-afci-177.yaml",
)
)
case = cases.Case(cs)


Expand Down
10 changes: 5 additions & 5 deletions armi/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,18 +156,18 @@ def listCommands(self):

sub = re.compile(r"\s+").sub

## given a string, condense white space into a single space
# given a string, condense white space into a single space
condense = lambda s: sub(" ", s.strip())

commands = self._entryPoints.values()

formatter = "{name:<{width}}{desc}".format
print("\ncommands:")
for cmd in sorted(commands, key=lambda cmd: cmd.name):
## Each command can optionally define a class attribute `description`
## as documentation. If description is not defined (default=None since
## it should inherit from EntryPoint), then the docstring is used.
## If the docstring is also None, then fall back to an empty string.
"""Each command can optionally define a class attribute `description`
as documentation. If description is not defined (default=None since
it should inherit from EntryPoint), then the docstring is used.
If the docstring is also None, then fall back to an empty string."""
desc = condense(cmd.description or cmd.__doc__ or "")
print(wrapper.fill(formatter(width=indent, name=cmd.name, desc=desc)))

Expand Down
Loading

0 comments on commit 919b79f

Please sign in to comment.