diff --git a/.gitignore b/.gitignore index 74472ea17..e64104dbf 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,22 @@ manual/*.idx manual/*.lof manual/*.lot manual/ippl_user_guide.pdf -*~ -*.~ +# ignure vtk dump stuff +data/ +datasets*/ +*.vtk + +# CMake and Build folder +CMakeFiles/ +build* +tags +compile_commands.json + +# temporary folder +.cache/ +.idea/ +*.dat +__pycache__ + +*.~ diff --git a/CMakeLists.txt b/CMakeLists.txt index db615c334..15a0dfe13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ -cmake_minimum_required (VERSION 3.20.3) -project (IPPL CXX) +cmake_minimum_required (VERSION 3.24) +project (IPPL LANGUAGES C CXX) + set (IPPL_VERSION_MAJOR 3) set (IPPL_VERSION_MINOR 0.2) include(FetchContent) @@ -146,12 +147,10 @@ set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeModules") find_package (MPI REQUIRED) include_directories(${MPI_INCLUDE_PATH}) link_directories(${MPI_LIBRARY_PATH}) - - - - +message (STATUS "The C compiler identification is: ${CMAKE_C_COMPILER_ID}") message (STATUS "The C++ compiler identification is: ${CMAKE_CXX_COMPILER_ID}") message (STATUS "The C++ compiler version is: ${CMAKE_CXX_COMPILER_VERSION}") +message (STATUS "The MPI C compiler is: ${MPI_C_COMPILER}") message (STATUS "The MPI C++ compiler is: ${MPI_CXX_COMPILER}") message (STATUS "The underlying C++ compiler is: ${CMAKE_CXX_COMPILER}") @@ -207,6 +206,7 @@ if (ENABLE_FFT) message (STATUS "Found Heffte_DIR: ${Heffte_DIR}") endif () +option (ENABLE_CATALYST "Build example with Catalyst enabled" OFF) option (ENABLE_SOLVERS "Enable IPPL solvers" ON) add_subdirectory (src) @@ -274,7 +274,7 @@ install ( RENAME ${PROJECT_NAME}Config.cmake ) -# vi: set et ts=4 sw=4 sts=4: +# vim: set et ts=4 sw=4 sts=4: # Local Variables: # mode: cmake diff --git a/IN-SITU.md b/IN-SITU.md new file mode 100644 index 000000000..24423cb08 --- /dev/null +++ b/IN-SITU.md @@ -0,0 +1,90 @@ +# In Situ Visualization with Catalyst +If Catalyst is not available as a module on the machine, this is the first to build. +For a more indepth documentation on how to build catalyst check the documentation, here are only minimal steps described. +## Build and Install Catalyst +### Requirements for Catalyst +* MPI + +1. Configuration +```sh +git clone https://gitlab.kitware.com/paraview/catalyst.git +cd catalyst +git checkout v2.0.0-rc4 +cmake -S . \ + -B build \ + -DCMAKE_BUILD_TYPE=RelWithDebInfo \ + -DCATALYST_USE_MPI=ONĀ \ + -DCMAKE_INSTALL_PREFIX=../catalyst_install +``` +2. Build and Test +`-j` flag is for parallel build and parallel test +```sh +cmake --build build -j 4 +cmake --install build +ctest --test-dir build/tests -j 4 +``` +The tests should all pass, however for some of them you need to export the `catalyst_DIR` path. +So inspect the output of the failed ones why they failed! + +## Build IPPL with Catalyst +I would recommend to use the install script from IPPL for building IPPL and then after that setting `ENABLE_CATALYST` to `ON`, this procedure would then be: +```sh +./ippl-build-scripts/999-build-everything -t serial -i +cmake ippl/build_serial +``` +Now in order you need to pass the `Catalyst_Dir` path to the install script. +You can do that in the cli over: +```sh +cmake build_serial\ + -DENABLE_CATALYST=ON \ + -DCATALYST_DIR= +``` +or using the cmake gui over: +```sh +ccmake build_serial +``` + +Now build again and you will have catalyst enabled. + + +## Starting a simulation with Catalyst +An general set for examples can be seen on [https://gitlab.kitware.com/paraview/paraview/-/tree/master/Examples/Catalyst2](https://gitlab.kitware.com/paraview/paraview/-/tree/master/Examples/Catalyst2). +Generally the setup is always similar and starting a simulation is usually as: +```sh +./some-program ./ +``` +Some sample scripts for ippl do lay under the `./test/stream/` directory. +For all scripts the `CATALYST_IMPLEMENTATION_NAME` should be set to `paraview` and `CATALYST_IMPLEMENTATION_PATHS` should be set to the proper library in the ParaView folder. +```sh +export CATALYST_IMPLEMENTATION_PATHS="/ParaView-5.11.1-MPI-Linux-Python3.9-x86_64/lib/catalyst" +export CATALYST_IMPLEMENTATION_NAME="ParaView" +``` + +I assume that you are familiar with the examples and manage to start them with catalyst. + +# Tips and Tricks +## ParaView Live +In order to use the ParaView live feature with an existing Catalyst script the following options need to be set +```python +# Catalyst options +from paraview import catalyst +options = catalyst.Options() +options.GlobalTrigger = 'TimeStep' +options.EnableCatalystLive = 1 +options.CatalystLiveTrigger = 'TimeStep' +``` +After these settings you can start `ParaView -> Catalyst -> Connect`, accept the port and then ParaView is waiting for catalyst to connect. +Now also set the simulation to pause over `ParaView -> Catalyst -> Pause Simulation`, then start the simulation. +Now when it worked out you can see on Pipeline Browser of ParaView a small symbol left from catalyst stuff, this needs to be activated to then access the catalyst data. + +## Creating a new script +Using ParaView Live you can quite easy get the data into the position and angle that you like for the simulation and depending on that you can then create different filter to exporting data. +Some choices do include dumping a csv, creating a vtp or also dumping images. + +General workflow would be: +1. Add `CatalystAdaptor::Initialize()` directly after the MPI/IPPL initialize +2. Add `CatalystAdaptor::Execute.....()` where you want your data to be extracted +3. Add `CatalystAdaptor::Finalize()` directly before the MPI/IPPL finalize +4. Start simulation with matching channel names in live mode +5. Generate extraction / dump script +6. Pass the script as argument to the program executable diff --git a/adios2.xml b/adios2.xml new file mode 100644 index 000000000..06d67f53d --- /dev/null +++ b/adios2.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/alpine/CMakeLists.txt b/alpine/CMakeLists.txt index c045305a8..e44b73c5b 100644 --- a/alpine/CMakeLists.txt +++ b/alpine/CMakeLists.txt @@ -16,7 +16,7 @@ set (IPPL_LIBS ippl ${MPI_CXX_LIBRARIES}) set (COMPILE_FLAGS ${OPAL_CXX_FLAGS}) add_executable (PenningTrap PenningTrap.cpp) -target_link_libraries (PenningTrap ${IPPL_LIBS}) +target_link_libraries (PenningTrap PUBLIC ${IPPL_LIBS}) add_executable (LandauDamping LandauDamping.cpp) target_link_libraries (LandauDamping ${IPPL_LIBS}) diff --git a/alpine/ParticleContainer.hpp b/alpine/ParticleContainer.hpp index a56f2022f..064079293 100644 --- a/alpine/ParticleContainer.hpp +++ b/alpine/ParticleContainer.hpp @@ -6,8 +6,8 @@ // Define the ParticlesContainer class template -class ParticleContainer : public ippl::ParticleBase>{ - using Base = ippl::ParticleBase>; +class ParticleContainer : public ippl::ParticleBase,Kokkos::DefaultExecutionSpace>{ + using Base = ippl::ParticleBase, Kokkos::DefaultExecutionSpace>; public: ippl::ParticleAttrib q; // charge diff --git a/alpine/PenningTrap.cpp b/alpine/PenningTrap.cpp index c53f08423..3f351a10b 100644 --- a/alpine/PenningTrap.cpp +++ b/alpine/PenningTrap.cpp @@ -30,10 +30,7 @@ const char* TestName = "PenningTrap"; #include #include #include -#include -#include #include -#include #include "datatypes.h" @@ -42,9 +39,18 @@ const char* TestName = "PenningTrap"; #include "Manager/PicManager.h" #include "PenningTrapManager.h" +#ifdef ENABLE_CATALYST +#include "Stream/InSitu/CatalystAdaptor.h" +#endif + int main(int argc, char* argv[]) { ippl::initialize(argc, argv); { + +#ifdef ENABLE_CATALYST + CatalystAdaptor::Initialize(argc, argv); +#endif + Inform msg(TestName); Inform msg2all(TestName, INFORM_ALL_NODES); @@ -72,12 +78,19 @@ int main(int argc, char* argv[]) { manager.setTime(0.0); + msg << "Starting iterations ..." << endl; + manager.run(manager.getNt()); msg << "End." << endl; +#ifdef ENABLE_CATALYST + CatalystAdaptor::Finalize(); +#endif + + IpplTimings::stopTimer(mainTimer); IpplTimings::print(); IpplTimings::print(std::string("timing.dat")); diff --git a/alpine/PenningTrapManager.h b/alpine/PenningTrapManager.h index b264c5250..08fe37f99 100644 --- a/alpine/PenningTrapManager.h +++ b/alpine/PenningTrapManager.h @@ -14,6 +14,11 @@ #include "Random/NormalDistribution.h" #include "Random/Randn.h" +#ifdef ENABLE_CATALYST +#include +#include "Stream/InSitu/CatalystAdaptor.h" +#endif + using view_type = typename ippl::detail::ViewType, 1>::view_type; template @@ -59,7 +64,7 @@ class PenningTrapManager : public AlpineManager { nrMax_m = 2048; // Max grid size in our studies dxFinest_m = length_m[0] / nrMax_m; - this->dt_m = 0.5 * dxFinest_m; // size of timestep + this->dt_m = 0.05;//0.5 * dxFinest_m; // size of timestep this->it_m = 0; this->time_m = 0.0; @@ -279,6 +284,15 @@ class PenningTrapManager : public AlpineManager { // scatter the charge onto the underlying grid this->par2grid(); +#ifdef ENABLE_CATALYST + std::optional node = std::nullopt; + //CatalystAdaptor::Execute_Particle(it, this->time_m, ippl::Comm->rank(), pc, node); + auto *rho = &this->fcontainer_m->getRho(); + CatalystAdaptor::Execute_Field(it, this->time_m, ippl::Comm->rank(), *rho, node); + //auto *E = &this->fcontainer_m->getE(); + //CatalystAdaptor::Execute_Field(it, this->time_m, ippl::Comm->rank(), *E, node); + //CatalystAdaptor::Execute_Field_Particle(it, this->time_m, ippl::Comm->rank(), *E, pc); +#endif // Field solve IpplTimings::startTimer(SolveTimer); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d130045c9..b5fd3eb26 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -64,10 +64,9 @@ add_ippl_sources (Ippl.cpp) add_subdirectory (Communicate) if (ENABLE_FFT) + set (HEFFTE_LIBRARY Heffte) add_subdirectory (FFT) -else() - set (HEFFTE_LIBRARY "") endif() add_subdirectory (Field) add_subdirectory (FieldLayout) @@ -82,6 +81,8 @@ add_subdirectory (Utility) add_subdirectory (Expression) add_subdirectory (Types) add_subdirectory (Partition) +add_subdirectory (Stream) +add_subdirectory (Stream/InSitu) add_subdirectory (Random) if (ENABLE_SOLVERS) @@ -91,6 +92,15 @@ if (ENABLE_SOLVERS) add_subdirectory (LinearSolvers) endif () +if (ENABLE_CATALYST) + find_package(catalyst 2.0 REQUIRED) + message (STATUS "Enable Catalyst") + message (STATUS "Found catalyst_DIR: ${catalyst_DIR}") +endif() + +if (ENABLE_AMR) + add_subdirectory(AmrParticle) +endif () include_directories ( BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ) @@ -103,9 +113,20 @@ string(REPLACE "SERIAL;" "" KokkosAccelerators "${KokkosAccelerators}") if ("${KokkosAccelerators}" MATCHES ".+;.+") set(TimerFences false) endif() + message("Timer fences for this build: ${TimerFences}") -target_compile_definitions(ippl PUBLIC IPPL_ENABLE_TIMER_FENCES=${TimerFences}) -target_link_libraries(ippl PUBLIC Kokkos::kokkos ${HEFFTE_LIBRARY}) + +target_compile_definitions(ippl PUBLIC + $<$:-DENABLE_FFT> + $<$:-DENABLE_CATALYST> + IPPL_ENABLE_TIMER_FENCES=${TimerFences} +) + +target_link_libraries(ippl PUBLIC + Kokkos::kokkos + $<$:Heffte> + $<$:catalyst::catalyst> + ) install (TARGETS ippl DESTINATION lib) install (FILES ${IPPL_BASEDIR_HDRS} DESTINATION include) diff --git a/src/Stream/CMakeLists.txt b/src/Stream/CMakeLists.txt new file mode 100644 index 000000000..cf5c3b671 --- /dev/null +++ b/src/Stream/CMakeLists.txt @@ -0,0 +1,24 @@ +set (_SRCS +) + +set (_HDRS +) + +include_DIRECTORIES ( + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_ippl_sources (${_SRCS}) +add_ippl_headers (${_HDRS}) + +install (FILES ${_HDRS} DESTINATION include/Stream) + + +# vi: set et ts=4 sw=4 sts=4: + +# Local Variables: +# mode: cmake +# cmake-tab-width: 4 +# indent-tabs-mode: nil +# require-final-newline: nil +# End: \ No newline at end of file diff --git a/src/Stream/InSitu/CMakeLists.txt b/src/Stream/InSitu/CMakeLists.txt new file mode 100644 index 000000000..6b3ddbcfc --- /dev/null +++ b/src/Stream/InSitu/CMakeLists.txt @@ -0,0 +1,24 @@ +set (_SRCS +) + +set (_HDRS + CatalystAdaptor.h +) + +include_DIRECTORIES ( + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_ippl_sources (${_SRCS}) +add_ippl_headers (${_HDRS}) + +install (FILES ${_HDRS} DESTINATION include/Stream/InSitu) + +# vi: set et ts=4 sw=4 sts=4: + +# Local Variables: +# mode: cmake +# cmake-tab-width: 4 +# indent-tabs-mode: nil +# require-final-newline: nil +# End: \ No newline at end of file diff --git a/src/Stream/InSitu/CatalystAdaptor.h b/src/Stream/InSitu/CatalystAdaptor.h new file mode 100644 index 000000000..514df25c2 --- /dev/null +++ b/src/Stream/InSitu/CatalystAdaptor.h @@ -0,0 +1,309 @@ +// SPDX-FileCopyrightText: Copyright (c) Kitware Inc. +// SPDX-License-Identifier: BSD-3-Clause +#ifndef CatalystAdaptor_h +#define CatalystAdaptor_h + +#include "Ippl.h" + +#include +#include +#include +#include +#include + +#include "Utility/IpplException.h" + + +namespace CatalystAdaptor { + + using View_vector = + Kokkos::View***, Kokkos::LayoutLeft, Kokkos::HostSpace>; + inline void setData(conduit_cpp::Node& node, const View_vector& view) { + node["electrostatic/association"].set_string("element"); + node["electrostatic/topology"].set_string("mesh"); + node["electrostatic/volume_dependent"].set_string("false"); + + auto length = std::size(view); + + // offset is zero as we start without the ghost cells + // stride is 1 as we have every index of the array + node["electrostatic/values/x"].set_external(&view.data()[0][0], length, 0, 1); + node["electrostatic/values/y"].set_external(&view.data()[0][1], length, 0, 1); + node["electrostatic/values/z"].set_external(&view.data()[0][2], length, 0, 1); + } + + using View_scalar = Kokkos::View; + inline void setData(conduit_cpp::Node& node, const View_scalar& view) { + node["density/association"].set_string("element"); + node["density/topology"].set_string("mesh"); + node["density/volume_dependent"].set_string("false"); + + node["density/values"].set_external(view.data(), view.size()); + } + + inline void callCatalystExecute(const conduit_cpp::Node& node) { + + // TODO: we should add here this IPPL-INFO stuff + //if ( static auto called {false}; !std::exchange(called, true) ) { + // catalyst_conduit_node_print(conduit_cpp::c_node(&node)); + //} + + catalyst_status err = catalyst_execute(conduit_cpp::c_node(&node)); + if (err != catalyst_status_ok) { + std::cerr << "Failed to execute Catalyst: " << err << std::endl; + } + } + + void Initialize(int argc, char* argv[]) { + conduit_cpp::Node node; + for (int cc = 1; cc < argc; ++cc) { + node["catalyst/scripts/script" + std::to_string(cc - 1)].set_string(argv[cc]); + } + try { + node["catalyst_load/implementation"] = getenv("CATALYST_IMPLEMENTATION_NAME"); + node["catalyst_load/search_paths/paraview"] = getenv("CATALYST_IMPLEMENTATION_PATHS"); + } catch (...) { + throw IpplException("CatalystAdaptor::Initialize", + "no environmental variable for CATALYST_IMPLEMENTATION_NAME or " + "CATALYST_IMPLEMENTATION_PATHS found"); + } + // TODO: catch catalyst error also with IpplException + catalyst_status err = catalyst_initialize(conduit_cpp::c_node(&node)); + if (err != catalyst_status_ok) { + std::cerr << "Failed to initialize Catalyst: " << err << std::endl; + } + } + + + void Initialize_Adios(int argc, char* argv[]) + { + conduit_cpp::Node node; + for (int cc = 1; cc < argc; ++cc) + { + if (strstr(argv[cc], "xml")) + { + node["adios/config_filepath"].set_string(argv[cc]); + } + else + { + node["catalyst/scripts/script" +std::to_string(cc - 1)].set_string(argv[cc]); + } + } + node["catalyst_load/implementation"] = getenv("CATALYST_IMPLEMENTATION_NAME"); + catalyst_status err = catalyst_initialize(conduit_cpp::c_node(&node)); + if (err != catalyst_status_ok) + { + std::cerr << "Failed to initialize Catalyst: " << err << std::endl; + } + } + + + template + std::optional Execute_Field(int cycle, double time, int rank, Field& field, std::optional& node_in) { + static_assert(Field::dim == 3, "CatalystAdaptor only supports 3D"); + // catalyst blueprint definition + // https://docs.paraview.org/en/latest/Catalyst/blueprints.html + // + // conduit blueprint definition (v.8.3) + // https://llnl-conduit.readthedocs.io/en/latest/blueprint_mesh.html + conduit_cpp::Node node; + if (node_in) + node = node_in.value(); + + auto nGhost = field.getNghost(); + + typename Field::view_type::host_mirror_type host_view = + Kokkos::create_mirror_view_and_copy(Kokkos::HostSpace(), field.getView()); + + Kokkos::View + host_view_layout_left("host_view_layout_left", + field.getLayout().getLocalNDIndex()[0].length(), + field.getLayout().getLocalNDIndex()[1].length(), + field.getLayout().getLocalNDIndex()[2].length()); + + for (size_t i = 0; i < field.getLayout().getLocalNDIndex()[0].length(); ++i) { + for (size_t j = 0; j < field.getLayout().getLocalNDIndex()[1].length(); ++j) { + for (size_t k = 0; k < field.getLayout().getLocalNDIndex()[2].length(); ++k) { + host_view_layout_left(i, j, k) = host_view(i + nGhost, j + nGhost, k + nGhost); + } + } + } + + + // add time/cycle information + auto state = node["catalyst/state"]; + state["cycle"].set(cycle); + state["time"].set(time); + state["domain_id"].set(rank); + + // add catalyst channel named ippl_field, as fields is reserved + auto channel = node["catalyst/channels/ippl_field"]; + channel["type"].set_string("mesh"); + + // in data channel now we adhere to conduits mesh blueprint definition + auto mesh = channel["data"]; + mesh["coordsets/coords/type"].set_string("uniform"); + + // number of points in specific dimension + std::string field_node_dim{"coordsets/coords/dims/i"}; + std::string field_node_origin{"coordsets/coords/origin/x"}; + std::string field_node_spacing{"coordsets/coords/spacing/dx"}; + + for (unsigned int iDim = 0; iDim < field.get_mesh().getGridsize().dim; ++iDim) { + // add dimension + mesh[field_node_dim].set(field.getLayout().getLocalNDIndex()[iDim].length() + 1); + + // add origin + mesh[field_node_origin].set( + field.get_mesh().getOrigin()[iDim] + field.getLayout().getLocalNDIndex()[iDim].first() + * field.get_mesh().getMeshSpacing(iDim)); + + // add spacing + mesh[field_node_spacing].set(field.get_mesh().getMeshSpacing(iDim)); + + // increment last char in string + ++field_node_dim.back(); + ++field_node_origin.back(); + ++field_node_spacing.back(); + } + + // add topology + mesh["topologies/mesh/type"].set_string("uniform"); + mesh["topologies/mesh/coordset"].set_string("coords"); + std::string field_node_origin_topo{"topologies/mesh/origin/x"}; + for (unsigned int iDim = 0; iDim < field.get_mesh().getGridsize().dim; ++iDim) { + // shift origin + mesh[field_node_origin_topo].set(field.get_mesh().getOrigin()[iDim] + + field.getLayout().getLocalNDIndex()[iDim].first() + * field.get_mesh().getMeshSpacing(iDim)); + + // increment last char in string + ++field_node_origin_topo.back(); + } + + // add values and subscribe to data + auto fields = mesh["fields"]; + setData(fields, host_view_layout_left); + + // as we have a local copy of the field, the catalyst_execute needs to be called + // within this scope otherwise the memory location might be already overwritten + if (node_in == std::nullopt) + { + callCatalystExecute(node); + return {}; + } + else + return node; + + } + + template + std::optional Execute_Particle(int cycle, double time, int rank, ParticleContainer& particleContainer, std::optional& node_in) { + assert((particleContainer->ID.getView().data() != nullptr) && "ID view should not be nullptr, might be missing the right execution space"); + + //auto layout_view = particleContainer->R.getView(); + typename ippl::ParticleAttrib>::HostMirror R_host = particleContainer->R.getHostMirror(); + typename ippl::ParticleAttrib>::HostMirror P_host = particleContainer->P.getHostMirror(); + typename ippl::ParticleAttrib::HostMirror q_host = particleContainer->q.getHostMirror(); + typename ippl::ParticleAttrib::HostMirror ID_host = particleContainer->ID.getHostMirror(); + Kokkos::deep_copy(R_host, particleContainer->R.getView()); + Kokkos::deep_copy(P_host, particleContainer->P.getView()); + Kokkos::deep_copy(q_host, particleContainer->q.getView()); + Kokkos::deep_copy(ID_host, particleContainer->ID.getView()); + + // if node is passed in, append data to it + conduit_cpp::Node node; + if (node_in) + node = node_in.value(); + + // add time/cycle information + auto state = node["catalyst/state"]; + state["cycle"].set(cycle); + state["time"].set(time); + state["domain_id"].set(rank); + + // channel for particles + auto channel = node["catalyst/channels/ippl_particle"]; + channel["type"].set_string("mesh"); + + // in data channel now we adhere to conduits mesh blueprint definition + auto mesh = channel["data"]; + mesh["coordsets/coords/type"].set_string("explicit"); + + //mesh["coordsets/coords/values/x"].set_external(&layout_view.data()[0][0], particleContainer->getLocalNum(), 0, sizeof(double)*3); + //mesh["coordsets/coords/values/y"].set_external(&layout_view.data()[0][1], particleContainer->getLocalNum(), 0, sizeof(double)*3); + //mesh["coordsets/coords/values/z"].set_external(&layout_view.data()[0][2], particleContainer->getLocalNum(), 0, sizeof(double)*3); + mesh["coordsets/coords/values/x"].set_external(&R_host.data()[0][0], particleContainer->getLocalNum(), 0, sizeof(double)*3); + mesh["coordsets/coords/values/y"].set_external(&R_host.data()[0][1], particleContainer->getLocalNum(), 0, sizeof(double)*3); + mesh["coordsets/coords/values/z"].set_external(&R_host.data()[0][2], particleContainer->getLocalNum(), 0, sizeof(double)*3); + + mesh["topologies/mesh/type"].set_string("unstructured"); + mesh["topologies/mesh/coordset"].set_string("coords"); + mesh["topologies/mesh/elements/shape"].set_string("point"); + //mesh["topologies/mesh/elements/connectivity"].set_external(particleContainer->ID.getView().data(),particleContainer->getLocalNum()); + mesh["topologies/mesh/elements/connectivity"].set_external(ID_host.data(),particleContainer->getLocalNum()); + + //auto charge_view = particleContainer->getQ().getView(); + + // add values for scalar charge field + auto fields = mesh["fields"]; + fields["charge/association"].set_string("vertex"); + fields["charge/topology"].set_string("mesh"); + fields["charge/volume_dependent"].set_string("false"); + + //fields["charge/values"].set_external(particleContainer->q.getView().data(), particleContainer->getLocalNum()); + fields["charge/values"].set_external(q_host.data(), particleContainer->getLocalNum()); + + // add values for vector velocity field + //auto velocity_view = particleContainer->P.getView(); + fields["velocity/association"].set_string("vertex"); + fields["velocity/topology"].set_string("mesh"); + fields["velocity/volume_dependent"].set_string("false"); + + //fields["velocity/values/x"].set_external(&velocity_view.data()[0][0], particleContainer->getLocalNum(),0 ,sizeof(double)*3); + //fields["velocity/values/y"].set_external(&velocity_view.data()[0][1], particleContainer->getLocalNum(),0 ,sizeof(double)*3); + //fields["velocity/values/z"].set_external(&velocity_view.data()[0][2], particleContainer->getLocalNum(),0 ,sizeof(double)*3); + fields["velocity/values/x"].set_external(&P_host.data()[0][0], particleContainer->getLocalNum(),0 ,sizeof(double)*3); + fields["velocity/values/y"].set_external(&P_host.data()[0][1], particleContainer->getLocalNum(),0 ,sizeof(double)*3); + fields["velocity/values/z"].set_external(&P_host.data()[0][2], particleContainer->getLocalNum(),0 ,sizeof(double)*3); + + fields["position/association"].set_string("vertex"); + fields["position/topology"].set_string("mesh"); + fields["position/volume_dependent"].set_string("false"); + + //fields["position/values/x"].set_external(&layout_view.data()[0][0], particleContainer->getLocalNum(), 0, sizeof(double)*3); + //fields["position/values/y"].set_external(&layout_view.data()[0][1], particleContainer->getLocalNum(), 0, sizeof(double)*3); + //fields["position/values/z"].set_external(&layout_view.data()[0][2], particleContainer->getLocalNum(), 0, sizeof(double)*3); + fields["position/values/x"].set_external(&R_host.data()[0][0], particleContainer->getLocalNum(), 0, sizeof(double)*3); + fields["position/values/y"].set_external(&R_host.data()[0][1], particleContainer->getLocalNum(), 0, sizeof(double)*3); + fields["position/values/z"].set_external(&R_host.data()[0][2], particleContainer->getLocalNum(), 0, sizeof(double)*3); + + // this node we can return as the pointer to velocity and charge is globally valid + if (node_in == std::nullopt) + { + callCatalystExecute(node); + return {}; + } + else + return node; + } + + + template + void Execute_Field_Particle(int cycle, double time, int rank, Field& field, ParticleContainer& particle) { + + auto node = std::make_optional(); + node = CatalystAdaptor::Execute_Particle(cycle, time, rank, particle, node); + CatalystAdaptor::Execute_Field(cycle, time, rank, field, node); + } + + void Finalize() { + conduit_cpp::Node node; + catalyst_status err = catalyst_finalize(conduit_cpp::c_node(&node)); + if (err != catalyst_status_ok) { + std::cerr << "Failed to finalize Catalyst: " << err << std::endl; + } + } +} // namespace CatalystAdaptor + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0c837b9f2..1f784cc0c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -28,6 +28,10 @@ add_subdirectory (region) add_subdirectory (random) add_subdirectory (serialization) +if (ENABLE_CATALYST) + add_subdirectory (stream) +endif () + # vi: set et ts=4 sw=4 sts=4: # Local Variables: diff --git a/test/stream/CMakeLists.txt b/test/stream/CMakeLists.txt new file mode 100644 index 000000000..7248e5f5f --- /dev/null +++ b/test/stream/CMakeLists.txt @@ -0,0 +1,30 @@ +file (RELATIVE_PATH _relPath "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") +message (STATUS "Adding index test found in ${_relPath}") + +include_directories ( + ${CMAKE_SOURCE_DIR}/src +) + +link_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} + ${Kokkos_DIR}/.. +) + +set (IPPL_LIBS ippl) +set (COMPILE_FLAGS ${OPAL_CXX_FLAGS}) + +add_executable (TestCatalystAdaptor TestCatalystAdaptor.cpp) +target_link_libraries ( + TestCatalystAdaptor + ${IPPL_LIBS} + ${MPI_CXX_LIBRARIES} +) + +# vi: set et ts=4 sw=4 sts=4: + +# Local Variables: +# mode: cmake +# cmake-tab-width: 4 +# indent-tabs-mode: nil +# require-final-newline: nil +# End: diff --git a/test/stream/TestCatalystAdaptor.cpp b/test/stream/TestCatalystAdaptor.cpp new file mode 100644 index 000000000..6641253c1 --- /dev/null +++ b/test/stream/TestCatalystAdaptor.cpp @@ -0,0 +1,111 @@ +// Tests the application for the Catalyst In-Situ Adaptor +// following environment variables do need to be set +// +// export CATALYST_IMPLEMENTATION_PATHS=/lib/catalyst +// export CATALYST_IMPLEMENTATION_NAME=paraview +// +// on juwels these both are direclty set! +// +// RUN +// ./TestCatalystAdaptor ./.py +// +// for dumping vtk files +// ./build/test/stream/TestCatalystAdaptor ./test/stream/catalyst_pipeline.py --info 5 +// + +#include "Ippl.h" + +#include +//#include + +#include "Stream/InSitu/CatalystAdaptor.h" + + +int main(int argc, char* argv[]) { + ippl::initialize(argc, argv); + { + constexpr unsigned int dim {3}; + + CatalystAdaptor::Initialize_Adios(argc, argv); + + const int pt{2}; + ippl::Index Ix(pt); + ippl::Index Iy{pt}; + ippl::Index Iz{pt}; + ippl::NDIndex owned(Ix, Iy, Iz); + + std::array isParallel{true}; // Specifies SERIAL, PARALLEL dims + + ippl::FieldLayout layout(MPI_COMM_WORLD, owned, isParallel); + + constexpr double dx = {1.0 / double(pt)}; + constexpr double dy = {1.0 / double(pt)}; + constexpr double dz = {1.0 / double(pt)}; + ippl::Vector hx = {dx, dy, dz}; + ippl::Vector origin = {0, 0, 0}; + + using Mesh_t = ippl::UniformCartesian; + using Centering_t = Mesh_t::DefaultCentering; + using field_type = ippl::Field; + + Mesh_t mesh(owned, hx, origin); + + std::cout << layout << std::endl; + + field_type field(mesh, layout); + + field = 1.0; + + const ippl::NDIndex& lDom = layout.getLocalNDIndex(); + const int nghost = field.getNghost(); + using mdrange_type = Kokkos::MDRangePolicy>; + const typename field_type::view_type& view = field.getView(); + + double time = {0.0}; + const double dt = {1}; + const unsigned int nt = {10}; + for (unsigned int it = 0; it < nt; ++it) { + Kokkos::parallel_for( + "Assign field", + mdrange_type( + {nghost, nghost, nghost}, + {view.extent(0) - nghost, view.extent(1) - nghost, view.extent(2) - nghost}), + KOKKOS_LAMBDA(const int i, const int j, const int k) { + // local to global index conversion + // const size_t ig = i + lDom[0].first() - nghost; + const size_t jg = j + lDom[1].first() - nghost; + double y = (jg + 0.5) * hx[1] + origin[1]; + view(i, j, k) = y * time; + }); + + // call catalyst execute with 5th argument as nullopt or not specified + + std::optional node = std::nullopt; + CatalystAdaptor::Execute_Field(it, time, ippl::Comm->rank(), field, node); + // print should be same as field data + time += dt; + + // dumpVTK only works with --info 5 and higher + // dumpVTK(field, field.get_mesh().getGridsize(0), field.get_mesh().getGridsize(1), + // field.get_mesh().getGridsize(2), it, field.get_mesh().getMeshSpacing(0), + // field.get_mesh().getMeshSpacing(1), field.get_mesh().getMeshSpacing(2)); + } + + int nRanks = ippl::Comm->size(); + for (int rank = 0; rank < nRanks; ++rank) { + if (rank == ippl::Comm->rank()) { + std::stringstream fname; + fname << "field_AllBC_"; + fname << ippl::Comm->rank(); + fname << ".dat"; + //std::string fname = std::format("field_AllBC_{}.dat", std::to_string(rank)); + Inform out("Output", fname.str().c_str(), Inform::OVERWRITE, rank); + field.write(out); + } + ippl::Comm->barrier(); + } + } + CatalystAdaptor::Finalize(); + ippl::finalize(); + return 0; +} diff --git a/test/stream/catalyst2_pipeline.py b/test/stream/catalyst2_pipeline.py new file mode 100644 index 000000000..ba378c355 --- /dev/null +++ b/test/stream/catalyst2_pipeline.py @@ -0,0 +1,206 @@ +# script-version: 2.0 +# Catalyst state generated using paraview version 5.11.1 + +#### import the simple module from the paraview +from paraview.simple import * +#### disable automatic camera reset on 'Show' +paraview.simple._DisableFirstRenderCameraReset() + +# ---------------------------------------------------------------- +# setup views used in the visualization +# ---------------------------------------------------------------- + +# get the material library +materialLibrary1 = GetMaterialLibrary() + +# Create a new 'Render View' +renderView3 = CreateView('RenderView') +renderView3.ViewSize = [936, 893] +renderView3.AxesGrid = 'GridAxes3DActor' +renderView3.CenterOfRotation = [0.5, 0.5, 0.5] +renderView3.StereoType = 'Crystal Eyes' +renderView3.CameraPosition = [5.357750529134775, 4.872085250907219, 5.280823925206746] +renderView3.CameraFocalPoint = [0.5, 0.5, 0.5] +renderView3.CameraViewUp = [-0.11343363691620603, 0.7878938103825996, -0.6052736187681985] +renderView3.CameraFocalDisk = 1.0 +renderView3.CameraParallelScale = 1.7320508075688772 +renderView3.BackEnd = 'OSPRay raycaster' +renderView3.OSPRayMaterialLibrary = materialLibrary1 + +SetActiveView(None) + +# ---------------------------------------------------------------- +# setup view layouts +# ---------------------------------------------------------------- + +# create new layout object 'Layout #1' +layout1 = CreateLayout(name='Layout #1') +layout1.SplitHorizontal(0, 0.500000) +layout1.AssignView(2, renderView3) +layout1.SetSize(1873, 893) + +# ---------------------------------------------------------------- +# restore active view +SetActiveView(renderView3) +# ---------------------------------------------------------------- + +# ---------------------------------------------------------------- +# setup the data processing pipelines +# ---------------------------------------------------------------- + +# create a new 'PVTrivialProducer' +# extractippl_field = PVTrivialProducer(registrationName='Extract: ippl_field') +extractippl_field = PVTrivialProducer(registrationName='ippl_field') + +# create a new 'Clip' +clip1 = Clip(registrationName='Clip1', Input=extractippl_field) +clip1.ClipType = 'Plane' +clip1.HyperTreeGridClipper = 'Plane' +clip1.Scalars = ['CELLS', 'density'] +clip1.Value = 0.5 + +# init the 'Plane' selected for 'ClipType' +clip1.ClipType.Origin = [0.5, 0.5, 0.5] + +# init the 'Plane' selected for 'HyperTreeGridClipper' +clip1.HyperTreeGridClipper.Origin = [0.5, 0.5, 0.5] + +# ---------------------------------------------------------------- +# setup the visualization in view 'renderView3' +# ---------------------------------------------------------------- + +# show data from extractippl_field +extractippl_fieldDisplay = Show(extractippl_field, renderView3, 'UniformGridRepresentation') + +# get 2D transfer function for 'density' +densityTF2D = GetTransferFunction2D('density') +densityTF2D.ScalarRangeInitialized = 1 + +# get color transfer function/color map for 'density' +densityLUT = GetColorTransferFunction('density') +densityLUT.TransferFunction2D = densityTF2D +densityLUT.ScalarRangeInitialized = 1.0 + +# get opacity transfer function/opacity map for 'density' +densityPWF = GetOpacityTransferFunction('density') +densityPWF.ScalarRangeInitialized = 1 + +# trace defaults for the display properties. +extractippl_fieldDisplay.Representation = 'Outline' +extractippl_fieldDisplay.ColorArrayName = ['CELLS', 'density'] +extractippl_fieldDisplay.LookupTable = densityLUT +extractippl_fieldDisplay.SelectTCoordArray = 'None' +extractippl_fieldDisplay.SelectNormalArray = 'None' +extractippl_fieldDisplay.SelectTangentArray = 'None' +extractippl_fieldDisplay.OSPRayScaleFunction = 'PiecewiseFunction' +extractippl_fieldDisplay.SelectOrientationVectors = 'None' +extractippl_fieldDisplay.ScaleFactor = 0.2 +extractippl_fieldDisplay.SelectScaleArray = 'None' +extractippl_fieldDisplay.GlyphType = 'Arrow' +extractippl_fieldDisplay.GlyphTableIndexArray = 'None' +extractippl_fieldDisplay.GaussianRadius = 0.01 +extractippl_fieldDisplay.SetScaleArray = [None, ''] +extractippl_fieldDisplay.ScaleTransferFunction = 'PiecewiseFunction' +extractippl_fieldDisplay.OpacityArray = [None, ''] +extractippl_fieldDisplay.OpacityTransferFunction = 'PiecewiseFunction' +extractippl_fieldDisplay.DataAxesGrid = 'GridAxesRepresentation' +extractippl_fieldDisplay.PolarAxes = 'PolarAxesRepresentation' +extractippl_fieldDisplay.ScalarOpacityUnitDistance = 0.8660254037844386 +extractippl_fieldDisplay.ScalarOpacityFunction = densityPWF +extractippl_fieldDisplay.TransferFunction2D = densityTF2D +extractippl_fieldDisplay.OpacityArrayName = ['CELLS', 'density'] +extractippl_fieldDisplay.ColorArray2Name = ['CELLS', 'density'] +extractippl_fieldDisplay.SliceFunction = 'Plane' +extractippl_fieldDisplay.Slice = 2 +extractippl_fieldDisplay.SelectInputVectors = [None, ''] +extractippl_fieldDisplay.WriteLog = '' + +# init the 'Plane' selected for 'SliceFunction' +extractippl_fieldDisplay.SliceFunction.Origin = [0.5, 0.5, 0.5] + +# show data from clip1 +clip1Display = Show(clip1, renderView3, 'UnstructuredGridRepresentation') + +# trace defaults for the display properties. +clip1Display.Representation = 'Surface' +clip1Display.ColorArrayName = ['CELLS', 'density'] +clip1Display.LookupTable = densityLUT +clip1Display.SelectTCoordArray = 'None' +clip1Display.SelectNormalArray = 'None' +clip1Display.SelectTangentArray = 'None' +clip1Display.OSPRayScaleFunction = 'PiecewiseFunction' +clip1Display.SelectOrientationVectors = 'None' +clip1Display.ScaleFactor = 0.2 +clip1Display.SelectScaleArray = 'None' +clip1Display.GlyphType = 'Arrow' +clip1Display.GlyphTableIndexArray = 'None' +clip1Display.GaussianRadius = 0.01 +clip1Display.SetScaleArray = [None, ''] +clip1Display.ScaleTransferFunction = 'PiecewiseFunction' +clip1Display.OpacityArray = [None, ''] +clip1Display.OpacityTransferFunction = 'PiecewiseFunction' +clip1Display.DataAxesGrid = 'GridAxesRepresentation' +clip1Display.PolarAxes = 'PolarAxesRepresentation' +clip1Display.ScalarOpacityFunction = densityPWF +clip1Display.ScalarOpacityUnitDistance = 0.9449407874211548 +clip1Display.OpacityArrayName = ['CELLS', 'density'] +clip1Display.SelectInputVectors = [None, ''] +clip1Display.WriteLog = '' + +# setup the color legend parameters for each legend in this view + +# get color legend/bar for densityLUT in view renderView3 +densityLUTColorBar = GetScalarBar(densityLUT, renderView3) +densityLUTColorBar.WindowLocation = 'Any Location' +densityLUTColorBar.Position = [0.8376068376068376, 0.027995520716685318] +densityLUTColorBar.Title = 'density' +densityLUTColorBar.ComponentTitle = '' +densityLUTColorBar.ScalarBarLength = 0.32999999999999996 + +# set color bar visibility +densityLUTColorBar.Visibility = 1 + +# show color legend +extractippl_fieldDisplay.SetScalarBarVisibility(renderView3, True) + +# show color legend +clip1Display.SetScalarBarVisibility(renderView3, True) + +# ---------------------------------------------------------------- +# setup color maps and opacity mapes used in the visualization +# note: the Get..() functions create a new object, if needed +# ---------------------------------------------------------------- + +# ---------------------------------------------------------------- +# setup extractors +# ---------------------------------------------------------------- + +# create extractor +pNG1 = CreateExtractor('PNG', renderView3, registrationName='PNG1') +# trace defaults for the extractor. +pNG1.Trigger = 'TimeStep' + +# init the 'PNG' selected for 'Writer' +pNG1.Writer.FileName = 'RenderView3_{timestep:06d}{camera}.png' +pNG1.Writer.ImageResolution = [936, 893] +pNG1.Writer.Format = 'PNG' + +# ---------------------------------------------------------------- +# restore active source +SetActiveSource(pNG1) +# ---------------------------------------------------------------- + +# ------------------------------------------------------------------------------ +# Catalyst options +from paraview import catalyst +options = catalyst.Options() +options.GlobalTrigger = 'TimeStep' +options.EnableCatalystLive = 1 +options.CatalystLiveTrigger = 'TimeStep' + +# ------------------------------------------------------------------------------ +if __name__ == '__main__': + from paraview.simple import SaveExtractsUsingCatalystOptions + # Code for non in-situ environments; if executing in post-processing + # i.e. non-Catalyst mode, let's generate extracts using Catalyst options + SaveExtractsUsingCatalystOptions(options) diff --git a/test/stream/catalyst_pipeline.py b/test/stream/catalyst_pipeline.py new file mode 100644 index 000000000..43e1d3cb8 --- /dev/null +++ b/test/stream/catalyst_pipeline.py @@ -0,0 +1,24 @@ +from paraview.simple import * +from paraview import catalyst +options = catalyst.Options() + +print("executing catalyst_pipeline") + + +# registrationName must match the channel name used in the +# 'CatalystAdaptor'. +producer = TrivialProducer(registrationName="ippl_field") +def catalyst_execute(info): + global producer + #SaveExtractsUsingCatalystOptions(options) +# global producer + producer.UpdatePipeline(info.time) +# print("-----------------------------------") + print("executing (cycle={}, time={})".format(info.cycle, info.time)) + arrayInfo = producer.CellData["density"] + arrayInfo.GetNumberOfComponents() + print("field:", producer.CellData["density"].GetRange(-1)) # .GetRange(0)) + arrayInfo = producer.CellData["electrostatic"] + arrayInfo.GetNumberOfComponents() + print("field:", producer.CellData["electrostatic"].GetRange(-1)) # .GetRange(0)) +# print("pressure-range:", producer.CellData["pressure"].GetRange(0)) diff --git a/test/stream/dump_density_field.py b/test/stream/dump_density_field.py new file mode 100644 index 000000000..94bb74553 --- /dev/null +++ b/test/stream/dump_density_field.py @@ -0,0 +1,224 @@ +# script-version: 2.0 +# Catalyst state generated using paraview version 5.11.1 + +#### import the simple module from the paraview +from paraview.simple import * +#### disable automatic camera reset on 'Show' +paraview.simple._DisableFirstRenderCameraReset() + +# ---------------------------------------------------------------- +# setup views used in the visualization +# ---------------------------------------------------------------- + +# get the material library +materialLibrary1 = GetMaterialLibrary() + +# Create a new 'Render View' +renderView1 = CreateView('RenderView') +renderView1.ViewSize = [795, 749] +renderView1.AxesGrid = 'GridAxes3DActor' +renderView1.CenterOfRotation = [10.0, 10.0, 10.0] +renderView1.HiddenLineRemoval = 1 +renderView1.StereoType = 'Crystal Eyes' +renderView1.CameraPosition = [48.63703305156274, 48.63703305156273, 48.637033051562746] +renderView1.CameraFocalPoint = [10.0, 10.0, 10.0] +renderView1.CameraViewUp = [-0.4082482904638631, 0.816496580927726, -0.40824829046386296] +renderView1.CameraFocalDisk = 1.0 +renderView1.CameraParallelScale = 17.320508075688775 +renderView1.BackEnd = 'OSPRay raycaster' +renderView1.OSPRayMaterialLibrary = materialLibrary1 + +SetActiveView(None) + +# ---------------------------------------------------------------- +# setup view layouts +# ---------------------------------------------------------------- + +# create new layout object 'Layout #1' +layout1 = CreateLayout(name='Layout #1') +layout1.AssignView(0, renderView1) +layout1.SetSize(795, 749) + +# ---------------------------------------------------------------- +# restore active view +SetActiveView(renderView1) +# ---------------------------------------------------------------- + +# ---------------------------------------------------------------- +# setup the data processing pipelines +# ---------------------------------------------------------------- + +# create a new 'XML Partitioned Dataset Reader' +ippl_field = PVTrivialProducer(registrationName='ippl_field') + +# create a new 'Ghost Cells Generator' +ghostCellsGenerator1 = GhostCellsGenerator(registrationName='GhostCellsGenerator1', Input=ippl_field) + +# create a new 'Contour' +contour1 = Contour(registrationName='Contour1', Input=ghostCellsGenerator1) +contour1.ContourBy = ['POINTS', 'density'] +contour1.Isosurfaces = [0.0, -9.560476096448486, -9.057293144003829, -8.554110191559172, -8.050927239114515, -7.547744286669857, -7.0445613342252, -6.541378381780543, -6.038195429335886, -5.535012476891229, -5.031829524446572, -4.5286465720019144, -4.025463619557257, -3.5222806671126, -3.019097714667943, -2.515914762223286, -2.0127318097786286, -1.5095488573339715, -1.0063659048893143, -0.5031829524446572, 0.0] +contour1.PointMergeMethod = 'Uniform Binning' + +# create a new 'Clip' +clip1 = Clip(registrationName='Clip1', Input=contour1) +clip1.ClipType = 'Plane' +clip1.HyperTreeGridClipper = 'Plane' +clip1.Scalars = ['POINTS', 'density'] +clip1.Value = -3.773872137069702 + +# init the 'Plane' selected for 'ClipType' +clip1.ClipType.Origin = [10.619441449642181, 10.038045406341553, 10.0] +clip1.ClipType.Normal = [0.0, 0.0, 1.0] + +# init the 'Plane' selected for 'HyperTreeGridClipper' +clip1.HyperTreeGridClipper.Origin = [10.619441449642181, 10.038045406341553, 10.0] + +# ---------------------------------------------------------------- +# setup the visualization in view 'renderView1' +# ---------------------------------------------------------------- + +# show data from ippl_field +ippl_fieldDisplay = Show(ippl_field, renderView1, 'UniformGridRepresentation') + +# trace defaults for the display properties. +ippl_fieldDisplay.Representation = 'Outline' +ippl_fieldDisplay.ColorArrayName = [None, ''] +ippl_fieldDisplay.SelectTCoordArray = 'None' +ippl_fieldDisplay.SelectNormalArray = 'None' +ippl_fieldDisplay.SelectTangentArray = 'None' +ippl_fieldDisplay.OSPRayScaleArray = 'density' +ippl_fieldDisplay.OSPRayScaleFunction = 'PiecewiseFunction' +ippl_fieldDisplay.SelectOrientationVectors = 'None' +ippl_fieldDisplay.ScaleFactor = 2.0 +ippl_fieldDisplay.SelectScaleArray = 'None' +ippl_fieldDisplay.GlyphType = 'Arrow' +ippl_fieldDisplay.GlyphTableIndexArray = 'None' +ippl_fieldDisplay.GaussianRadius = 0.1 +ippl_fieldDisplay.SetScaleArray = ['POINTS', 'density'] +ippl_fieldDisplay.ScaleTransferFunction = 'PiecewiseFunction' +ippl_fieldDisplay.OpacityArray = ['POINTS', 'density'] +ippl_fieldDisplay.OpacityTransferFunction = 'PiecewiseFunction' +ippl_fieldDisplay.DataAxesGrid = 'GridAxesRepresentation' +ippl_fieldDisplay.PolarAxes = 'PolarAxesRepresentation' +ippl_fieldDisplay.ScalarOpacityUnitDistance = 1.0825317547305484 +ippl_fieldDisplay.OpacityArrayName = ['CELLS', 'density'] +ippl_fieldDisplay.ColorArray2Name = ['CELLS', 'density'] +ippl_fieldDisplay.SliceFunction = 'Plane' +ippl_fieldDisplay.Slice = 16 +ippl_fieldDisplay.SelectInputVectors = [None, ''] +ippl_fieldDisplay.WriteLog = '' + +# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction' +ippl_fieldDisplay.ScaleTransferFunction.Points = [-9.560476096448486, 0.0, 0.5, 0.0, 0.1953125, 1.0, 0.5, 0.0] + +# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction' +ippl_fieldDisplay.OpacityTransferFunction.Points = [-9.560476096448486, 0.0, 0.5, 0.0, 0.1953125, 1.0, 0.5, 0.0] + +# init the 'Plane' selected for 'SliceFunction' +ippl_fieldDisplay.SliceFunction.Origin = [10.0, 10.0, 10.0] + +# show data from clip1 +clip1Display = Show(clip1, renderView1, 'UnstructuredGridRepresentation') + +# get 2D transfer function for 'density' +densityTF2D = GetTransferFunction2D('density') + +# get color transfer function/color map for 'density' +densityLUT = GetColorTransferFunction('density') +densityLUT.TransferFunction2D = densityTF2D +densityLUT.RGBPoints = [-7.547744274139404, 0.231373, 0.298039, 0.752941, -3.773872137069702, 0.865003, 0.865003, 0.865003, 0.0, 0.705882, 0.0156863, 0.14902] +densityLUT.ScalarRangeInitialized = 1.0 + +# get opacity transfer function/opacity map for 'density' +densityPWF = GetOpacityTransferFunction('density') +densityPWF.Points = [-7.547744274139404, 0.0, 0.5, 0.0, 0.0, 1.0, 0.5, 0.0] +densityPWF.ScalarRangeInitialized = 1 + +# trace defaults for the display properties. +clip1Display.Representation = 'Surface' +clip1Display.ColorArrayName = ['POINTS', 'density'] +clip1Display.LookupTable = densityLUT +clip1Display.SelectTCoordArray = 'None' +clip1Display.SelectNormalArray = 'Normals' +clip1Display.SelectTangentArray = 'None' +clip1Display.OSPRayScaleArray = 'density' +clip1Display.OSPRayScaleFunction = 'PiecewiseFunction' +clip1Display.SelectOrientationVectors = 'None' +clip1Display.ScaleFactor = 1.851871407032013 +clip1Display.SelectScaleArray = 'density' +clip1Display.GlyphType = 'Arrow' +clip1Display.GlyphTableIndexArray = 'density' +clip1Display.GaussianRadius = 0.09259357035160065 +clip1Display.SetScaleArray = ['POINTS', 'density'] +clip1Display.ScaleTransferFunction = 'PiecewiseFunction' +clip1Display.OpacityArray = ['POINTS', 'density'] +clip1Display.OpacityTransferFunction = 'PiecewiseFunction' +clip1Display.DataAxesGrid = 'GridAxesRepresentation' +clip1Display.PolarAxes = 'PolarAxesRepresentation' +clip1Display.ScalarOpacityFunction = densityPWF +clip1Display.ScalarOpacityUnitDistance = 0.9212026380832151 +clip1Display.OpacityArrayName = ['POINTS', 'density'] +clip1Display.SelectInputVectors = ['POINTS', 'Normals'] +clip1Display.WriteLog = '' + +# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction' +clip1Display.ScaleTransferFunction.Points = [-7.547744274139404, 0.0, 0.5, 0.0, 0.0, 1.0, 0.5, 0.0] + +# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction' +clip1Display.OpacityTransferFunction.Points = [-7.547744274139404, 0.0, 0.5, 0.0, 0.0, 1.0, 0.5, 0.0] + +# setup the color legend parameters for each legend in this view + +# get color legend/bar for densityLUT in view renderView1 +densityLUTColorBar = GetScalarBar(densityLUT, renderView1) +densityLUTColorBar.Title = 'density' +densityLUTColorBar.ComponentTitle = '' + +# set color bar visibility +densityLUTColorBar.Visibility = 1 + +# show color legend +clip1Display.SetScalarBarVisibility(renderView1, True) + +# ---------------------------------------------------------------- +# setup color maps and opacity mapes used in the visualization +# note: the Get..() functions create a new object, if needed +# ---------------------------------------------------------------- + +# ---------------------------------------------------------------- +# setup extractors +# ---------------------------------------------------------------- + +# create extractor +pNG1 = CreateExtractor('PNG', renderView1, registrationName='PNG1') +# trace defaults for the extractor. +pNG1.Trigger = 'TimeStep' + +# init the 'PNG' selected for 'Writer' +pNG1.Writer.FileName = 'Density_Field_{timestep:06d}{camera}.png' +pNG1.Writer.ImageResolution = [3840, 2160] +pNG1.Writer.TransparentBackground = 1 +pNG1.Writer.Format = 'PNG' + +# ---------------------------------------------------------------- +# restore active source +SetActiveSource(pNG1) +# ---------------------------------------------------------------- + +# ------------------------------------------------------------------------------ +# Catalyst options +from paraview import catalyst +options = catalyst.Options() +options.ExtractsOutputDirectory = 'datasets_density' +options.GenerateCinemaSpecification = 1 +options.GlobalTrigger = 'TimeStep' +#options.EnableCatalystLive = 1 +#options.CatalystLiveTrigger = 'TimeStep' + +# ------------------------------------------------------------------------------ +if __name__ == '__main__': + from paraview.simple import SaveExtractsUsingCatalystOptions + # Code for non in-situ environments; if executing in post-processing + # i.e. non-Catalyst mode, let's generate extracts using Catalyst options + SaveExtractsUsingCatalystOptions(options) diff --git a/test/stream/dump_electric_field.py b/test/stream/dump_electric_field.py new file mode 100644 index 000000000..4ec2006a8 --- /dev/null +++ b/test/stream/dump_electric_field.py @@ -0,0 +1,207 @@ +# script-version: 2.0 +# Catalyst state generated using paraview version 5.11.1 + +#### import the simple module from the paraview +from paraview.simple import * +#### disable automatic camera reset on 'Show' +paraview.simple._DisableFirstRenderCameraReset() + +# ---------------------------------------------------------------- +# setup views used in the visualization +# ---------------------------------------------------------------- + +# get the material library +materialLibrary1 = GetMaterialLibrary() + +# Create a new 'Render View' +renderView1 = CreateView('RenderView') +renderView1.ViewSize = [637, 749] +renderView1.AxesGrid = 'GridAxes3DActor' +renderView1.CenterOfRotation = [10.0, 10.0, 10.0] +renderView1.HiddenLineRemoval = 1 +renderView1.StereoType = 'Crystal Eyes' +renderView1.CameraPosition = [55.0073453709904, 55.00734537099039, 55.00734537099041] +renderView1.CameraFocalPoint = [10.0, 10.0, 10.0] +renderView1.CameraViewUp = [-0.4082482904638631, 0.816496580927726, -0.40824829046386296] +renderView1.CameraFocalDisk = 1.0 +renderView1.CameraParallelScale = 20.365872132952735 +renderView1.BackEnd = 'OSPRay raycaster' +renderView1.OSPRayMaterialLibrary = materialLibrary1 + +SetActiveView(None) + +# ---------------------------------------------------------------- +# setup view layouts +# ---------------------------------------------------------------- + +# create new layout object 'Layout #1' +layout1 = CreateLayout(name='Layout #1') +layout1.AssignView(0, renderView1) +layout1.SetSize(637, 749) + +# ---------------------------------------------------------------- +# restore active view +SetActiveView(renderView1) +# ---------------------------------------------------------------- + +# ---------------------------------------------------------------- +# setup the data processing pipelines +# ---------------------------------------------------------------- + +# create a new 'PVTrivialProducer' +ippl_field = PVTrivialProducer(registrationName='ippl_field') + +# create a new 'Glyph' +glyph1 = Glyph(registrationName='Glyph1', Input=ippl_field, + GlyphType='Arrow') +glyph1.OrientationArray = ['CELLS', 'electrostatic'] +glyph1.ScaleArray = ['POINTS', 'No scale array'] +glyph1.ScaleFactor = 1.1 +glyph1.GlyphTransform = 'Transform2' + +# ---------------------------------------------------------------- +# setup the visualization in view 'renderView1' +# ---------------------------------------------------------------- + +# show data from ippl_field +ippl_fieldDisplay = Show(ippl_field, renderView1, 'UniformGridRepresentation') + +# get 2D transfer function for 'electrostatic' +electrostaticTF2D = GetTransferFunction2D('electrostatic') +electrostaticTF2D.ScalarRangeInitialized = 1 +electrostaticTF2D.Range = [0.034176988881870436, 5.3579889614424, 0.0, 1.0] + +# get color transfer function/color map for 'electrostatic' +electrostaticLUT = GetColorTransferFunction('electrostatic') +electrostaticLUT.TransferFunction2D = electrostaticTF2D +electrostaticLUT.RGBPoints = [0.034176988881870436, 0.231373, 0.298039, 0.752941, 2.6960829751621356, 0.865003, 0.865003, 0.865003, 5.3579889614424, 0.705882, 0.0156863, 0.14902] +electrostaticLUT.ScalarRangeInitialized = 1.0 + +# get opacity transfer function/opacity map for 'electrostatic' +electrostaticPWF = GetOpacityTransferFunction('electrostatic') +electrostaticPWF.Points = [0.034176988881870436, 0.0, 0.5, 0.0, 5.3579889614424, 1.0, 0.5, 0.0] +electrostaticPWF.ScalarRangeInitialized = 1 + +# trace defaults for the display properties. +ippl_fieldDisplay.Representation = 'Outline' +ippl_fieldDisplay.ColorArrayName = ['CELLS', 'electrostatic'] +ippl_fieldDisplay.LookupTable = electrostaticLUT +ippl_fieldDisplay.SelectTCoordArray = 'None' +ippl_fieldDisplay.SelectNormalArray = 'None' +ippl_fieldDisplay.SelectTangentArray = 'None' +ippl_fieldDisplay.OSPRayScaleArray = 'electrostatic' +ippl_fieldDisplay.OSPRayScaleFunction = 'PiecewiseFunction' +ippl_fieldDisplay.SelectOrientationVectors = 'None' +ippl_fieldDisplay.ScaleFactor = 2.0 +ippl_fieldDisplay.SelectScaleArray = 'None' +ippl_fieldDisplay.GlyphType = 'Arrow' +ippl_fieldDisplay.GlyphTableIndexArray = 'None' +ippl_fieldDisplay.GaussianRadius = 0.1 +ippl_fieldDisplay.SetScaleArray = ['POINTS', 'electrostatic'] +ippl_fieldDisplay.ScaleTransferFunction = 'PiecewiseFunction' +ippl_fieldDisplay.OpacityArray = ['POINTS', 'electrostatic'] +ippl_fieldDisplay.OpacityTransferFunction = 'PiecewiseFunction' +ippl_fieldDisplay.DataAxesGrid = 'GridAxesRepresentation' +ippl_fieldDisplay.PolarAxes = 'PolarAxesRepresentation' +ippl_fieldDisplay.ScalarOpacityUnitDistance = 1.0825317547305484 +ippl_fieldDisplay.ScalarOpacityFunction = electrostaticPWF +ippl_fieldDisplay.TransferFunction2D = electrostaticTF2D +ippl_fieldDisplay.OpacityArrayName = ['CELLS', 'electrostatic'] +ippl_fieldDisplay.ColorArray2Name = ['CELLS', 'electrostatic'] +ippl_fieldDisplay.SliceFunction = 'Plane' +ippl_fieldDisplay.Slice = 16 +ippl_fieldDisplay.SelectInputVectors = ['POINTS', 'electrostatic'] +ippl_fieldDisplay.WriteLog = '' + +# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction' +ippl_fieldDisplay.ScaleTransferFunction.Points = [-3.4982625412984754, 0.0, 0.5, 0.0, 3.5997197159102856, 1.0, 0.5, 0.0] + +# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction' +ippl_fieldDisplay.OpacityTransferFunction.Points = [-3.4982625412984754, 0.0, 0.5, 0.0, 3.5997197159102856, 1.0, 0.5, 0.0] + +# init the 'Plane' selected for 'SliceFunction' +ippl_fieldDisplay.SliceFunction.Origin = [10.0, 10.0, 10.0] + +# show data from glyph1 +glyph1Display = Show(glyph1, renderView1, 'GeometryRepresentation') + +# trace defaults for the display properties. +glyph1Display.Representation = 'Surface' +glyph1Display.ColorArrayName = ['POINTS', 'electrostatic'] +glyph1Display.LookupTable = electrostaticLUT +glyph1Display.SelectTCoordArray = 'None' +glyph1Display.SelectNormalArray = 'None' +glyph1Display.SelectTangentArray = 'None' +glyph1Display.OSPRayScaleFunction = 'PiecewiseFunction' +glyph1Display.SelectOrientationVectors = 'None' +glyph1Display.ScaleFactor = 2.2 +glyph1Display.SelectScaleArray = 'None' +glyph1Display.GlyphType = 'Arrow' +glyph1Display.GlyphTableIndexArray = 'None' +glyph1Display.GaussianRadius = 0.11 +glyph1Display.SetScaleArray = [None, ''] +glyph1Display.ScaleTransferFunction = 'PiecewiseFunction' +glyph1Display.OpacityArray = [None, ''] +glyph1Display.OpacityTransferFunction = 'PiecewiseFunction' +glyph1Display.DataAxesGrid = 'GridAxesRepresentation' +glyph1Display.PolarAxes = 'PolarAxesRepresentation' +glyph1Display.SelectInputVectors = [None, ''] +glyph1Display.WriteLog = '' + +# setup the color legend parameters for each legend in this view + +# get color legend/bar for electrostaticLUT in view renderView1 +electrostaticLUTColorBar = GetScalarBar(electrostaticLUT, renderView1) +electrostaticLUTColorBar.Title = 'electrostatic' +electrostaticLUTColorBar.ComponentTitle = 'Magnitude' + +# set color bar visibility +electrostaticLUTColorBar.Visibility = 1 + +# show color legend +ippl_fieldDisplay.SetScalarBarVisibility(renderView1, True) + +# show color legend +glyph1Display.SetScalarBarVisibility(renderView1, True) + +# ---------------------------------------------------------------- +# setup color maps and opacity mapes used in the visualization +# note: the Get..() functions create a new object, if needed +# ---------------------------------------------------------------- + +# ---------------------------------------------------------------- +# setup extractors +# ---------------------------------------------------------------- + +# create extractor +pNG1 = CreateExtractor('PNG', renderView1, registrationName='PNG1') +# trace defaults for the extractor. +pNG1.Trigger = 'TimeStep' + +# init the 'PNG' selected for 'Writer' +pNG1.Writer.FileName = 'Electric_Field_{timestep:06d}{camera}.png' +pNG1.Writer.ImageResolution = [3840, 2160] +pNG1.Writer.TransparentBackground = 1 +pNG1.Writer.Format = 'PNG' + +# ---------------------------------------------------------------- +# restore active source +SetActiveSource(pNG1) +# ---------------------------------------------------------------- + +# ------------------------------------------------------------------------------ +# Catalyst options +from paraview import catalyst +options = catalyst.Options() +options.ExtractsOutputDirectory = 'datasets_electric' +options.GenerateCinemaSpecification = 1 +options.GlobalTrigger = 'TimeStep' +#options.EnableCatalystLive = 1 +#options.CatalystLiveTrigger = 'TimeStep' + +# ------------------------------------------------------------------------------ +if __name__ == '__main__': + from paraview.simple import SaveExtractsUsingCatalystOptions + # Code for non in-situ environments; if executing in post-processing + # i.e. non-Catalyst mode, let's generate extracts using Catalyst options + SaveExtractsUsingCatalystOptions(options) diff --git a/test/stream/dump_field_particle_vtpd.py b/test/stream/dump_field_particle_vtpd.py new file mode 100644 index 000000000..ad462db50 --- /dev/null +++ b/test/stream/dump_field_particle_vtpd.py @@ -0,0 +1,63 @@ +# script-version: 2.0 +# Catalyst state generated using paraview version 5.11.1 + +#### import the simple module from the paraview +from paraview.simple import * +#### disable automatic camera reset on 'Show' +paraview.simple._DisableFirstRenderCameraReset() + +# ---------------------------------------------------------------- +# setup the data processing pipelines +# ---------------------------------------------------------------- + +# create a new 'PVTrivialProducer' +ippl_field = PVTrivialProducer(registrationName='ippl_field') +ippl_particle = PVTrivialProducer(registrationName='ippl_particle') + +# ---------------------------------------------------------------- +# setup extractors +# ---------------------------------------------------------------- + +vTPD1 = CreateExtractor('VTPD', ippl_field, registrationName='VTPD1') +# trace defaults for the extractor. +vTPD1.Trigger = 'TimeStep' + +# init the 'VTPD' selected for 'Writer' +vTPD1.Writer.FileName = 'ippl_field_{timestep:06d}.vtpd' + +# ---------------------------------------------------------------- +# restore active source +SetActiveSource(vTPD1) +# ---------------------------------------------------------------- + +# ---------------------------------------------------------------- +# setup extractors +# ---------------------------------------------------------------- + +vTPD2 = CreateExtractor('VTPD', ippl_particle, registrationName='VTPD2') +# trace defaults for the extractor. +vTPD2.Trigger = 'TimeStep' + +# init the 'VTPD' selected for 'Writer' +vTPD2.Writer.FileName = 'ippl_particle_{timestep:06d}.vtpd' + +# ---------------------------------------------------------------- +# restore active source +SetActiveSource(vTPD1) +# ---------------------------------------------------------------- + +# ------------------------------------------------------------------------------ +# Catalyst options +from paraview import catalyst +options = catalyst.Options() +options.GenerateCinemaSpecification = 1 +options.GlobalTrigger = 'TimeStep' +options.EnableCatalystLive = 1 +options.CatalystLiveTrigger = 'TimeStep' + +# ------------------------------------------------------------------------------ +if __name__ == '__main__': + from paraview.simple import SaveExtractsUsingCatalystOptions + # Code for non in-situ environments; if executing in post-processing + # i.e. non-Catalyst mode, let's generate extracts using Catalyst options + SaveExtractsUsingCatalystOptions(options) diff --git a/test/stream/dump_particles.py b/test/stream/dump_particles.py new file mode 100644 index 000000000..b6200ccd9 --- /dev/null +++ b/test/stream/dump_particles.py @@ -0,0 +1,161 @@ +# script-version: 2.0 +# Catalyst state generated using paraview version 5.11.1 + +#### import the simple module from the paraview +from paraview.simple import * +#### disable automatic camera reset on 'Show' +paraview.simple._DisableFirstRenderCameraReset() + +# ---------------------------------------------------------------- +# setup views used in the visualization +# ---------------------------------------------------------------- + +# get the material library +materialLibrary1 = GetMaterialLibrary() + +# Create a new 'Render View' +renderView1 = CreateView('RenderView') +renderView1.ViewSize = [877, 811] +renderView1.AxesGrid = 'GridAxes3DActor' +renderView1.CenterOfRotation = [9.804888932121028, 10.012698468217557, 10.017046030145888] +renderView1.HiddenLineRemoval = 1 +renderView1.StereoType = 'Crystal Eyes' +renderView1.CameraPosition = [42.01243955103898, 42.22024908713551, 42.224596649063855] +renderView1.CameraFocalPoint = [9.804888932121028, 10.012698468217557, 10.017046030145888] +renderView1.CameraViewUp = [-0.4082482904638631, 0.816496580927726, -0.40824829046386296] +renderView1.CameraFocalDisk = 1.0 +renderView1.CameraParallelScale = 14.438249951766423 +renderView1.BackEnd = 'OSPRay raycaster' +renderView1.OSPRayMaterialLibrary = materialLibrary1 + +SetActiveView(None) + +# ---------------------------------------------------------------- +# setup view layouts +# ---------------------------------------------------------------- + +# create new layout object 'Layout #1' +layout1 = CreateLayout(name='Layout #1') +layout1.AssignView(0, renderView1) +layout1.SetSize(877, 811) + +# ---------------------------------------------------------------- +# restore active view +SetActiveView(renderView1) +# ---------------------------------------------------------------- + +# ---------------------------------------------------------------- +# setup the data processing pipelines +# ---------------------------------------------------------------- + +# create a new 'XML Partitioned Dataset Reader' +ippl_particle = PVTrivialProducer(registrationName='ippl_particle') + +# ---------------------------------------------------------------- +# setup the visualization in view 'renderView1' +# ---------------------------------------------------------------- + +# show data from ippl_particle +ippl_particleDisplay = Show(ippl_particle, renderView1, 'UnstructuredGridRepresentation') + +# get 2D transfer function for 'velocity' +velocityTF2D = GetTransferFunction2D('velocity') + +# get color transfer function/color map for 'velocity' +velocityLUT = GetColorTransferFunction('velocity') +velocityLUT.TransferFunction2D = velocityTF2D +velocityLUT.RGBPoints = [0.050641224585373915, 0.231373, 0.298039, 0.752941, 2.3924284143906274, 0.865003, 0.865003, 0.865003, 4.734215604195881, 0.705882, 0.0156863, 0.14902] +velocityLUT.ScalarRangeInitialized = 1.0 + +# get opacity transfer function/opacity map for 'velocity' +velocityPWF = GetOpacityTransferFunction('velocity') +velocityPWF.Points = [0.050641224585373915, 0.0, 0.5, 0.0, 4.734215604195881, 1.0, 0.5, 0.0] +velocityPWF.ScalarRangeInitialized = 1 + +# trace defaults for the display properties. +ippl_particleDisplay.Representation = 'Point Gaussian' +ippl_particleDisplay.ColorArrayName = ['POINTS', 'velocity'] +ippl_particleDisplay.LookupTable = velocityLUT +ippl_particleDisplay.SelectTCoordArray = 'None' +ippl_particleDisplay.SelectNormalArray = 'None' +ippl_particleDisplay.SelectTangentArray = 'None' +ippl_particleDisplay.OSPRayScaleArray = 'charge' +ippl_particleDisplay.OSPRayScaleFunction = 'PiecewiseFunction' +ippl_particleDisplay.SelectOrientationVectors = 'None' +ippl_particleDisplay.ScaleFactor = 1.9956595386576226 +ippl_particleDisplay.SelectScaleArray = 'None' +ippl_particleDisplay.GlyphType = 'Arrow' +ippl_particleDisplay.GlyphTableIndexArray = 'None' +ippl_particleDisplay.GaussianRadius = 0.09978297693288113 +ippl_particleDisplay.SetScaleArray = ['POINTS', 'charge'] +ippl_particleDisplay.ScaleTransferFunction = 'PiecewiseFunction' +ippl_particleDisplay.OpacityArray = ['POINTS', 'charge'] +ippl_particleDisplay.OpacityTransferFunction = 'PiecewiseFunction' +ippl_particleDisplay.DataAxesGrid = 'GridAxesRepresentation' +ippl_particleDisplay.PolarAxes = 'PolarAxesRepresentation' +ippl_particleDisplay.ScalarOpacityFunction = velocityPWF +ippl_particleDisplay.ScalarOpacityUnitDistance = 1.3403283950605853 +ippl_particleDisplay.OpacityArrayName = ['POINTS', 'charge'] +ippl_particleDisplay.SelectInputVectors = ['POINTS', 'position'] +ippl_particleDisplay.WriteLog = '' + +# init the 'PiecewiseFunction' selected for 'ScaleTransferFunction' +ippl_particleDisplay.ScaleTransferFunction.Points = [-0.15625, 0.0, 0.5, 0.0, -0.156219482421875, 1.0, 0.5, 0.0] + +# init the 'PiecewiseFunction' selected for 'OpacityTransferFunction' +ippl_particleDisplay.OpacityTransferFunction.Points = [-0.15625, 0.0, 0.5, 0.0, -0.156219482421875, 1.0, 0.5, 0.0] + +# setup the color legend parameters for each legend in this view + +# get color legend/bar for velocityLUT in view renderView1 +velocityLUTColorBar = GetScalarBar(velocityLUT, renderView1) +velocityLUTColorBar.Title = 'velocity' +velocityLUTColorBar.ComponentTitle = 'Magnitude' + +# set color bar visibility +velocityLUTColorBar.Visibility = 1 + +# show color legend +ippl_particleDisplay.SetScalarBarVisibility(renderView1, True) + +# ---------------------------------------------------------------- +# setup color maps and opacity mapes used in the visualization +# note: the Get..() functions create a new object, if needed +# ---------------------------------------------------------------- + +# ---------------------------------------------------------------- +# setup extractors +# ---------------------------------------------------------------- + +# create extractor +pNG1 = CreateExtractor('PNG', renderView1, registrationName='PNG1') +# trace defaults for the extractor. +pNG1.Trigger = 'TimeStep' + +# init the 'PNG' selected for 'Writer' +pNG1.Writer.FileName = 'Particles_{timestep:06d}{camera}.png' +pNG1.Writer.ImageResolution = [3840, 2160] +pNG1.Writer.TransparentBackground = 1 +pNG1.Writer.Format = 'PNG' + +# ---------------------------------------------------------------- +# restore active source +SetActiveSource(pNG1) +# ---------------------------------------------------------------- + +# ------------------------------------------------------------------------------ +# Catalyst options +from paraview import catalyst +options = catalyst.Options() +options.ExtractsOutputDirectory = 'datasets_particles' +options.GenerateCinemaSpecification = 1 +options.GlobalTrigger = 'TimeStep' +#options.EnableCatalystLive = 1 +#options.CatalystLiveTrigger = 'TimeStep' + +# ------------------------------------------------------------------------------ +if __name__ == '__main__': + from paraview.simple import SaveExtractsUsingCatalystOptions + # Code for non in-situ environments; if executing in post-processing + # i.e. non-Catalyst mode, let's generate extracts using Catalyst options + SaveExtractsUsingCatalystOptions(options)