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_executegets thestateconduit node using thecatalyst_state_conduit_node()call and it reads apassnode from it.- If the
passis set to meta-data, it returns meta-data (theTrivialProducerhas no data at this point). This is done by directly manipulating thestatenode - If the
passis 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