Catalyst old and new, necessity of MPI

I would like to implement Catalyst support for simulation software which already can export visualization data to VTK files and would like to get oriented in the topic.

  1. As I understand, passing VTK structures is now (since Paraview 3.9) considered legacy approach; is it going to be supported alongside conduit-based communication in the future? It would be much easier for me to get started just passing VTK meshes I already produce, instead of having to learn the new nomenclature and do additional data conversions. What pathway would you recommend?

  2. The code is OpenMP-parallelized, not using MPI. Is it mandatory to use MPI for Catalyst? Would it be enough just to initialize the MPI runtime without actually using it?

  3. I am running on Ubuntu 22.04 (pre-release) currently; for Catalyst (old-style, at least), I will need the paraview-dev package, which pulls in python3-paraview, which conflicts with python3-vtk9, thus indirectly conflicting with libvtk9-dev. Is there some way to ask CMake to look for VTK in Paraview directory?


  1. For now both version of Catalyst are usable with ParaView but the newest is not intended so support VTK meshes directly. Note that a vtkDataObjectToConduit exists (inside ParaView but may be ported to VTK in a near future) to help such conversion.

  2. MPI is not mandatory for Catalyst

  3. For a CMake project using VTK, you can specify the vtk_DIR at config time to point the VTK from ParaView (e.x. <pv-install>/lib/cmake/paraview-<version>/vtk)

Thank you for the reply, that got me oriented. The vtkDataObjectToConduit source is a good inspiration, surprisingly simple; I might switch to generating just the arrays in my code and then build either vtk arrays or conduit objects from them, as needed (exporting to file or sending to Catalyst). I also understand now the pain of linking against ParaView when using old-style Catalyst and will go the way of using the new-style Catalyst.

One more clarification to get me started. I do add_subdirectory on and link my code against catalyst::catalyst. Then in my code I can roughly follow catalyst_example_about.cxx, As I understand, the basic use (simpler than the catalyst_example_about.cxx - I can run simulation, but if I choose so, I can run with piping data to ParaView) would be (please let me know whether I am following the logic correctly):

  1. call catalyst_initialize(...) with an empty node, without specifying any implementation or paths; that finds (with an appropriate LD_LIBRARY_PATH) the no-op implementation ( from the catalyst.git repo, providing an implementation called stub).
  2. If I want to use visualize ParaView for a particular run, then I will specify LD_LIBRARY_PATH=/opt/paraview/lib so that catalyst_initialize finds in the paraview installation. That implementation is also called stub.

How can the code recognize whether it is talking to a functional API or the no-op implementation (both called stub)? And then, is there an equivalent of RequestDataDescription of the legacy Catalyst API, querying whether the Catalyst pipeline is ready for new data?


P.S. in Catalyst for Simulation Developers, the find_package(catalyst VERSION 2.0 REQUIRED) should be find_package(catalyst 2.0 REQUIRED).

First not that the doc advise to use those environment variables instead of LD_LIBRARY_PATH:

  • CATALYST_IMPLEMENTATION_PATHS to specify directories where to look
  • CATALYST_IMPLEMENTATION_NAME to specify the impl name (like stub or paraview, not the full .so name)

If you want to use ParaView, you should use CATALYST_IMPLEMENTATION_NAME=paraview and not stub.

To check the used version, you should:

Indeed, both catalyst and paraview repo can provide the stub implementation, but this is the same :slight_smile:

And thanks for reporting the doc issue!

Thanks for the reply, one more step further :slight_smile:

LD_LIBRARY_PATH was just for (linked against, and not in default lookup paths); then using CATALYST_IMPLEMENTATION_PATHS and CATALYST_IMPLEMENTATION_NAME I can indeed connect to the “paraview” implementation. Good.

Now, please correct me if I am wrong: I need to set catalyst/scripts/script* in the node passed to catalyst_initialize to setup live connection to a listening Paraview instance, as detailed in CatalystPythonScriptV2. Is there some easier way to accomplish that for trivial cases? Or can I pass the python script as string (as opposed to filename) for short pieces I can embed in the c++ code?

Python code can only be passed as a filename, no direct code.

Note that you can setup writers directly from the conduit nodes, without python script. That is done in a pipelines node described in the ParaView Blueprint documentation