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

Serpent Interface Upgrade #2290

Merged
merged 29 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0d84018
serpent modifications
alfoa Jan 11, 2024
0e17293
fixed subdomain statistics
alfoa Feb 19, 2024
466dd41
Updated Serpent Interface to use serpent tools and parse new output f…
alfoa Feb 27, 2024
5ad99b2
fixed error msg
alfoa Feb 27, 2024
2b35e6b
Merge branch 'devel' into alfoa/serpentModifications
alfoa Feb 27, 2024
72a3550
new utility script
alfoa Feb 28, 2024
c22bffe
fixed parser
alfoa Feb 28, 2024
9b7dda6
added documentation
alfoa Feb 28, 2024
7aa3706
updated test
alfoa Feb 28, 2024
f8e30fe
removed bumat
alfoa Feb 28, 2024
7aae099
remove iso file
alfoa Mar 6, 2024
765edc8
new input
alfoa Mar 6, 2024
c55ead7
Merge branch 'devel' into alfoa/serpentModifications
alfoa Mar 6, 2024
44f1d32
Merge branch 'devel' into alfoa/serpentModifications
alfoa Mar 26, 2024
1d96034
added EOL if burn up calc
alfoa Mar 26, 2024
8015339
added eol
alfoa Mar 27, 2024
3bc7b3f
modified reactivity
alfoa Mar 27, 2024
33afc32
added tests
alfoa Mar 27, 2024
23f3159
in utils only python 2 syntax is allowed
alfoa Mar 27, 2024
b24408b
fixed typo
alfoa Mar 27, 2024
80e1659
still some python3 syntax in utils that is not allowed in regression …
alfoa Mar 27, 2024
3c09227
Update ravenframework/CodeInterfaceClasses/SERPENT/utilityForCreating…
alfoa Mar 27, 2024
b2b4d78
Update ravenframework/CodeInterfaceClasses/SERPENT/SerpentInterface.py
alfoa Mar 27, 2024
e9c986d
Apply suggestions from code review
alfoa Mar 27, 2024
2657cfa
removed file of iso list that is not used anymore
alfoa Mar 27, 2024
a4f9151
Merge branch 'alfoa/serpentModifications' of github.com:idaholab/rave…
alfoa Mar 27, 2024
ec32028
Added doc for EOL parameter
alfoa Mar 28, 2024
6190b85
addressed Wang's comments
alfoa Apr 2, 2024
a5b2cd7
add optional to pip
alfoa Apr 3, 2024
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
295 changes: 190 additions & 105 deletions doc/user_manual/code_interfaces/serpent.tex

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion doc/user_manual/raven_user_manual.tex
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@
\\Alp Tezbasaran (new external code interface)
\\Anthoney A. Griffith (Bayesian optimization)
\\Jacob A. Bryan (TSA module)
\\Haoyu Wang (DMD amd DMDc)
\\Haoyu Wang (DMDc)
\\Khang Nguyen (new external code interface)
}

Expand Down
85 changes: 40 additions & 45 deletions ravenframework/CodeInterfaceClasses/SERPENT/SerpentInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,38 @@
"""
#External Modules--------------------begin
import os
import sys
#External Modules--------------------end

#Internal Modules--------------------begin
from ravenframework.utils import utils
from ..Generic.GenericCodeInterface import GenericCode
from . import serpentOutputParser as op
#Internal Modules--------------------end

class SERPENT(GenericCode):
"""
Provides code to interface RAVEN to SERPENT
This class is used as a code interface for SERPENT in RAVEN. It expects
input parameters to be specified by input file, input files be specified by either
command line or in a main input file, and produce a csv output.
It is based on the code interface developed by jbae11 and mostly re-written.
The class has been upgraded since its first version to allow
the usage of the interface for both steadystate and depletion calculations.
The output parsing is performed leveraging the library
serpentTools (https://serpent-tools.readthedocs.io/en/master/index.html)
Multiple output formats are now processable (both for steady state and depletion)
"""
def __init__(self):
"""
Initializes the SERPENT Interface.
@ In, None
@ Out, None
"""
# check if serpentTools is available, install it otherwise
utils.importOrInstall("serpentTools")
# intialize code interface
GenericCode.__init__(self)
self.printTag = 'SERPENT'# Print Tag
self.isotope_list_f = None # isotope list file (if any)
self.isotopes = [] # isotopes to collect
self.traceCutOff = 1.e-7 # cutoff threshold for ignoring isotopes
self.printTag = 'SERPENT' # Print Tag
self._fileTypesToRead = ['ResultsReader'] # container of file types to read
# in case of burnup calc, the interface can compute the time at which FOMs (e.g. keff) crosses
# a target. For example (default), we can compute the time (burnDays) at which absKeff crosses 1.0
self.EOLtarget = {'absKeff':1.0}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kind do not like the naming here, but I do not have a better suggestion here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe eolTarget?

Copy link
Collaborator Author

@alfoa alfoa Apr 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah. EOL is the acronym for "End Of Life". I changed it following your suggestion above.


def _findInputFile(self, inputFiles):
"""
Expand All @@ -67,21 +72,28 @@ def _readMoreXML(self,xmlNode):
@ In, xmlNode, xml.etree.ElementTree.Element, Xml element node
@ Out, None.
"""
isotopeList = xmlNode.find("isotope_list")
eolNodes = xmlNode.findall("EOL")
for eolNode in eolNodes:
if eolNode is not None:
target = eolNode.attrib.get('target')
if target is None:
raise IOError(self.printTag+' ERROR: "target" attribute in <EOL> must be present if <EOL> node is inputted')
alfoa marked this conversation as resolved.
Show resolved Hide resolved
value = float(eolNode.text)
self.EOLtarget[target] = value

if isotopeList is None:
raise IOError(self.printTag+' ERROR: <isotope_list> node not inputted!!')
body = isotopeList.text.strip()
if "," in body:
self.isotopes = [iso.strip() for iso in body.split(",")]
else:
if not body.strip().endswith(".csv"):
raise IOError(self.printTag+' ERROR: <isotope_list> file must be a CSV!!')
self.isotope_list_f = body
cutOff = xmlNode.find("traceCutOff")

if cutOff is not None:
self.traceCutOff = float(cutOff.text)
# by default only the "_res.m" file is read.
# if additional files are required, the user should request them here
addFileTypes = xmlNode.find("additionalFileTypes")
if addFileTypes is not None:
serpentFileTypes = [ft.strip().lower() for ft in addFileTypes.text.split(",")]
if 'ResultsReader' in serpentFileTypes:
# we pop this because it is the default
serpentFileTypes.pop(serpentFileTypes.index('ResultsReader'))
for ft in serpentFileTypes:
if ft not in op.serpentOutputAvailableTypes:
raise IOError(self.printTag+f' ERROR: <Serpent File Type> {ft} not supported! Available types are "'
alfoa marked this conversation as resolved.
Show resolved Hide resolved
f'{", ".join(op.serpentOutputAvailableTypes)}!!')
self._fileTypesToRead += serpentFileTypes

def initialize(self, runInfo, oriInputFiles):
"""
Expand All @@ -90,15 +102,9 @@ def initialize(self, runInfo, oriInputFiles):
@ In, oriInputFiles, list, list of the original input files
@ Out, None
"""
# read the isotopes
if self.isotope_list_f is not None:
self.isotopes = []
if not os.path.isabs(self.isotope_list_f):
self.isotope_list_f = os.path.join(runInfo['WorkingDir'], self.isotope_list_f)
lines = open(self.isotope_list_f,"r").readlines()
for line in lines:
self.isotopes+= [elm.strip() for elm in line.split(",")]
inputFile = self._findInputFile(oriInputFiles)
# check if all the output files will be actually generated by the provided input
op.checkCompatibilityFileTypesAndInputFile(inputFile, self._fileTypesToRead)
# set the extension
self.setInputExtension([inputFile.getExt()])

Expand Down Expand Up @@ -136,19 +142,8 @@ def finalizeCodeOutput(self, command, output, workDir):
@ In, workDir, string, working directory path
@ Out, None
"""
# resfile would be 'input.serpent_res.m'
# this is the file produced by RAVEN
inputRoot = output.replace("_res","")
resfile = os.path.join(workDir, output+".m")
inputFile = os.path.join(workDir,inputRoot)
inbumatfile = os.path.join(workDir, inputRoot+".bumat0")
outbumatfile = os.path.join(workDir, inputRoot+".bumat1")
# parse files into dictionary
keffDict = op.searchKeff(resfile)
# the second argument is the percent cutoff
inBumatDict = op.bumatRead(inbumatfile, self.traceCutOff)
outBumatDict = op.bumatRead(outbumatfile, self.traceCutOff)
outputParser = op.SerpentOutputParser(self._fileTypesToRead, os.path.join(workDir,inputRoot), self.EOLtarget)
results = outputParser.processOutputs()
return results

outputPath = os.path.join(workDir, output+'.csv')
op.makeCsv(outputPath, inBumatDict, outBumatDict,
keffDict, self.isotopes, inputFile)
Loading