pax_global_header 0000666 0000000 0000000 00000000064 14675621442 0014525 g ustar 00root root 0000000 0000000 52 comment=42cc0810163528bdfa9540237019df73e46fba53
glvis-4.3.2/ 0000775 0000000 0000000 00000000000 14675621442 0012657 5 ustar 00root root 0000000 0000000 glvis-4.3.2/.github/ 0000775 0000000 0000000 00000000000 14675621442 0014217 5 ustar 00root root 0000000 0000000 glvis-4.3.2/.github/workflows/ 0000775 0000000 0000000 00000000000 14675621442 0016254 5 ustar 00root root 0000000 0000000 glvis-4.3.2/.github/workflows/builds.yml 0000664 0000000 0000000 00000021260 14675621442 0020262 0 ustar 00root root 0000000 0000000 # Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-443271.
#
# This file is part of the GLVis visualization tool and library. For more
# information and source code availability see https://glvis.org.
#
# GLVis is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# GLVis - an OpenGL visualization server based on the MFEM library
name: builds
on:
push:
branches:
- master
pull_request:
workflow_dispatch:
env:
HYPRE_ARCHIVE: v2.19.0.tar.gz
HYPRE_TOP_DIR: hypre-2.19.0
METIS_ARCHIVE: metis-4.0.3.tar.gz
METIS_TOP_DIR: metis-4.0.3
MFEM_TOP_DIR: mfem
MFEM_BRANCH: master
jobs:
builds-and-tests:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
target: [dbg, opt]
mpi: [seq]
build-system: [cmake]
include:
- os: ubuntu-latest
target: opt
mpi: seq
build-system: make
- os: ubuntu-latest
target: dbg
mpi: par
build-system: make
- os: macos-latest
target: opt
mpi: seq
build-system: make
- os: macos-latest
target: dbg
mpi: par
build-system: make
name: ${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}
runs-on: ${{ matrix.os }}
steps:
- name: get MPI (Linux)
if: matrix.os == 'ubuntu-latest' && matrix.mpi == 'par'
run: |
sudo apt-get update
sudo apt-get install mpich libmpich-dev
export MAKE_CXX_FLAG="MPICXX=mpic++"
# Keep the following section in case we need it again in the future,
# see: https://github.com/mfem/mfem/pull/3385#discussion_r1058013032
# - name: Set up Homebrew
# if: matrix.os == 'macos-latest' && matrix.mpi == 'par'
# uses: Homebrew/actions/setup-homebrew@master
- name: get MPI (MacOS)
if: matrix.os == 'macos-latest' && matrix.mpi == 'par'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install openmpi
export MAKE_CXX_FLAG="MPICXX=mpic++"
# Get Hypre through cache, or build it.
# Install will only run on cache miss.
- name: cache hypre
if: matrix.mpi == 'par'
id: hypre-cache
uses: actions/cache@v4
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-v2.2
- name: build hypre
if: steps.hypre-cache.outputs.cache-hit != 'true' && matrix.mpi == 'par'
uses: mfem/github-actions/build-hypre@v2.4
with:
archive: ${{ env.HYPRE_ARCHIVE }}
dir: ${{ env.HYPRE_TOP_DIR }}
build-system: make
# Get Metis through cache, or build it.
# Install will only run on cache miss.
- name: cache metis
if: matrix.mpi == 'par'
id: metis-cache
uses: actions/cache@v4
with:
path: ${{ env.METIS_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.2
- name: build metis
if: steps.metis-cache.outputs.cache-hit != 'true' && matrix.mpi == 'par'
uses: mfem/github-actions/build-metis@v2.4
with:
archive: ${{ env.METIS_ARCHIVE }}
dir: ${{ env.METIS_TOP_DIR }}
# make generic links to libraries for MFEM install
# Those links are already created by build-mfem action, but not when the cache is used...
- name: configure links
if: matrix.mpi == 'par'
run: |
echo "Hypre symlink:"
ln -s $HYPRE_TOP_DIR hypre;
echo "Metis symlink:"
ln -s $METIS_TOP_DIR metis-4.0;
- name: MFEM ${{ env.MFEM_BRANCH }} commit
run: |
echo "MFEM_COMMIT=$(git ls-remote --heads https://github.com/mfem/mfem.git ${MFEM_BRANCH} | awk '{print $1;}')" >> $GITHUB_ENV
# Get MFEM through cache, or build it.
# Install will only run on cache miss.
- name: cache mfem
id: cache-mfem
uses: actions/cache@v4
with:
path: ${{ env.MFEM_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.MFEM_TOP_DIR }}-${{ env.MFEM_COMMIT }}-${{ matrix.target }}-${{ matrix.build-system}}-v2.4
# We are using the defaults of the MFEM action here, which is to use master
# branch. There is an implicit assumption here that mfem master hasn't
# changed since the 'MFEM master commit' step.
# Also, if we apply to MFEM build the same target as GLVis. This may be
# superfluous.
- name: build mfem
if: steps.cache-mfem.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-mfem@v2.4
with:
os: ${{ matrix.os }}
target: ${{ matrix.target }}
hypre-dir: ${{ env.HYPRE_TOP_DIR }}
metis-dir: ${{ env.METIS_TOP_DIR }}
mfem-dir: ${{ env.MFEM_TOP_DIR }}
mfem-branch: ${{ env.MFEM_BRANCH }}
build-system: ${{ matrix.build-system }}
mpi: ${{ matrix.mpi }}
library-only: true
# Install GLVis dependencies with package manager
- name: get deps (Linux)
if: matrix.os == 'ubuntu-latest'
run: |
# We need to add a PPA for SDL 2.0.14 - fixes some initialization
# errors for X11
sudo add-apt-repository -y ppa:savoury1/multimedia
sudo apt-get update
sudo apt-get install libfontconfig1-dev libfreetype6-dev libsdl2-dev libglew-dev libglm-dev libpng-dev
# - name: Set up Homebrew
# if: matrix.os == 'macos-latest'
# uses: Homebrew/actions/setup-homebrew@master
- name: get deps (MacOS)
if: matrix.os == 'macos-latest'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install fontconfig freetype sdl2 glew glm libpng
- name: cache deps (Windows)
id: cache-deps
uses: actions/cache@v4
with:
path: vcpkg_cache
key: ${{ runner.os }}-vcpkg-v1
- name: prepare binary cache location
if: steps.cache-deps.outputs.cache-hit != 'true'
run: |
mkdir -p vcpkg_cache
- name: checkout GLVis
uses: actions/checkout@v4
with:
path: glvis
submodules: recursive
- name: build GLVis (make)
if: matrix.build-system == 'make'
run: |
glvis_target="opt"
[[ ${{ matrix.target }} == "dbg" ]] && glvis_target="debug";
cd glvis && make ${glvis_target} -j3
- name: build GLVis (cmake)
if: matrix.build-system == 'cmake'
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg_cache
run: |
build_type="Release"
[[ ${{ matrix.target }} == "dbg" ]] && build_type="Debug";
[[ ${{ matrix.os }} == "windows-latest" ]] \
&& toolchain_file="${VCPKG_INSTALLATION_ROOT}\\scripts\\buildsystems\\vcpkg.cmake"
cd glvis && mkdir build && cd build
cmake \
-D CMAKE_TOOLCHAIN_FILE:STRING=${toolchain_file} \
-D CMAKE_BUILD_TYPE:STRING=${build_type} \
-D ENABLE_TESTS:BOOL=TRUE \
-D mfem_DIR:PATH=${GITHUB_WORKSPACE}/${MFEM_TOP_DIR}/build \
-D GLVIS_BASELINE_SYS=${{ matrix.os }} \
..
cmake --build . --parallel 3 --config "${build_type}"
shell: bash
- name: setup Python
if: matrix.build-system == 'cmake'
uses: actions/setup-python@v5
with:
python-version: 3.9
- name: setup Python packages for testing
if: matrix.build-system == 'cmake'
run: |
python -m pip install --upgrade pip
python -m pip install -r glvis/tests/requirements.txt
- name: setup Linux testing dependencies
if: matrix.build-system == 'cmake' && matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install xvfb
- name: test GLVis (cmake/linux)
if: matrix.build-system == 'cmake' && matrix.os == 'ubuntu-latest'
run: |
cd glvis && cd build
xvfb-run -a ctest --verbose
- name: test GLVis (cmake/mac)
if: matrix.build-system == 'cmake' && matrix.os == 'macos-latest'
run: |
cd glvis && cd build
ctest --verbose
- name: create screenshot tarball
if: always() && matrix.build-system == 'cmake' && matrix.os != 'windows-latest'
run: |
cd glvis && cd build
cd tests && tar czvf ../test_screenshots.tar.gz outputs
- name: upload test screenshots
if: always() && matrix.build-system == 'cmake' && matrix.os != 'windows-latest'
uses: actions/upload-artifact@v4
with:
name: test-screenshots-${{ matrix.os }}-${{ matrix.target }}-${{ matrix.mpi }}
path: glvis/build/test_screenshots.tar.gz
glvis-4.3.2/.github/workflows/release.yml 0000664 0000000 0000000 00000020046 14675621442 0020421 0 ustar 00root root 0000000 0000000 # Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-443271.
#
# This file is part of the GLVis visualization tool and library. For more
# information and source code availability see https://glvis.org.
#
# GLVis is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# GLVis - an OpenGL visualization server based on the MFEM library
name: release
on:
push:
tags:
- v*
branches:
- master
workflow_dispatch:
env:
HYPRE_ARCHIVE: v2.19.0.tar.gz
HYPRE_TOP_DIR: hypre-2.19.0
METIS_ARCHIVE: metis-4.0.3.tar.gz
METIS_TOP_DIR: metis-4.0.3
MFEM_TOP_DIR: mfem
MFEM_BRANCH: master
jobs:
release-builds:
strategy:
matrix:
os: [macos-latest, windows-latest]
target: [opt]
mpi: [seq]
build-system: [cmake]
name: ${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}
runs-on: ${{ matrix.os }}
steps:
- name: get MPI (Linux)
if: matrix.os == 'ubuntu-latest' && matrix.mpi == 'par'
run: |
sudo apt-get update
sudo apt-get install mpich libmpich-dev
export MAKE_CXX_FLAG="MPICXX=mpic++"
# Keep the following section in case we need it again in the future,
# see: https://github.com/mfem/mfem/pull/3385#discussion_r1058013032
# - name: Set up Homebrew
# if: matrix.os == 'macos-latest' && matrix.mpi == 'par'
# uses: Homebrew/actions/setup-homebrew@master
- name: get MPI (MacOS)
if: matrix.os == 'macos-latest' && matrix.mpi == 'par'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install openmpi
export MAKE_CXX_FLAG="MPICXX=mpic++"
# Get Hypre through cache, or build it.
# Install will only run on cache miss.
- name: cache hypre
if: matrix.mpi == 'par'
id: hypre-cache
uses: actions/cache@v4
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-v2.2
- name: build hypre
if: steps.hypre-cache.outputs.cache-hit != 'true' && matrix.mpi == 'par'
uses: mfem/github-actions/build-hypre@v2.4
with:
archive: ${{ env.HYPRE_ARCHIVE }}
dir: ${{ env.HYPRE_TOP_DIR }}
build-system: make
# Get Metis through cache, or build it.
# Install will only run on cache miss.
- name: cache metis
if: matrix.mpi == 'par'
id: metis-cache
uses: actions/cache@v4
with:
path: ${{ env.METIS_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.2
- name: build metis
if: steps.metis-cache.outputs.cache-hit != 'true' && matrix.mpi == 'par'
uses: mfem/github-actions/build-metis@v2.4
with:
archive: ${{ env.METIS_ARCHIVE }}
dir: ${{ env.METIS_TOP_DIR }}
# make generic links to libraries for MFEM install
# Those links are already created by build-mfem action, but not when the cache is used...
- name: configure links
if: matrix.mpi == 'par'
run: |
echo "Hypre symlink:"
ln -s $HYPRE_TOP_DIR hypre;
echo "Metis symlink:"
ln -s $METIS_TOP_DIR metis-4.0;
- name: MFEM ${{ env.MFEM_BRANCH }} commit
run: |
echo "MFEM_COMMIT=$(git ls-remote --heads https://github.com/mfem/mfem.git ${MFEM_BRANCH} | awk '{print $1;}')" >> $GITHUB_ENV
# Get MFEM through cache, or build it.
# Install will only run on cache miss.
- name: cache mfem
id: cache-mfem
uses: actions/cache@v4
with:
path: ${{ env.MFEM_TOP_DIR }}
key: ${{ runner.os }}-build-${{ env.MFEM_TOP_DIR }}-${{ env.MFEM_COMMIT }}-${{ matrix.target }}-${{ matrix.build-system}}-v2.2
# We are using the defaults of the MFEM action here, which is to use master
# branch. There is an implicit assumption here that mfem master hasn't
# changed since the 'MFEM master commit' step.
# Also, if we apply to MFEM build the same target as GLVis. This may be
# superfluous.
- name: build mfem
if: steps.cache-mfem.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-mfem@v2.4
with:
os: ${{ matrix.os }}
target: ${{ matrix.target }}
hypre-dir: ${{ env.HYPRE_TOP_DIR }}
metis-dir: ${{ env.METIS_TOP_DIR }}
mfem-dir: ${{ env.MFEM_TOP_DIR }}
mfem-branch: ${{ env.MFEM_BRANCH }}
build-system: ${{ matrix.build-system }}
mpi: ${{ matrix.mpi }}
# Install GLVis dependencies with package manager
- name: get deps (Linux)
if: matrix.os == 'ubuntu-latest'
run: |
# We need to add a PPA for SDL 2.0.14 - fixes some initialization
# errors for X11
sudo add-apt-repository -y ppa:savoury1/multimedia
sudo apt-get update
sudo apt-get install libfontconfig1-dev libfreetype6-dev libsdl2-dev libglew-dev libglm-dev libpng-dev
# - name: Set up Homebrew
# if: matrix.os == 'macos-latest'
# uses: Homebrew/actions/setup-homebrew@master
- name: get deps (MacOS)
if: matrix.os == 'macos-latest'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install fontconfig freetype sdl2 glew glm libpng
- name: cache deps (Windows)
id: cache-deps
uses: actions/cache@v4
with:
path: vcpkg_cache
key: ${{ runner.os }}-vcpkg-v1
- name: prepare binary cache location
if: steps.cache-deps.outputs.cache-hit != 'true'
run: |
mkdir -p vcpkg_cache
- name: checkout GLVis
uses: actions/checkout@v4
with:
path: glvis
submodules: recursive
- name: build GLVis (cmake)
if: matrix.build-system == 'cmake'
env:
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg_cache
run: |
build_type="Release"
[[ ${{ matrix.os }} == "windows-latest" ]] \
&& toolchain_file="${VCPKG_INSTALLATION_ROOT}\\scripts\\buildsystems\\vcpkg.cmake"
cd glvis && mkdir build && cd build
cmake \
-D CMAKE_TOOLCHAIN_FILE:STRING=${toolchain_file} \
-D CMAKE_BUILD_TYPE:STRING=${build_type} \
-D ENABLE_TESTS:BOOL=TRUE \
-D mfem_DIR:PATH=${GITHUB_WORKSPACE}/${MFEM_TOP_DIR}/build \
-D GLVIS_BASELINE_SYS=${{ matrix.os }} \
-D CMAKE_INSTALL_PREFIX=../install-${{ matrix.os }} \
..
cmake --build . --parallel 3 --config "${build_type}"
shell: bash
- name: package binary (Windows)
if: matrix.os == 'windows-latest'
env:
GLVIS_EXPORT_NAME: glvis-${{ github.ref_name }}-${{ runner.os }}-${{ runner.arch }}
run: |
cd glvis/build
Copy-Item -Path "Release" -Destination "${Env:GLVIS_EXPORT_NAME}" -Recurse
- name: package binary (Mac)
if: matrix.os == 'macos-latest'
env:
GLVIS_EXPORT_NAME: glvis-${{ github.ref_name }}-${{ runner.os }}-${{ runner.arch }}
run: |
cd glvis/build
make app
# Creates the actual relocatable bundle (copying system libraries)
sudo make install
# Fix permissions from running `make install` as root
cd ../install-${{ matrix.os }}
sudo chown -R ${USER} GLVis.app
# Go back to build directory
cd ../build
# Copy executable to a temporary directory
mkdir dmg_tmp
cp -a ../install-${{ matrix.os }}/GLVis.app dmg_tmp/GLVis.app
# Create DMG since actions/upload-artifact will clobber Unix permissions
hdiutil create -volname "GLVis macOS arm64" -srcfolder dmg_tmp -ov -format UDZO GLVis.dmg
mkdir ${GLVIS_EXPORT_NAME}
cp GLVis.dmg ${GLVIS_EXPORT_NAME}
- name: upload binary
uses: actions/upload-artifact@v4
env:
GLVIS_EXPORT_NAME: glvis-${{ github.ref_name }}-${{ runner.os }}-${{ runner.arch }}
with:
name: ${{ env.GLVIS_EXPORT_NAME }}
path: glvis/build/${{ env.GLVIS_EXPORT_NAME }}
glvis-4.3.2/.gitignore 0000664 0000000 0000000 00000000552 14675621442 0014651 0 ustar 00root root 0000000 0000000 # Build artifacts
*.o
*.bc
lib/libglvis.js
lib/libglvis.a
share/logo.rgba.bin.cpp
glvis
GLVis.app
# Output from running glvis
GLVis.pdf
GLVis_s*.png
GLVis_m*.png
glvis-saved.*
# CMake-specific exclusions
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
# OS-specific: Mac
*.dSYM
.DS_Store
glvis-4.3.2/.gitmodules 0000664 0000000 0000000 00000000125 14675621442 0015032 0 ustar 00root root 0000000 0000000 [submodule "tests/data"]
path = tests/data
url = https://github.com/GLVis/data.git
glvis-4.3.2/CHANGELOG 0000664 0000000 0000000 00000045434 14675621442 0014103 0 ustar 00root root 0000000 0000000 GLVis visualization tool
_/_/_/ _/ _/ _/ _/
_/ _/ _/ _/ _/_/_/
_/ _/_/ _/ _/ _/ _/ _/_/
_/ _/ _/ _/ _/ _/ _/_/
_/_/_/ _/_/_/_/ _/ _/ _/_/_/
https://glvis.org
Version 4.3.2 released on Sep 27, 2024
======================================
- Fixed the Mac binary build in GitHub CI and provided a signed and notarized
version for download from the website.
- Fixed handling of key press events to work with localized layouts and enable
key translation with 'AltGr'.
- Updated JavaScript bindings to fix issues in glvis-js and pyglvis, and added
support for quadrature data visualization.
- Fixed visualization of 1D data and added a regression test.
- Miscellaneous CI improvements including: generating image diffs for tests,
set `fail-fast: false` so that tests always run, rename artifacts to help
avoid confusion, code-cleanup/light refactoring.
Version 4.3 released on Aug 7, 2024
===================================
- Added visualization of quadrature data (QuadratureFunction in MFEM). Both
loading from file, with the new command line argument '-q', or from a socket
stream, with the keyword 'quadrature', are supported. Three visualization
options are provided: piece-wise constants on a refined mesh (LOR), L2 field
with DOFs collocated (interpolation), or projection to discontinuous elements
(L2 projection). Use 'Q' to switch between them. High-order quadrature data is
supported only for tensor finite elements with the first two options. With the
first option, only the mesh lines of the original mesh are visualized. This
feature is also supported for the element-wise cutting plane in 3D (cplane=2).
- The GLVis auto refinement algorithm now takes into account the order of the
data (mesh and grid function). The new refinement is chosen to be sufficient
for resolving the curvature of the data, but only if we can do that with less
than 2M vertices and 16 refinements. Otherwise, we print a warning and the
user may still need to press 'o' to fully resolve the data. For more details,
see the section Auto-refinement in README.md.
- Added option to specify the floating point number formatting in GLVis axes and
colorbar. Use 'Alt+a' for the axes and 'Alt+c' for the colorbar. Formatting
can also be specified in socket stream or glvis script with axis_numberformat
or colorbar_numberformat, followed by a C-like formatting string, for example
"colorbar_numberformat '%+06.1f'".
- Added a building option for setting the default font size.
- Added support for scalar integral finite elements, where calculation of the
surface normals was not implemented and was crashing GLVis. The normals are
approximately calculated from the point-wise projected value-based elements.
- Added two new modes for visualization of vector fields in 2D, placing the
arrows above the plotted surface and using a single color.
- Added support to visualize solutions on 1D elements embedded in 2D and 3D.
- Significantly improved memory usage.
- Various other bugfixes and improvements.
Version 4.2 released on May 23, 2022
====================================
- Added 3D scene export to glTF format (https://www.khronos.org/gltf) which is
bound to the key 'G'. This can be used to import GLVis scenes for rendering in
Blender, as well as for augmented reality, see https://modelviewer.dev/editor.
- Added the option to cut a portion of the interiors of 3D faces to expose more
of the mesh. Useful as an alternative to transparency. See keys Ctrl+F3/F4.
- Added a third mode to keys 'b'/'B' in 2D to display the mesh boundary colored
by boundary element attribute.
- Support for visualization of pyramid-shaped elements.
- An edge numbering option is now available in 2D.
- In 2D, save and restore solution's value range when using keys 'e' and 'b'.
- Mac and Windows binaries are now automatically built with GitHub actions CI.
- The command-line option -mac was renamed to -save.
- Various other bugfixes and improvements.
Version 4.1, released on Aug 31, 2021
=====================================
- Use threads in server mode for window creation and session management instead
of fork(). This resolves issues with the GLVis server mode on macOS. It also
allows for closing all open GLVis server windows by Ctrl-C in the terminal.
- Preliminary support for interactive inline GLVis plots in Python Jupyter
Notebooks with https://github.com/glvis/pyglvis and C++ Jupyter Notebooks with
https://github.com/glvis/xeus-glvis.
- Added support for native builds on Windows with CMake.
- Added support for native Mac application bundle with "make app". The resulting
app can be double-clicked, added to the Dock, etc.
- Added screenshots support to the JavaScript/web version (key 'S').
- Enabled support for WebGL 2, when available. This enables, among other
features, support for controllable multisampling via framebuffers.
- Refactored rendering components, including palette and shader handling.
- Replaced pthreads and POSIX-specific code with C++11 standard thread library.
- Added a new regression test suite based on generated screenshots of stream
files. See the README in the tests/ directory for more details. Note that this
requires a git submodule for the baseline images, which are located in the
separate https://github.com/glvis/data repository.
- Various bugfixes and improvements related to the JavaScript version, vertex
numbering, script handling, screenshots, HiDPI support, and more.
Version 4.0, released on Dec 11, 2020
=====================================
Starting with this version, the GLVis open source license is changed to BSD-3.
Unlike previous GLVis releases, this version requires a C++11 compiler.
- Major overhaul and modernization of the GLVis rendering and window management,
replacing X Windows with SDL for platform-native window and event handling.
This enables OpenGL 3+ support and HiDPI support on Mac OS X.
- Two rendering backends are included: one for legacy OpenGL contexts without
support for shaders, and one with full support for modern OpenGL 3 features.
The modern OpenGL context is preferred by default; a new command-line argument
"-oldgl" can be used to request the legacy backend.
- Preliminary support for building GLVis to JavaScript/WebAssembly using
Emscripten, see https://github.com/GLVis/glvis-js.
- Documented project workflow and provided contribution guidelines in the new
top-level file, CONTRIBUTING.md.
- Added several perceptually uniform colormaps "turbo", "viridis", "plasma",
"fusion", "iceburn", "viola", "pride" and "ocean" from
* Google AI: https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html
* Matplotlib: https://bids.github.io/colormap/
* CMasher: https://github.com/1313e/CMasher
- Added support for visualization of the element ordering curve with 'Ctrl+o'.
- Keystroke changes: cutting plane in 2D is now toggled with 'i' instead of 'w',
and 2D element subdivision is controlled with 'o/O' instead of 'i/I'. These
are the same as the corresponding keystrokes in 3D.
- Improved the 3D cutting plane algorithm for curved elements. The key 'I' can
be used to switch to the previous (faster) algorithm which is suitable for
meshes with planar faces.
- Updated to support the display and slicing of meshes with wedge elements.
- Improved the opening of parallel meshes/solutions.
- Transparency and printing in textured coloring modes is now supported, and
no-texture coloring has been removed as a result.
- FreeType is now a required dependency and text on screen is rendered using a
texture atlas.
- Replaced the "deep sea" palette with "ocean". Added new palette: gray.
- Added the ability to discretize a palette, i.e. to use just a prescribed
number of its colors, see the new "number of colors" input of the F6 key.
- Added new script and socket command: "palette_repeat" which can be used to
repeat and reverse/flip the palette - controls the same parameter as the first
prompt after pressing the F6 key in the GLVis window.
- Added a key for setting the bounding box from the terminal (Shift+F7).
Version 3.4, released on May 29, 2018
=====================================
- When enabled, secure sockets (based on GnuTLS) now use authentication based on
X.509 certificates. A new set of X.509 client/server keys can be generated
with the updated version of the script 'glvis-keygen.sh'.
- Added capability to show element and vertex numbering in 2D (key 'n').
- Added support for reading mesh and solution from the same file.
- Added a CMake build system.
- Added 10 new color palettes which can now be switched both forwards and
backwards with the 'p' and 'P' keys respectively.
- Allow multi-screen window managers to redraw on current screen.
- Printing to PDF is now done with 'Ctrl+p' (replacing 'P').
- Default multisampling linewidth for Macs is now 0.01 (seems to work better).
On other platforms the default remains 1.4.
Version 3.3, released on Jan 28, 2017
=====================================
- Added the ability to change the axis labels displayed with the coordinate
cross in the lower left corner. They can be set with the new 'axis_labels'
socket command, for example: sol_sock << "axis_labels 'u' 'v' 'w'\n";
- With the corresponding version of MFEM, GLVis now supports gz-compressed
files and socket streams.
Version 3.2, released on Jun 30, 2016
=====================================
- Added support for secure socket connections based on the GnuTLS library
through MFEM. This option may be useful in multi-user environment to prevent
users from sending/receiving visualization data to/from other users. See
INSTALL for setup instructions.
- Added an optional caption at the top of the GLVis window. This can be set in
several different ways: through a command-line parameter (-c|--plot-caption),
a socket command (plot_caption), a GLVis script command (plot_caption) or the
'C' keystroke.
The caption is displayed as one of the states of the colorbar (key 'c') which
now has 3 modes: no colorbar & no caption; colorbar & caption; colorbar & no
caption. With empty caption, 'c' works the same as before.
For vector fields, the current vector-to-scalar function is added to the
caption in parenthesis. Similarly, for 2D scalar fields, the "surface
elements mode" (attached to the 'e' key) is added to the caption.
- Improved the handling of the "keys" command in GLVis scripts and socket
connections.
- Added "scale" and "translate" script commands.
Version 3.1, released on Feb 5, 2016
====================================
- Moved GLVis from Google Code to GitHub. New website: http://glvis.org.
- Formatted the code with Artistic Style, see the "make style" target.
- Added 'help', 'distclean', 'install' and 'status'/'info' targets to the GLVis
makefile. The default install directory is ./bin. That can be overwritten with
"make install PREFIX=
".
- With the corresponding version of MFEM, GLVis now supports the visualization
of non-conforming meshes and grid functions.
- Added support for visualizing vector fields on surface meshes, and for element
shrinking (F3/F4) of surface meshes.
- The 'P' key now prints in PDF instead of EPS format. The output still has
some deficiencies, so 'P' is recommended only if vector format is necessary.
For quick screenshots (e.g. for a talk), the 'S' key is preferable.
- Added a command-line option (-d | --pad-digits), to set the number of digits
used for processor ranks in file names.
- Added a command-line option (-grt | -geom_ref_type) to refine the geometry
using the Gauss-Lobatto instead of uniform points.
- In 2D, added keys that in addition to 'b', can cycle through the boundary
attributes: shift+f9 (forward) and shift-f10 (backward); added visualization
of element attributes as another state of the 'e' key.
- New socket command, window_geometry, can be used to arrange the visualization
window on the screen
- Various other small fixes and styling updates.
Version 3.0, released on Jan 26, 2015
=====================================
- Updated the makefile to use the new build system in MFEM, so GLVis can now be
built from any (serial or parallel) MFEM build.
- Support for saving screenshots directly in png format using libpng. Enabled
by default with "USE_LIBPNG = YES" in the makefile.
- Support for antialiased fonts using the freetype library. Enabled by default
with "USE_FREETYPE = YES" in the makefile (the options "FT_OPTS_YES" and
"FT_LIBS_YES" may need to be adjusted). The font is determined at runtime from
a list of fontconfig patterns: fc_font_patterns in lib/aux_vis.cpp. It can
also be specified on the command line, e.g. "-fn Ubuntu-15".
- Improved level surfaces to support hexahedral elements and to better represent
high-order grid-functions and curved meshes using element subdivision.
- Added support for 1D meshes + solutions, visualized in 2D via extrusion in
y-direction. The z-axis is scaled relative to the x-axis.
- Added support for surface meshes (2D meshes in 3 space dimensions).
- Added new (input stream) command, "autopause " that will stop (when
turned on) the interpretation of the input stream after every mesh + solution
update. Autopause can also be toggled using the "Control+Space" key.
- When visualizing a GridFunction from a socket, script, or the command line
GLVis will now enable the subdivision mode ("f" key) and select subdivision
factor (using the new AutoRefine method) depending on the number of elements
(2D) or number of boundary elements (3D) in the mesh.
- Additional stream command support. Most of the script commands are supported
including taking screenshots.
- New camera manipulation using Ctrl, the middle mouse button, and optionally
Shift and Alt.
- Significantly improved logarithmic scaling mode (key "L").
- Improved visualization of smoothed (antialiased) lines without multisampling.
- Switched to MFEM's OptionParser class for command line arguments parsing.
- Various small fixes and styling updates.
Version 2.0, released on Nov 18, 2011
=====================================
- Extended GLVis to allow visualization of parallel meshes and grid functions.
For data saved in separate files, the format is:
glvis -np <#proc> -m [-g ]
The file names are obtained from the prefix by appending '.' followed by a
6-digit processor/subdomain number padded with 0's. The related (obsolete)
option -par3d was removed.
For results send by separate socket connections from each processor, the
format just adds the prefix: "parallel <#proc> " (see the parallel
MFEM examples).
The corresponding GLVis script command is "psolution
", where controls if the boundary
attributes should be replaced with the processor number or if they should be
kept unchanged (this option is also available from the command line as '-a').
In all cases, GLVis will stitch the parallel results to show the global mesh
and solution, but the subdomain data can still be examined through the F3/F4,
F8, F9/F10 and F11/F12 keystrokes.
- Added the ability to directly visualize 3D VectorFiniteElement-based grid
functions (e.g. from a Nedelec or a Raviart-Thomas space), by an internal
projection onto the discontinuous piece-wise polynomial space of the
appropriate order.
- Added new bounding box visualization mode (fourth state for the 'a' key) using
red, green, blue colored main axes and dashed box.
- Added support for dynamic mesh and solution (grid function) update over
sockets based on MFEM's new socket communication classes socketserver and
socketstream. Both serial and parallel codes can use this capability.
- Switched to GLX 1.3 compatible mode selection and window creation. The old GLX
calls are still available when GLVis is compiled with -DGLVIS_GLX10. The new
functions allow for multisampling on Macs with ATI cards, though the X11
server on OS X Snow Leopard gives a warning that "GLX 1.3 is not supported",
but works fine in practice.
- Added functionality allowing GLVis to handle modifier+key input. As a first
application, control + arrow keys can be used now to translate the view.
- Improved the handling of the boundary in 2D ('b' key) for curved meshes.
- The palettes can now be flipped by specifying a negative value for the number
of times the palette is repeated (F6 key).
- Provided workaround for a bug in the NVIDIA driver on some 64 bit systems,
where glX calls after a fork() close file descriptor 0.
- Various small fixes and styling updates.
Version 1.2, released on Apr 8, 2011
====================================
- If build with mfem version 1.2 (or later), glvis now supports unstructured
meshes in VTK format, including quadratic curvilinear meshes.
- When viewing 3D vector field, 'F' will cycle the displayed scalar function
between magnitude, x-component, y-component and z-component.
- Added a new command line option: '-gc' allowing visualization of a single
component of a GridFunction, e.g: glvis -m mesh -g sol -gc 0. This is useful
for grid functions describing tensors.
- Ensured that the shrinking of elements (F3/F4) and material subdomains
(F11/F12) work in 2D/3D, with scalar/vector plots and on curved meshes. The
latter are useful, in particular, to visualize the subdomains corresponding to
different processors in a mfem parallel run.
- The palette update (key 'p') when using texture is now instantaneous.
- Added a new script command: toggle_attributes.
- Added a new palette: calewhite, from VisIt.
- Various small fixes and styling updates.
Version 1.1, released on Sep 13, 2010
=====================================
- Anti-aliasing (key 'A') now uses the OpenGL ARB_multisample extension (when
available). By default, 4x multisampling is used. See file lib/tk.cpp. This
value can be changed by setting GLVIS_MULTISAMPLE during compilation.
- When drawing subdivided elements, the real normals are now used (at least in
some cases) to smooth the appearance inside the element, i.e. the surface in
2D and the (curved) boundary in 3D.
- Enabled the shrinking of elements (F3/F4) and material subdomains (F11/F12)
for 3D meshes saved using Mesh::PrintWithPartitioning(). This allows for
better visualization of the interior of the mesh.
- Improved the hex-cutting algorithm to handle all cases of non-flat faces.
- Scripts now work with scalar 3D mesh/solution.
- Changed the makefile to recompile only files that have been changed and to
allow 'make -j'.
- Various small fixes and styling updates.
Version 1.0, released on Jul 21, 2010
=====================================
- Uploaded to http://glvis.googlecode.com.
- Initial release.
glvis-4.3.2/CMakeLists.txt 0000664 0000000 0000000 00000027311 14675621442 0015423 0 ustar 00root root 0000000 0000000 # Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-443271.
#
# This file is part of the GLVis visualization tool and library. For more
# information and source code availability see https://glvis.org.
#
# GLVis is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# CMake v3.10 is where "Imported Targets" like "Freetype::Freetype" are
# introduced.
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Prohibit in-source builds
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
message(FATAL_ERROR "In-source builds are prohibited.")
endif ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
project(glvis NONE)
# Import MFEM. The following variables can be used to help CMake find MFEM:
# * MFEM_DIR - absolute path to the MFEM build or install prefix.
# * mfem_DIR - absolute path to where MFEMConfig.cmake is.
message(STATUS "Looking for mfem ...")
set(MFEM_DIR "" CACHE PATH "Path to the MFEM build or install prefix.")
if (MFEM_DIR)
find_package(mfem REQUIRED NAMES MFEM HINTS "${MFEM_DIR}"
"${MFEM_DIR}/lib/cmake/mfem" NO_DEFAULT_PATH)
else()
find_package(mfem REQUIRED NAMES MFEM)
endif()
message(STATUS "Found mfem config in: ${mfem_DIR} (version ${MFEM_VERSION})")
# Use the same C++ compiler as MFEM. This is needed when MFEM was built using
# an MPI wrapper and we do not have explicitly the MPI compile and link flags.
if (NOT CMAKE_CXX_COMPILER AND MFEM_CXX_COMPILER)
set(CMAKE_CXX_COMPILER "${MFEM_CXX_COMPILER}")
endif()
enable_language(C)
enable_language(CXX)
# Default options match the Makefile
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
option(GLVIS_USE_LIBTIFF
"Use libtiff for taking screenshots internally"
OFF)
option(GLVIS_USE_LIBPNG
"Use libpng for taking screenshots internally"
ON)
#
# Handle a few other definitions
#
# Default multisampling mode
if (NOT GLVIS_MULTISAMPLE)
set(GLVIS_MULTISAMPLE 4)
endif (NOT GLVIS_MULTISAMPLE)
# Default multisampling line-width
if (NOT GLVIS_MS_LINEWIDTH)
if (NOT APPLE)
set(GLVIS_MS_LINEWIDTH 1.4)
else()
# This value seems to work better on Macs
set(GLVIS_MS_LINEWIDTH 1.0)
endif()
endif (NOT GLVIS_MS_LINEWIDTH)
# Default font size
if (NOT GLVIS_FONT_SIZE)
set(GLVIS_FONT_SIZE 12)
endif (NOT GLVIS_FONT_SIZE)
#
# Start finding everything
#
set(_glvis_compile_defs)
set(_glvis_compile_opts)
set(_glvis_include_dirs)
set(_glvis_libraries)
list(APPEND _glvis_compile_defs "GLVIS_MULTISAMPLE=${GLVIS_MULTISAMPLE}")
list(APPEND _glvis_compile_defs "GLVIS_MS_LINEWIDTH=${GLVIS_MS_LINEWIDTH}")
list(APPEND _glvis_compile_defs "GLVIS_FONT_SIZE=${GLVIS_FONT_SIZE}")
if (NOT WIN32)
list(APPEND _glvis_compile_defs "GLVIS_USE_LOGO")
else()
list(APPEND _glvis_compile_defs "_USE_MATH_DEFINES")
endif()
if(NOT WIN32)
find_program(XXD_FOUND xxd)
if(NOT XXD_FOUND)
message(FATAL_ERROR "Required tool not found: xxd.")
endif()
endif()
if (CMAKE_BUILD_TYPE MATCHES "Debug|debug|DEBUG")
list(APPEND _glvis_compile_defs "GLVIS_DEBUG")
list(APPEND _glvis_compile_opts "-Wall")
endif()
# Include paths and libraries needed by MFEM
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MFEM_CXX_FLAGS}")
list(APPEND _glvis_include_dirs "${MFEM_INCLUDE_DIRS}")
list(APPEND _glvis_libraries "${MFEM_LIBRARIES}")
if (NOT EMSCRIPTEN)
# Find OpenGL
find_package(OpenGL REQUIRED)
list(APPEND _glvis_libraries OpenGL::GL)
# Find 'SDL2' which is not part of the CMake standard modules
list(APPEND SDL2_DIR "../SDL2")
set(SDL2_DIR_SAVE ${SDL2_DIR})
find_package(SDL2 QUIET HINTS ${SDL2_DIR})
# The SDL2 target 'SDL2::SDL2' is not always defined, so instead we use
# directly 'SDL2_INCLUDE_DIRS' and 'SDL2_LIBRARIES'.
if (TARGET SDL2::SDL2)
list(APPEND _glvis_libraries SDL2::SDL2)
elseif (SDL2_INCLUDE_DIRS AND SDL2_LIBRARIES)
# SDL2_INCLUDE_DIRS is defined with 'SDL2' at the end of the path we need to
# strip that.
set(new_list_)
foreach (path IN LISTS SDL2_INCLUDE_DIRS)
string(REGEX REPLACE "/include/SDL2$" "/include" new_path_ "${path}")
list(APPEND new_list_ "${new_path_}")
endforeach()
set(SDL2_INCLUDE_DIRS ${new_list_})
list(APPEND _glvis_include_dirs "${SDL2_INCLUDE_DIRS}")
list(APPEND _glvis_libraries "${SDL2_LIBRARIES}")
else()
# find_package() did not work; try more direct approach.
set(SDL2_DIR ${SDL2_DIR_SAVE})
find_path(SDL2_INCLUDE_DIRS "SDL2/SDL.h"
HINTS ${SDL2_DIR} ENV SDL2_DIR
PATH_SUFFIXES "include"
DOC "SDL2 include path.")
find_library(SDL2_LIBRARIES "SDL2"
HINTS ${SDL2_DIR} ENV SDL2_DIR
PATH_SUFFIXES "lib"
DOC "SDL2 library.")
if (NOT (SDL2_INCLUDE_DIRS AND SDL2_LIBRARIES))
message(FATAL_ERROR "SDL2 library not found. Please set SDL2_DIR.")
endif()
list(APPEND _glvis_include_dirs "${SDL2_INCLUDE_DIRS}")
list(APPEND _glvis_libraries "${SDL2_LIBRARIES}")
endif()
message(STATUS "SDL2 found: ${SDL2_LIBRARIES}")
message(STATUS "SDL2_INCLUDE_DIRS = ${SDL2_INCLUDE_DIRS}")
# Find GLEW
# GLEW search path can be set using CMAKE_PREFIX_PATH
list(APPEND CMAKE_PREFIX_PATH "../glew")
find_package(GLEW REQUIRED)
list(APPEND _glvis_libraries GLEW::GLEW)
# Find 'glm' which is not part of the CMake standard modules
list(APPEND GLM_DIR "../glm")
find_package(glm QUIET HINTS ${GLM_DIR})
if (NOT GLM_INCLUDE_DIRS)
find_path(GLM_INCLUDE_DIRS "glm/glm.hpp"
HINTS ${GLM_DIR} ENV GLM_DIR
PATH_SUFFIXES "include"
DOC "GLM include path.")
if (NOT GLM_INCLUDE_DIRS)
message(FATAL_ERROR "GLM headers not found. Please set GLM_DIR.")
endif()
endif()
message(STATUS "GLM headers found: ${GLM_INCLUDE_DIRS}")
list(APPEND _glvis_include_dirs "${GLM_INCLUDE_DIRS}")
# Find TIFF
if (GLVIS_USE_LIBTIFF)
find_package(TIFF)
if (TIFF_FOUND)
list(APPEND _glvis_compile_defs "GLVIS_USE_LIBTIFF")
list(APPEND _glvis_libraries TIFF::TIFF)
else()
message(WARNING "TIFF library not found. TIFF disabled.")
set(GLVIS_USE_LIBTIFF OFF)
endif (TIFF_FOUND)
endif (GLVIS_USE_LIBTIFF)
# Find PNG
if (GLVIS_USE_LIBPNG)
find_package(PNG)
if (PNG_FOUND)
list(APPEND _glvis_compile_defs "GLVIS_USE_LIBPNG")
list(APPEND _glvis_libraries PNG::PNG)
else()
message(WARNING "PNG library not found. PNG disabled.")
set(GLVIS_USE_LIBPNG OFF)
endif (PNG_FOUND)
endif (GLVIS_USE_LIBPNG)
# Find FreeType.
find_package(Freetype REQUIRED)
# Find FontConfig (FindFontconfig.cmake was added in CMake 3.14)
find_library(FONTCONFIG_LIBRARY fontconfig
HINTS ${FONTCONFIG_DIR} $ENV{FONTCONFIG_DIR}
DOC "The fontconfig library for use with FreeType."
NO_DEFAULT_PATH)
find_library(FONTCONFIG_LIBRARY fontconfig)
if (FONTCONFIG_LIBRARY)
list(APPEND _glvis_libraries Freetype::Freetype)
# Need FONTCONFIG_INCLUDE_DIRS?
list(APPEND _glvis_libraries "${FONTCONFIG_LIBRARY}")
message(STATUS "Found Fontconfig: ${FONTCONFIG_LIBRARY}")
else()
message(STATUS "Fontconfig not found. Please set FONTCONFIG_DIR.")
message(FATAL_ERROR "Fontconfig not found.")
endif (FONTCONFIG_LIBRARY)
# Find threading library
find_package(Threads REQUIRED)
list(APPEND _glvis_libraries "${CMAKE_THREAD_LIBS_INIT}")
if (CMAKE_USE_PTHREADS_INIT)
message(STATUS "System threading library: pthreads")
elseif (CMAKE_USE_WIN32_THREADS_INIT)
message(STATUS "System threading library: Win32 threads")
elseif (Threads_FOUND)
message(STATUS "System threading library: other")
endif()
else(NOT EMSCRIPTEN)
find_package(glm REQUIRED)
list(APPEND _glvis_include_dirs "${GLM_INCLUDE_DIRS}")
set(_emscripten_opts)
# Enable embind
list(APPEND _emscripten_opts "--bind")
# OpenGL, SDL2, and GLEW are provided by the Emscripten runtime
# Enable SDL2
list(APPEND _emscripten_opts "-s USE_SDL=2")
list(APPEND _emscripten_opts
"-s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=0")
# Set WebGL options
list(APPEND _emscripten_opts
"-s GL_ASSERTIONS=1 -s GL_DEBUG=1 -s MAX_WEBGL_VERSION=2")
# Enable Freetype port
list(APPEND _emscripten_opts "-s USE_FREETYPE=1")
# Module export options
list(APPEND _emscripten_opts "-s ENVIRONMENT=web")
list(APPEND _emscripten_opts "-s MODULARIZE=1")
list(APPEND _emscripten_opts "-s EXPORT_NAME=glvis")
# Other emscripten options
list(APPEND _emscripten_opts "-s ALLOW_MEMORY_GROWTH=1")
list(APPEND _emscripten_opts "-s SINGLE_FILE=1")
list(APPEND _emscripten_opts "--no-heap-copy")
# Since we don't have access to fontconfig, embed a font
if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/OpenSans.ttf")
message(FATAL_ERROR "Preload font file \"OpenSans.ttf\" not found.")
endif()
list(APPEND _emscripten_opts
"--embed-file ${CMAKE_CURRENT_SOURCE_DIR}/OpenSans.ttf@OpenSans.ttf")
endif(NOT EMSCRIPTEN)
message(STATUS "GLVis build type: CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
message(STATUS "GLVis defines: ${_glvis_compile_defs}")
# message(STATUS "GLVis opts: ${_glvis_compile_opts}")
# message(STATUS "GLVis include dirs: ${_glvis_include_dirs}")
# message(STATUS "GLVis libraries: ${_glvis_libraries}")
message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
#
# Setup the GLVis library target
#
add_subdirectory(lib)
add_subdirectory(share)
if(NOT EMSCRIPTEN)
# Setup the GLVis executable
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON CACHE BOOL "")
set(CMAKE_INSTALL_RPATH "${MFEM_LIBRARY_DIR}" CACHE PATH "")
add_executable(glvis-exe glvis.cpp)
set_target_properties(glvis-exe PROPERTIES OUTPUT_NAME glvis)
target_link_libraries(glvis-exe PRIVATE glvis)
if (WIN32)
target_sources(glvis-exe
PRIVATE
"share/windows.manifest"
"${CMAKE_CURRENT_BINARY_DIR}/share/resource.rc")
else()
target_link_libraries(glvis-exe PRIVATE glvis_logo)
endif (WIN32)
# Install the executable
install(TARGETS glvis-exe RUNTIME DESTINATION bin)
# Install the gnutls helper script
if (MFEM_USE_GNUTLS)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/glvis-keygen.sh
DESTINATION bin
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif (MFEM_USE_GNUTLS)
if (APPLE)
set(GLVIS_APP_ICON ${CMAKE_CURRENT_SOURCE_DIR}/share/GLVis.icns)
set(GLVIS_APP_CREDITS ${CMAKE_CURRENT_SOURCE_DIR}/share/Credits.rtf)
set_source_files_properties(
${GLVIS_APP_ICON} ${GLVIS_APP_CREDITS}
PROPERTIES
MACOSX_PACKAGE_LOCATION "Resources")
add_executable(app MACOSX_BUNDLE glvis.cpp
${GLVIS_APP_ICON} ${GLVIS_APP_CREDITS})
set_target_properties(app
PROPERTIES
EXCLUDE_FROM_ALL TRUE
OUTPUT_NAME GLVis
MACOSX_BUNDLE_INFO_PLIST
${CMAKE_CURRENT_SOURCE_DIR}/share/Info.cmake.plist.in)
target_link_libraries(app PRIVATE glvis glvis_logo)
install(TARGETS app
RUNTIME DESTINATION .
BUNDLE DESTINATION .)
install(CODE [[
include (BundleUtilities)
fixup_bundle("${CMAKE_INSTALL_PREFIX}/GLVis.app" "" "")
file(GLOB LIBS_TO_SIGN
"${CMAKE_INSTALL_PREFIX}/GLVis.app/Contents/Frameworks/*.dylib")
foreach(LIB ${LIBS_TO_SIGN})
if (NOT IS_SYMLINK ${LIB})
execute_process(COMMAND codesign --force --sign - ${LIB})
endif()
endforeach()
execute_process(COMMAND codesign --force --sign - ${CMAKE_INSTALL_PREFIX}/GLVis.app)
]] COMPONENT RUNTIME)
endif(APPLE)
endif(NOT EMSCRIPTEN)
if(ENABLE_TESTS)
enable_testing()
add_subdirectory(tests)
endif(ENABLE_TESTS)
glvis-4.3.2/CONTRIBUTING.md 0000664 0000000 0000000 00000041431 14675621442 0015113 0 ustar 00root root 0000000 0000000
# How to Contribute
The GLVis team welcomes contributions at all levels: bugfixes; code improvements;
simplifications; new visualization capabilities; improved documentation; etc.
GLVis is distributed under the terms of the BSD-3 license. All new contributions
must be made under this license.
If you plan on contributing to GLVis, consider reviewing the
[issue tracker](https://github.com/glvis/glvis/issues) first to check if a thread
already exists for your desired feature or the bug you ran into. Use a pull
request (PR) toward the `glvis:master` branch to propose your contribution. If
you are planning significant code changes or have questions, you may want to
open an [issue](https://github.com/glvis/glvis/issues) before issuing a PR. In
addition to technical contributions, we are also interested in your results and
[simulation images](https://glvis.org/gallery/), which you can share via a pull
request in the [glvis/web](https://github.com/glvis/web) repo.
See the [Quick Summary](#quick-summary) section for the main highlights of our
GitHub workflow. For more details, consult the following sections and refer
back to them before issuing pull requests:
- [Quick Summary](#quick-summary)
- [Code Overview](#code-overview)
- [GitHub Workflow](#github-workflow)
- [GLVis Organization](#glvis-organization)
- [New Feature Development](#new-feature-development)
- [Developer Guidelines](#developer-guidelines)
- [Pull Requests](#pull-requests)
- [Pull Request Checklist](#pull-request-checklist)
- [Releases](#releases)
- [Release Checklist](#release-checklist)
- [LLNL Workflow](#llnl-workflow)
- [Automated Testing](#automated-testing)
- [Contact Information](#contact-information)
Contributing to GLVis requires knowledge of Git and, likely, OpenGL and/or finite
elements. If you are new to Git, see the [GitHub learning
resources](https://help.github.com/articles/git-and-github-learning-resources/).
To learn more about the finite element method, see this [MFEM page](https://mfem.org/fem).
*By submitting a pull request, you are affirming the [Developer's Certificate of
Origin](#developers-certificate-of-origin-11) at the end of this file.*
## Quick Summary
- We encourage you to [join the GLVis organization](#glvis-organization) and create
development branches off `glvis:master`.
- Please follow the [developer guidelines](#developer-guidelines), in particular
with regards to documentation and code styling.
- Pull requests should be issued toward `glvis:master`. Make sure
to check the items off the [Pull Request Checklist](#pull-request-checklist).
- When your contribution is fully working and ready to be reviewed, add
the `ready-for-review` label.
- PRs are treated similarly to journal submission with an "editor" assigning two
reviewers to evaluate the changes.
- The reviewers have 3 weeks to evaluate the PR and work with the author to
fix issues and implement improvements.
- We use [milestones](https://github.com/glvis/glvis/milestones) to coordinate the
work on different PRs toward a release.
- Don't hesitate to [contact us](#contact-information) if you have any questions.
### Code Overview
#### Source code structure:
The GLVis library uses object-oriented design principles which reflect, in code,
the independent mathematical concepts of meshing, linear algebra and finite
element spaces and operators.
The GLVis source code has the following structure:
```
.
├── lib
│ └── gl
│ └── shaders
├── share
└── tests
```
## GitHub Workflow
The GLVis GitHub organization: https://github.com/glvis, is the main developer hub
for the GLVis project.
If you plan to make contributions or would like to stay up-to-date with changes
in the code, *we strongly encourage you to [join the GLVis organization](#glvis-organization)*.
This will simplify the workflow (by providing you additional permissions), and
will allow us to reach you directly with project announcements.
### GLVis Organization
#### Getting started (GitHub)
Before you can start, you need a GitHub account, here are a few suggestions:
+ Create the account at: [github.com/join](https://github.com/join).
+ For easy identification, please add your full name and maybe a picture of you at:
https://github.com/settings/profile.
+ To receive notification, set a primary email at: https://github.com/settings/emails.
+ For password-less pull/push over SSH, add your SSH keys at: https://github.com/settings/keys.
#### Joining
- [Contact us](#contact-information) for an invitation to join the GLVis GitHub
organization. You will receive an invitation email, which you can directly accept.
Alternatively, *after logging into GitHub*, you can accept the invitation at
the top of https://github.com/glvis.
- Consider making your membership public by going to https://github.com/orgs/glvis/people
and clicking on the organization visibility drop box next to your name.
- Project discussions and announcements will be posted at
https://github.com/orgs/glvis/teams/everyone.
#### Structure
- The GLVis source code is in the [glvis](https://github.com/glvis/glvis)
repository.
- The website and corresponding documentation are in the
[web](https://github.com/glvis/web) repository.
### New Feature Development
- A new feature should be important enough that at least one person, the
author, is willing to work on it and be its champion.
- The author creates a branch for the new feature (with suffix `-dev`), off
the `master` branch, or another existing feature branch, for example:
```
# Clone assuming you have setup your ssh keys on GitHub:
git clone git@github.com:glvis/glvis.git
# Alternatively, clone using the "https" protocol:
git clone https://github.com/glvis/glvis.git
# Create a new feature branch starting from "master":
git checkout master
git pull
git checkout -b feature-dev
# Work on "feature-dev", add local commits
# ...
# (One time only) push the branch to github and setup your local
# branch to track the github branch (for "git pull"):
git push -u origin feature-dev
```
- **We prefer that you create the new feature branch inside the GLVis organization
as opposed to in a fork.** This allows everyone in the community to collaborate
in one central place.
- If you prefer to work in your fork, please [enable upstream edits](https://help.github.com/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork/).
- Never use the `next` branch to start a new feature branch!
- The typical feature branch name is `new-feature-dev`, e.g. `pumi-dev`. While
not frequent in GLVis, other suffixes are possible, e.g. `-fix`, `-doc`, etc.
### Developer Guidelines
- *Keep the code lean and as simple as possible*
- Well-designed simple code is frequently more general and powerful.
- Lean code base is easier to understand by new collaborators.
- New features should be added only if they are necessary or generally useful.
- Introduction of language constructions not currently used in GLVis should be
justified and generally avoided (to maintain portability to various systems
and compilers, including early access hardware).
- We prefer basic C++ and the C++03 standard, to keep the code readable by
a large audience and to make sure it compiles anywhere.
- *Keep the code general and reasonably efficient*
- The main goal is fast prototyping for research and application development.
- When in doubt, generality wins over efficiency.
- Respect the needs of different users (current and/or future).
- *Keep things separate and logically organized*
- General usage features go in GLVis (implemented in as much generality as
possible), non-general features go into external apps.
- Inside GLVis, compartmentalize between linalg, fem, mesh, GLVis, etc.
- Contributions that are project-specific or have external dependencies are
allowed (if they are of broader interest), but should be `#ifdef`-ed and not
change the code by default.
- Code specifics
- All significant new classes, methods and functions have Doxygen-style
documentation in source comments.
- Consistent code styling is enforced with `make style` in the top-level
directory. This requires [Artistic Style](http://astyle.sourceforge.net)
version 3.1 and MFEM's style configuration file, typically located in
`../mfem/config/mfem.astylerc`.
- When manually resolving conflicts during a merge, make sure to mention the
conflicted files in the commit message.
### Pull Requests
- When your branch is ready for other developers to review / comment on
the code, create a pull request towards `glvis:master`.
- Pull request typically have titles like:
`Description [new-feature-dev]`
for example:
`Parallel Unstructured Mesh Infrastructure (PUMI) integration [pumi-dev]`
Note the branch name suffix (in square brackets).
- Titles may contain a prefix in square brackets to emphasize the type of PR.
Common choices are: `[DON'T MERGE]`, `[WIP]` and `[DISCUSS]`, for example:
`[DISCUSS] Hybridized DG [hdg-dev]`
- If the PR is still a work in progress, add the `WIP` label to it and
optionally the `[WIP]` prefix in the title.
- Add a description, appropriate labels and assign yourself to the PR. The GLVis
team will add reviewers as appropriate.
- List outstanding TODO items in the description, see PR #222 for an example.
- When your contribution is fully working and ready to be reviewed, add
the `ready-for-review` label.
- PRs are treated similarly to journal submission with an "editor" assigning
two reviewers to evaluate the changes. The reviewers have 3 weeks to evaluate
the PR and work with the author to implement improvements and fix issues.
### Pull Request Checklist
Before a PR can be merged, it should satisfy the following:
- [ ] Code builds.
- [ ] Code passes `make style`.
- [ ] Update `CHANGELOG`:
- [ ] Is this a new feature users need to be aware of?
- [ ] Does it make sense to create a new section in the `CHANGELOG` to group with other related features?
- [ ] Update `INSTALL`:
- [ ] Had a new optional library been added? If so, what range of versions of this library are required? (*Make sure the external library is compatible with our BSD license, e.g. it is not licensed under GPL!*)
- [ ] Have the version ranges for any required or optional libraries changed?
- [ ] Does `make` or `cmake` have a new target?
- [ ] Did the requirements or the installation process change? *(rare)*
- [ ] Update `.gitignore`:
- [ ] Check if `make distclean; git status` shows any files that were generated from the source by the project (not an IDE) but we don't want to track in the repository.
- [ ] Add new patterns (just for the new files above) and re-run the above test.
- [ ] New capability:
- [ ] All significant new classes, methods and functions have Doxygen-style documentation in source comments.
- [ ] Consider saving cool simulation pictures with the new capability in the Confluence gallery (LLNL only) or submitting them, via pull request, to the gallery section of the `glvis/web` repo.
- [ ] If this is a major new feature, consider mentioning it in the short summary inside `README` *(rare)*.
- [ ] List major new classes in `doc/CodeDocumentation.dox` *(rare)*.
- [ ] Update this checklist, if the new pull request affects it.
### Releases
- Releases are just tags in the `master` branch, e.g. https://github.com/glvis/glvis/releases/tag/v3.4,
and have a version that ends in an even "patch" number, e.g. `v3.4.2` or
`v3.4` (by convention `v3.4` is the same as `v3.4.0`.) Between releases, the
version ends in an odd "patch" number, e.g. `v3.4.1`.
- We use [milestones](https://github.com/glvis/glvis/milestones) to coordinate the
work on different PRs toward a release, see for example the
[v3.4 release](https://github.com/glvis/glvis/milestone/1?closed=1).
- After a release is complete, the `next` branch is recreated, e.g. as follows
(replace `3.4` with current release):
- Rename the current `next` branch to `next-pre-v3.4`.
- Create a new `next` branch starting from the `v3.4` release.
- Local copies of `next` can then be updated with `git fetch origin next && git checkout -B next origin/next`.
### Release Checklist
- [ ] Update the GLVis version in the following files:
- [ ] `CHANGELOG`
- [ ] `README.md`
- [ ] `vcpkg.json`
- [ ] `share/Info.plist`
- [ ] `share/Info.cmake.plist.in`
- [ ] Check that version requirements for each of GLVis's dependencies are documented in `INSTALL` and up-to-date
- [ ] Update the `CHANGELOG` to organize all release contributions
- [ ] Review the whole source code once over
- [ ] Ask GLVis-based applications to test the pre-release branch
- [ ] Test on additional platforms and compilers
- [ ] Tag the repository:
```
git tag -a v3.1 -m "Official release v3.1"
git push origin v3.1
```
- [ ] Create the release tarball and push to `glvis/releases`.
- [ ] Recreate the `next` branch as described in previous section.
- [ ] Update and push documentation to `glvis/doxygen`.
- [ ] Update URL shortlinks:
- [ ] Create a shortlink at [http://bit.ly/](http://bit.ly/) for the release tarball, e.g. https://glvis.github.io/releases/glvis-3.1.tgz.
- [ ] (LLNL only) Add and commit the new shortlink in the `links` and `links-glvis` files of the internal `glvis/downloads` repo.
- [ ] Add the new shortlinks to the GLVis packages in `spack`, `homebrew/science`, `VisIt`, etc.
- [ ] Update website in `glvis/web` repo:
- Update version and shortlinks in `src/index.md` and `src/download.md`.
- Use [cloc-1.62.pl](http://cloc.sourceforge.net/) and `ls -lh` to estimate the SLOC and the tarball size in `src/download.md`.
## LLNL Workflow
### Mirroring on Bitbucket
- The GitHub `master` and `next` branches are mirrored to the LLNL institutional
Bitbucket repository as `gh-master` and `gh-next`.
- `gh-master` is merged into LLNL's internal `master` through pull requests; write
permissions to `master` are restricted to ensure this is the only way in which it
gets updated.
- We never push directly from LLNL to GitHub.
- Versions of the code on LLNL's internal server, from most to least stable:
- GLVis official release on glvis.org -- Most stable, tested in many apps.
- `glvis:master` -- Recent development version, guaranteed to work.
- `glvis:gh-master` -- Stable development version, passed testing, you can use
it to build your code between releases.
- `glvis:gh-next` -- Bleeding-edge development version, may be broken, use at
your own risk.
## Contact Information
- Contact the GLVis team by posting to the [GitHub issue tracker](https://github.com/glvis/glvis).
Please perform a search to make sure your question has not been answered already.
## [Developer's Certificate of Origin 1.1](https://developercertificate.org/)
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I have the right
to submit it under the open source license indicated in the file; or
(b) The contribution is based upon previous work that, to the best of my
knowledge, is covered under an appropriate open source license and I have
the right under that license to submit that work with modifications, whether
created in whole or in part by me, under the same open source license
(unless I am permitted to submit under a different license), as indicated in
the file; or
(c) The contribution was provided directly to me by some other person who
certified (a), (b) or (c) and I have not modified it.
(d) I understand and agree that this project and the contribution are public and
that a record of the contribution (including all personal information I
submit with it, including my sign-off) is maintained indefinitely and may be
redistributed consistent with this project or the open source license(s)
involved.
glvis-4.3.2/INSTALL 0000664 0000000 0000000 00000021614 14675621442 0013714 0 ustar 00root root 0000000 0000000 GLVis visualization tool
_/_/_/ _/ _/ _/ _/
_/ _/ _/ _/ _/_/_/
_/ _/_/ _/ _/ _/ _/ _/_/
_/ _/ _/ _/ _/ _/ _/_/
_/_/_/ _/_/_/_/ _/ _/ _/_/_/
https://glvis.org
GLVis is a multiplatform OpenGL application and can be built on Linux/Unix
systems, including Mac OS X, and under Windows.
Besides a C++ compiler, GLVis depends on the following external packages:
- the MFEM library (use the latest release) plus any libraries that MFEM was
built to depend on
https://mfem.org
- the OpenGL library
https://www.opengl.org
- the GLEW library; used for setting up OpenGL functions and extensions
http://glew.sourceforge.net
- the GLM library; used for computing OpenGL-related mathematics
https://glm.g-truc.net
- the SDL2 library; used for platform-native window and event management
https://www.libsdl.org
- the FreeType 2 and Fontconfig libraries; used for font rendering
https://www.freetype.org, https://www.fontconfig.org
- the libpng or libtiff library; used for taking screenshots (optional)
http://www.libpng.org, http://www.libtiff.org
- the XQuartz app (on Mac OS X, if running GLVis remotely through ssh)
https://www.xquartz.org
There are two build systems, one based on GNU make and one based on CMake, as
described below. Choose the one that matches the build system you used to
build MFEM.
In addition to the native build systems, a GLVis package is also available
in the Spack package manager, https://github.com/spack/spack.
Building with GNU make
======================
GLVis comes with a standard makefile, which can be adjusted to specify the paths
to the external libraries, the compiler flags, etc.
Some of the available 'make' targets are:
make -> Builds the glvis binary, using the MFEM compiler and options
make opt -> Builds an optimized version
make debug -> Builds a debug version
make app -> Builds a Mac OS application bundle
make clean -> Cleans the build
make style -> Format the code with Artistic Style.
make help -> Prints a short help message
Information about the current build configuration can be viewed using
make status
make info
An optional installation of the glvis executable can be performed with
make install [PREFIX=]
Building with CMake
===================
GLVis may also be configured using CMake to find dependencies. This is the only
supported build method for native Windows builds with Visual Studio.
NOTE: You must have built MFEM using CMake to build GLVis using CMake.
An example invocation of CMake may be:
cmake \
-G Ninja \
-D CMAKE_BUILD_TYPE:STRING=Release \
-D CMAKE_INSTALL_PREFIX:STRING=/path/to/glvis/install \
\
-D GLVIS_USE_LIBTIFF=OFF \
-D GLVIS_USE_LIBPNG=ON \
\
-D MFEM_DIR=/path/to/directory/with/MFEMConfig.cmake \
\
/path/to/glvis/source
Some important variables for CMake are:
- MFEM_DIR: This is the MFEM build or install prefix. Can be used if the MFEM
location is not auto-detected correctly.
- mfem_DIR: (alternative to MFEM_DIR) This is the location of the configuration
file MFEMConfig.cmake that is created during the build and/or install of
MFEM. You may use either the build directory's config file or the install
directory's config file.
- CMAKE_BUILD_TYPE: Most common options are "Debug" and "Release" [default].
- CMAKE_INSTALL_PREFIX: Top-level directory for the install. GLVis will be
installed to ${CMAKE_INSTALL_PREFIX}/bin. Default is "/usr/local".
- GLVIS_USE_LIBPNG: Use libpng for creating screenshots. Default is "ON".
- GLVIS_USE_LIBTIFF: Use libtiff for creating screenshots. Default is "OFF".
- GLVIS_MULTISAMPLE and GLVIS_MS_LINEWIDTH: See building considerations below
for more information on these variables.
- GLVIS_FONT_SIZE: Default font size for text. Default is "12".
Some building considerations
============================
- On most Linux distributions, the required dependencies (except MFEM) can be
installed via a package manager.
On Ubuntu/Debian, the required dependencies can be installed by running:
apt-get install libfontconfig1-dev libfreetype-dev libsdl2-dev \
libglew-dev libglm-dev libpng-dev
On Fedora/RHEL, the required dependencies can be installed by running:
dnf install fontconfig-devel freetype-devel SDL2-devel glew-devel \
glm-devel libpng-devel
On Mac OS X, the required dependencies can be installed with Homebrew:
brew install fontconfig freetype sdl2 glew glm libpng
Package names in other distributions may vary.
- On Windows, GLVis can be built in two ways:
1) Via a Linux-compatible environment, such as Cygwin or Windows Subsystem for
Linux (WSL).
Install the required dependencies, following the directions above for your
WSL environment's Linux distribution, then continue with the build method
of your choice.
For WSL, you may also need to install an X server to run GLVis, such as
VcXsrv (https://sourceforge.net/projects/vcxsrv/).
2) As a native Windows executable. This enables support for platform-native
visualization windows, as well as the modern OpenGL backend.
Visual Studio or another Windows-compatible compiler is required.
It is recommended to install dependencies via vcpkg:
vcpkg install fontconfig freetype sdl2 glew glm libpng \
--triplet=x64-windows
After installing, proceed with the CMake configuration process, making sure
to point the CMake variable CMAKE_TOOLCHAIN_FILE to the correct path, based
on the directory where you installed vcpkg. More directions can be found in
the link below:
https://vcpkg.readthedocs.io/en/latest/examples/installing-and-using-packages/#cmake
You may then open the generated Visual Studio project files to build GLVis,
or call the following command from the GLVis project root directory:
cmake --build [build directory] --parallel
- In case packaged versions of the needed libraries are not available, download
and build instructions are included below for GLM, GLEW, and SDL2.
- To adjust the anti-aliasing settings for your hardware:
1) Modify the value of the GLVIS_MULTISAMPLE variable (multisample mode) in
the makefile or CMake invocation. Supported values can be obtained from
the 'glxinfo' command ('ms' columns) or a from a tool like
'nvidia-settings'.
2) Modify the value of the GLVIS_MS_LINEWIDTH variable (anti-aliased line
width) in the makefile or CMake invocation. Note that the same value can
produce different results depending on the OpenGL implementation.
3) The above options and some other built-in defaults can be overwritten with
command line options, see glvis -h for short help.
- GLVis can be built without libpng/libtiff by setting the makefile variables
GLVIS_USE_LIBPNG/GLVIS_USE_LIBTIFF to NO or setting the same variables to OFF
during cmake configuration. In this case, GLVis uses SDL to take screenshots
in .bmp format, which are then converted to .png using `convert`.
- Support for secure sockets using the GnuTLS library through MFEM can be
enabled by configuring and compiling MFEM with the option MFEM_USE_GNUTLS=YES,
see MFEM's INSTALL for more details. In addition, in order for this to work,
one needs to generate GLVis server/client key pairs (in ~/.config/glvis),
similar to ssh keys. The script 'glvis-keygen.sh' can be used to do that:
bash glvis-keygen.sh ["Your Name"] ["Your Email"]
- On Mac OS X, GLVis can be built as a native application bundle using the 'make
app' target (with both the makefile and CMake build systems).
Dependency building instructions
================================
Note that using the build locations given below will let the GLVis build systems
(GNU make and CMake) find these libraries automatically.
-----
GLM
-----
From the directory containing the 'glvis' directory run the command:
git clone https://github.com/g-truc/glm.git
or the sequence of commands:
wget "https://github.com/g-truc/glm/archive/0.9.9.8.tar.gz"
mv 0.9.9.8.tar.gz glm-0.9.9.8.tar.gz
tar zxf glm-0.9.9.8.tar.gz
ln -s glm-0.9.9.8 glm
GLM is a header-only library, no building is necessary.
------
GLEW
------
From the directory containing the 'glvis' directory run the commands:
wget "https://github.com/nigels-com/glew/releases/download/glew-2.1.0/glew-2.1.0.tgz"
tar zxf glew-2.1.0.tgz
ln -s glew-2.1.0 glew
To build the library run the commands (see also glew/README.md):
cd glew
make -j 4
cd ..
------
SDL2
------
From the directory containing the 'glvis' directory run the commands:
wget "https://www.libsdl.org/release/SDL2-2.0.12.tar.gz"
tar zxf SDL2-2.0.12.tar.gz
To build the library run the commands (see also SDL2-2.0.12/INSTALL.txt):
cd SDL2-2.0.12
./configure --prefix=`dirname $PWD`/SDL2
make -j 4
make install
cd ..
glvis-4.3.2/LICENSE 0000664 0000000 0000000 00000003012 14675621442 0013660 0 ustar 00root root 0000000 0000000 BSD 3-Clause License
Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
glvis-4.3.2/NOTICE 0000664 0000000 0000000 00000002720 14675621442 0013564 0 ustar 00root root 0000000 0000000 This work was produced under the auspices of the U.S. Department of Energy by
Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
This work was prepared as an account of work sponsored by an agency of
the United States Government. Neither the United States Government nor
Lawrence Livermore National Security, LLC, nor any of their employees
makes any warranty, expressed or implied, or assumes any legal liability
or responsibility for the accuracy, completeness, or usefulness of any
information, apparatus, product, or process disclosed, or represents that
its use would not infringe privately owned rights.
Reference herein to any specific commercial product, process, or service
by trade name, trademark, manufacturer, or otherwise does not necessarily
constitute or imply its endorsement, recommendation, or favoring by the
United States Government or Lawrence Livermore National Security, LLC.
The views and opinions of authors expressed herein do not necessarily
state or reflect those of the United States Government or Lawrence
Livermore National Security, LLC, and shall not be used for advertising
or product endorsement purposes.
Inclusion of external software:
This project distributes the sources of several external software products with
their own respective licenses which can be found in their code and attached
license files. These software products and their licenses are as follows:
* GL2PS (linalg/gl2ps.{h,c}) -- Custom 1-clause license
glvis-4.3.2/README.md 0000664 0000000 0000000 00000045244 14675621442 0014147 0 ustar 00root root 0000000 0000000 GLVis visualization tool
_/_/_/ _/ _/ _/ _/
_/ _/ _/ _/ _/_/_/
_/ _/_/ _/ _/ _/ _/ _/_/
_/ _/ _/ _/ _/ _/ _/_/
_/_/_/ _/_/_/_/ _/ _/ _/_/_/
https://glvis.org
[GLVis](https://glvis.org) is an OpenGL tool for visualization of finite element
meshes and functions. It is a multiplatform application that can be built on
Linux/Unix systems, including macOS, and under Windows. It can also be used in a
Jupyter notebook, or in a web browser, see https://glvis.org/live.
- For building instructions, see [INSTALL](INSTALL).
- The GLVis [key commands](#key-commands) and [mouse functions](#mouse-functions)
are documented below.
- GLVis is distributed under the terms of the BSD-3 license. All new contributions
must be made under this license. See [LICENSE](LICENSE) and [NOTICE](NOTICE) for details.
We welcome contributions and feedback from the community. Please see the file
[CONTRIBUTING.md](CONTRIBUTING.md) for additional details about our development
process.
When started without any options, glvis starts a server which waits for a socket
connections (on port `19916` by default) and visualizes any received data. This
way the results of simulations on a remote (parallel) machine can be visualized
on the local user desktop.
GLVis can also be used to visualize a mesh with or without a finite element
function (solution), as in
```
glvis -m cube.mesh3d
```
For parallel computations, GLVis supports input from several parallel socket
connections as well as the visualization of parallel meshes and grid functions
saved in separate files from the command line as in
```
glvis -np 4 -m mesh -g solution
```
When given parallel input, GLVis will stitch the results to show the global mesh
and solution. GLVis can also run a batch sequence of commands (GLVis scripts),
or display previously saved socket streams.
For a complete list of command line options, type
```
glvis -h
```
Depending on the data type, variety of manipulations can be performed by using
the mouse and by typing (case sensitive) keystrokes in the GLVis window. Below
is a partial list of the available functionality. Some of these keys can also be
provided as input, using the `-k` command-line option and the `keys` script
command.
For high-order meshes and/or solution data, GLVis performs element subdivision
to try to represent the data more accurately. However, for highly-varying data
or large meshes, the auto-selected subdivision factor (see the
[Auto-refinement](#auto-refinement) section below) may not be sufficient -- use
the keys o / O, described below, to manually adjust the
subdivision factor.
SPDX-License-Identifier: BSD-3-Clause
LLNL Release Number: LLNL-CODE-443271
DOI: 10.11578/dc.20171025.1249
Mouse functions
===============
## Basic
- Left – Rotate the viewpoint
- Right – Zoom in (up) / Zoom out (down)
- Middle – Translate the viewpoint
- Left + Shift – Start spinning the viewpoint (according to the dragging vector)
## Advanced
- Left + Alt – Tilt
- Left + Ctrl – Spherical rotation
- Left + Ctrl + Shift – `z`-spinning
- Right + Ctrl – Object scaling (see also [ and ])
- Right + Shift – Change light source position (see \\)
- Middle + Ctrl – Object translation (moves the camera left/right/up/down)
- Middle + Ctrl + Alt – Moves the camera forward/backward (vertical mouse motion) and tilts the camera left/right (horizontal mouse motion)
- Middle + Ctrl + Shift – Object translation (turns the camera left/right/up/down)
Key commands
============
## Basic
- h – Print a short help message in the terminal
- r – Reset the plot to 3D view
- R – Cycle through the six 2D projections (camera looking above/below in `x`/`y`/`z` directions)
- j – Turn on/off perspective
- s – Turn on/off unit cube scaling
- A – Turn on/off the use of anti-aliasing/multi-sampling
- L – Turn on/off logarithmic scale
- c – Toggle the colorbar and caption display state
- C – Change the main plot caption
- p / P – Cycle forward/backwards through color palettes (lots of options, use F6 for a menu)
- t – Cycle materials and lights (5 states)
- i – Toggle cutting plane (different options in 2D and 3D, see below)
- o / O – Control element subdivisions (different options in 2D and 3D, see below)
- l – Turn on/off the light
- g – Toggle background color (white/black)
- a – Toggle the bounding box *axes*. The options are:
- none
- bounding box with coordinates of the corners
- bounding box without coordinates
- red, green, blue colored main `x`, `y`, `z` axes + dashed axes
- m – Toggle the *mesh* state. The options are:
- no mesh or level lines
- draw the element edges (i.e. the mesh)
- draw the level lines (use F5 to modify the level lines)
- e – Toggle the *elements* state (see below for vector functions). The options are:
- show surface elements (corresponding to the function)
- show no surface elements
- (2D only) show element attributes
- (2D only) show element `det(J)`
- (2D only) show element `1/det(J)`
- (2D only) show element `\kappa`
- (2D only) show element `\kappa + 1/\kappa`
- S – Take an image snapshot or record a movie (in spinning mode). By
default, the screenshots are taken in `png` format, using libpng. When GLVis
is compiled with `libtiff` support (see [INSTALL](INSTALL)) then the
screenshots are taken internally and saved in TIFF format (`.tif`
extension). If both of these options are disabled during the build process,
GLVis will use `SDL` to take screenshots in `bmp` format, which it will then
convert to `png` if ImageMagick's `convert` tool is available.
- G – 3D scene export to [glTF format](https://www.khronos.org/gltf)
- Ctrl + p – Print to a PDF file using `gl2ps`. Other
vector formats (SVG, EPS) are also possible, but keep in mind that the
printing takes a while and the generated files are big.
- Q – Cycle between representations of the visualized *quadrature data*. The options are:
- piece-wise constant refined (LOR)
- L2 element dof collocation (interpolation)
- L2 element projection (L2 projection)
- q – Exit
## Advanced
- f – Change the shading type (the way the elements and mesh are drawn). The options are:
- one triangle / quad per element with a constant normal
- one triangle / quad per element with normals averaged at the vertices
- multiple triangles / quads per element, also allowing for the visualization of discontinuous
functions and curvilinear elements (use o / O to control subdivisions)
- \\ – Set light source position (see Right + Shift)
- * / / – Zoom in/out
- + / - – Stretch/compress in `z`-direction
- [ / ] – Shrink/enlarge the bounding box (relative to the colorbar)
- ( / ) – Shrink/enlarge the visualization window
- . – Start/stop `z`-spinning (speed/direction can be controlled with 0 / Enter)
- ←, →, ↑, ↓ – Manual rotation
- 1, 2, 3, 4, 5, 6, 7, 8, 9 – Manual rotation along coordinate axes
- Alt + a – Set axes number format
- Alt + c – Set colorbar number format
- Ctrl + ←, →, ↑, ↓ – Translate the viewpoint
- Ctrl + o – Toggle an element ordering curve
- n / N – Cycle through numberings. The options are:
- none
- show element numbering
- show edge numbering
- show vertex numbering
- ` – Toggle a ruler, with initial origin at the center of the bounding box. The origin can be later moved with ~. The options are:
- none
- coordinate axes lines
- coordinate axes planes
- ~ - Enter new ruler origin
- k / K - Adjust the transparency level. The balance of
transparency can be further adjusted with , and <.
- ! - Toggle the use of (1D) texture (smooth interpolation of colors). The options are:
- use discrete texture, the number of colors used depends on the current palette
- use smooth texture (interpolated from current palette)
- F5 – Change the range and number of the level lines
- F6 – Palette menu (negative repeat number flips the palette)
- F7 – Change the minimum and maximum values
- Shift + F7 – Set the bounding box from the terminal
- Ctrl + a – Cycle through the auto-scaling options:
- `off`: do not change the bounding box and the value range
- `on` (default): recompute both the bounding box and the value range
- `value`: recompute only the value range
- `mesh`: recompute only the bounding box
## 2D scalar data
- i – Toggle cutting (clipping) plane in 2D
- y / Y – Rotate cutting plane (`\theta`) in 2D
- z / Z – Translate cutting plane in 2D
- o / O – Control element subdivisions in 2D
- there are two subdivision factors in this case: element (`s1`) and boundary (`s2`).
- O cycles through the following "subdivision functions", (prints a message in the terminal when changed):
- Increase element subdivision factor: `s1 += s2`
- Decrease element subdivision factor: `s1 -= s2`
- Increase boundary subdivision factor: `s2++`
- Decrease boundary subdivision factor: `s2--`
- o – performs the currently selected function
- b – Toggle the boundary in 2D scalar mode. The options are:
- no boundary
- black boundary
- boundary colored with the boundary attribute
- Use Shift + F9 / F10 to cycle through the boundary attributes.
- F3 / F4 – Shrink/Zoom each element towards its center, in order to better visualize the different element shapes
- F8 – List of material subdomains to show
- F9 / F10 – Walk through material subdomains
- F11 / F12 – Shrink/Zoom material subdomains (to the centers of the attributes)
## 3D scalar data
- i – Toggle cutting (clipping) plane in 3D. The options are:
- none
- cut through the elements
- show only elements behind the cutting plane
- I – Toggle the cutting plane algorithm used when the option *cut through the elements* is selected. The two algorithms are:
- slower, more accurate algorithm for curved meshes (default)
- faster algorithm suitable for meshes with planar faces
- x / X – Rotate cutting plane (`\phi`) in 3D
- y / Y – Rotate cutting plane (`\theta`) in 3D
- z / Z – Translate cutting plane in 3D
- E – Display/Hide the elements in the cutting plane
- M – Display/Hide the mesh in the cutting plane
- o / O – Refine/de-refine elements in 3D
- u / U – Move level surface value up/down
- v / V – Add/Delete a level surface value
- w / W – Move boundary elements up/down in direction of
the normal (i.e. "plot" the boundary values in normal direction)
- F3 / F4 – Shrink/Zoom boundary elements (to the centers of the attributes)
- F8 – List of boundary subdomains to show
- F9 / F10 – Walk through boundary subdomains
- F11 / F12 – Shrink/Zoom material subdomains (to the centers of the attributes)
## 2D vector data
- v – Toggle the *vector* state (uses vector subdivision factor, accept u / U). The options are:
- do not show vectors
- show vectors as displacement
- show vector field; vectors are uniformly scaled; the color varies with the
magnitude (or the current *vector-to-scalar function*, see keys u / U)
- show vector field as above, but the vectors are scaled proportionally to their magnitude
- show vector field; vectors are uniformly scaled; the color is gray; arrows are above the surface
- show vector field as above, but the vectors are scaled proportionally to their magnitude
- V – Change the scaling of the vectors relative to the default
- d – Toggle the *displaced mesh* state: (see also keys n / b). The options are:
- do not show displaced mesh
- show displaced mesh
- assuming displacement field show deformation using Cartesian lines
- assuming displacement field show deformation using polar lines
- n – Increase the displacement amount in 10% steps, wraps around from 100% to 0%
- b – Decrease the displacement amount in 10% steps, wraps around from 0% to 100%
- B – Toggle the boundary in 2D vector mode
- e – Toggle the *elements* state (vector data version). The options are:
- show surface elements corresponding to the current *vector-to-scalar function*
- do not show surface elements
- assuming a displacement field show `det(J)/det(J_d)`
- assuming a displacement field show `det(J_d)/det(J)`
- u / U – Change the *vector-to-scalar function* and the vector subdivision factor
- U – Toggle the functionality of u (prints a message in the terminal when changed). The options are:
- Increase the vector subdivision factor
- Decrease the vector subdivision factor
- Cycle through *vector-to-scalar functions* choices:
- magnitude: `\sqrt{v_x^2+v_y^2}`
- direction from `-\pi` to `\pi`: `atan2(v_y,v_x)`
- `x`-component: `v_x`
- `y`-component: `v_y`
- divergence: `div(v)`
- curl: `curl(v)` [skipped for H(div) elements]
- anisotropy in `grad(v)` [skipped for H(div) elements]
## 3D vector data
- v – Toggle the *vector* state. The options are:
- do not show vectors
- show vectors as displacement
- show vector field; vectors are uniformly scaled; the color varies with the
magnitude (or the current *vector-to-scalar function*, see key F)
- show vector field as above, but the vectors are scaled proportionally to
their magnitude
- show the subset of the vector field with scalar function around a given
value (adjusted with keys u / U and w / W)
- show the vector field restricted to the boundary of the domain
- V – Cycle the *vector* state in the opposite direction of v
- u / U – Move the level field vectors (in the appropriate *vector* state)
- w / W – Add/Delete level field vector (in the appropriate *vector* state)
- d – Toggle the *displaced mesh* state (see also keys n / b). The options are:
- do not show displaced mesh
- show displaced mesh
- n – Increase the displacement amount in 10% steps, wraps around from 100% to 0%
- b – Decrease the displacement amount in 10% steps, wraps around from 0% to 100%
- F – Change the *vector-to-scalar function*. The options are:
- magnitude: `\sqrt{v_x^2+v_y^2+v_z^2}`
- `x`-component: `v_x`
- `y`-component: `v_y`
- `z`-component: `v_z`
## Auto-refinement
The GLVis auto-refinement algorithm selects a subdivision factor trying to
achieve an accurate representation of high-order meshes and solution data while
keeping the initial time to visualize the data reasonable. The algorithm can be
summarized as follows:
- GLVis draws surface elements; the number of drawn elements, `ne`, is either:
- the number of elements in the mesh for 2D meshes (including surface meshes,
i.e. 2D meshes embedded in 3D space), or
- the number of boundary mesh elements described by the mesh in 3D.
- A tentative upper limit on the number of vertices to be drawn is defined based
on the maximum order of the mesh and the solution, `max_order`:
```
max_vert = ne * (max_order + 1) * (max_order + 1)
```
- To allow more accurate representation for small meshes, this number is
potentially increased:
```
max_vert = max(max_vert, 100 000)
```
- To keep the time to initially visualize the data reasonable, this number is
potentially reduced:
```
max_vert = min(max_vert, 2 000 000)
```
- Finally, the subdivision factor `ref` is chosen to be the largest number such
that:
- the number of vertices needed to draw the `ne` surface elements with `ref`
subdivisions does not exceed `max_vert`:
```
ne * (ref + 1) * (ref + 1) <= max_vert
```
- for large meshes where the above limit cannot be satisfied, set `ref = 1`
- for small meshes, avoid excessive refinements:
```
ref <= 16
```
Note that, for highly-varying data or large meshes, this auto-selected
subdivision factor may not be sufficient for accurate representation. In such
cases the subdivision can be manually adjusted using the keys o /
O, described above.
glvis-4.3.2/glvis-keygen.sh 0000775 0000000 0000000 00000025765 14675621442 0015641 0 ustar 00root root 0000000 0000000 #!/bin/bash
# Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-443271.
#
# This file is part of the GLVis visualization tool and library. For more
# information and source code availability see https://glvis.org.
#
# GLVis is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
GLVIS_KEYS_DIR="${HOME}"/.config/glvis
NAME_COMMENT_SERVER="GLVis server key"
NAME_COMMENT_CLIENT="GLVis client key"
function have_command()
{
command -v $1 > /dev/null 2>&1
}
function check_gpg2()
{
if ! have_command ${GPG2}; then
printf "\nThe required command \"${GPG2}\" was not found. Stop.\n\n"
exit 1
fi
}
function check_certtool()
{
if ! have_command ${CERTTOOL}; then
printf "\nThe required command \"${CERTTOOL}\" was not found. Stop.\n\n"
exit 1
fi
if { ${CERTTOOL} --help | head -1 | grep -q GnuTLS; }; then
# newer versions of GnuTLS certtool
return 0
elif { ${CERTTOOL} --version | head -1 | grep -q GnuTLS; }; then
# older versions of GnuTLS certtool
return 0
else
printf "\nThe required command \"${CERTTOOL}\" is not GnuTLS certtool."
printf " Stop.\n\n"
exit 1
fi
}
function gen_keys_gpg2()
{
local IN=""
IN="${IN}Key-Type: RSA\n"
IN="${IN}Key-Length: 2048\n"
IN="${IN}Subkey-Type: RSA\n"
IN="${IN}Subkey-Length: 2048\n"
IN="${IN}Name-Real: "'${NAME_REAL}'"\n"
IN="${IN}Name-Comment: "'${NAME_COMMENT}'"\n"
IN="${IN}Name-Email: "'${NAME_EMAIL}'"\n"
IN="${IN}Expire-Date: 0\n"
IN="${IN}%%no-protection\n" # for gpg2 version >= 2.1
IN="${IN}%%commit"
IN=$(printf "${IN}")
eval "IN=\"${IN}\""
# printf "%s\n" "${IN}"
local GPG2_ARGS=("--homedir" "${KEY_DIR}" "--batch" "--gen-key" "-")
printf "%s\n" "${IN}" | ${GPG2} "${GPG2_ARGS[@]}"
}
function gen_keys_certtool()
{
local CT="${CERTTOOL}" ROLE="$1" IN=""
cd "${KEY_DIR}" || return 1
# Generate user CA key
$CT --generate-privkey --outfile ca-key.pem || return 1
# Generate self-signed user CA certificate
IN="cn = \"${NAME_REAL}'s GLVis ${ROLE} CA Certificate\"\n"
IN="${IN}email = \"${NAME_EMAIL}\"\n"
IN="${IN}expiration_days = 3651\n"
IN="${IN}ca\n"
IN="${IN}cert_signing_key\n"
printf "$IN" > ca-cert.cfg
$CT --generate-self-signed --load-privkey ca-key.pem \
--outfile ca-cert.pem --template ca-cert.cfg \
> ca-cert.txt 2>&1 || return 1
rm -f ca-cert.cfg ca-cert.txt
# Generate user key
$CT --generate-privkey --outfile key.pem || return 1
# Generate user certificate signed with the CA key & certificate
IN="cn = \"${NAME_REAL}'s GLVis ${ROLE} Certificate\"\n"
IN="${IN}email = \"${NAME_EMAIL}\"\n"
IN="${IN}expiration_days = 3650\n"
IN="${IN}signing_key\n"
IN="${IN}encryption_key\n"
if [ "${ROLE}" == "Client" ]; then
IN="${IN}tls_www_client\n"
else
IN="${IN}tls_www_server\n"
fi
printf "$IN" > cert.cfg
$CT --generate-certificate --load-privkey key.pem \
--outfile cert.pem --load-ca-certificate ca-cert.pem \
--load-ca-privkey ca-key.pem --template cert.cfg \
> cert.txt 2>&1 || return 1
rm -f cert.cfg cert.txt
}
function check_keys_gpg2()
{
if [ -s "${GLVIS_KEYS_DIR}"/server/pubring.gpg ] && \
[ -s "${GLVIS_KEYS_DIR}"/server/secring.gpg ]; then
GEN_SERVER_KEY="NO"
fi
if [ -s "${GLVIS_KEYS_DIR}"/client/pubring.gpg ] && \
[ -s "${GLVIS_KEYS_DIR}"/client/secring.gpg ]; then
GEN_CLIENT_KEY="NO"
fi
if [ -s "${GLVIS_KEYS_DIR}"/client/trusted-servers.gpg ]; then
ADD_SERVER_KEY="NO"
fi
if [ -s "${GLVIS_KEYS_DIR}"/server/trusted-clients.gpg ]; then
ADD_CLIENT_KEY="NO"
fi
}
function check_keys_certtool()
{
if [ -s "${GLVIS_KEYS_DIR}"/server/cert.pem ] && \
[ -s "${GLVIS_KEYS_DIR}"/server/key.pem ]; then
GEN_SERVER_KEY="NO"
fi
if [ -s "${GLVIS_KEYS_DIR}"/client/cert.pem ] && \
[ -s "${GLVIS_KEYS_DIR}"/client/key.pem ]; then
GEN_CLIENT_KEY="NO"
fi
if [ -s "${GLVIS_KEYS_DIR}"/client/trusted-servers.pem ]; then
ADD_SERVER_KEY="NO"
fi
if [ -s "${GLVIS_KEYS_DIR}"/server/trusted-clients.pem ]; then
ADD_CLIENT_KEY="NO"
fi
}
# $1 - scr dir, $2 - dest dir
function add_keys_gpg2()
{
cd "${GLVIS_KEYS_DIR}" && \
${GPG2} --homedir "${GLVIS_KEYS_DIR}"/$1 --export --armor \
--output "$1.asc" && \
${GPG2} --homedir "${GLVIS_KEYS_DIR}"/$2 --no-default-keyring \
--keyring "trusted-${1}s.gpg" --import "$1.asc"
}
# $1 - scr dir, $2 - dest dir
add_keys_certtool()
{
cd "${GLVIS_KEYS_DIR}" && \
cp -fp $1/ca-cert.pem $2/trusted-${1}s.pem
}
function list_keys_gpg2()
{
# ${GPG2} --homedir "${GLVIS_KEYS_DIR}"/server --list-secret-keys
if [ -s "${GLVIS_KEYS_DIR}"/server/trusted-clients.gpg ]; then
${GPG2} --homedir "${GLVIS_KEYS_DIR}"/server \
--keyring "trusted-clients.gpg" --list-public-keys
else
printf "Server/trusted-client keys not found.\n"
fi
# ${GPG2} --homedir "${GLVIS_KEYS_DIR}"/client --list-secret-keys
if [ -s "${GLVIS_KEYS_DIR}"/client/trusted-servers.gpg ]; then
${GPG2} --homedir "${GLVIS_KEYS_DIR}"/client \
--keyring "trusted-servers.gpg" --list-public-keys
else
printf "Client/trusted-server keys not found.\n"
fi
}
function list_keys_certtool()
{
local CT="${CERTTOOL}"
local sc="${GLVIS_KEYS_DIR}"/server/cert.pem sn="Server certificate"
local cc="${GLVIS_KEYS_DIR}"/client/cert.pem cn="Client certificate"
if [ -s "$sc" ]; then
echo "$sn:"
echo "-------------------"
$CT --certificate-info --infile "$sc"
else
printf "$sn not found.\n"
fi
echo
if [ -s "$cc" ]; then
echo "$cn:"
echo "-------------------"
$CT --certificate-info --infile "$cc"
else
printf "$cn not found.\n"
fi
}
function read_name_email()
{
NAME_REAL="$1"
NAME_EMAIL="$2"
if [ "${NAME_REAL}" == "" ]; then
if [ -t 0 ]; then
if [ -s "${HOME}"/.gitconfig ] && have_command git; then
FULL_NAME=$(git config user.name)
elif [ $(uname -s) == "Darwin" ]; then
FULL_NAME=$(id -P ${USER} | awk -F: '{print $8}')
elif have_command getent; then
FULL_NAME=$(getent passwd ${USER} | awk -F: '{print $5}')
else
FULL_NAME=${USER}
fi
read -p "Enter your name [${FULL_NAME}]: " NAME_REAL
if [ "${NAME_REAL}" == "" ]; then
NAME_REAL="${FULL_NAME}"
fi
else
return 1
fi
fi
if [ "${NAME_EMAIL}" == "" ]; then
if [ -t 0 ]; then
if [ -s "${HOME}"/.gitconfig ] && have_command git; then
FULL_EMAIL=$(git config user.email)
else
FULL_EMAIL="${USER}@${HOST}"
fi
read -p "Enter your email [${FULL_EMAIL}]: " NAME_EMAIL
if [ "${NAME_EMAIL}" == "" ]; then
NAME_EMAIL="${FULL_EMAIL}"
fi
else
return 1
fi
fi
}
function print_usage()
{
printf "Usage:\n"
printf " $0 {-h|--help}\n"
printf " $0 [=]... {-l|--list}\n"
printf " $0 [=]... [\"Your Name\"] [\"Your Email\"]\n"
printf "Valid variables:\n"
printf " keytype={x509|gpg} (current value: ${KEYTYPE})\n"
printf " certtool= (current value: ${CERTTOOL}"
printf ", keytype: x509)\n"
printf " gpg2= (current value: ${GPG2}"
printf ", keytype: gpg)\n"
}
function select_params()
{
# Key generation programs: gpg2, certtool
GPG2=${gpg2:-gpg2}
case "$OSTYPE" in
darwin*)
CERTTOOL=${certtool:-gnutls-certtool}
;;
*)
CERTTOOL=${certtool:-certtool}
;;
esac
# Key type to generate: gpg or x509
KEYTYPE=${keytype:-x509}
case "$KEYTYPE" in
gpg)
keytype_prog=gpg2
;;
x509)
keytype_prog=certtool
;;
*)
printf "\nInvalid keytype: '${KEYTYPE}'. Stop.\n\n"
exit 1
;;
esac
}
while [ $# -gt 0 ]; do
case "$1" in
-h|--help)
select_params
print_usage
exit 0
;;
-l|--list)
select_params
check_$keytype_prog
echo
list_keys_$keytype_prog
exit 0
;;
-*)
printf "Unknown option: '$1'. Stop.\n\n"
exit 1
;;
*=*)
eval $1
shift
;;
*)
break
;;
esac
done
select_params
GEN_SERVER_KEY="YES"
GEN_CLIENT_KEY="YES"
ADD_SERVER_KEY="YES"
ADD_CLIENT_KEY="YES"
check_keys_$keytype_prog
if [ "${GEN_SERVER_KEY}" == "YES" ] || [ "${GEN_CLIENT_KEY}" == "YES" ]; then
check_$keytype_prog
if ! read_name_email "$@"; then
print_usage
exit 1
fi
elif [ "${ADD_SERVER_KEY}" == "YES" ] || [ "${ADD_CLIENT_KEY}" == "YES" ]; then
check_$keytype_prog
fi
echo
if [ "${GEN_SERVER_KEY}" == "NO" ]; then
printf "Server key exists.\n\n"
else
printf "\r---------------------------\n"
printf " Generating server key\n"
printf "\r---------------------------\n"
NAME_COMMENT="${NAME_COMMENT_SERVER}"
KEY_DIR="${GLVIS_KEYS_DIR}"/server
echo mkdir -p "${KEY_DIR}"
mkdir -p "${KEY_DIR}"
if ! gen_keys_$keytype_prog "Server"; then
printf "\nGeneration failed. Stop.\n\n"
exit 1
fi
printf "\r---------------------------\n\n"
fi
if [ "${GEN_CLIENT_KEY}" == "NO" ]; then
printf "Client key exists.\n\n"
else
printf "\r---------------------------\n"
printf " Generating client key\n"
printf "\r---------------------------\n"
NAME_COMMENT="${NAME_COMMENT_CLIENT}"
KEY_DIR="${GLVIS_KEYS_DIR}"/client
echo mkdir -p "${KEY_DIR}"
mkdir -p "${KEY_DIR}"
if ! gen_keys_$keytype_prog "Client"; then
printf "\nGeneration failed. Stop.\n\n"
exit 1
fi
printf "\r---------------------------\n\n"
fi
if [ "${ADD_SERVER_KEY}" == "NO" ]; then
printf "Client's trusted-servers keyring exists.\n\n"
else
printf "\r-------------------------------------------------------\n"
printf " Adding the server key to the client's trusted-servers\n"
printf "\r-------------------------------------------------------\n"
if ! add_keys_$keytype_prog "server" "client"; then
printf "\nOperation failed. Stop.\n\n"
exit 1
fi
printf "\r-------------------------------------------------------\n\n"
fi
if [ "${ADD_CLIENT_KEY}" == "NO" ]; then
printf "Server's trusted-clients keyring exists.\n\n"
else
printf "\r-------------------------------------------------------\n"
printf " Adding the client key to the server's trusted-clients\n"
printf "\r-------------------------------------------------------\n"
if ! add_keys_$keytype_prog "client" "server"; then
printf "\nOperation failed. Stop.\n\n"
exit 1
fi
printf "\r-------------------------------------------------------\n\n"
fi
glvis-4.3.2/glvis.cpp 0000664 0000000 0000000 00000156072 14675621442 0014522 0 ustar 00root root 0000000 0000000 // Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-443271.
//
// This file is part of the GLVis visualization tool and library. For more
// information and source code availability see https://glvis.org.
//
// GLVis is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
// GLVis - an OpenGL visualization server based on the MFEM library
#include
#include
#include
#include
#include
#include
#include
// SDL may redefine main() as SDL_main() ostensibly to ease portability.
// (WinMain() instead of main() is used as the entry point in a non-console
// Windows program.)
//
// We must instead define SDL_MAIN_HANDLED so that SDL doesn't do this
// substitution, since we need a console to accept certain user input from
// stdin.
#ifdef _WIN32
#define SDL_MAIN_HANDLED
#endif
#include "mfem.hpp"
#include "lib/palettes.hpp"
#include "lib/visual.hpp"
#include "lib/stream_reader.hpp"
using namespace std;
using namespace mfem;
const char *string_none = "(none)";
const char *string_default = "(default)";
// Global variables for command line arguments
const char *mesh_file = string_none;
const char *sol_file = string_none;
const char *vec_sol_file = string_none;
const char *gfunc_file = string_none;
const char *qfunc_file = string_none;
const char *arg_keys = string_none;
int pad_digits = 6;
int gf_component = -1;
int qf_component = -1;
int window_x = 0; // not a command line option
int window_y = 0; // not a command line option
int window_w = 400;
int window_h = 350;
const char *window_title = string_default;
const char *c_plot_caption = string_none;
thread_local string plot_caption;
thread_local string extra_caption;
bool secure = socketstream::secure_default;
// Global variables
enum InputOptions
{
INPUT_SERVER_MODE = 1,
INPUT_MESH = 2,
INPUT_SCALAR_SOL = 4,
INPUT_VECTOR_SOL = 8,
//...
INPUT_PARALLEL = 256,
};
int input = INPUT_SERVER_MODE;
thread_local StreamState stream_state;
thread_local VisualizationSceneScalarData *vs = NULL;
extern thread_local GLVisCommand* glvis_command;
thread_local communication_thread *comm_thread = NULL;
thread_local GeometryRefiner GLVisGeometryRefiner;
const char *window_titles[] = { "GLVis [scalar data]",
"GLVis [vector data]",
"GLVis [mesh]"
};
istream *script = NULL;
int scr_running = 0;
int scr_level = 0;
Vector *init_nodes = NULL;
double scr_min_val, scr_max_val;
extern char **environ;
void PrintSampleUsage(ostream &out);
// read the mesh and the solution from a file
void ReadSerial(StreamState& state);
// choose grid function component and set the input flag
void SetGridFunction(StreamState& state);
// choose quadrature function component and set the input flag
void SetQuadFunction(StreamState& state);
// read the mesh and the solution from multiple files
void ReadParallel(int np, StreamState& state);
int ReadParMeshAndGridFunction(int np, const char *mesh_prefix,
const char *sol_prefix, StreamState& state);
int ReadParMeshAndQuadFunction(int np, const char *mesh_prefix,
const char *sol_prefix, StreamState& state);
// switch representation of the quadrature function
void SwitchQuadSolution();
// Visualize the data in the global variables mesh, sol/grid_f, etc
bool GLVisInitVis(StreamState::FieldType field_type,
StreamCollection input_streams)
{
if (field_type <= StreamState::FieldType::MIN
|| field_type >= StreamState::FieldType::MAX)
{
return false;
}
const char *win_title = (window_title == string_default) ?
window_titles[(int)field_type] : window_title;
if (InitVisualization(win_title, window_x, window_y, window_w, window_h))
{
cerr << "Initializing the visualization failed." << endl;
return false;
}
if (input_streams.size() > 0)
{
GetAppWindow()->setOnKeyDown(SDLK_SPACE, ThreadsPauseFunc);
glvis_command = new GLVisCommand(&vs, stream_state, &stream_state.keep_attr);
comm_thread = new communication_thread(std::move(input_streams), glvis_command);
}
if (stream_state.quad_f)
{
GetAppWindow()->setOnKeyDown('Q', SwitchQuadSolution);
}
double mesh_range = -1.0;
if (field_type == StreamState::FieldType::SCALAR
|| field_type == StreamState::FieldType::MESH)
{
if (stream_state.grid_f)
{
stream_state.grid_f->GetNodalValues(stream_state.sol);
}
if (stream_state.mesh->SpaceDimension() == 2)
{
VisualizationSceneSolution * vss;
if (stream_state.normals.Size() > 0)
{
vs = vss = new VisualizationSceneSolution(*stream_state.mesh, stream_state.sol,
stream_state.mesh_quad.get(), &stream_state.normals);
}
else
{
vs = vss = new VisualizationSceneSolution(*stream_state.mesh, stream_state.sol,
stream_state.mesh_quad.get());
}
if (stream_state.grid_f)
{
vss->SetGridFunction(*stream_state.grid_f);
}
if (field_type == StreamState::FieldType::MESH)
{
vs->OrthogonalProjection = 1;
vs->SetLight(false);
vs->Zoom(1.8);
// Use the 'bone' palette when visualizing a 2D mesh only (otherwise
// the 'jet-like' palette is used in 2D, see vssolution.cpp).
vs->palette.SetIndex(4);
}
}
else if (stream_state.mesh->SpaceDimension() == 3)
{
VisualizationSceneSolution3d * vss;
vs = vss = new VisualizationSceneSolution3d(*stream_state.mesh,
stream_state.sol, stream_state.mesh_quad.get());
if (stream_state.grid_f)
{
vss->SetGridFunction(stream_state.grid_f.get());
}
if (field_type == StreamState::FieldType::MESH)
{
if (stream_state.mesh->Dimension() == 3)
{
// Use the 'white' palette when visualizing a 3D volume mesh only
vss->palette.SetIndex(11);
vss->SetLightMatIdx(4);
}
else
{
// Use the 'bone' palette when visualizing a surface mesh only
vss->palette.SetIndex(4);
}
// Otherwise, the 'vivid' palette is used in 3D see vssolution3d.cpp
vss->ToggleDrawAxes();
vss->ToggleDrawMesh();
}
}
if (field_type == StreamState::FieldType::MESH)
{
if (stream_state.grid_f)
{
mesh_range = stream_state.grid_f->Max() + 1.0;
}
else
{
mesh_range = stream_state.sol.Max() + 1.0;
}
}
}
else if (field_type == StreamState::FieldType::VECTOR)
{
if (stream_state.mesh->SpaceDimension() == 2)
{
if (stream_state.grid_f)
{
vs = new VisualizationSceneVector(*stream_state.grid_f);
}
else
{
vs = new VisualizationSceneVector(*stream_state.mesh, stream_state.solu,
stream_state.solv, stream_state.mesh_quad.get());
}
}
else if (stream_state.mesh->SpaceDimension() == 3)
{
if (stream_state.grid_f)
{
stream_state.ProjectVectorFEGridFunction();
vs = new VisualizationSceneVector3d(*stream_state.grid_f,
stream_state.mesh_quad.get());
}
else
{
vs = new VisualizationSceneVector3d(*stream_state.mesh, stream_state.solu,
stream_state.solv, stream_state.solw,
stream_state.mesh_quad.get());
}
}
}
if (vs)
{
// increase the refinement factors if visualizing a GridFunction
if (stream_state.grid_f)
{
vs->AutoRefine();
vs->SetShading(VisualizationSceneScalarData::Shading::Noncomforming, true);
}
if (mesh_range > 0.0)
{
vs->SetValueRange(-mesh_range, mesh_range);
vs->SetAutoscale(0);
}
if (stream_state.mesh->SpaceDimension() == 2
&& field_type == StreamState::FieldType::MESH)
{
SetVisualizationScene(vs, 2, stream_state.keys.c_str());
}
else
{
SetVisualizationScene(vs, 3, stream_state.keys.c_str());
}
}
return true;
}
void GLVisStartVis()
{
RunVisualization(); // deletes vs
vs = NULL;
if (glvis_command)
{
glvis_command->Terminate();
delete comm_thread;
delete glvis_command;
glvis_command = NULL;
}
cout << "GLVis window closed." << endl;
}
int ScriptReadSolution(istream &scr, StreamState& state)
{
string mword,sword;
cout << "Script: solution: " << flush;
// read the mesh
scr >> ws >> mword; // mesh filename (can't contain spaces)
cout << "mesh: " << mword << "; " << flush;
named_ifgzstream imesh(mword.c_str());
if (!imesh)
{
cout << "Can not open mesh file: " << mword << endl;
return 1;
}
state.SetMesh(new Mesh(imesh, 1, 0, state.fix_elem_orient));
// read the solution (GridFunction)
scr >> ws >> sword;
if (sword == mword) // mesh and solution in the same file
{
cout << "solution: " << mword << endl;
state.SetGridFunction(new GridFunction(state.mesh.get(), imesh));
}
else
{
cout << "solution: " << sword << endl;
ifgzstream isol(sword.c_str());
if (!isol)
{
cout << "Can not open solution file: " << sword << endl;
return 2;
}
state.SetGridFunction(new GridFunction(state.mesh.get(), isol));
}
state.Extrude1DMeshAndSolution();
return 0;
}
int ScriptReadQuadrature(istream &scr, StreamState& state)
{
string mword,sword;
cout << "Script: quadrature: " << flush;
// read the mesh
scr >> ws >> mword; // mesh filename (can't contain spaces)
cout << "mesh: " << mword << "; " << flush;
named_ifgzstream imesh(mword.c_str());
if (!imesh)
{
cout << "Can not open mesh file: " << mword << endl;
return 1;
}
state.SetMesh(new Mesh(imesh, 1, 0, state.fix_elem_orient));
// read the quadrature (QuadratureFunction)
scr >> ws >> sword;
if (sword == mword) // mesh and quadrature in the same file
{
cout << "quadrature: " << mword << endl;
state.SetQuadFunction(new QuadratureFunction(state.mesh.get(), imesh));
}
else
{
cout << "quadrature: " << sword << endl;
ifgzstream isol(sword.c_str());
if (!isol)
{
cout << "Can not open quadrature file: " << sword << endl;
return 2;
}
state.SetQuadFunction(new QuadratureFunction(state.mesh.get(), isol));
}
state.SetQuadSolution();
state.Extrude1DMeshAndSolution();
return 0;
}
int ScriptReadParSolution(istream &scr, StreamState& state)
{
int np, scr_keep_attr, err_read;
string mesh_prefix, sol_prefix;
cout << "Script: psolution: " << flush;
// read number of processors
scr >> np;
cout << "# processors: " << np << "; " << flush;
// read the mesh prefix
scr >> ws >> mesh_prefix; // mesh prefix (can't contain spaces)
cout << "mesh prefix: " << mesh_prefix << "; " << flush;
scr >> ws >> scr_keep_attr;
if (scr_keep_attr)
{
cout << "(real attributes); " << flush;
}
else
{
cout << "(processor attributes); " << flush;
}
// read the solution prefix
scr >> ws >> sol_prefix;
cout << "solution prefix: " << sol_prefix << endl;
err_read = ReadParMeshAndGridFunction(np, mesh_prefix.c_str(),
sol_prefix.c_str(), state);
if (!err_read)
{
state.Extrude1DMeshAndSolution();
}
return err_read;
}
int ScriptReadParQuadrature(istream &scr, StreamState& state)
{
int np, scr_keep_attr, err_read;
string mesh_prefix, quad_prefix;
cout << "Script: pquadrature: " << flush;
// read number of processors
scr >> np;
cout << "# processors: " << np << "; " << flush;
// read the mesh prefix
scr >> ws >> mesh_prefix; // mesh prefix (can't contain spaces)
cout << "mesh prefix: " << mesh_prefix << "; " << flush;
scr >> ws >> scr_keep_attr;
if (scr_keep_attr)
{
cout << "(real attributes); " << flush;
}
else
{
cout << "(processor attributes); " << flush;
}
// read the quadrature prefix
scr >> ws >> quad_prefix;
cout << "quadrature prefix: " << quad_prefix << endl;
err_read = ReadParMeshAndQuadFunction(np, mesh_prefix.c_str(),
quad_prefix.c_str(), state);
if (!err_read)
{
state.SetQuadSolution();
state.Extrude1DMeshAndSolution();
}
return err_read;
}
int ScriptReadDisplMesh(istream &scr, StreamState& state)
{
StreamState meshstate;
string word;
cout << "Script: mesh: " << flush;
scr >> ws >> word;
{
named_ifgzstream imesh(word.c_str());
if (!imesh)
{
cout << "Can not open mesh file: " << word << endl;
return 1;
}
cout << word << endl;
meshstate.SetMesh(new Mesh(imesh, 1, 0, state.fix_elem_orient));
}
meshstate.Extrude1DMeshAndSolution();
Mesh* const m = meshstate.mesh.get();
if (init_nodes == NULL)
{
init_nodes = new Vector;
meshstate.mesh->GetNodes(*init_nodes);
state.SetMesh(NULL);
state.SetGridFunction(NULL);
}
else
{
FiniteElementCollection *vfec = NULL;
FiniteElementSpace *vfes;
vfes = (FiniteElementSpace *)m->GetNodalFESpace();
if (vfes == NULL)
{
vfec = new LinearFECollection;
vfes = new FiniteElementSpace(m, vfec, m->SpaceDimension());
}
meshstate.SetGridFunction(new GridFunction(vfes));
GridFunction * const g = meshstate.grid_f.get();
if (vfec)
{
g->MakeOwner(vfec);
}
m->GetNodes(*g);
if (g->Size() == init_nodes->Size())
{
subtract(*init_nodes, *g, *g);
}
else
{
cout << "Script: incompatible meshes!" << endl;
*g = 0.0;
}
state = std::move(meshstate);
}
return 0;
}
void ExecuteScriptCommand()
{
if (!script)
{
cout << "No script stream defined! (Bug?)" << endl;
return;
}
istream &scr = *script;
string word;
int done_one_command = 0;
while (!done_one_command)
{
scr >> ws;
if (!scr.good())
{
cout << "End of script." << endl;
scr_level = 0;
return;
}
if (scr.peek() == '#')
{
getline(scr, word);
continue;
}
scr >> word;
if (word == "{")
{
scr_level++;
}
else if (word == "}")
{
scr_level--;
if (scr_level < 0)
{
scr_level = 0;
}
}
else if (word == "solution" || word == "mesh" || word == "psolution"
|| word == "quadrature" || word == "pquadrature")
{
StreamState new_state;
if (word == "solution")
{
if (ScriptReadSolution(scr, new_state))
{
done_one_command = 1;
continue;
}
}
else if (word == "quadrature")
{
if (ScriptReadQuadrature(scr, new_state))
{
done_one_command = 1;
continue;
}
}
else if (word == "mesh")
{
if (ScriptReadDisplMesh(scr, new_state))
{
done_one_command = 1;
continue;
}
if (new_state.mesh == NULL)
{
cout << "Script: unexpected 'mesh' command!" << endl;
done_one_command = 1;
continue;
}
}
else if (word == "psolution")
{
if (ScriptReadParSolution(scr, new_state))
{
done_one_command = 1;
continue;
}
}
else if (word == "pquadrature")
{
if (ScriptReadParQuadrature(scr, new_state))
{
done_one_command = 1;
continue;
}
}
if (stream_state.SetNewMeshAndSolution(std::move(new_state), vs))
{
MyExpose();
}
else
{
cout << "Different type of mesh / solution." << endl;
}
}
else if (word == "screenshot")
{
scr >> ws >> word;
cout << "Script: screenshot: " << flush;
if (Screenshot(word.c_str(), true))
{
cout << "Screenshot(" << word << ") failed." << endl;
done_one_command = 1;
continue;
}
cout << "-> " << word << endl;
if (scr_min_val > vs->GetMinV())
{
scr_min_val = vs->GetMinV();
}
if (scr_max_val < vs->GetMaxV())
{
scr_max_val = vs->GetMaxV();
}
}
else if (word == "viewcenter")
{
scr >> vs->ViewCenterX >> vs->ViewCenterY;
cout << "Script: viewcenter: "
<< vs->ViewCenterX << ' ' << vs->ViewCenterY << endl;
MyExpose();
}
else if (word == "perspective")
{
scr >> ws >> word;
cout << "Script: perspective: " << word;
if (word == "off")
{
vs->OrthogonalProjection = 1;
}
else if (word == "on")
{
vs->OrthogonalProjection = 0;
}
else
{
cout << '?';
}
cout << endl;
MyExpose();
}
else if (word == "light")
{
scr >> ws >> word;
cout << "Script: light: " << word;
if (word == "off")
{
vs->SetLight(false);
}
else if (word == "on")
{
vs->SetLight(true);
}
else
{
cout << '?';
}
cout << endl;
MyExpose();
}
else if (word == "view")
{
double theta, phi;
scr >> theta >> phi;
cout << "Script: view: " << theta << ' ' << phi << endl;
vs->SetView(theta, phi);
MyExpose();
}
else if (word == "zoom")
{
double factor;
scr >> factor;
cout << "Script: zoom: " << factor << endl;
vs->Zoom(factor);
MyExpose();
}
else if (word == "shading")
{
scr >> ws >> word;
cout << "Script: shading: " << flush;
VisualizationSceneScalarData::Shading s =
VisualizationSceneScalarData::Shading::Invalid;
if (word == "flat")
{
s = VisualizationSceneScalarData::Shading::Flat;
}
else if (word == "smooth")
{
s = VisualizationSceneScalarData::Shading::Smooth;
}
else if (word == "cool")
{
s = VisualizationSceneScalarData::Shading::Noncomforming;
}
if (s != VisualizationSceneScalarData::Shading::Invalid)
{
vs->SetShading(s, false);
cout << word << endl;
MyExpose();
}
else
{
cout << word << " ?" << endl;
}
}
else if (word == "subdivisions")
{
int t, b;
scr >> t >> b;
cout << "Script: subdivisions: " << flush;
vs->SetRefineFactors(t, b);
cout << t << ' ' << b << endl;
MyExpose();
}
else if (word == "valuerange")
{
double min, max;
scr >> min >> max;
cout << "Script: valuerange: " << flush;
vs->SetValueRange(min, max);
cout << min << ' ' << max << endl;
MyExpose();
}
else if (word == "autoscale")
{
scr >> ws >> word;
cout << "Script: autoscale: " << word;
if (word == "off")
{
vs->SetAutoscale(0);
}
else if (word == "on")
{
vs->SetAutoscale(1);
}
else if (word == "value")
{
vs->SetAutoscale(2);
}
else if (word == "mesh")
{
vs->SetAutoscale(3);
}
else
{
cout << '?';
}
cout << endl;
}
else if (word == "levellines")
{
double min, max;
int num;
scr >> min >> max >> num;
cout << "Script: levellines: " << flush;
vs->SetLevelLines(min, max, num);
vs->UpdateLevelLines();
cout << min << ' ' << max << ' ' << num << endl;
MyExpose();
}
else if (word == "axis_numberformat")
{
char delim;
string axis_formatting;
scr >> ws >> delim;
getline(scr, axis_formatting, delim);
cout << "Script: axis_numberformat: " << flush;
vs->SetAxisNumberFormat(axis_formatting);
cout << axis_formatting << endl;
MyExpose();
}
else if (word == "colorbar_numberformat")
{
char delim;
string colorbar_formatting;
scr >> ws >> delim;
getline(scr, colorbar_formatting, delim);
cout << "Script: colorbar_numberformat: " << flush;
vs->SetColorbarNumberFormat(colorbar_formatting);
cout << colorbar_formatting << endl;
MyExpose();
}
else if (word == "window")
{
scr >> window_x >> window_y >> window_w >> window_h;
cout << "Script: window: " << window_x << ' ' << window_y
<< ' ' << window_w << ' ' << window_h << endl;
MoveResizeWindow(window_x, window_y, window_w, window_h);
MyExpose();
}
else if (word == "keys")
{
scr >> stream_state.keys;
cout << "Script: keys: '" << stream_state.keys << "'" << endl;
// SendKeySequence(keys.c_str());
CallKeySequence(stream_state.keys.c_str());
MyExpose();
}
else if (word == "palette")
{
int pal;
scr >> pal;
cout << "Script: palette: " << pal << endl;
vs->palette.SetIndex(pal-1);
MyExpose();
}
else if (word == "palette_repeat")
{
int rpt_times;
scr >> rpt_times;
cout << "Script: palette_repeat: " << rpt_times << endl;
vs->palette.SetRepeatTimes(rpt_times);
vs->palette.Init();
MyExpose();
}
else if (word == "toggle_attributes")
{
Array attr_list;
cout << "Script: toggle_attributes:";
for (scr >> ws; scr.peek() != ';'; scr >> ws)
{
attr_list.Append(0);
scr >> attr_list.Last();
if (attr_list.Size() <= 256)
{
cout << ' ' << attr_list.Last();
}
else if (attr_list.Size() == 257)
{
cout << " ... " << flush;
}
}
scr.get(); // read the end symbol: ';'
cout << endl;
vs->ToggleAttributes(attr_list);
MyExpose();
}
else if (word == "rotmat")
{
cout << "Script: rotmat:";
for (int i = 0; i < 16; i++)
{
scr >> vs->rotmat[i/4][i%4];
cout << ' ' << vs->rotmat[i/4][i%4];
}
cout << endl;
MyExpose();
}
else if (word == "camera")
{
double cam[9];
cout << "Script: camera:";
for (int i = 0; i < 9; i++)
{
scr >> cam[i];
cout << ' ' << cam[i];
}
cout << endl;
vs->cam.Set(cam);
MyExpose();
}
else if (word == "scale")
{
double scale;
cout << "Script: scale:";
scr >> scale;
cout << ' ' << scale;
cout << endl;
vs->Scale(scale);
MyExpose();
}
else if (word == "translate")
{
double x, y, z;
cout << "Script: translate:";
scr >> x >> y >> z;
cout << ' ' << x << ' ' << y << ' ' << z;
cout << endl;
vs->Translate(x, y, z);
MyExpose();
}
else if (word == "plot_caption")
{
char delim;
scr >> ws >> delim;
getline(scr, plot_caption, delim);
vs->PrepareCaption(); // turn on or off the caption
MyExpose();
}
else
{
cout << "Unknown command in script: " << word << endl;
}
done_one_command = 1;
}
}
void ScriptControl();
void ScriptIdleFunc()
{
ExecuteScriptCommand();
if (scr_level == 0)
{
ScriptControl();
}
}
void ScriptControl()
{
if (scr_running)
{
scr_running = 0;
RemoveIdleFunc(ScriptIdleFunc);
}
else
{
scr_running = 1;
AddIdleFunc(ScriptIdleFunc);
}
}
void PlayScript(istream &scr)
{
string word;
scr_min_val = numeric_limits::infinity();
scr_max_val = -scr_min_val;
// read initializing commands
while (1)
{
scr >> ws;
if (!scr.good())
{
cout << "Error in script" << endl;
return;
}
if (scr.peek() == '#')
{
getline(scr, word);
continue;
}
scr >> word;
if (word == "window")
{
scr >> window_x >> window_y >> window_w >> window_h;
}
else if (word == "solution")
{
if (ScriptReadSolution(scr, stream_state))
{
return;
}
// start the visualization
break;
}
else if (word == "quadrature")
{
if (ScriptReadQuadrature(scr, stream_state))
{
return;
}
// start the visualization
break;
}
else if (word == "psolution")
{
if (ScriptReadParSolution(scr, stream_state))
{
return;
}
// start the visualization
break;
}
else if (word == "pquadrature")
{
if (ScriptReadParQuadrature(scr, stream_state))
{
return;
}
// start the visualization
break;
}
else if (word == "mesh")
{
if (ScriptReadDisplMesh(scr, stream_state))
{
return;
}
if (stream_state.mesh)
{
break;
}
}
else
{
cout << "Unknown command in script: " << word << endl;
}
}
scr_level = scr_running = 0;
script = &scr;
stream_state.keys.clear();
// Make sure the singleton object returned by GetMainThread() is
// initialized from the main thread.
GetMainThread();
std::thread worker_thread
{
[&](StreamState local_state)
{
// set the thread-local StreamState
stream_state = std::move(local_state);
if (c_plot_caption != string_none)
{
plot_caption = c_plot_caption;
}
if (GLVisInitVis((stream_state.grid_f->VectorDim() == 1) ?
StreamState::FieldType::SCALAR : StreamState::FieldType::VECTOR,
{}))
{
GetAppWindow()->setOnKeyDown(SDLK_SPACE, ScriptControl);
GLVisStartVis();
}
},
std::move(stream_state)
};
SDLMainLoop();
worker_thread.join();
delete init_nodes; init_nodes = NULL;
cout << "Script: min_val = " << scr_min_val
<< ", max_val = " << scr_max_val << endl;
script = NULL;
}
struct Session
{
StreamCollection input_streams;
StreamState state;
StreamState::FieldType ft = StreamState::FieldType::UNKNOWN;
std::thread handler;
Session(bool fix_elem_orient,
bool save_coloring)
{
state.fix_elem_orient = fix_elem_orient;
state.save_coloring = save_coloring;
}
Session(StreamState::FieldType other_ft, StreamState other_state)
: state(std::move(other_state))
, ft(other_ft)
{ }
~Session() = default;
Session(Session&& from) = default;
Session& operator= (Session&& from) = default;
void StartSession()
{
auto funcThread =
[](StreamState thread_state, StreamState::FieldType ftype, StreamCollection is)
{
// Set thread-local stream state
stream_state = std::move(thread_state);
if (c_plot_caption != string_none)
{
plot_caption = c_plot_caption;
}
if (GLVisInitVis(ftype, std::move(is)))
{
GLVisStartVis();
}
};
handler = std::thread {funcThread,
std::move(state), ft, std::move(input_streams)};
handler.detach();
}
bool StartSavedSession(std::string stream_file)
{
unique_ptr ifs(new ifstream(stream_file));
if (!(*ifs))
{
cout << "Can not open stream file: " << stream_file << endl;
return false;
}
string data_type;
*ifs >> data_type >> ws;
ft = state.ReadStream(*ifs, data_type);
input_streams.emplace_back(std::move(ifs));
StartSession();
return true;
}
};
void GLVisServer(int portnum, bool save_stream, bool fix_elem_orient,
bool save_coloring)
{
std::vector current_sessions;
string data_type;
int viscount = 0;
unsigned int nproc = 1, proc = 0;
#ifdef MFEM_USE_GNUTLS
unique_ptr state;
unique_ptr params;
if (secure)
{
state.reset(new GnuTLS_global_state);
// state->set_log_level(1000);
string home_dir(getenv("HOME"));
string server_dir = home_dir + "/.config/glvis/server/";
#ifndef MFEM_USE_GNUTLS_X509
string pubkey = server_dir + "pubring.gpg";
string privkey = server_dir + "secring.gpg";
string trustedkeys = server_dir + "trusted-clients.gpg";
#else
string pubkey = server_dir + "cert.pem";
string privkey = server_dir + "key.pem";
string trustedkeys = server_dir + "trusted-clients.pem";
#endif
params.reset(new GnuTLS_session_params(
*state, pubkey.c_str(), privkey.c_str(),
trustedkeys.c_str(), GNUTLS_SERVER));
if (!params->status.good())
{
cout << " public key = " << pubkey << '\n'
<< " private key = " << privkey << '\n'
<< " trusted keys = " << trustedkeys << endl;
cout << "Error setting GLVis server parameters.\n"
"Generate your GLVis keys with:"
" bash glvis-keygen.sh [\"Your Name\"] [\"Your Email\"]"
<< endl;
return;
}
}
#endif
const int backlog = 128;
socketserver server(portnum, backlog);
if (server.good())
{
cout << "Waiting for data on port " << portnum << " ..." << endl;
}
else
{
cout << "Server already running on port " << portnum << ".\n" << endl;
exit(2);
}
while (1)
{
unique_ptr isock;
#ifndef MFEM_USE_GNUTLS
isock.reset(new socketstream);
#else
isock.reset(secure ? new socketstream(*params) : new socketstream(false));
#endif
vector> input_streams;
while (server.accept(*isock) < 0)
{
#ifdef GLVIS_DEBUG
cout << "GLVis: server.accept(...) failed." << endl;
#endif
}
*isock >> data_type >> ws;
if (save_stream)
{
viscount++;
}
int par_data = 0;
if (data_type == "parallel")
{
par_data = 1;
unsigned int np = 0;
do
{
*isock >> nproc >> proc;
#ifdef GLVIS_DEBUG
cout << "new connection: parallel " << nproc << ' ' << proc
<< endl;
#endif
if (np == 0)
{
if (nproc <= 0)
{
cout << "Invalid number of processors: " << nproc << endl;
mfem_error();
}
input_streams.resize(nproc);
}
else
{
if (nproc != input_streams.size())
{
cout << "Unexpected number of processors: " << nproc
<< ", expected: " << input_streams.size() << endl;
mfem_error();
}
}
if (proc >= nproc)
{
cout << "Invalid processor rank: " << proc
<< ", number of processors: " << nproc << endl;
mfem_error();
}
if (input_streams[proc])
{
cout << "Second connection attempt from processor rank: "
<< proc << endl;
mfem_error();
}
input_streams[proc] = std::move(isock);
#ifndef MFEM_USE_GNUTLS
isock.reset(new socketstream);
#else
isock.reset(secure ? new socketstream(*params) :
new socketstream(false));
#endif
np++;
if (np == nproc)
{
break;
}
// read next available socket stream
while (server.accept(*isock) < 0)
{
#ifdef GLVIS_DEBUG
cout << "GLVis: server.accept(...) failed." << endl;
#endif
}
*isock >> data_type >> ws; // "parallel"
if (data_type != "parallel")
{
cout << "Expected keyword \"parallel\", got \"" << data_type
<< '"' << endl;
mfem_error();
}
}
while (1);
}
Session new_session(fix_elem_orient, save_coloring);
constexpr int tmp_filename_size = 50;
char tmp_file[tmp_filename_size];
if (save_stream)
{
snprintf(tmp_file, tmp_filename_size, "glvis-saved.%04d", viscount);
ofstream ofs(tmp_file);
if (!par_data)
{
ofs << data_type << '\n';
ofs << isock->rdbuf();
isock->close();
}
else
{
new_session.state.ReadStreams(input_streams);
new_session.state.WriteStream(ofs);
}
ofs.close();
cout << "Data saved in " << tmp_file << endl;
new_session.StartSavedSession(tmp_file);
}
else
{
if (!par_data)
{
new_session.ft = new_session.state.ReadStream(*isock, data_type);
input_streams.emplace_back(std::move(isock));
}
else
{
new_session.ft = new_session.state.ReadStreams(input_streams);
}
// Pass ownership of input streams into session object
new_session.input_streams = std::move(input_streams);
new_session.StartSession();
}
current_sessions.emplace_back(std::move(new_session));
}
}
int main (int argc, char *argv[])
{
#ifdef _WIN32
// Call needed to avoid SDL_Init failure when not substituting main() for
// SDL_main().
SDL_SetMainReady();
#endif
// variables for command line arguments
int np = 0;
bool save_stream = false;
const char *stream_file = string_none;
const char *script_file = string_none;
const char *font_name = string_default;
int portnum = 19916;
int multisample = GetMultisample();
double line_width = GetLineWidth();
double ms_line_width = GetLineWidthMS();
int geom_ref_type = Quadrature1D::ClosedUniform;
bool legacy_gl_ctx = false;
bool enable_hidpi = true;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to visualize.");
args.AddOption(&gfunc_file, "-g", "--grid-function",
"Solution (GridFunction) file to visualize.");
args.AddOption(&gf_component, "-gc", "--grid-function-component",
"Select a grid function component, [0-) or"
" -1 for all.");
args.AddOption(&qfunc_file, "-q", "--quadrature-function",
"Quadrature function file to visualize.");
args.AddOption(&qf_component, "-qc", "--quadrature-function-component",
"Select a quadrature function component, [0-) or"
" -1 for all.");
args.AddOption(&sol_file, "-s", "--scalar-solution",
"Scalar solution (vertex values) file to visualize.");
args.AddOption(&vec_sol_file, "-v", "--vector-solution",
"Vector solution (vertex values) file to visualize.");
args.AddOption(&np, "-np", "--num-proc",
"Load mesh/solution from multiple processors.");
args.AddOption(&pad_digits, "-d", "--pad-digits",
"Number of digits used for processor ranks in file names.");
args.AddOption(&script_file, "-run", "--run-script",
"Run a GLVis script file.");
args.AddOption(&arg_keys, "-k", "--keys",
"Execute key shortcut commands in the GLVis window.");
args.AddOption(&stream_state.fix_elem_orient, "-fo", "--fix-orientations",
"-no-fo", "--dont-fix-orientations",
"Attempt to fix the orientations of inverted elements.");
args.AddOption(&stream_state.keep_attr, "-a", "--real-attributes",
"-ap", "--processor-attributes",
"When opening a parallel mesh, use the real mesh attributes"
" or replace them with the processor rank.");
args.AddOption(&geom_ref_type, "-grt", "--geometry-refiner-type",
"Set of points to use when refining geometry:"
" 3 = uniform, 1 = Gauss-Lobatto, (see mfem::Quadrature1D).");
args.AddOption(&stream_state.save_coloring, "-sc", "--save-coloring",
"-no-sc", "--dont-save-coloring",
"Save the mesh coloring generated when opening only a mesh.");
args.AddOption(&portnum, "-p", "--listen-port",
"Specify the port number on which to accept connections.");
args.AddOption(&secure, "-sec", "--secure-sockets",
"-no-sec", "--standard-sockets",
"Enable or disable GnuTLS secure sockets.");
args.AddOption(&save_stream, "-save", "--save-stream",
"-no-save", "--dont-save-stream",
"In server mode, save incoming data to a file before"
" visualization.");
args.AddOption(&stream_file, "-saved", "--saved-stream",
"Load a GLVis stream saved to a file.");
args.AddOption(&window_w, "-ww", "--window-width",
"Set the window width.");
args.AddOption(&window_h, "-wh", "--window-height",
"Set the window height.");
args.AddOption(&window_title, "-wt", "--window-title",
"Set the window title.");
args.AddOption(&c_plot_caption, "-c", "--plot-caption",
"Set the plot caption (visible when colorbar is visible).");
args.AddOption(&font_name, "-fn", "--font",
"Set the font: [[:style=