From d2d096bcf90ee4ab80653832e5333210abc27109 Mon Sep 17 00:00:00 2001 From: strakpe <petr.strakos@vsb.cz> Date: Wed, 9 Jan 2019 23:20:57 +0100 Subject: [PATCH] code supplied --- docs.it4i/software/viz/insitu.md | 56 +++++++++++++----- docs.it4i/software/viz/insitu/CMakeLists.txt | 5 +- .../software/viz/insitu/feslicescript.py | 27 +-------- docs.it4i/software/viz/insitu/insitu.tar.gz | Bin 5687 -> 5308 bytes 4 files changed, 46 insertions(+), 42 deletions(-) diff --git a/docs.it4i/software/viz/insitu.md b/docs.it4i/software/viz/insitu.md index 9cd552bcb..e0e1fb2e1 100644 --- a/docs.it4i/software/viz/insitu.md +++ b/docs.it4i/software/viz/insitu.md @@ -2,24 +2,53 @@ ## Introduction -In situ visualization is a possibility how to visualize your data during the computation performed on multiple nodes of a supercomputer. It is a visualization pipeline that can be used on our [Salomon][1] cluster. The pipeline is based on [ParaView Catalyst][2] library. +In situ visualization is a possibility how to visualize your data while your computation is progressing on multiple nodes of a cluster. It is a visualization pipeline that can be used on our [Salomon][salomon_web] supercomputer. The pipeline is based on [ParaView Catalyst][catalyst_web] library. -TEST +To leverage the possibilities of the in situ visualization by Catalyst library, you have to write an adaptor code that will use the actual data from your simulation and process them in the way they can be passed to ParaView for visualization. We provide a simple example of such simulator/adaptor code that bind together to provide the in situ visualization. -[ParaView][a] is an open-source, multi-platform data analysis and visualization application. ParaView users can quickly build visualizations to analyze their data using qualitative and quantitative techniques. The data exploration can be done interactively in 3D or programmatically using ParaView's batch processing capabilities. - -ParaView was developed to analyze extremely large datasets using distributed memory computing resources. It can be run on supercomputers to analyze datasets of exascale size as well as on laptops for smaller data. +Detailed description of the Catalyst API can be found [here][catalyst_guide]. We restrict ourselves to provide more of an overall description of the code parts together with building description, and startup description to run it all on the cluster. + ## Installed Version -The Catalyst library is part of the ParaView module in version 5.6.0. It has been compiled with intel/2017a and installed on the Salomon cluster. +The Catalyst library is part of the ParaView module. More about ParaView can be found [here][paraview_web]. We use version 5.6.0. It has been compiled with intel/2017a and installed on the Salomon cluster. ## Usage -On the clusters, ParaView is to be used in client-server mode. A parallel ParaView server is launched on compute nodes by the user, and client is launched on your desktop PC to control and view the visualization. Download ParaView client application for your OS [here][b]. +All code concerning the simulator/adaptor are available to download from [here][code]. It is a package that contains following files: CMakeLists.txt, FEAdaptor.h, FEAdaptor.cxx, FEDataStructures.h, FEDataStructures.cxx, FEDriver.cxx and feslicescript.py. + +First unpack the [code][code]. You can do it by + +```console +$ tar xvf package_name +``` + + +Use CMake to manage the build process but first load the appropriate modules (CMake, compiler, ParaView) by + +```console +$ ml CMake intel/2017a ParaView/5.6.0-intel-2017a-mpi +``` + +```console +$ mkdir build +$ cd build +$ cmake ../ +``` + +Now you can build the simulator/adaptor code using make +```console +$ make +``` + +It will generate the CxxFullExampleAdaptor executable file. This can be later run together with ParaView and provide the in situ visualization. + +## Code explanation + + + +mpirun -n 2 ./CxxFullExample 30 30 30 ../SampleScripts/feslicescript.py -!!!Warning - Your version must match the version number installed on the cluster. ### Launching Server @@ -87,8 +116,7 @@ You can now use Parallel ParaView. Remember to close the interactive session after you finish working with ParaView server, as it will remain launched even after your client is disconnected and will continue to consume resources. -[1]: https://docs.it4i.cz/salomon/introduction/ -[2]: https://www.paraview.org/in-situ/ - -[a]: http://www.paraview.org/ -[b]: http://paraview.org/paraview/resources/software.php +[salomon_web]: https://docs.it4i.cz/salomon/introduction/ +[catalyst_web]: https://www.paraview.org/in-situ/ +[paraview_web]: http://www.paraview.org/ +[catalyst_guide]: https://www.paraview.org/files/catalyst/docs/ParaViewCatalystUsersGuide_v2.pdf diff --git a/docs.it4i/software/viz/insitu/CMakeLists.txt b/docs.it4i/software/viz/insitu/CMakeLists.txt index c1f7b97df..387365643 100644 --- a/docs.it4i/software/viz/insitu/CMakeLists.txt +++ b/docs.it4i/software/viz/insitu/CMakeLists.txt @@ -1,12 +1,9 @@ cmake_minimum_required(VERSION 3.3) project(CatalystCxxFullExample) -include_directories(/apps/all/ParaView/5.6.0-intel-2017a-mpi/include/paraview-5.6/) -link_directories(/apps/all/ParaView/5.6.0-intel-2017a-mpi/lib/) - set(USE_CATALYST ON CACHE BOOL "Link the simulator with Catalyst") if(USE_CATALYST) - find_package(ParaView 4.1 REQUIRED COMPONENTS vtkPVPythonCatalyst) + find_package(ParaView 5.6 REQUIRED COMPONENTS vtkPVPythonCatalyst) include("${PARAVIEW_USE_FILE}") set(Adaptor_SRCS FEAdaptor.cxx diff --git a/docs.it4i/software/viz/insitu/feslicescript.py b/docs.it4i/software/viz/insitu/feslicescript.py index 21e9d7522..1a3344ec7 100644 --- a/docs.it4i/software/viz/insitu/feslicescript.py +++ b/docs.it4i/software/viz/insitu/feslicescript.py @@ -10,28 +10,7 @@ from paraview import coprocessing def CreateCoProcessor(): def _CreatePipeline(coprocessor, datadescription): class Pipeline: - filename_3_pvtu = coprocessor.CreateProducer( datadescription, "input" ) - - Slice1 = Slice( guiName="Slice1", Crinkleslice=0, SliceOffsetValues=[0.0], Triangulatetheslice=1, SliceType="Plane" ) - Slice1.SliceType.Offset = 0.0 - Slice1.SliceType.Origin = [34.5, 32.45, 27.95] - Slice1.SliceType.Normal = [1.0, 0.0, 0.0] - - # create a new 'Parallel PolyData Writer' - parallelPolyDataWriter1 = servermanager.writers.XMLPPolyDataWriter(Input=Slice1) - - # register the writer with coprocessor - # and provide it with information such as the filename to use, - # how frequently to write the data, etc. - coprocessor.RegisterWriter(parallelPolyDataWriter1, filename='slice_%t.pvtp', freq=10) - - # create a new 'Parallel UnstructuredGrid Writer' - unstructuredGridWriter1 = servermanager.writers.XMLPUnstructuredGridWriter(Input=filename_3_pvtu) - - # register the writer with coprocessor - # and provide it with information such as the filename to use, - # how frequently to write the data, etc. - coprocessor.RegisterWriter(unstructuredGridWriter1, filename='fullgrid_%t.pvtu', freq=100) + coprocessor.CreateProducer( datadescription, "input" ) return Pipeline() @@ -40,7 +19,7 @@ def CreateCoProcessor(): self.Pipeline = _CreatePipeline(self, datadescription) coprocessor = CoProcessor() - freqs = {'input': [10, 100]} + freqs = {'input': []} coprocessor.SetUpdateFrequencies(freqs) return coprocessor @@ -53,7 +32,7 @@ coprocessor = CreateCoProcessor() #-------------------------------------------------------------- # Enable Live-Visualizaton with ParaView -coprocessor.EnableLiveVisualization(False) +coprocessor.EnableLiveVisualization(True) # ---------------------- Data Selection method ---------------------- diff --git a/docs.it4i/software/viz/insitu/insitu.tar.gz b/docs.it4i/software/viz/insitu/insitu.tar.gz index d207465c54760da5dc15d3fae7c05591f7bf5547..fb1e220751d15bb35345d41f906a58159171ceeb 100644 GIT binary patch literal 5308 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 Dz*S{t literal 5687 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 -- GitLab