As it stands right now if a simulation calls catalyst_execute
data will be converted even if the extractors run at a frequency greater than one. Even though conduit blueprints are lightweight this could be costly depending on the conversion a simulation may required to do. We could ask from the simulation side to control how often catalyst is called but then the integration becomes more convoluted.
See also related issue paraview/paraview#22358.
Moreover, users of catalyst have expressed the need to alter the behavior of a catalyst script based on information coming from the simulation. For example, near convergence they might need more frequent runs of the extractors of even different kinds of extractors/pipelines. Another use case could be to modify the properties of the filters composing a pipeline dynamically based on values coming from each iteration.
With the current design the above use-cases are either too convoluted or impossible.
To allow for a finer control over the execution of catalyst we could provide an optional field under catalyst/state
of the execute
protocol in the ParaViewBlueprint.
Here is a possible usage as documented by @berkgeveci in paraview/paraview#22358 which I copy here for completeness
from paraview.simple import *
source = TrivialProducer(registrationName='input')
def catalyst_execute(info):
global source
n = info.catalyst_state_conduit_node()
if n['pass'] == 'meta-data':
n['request/arrays/a'] = 1
n['request/arrays/b'] = 1
elif n['pass'] == 'execute':
source.UpdatePipeline()
print(source.GetDataInformation().DataInformation)
catalyst/state/pass
can be populated by the simulation upon runtime.
This is in Python but any of the supported languages could be used.
Some things to note here:
catalyst_execute
gets thestate
conduit node using thecatalyst_state_conduit_node()
call and it reads apass
node from it.- If the
pass
is set to meta-data, it returns meta-data (theTrivialProducer
has no data at this point). This is done by directly manipulating thestate
node - If the
pass
is set to execute, it executes theTrivialProducer
.
def coprocess(time, timeStep, grid, attributes):
# do the actual in situ analysis and visualization.
node = catalyst_conduit.Node()
node['catalyst/state/timestep'] = timeStep
node['catalyst/state/time'] = time
# meta-data pass
node['catalyst/state/pass'] = 'meta-data'
catalyst.execute(node)
# execution pass
arrays_requested = node['catalyst/state/request/arrays']
node['catalyst/state/pass'] = 'execute'
node['catalyst/channels/input/type'] = 'mesh'
mesh = node['catalyst/channels/input/data']
# Populate the mesh. Use the arrays_requested from above
# ...
catalyst.execute(node)
A working merge request of this functionality can be found in paraview/paraview!6614.
What do you think of this feature ? Any concerns or ideas for improving it ?
cc: @Francois_Mazen , @Lucas_Givord @nicolas.vuaille @Andy_Bauer @coreylee @utkarsh.ayachit