diff --git a/Tutorial/gray-scott/README.md b/Tutorial/gray-scott/README.md index 2d8f193..a0aeb3a 100644 --- a/Tutorial/gray-scott/README.md +++ b/Tutorial/gray-scott/README.md @@ -146,3 +146,68 @@ $ mpirun -n 4 build/gray-scott simulation/settings-staging.json : \ -n 1 python3 plot/gsplot.py -i gs.bp ``` + +## In situ batch visualization with ParaView Catalyst + +This requires ADIOS 2.8.0 or later, due to the use of `ParaViewFidesEngine` plugin for ADIOS. +Internally, this plugin uses the ADIOS inline engine to pass data pointers to ParaView's +[Fides](https://fides.readthedocs.io/en/latest/) reader +and uses ParaView [Catalyst](https://catalyst-in-situ.readthedocs.io/en/latest/index.html) +to process a user python script that contains a ParaView pipeline. +Fides is a library that provides a schema for reading ADIOS data into visualization services +such as ParaView. By integrating it with ParaView Catalyst, it is now possible to perform +in situ visualization with ADIOS2-enabled codes without writing adaptors. All that is needed +from the user is a simple JSON file describing the data. + + +`simulation/settings-inline.json` uses the `adios2-inline-plugin.xml` configuration file. +It sets the engine type to `plugin` and provides the `PluginName` and `PluginLibrary` +parameters required when using engine plugins. In addition, you will need to set the +environment variable `ADIOS2_PLUGIN_PATH` to contain the path to the `libADIOSInSituPlugin.so` +shared library built by ParaView. + +In the `catalyst` dir, there is a `gs-fides.json`, which is the data model Fides uses to read the data. +The `gs-pipeline.py` contains the pipeline Catalyst will execute on each step. +These files are passed as parameters to the engine plugin (see parameters `DataModel` and `Script` in +the `adios2-inline-plugin.xml` file). + + +### Build and Run + +This example is built as normal (making sure you are using ADIOS v2.8.0 or later) +and does not have build dependencies on ParaView. + +The changes for this example are not yet in ParaView, but you can use the following instructions +for grabbing the branches necessary to run: + +``` +$ git clone --recursive https://gitlab.kitware.com/caitlin.ross/paraview.git +$ mkdir paraview-build +$ cd paraview +$ git checkout catalyst-fides +$ cd paraview/VTK +$ git remote add caitlin.ross https://gitlab.kitware.com/caitlin.ross/vtk.git +$ git fetch caitlin.ross fides-inline-engine +$ git checkout fides-inline-engine +$ cd ../../paraview-build +``` + +Now we're ready to build: + +``` +$ cmake -GNinja -DPARAVIEW_USE_PYTHON=ON -DPARAVIEW_USE_MPI=ON -DPARAVIEW_ENABLE_FIDES=ON -DADIOS2_DIR=/path/to/adios2.8.0 -DCMAKE_BUILD_TYPE=Release ../paraview +$ ninja +``` + +The lib directory should contain `libADIOSInSituPlugin.so`. +Set the following env variables. +``` +$ export ADIOS2_PLUGIN_PATH=/path/to/paraview-build/lib +$ export CATALYST_IMPLEMENTATION_NAME=paraview +$ export CATALYST_IMPLEMENTATION_PATHS=/path/to/paraview-build/lib/catalyst +``` + +To run: +``` +$ mpirun -n 4 build/gray-scott simulation/settings-inline.json +``` diff --git a/Tutorial/gray-scott/adios2-inline-plugin.xml b/Tutorial/gray-scott/adios2-inline-plugin.xml new file mode 100644 index 0000000..ea2448a --- /dev/null +++ b/Tutorial/gray-scott/adios2-inline-plugin.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Tutorial/gray-scott/catalyst/gs-fides.json b/Tutorial/gray-scott/catalyst/gs-fides.json new file mode 100644 index 0000000..cb0a5e1 --- /dev/null +++ b/Tutorial/gray-scott/catalyst/gs-fides.json @@ -0,0 +1,60 @@ +{ + "VTK-Cartesian-grid": { + "data_sources": [ + { + "name": "source", + "filename_mode": "input" + } + ], + "step_information": { + "data_source": "source", + "variable": "step" + }, + "coordinate_system" : { + "array" : { + "array_type" : "uniform_point_coordinates", + "dimensions" : { + "source" : "variable_dimensions", + "data_source": "source", + "variable" : "U" + }, + "origin" : { + "source" : "array", + "values" : [0.0, 0.0, 0.0] + }, + "spacing" : { + "source" : "array", + "values" : [0.1, 0.1, 0.1] + } + } + }, + "cell_set": { + "cell_set_type" : "structured", + "dimensions" : { + "source" : "variable_dimensions", + "data_source": "source", + "variable" : "U" + } + }, + "fields": [ + { + "name": "U", + "association": "points", + "array" : { + "array_type" : "basic", + "data_source": "source", + "variable" : "U" + } + }, + { + "name": "V", + "association": "points", + "array" : { + "array_type" : "basic", + "data_source": "source", + "variable" : "V" + } + } + ] + } +} diff --git a/Tutorial/gray-scott/catalyst/gs-pipeline.py b/Tutorial/gray-scott/catalyst/gs-pipeline.py new file mode 100644 index 0000000..847f251 --- /dev/null +++ b/Tutorial/gray-scott/catalyst/gs-pipeline.py @@ -0,0 +1,64 @@ +from paraview.simple import * +from paraview import print_info + +# catalyst options +from paraview.catalyst import Options +options = Options() + +# print start marker +print_info("begin '%s'", __name__) + +# directory under which to save all extracts +# generated using Extractors defined in the pipeline +# (optional, but recommended) +options.ExtractsOutputDirectory = '/tmp' +SaveExtractsUsingCatalystOptions(options) + +view = CreateRenderView() +# when using Fides, registrationName is always 'fides' +producer = TrivialProducer(registrationName='fides') +display = Show(producer) +view.ResetCamera() +ColorBy(display, ('POINTS', 'U')) +display.RescaleTransferFunctionToDataRange(True, False) +display.SetScalarBarVisibility(view, True) +transFunc = GetColorTransferFunction('U') +transFunc.RescaleOnVisibilityChange = 1 + +display.SetRepresentationType('Surface') + +clip = Clip(registrationName="clip1", Input=producer) +clip.ClipType = 'Plane' +clip.Scalars = ['POINTS', 'U'] +clip.ClipType.Origin = [1.5, 1.5, 1.5] +clip.ClipType.Normal = [0.0, 1.0, 0.0] +clipDisplay = Show(clip, view, 'UnstructuredGridRepresentation') + +Hide(producer, view) +view.ResetCamera() + +camera = GetActiveCamera() +camera.Azimuth(45) +camera.Elevation(45) + +# the extractor will save the view on each time step +extractor = CreateExtractor('PNG', view, registrationName='PNG1') +extractor.Writer.FileName = 'output-{timestep}.png' +extractor.Writer.ImageResolution = [800, 800] + + +def catalyst_execute(info): + print_info("in '%s::catalyst_execute'", __name__) + global producer + producer.UpdatePipeline() + print("updating pipeline and saving image") + + #print("-----------------------------------") + #print("executing (cycle={}, time={})".format(info.cycle, info.time)) + #print("bounds:", producer.GetDataInformation().GetBounds()) + #print("U-range:", producer.PointData['U'].GetRange(0)) + #print("V-range:", producer.PointData['V'].GetRange(0)) + + +# print end marker +print_info("end '%s'", __name__) diff --git a/Tutorial/gray-scott/simulation/settings-inline.json b/Tutorial/gray-scott/simulation/settings-inline.json new file mode 100644 index 0000000..c33d682 --- /dev/null +++ b/Tutorial/gray-scott/simulation/settings-inline.json @@ -0,0 +1,19 @@ +{ + "L": 64, + "Du": 0.2, + "Dv": 0.1, + "F": 0.02, + "k": 0.048, + "dt": 2.0, + "plotgap": 10, + "steps": 100, + "noise": 0.0000001, + "output": "gs.bp", + "checkpoint": false, + "checkpoint_freq": 10, + "checkpoint_output": "gs_ckpt.bp", + "adios_config": "adios2-inline-plugin.xml", + "adios_span": false, + "adios_memory_selection": false, + "mesh_type": "image" +}