diff --git a/.gitignore b/.gitignore index ff588ebb..87b27a2c 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,12 @@ compile_commands.json # OS-specific: Mac *.dSYM .DS_Store + +# Typical build directory +/build/ + +# Visual Studio Code +/.vscode/ + +# CMake user configuration files +user.cmake diff --git a/CHANGELOG b/CHANGELOG index 15c5e145..8a6a66c1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,13 @@ https://glvis.org +Version 4.5 (development) +========================= + +- Implemented DOF numbering, pressing the `n` or `N` key in 2D mode cycles through: + None → Elements → Edges → Vertices → DOFs. Parallel numbering is now by default + 'local' to each rank; 'global' vs. 'local' numbering can be toggled with 'Alt+n'. + Version 4.4 released on May 1, 2025 =================================== diff --git a/CMakeLists.txt b/CMakeLists.txt index f6c903c3..7e0df6ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ # introduced. cmake_minimum_required(VERSION 3.10) + set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) @@ -24,6 +25,16 @@ endif ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") project(glvis NONE) +# Load user settings +set(USER_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/user.cmake" CACHE PATH + "User configuration file. This file is not part of the GLVis source code and + is not distributed with GLVis. It can be used to set user-specific options, + such as paths to external libraries, compiler flags, etc.") +include("${USER_CONFIG}" OPTIONAL RESULT_VARIABLE USER_CONFIG_LOADED) +if (USER_CONFIG_LOADED) + message(STATUS "USER_CONFIG = ${USER_CONFIG} (LOADED)") +endif() + # 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. diff --git a/README.md b/README.md index ee4c3dee..bef56eeb 100644 --- a/README.md +++ b/README.md @@ -177,9 +177,10 @@ Key commands - 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 + - show elements numbering + - show edges numbering + - show vertices numbering + - show DOFs 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 diff --git a/glvis.cpp b/glvis.cpp index 8c5721d3..7395dc90 100644 --- a/glvis.cpp +++ b/glvis.cpp @@ -19,6 +19,10 @@ #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 @@ -31,8 +35,7 @@ #define SDL_MAIN_HANDLED #endif -#include "mfem.hpp" -#include "lib/palettes.hpp" +#include #include "lib/visual.hpp" #include "lib/stream_reader.hpp" #include "lib/file_reader.hpp" @@ -171,6 +174,7 @@ bool GLVisInitVis(StreamCollection input_streams) // the 'jet-like' palette is used in 2D, see vssolution.cpp). vs->palette.SetIndex(4); } + vs->SetDataOffsets(stream_state.offsets.get()); } else if (stream_state.mesh->SpaceDimension() == 3) { @@ -224,6 +228,7 @@ bool GLVisInitVis(StreamCollection input_streams) vs = new VisualizationSceneVector(*stream_state.mesh, stream_state.solu, stream_state.solv, stream_state.mesh_quad.get()); } + vs->SetDataOffsets(stream_state.offsets.get()); } else if (stream_state.mesh->SpaceDimension() == 3) { diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index a3e65200..13b3db7c 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -23,6 +23,7 @@ list(APPEND SOURCES material.cpp openglvis.cpp palettes.cpp + palettes_default.cpp palettes_base.cpp sdl.cpp sdl_helper.cpp diff --git a/lib/aux_vis.cpp b/lib/aux_vis.cpp index d7e4b282..7c70be5c 100644 --- a/lib/aux_vis.cpp +++ b/lib/aux_vis.cpp @@ -11,16 +11,17 @@ #include #include -#include #include #include #include -#include "mfem.hpp" -#include "sdl.hpp" -#include "palettes.hpp" -#include "visual.hpp" +#include "gl/types.hpp" #include "gl2ps.h" +#include "palettes.hpp" +#include "sdl.hpp" +#include "threads.hpp" + +#include #if defined(GLVIS_USE_LIBTIFF) #include "tiffio.h" @@ -33,11 +34,9 @@ #include #endif -using namespace mfem; - thread_local int visualize = 0; thread_local VisualizationScene * locscene; -thread_local GLVisCommand *glvis_command = NULL; +thread_local GLVisCommand *glvis_command = nullptr; #ifdef GLVIS_MULTISAMPLE static int glvis_multisample = GLVIS_MULTISAMPLE; @@ -435,7 +434,7 @@ void MyExpose() } -thread_local Array IdleFuncs; +thread_local mfem::Array IdleFuncs; thread_local int LastIdleFunc; thread_local bool use_idle = false; diff --git a/lib/aux_vis.hpp b/lib/aux_vis.hpp index 9929639b..989143a0 100644 --- a/lib/aux_vis.hpp +++ b/lib/aux_vis.hpp @@ -12,7 +12,6 @@ #ifndef GLVIS_AUX_VIS_HPP #define GLVIS_AUX_VIS_HPP -#include "gl/platform_gl.hpp" #include "gl/types.hpp" #include "openglvis.hpp" @@ -184,4 +183,4 @@ function validator = [](T) { return true; }) return input; } -#endif +#endif // GLVIS_AUX_VIS_HPP diff --git a/lib/coll_reader.cpp b/lib/coll_reader.cpp index a50fafe3..9782c4de 100644 --- a/lib/coll_reader.cpp +++ b/lib/coll_reader.cpp @@ -11,8 +11,6 @@ #include "coll_reader.hpp" -#include - using namespace std; using namespace mfem; diff --git a/lib/coll_reader.hpp b/lib/coll_reader.hpp index a0c6f86c..bba8b9fa 100644 --- a/lib/coll_reader.hpp +++ b/lib/coll_reader.hpp @@ -12,8 +12,6 @@ #ifndef GLVIS_COLL_READER_HPP #define GLVIS_COLL_READER_HPP -#include -#include "mfem.hpp" #include "data_state.hpp" class DataCollectionReader diff --git a/lib/data_state.cpp b/lib/data_state.cpp index 287cb68c..3d65665e 100644 --- a/lib/data_state.cpp +++ b/lib/data_state.cpp @@ -9,11 +9,12 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. -#include "data_state.hpp" -#include "visual.hpp" - #include +#include "data_state.hpp" +#include "vsvector.hpp" +#include "vsvector3d.hpp" + using namespace std; using namespace mfem; @@ -57,13 +58,59 @@ DataState &DataState::operator=(DataState &&ss) return *this; } -void DataState::SetMesh(mfem::Mesh *mesh_) +void DataState::SetMesh(Mesh *mesh_) { internal.mesh.reset(mesh_); SetMesh(std::move(internal.mesh)); } -void DataState::SetMesh(std::unique_ptr &&pmesh) +void DataState::ComputeDofsOffsets(std::vector &gf_array) +{ + const int nprocs = static_cast(gf_array.size()); + MFEM_VERIFY(!gf_array.empty(), "No grid functions provided for offsets"); + + internal.offsets.reset(new DataState::Offsets(nprocs)); + + DenseMatrix pointmat; + Array dofs, vertices; + for (int i = 0, g_e = 0; i < nprocs; i++) + { + const GridFunction *gf = gf_array[i]; + const FiniteElementSpace *l_fes = gf->FESpace(); + Mesh *l_mesh = l_fes->GetMesh(); + // store the dofs numbers as they are fespace dependent + auto &offset = offsets->operator[](i); + for (int l_e = 0; l_e < l_mesh->GetNE(); l_e++, g_e++) + { +#ifdef GLVIS_DEBUG + // Store elements centers + l_mesh->GetPointMatrix(l_e, pointmat); + const int nv = pointmat.Width(); + double xs = 0.0, ys = 0.0; + for (int j = 0; j < nv; j++) + { + xs += pointmat(0,j), ys += pointmat(1,j); + } + xs /= nv, ys /= nv; + offset.exy_map[ {l_e, i} ] = {xs, ys}; +#endif // end GLVIS_DEBUG + l_fes->GetElementDofs(l_e, dofs); + l_fes->AdjustVDofs(dofs); + for (int k = 0; k < dofs.Size(); k++) + { + offset[ {g_e, k} ] = dofs[k]; + } + } + if (i + 1 == nprocs) { continue; } + auto &next = offsets->operator[](i+1); + // for NE, NV and NEdges, we accumulate the values + next.nelems = offset.nelems + l_mesh->GetNE(); + next.nedges = offset.nedges + l_mesh->GetNEdges(); + next.nverts = offset.nverts + l_mesh->GetNV(); + } +} + +void DataState::SetMesh(std::unique_ptr &&pmesh) { internal.mesh = std::move(pmesh); internal.mesh_quad.reset(); @@ -71,14 +118,14 @@ void DataState::SetMesh(std::unique_ptr &&pmesh) if (quad_f && quad_f->GetSpace()->GetMesh() != mesh.get()) { SetQuadFunction(NULL); } } -void DataState::SetGridFunction(mfem::GridFunction *gf, int component) +void DataState::SetGridFunction(GridFunction *gf, int component) { internal.grid_f.reset(gf); SetGridFunction(std::move(internal.grid_f), component); } -void DataState::SetGridFunction( - std::unique_ptr &&pgf, int component) +void DataState::SetGridFunction(std::unique_ptr &&pgf, + int component) { internal.grid_f = std::move(pgf); internal.quad_f.reset(); @@ -86,7 +133,7 @@ void DataState::SetGridFunction( SetGridFunctionSolution(component); } -void DataState::SetQuadFunction(mfem::QuadratureFunction *qf, int component) +void DataState::SetQuadFunction(QuadratureFunction *qf, int component) { if (quad_f.get() != qf) { @@ -97,8 +144,8 @@ void DataState::SetQuadFunction(mfem::QuadratureFunction *qf, int component) SetQuadFunctionSolution(component); } -void DataState::SetQuadFunction( - std::unique_ptr &&pqf, int component) +void DataState::SetQuadFunction(std::unique_ptr &&pqf, + int component) { if (quad_f.get() != pqf.get()) { @@ -109,8 +156,8 @@ void DataState::SetQuadFunction( SetQuadFunctionSolution(component); } -void DataState::SetQuadFunction( - const std::vector &qf_array, int component) +void DataState::SetQuadFunction(const std::vector + &qf_array, int component) { // assume the same vdim const int vdim = qf_array[0]->GetVDim(); @@ -132,7 +179,7 @@ void DataState::SetQuadFunction( SetQuadFunction(qf, component); } -void DataState::SetDataCollectionField(mfem::DataCollection *dc, int ti, +void DataState::SetDataCollectionField(DataCollection *dc, int ti, const char *field, bool quad, int component) { internal.data_coll.reset(dc); @@ -589,17 +636,18 @@ void DataState::ResetMeshAndSolution(DataState &ss, VisualizationScene* vs) { if (ss.grid_f->VectorDim() == 1) { - VisualizationSceneSolution *vss = - dynamic_cast(vs); + auto *vss = dynamic_cast(vs); // use the local vector as pointer is invalid after the move ss.grid_f->GetNodalValues(sol); + // update the offsets before the mesh and solution + vss->SetDataOffsets(ss.offsets.get()); vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &sol, ss.grid_f.get()); } else { - VisualizationSceneVector *vsv = - dynamic_cast(vs); + auto *vsv = dynamic_cast(vs); + vsv->SetDataOffsets(ss.offsets.get()); vsv->NewMeshAndSolution(*ss.grid_f, ss.mesh_quad.get()); } } @@ -607,8 +655,7 @@ void DataState::ResetMeshAndSolution(DataState &ss, VisualizationScene* vs) { if (ss.grid_f->VectorDim() == 1) { - VisualizationSceneSolution3d *vss = - dynamic_cast(vs); + auto *vss = dynamic_cast(vs); // use the local vector as pointer is invalid after the move ss.grid_f->GetNodalValues(sol); vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), &sol, @@ -618,8 +665,7 @@ void DataState::ResetMeshAndSolution(DataState &ss, VisualizationScene* vs) { ss.ProjectVectorFEGridFunction(); - VisualizationSceneVector3d *vss = - dynamic_cast(vs); + auto *vss = dynamic_cast(vs); vss->NewMeshAndSolution(ss.mesh.get(), ss.mesh_quad.get(), ss.grid_f.get()); } } diff --git a/lib/data_state.hpp b/lib/data_state.hpp index 8b61b1e8..c1e7d5f0 100644 --- a/lib/data_state.hpp +++ b/lib/data_state.hpp @@ -12,12 +12,17 @@ #ifndef GLVIS_DATA_STATE_HPP #define GLVIS_DATA_STATE_HPP +#include #include -#include #include -#include "mfem.hpp" +#include +#include + +#include + #include "openglvis.hpp" + struct DataState { enum class FieldType @@ -44,6 +49,26 @@ struct DataState MAX }; + // Class used for storing offsets and map of DOFs for each rank + class Offset + { + std::map, int> dof; + public: + int nelems, nedges, nverts; +#ifdef GLVIS_DEBUG + // in debug mode, we store the element centers + // to be able to compare them with the ones of the global mesh, + // as it could depend on the way the global mesh is constructed + // from the array of 'local' ones. + struct xy {double x,y;}; + std::map, xy> exy_map; +#endif + Offset() = default; + int& operator[](const std::pair &key) { return dof[key]; } + const int& operator[](const std::pair &key) const { return dof.at(key); } + }; + using Offsets = std::vector; + private: friend class StreamReader; friend class FileReader; @@ -54,6 +79,7 @@ struct DataState std::unique_ptr grid_f; std::unique_ptr quad_f; std::unique_ptr data_coll; + std::unique_ptr offsets; } internal; FieldType type {FieldType::UNKNOWN}; @@ -75,6 +101,7 @@ struct DataState const std::unique_ptr &grid_f{internal.grid_f}; const std::unique_ptr &quad_f{internal.quad_f}; const std::unique_ptr &data_coll{internal.data_coll}; + const std::unique_ptr &offsets{internal.offsets}; std::string keys; bool fix_elem_orient{false}; @@ -93,6 +120,9 @@ struct DataState @see SetMesh(std::unique_ptr &&pmesh) */ void SetMesh(mfem::Mesh *mesh); + /// Compute the dofs offsets from the grid function vector + void ComputeDofsOffsets(std::vector &gf_array); + /// Set a mesh (unique pointer version) /** Sets the mesh and resets grid/quadrature functions if they do not use the same one. */ diff --git a/lib/file_reader.cpp b/lib/file_reader.cpp index 7efc897e..d42c1705 100644 --- a/lib/file_reader.cpp +++ b/lib/file_reader.cpp @@ -9,10 +9,10 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. -#include "file_reader.hpp" - #include +#include "file_reader.hpp" + using namespace std; using namespace mfem; diff --git a/lib/file_reader.hpp b/lib/file_reader.hpp index 762cd1bc..87eed714 100644 --- a/lib/file_reader.hpp +++ b/lib/file_reader.hpp @@ -12,8 +12,6 @@ #ifndef GLVIS_FILE_READER_HPP #define GLVIS_FILE_READER_HPP -#include -#include "mfem.hpp" #include "data_state.hpp" class FileReader diff --git a/lib/font.hpp b/lib/font.hpp index 24ec2873..27fbf576 100644 --- a/lib/font.hpp +++ b/lib/font.hpp @@ -21,8 +21,6 @@ #include "gl/platform_gl.hpp" -using namespace std; - class GlVisFont { public: @@ -66,7 +64,7 @@ class GlVisFont { if (FT_Init_FreeType(&library)) { - cout << "GLVis: Can not initialize FreeType library!" << endl; + std::cout << "GLVis: Can not initialize FreeType library!" << std::endl; } init = true; } @@ -109,4 +107,4 @@ class GlVisFont void setAlphaChannel(GLenum alpha) { alpha_channel = alpha; } }; -#endif /* GLVIS_FONT_HPP */ +#endif // GLVIS_FONT_HPP diff --git a/lib/geom_utils.hpp b/lib/geom_utils.hpp index 25cf2c7c..69de052d 100644 --- a/lib/geom_utils.hpp +++ b/lib/geom_utils.hpp @@ -11,7 +11,8 @@ #ifndef GLVIS_GEOM_UTILS_HPP #define GLVIS_GEOM_UTILS_HPP -#include "mfem.hpp" + +#include // Some inline functions diff --git a/lib/gl/attr_traits.hpp b/lib/gl/attr_traits.hpp index 337c4a33..bca14554 100644 --- a/lib/gl/attr_traits.hpp +++ b/lib/gl/attr_traits.hpp @@ -12,9 +12,7 @@ #ifndef GLVIS_ATTR_TRAITS_HPP #define GLVIS_ATTR_TRAITS_HPP -#include "types.hpp" #include "renderer_core.hpp" -#include namespace gl3 { @@ -159,4 +157,4 @@ AttrTexcoord> } -#endif +#endif // GLVIS_ATTR_TRAITS_HPP diff --git a/lib/gl/platform_gl.hpp b/lib/gl/platform_gl.hpp index b9d64323..d9b424dd 100644 --- a/lib/gl/platform_gl.hpp +++ b/lib/gl/platform_gl.hpp @@ -21,4 +21,4 @@ #include #endif -#endif +#endif // GLVIS_PLATFORM_GL_HPP diff --git a/lib/gl/renderer.cpp b/lib/gl/renderer.cpp index ad9421ef..88757102 100644 --- a/lib/gl/renderer.cpp +++ b/lib/gl/renderer.cpp @@ -14,6 +14,8 @@ namespace gl3 { +using namespace resource; + // Beginning in OpenGL 3.0, there were two changes in texture format support: // - The older single-channel internal format GL_ALPHA was deprecated in favor // of GL_RED diff --git a/lib/gl/renderer.hpp b/lib/gl/renderer.hpp index f0c9b524..0f79647b 100644 --- a/lib/gl/renderer.hpp +++ b/lib/gl/renderer.hpp @@ -14,8 +14,6 @@ #include #include -#include -#include #include "platform_gl.hpp" #include "types.hpp" @@ -25,13 +23,11 @@ namespace gl3 { -using namespace resource; - const int LIGHTS_MAX = 3; #ifdef GLVIS_MS_LINEWIDTH const float LINE_WIDTH_AA = GLVIS_MS_LINEWIDTH; #else -const float LINE_WIDTH_AA = 1.4; +const float LINE_WIDTH_AA = 1.4f; #endif struct RenderParams @@ -105,7 +101,7 @@ class GLDevice std::array static_color; protected: - TextureHandle passthrough_texture; + resource::TextureHandle passthrough_texture; public: diff --git a/lib/gl/renderer_core.cpp b/lib/gl/renderer_core.cpp index 4b026307..0c8f29f8 100644 --- a/lib/gl/renderer_core.cpp +++ b/lib/gl/renderer_core.cpp @@ -9,13 +9,15 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. +#include + #include "attr_traits.hpp" #include "renderer_core.hpp" #include "../aux_vis.hpp" -#include -#include +#ifdef GLVIS_DEBUG #include +#endif // weird but loads them inline @@ -146,7 +148,7 @@ void CoreGLDevice::initializeShaderState(const ShaderProgram& prog) } } #ifdef GLVIS_DEBUG - unordered_set expectedUnifs(unif_list.begin(), unif_list.end()); + std::unordered_set expectedUnifs(unif_list.begin(), unif_list.end()); for (const auto& pairunif : uniforms) { if (expectedUnifs.find(pairunif.first) == expectedUnifs.end()) @@ -175,12 +177,12 @@ void CoreGLDevice::init() { GLuint hnd_vao; glGenVertexArrays(1, &hnd_vao); - global_vao = VtxArrayHandle(hnd_vao); + global_vao = resource::VtxArrayHandle(hnd_vao); glBindVertexArray(global_vao); } GLuint hnd_fb_buf; glGenBuffers(1, &hnd_fb_buf); - feedback_vbo = BufObjHandle(hnd_fb_buf); + feedback_vbo = resource::BufObjHandle(hnd_fb_buf); } void CoreGLDevice::setTransformMatrices(glm::mat4 model_view, diff --git a/lib/gl/renderer_core.hpp b/lib/gl/renderer_core.hpp index 41f41ab2..f8bcd609 100644 --- a/lib/gl/renderer_core.hpp +++ b/lib/gl/renderer_core.hpp @@ -11,11 +11,15 @@ #ifndef GLVIS_RENDERER_CORE_HPP #define GLVIS_RENDERER_CORE_HPP + +#include + #include "renderer.hpp" #include "shader.hpp" namespace gl3 { + // Renderer for OpenGL versions with access to the programmable pipeline class CoreGLDevice : public GLDevice { @@ -40,9 +44,9 @@ class CoreGLDevice : public GLDevice private: ShaderProgram default_prgm; ShaderProgram feedback_prgm; - VtxArrayHandle global_vao; + resource::VtxArrayHandle global_vao; - BufObjHandle feedback_vbo; + resource::BufObjHandle feedback_vbo; const static std::vector unif_list; @@ -52,8 +56,8 @@ class CoreGLDevice : public GLDevice struct VBOData { - BufObjHandle vert_buf; - BufObjHandle elem_buf; + resource::BufObjHandle vert_buf; + resource::BufObjHandle elem_buf; GLenum shape; size_t count; array_layout layout; diff --git a/lib/gl/renderer_ff.cpp b/lib/gl/renderer_ff.cpp index e507acb6..a066f854 100644 --- a/lib/gl/renderer_ff.cpp +++ b/lib/gl/renderer_ff.cpp @@ -9,6 +9,10 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. +#include +#include +#include + #include "renderer_ff.hpp" #include "attr_traits.hpp" #include "../aux_vis.hpp" @@ -370,7 +374,7 @@ void FFGLDevice::captureXfbBuffer(PaletteState& pal, CaptureBuffer& cbuf, return; } // allocate feedback buffer - vector xfb_buf; + std::vector xfb_buf; xfb_buf.resize(sizebuf); glFeedbackBuffer(sizebuf, fbType, xfb_buf.data()); // draw with feedback capture diff --git a/lib/gl/renderer_ff.hpp b/lib/gl/renderer_ff.hpp index 1af05b3d..6b3946ab 100644 --- a/lib/gl/renderer_ff.hpp +++ b/lib/gl/renderer_ff.hpp @@ -12,6 +12,10 @@ #ifndef GLVIS_RENDERER_FF_HPP #define GLVIS_RENDERER_FF_HPP +#include +#include +#include + #include "renderer.hpp" namespace gl3 @@ -23,7 +27,7 @@ class FFGLDevice : public GLDevice { struct DispListData_ { - DispListHandle list; + resource::DispListHandle list; GLenum shape; size_t count; array_layout layout; diff --git a/lib/gl/shader.cpp b/lib/gl/shader.cpp index 9f72aa84..67677a0c 100644 --- a/lib/gl/shader.cpp +++ b/lib/gl/shader.cpp @@ -9,9 +9,12 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. -#include "shader.hpp" +#include #include +#include "shader.hpp" +#include "renderer.hpp" + namespace gl3 { diff --git a/lib/gl/shader.hpp b/lib/gl/shader.hpp index 287cf4cd..0de0e726 100644 --- a/lib/gl/shader.hpp +++ b/lib/gl/shader.hpp @@ -12,10 +12,12 @@ #ifndef GLVIS_SHADER_HPP #define GLVIS_SHADER_HPP -#include "renderer.hpp" - +#include #include +#include "platform_gl.hpp" +#include "types.hpp" + namespace gl3 { class ShaderProgram @@ -69,9 +71,9 @@ class ShaderProgram std::unordered_map attrib_idx; int num_outputs = 0; - ShaderPrgmHandle program_id = 0; - ShaderHandle vertex_shader = 0; - ShaderHandle fragment_shader = 0; + resource::ShaderPrgmHandle program_id = 0; + resource::ShaderHandle vertex_shader = 0; + resource::ShaderHandle fragment_shader = 0; bool is_compiled = false; std::unordered_map uniform_idx; }; diff --git a/lib/gl/types.cpp b/lib/gl/types.cpp index d02cca4a..4de90da5 100644 --- a/lib/gl/types.cpp +++ b/lib/gl/types.cpp @@ -10,7 +10,6 @@ // CONTRIBUTING.md for details. #include "types.hpp" -#include #include using namespace gl3; @@ -20,9 +19,9 @@ void GlDrawable::addCone(float x, float y, float z, float vx, float vy, float vz, float cone_scale) { - double rhos = sqrt (vx*vx+vy*vy+vz*vz); - float phi = acos(vz/rhos); - float theta = atan2 (vy, vx); + double rhos = sqrt(vx*vx+vy*vy+vz*vz); + float phi = acos(vz/rhos); + float theta = atan2(vy, vx); glm::mat4 mtx(1.0); mtx = glm::translate(mtx, glm::vec3(x, y, z)); diff --git a/lib/gl/types.hpp b/lib/gl/types.hpp index 43cd9563..af0c6c23 100644 --- a/lib/gl/types.hpp +++ b/lib/gl/types.hpp @@ -14,8 +14,9 @@ #include #include -#include #include +#include +#include #include #include diff --git a/lib/gl2ps.c b/lib/gl2ps.c index 3182a79d..da38ef05 100644 --- a/lib/gl2ps.c +++ b/lib/gl2ps.c @@ -4349,7 +4349,7 @@ static int gl2psPrintPDFShaderStreamDataCoord(GL2PSvertex *vertex, int offs = 0; unsigned long imap; GLfloat diff; - double dmax = ~1UL; + double dmax = (double) ~1UL; char edgeflag = 0; /* FIXME: temp bux fix for 64 bit archs: */ @@ -4392,7 +4392,7 @@ static int gl2psPrintPDFShaderStreamDataRGB(GL2PSvertex *vertex, { int offs = 0; unsigned long imap; - double dmax = ~1UL; + double dmax = (double) ~1UL; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; @@ -4417,7 +4417,7 @@ static int gl2psPrintPDFShaderStreamDataAlpha(GL2PSvertex *vertex, { int offs = 0; unsigned long imap; - double dmax = ~1UL; + double dmax = (double) ~1UL; /* FIXME: temp bux fix for 64 bit archs: */ if(sizeof(unsigned long) == 8) dmax = dmax - 2048.; @@ -6473,7 +6473,7 @@ GL2PSDLL_API const char *gl2psGetFormatDescription(GLint format) return "Unknown format"; } -GL2PSDLL_API GLint gl2psGetFileFormat() +GL2PSDLL_API GLint gl2psGetFileFormat(void) { return gl2ps->format; } diff --git a/lib/gl2ps.h b/lib/gl2ps.h index 8cc4c298..a5291c33 100644 --- a/lib/gl2ps.h +++ b/lib/gl2ps.h @@ -244,7 +244,7 @@ GL2PSDLL_API GLint gl2psDrawImageMap(GLsizei width, GLsizei height, const unsigned char *imagemap); GL2PSDLL_API const char *gl2psGetFileExtension(GLint format); GL2PSDLL_API const char *gl2psGetFormatDescription(GLint format); -GL2PSDLL_API GLint gl2psGetFileFormat(); +GL2PSDLL_API GLint gl2psGetFileFormat(void); #if defined(__cplusplus) } diff --git a/lib/gltf.hpp b/lib/gltf.hpp index d60d6f89..d75330d8 100644 --- a/lib/gltf.hpp +++ b/lib/gltf.hpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/lib/logo.hpp b/lib/logo.hpp index 201c4ce5..b203b466 100644 --- a/lib/logo.hpp +++ b/lib/logo.hpp @@ -19,4 +19,4 @@ extern unsigned int logo_rgba_len; #endif // GLVIS_USE_LOGO -#endif //__LOGO_HPP__ +#endif // GLVIS_LOGO_HPP diff --git a/lib/material.cpp b/lib/material.cpp index 7aac062e..65b7c96c 100644 --- a/lib/material.cpp +++ b/lib/material.cpp @@ -9,62 +9,64 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. -#include "material.hpp" #include + +#include "material.hpp" + Material materials[5] = { { - { 0.8, 0.8, 0.8, 1.0 }, - { 0.8, 0.8, 0.8, 1.0 }, - { 1.0, 1.0, 1.0, 1.0 }, - 100 + { 0.8f, 0.8f, 0.8f, 1.0f }, + { 0.8f, 0.8f, 0.8f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + 100.0f }, { - { 0.3, 0.3, 0.3, 1.0 }, - { 0.7, 0.7, 0.7, 1.0 }, - { 0.8, 0.8, 0.8, 1.0 }, - 20 + { 0.3f, 0.3f, 0.3f, 1.0f }, + { 0.7f, 0.7f, 0.7f, 1.0f }, + { 0.8f, 0.8f, 0.8f, 1.0f }, + 20.0f }, { - { 0.3, 0.3, 0.3, 1.0 }, - { 1.0, 1.0, 1.0, 1.0 }, - { 0.0, 0.0, 0.0, 1.0 }, - 0 + { 0.3f, 0.3f, 0.3f, 1.0f }, + { 1.0f, 1.0f, 1.0f, 1.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, + 0.0f }, { - { 0.24725, 0.1995, 0.0745, 1.0 }, - { 0.75164, 0.60648, 0.22648, 1.0 }, - { 0.628281, 0.555802, 0.366065, 1.0 }, - 51.2 + { 0.24725f, 0.1995f, 0.0745f, 1.0f }, + { 0.75164f, 0.60648f, 0.22648f, 1.0f }, + { 0.628281f, 0.555802f, 0.366065f, 1.0f }, + 51.2f }, { - { 0.0, 0.0, 0.0, 1.0 }, - { 0.8, 0.8, 0.8, 1.0 }, - { 0.1, 0.1, 0.1, 1.0 }, - 1.0 + { 0.0f, 0.0f, 0.0f, 1.0f }, + { 0.8f, 0.8f, 0.8f, 1.0f }, + { 0.1f, 0.1f, 0.1f, 1.0f }, + 1.0f } }; Light lights[] = { - { { 1.0, 1.0, 1.0, 0.0 }, { 0.9, 0.9, 0.9, 1.0 }, { 0.8, 0.8, 0.8, 1.0 } }, - { { 0.5, 0.5, 1.0, 0.0 }, { 0.5, 0.5, 0.5, 1.0 }, { 1.0, 1.0, 1.0, 1.0 } }, - { { 0.0, 0.0, 1.0, 0.0 }, { 0.5, 0.5, 0.5, 1.0 }, { 0.0, 0.0, 0.0, 1.0 } }, - { { 0.0, 0.0, 1.0, 0.0 }, { 0.7, 0.7, 0.7, 1.0 }, { 0.6, 0.6, 0.6, 1.0 } } + { { 1.0f, 1.0f, 1.0f, 0.0f }, { 0.9f, 0.9f, 0.9f, 1.0f }, { 0.8f, 0.8f, 0.8f, 1.0f } }, + { { 0.5f, 0.5f, 1.0f, 0.0f }, { 0.5f, 0.5f, 0.5f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, + { { 0.0f, 0.0f, 1.0f, 0.0f }, { 0.5f, 0.5f, 0.5f, 1.0f }, { 0.0f, 0.0f, 0.0f, 1.0f } }, + { { 0.0f, 0.0f, 1.0f, 0.0f }, { 0.7f, 0.7f, 0.7f, 1.0f }, { 0.6f, 0.6f, 0.6f, 1.0f } } }; std::array amb_setting[] = { - { 0.3, 0.3, 0.3, 1.0 }, - { 0.5, 0.5, 0.5, 1.0 }, - { 0.5, 0.5, 0.5, 1.0 }, - { 0.5, 0.5, 0.5, 1.0 }, - { 0.5, 0.5, 0.5, 1.0 } + { 0.3f, 0.3f, 0.3f, 1.0f }, + { 0.5f, 0.5f, 0.5f, 1.0f }, + { 0.5f, 0.5f, 0.5f, 1.0f }, + { 0.5f, 0.5f, 0.5f, 1.0f }, + { 0.5f, 0.5f, 0.5f, 1.0f } }; Light lights_4[] = { - { { 1.0, 0.0, 1.0, 0.0 }, { 0.4, 0.0, 0.0, 1.0 }, { 0.3, 0.3, 0.3, 1.0 } }, - { { 1.0, 1.0, 1.0, 0.0 }, { 0.0, 0.4, 0.0, 1.0 }, { 0.3, 0.3, 0.3, 1.0 } }, - { { 0.0, 1.0, 1.0, 0.0 }, { 0.0, 0.0, 0.4, 1.0 }, { 0.3, 0.3, 0.3, 1.0 } } + { { 1.0f, 0.0f, 1.0f, 0.0f }, { 0.4f, 0.0f, 0.0f, 1.0f }, { 0.3f, 0.3f, 0.3f, 1.0f } }, + { { 1.0f, 1.0f, 1.0f, 0.0f }, { 0.0f, 0.4f, 0.0f, 1.0f }, { 0.3f, 0.3f, 0.3f, 1.0f } }, + { { 0.0f, 1.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.4f, 1.0f }, { 0.3f, 0.3f, 0.3f, 1.0f } } }; diff --git a/lib/material.hpp b/lib/material.hpp index 9d10c6fa..6506b67d 100644 --- a/lib/material.hpp +++ b/lib/material.hpp @@ -28,4 +28,4 @@ struct Light std::array specular; }; -#endif +#endif // GLVIS_MATERIAL_HPP diff --git a/lib/openglvis.hpp b/lib/openglvis.hpp index 1455242d..6bc59aa1 100644 --- a/lib/openglvis.hpp +++ b/lib/openglvis.hpp @@ -12,11 +12,9 @@ #ifndef GLVIS_OPENGLVIS_HPP #define GLVIS_OPENGLVIS_HPP -#include #include "gl/types.hpp" #include "material.hpp" #include "palettes.hpp" -#include "mfem.hpp" #include "geom_utils.hpp" #include "sdl.hpp" #include "gltf.hpp" @@ -113,7 +111,7 @@ class VisualizationScene if (val < 0.0) { val = 0.0; } if (val > 1.0) { val = 1.0; } - builder.glTexCoord1f(val); + builder.glTexCoord1f(static_cast(val)); } // We only need 3 points, but the array is 4x3 @@ -228,4 +226,4 @@ class VisualizationScene int view; }; -#endif +#endif // GLVIS_OPENGLVIS_HPP diff --git a/lib/palettes.cpp b/lib/palettes.cpp index 898599bf..7da10cf8 100644 --- a/lib/palettes.cpp +++ b/lib/palettes.cpp @@ -15,8 +15,6 @@ #include #include #include -#include -#include using namespace std; diff --git a/lib/palettes_base.cpp b/lib/palettes_base.cpp index 1393c2d2..f61e0130 100644 --- a/lib/palettes_base.cpp +++ b/lib/palettes_base.cpp @@ -10,17 +10,18 @@ // CONTRIBUTING.md for details. #include "palettes_base.hpp" -#include "palettes_default.cpp" #include "gl/renderer.hpp" +#include +#include void RGBAf::Print(ostream& os) const { - os << fixed << setprecision(6) - << setw(10) << r << " " - << setw(10) << g << " " - << setw(10) << b << " " - << setw(10) << a; + os << std::fixed << std::setprecision(6) + << std::setw(10) << r << " " + << std::setw(10) << g << " " + << std::setw(10) << b << " " + << std::setw(10) << a; } template diff --git a/lib/palettes_base.hpp b/lib/palettes_base.hpp index 7ecd437f..c68ad8dc 100644 --- a/lib/palettes_base.hpp +++ b/lib/palettes_base.hpp @@ -17,12 +17,8 @@ #include #include #include -#include #include #include -#include - -using namespace std; struct RGBAf { @@ -224,4 +220,4 @@ class PaletteRegistry extern PaletteRegistry BasePalettes; -#endif +#endif // GLVIS_PALETTESBASE_HPP diff --git a/lib/palettes_default.cpp b/lib/palettes_default.cpp index 733b3109..1806a8cf 100644 --- a/lib/palettes_default.cpp +++ b/lib/palettes_default.cpp @@ -9,6 +9,7 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. +#include "palettes_base.hpp" const Palette BPAL_1 = Palette("5-color", { diff --git a/lib/sdl.cpp b/lib/sdl.cpp index 3131d757..ecd6ffc6 100644 --- a/lib/sdl.cpp +++ b/lib/sdl.cpp @@ -15,6 +15,7 @@ #include "gl/renderer_ff.hpp" #include "sdl.hpp" #include "sdl_main.hpp" + #ifdef __EMSCRIPTEN__ #include #include diff --git a/lib/sdl.hpp b/lib/sdl.hpp index 4a82b773..47e51b0e 100644 --- a/lib/sdl.hpp +++ b/lib/sdl.hpp @@ -20,7 +20,6 @@ #include #include #include "gl/renderer.hpp" -#include "sdl_helper.hpp" struct EventInfo { @@ -29,12 +28,12 @@ struct EventInfo SDL_Keymod keymod; }; -typedef void (*TouchDelegate)(SDL_MultiGestureEvent&); -typedef void (*MouseDelegate)(EventInfo*); -typedef std::function KeyDelegate; -typedef void (*WindowDelegate)(int, int); -typedef void (*Delegate)(); -typedef bool (*IdleDelegate)(); +using TouchDelegate = void (*)(SDL_MultiGestureEvent&); +using MouseDelegate = void (*)(EventInfo*); +using KeyDelegate = std::function; +using WindowDelegate = void (*)(int, int); +using Delegate = void (*)(); +using IdleDelegate = bool (*)(); class SdlMainThread; SdlMainThread& GetMainThread(); diff --git a/lib/sdl_helper.hpp b/lib/sdl_helper.hpp index d0990e49..ac9310e1 100644 --- a/lib/sdl_helper.hpp +++ b/lib/sdl_helper.hpp @@ -36,4 +36,4 @@ class SdlNativePlatform virtual void SendEvent() = 0; }; -#endif +#endif // GLVIS_SDL_HELPER_HPP diff --git a/lib/sdl_mac.hpp b/lib/sdl_mac.hpp index 37247152..2206e8ed 100644 --- a/lib/sdl_mac.hpp +++ b/lib/sdl_mac.hpp @@ -16,8 +16,8 @@ class SdlCocoaPlatform final : public SdlNativePlatform { public: - void WaitEvent(); - void SendEvent(); + void WaitEvent() override; + void SendEvent() override; void ContextUpdate(); @@ -28,4 +28,4 @@ class SdlCocoaPlatform final : public SdlNativePlatform void SwapWindow(); }; -#endif +#endif // GLVIS_SDL_MAC_HPP diff --git a/lib/sdl_main.cpp b/lib/sdl_main.cpp index d9a6941a..599df8c4 100644 --- a/lib/sdl_main.cpp +++ b/lib/sdl_main.cpp @@ -678,6 +678,7 @@ void SdlMainThread::createWindowImpl(CreateWindowCmd& cmd) // Detect if we are using a high-dpi display and resize the window unless it // was already resized by SDL's underlying backend. + if (wndUseHiDPI) { SdlWindow* wnd = cmd.wnd; int scr_w, scr_h, pix_w, pix_h, wdpi, hdpi; diff --git a/lib/sdl_main.hpp b/lib/sdl_main.hpp index d5b627c2..44838652 100644 --- a/lib/sdl_main.hpp +++ b/lib/sdl_main.hpp @@ -12,10 +12,16 @@ #ifndef GLVIS_SDL_MAIN_HPP #define GLVIS_SDL_MAIN_HPP -#include #include +#include +#include +#include +#include +#include +#include #include "sdl.hpp" +#include "sdl_helper.hpp" class SdlMainThread { @@ -113,14 +119,14 @@ class SdlMainThread // A flag indicating whether the main loop will *begin* terminating bool terminating {false}; - unique_ptr bg_wnd{nullptr, SDL_DestroyWindow}; + std::unique_ptr bg_wnd{nullptr, SDL_DestroyWindow}; // ------------------------------------------------------------------------- // Objects for handling passing of window control commands to the main event // loop. mutex window_cmd_mtx; - vector window_cmds; + std::vector window_cmds; int num_windows {-1}; // -1: waiting for window to be created @@ -128,19 +134,19 @@ class SdlMainThread // Objects for handling dispatching events from the main event loop to // worker threads. - unordered_map hwnd_to_window; - unordered_map> wnd_events; + std::unordered_map hwnd_to_window; + std::unordered_map> wnd_events; std::set fingers; bool disable_mouse {false}; - mutex gl_ctx_mtx; + std::mutex gl_ctx_mtx; - mutex event_mtx; + std::mutex event_mtx; condition_variable event_cv; bool try_create_platform{false}; - unique_ptr platform; + std::unique_ptr platform; int title_height_offset {0}; }; -#endif +#endif // GLVIS_SDL_MAIN_HPP diff --git a/lib/stream_reader.cpp b/lib/stream_reader.cpp index 9fa45538..57695889 100644 --- a/lib/stream_reader.cpp +++ b/lib/stream_reader.cpp @@ -295,6 +295,7 @@ int StreamReader::ReadStreams(const StreamCollection &input_streams) if (gf_count > 0) { data.SetGridFunction(new GridFunction(data.mesh.get(), gf_array.data(), nproc)); + if (!data.keep_attr) { data.ComputeDofsOffsets(gf_array); } } else if (qf_count > 0) { diff --git a/lib/stream_reader.hpp b/lib/stream_reader.hpp index eb9606f0..720b878d 100644 --- a/lib/stream_reader.hpp +++ b/lib/stream_reader.hpp @@ -16,7 +16,6 @@ #include #include #include -#include "mfem.hpp" #include "data_state.hpp" using StreamCollection = std::vector>; diff --git a/lib/threads.cpp b/lib/threads.cpp index 5c2cb678..3b1a4593 100644 --- a/lib/threads.cpp +++ b/lib/threads.cpp @@ -9,11 +9,17 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. -#include "visual.hpp" -#include "palettes.hpp" +#include #include +#include + +#include "threads.hpp" +#include "vsdata.hpp" +#include "palettes.hpp" + using namespace std; +using namespace mfem; extern const char *strings_off_on[]; // defined in vsdata.cpp @@ -931,6 +937,7 @@ void communication_thread::execute() if (gf_array.size() > 0) { tmp.SetGridFunction(new GridFunction(tmp.mesh.get(), gf_array.data(), nproc)); + if (!keep_attr) { tmp.ComputeDofsOffsets(gf_array); } } else if (qf_array.size() > 0) { diff --git a/lib/threads.hpp b/lib/threads.hpp index 1a48aa95..5ef521f2 100644 --- a/lib/threads.hpp +++ b/lib/threads.hpp @@ -12,13 +12,14 @@ #ifndef GLVIS_THREADS_HPP #define GLVIS_THREADS_HPP -#include "vsdata.hpp" -#include "data_state.hpp" #include #include #include #include +#include "vsdata.hpp" +#include "data_state.hpp" + class GLVisCommand { private: @@ -157,8 +158,8 @@ class communication_thread GLVisCommand* glvis_command; // data that may be dynamically allocated by the thread - std::unique_ptr new_m; - std::unique_ptr new_g; + std::unique_ptr new_m; + std::unique_ptr new_g; std::string ident; // thread object @@ -174,4 +175,4 @@ class communication_thread ~communication_thread(); }; -#endif +#endif // GLVIS_THREADS_HPP diff --git a/lib/visual.hpp b/lib/visual.hpp index 8c5e5dfa..3e7319f9 100644 --- a/lib/visual.hpp +++ b/lib/visual.hpp @@ -25,4 +25,4 @@ #include "threads.hpp" #include "gl/types.hpp" -#endif +#endif // GLVIS_VISUAL_HPP diff --git a/lib/vsdata.cpp b/lib/vsdata.cpp index dd19091b..4f560819 100644 --- a/lib/vsdata.cpp +++ b/lib/vsdata.cpp @@ -9,22 +9,18 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. -#include #include - +#include #include - -#include #include #include -using namespace std; #include "vsdata.hpp" #include "aux_vis.hpp" #include "material.hpp" #include "palettes.hpp" -#include "gl2ps.h" +using namespace mfem; const char *strings_off_on[] = { "off", "on" }; @@ -37,7 +33,7 @@ void VisualizationSceneScalarData::FixValueRange() { // Shading quality may be bad since OpenGL uses single precision. We // should probably pre-scale the solution before feeding it to OpenGL - int old_prec = cout.precision(12); + auto old_prec = std::cout.precision(12); cout << "[minv,maxv] = " << "[" << minv << "," << maxv << "] (maxv-minv = " << maxv-minv << ")\n --> "; minv -= 0.49999e-5*am; diff --git a/lib/vsdata.hpp b/lib/vsdata.hpp index ed09eca6..c16c3131 100644 --- a/lib/vsdata.hpp +++ b/lib/vsdata.hpp @@ -12,13 +12,10 @@ #ifndef GLVIS_VSDATA_HPP #define GLVIS_VSDATA_HPP -#include - -#include "mfem.hpp" +#include #include "openglvis.hpp" #include "aux_vis.hpp" - -using namespace mfem; +#include "data_state.hpp" extern thread_local std::string plot_caption; // defined in glvis.cpp extern thread_local std::string extra_caption; // defined in glvis.cpp @@ -69,8 +66,9 @@ class VisualizationSceneScalarData : public VisualizationScene }; protected: - Mesh *mesh{}, *mesh_coarse{}; - Vector *sol{}; + mfem::Mesh *mesh{}, *mesh_coarse{}; + mfem::Vector *sol{}; + const DataState::Offsets *offsets{}; double minv, maxv; @@ -79,6 +77,7 @@ class VisualizationSceneScalarData : public VisualizationScene int scaling, colorbar, drawaxes; Shading shading; int auto_ref_max, auto_ref_min_surf_vert, auto_ref_max_surf_vert; + bool legacy_parallel_numbering = false; // Formatter for axes & colorbar numbers. Set defaults. function axis_formatter = NumberFormatter(4, 'd', false); @@ -97,7 +96,7 @@ class VisualizationSceneScalarData : public VisualizationScene int arrow_type, arrow_scaling_type; int nl; - Array level; + mfem::Array level; int ruler_on; double ruler_x, ruler_y, ruler_z; @@ -143,7 +142,7 @@ class VisualizationSceneScalarData : public VisualizationScene void FixValueRange(); - static int GetFunctionAutoRefineFactor(GridFunction &gf); + static int GetFunctionAutoRefineFactor(mfem::GridFunction &gf); virtual int GetFunctionAutoRefineFactor() = 0; virtual int GetAutoRefineFactor(); @@ -160,7 +159,8 @@ class VisualizationSceneScalarData : public VisualizationScene VisualizationSceneScalarData() : a_label_x("x"), a_label_y("y"), a_label_z("z") {} - VisualizationSceneScalarData (Mesh & m, Vector & s, Mesh *mc = NULL); + VisualizationSceneScalarData (mfem::Mesh & m, mfem::Vector & s, + mfem::Mesh *mc = nullptr); virtual ~VisualizationSceneScalarData(); @@ -215,13 +215,18 @@ class VisualizationSceneScalarData : public VisualizationScene auto_ref_max_surf_vert = max_surf_vert; } virtual void AutoRefine() = 0; - virtual void ToggleAttributes(Array &attr_list) = 0; + virtual void ToggleAttributes(mfem::Array &attr_list) = 0; virtual void PrintState(); - Mesh *GetMesh() { return mesh; } + mfem::Mesh *GetMesh() { return mesh; } + + void SetDataOffsets(const DataState::Offsets *data_offsets) + { + offsets = data_offsets; + } - virtual gl3::SceneInfo GetSceneObjs(); + gl3::SceneInfo GetSceneObjs() override; void ProcessUpdatedBufs(gl3::SceneInfo& scene); @@ -262,7 +267,7 @@ class VisualizationSceneScalarData : public VisualizationScene double cval = HUGE_VAL); void DrawPolygonLevelLines(gl3::GlBuilder& builder, double *point, int n, - Array &level, bool log_vals); + mfem::Array &level, bool log_vals); void ToggleLight() { use_light = !use_light; } void SetLight(bool light_set) { use_light = light_set; } @@ -282,8 +287,8 @@ class VisualizationSceneScalarData : public VisualizationScene void SetColorbarNumberFormat(string formatting); void PrepareColorBar(double minval, double maxval, - Array * level = NULL, - Array * levels = NULL); + mfem::Array * level = nullptr, + mfem::Array * levels = nullptr); void SetAxisLabels(const char * a_x, const char * a_y, const char * a_z); @@ -318,9 +323,9 @@ class VisualizationSceneScalarData : public VisualizationScene int GetAutoscale() const { return autoscale; } /// Shrink the set of points towards attributes centers of gravity - void ShrinkPoints(DenseMatrix &pointmat, int i, int fn, int di); + void ShrinkPoints(mfem::DenseMatrix &pointmat, int i, int fn, int di); // Centers of gravity based on the boundary/element attributes - DenseMatrix bdrc, matc; + mfem::DenseMatrix bdrc, matc; /// Compute the center of gravity for each boundary attribute void ComputeBdrAttrCenter(); /// Compute the center of gravity for each element attribute diff --git a/lib/vssolution.cpp b/lib/vssolution.cpp index 246f88c0..21e2574e 100644 --- a/lib/vssolution.cpp +++ b/lib/vssolution.cpp @@ -9,21 +9,11 @@ // terms of the BSD-3 license. We welcome feedback and contributions, see file // CONTRIBUTING.md for details. -#include -#include -#include -#include -#include -#include - -#include "mfem.hpp" -#include "visual.hpp" +#include "vssolution.hpp" #include "palettes.hpp" #include "gltf.hpp" using namespace mfem; -using namespace std; - thread_local VisualizationSceneSolution *vssol; extern thread_local VisualizationScene *locscene; @@ -87,6 +77,7 @@ std::string VisualizationSceneSolution::GetHelpString() const << "| \\ - Set light source position |" << endl << "| Alt+a - Axes number format |" << endl << "| Alt+c - Colorbar number format |" << endl + << "| Alt+n - Numberings method |" << endl << "| Ctrl+o - Element ordering curve |" << endl << "| Ctrl+p - Print to a PDF file |" << endl << "+------------------------------------+" << endl @@ -191,6 +182,7 @@ static void SwitchAttribute(int increment, int &attribute, } else { + vssol->PrepareNumbering(); vssol->PrepareLines(); vssol->Prepare(); } @@ -279,9 +271,20 @@ static void KeyMPressed() SendExposeEvent(); } -static void KeyNPressed() +static void KeyNPressed(GLenum state) { - vssol -> ToggleDrawNumberings(); + if (state & KMOD_ALT) + { + vssol->ToggleParallelNumbering(); + } + else if (state & (KMOD_CTRL | KMOD_GUI)) + { + /* No-op */ + } + else + { + vssol->ToggleDrawNumberings(); + } SendExposeEvent(); } @@ -444,7 +447,7 @@ void VisualizationSceneSolution::Init() shading = Shading::Smooth; drawmesh = 0; draworder = 0; - drawnums = 0; + drawnums = Numbering::NONE; refine_func = 0; have_sol_range = false; @@ -594,6 +597,8 @@ void VisualizationSceneSolution::NewMeshAndSolution( mesh_coarse = new_mc; sol = new_sol; rsol = new_u; + MFEM_VERIFY(new_sol->Size() == mesh->GetNV(), + "New solution vector size does not match the mesh node count."); // If the number of elements changes, recompute the refinement factor if (mesh->GetNE() != old_m->GetNE()) @@ -619,7 +624,6 @@ void VisualizationSceneSolution::NewMeshAndSolution( PrepareOrderingCurve(); } - void VisualizationSceneSolution::GetRefinedDetJ( int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr) { @@ -697,8 +701,10 @@ void VisualizationSceneSolution::GetRefinedDetJ( J.ClearExternalData(); } -void VisualizationSceneSolution::GetRefinedValues( - int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr) +void VisualizationSceneSolution::GetRefinedValues(const int i, + const IntegrationRule &ir, + Vector &vals, DenseMatrix &tr, + const bool do_shrink) { if (drawelems < 2) { @@ -715,15 +721,16 @@ void VisualizationSceneSolution::GetRefinedValues( vals(j) = _LogVal(vals(j)); } - if (shrink != 1.0 || shrinkmat != 1.0) + if (do_shrink && (shrink != 1.0 || shrinkmat != 1.0)) { ShrinkPoints(tr, i, 0, 0); } } -int VisualizationSceneSolution::GetRefinedValuesAndNormals( - int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr, - DenseMatrix &normals) +int VisualizationSceneSolution::GetRefinedValuesAndNormals(const int i, + const IntegrationRule &ir, + Vector &vals, DenseMatrix &tr, + DenseMatrix &normals) { int have_normals = 0; @@ -1825,169 +1832,167 @@ double VisualizationSceneSolution::GetElementLengthScale(int k) void VisualizationSceneSolution::PrepareElementNumbering() { - if (shading == Shading::Noncomforming) - { - PrepareElementNumbering2(); - } - else + auto offset = [&](const int e) { - PrepareElementNumbering1(); - } -} + if (!offsets) { return e; } + if (legacy_parallel_numbering) + { + // std::cout << "\x1b[31m[legacy_parallel_numbering]\x1b[m"; + return e; + } + // std::cout << "\x1b[32m[legacy_parallel_numbering]\x1b[m"; + const int rank = mesh->GetAttribute(e) - 1; + MFEM_VERIFY(rank >= 0 && rank < (int)offsets->size(), + "Invalid rank for element " + std::to_string(e)); + const int nelems = (*offsets)[rank].nelems; + MFEM_VERIFY(e >= nelems, + "Invalid element " + std::to_string(e) + + " for rank " + std::to_string(rank)); + return e - nelems; + }; -void VisualizationSceneSolution::PrepareElementNumbering1() -{ e_nums_buf.clear(); - DenseMatrix pointmat; - Array vertices; - - int ne = mesh->GetNE(); - for (int k = 0; k < ne; k++) + if (shading == Shading::Noncomforming) { - mesh->GetPointMatrix (k, pointmat); - mesh->GetElementVertices (k, vertices); - int nv = vertices.Size(); - - ShrinkPoints(pointmat, k, 0, 0); + IntegrationRule center_ir(1); + DenseMatrix pointmat; + Vector values; - double xs = 0.0; - double ys = 0.0; - double us = 0.0; - for (int j = 0; j < nv; j++) - { - xs += pointmat(0,j); - ys += pointmat(1,j); - us += LogVal((*sol)(vertices[j])); + for (int e = 0; e < mesh->GetNE(); e++) + { + if (!el_attr_to_show[mesh->GetAttribute(e)-1]) { continue; } + center_ir.IntPoint(0) = + Geometries.GetCenter(mesh->GetElementBaseGeometry(e)); + GetRefinedValues (e, center_ir, values, pointmat); + const double xc = pointmat(0,0), yc = pointmat(1,0), uc = values(0); + const double dx = 0.05 * GetElementLengthScale(e); + const double xx[3] = {xc, yc, uc}; + DrawNumberedMarker(e_nums_buf, xx, dx, offset(e)); +#ifdef GLVIS_DEBUG + if (offsets && shrink == 1.0 && shrinkmat == 1.0) + { + constexpr double eps = 1e-12; + const int rank = mesh->GetAttribute(e) - 1; + MFEM_VERIFY(rank >= 0 && rank < (int)offsets->size(), + "Invalid rank"); + const int l_e = offset(e); + const auto &xy = (*offsets)[rank].exy_map.at({l_e,rank}); + MFEM_VERIFY(fabs(xy.x - xc) < eps && fabs(xy.y - yc) < eps, + "Element center does not match expected position"); + } +#endif // GLVIS_DEBUG } - xs /= nv; - ys /= nv; - us /= nv; - - double ds = GetElementLengthScale(k); - double dx = 0.05*ds; - - double xx[3] = {xs,ys,us}; - DrawNumberedMarker(e_nums_buf,xx,dx,k); } - - updated_bufs.emplace_back(&e_nums_buf); -} - -void VisualizationSceneSolution::PrepareElementNumbering2() -{ - IntegrationRule center_ir(1); - DenseMatrix pointmat; - Vector values; - - e_nums_buf.clear(); - - int ne = mesh->GetNE(); - for (int i = 0; i < ne; i++) + else { - if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; } - - center_ir.IntPoint(0) = - Geometries.GetCenter(mesh->GetElementBaseGeometry(i)); - GetRefinedValues (i, center_ir, values, pointmat); - - double xc = pointmat(0,0); - double yc = pointmat(1,0); - double uc = values(0); - - double ds = GetElementLengthScale(i); - double dx = 0.05*ds; + DenseMatrix pointmat; + Array vertices; - double xx[3] = {xc,yc,uc}; - DrawNumberedMarker(e_nums_buf,xx,dx,i); + for (int e = 0; e < mesh->GetNE(); e++) + { + if (!el_attr_to_show[mesh->GetAttribute(e) - 1]) { continue; } + mesh->GetPointMatrix (e, pointmat); + mesh->GetElementVertices (e, vertices); + const int nv = vertices.Size(); + ShrinkPoints(pointmat, e, 0, 0); + double xs = 0.0, ys = 0.0, us = 0.0; + for (int j = 0; j < nv; j++) + { + xs += pointmat(0,j); + ys += pointmat(1,j); + us += LogVal((*sol)(vertices[j])); + } + xs /= nv; + ys /= nv; + us /= nv; +#ifdef GLVIS_DEBUG + if (offsets && shrink == 1.0 && shrinkmat == 1.0) + { + constexpr double eps = 1e-12; + const int rank = mesh->GetAttribute(e) - 1; + MFEM_VERIFY(rank >= 0 && rank < (int)offsets->size(), + "Invalid rank"); + const auto &xy = (*offsets)[rank].exy_map.at({offset(e), rank}); + MFEM_VERIFY(fabs(xy.x - xs) < eps && fabs(xy.y - ys) < eps, + "Element center does not match expected position"); + } +#endif // GLVIS_DEBUG + const double dx = 0.05 * GetElementLengthScale(e); + const double xx[3] = {xs, ys, us}; + DrawNumberedMarker(e_nums_buf, xx, dx, offset(e)); + } } - updated_bufs.emplace_back(&e_nums_buf); } void VisualizationSceneSolution::PrepareVertexNumbering() { - if (shading == Shading::Noncomforming) - { - PrepareVertexNumbering2(); - } - else + auto offset = [&](const int e, const int v) { - PrepareVertexNumbering1(); - } -} + if (!offsets) { return v; } + if (legacy_parallel_numbering) + { + // std::cout << "\x1b[31m[legacy_parallel_numbering]\x1b[m"; + return v; + } + // std::cout << "\x1b[32m[legacy_parallel_numbering]\x1b[m"; + const int rank = mesh->GetAttribute(e) - 1; + MFEM_VERIFY(rank >= 0 && rank < (int)offsets->size(), + "Invalid rank for element " + std::to_string(e)); + const int nverts = (*offsets)[rank].nverts; + MFEM_VERIFY(v >= nverts, + "Invalid vertex " + std::to_string(v) + + " for element " + std::to_string(e)); + return v - nverts; + }; -void VisualizationSceneSolution::PrepareVertexNumbering1() -{ v_nums_buf.clear(); - DenseMatrix pointmat; Array vertices; - // Draw the vertices for each element. This is redundant, except when the - // elements or domains are shrunk. - - const int ne = mesh->GetNE(); - for (int k = 0; k < ne; k++) + if (shading == Shading::Noncomforming) { - mesh->GetPointMatrix (k, pointmat); - mesh->GetElementVertices (k, vertices); - int nv = vertices.Size(); - - ShrinkPoints(pointmat, k, 0, 0); - - double ds = GetElementLengthScale(k); - double xs = 0.05*ds; - - for (int j = 0; j < nv; j++) + Vector values; + for (int i = 0; i < mesh->GetNE(); i++) { - double x = pointmat(0,j); - double y = pointmat(1,j); - double u = LogVal((*sol)(vertices[j])); - - double xx[3] = {x,y,u}; - DrawNumberedMarker(v_nums_buf,xx,xs,vertices[j]); + if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; } + mesh->GetElementVertices (i, vertices); + const IntegrationRule &vert_ir = + *Geometries.GetVertices(mesh->GetElementBaseGeometry(i)); + GetRefinedValues (i, vert_ir, values, pointmat); + const double xs = 0.05 * GetElementLengthScale(i); + for (int j = 0; j < values.Size(); j++) + { + double xv = pointmat(0, j); + double yv = pointmat(1, j); + double u = values[j]; + double xx[3] = {xv, yv, u}; + DrawNumberedMarker(v_nums_buf, xx, xs, offset(i, vertices[j])); + } } } - - updated_bufs.emplace_back(&v_nums_buf); -} - -void VisualizationSceneSolution::PrepareVertexNumbering2() -{ - DenseMatrix pointmat; - Vector values; - Array vertices; - - v_nums_buf.clear(); - - const int ne = mesh->GetNE(); - for (int i = 0; i < ne; i++) + else { - if (!el_attr_to_show[mesh->GetAttribute(i)-1]) { continue; } - - mesh->GetElementVertices (i, vertices); - - const IntegrationRule &vert_ir = - *Geometries.GetVertices(mesh->GetElementBaseGeometry(i)); - - GetRefinedValues (i, vert_ir, values, pointmat); - - double ds = GetElementLengthScale(i); - double xs = 0.05*ds; - - for (int j = 0; j < values.Size(); j++) + // Draw the vertices for each element. This is redundant, + // except when the elements or domains are shrunk. + for (int e = 0; e < mesh->GetNE(); e++) { - double xv = pointmat(0, j); - double yv = pointmat(1, j); - - double u = values[j]; - - double xx[3] = {xv,yv,u}; - DrawNumberedMarker(v_nums_buf,xx,xs,vertices[j]); + if (!el_attr_to_show[mesh->GetAttribute(e) - 1]) { continue; } + mesh->GetPointMatrix(e, pointmat); + mesh->GetElementVertices(e, vertices); + const int nv = vertices.Size(); + const double xs = 0.05 * GetElementLengthScale(e); + for (int j = 0; j < nv; j++) + { + double x = pointmat(0,j); + double y = pointmat(1,j); + double u = LogVal((*sol)(vertices[j])); + double xx[3] = {x, y, u}; + DrawNumberedMarker(v_nums_buf, xx, xs, offset(e, vertices[j])); + } } } - updated_bufs.emplace_back(&v_nums_buf); } @@ -1998,39 +2003,128 @@ void VisualizationSceneSolution::PrepareEdgeNumbering() f_nums_buf.clear(); + Vector vals; DenseMatrix p; - Array vertices; - Array edges; - Array edges_ori; + Array vertices, edges, edges_ori; + + auto offset = [&](const int e, const int i) + { + const int edge = edges[i]; + if (!offsets) { return edge; } + if (legacy_parallel_numbering) + { + // std::cout << "\x1b[31m[legacy_parallel_numbering]\x1b[m"; + return edge; + } + // std::cout << "\x1b[32m[legacy_parallel_numbering]\x1b[m"; + const int rank = mesh->GetAttribute(e) - 1; + MFEM_VERIFY(rank >= 0 && rank < (int)offsets->size(), + "Invalid rank for element " + std::to_string(e)); + const int nedges = (*offsets)[rank].nedges; + MFEM_VERIFY(edge >= (int)nedges, + "Invalid edge " + std::to_string(edge) + + " for element " + std::to_string(e)); + return edge - nedges; + }; - const int ne = mesh->GetNE(); - for (int k = 0; k < ne; k++) + if (shading == Shading::Flat || shading == Shading::Smooth) { - mesh->GetElementEdges(k, edges, edges_ori); + for (int e = 0; e < mesh->GetNE(); e++) + { + if (!el_attr_to_show[mesh->GetAttribute(e) - 1]) { continue; } + mesh->GetElementEdges(e, edges, edges_ori); + const double dx = 0.05 * GetElementLengthScale(e); + for (int i = 0; i < edges.Size(); i++) + { + mesh->GetEdgeVertices(edges[i], vertices); + p.SetSize(mesh->Dimension(), vertices.Size()); + p.SetCol(0, mesh->GetVertex(vertices[0])); + p.SetCol(1, mesh->GetVertex(vertices[1])); + ShrinkPoints(p, e, 0, 0); + const double m[2] = {0.5 * (p(0,0) + p(0,1)), 0.5 * (p(1,0) + p(1,1))}; + const double u = LogVal(0.5 * ((*sol)(vertices[0]) + (*sol)(vertices[1]))); + const double xx[3] = {m[0], m[1], u}; + DrawNumberedMarker(f_nums_buf, xx, dx, offset(e,i)); + } + } + } + else if (shading == Shading::Noncomforming) + { + for (int e = 0; e < mesh->GetNE(); e++) + { + if (!el_attr_to_show[mesh->GetAttribute(e) - 1]) { continue; } + mesh->GetElementEdges(e, edges, edges_ori); + const auto dx = 0.05 * GetElementLengthScale(e); + const auto geom = mesh->GetElementBaseGeometry(e); + MFEM_VERIFY(geom == Geometry::TRIANGLE || geom == Geometry::SQUARE, + "Only TRIANGLE and SQUARE geometries are supported."); + const auto *RefG = GLVisGeometryRefiner.Refine(geom, 2, 2); + GetRefinedValues(e, RefG->RefPts, vals, p); + const int ij3[3] = { 1, 4, 3 }, ie3[3] = { 0, 1, 2 }; + const int ij4[4] = { 1, 3, 5, 7 }, ie4[4] = { 0, 3, 1, 2 }; + const int *ij = geom == Geometry::TRIANGLE ? ij3 : ij4; + const int *ie = geom == Geometry::TRIANGLE ? ie3 : ie4; + for (int i = 0; i < edges.Size(); i++) + { + const int j = ij[i]; + const double xx[3] = { p(0,j), p(1,j), vals(j) }; + DrawNumberedMarker(f_nums_buf, xx, dx, offset(e,ie[i])); + } + } + } + else { MFEM_ABORT("Shading not supported"); } + updated_bufs.emplace_back(&f_nums_buf); +} - double ds = GetElementLengthScale(k); - double xs = 0.05 * ds; +void VisualizationSceneSolution::PrepareDofNumbering() +{ + Vector vals; + DenseMatrix tr; + Array dofs; - for (int i = 0; i < edges.Size(); i++) - { - mesh->GetEdgeVertices(edges[i], vertices); + d_nums_buf.clear(); - p.SetSize(mesh->Dimension(), vertices.Size()); - p.SetCol(0, mesh->GetVertex(vertices[0])); - p.SetCol(1, mesh->GetVertex(vertices[1])); + auto *rsol_fes = rsol->FESpace(); + FiniteElementSpace rdof_fes(mesh, rsol_fes->FEColl()); + H1_FECollection h1_fec(1, mesh->Dimension()); + FiniteElementSpace h1_fes(mesh, &h1_fec); + MFEM_VERIFY(sol->Size() == h1_fes.GetNDofs(), + "Flat space does not match the solution size"); + GridFunction h1_sol(&h1_fes, sol->GetData()); + const bool non_conforming_shading = shading == Shading::Noncomforming; - ShrinkPoints(p, k, 0, 0); + auto offset = [&](const int e, const int q) + { + if (!offsets) { return dofs[q]; } + if (legacy_parallel_numbering) + { + // std::cout << "\x1b[31m[legacy_parallel_numbering]\x1b[m"; + return dofs[q]; + } + // std::cout << "\x1b[32m[legacy_parallel_numbering]\x1b[m"; + const int rank = mesh->GetAttribute(e) - 1; + return (*offsets)[rank][ {e,q}]; + }; - const double m[2] = {0.5 * (p(0,0) + p(0,1)), 0.5 * (p(1,0) + p(1,1))}; - // TODO: figure out something better... - double u = LogVal(0.5 * ((*sol)(vertices[0]) + (*sol)(vertices[1]))); + for (int e = 0; e < mesh->GetNE(); e++) + { + if (!el_attr_to_show[mesh->GetAttribute(e) - 1]) { continue; } + const auto dx = 0.05 * GetElementLengthScale(e); + const auto &ir = rsol_fes->GetFE(e)->GetNodes(); + const bool do_shrink = non_conforming_shading; + GetRefinedValues(e, ir, vals, tr, do_shrink); + rdof_fes.GetElementDofs(e, dofs); + rdof_fes.AdjustVDofs(dofs); - double xx[3] = {m[0], m[1], u}; - DrawNumberedMarker(f_nums_buf, xx, xs, edges[i]); + for (int q = 0; q < ir.GetNPoints(); q++) + { + const real_t z = non_conforming_shading ? vals[q] : + h1_sol.GetValue(e, ir.IntPoint(q)); + const real_t x[3] = {tr(0,q), tr(1,q), z}; + DrawNumberedMarker(d_nums_buf, x, dx, offset(e,q)); } } - - updated_bufs.emplace_back(&f_nums_buf); + updated_bufs.emplace_back(&d_nums_buf); } void VisualizationSceneSolution::PrepareOrderingCurve() @@ -2129,22 +2223,35 @@ void VisualizationSceneSolution::PrepareNumbering(bool invalidate) e_nums_buf_ready = false; v_nums_buf_ready = false; f_nums_buf_ready = false; + d_nums_buf_ready = false; + } + else + { + static const char *numbering[(int)Numbering::MAX] = + { "None", "Elements", "Edges", "Vertices", "DOFs" }; + std::cout << "Numbering : " << numbering[(int)drawnums] << std::endl; } - if (drawnums == 1 && !e_nums_buf_ready) + + if (drawnums == Numbering::ELEMENTS && !e_nums_buf_ready) { PrepareElementNumbering(); e_nums_buf_ready = true; } - if (drawnums == 2 && !f_nums_buf_ready) + if (drawnums == Numbering::EDGES && !f_nums_buf_ready) { PrepareEdgeNumbering(); f_nums_buf_ready = true; } - if (drawnums == 3 && !v_nums_buf_ready) + if (drawnums == Numbering::VERTICES && !v_nums_buf_ready) { PrepareVertexNumbering(); v_nums_buf_ready = true; } + if (drawnums == Numbering::DOFS && !d_nums_buf_ready) + { + PrepareDofNumbering(); + d_nums_buf_ready = true; + } } void VisualizationSceneSolution::PrepareLines2() @@ -2554,18 +2661,27 @@ gl3::SceneInfo VisualizationSceneSolution::GetSceneObjs() } // draw numberings - if (drawnums == 1) + if (drawnums == Numbering::ELEMENTS) { scene.queue.emplace_back(params, &e_nums_buf); } - else if (drawnums == 2) + else if (drawnums == Numbering::EDGES) { scene.queue.emplace_back(params, &f_nums_buf); } - else if (drawnums == 3) + else if (drawnums == Numbering::VERTICES) { scene.queue.emplace_back(params, &v_nums_buf); } + else if (drawnums == Numbering::DOFS) + { + scene.queue.emplace_back(params, &d_nums_buf); + } + else + { + MFEM_VERIFY(drawnums == Numbering::NONE, + "Unsupported drawnums value: " << (int)drawnums); + } // draw orderings -- "black" modes if (draworder == 3) diff --git a/lib/vssolution.hpp b/lib/vssolution.hpp index 86b848ca..6ea110d7 100644 --- a/lib/vssolution.hpp +++ b/lib/vssolution.hpp @@ -12,24 +12,22 @@ #ifndef GLVIS_VSSOLUTION_HPP #define GLVIS_VSSOLUTION_HPP -#include "mfem.hpp" -using namespace mfem; - -#include "sdl.hpp" #include "gl/types.hpp" #include "vsdata.hpp" -#include +#include // Visualization header file class VisualizationSceneSolution : public VisualizationSceneScalarData { protected: - Vector *v_normals; - GridFunction *rsol; + mfem::Vector *v_normals; + mfem::GridFunction *rsol; - int drawmesh, drawelems, drawnums, draworder; + int drawmesh, drawelems, draworder; + enum class Numbering { NONE, ELEMENTS, EDGES, VERTICES, DOFS, MAX }; + Numbering drawnums; int drawbdr, draw_cp; int refine_func = 0; @@ -44,9 +42,8 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData bool e_nums_buf_ready = false; bool v_nums_buf_ready = false; bool f_nums_buf_ready = false; - gl3::GlDrawable e_nums_buf; - gl3::GlDrawable v_nums_buf; - gl3::GlDrawable f_nums_buf; + bool d_nums_buf_ready = false; + gl3::GlDrawable e_nums_buf, v_nums_buf, f_nums_buf, d_nums_buf; gl3::GlDrawable lcurve_buf; gl3::GlDrawable line_buf; @@ -61,20 +58,22 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData void FindNewBox(double rx[], double ry[], double rval[]); void DrawCPLine(gl3::GlBuilder& bld, - DenseMatrix &pointmat, Vector &values, Array &ind); + mfem::DenseMatrix &pointmat, mfem::Vector &values, mfem::Array &ind); - void GetRefinedDetJ(int i, const IntegrationRule &ir, - Vector &vals, DenseMatrix &tr); + void GetRefinedDetJ(int i, const mfem::IntegrationRule &ir, + mfem::Vector &vals, mfem::DenseMatrix &tr); // redefined for vector solution - virtual void GetRefinedValues(int i, const IntegrationRule &ir, - Vector &vals, DenseMatrix &tr); - virtual int GetRefinedValuesAndNormals(int i, const IntegrationRule &ir, - Vector &vals, DenseMatrix &tr, - DenseMatrix &normals); - - void DrawLevelCurves(gl3::GlBuilder& buf, Array &RG, DenseMatrix &pointmat, - Vector &values, int sides, Array &lvl, + virtual void GetRefinedValues(const int i, const mfem::IntegrationRule &ir, + mfem::Vector &vals, mfem::DenseMatrix &tr, + const bool do_shrink = true); + virtual int GetRefinedValuesAndNormals(int i, const mfem::IntegrationRule &ir, + mfem::Vector &vals, mfem::DenseMatrix &tr, + mfem::DenseMatrix &normals); + + void DrawLevelCurves(gl3::GlBuilder& buf, mfem::Array &RG, + mfem::DenseMatrix &pointmat, + mfem::Vector &values, int sides, mfem::Array &lvl, int flat = 0); int GetFunctionAutoRefineFactor() override; @@ -84,20 +83,22 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData public: int attr_to_show, bdr_attr_to_show; - Array el_attr_to_show, bdr_el_attr_to_show; + mfem::Array el_attr_to_show, bdr_el_attr_to_show; VisualizationSceneSolution(); - VisualizationSceneSolution(Mesh &m, Vector &s, Mesh *mc = NULL, - Vector *normals = NULL); + VisualizationSceneSolution(mfem::Mesh &m, mfem::Vector &s, + mfem::Mesh *mc = nullptr, + mfem::Vector *normals = nullptr); virtual ~VisualizationSceneSolution(); std::string GetHelpString() const override; - void SetGridFunction(GridFunction & u) { rsol = &u; } + void SetGridFunction(mfem::GridFunction & u) { rsol = &u; } - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol, - GridFunction *new_u = NULL); + void NewMeshAndSolution(mfem::Mesh *new_m, mfem::Mesh *new_mc, + mfem::Vector *new_sol, + mfem::GridFunction *new_u = nullptr); void SetNewScalingFromBox() override; void FindNewBox(bool prepare) override; @@ -131,12 +132,9 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData void PrepareNumbering(bool invalidate = true); void PrepareElementNumbering(); - void PrepareElementNumbering1(); - void PrepareElementNumbering2(); void PrepareVertexNumbering(); - void PrepareVertexNumbering1(); - void PrepareVertexNumbering2(); void PrepareEdgeNumbering(); + void PrepareDofNumbering(); void PrepareCP(); @@ -157,13 +155,22 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData // 3 - no arrows (black), 4 - with arrows (black) void ToggleDrawOrdering() { draworder = (draworder+1)%5; } - // 0 - none, 1 - elements, 2 - edges, 3 - vertices + // 0 - none, 1 - elements, 2 - edges, 3 - vertices, 4 - DOFs void ToggleDrawNumberings() { - drawnums = (drawnums+1)%4; + drawnums = (Numbering) (((int)drawnums + 1) % (int)Numbering::MAX); PrepareNumbering(false); } + void ToggleParallelNumbering() + { + legacy_parallel_numbering = !legacy_parallel_numbering; + std::cout << "Numbering : " + << (legacy_parallel_numbering ? "global": "local") + << std::endl; + PrepareNumbering(true); + } + void SetShading(Shading, bool) override; void ToggleShading() override; @@ -174,7 +181,7 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData void SetRefineFactors(int, int) override; void AutoRefine() override; - void ToggleAttributes(Array &attr_list) override; + void ToggleAttributes(mfem::Array &attr_list) override; virtual void SetDrawMesh(int i) { drawmesh = i % 3; } virtual int GetDrawMesh() { return drawmesh; } @@ -183,4 +190,4 @@ class VisualizationSceneSolution : public VisualizationSceneScalarData void DrawNumberedMarker(gl3::GlDrawable& buff, const double x[3], double dx, int n); -#endif +#endif // GLVIS_VSSOLUTION_HPP diff --git a/lib/vssolution3d.cpp b/lib/vssolution3d.cpp index 4d927da8..72fb13b4 100644 --- a/lib/vssolution3d.cpp +++ b/lib/vssolution3d.cpp @@ -14,12 +14,13 @@ #include #include -#include "mfem.hpp" -#include "visual.hpp" +#include + #include "palettes.hpp" -using namespace mfem; -using namespace std; +#include "vssolution3d.hpp" +using namespace std; +using namespace mfem; thread_local VisualizationSceneSolution3d *vssol3d; extern thread_local GeometryRefiner GLVisGeometryRefiner; diff --git a/lib/vssolution3d.hpp b/lib/vssolution3d.hpp index 0448e128..b36d88f6 100644 --- a/lib/vssolution3d.hpp +++ b/lib/vssolution3d.hpp @@ -12,11 +12,9 @@ #ifndef GLVIS_VSSOLUTION_3D_HPP #define GLVIS_VSSOLUTION_3D_HPP -#include "mfem.hpp" +#include #include "gl/types.hpp" #include "vsdata.hpp" -#include -using namespace mfem; class VisualizationSceneSolution3d : public VisualizationSceneScalarData { @@ -41,69 +39,70 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData double *node_pos; int nlevels; - Array levels; + mfem::Array levels; - GridFunction *GridF; + mfem::GridFunction *GridF; void Init(); void GetFaceNormals(const int FaceNo, const int side, - const IntegrationRule &ir, DenseMatrix &normals); + const mfem::IntegrationRule &ir, mfem::DenseMatrix &normals); void DrawRefinedSurf (int n, double *points, int elem, int func, int part = -1); - void DrawRefinedSurf (int n, DenseMatrix &pointmat, - Vector &values, Array &RefGeoms); - void DrawRefinedSurfLevelLines (int n, DenseMatrix &pointmat, - Vector &values, Array &RefGeoms); - void DrawRefinedSurfEdges (int n, DenseMatrix &pointmat, - Vector &values, Array &RefEdges, + void DrawRefinedSurf (int n, mfem::DenseMatrix &pointmat, + mfem::Vector &values, mfem::Array &RefGeoms); + void DrawRefinedSurfLevelLines (int n, mfem::DenseMatrix &pointmat, + mfem::Vector &values, mfem::Array &RefGeoms); + void DrawRefinedSurfEdges (int n, mfem::DenseMatrix &pointmat, + mfem::Vector &values, mfem::Array &RefEdges, int part = -1); void DrawBdrElCoarseSurfEdges(gl3::GlBuilder &line, int be, - DenseMatrix &pointmat, const IntegrationRule *ir = NULL, - Array *idxs = NULL); - void DrawFaceCoarseSurfEdges(gl3::GlBuilder &line, int f, DenseMatrix &pointmat, - const IntegrationRule *ir = NULL, Array *idxs = NULL); + mfem::DenseMatrix &pointmat, const mfem::IntegrationRule *ir = NULL, + mfem::Array *idxs = NULL); + void DrawFaceCoarseSurfEdges(gl3::GlBuilder &line, int f, + mfem::DenseMatrix &pointmat, + const mfem::IntegrationRule *ir = NULL, mfem::Array *idxs = NULL); void DrawCoarseSurfEdges(gl3::GlBuilder &line, int f, int e1, int e2, - DenseMatrix &pointmat, const IntegrationRule *ir = NULL, - Array *idxs = NULL); - void LiftRefinedSurf (int n, DenseMatrix &pointmat, - Vector &values, int *RG); - void DrawTetLevelSurf(gl3::GlDrawable& target, const DenseMatrix &verts, - const Vector &vals, - const int *ind, const Array &levels, - const DenseMatrix *grad = NULL); - - static int GetPyramidFaceSplits(const Array &quad_diag, - const Array &faces, - const Array &ofaces); + mfem::DenseMatrix &pointmat, const mfem::IntegrationRule *ir = NULL, + mfem::Array *idxs = NULL); + void LiftRefinedSurf (int n, mfem::DenseMatrix &pointmat, + mfem::Vector &values, int *RG); + void DrawTetLevelSurf(gl3::GlDrawable& target, const mfem::DenseMatrix &verts, + const mfem::Vector &vals, + const int *ind, const mfem::Array &levels, + const mfem::DenseMatrix *grad = NULL); + + static int GetPyramidFaceSplits(const mfem::Array &quad_diag, + const mfem::Array &faces, + const mfem::Array &ofaces); void DrawRefinedPyramidLevelSurf(gl3::GlDrawable& target, - const DenseMatrix &verts, - const Vector &vals, const int *RG, + const mfem::DenseMatrix &verts, + const mfem::Vector &vals, const int *RG, const int np, const int face_splits, - const DenseMatrix *grad = NULL); + const mfem::DenseMatrix *grad = NULL); - static int GetWedgeFaceSplits(const Array &quad_diag, - const Array &faces, - const Array &ofaces); + static int GetWedgeFaceSplits(const mfem::Array &quad_diag, + const mfem::Array &faces, + const mfem::Array &ofaces); void DrawRefinedWedgeLevelSurf(gl3::GlDrawable& target, - const DenseMatrix &verts, - const Vector &vals, const int *RG, + const mfem::DenseMatrix &verts, + const mfem::Vector &vals, const int *RG, const int np, const int face_splits, - const DenseMatrix *grad = NULL); + const mfem::DenseMatrix *grad = NULL); - static int GetHexFaceSplits(const Array &quad_diag, - const Array &faces, - const Array &ofaces); + static int GetHexFaceSplits(const mfem::Array &quad_diag, + const mfem::Array &faces, + const mfem::Array &ofaces); void DrawRefinedHexLevelSurf(gl3::GlDrawable& target, - const DenseMatrix &verts, - const Vector &vals, const int *RG, + const mfem::DenseMatrix &verts, + const mfem::Vector &vals, const int *RG, const int nh, const int face_splits, - const DenseMatrix *grad = NULL); + const mfem::DenseMatrix *grad = NULL); int GetFunctionAutoRefineFactor() override; - bool CheckPositions(Array &vertices) const + bool CheckPositions(mfem::Array &vertices) const { int n = 0; for (int j = 0; j < vertices.Size(); j++) @@ -117,15 +116,16 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData int TimesToRefine; double FaceShiftScale; - Array bdr_attr_to_show; + mfem::Array bdr_attr_to_show; VisualizationSceneSolution3d(); - VisualizationSceneSolution3d(Mesh & m, Vector & s, Mesh *mc); + VisualizationSceneSolution3d(mfem::Mesh & m, mfem::Vector & s, mfem::Mesh *mc); - void SetGridFunction (GridFunction *gf) { GridF = gf; } + void SetGridFunction(mfem::GridFunction *gf) { GridF = gf; } - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, Vector *new_sol, - GridFunction *new_u = NULL); + void NewMeshAndSolution(mfem::Mesh *new_m, mfem::Mesh *new_mc, + mfem::Vector *new_sol, + mfem::GridFunction *new_u = nullptr); virtual ~VisualizationSceneSolution3d(); @@ -159,19 +159,19 @@ class VisualizationSceneSolution3d : public VisualizationSceneScalarData void ToggleShading() override; void SetRefineFactors(int, int) override; void AutoRefine() override; - void ToggleAttributes(Array &attr_list) override; + void ToggleAttributes(mfem::Array &attr_list) override; void FindNodePos(); void CuttingPlaneFunc (int type); // func: 0 - draw surface, 1 - draw level lines void CutRefinedElement(gl3::GlDrawable& target, - const DenseMatrix &verts, const Vector &vert_dist, - const Vector &vals, const Geometry::Type geom, + const mfem::DenseMatrix &verts, const mfem::Vector &vert_dist, + const mfem::Vector &vals, const mfem::Geometry::Type geom, const int *elems, int num_elems, int func); void CutRefinedFace(gl3::GlDrawable& target, - const DenseMatrix &verts, const Vector &vert_dist, - const Vector &vals, const Geometry::Type geom, + const mfem::DenseMatrix &verts, const mfem::Vector &vert_dist, + const mfem::Vector &vals, const mfem::Geometry::Type geom, const int *faces, int num_faces); void CPPrepare(); void CPMoved(); diff --git a/lib/vsvector.cpp b/lib/vsvector.cpp index 2b5efda4..9a55109d 100644 --- a/lib/vsvector.cpp +++ b/lib/vsvector.cpp @@ -14,8 +14,8 @@ #include #include -#include "mfem.hpp" -#include "visual.hpp" +#include +#include "vsvector.hpp" using namespace mfem; using namespace std; @@ -532,8 +532,10 @@ VisualizationSceneVector::~VisualizationSceneVector() } } -void VisualizationSceneVector::GetRefinedValues( - int i, const IntegrationRule &ir, Vector &vals, DenseMatrix &tr) +void VisualizationSceneVector::GetRefinedValues(const int i, + const IntegrationRule &ir, + Vector &vals, DenseMatrix &tr, + const bool do_shrink) { if (drawelems < 2) { @@ -638,7 +640,7 @@ void VisualizationSceneVector::GetRefinedValues( vals(j) = _LogVal(vals(j)); } - if (shrink != 1.0 || shrinkmat != 1.0) + if (do_shrink && (shrink != 1.0 || shrinkmat != 1.0)) { ShrinkPoints(tr, i, 0, 0); } @@ -1020,14 +1022,23 @@ gl3::SceneInfo VisualizationSceneVector::GetSceneObjs() } // draw numberings - if (drawnums == 1) + if (drawnums == Numbering::ELEMENTS) { scene.queue.emplace_back(params, &e_nums_buf); } - else if (drawnums == 2) + else if (drawnums == Numbering::VERTICES) { scene.queue.emplace_back(params, &v_nums_buf); } + else if (drawnums == Numbering::EDGES) + { + scene.queue.emplace_back(params, &f_nums_buf); + } + else if (drawnums == Numbering::DOFS) + { + scene.queue.emplace_back(params, &d_nums_buf); + } + else { /* Numbering::NONE */ } if (drawvector == 1 || drawvector > 3) { diff --git a/lib/vsvector.hpp b/lib/vsvector.hpp index c7453bd2..870db3ad 100644 --- a/lib/vsvector.hpp +++ b/lib/vsvector.hpp @@ -12,29 +12,29 @@ #ifndef GLVIS_VSVECTOR_HPP #define GLVIS_VSVECTOR_HPP -#include "mfem.hpp" +#include #include "gl/types.hpp" #include "vssolution.hpp" -using namespace mfem; class VisualizationSceneVector : public VisualizationSceneSolution { protected: - Vector *solx, *soly; + mfem::Vector *solx, *soly; int drawdisp, drawvector; gl3::GlDrawable vector_buf; gl3::GlDrawable displine_buf; - GridFunction *VecGridF; + mfem::GridFunction *VecGridF; void Init(); - void GetRefinedValues(int i, const IntegrationRule &ir, - Vector &vals, DenseMatrix &tr) override; - int GetRefinedValuesAndNormals(int i, const IntegrationRule &ir, - Vector &vals, DenseMatrix &tr, - DenseMatrix &normals) override; + void GetRefinedValues(const int i, const mfem::IntegrationRule &ir, + mfem::Vector &vals, mfem::DenseMatrix &tr, + const bool do_shrink = true) override; + int GetRefinedValuesAndNormals(int i, const mfem::IntegrationRule &ir, + mfem::Vector &vals,mfem::DenseMatrix &tr, + mfem::DenseMatrix &normals) override; double (*Vec2Scalar)(double, double); @@ -42,16 +42,17 @@ class VisualizationSceneVector : public VisualizationSceneSolution double maxlen; - Vector vc0; - IsoparametricTransformation T0; + mfem::Vector vc0; + mfem::IsoparametricTransformation T0; int GetFunctionAutoRefineFactor() override; public: - VisualizationSceneVector(Mesh &m, Vector &sx, Vector &sy, Mesh *mc = NULL); - VisualizationSceneVector(GridFunction &vgf); + VisualizationSceneVector(mfem::Mesh &m, mfem::Vector &sx, mfem::Vector &sy, + mfem::Mesh *mc = nullptr); + VisualizationSceneVector(mfem::GridFunction &vgf); - void NewMeshAndSolution(GridFunction &vgf, Mesh *mc = NULL); + void NewMeshAndSolution(mfem::GridFunction &vgf, mfem::Mesh *mc = nullptr); virtual ~VisualizationSceneVector(); diff --git a/lib/vsvector3d.cpp b/lib/vsvector3d.cpp index d66059f2..ae322bbb 100644 --- a/lib/vsvector3d.cpp +++ b/lib/vsvector3d.cpp @@ -14,8 +14,7 @@ #include #include -#include "mfem.hpp" -#include "visual.hpp" +#include "vsvector3d.hpp" using namespace mfem; using namespace std; diff --git a/lib/vsvector3d.hpp b/lib/vsvector3d.hpp index b32fe3ea..7c1b9c56 100644 --- a/lib/vsvector3d.hpp +++ b/lib/vsvector3d.hpp @@ -12,38 +12,40 @@ #ifndef GLVIS_VSVECTOR_3D_HPP #define GLVIS_VSVECTOR_3D_HPP -#include "mfem.hpp" +#include #include "gl/types.hpp" -using namespace mfem; +#include "vssolution3d.hpp" class VisualizationSceneVector3d : public VisualizationSceneSolution3d { protected: - Vector *solx, *soly, *solz; + mfem::Vector *solx, *soly, *solz; int drawvector, scal_func; double mesh_volume; gl3::GlDrawable vector_buf; gl3::GlDrawable displine_buf; - GridFunction *VecGridF; - FiniteElementSpace *sfes; + mfem::GridFunction *VecGridF; + mfem::FiniteElementSpace *sfes; void Init(); - Array vflevel; - Array dvflevel; + mfem::Array vflevel; + mfem::Array dvflevel; int GetFunctionAutoRefineFactor() override; public: int ianim, ianimd, ianimmax, drawdisp; - VisualizationSceneVector3d(Mesh & m, Vector & sx, Vector & sy, Vector & sz, - Mesh *mc = NULL); - VisualizationSceneVector3d (GridFunction &vgf, Mesh *mc = NULL); + VisualizationSceneVector3d(mfem::Mesh & m, mfem::Vector & sx, mfem::Vector & sy, + mfem::Vector & sz, + mfem::Mesh *mc = nullptr); + VisualizationSceneVector3d(mfem::GridFunction &vgf, mfem::Mesh *mc = nullptr); - void NewMeshAndSolution(Mesh *new_m, Mesh *new_mc, GridFunction *new_v); + void NewMeshAndSolution(mfem::Mesh *new_m, mfem::Mesh *new_mc, + mfem::GridFunction *new_v); virtual ~VisualizationSceneVector3d(); diff --git a/makefile b/makefile index 17548919..89dcab0b 100644 --- a/makefile +++ b/makefile @@ -250,14 +250,15 @@ Ccc = $(strip $(CC) $(CFLAGS) $(GL_OPTS)) # generated with 'echo lib/gl/*.c* lib/*.c*', does not include lib/*.m (Obj-C) ALL_SOURCE_FILES = \ - lib/gl/renderer.cpp lib/gl/renderer_core.cpp lib/gl/renderer_ff.cpp \ - lib/gl/shader.cpp lib/gl/types.cpp lib/aux_js.cpp lib/aux_vis.cpp \ - lib/coll_reader.cpp lib/data_state.cpp lib/file_reader.cpp \ - lib/font.cpp lib/gl2ps.c lib/gltf.cpp lib/material.cpp \ - lib/openglvis.cpp lib/palettes.cpp lib/palettes_base.cpp lib/sdl.cpp \ - lib/sdl_helper.cpp lib/sdl_main.cpp lib/sdl_windows.cpp \ - lib/sdl_x11.cpp lib/stream_reader.cpp lib/threads.cpp lib/vsdata.cpp \ - lib/vssolution.cpp lib/vssolution3d.cpp lib/vsvector.cpp \ + lib/gl/renderer_core.cpp lib/gl/renderer_ff.cpp lib/gl/renderer.cpp \ + lib/gl/shader.cpp lib/gl/types.cpp lib/aux_js.cpp lib/aux_vis.cpp \ + lib/coll_reader.cpp lib/data_state.cpp lib/file_reader.cpp \ + lib/font.cpp lib/gl2ps.c lib/gltf.cpp lib/material.cpp \ + lib/openglvis.cpp lib/palettes_base.cpp lib/palettes_default.cpp \ + lib/palettes.cpp lib/sdl_helper.cpp lib/sdl_main.cpp \ + lib/sdl_windows.cpp lib/sdl_x11.cpp lib/sdl.cpp \ + lib/stream_reader.cpp lib/threads.cpp lib/vsdata.cpp \ + lib/vssolution.cpp lib/vssolution3d.cpp lib/vsvector.cpp \ lib/vsvector3d.cpp OBJC_SOURCE_FILES = $(if $(NOTMAC),,lib/sdl_mac.mm) DESKTOP_ONLY_SOURCE_FILES = \ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4a4ef136..1e9cf3fb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -31,6 +31,7 @@ set(stream_tests "ex27" "ex3" "ex5" + "ex6-dofs-numbering" "ex9" "klein-bottle" "laghos" diff --git a/tests/data b/tests/data index b8092cca..606b2e29 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit b8092cca36e282e36c72456cee2e63d07d86c3c8 +Subproject commit 606b2e298b1c6ac225ed137542f96894218f9084