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

Arbitrary Custom Input in InputSpec #2332

Merged
merged 4 commits into from
Jun 12, 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
14 changes: 11 additions & 3 deletions ravenframework/utils/InputData.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,13 @@ def __init__(self):
create new instance.
@ Out, None
"""
self.parameterValues = {}
self.subparts = []
self.value = ""
self.parameterValues = {} # attributes of the hierarchal input, attached to nodes, but not nodes themselves
self.subparts = [] # pre-defined nodes that are children of this node
self.value = "" # non-hierarchal value associated with this node
# addtionalInput is a List of raven.utils.TreeStructure.InputNode instances. Unlike subparts, these do not have
# a predefined structure, and will not directly be parsed as part of the spec. Only used when
# strictMode is set to False for this node.
self.additionalInput = []
joshua-cogliati-inl marked this conversation as resolved.
Show resolved Hide resolved

@classmethod
def createClass(cls, name, ordered=False, contentType=None, baseNode=None,
Expand Down Expand Up @@ -464,10 +468,12 @@ def handleError(s):
subs = self.subs
# read in subnodes
subNames = set()
# loop over each of the nodes in the input and find matches in the defined spec
for child in node:
childName = child.tag
subsSet = self._subDict.get(childName,set())
foundSubs = 0
# loop over defined spec subs and see if there's a match for the input node
for sub in subsSet:
if sub._checkCanRead is None:
subInstance = sub()
Expand All @@ -482,6 +488,8 @@ def handleError(s):
elif self.strictMode:
allowed = [s.getName() for s in subs]
handleError(f'Unrecognized input node "{childName}"! Allowed: [{", ".join(allowed)}], tried [{", ".join(subsSet)}]')
else:
self.additionalInput.append(child)
if self.strictMode:
nodeNames = set([child.tag for child in node])
if nodeNames != subNames:
Expand Down
13 changes: 4 additions & 9 deletions tests/cluster_tests/AdaptiveSobol/test_adapt_sobol_parallel.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
<WorkingDir>workdir</WorkingDir>
<Sequence>make,train,print</Sequence>
<batchSize>3</batchSize>
<internalParallel>True</internalParallel>
<expectedTime>00:10:00</expectedTime>
<expectedTime>00:20:00</expectedTime>
<JobName>test_qsub</JobName>
<mode>
mpi
Expand All @@ -14,8 +13,8 @@
</RunInfo>

<Steps>
<MultiRun name="make" pauseAtEnd="False">
<Input class="DataObjects" type="PointSet">dummyIN</Input>
<MultiRun name="make">
<Input class="DataObjects" type="PointSet">placeholder</Input>
<Model class="Models" type="ExternalModel">poly</Model>
<Sampler class="Samplers" type="AdaptiveSobol">sobol</Sampler>
<Output class="DataObjects" type="PointSet">solns</Output>
Expand Down Expand Up @@ -65,7 +64,6 @@
</Samplers>

<Models>
<Dummy name="MyDummy" print="True" subType=""/>
<ExternalModel ModuleToLoad="../multi" name="poly" subType="">
<inputs>x1,x2,x3,x4</inputs>
<outputs>ans,ans2</outputs>
Expand All @@ -80,10 +78,7 @@
</Models>

<DataObjects>
<PointSet name="dummyIN">
<Input>x1,x2,x3,x4</Input>
<Output>OutputPlaceHolder</Output>
</PointSet>
<PointSet name="placeholder"/>
<PointSet name="solns">
<Input>x1,x2,x3,x4</Input>
<Output>ans,ans2</Output>
Expand Down
51 changes: 49 additions & 2 deletions tests/framework/unit_tests/utils/testInputData.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,66 @@
ravenPath = os.path.join(os.path.dirname(__file__), *(['..']*4))
sys.path.append(ravenPath)

from ravenframework.utils import InputData
from ravenframework.utils import InputData, TreeStructure
import xml.etree.ElementTree as ET
print('Testing:', InputData)

results = {'pass':0, 'fail':0}



####################################
# Test InputData creating LaTeX
# Test arbitrary XML spec
#
# Write the spec
ASpec = InputData.parameterInputFactory('A', descr='first')
BSpec = InputData.parameterInputFactory('B', descr='second')
BSpec.setStrictMode(False)
ASpec.addSub(BSpec)
# Write the tree
# <A>
# <B>
# <TheQuestion really='True'>unknown</TheQuestion>
# <TheAnswer>42</TheAnswer>
# </B>
# </A>
ANode = TreeStructure.InputNode('A')
BNode = TreeStructure.InputNode('B')
TQNode = TreeStructure.InputNode('TheQuestion', attrib={'really': 'True'}, text='unknown')
BNode.append(TQNode)
TANode = TreeStructure.InputNode('TheAnswer', text='42')
BNode.append(TANode)
ANode.append(BNode)
# parse and check
A = ASpec()
A.parseNode(ANode)
B = A.findFirst('B')

if B.additionalInput[0].tag == 'TheQuestion' and \
B.additionalInput[0].attrib['really'] == 'True' and\
B.additionalInput[0].text == 'unknown':
results['pass'] += 1
else:
print('InputData Arbitrary Custom XML 0 did not match!')
results['fail'] += 1

if B.additionalInput[1].tag == 'TheAnswer' and \
B.additionalInput[1].text == '42':
results['pass'] += 1
else:
print('InputData Arbitrary Custom XML 1 did not match!')
results['fail'] += 1


####################################
# load libraries for all of RAVEN
from ravenframework.CustomDrivers import DriverUtils
DriverUtils.doSetup()
DriverUtils.setupBuiltins()

####################################
# Test InputData creating LaTeX
#
# test MultiRun Step
from ravenframework import Steps

Expand Down