Compare commits

..
Author SHA1 Message Date
Stowell, Mark L. ef5f729245 Merge remote-tracking branch 'origin/master' into aniso-diffusion-dev
# Conflicts:
#	fem/bilininteg.hpp
#	fem/coefficient.cpp
#	fem/coefficient.hpp
#	linalg/hypre.cpp
#	linalg/hypre.hpp
#	linalg/solvers.cpp
#	makefile
#	miniapps/common/pfem_extras.hpp
#	miniapps/electromagnetics/tesla_solver.hpp
2025-03-13 17:43:24 -07:00
Stowell, Mark L 6fa5a0b096 Merge remote-tracking branch 'origin/master' into aniso-diffusion-dev
# Conflicts:
#	fem/coefficient.cpp
#	fem/coefficient.hpp
2019-04-01 11:27:41 -07:00
Stowell, Mark L 3bd8349909 Merge remote-tracking branch 'origin/master' into aniso-diffusion-dev 2018-11-08 18:00:03 -08:00
Stowell, Mark L af82ee8560 Merge remote-tracking branch 'origin/master' into aniso-diffusion-dev 2018-10-20 12:18:07 -07:00
Stowell, Mark L 2ac542c720 Attempting to support 2D curl cleaning 2018-10-20 12:17:00 -07:00
Mark L. Stowell e6f828a5fe Attempting to add curl free projection... 2018-10-18 13:07:44 -07:00
Mark L. Stowell 4d756edd80 Adding DivergenceFree/Irrotational projectors for RT spaces 2018-10-18 10:29:50 -07:00
Stowell, Mark L cf5bd1f5cc make style 2018-10-18 00:17:32 -07:00
Stowell, Mark L 7173dd2002 Adding H1 diffusion solver 2018-10-18 00:16:56 -07:00
Stowell, Mark L 50182bf440 Adding perturbed elliptic case 2018-10-17 19:51:12 -07:00
Stowell, Mark L 24bfcc5165 Initializing a solution vector before solve 2018-10-17 10:20:38 -07:00
Stowell, Mark L 302f22f297 Switching to analytic evaluation of b vector field 2018-10-16 15:34:29 -07:00
Stowell, Mark L 1637fcd933 Adding argument to control lower bound of mesh size 2018-10-16 13:13:56 -07:00
Stowell, Mark L 2563506174 make style 2018-10-14 16:14:31 -07:00
Stowell, Mark L 60640c3f7e Adding computation of full thermal flux 2018-10-14 10:39:39 -07:00
Stowell, Mark L f221521203 make style 2018-10-14 10:12:37 -07:00
Stowell, Mark L 1d9e736af6 Adding a miniapp which solve for thermal flux in HDiv 2018-10-14 10:10:55 -07:00
Stowell, Mark L d80dbfd99a Adding flux computation 2018-10-10 16:46:17 -07:00
Stowell, Mark L 3f44043e60 Adding steady state anisotropic diffusion solver 2018-10-10 12:48:07 -07:00
Stowell, Mark L b218959bca Inserting the thermal flux solver 2018-10-03 10:33:45 -07:00
Stowell, Mark L aee7bc9d43 Adding first draft of hybrid diffusion solver 2018-10-01 16:14:53 -07:00
Stowell, Mark L 31cac320d4 Bugfix in activation of nonlinear solver 2018-10-01 15:08:15 -07:00
Stowell, Mark L e7e0fb0a88 Adding a specialized miniapp to duplicate results from the van Es papper 2018-09-30 21:47:54 -07:00
Stowell, Mark L ba71d13980 Merge remote-tracking branch 'origin/master' into aniso-diffusion-dev 2018-09-25 13:04:15 -07:00
Stowell, Mark L 5c326a5535 Fixing a typo in a comment 2018-09-25 13:02:39 -07:00
Stowell, Mark L 9457f7e5b6 Switching to nonlinear solver 2018-09-24 15:45:49 -07:00
Stowell, Mark L ff030ee970 Adding another time dependent test case 2018-09-24 12:45:36 -07:00
Stowell, Mark L 2be9e1f36c Adding a steady state solver to the thermal miniapps 2018-09-24 12:45:03 -07:00
Stowell, Mark L 7671cd9f36 Merge remote-tracking branch 'origin/master' into aniso-diffusion-dev 2018-09-16 13:17:34 -07:00
Stowell, Mark L f89a633fda make style 2018-09-14 14:41:13 -07:00
Stowell, Mark L 4ce1cef6b8 Adding SetOperator methods to HyprePCG, HypreGMRES, HypreDiagScale, and HypreParaSails 2018-09-14 14:34:13 -07:00
Stowell, Mark L c667bf3025 Fixing HypreGMRES::SetOperator method in the presence of a preconditioner 2018-09-14 13:47:29 -07:00
Stowell, Mark L e1678afe40 Using new HypreGMRES with SetOperator method 2018-09-10 16:46:25 -07:00
Stowell, Mark L c0291398ed Implementing HypreGMRES::SetOperator method 2018-09-10 16:45:59 -07:00
Stowell, Mark L 0b4f10d79d Debugging gradient check 2018-09-09 16:29:15 -07:00
Stowell, Mark L 8dfd0e1547 Adding NewtonSolver method to validate gradient 2018-09-09 16:28:18 -07:00
Stowell, Mark L caf239c99a Updating with time dependent source and exact solution 2018-09-09 00:39:58 -07:00
Stowell, Mark L 44c33aece0 Merge remote-tracking branch 'origin/master' into aniso-diffusion-dev 2018-09-08 23:59:16 -07:00
Stowell, Mark L ed49856390 Merge branch 'aniso-diffusion-dev' of github.com:mfem/mfem into aniso-diffusion-dev 2018-09-06 14:13:18 -07:00
Stowell, Mark L 4fef6ca298 make style 2018-09-06 14:12:28 -07:00
Stowell, Mark L d9d809e81c Adding "thermal" to miniapps subdirectories 2018-09-06 14:12:16 -07:00
Stowell, Mark L 51e85ccd84 Fixing nonlinear solve and applying 'make style' 2018-09-06 14:11:54 -07:00
Mark L. Stowell 4304159303 Merge branch 'aniso-diffusion-dev' of github.com:mfem/mfem into aniso-diffusion-dev 2018-09-05 16:56:05 -07:00
Stowell, Mark L 6276268e52 Retain zeros to maintain sparsity pattern 2018-09-05 16:54:59 -07:00
Mark L. Stowell 580ae34842 Retaining zeros to maintain sparsity pattern 2018-09-05 16:51:10 -07:00
Stowell, Mark L 97eaf8efbc Parallelizing the linear solves 2018-09-05 15:48:28 -07:00
Stowell, Mark L e6621c9b0c Parallel bug 2018-09-05 15:25:18 -07:00
Stowell, Mark L 461246f80e Adding a missing overload 2018-09-05 13:29:10 -07:00
Stowell, Mark L a5941ee72f Bugfix: reinitializing matrices before reassembling 2018-09-05 11:10:09 -07:00
Stowell, Mark L c4c2ceab59 Linear case now working 2018-09-05 10:15:17 -07:00
Stowell, Mark L 88b99a1719 Fixing vector dimension in vector grid functions 2018-09-05 10:14:52 -07:00
Stowell, Mark L 7aa7b4ee53 Adjusting initialization order so that vector size is known earlier 2018-09-03 11:19:27 -07:00
Stowell, Mark L bcf87fee29 Modifying VectorGridFunctionCoefs to accept NULL pointers 2018-09-03 11:06:32 -07:00
Stowell, Mark L 2949dc5a46 Adding makefile for miniapps/thermal 2018-09-03 10:48:11 -07:00
Stowell, Mark L b0dbadd007 Adding first draft of non-linear thermal diffusion solver 2018-09-03 10:19:34 -07:00
Stowell, Mark L 6ca1f95979 Adding scalar multiplication by a constant 2018-08-31 22:54:36 -07:00
Stowell, Mark L 39794585c4 Adding an Identity Matrix Coefficient 2018-08-31 16:50:02 -07:00
Stowell, Mark L 65a71259f1 Merge remote-tracking branch 'origin/elementwise-error-dev' into aniso-diffusion-dev 2018-08-31 16:49:37 -07:00
Stowell, Mark L 3f4e8324d4 Adding a coefficient which computes a unit vector field from a vector field 2018-08-29 14:26:29 -07:00
Stowell, Mark L 9fca398741 Adding ability to alter derived coefficients 2018-08-29 13:59:38 -07:00
Stowell, Mark L a2b8f7a129 Merge remote-tracking branch 'origin/master' into aniso-diffusion-dev 2018-08-29 09:28:15 -07:00
Stowell, Mark L a367631ce5 Adding various coefficients which are sums or products of other coefficients 2018-08-28 16:34:13 -07:00
Stowell, Mark L d7718f5c57 make style 2018-08-28 14:51:48 -07:00
Stowell, Mark L fe88c4685d Adding coefficients to compute div, grad, or curl of grid functions. 2018-08-28 14:24:15 -07:00
490 changed files with 18472 additions and 51938 deletions
-154
View File
@@ -1,154 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: Sanitizer Config
description: Sets up environment variables for MFEM sanitizer workflow
inputs:
DEBUG:
description: If true, use intermediate caches to speed up the workflow
by reusing previous builds.
default: false
REPOSITORY:
description: Repository to checkout
default: mfem/mfem
BRANCH:
description: Branch to checkout
default: ubsan
CLANG_VER:
description: CLANG version to use
default: 18
# https://github.com/llvm/llvm-project/releases
LLVM_VER:
description: LLVM version to use
default: 19.1.7
# https://github.com/hypre-space/hypre/releases
HYPRE_VER:
description: HYPRE version to use
default: 2.19.0
METIS_VER:
description: METIS version to use
default: 4.0.3
CTEST:
description: CTest command to use
default: ctest -j --test-load $(nproc)
--schedule-random
--stop-on-failure --output-on-failure
--test-dir
# https://clang.llvm.org/docs/AddressSanitizer.html
ASAN_OPTIONS:
default: detect_leaks=1,
strict_init_order=1,
strict_string_checks=1,
check_initialization_order=1,
detect_stack_use_after_return=1
ASAN_CXXFLAGS:
default: -fsanitize=address
-fsanitize-address-use-after-scope
ASAN_LDFLAGS:
default: -fsanitize=address
# https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
UBSAN_OPTIONS:
default: halt_on_error=1, print_stacktrace=1
UBSAN_CXXFLAGS:
default: -fsanitize=undefined
UBSAN_LDFLAGS:
default: -fsanitize=undefined
# https://clang.llvm.org/docs/MemorySanitizer.html
MSAN_OPTIONS:
default: "poison_in_dtor=1"
MSAN_CXXFLAGS:
default: -fsanitize=memory
-fsanitize-memory-track-origins
-fsanitize-memory-use-after-dtor
MSAN_LDFLAGS:
default: -fsanitize=memory
LSAN_DIR:
description: LSAN suppression directory
default: lsan
LSAN_FILE:
description: LSAN suppression file
default: lsan.supp
NO_FLAGS:
description: If true, do not set any CXXFLAGS or LDFLAGS.
default: false
runs:
using: 'composite'
steps:
- name: Env (Inputs)
run: |
echo DEBUG=${{inputs.DEBUG}} >> $GITHUB_ENV
echo REPOSITORY=${{inputs.REPOSITORY}} >> $GITHUB_ENV
echo BRANCH=${{inputs.BRANCH}} >> $GITHUB_ENV
echo CLANG_VER=${{inputs.CLANG_VER}} >> $GITHUB_ENV
echo LLVM_VER=${{inputs.LLVM_VER}} >> $GITHUB_ENV
echo HYPRE_VER=${{inputs.HYPRE_VER}} >> $GITHUB_ENV
echo METIS_VER=${{inputs.METIS_VER}} >> $GITHUB_ENV
echo CTEST=${{inputs.CTEST}} >> $GITHUB_ENV
echo ASAN_OPTIONS=${{inputs.ASAN_OPTIONS}} >> $GITHUB_ENV
echo UBSAN_OPTIONS=${{inputs.UBSAN_OPTIONS}} >> $GITHUB_ENV
echo MSAN_OPTIONS=${{inputs.MSAN_OPTIONS}} >> $GITHUB_ENV
echo LSAN_DIR=${{inputs.LSAN_DIR}} >> $GITHUB_ENV
echo LSAN_FILE=${{inputs.LSAN_FILE}} >> $GITHUB_ENV
echo ASAN_CXXFLAGS=${{inputs.ASAN_CXXFLAGS}} >> $GITHUB_ENV
echo ASAN_LDFLAGS=${{inputs.ASAN_LDFLAGS}} >> $GITHUB_ENV
echo UBSAN_CXXFLAGS=${{inputs.UBSAN_CXXFLAGS}} >> $GITHUB_ENV
echo UBSAN_LDFLAGS=${{inputs.UBSAN_LDFLAGS}} >> $GITHUB_ENV
echo MSAN_CXXFLAGS=${{inputs.MSAN_CXXFLAGS}} >> $GITHUB_ENV
echo MSAN_LDFLAGS=${{inputs.MSAN_LDFLAGS}} >> $GITHUB_ENV
shell: bash
- name: Env (dir)
run: |
echo LLVM_DIR=${{github.workspace}}/llvm >> $GITHUB_ENV
echo HYPRE_DIR=hypre-${{inputs.HYPRE_VER}} >> $GITHUB_ENV
echo METIS_DIR=metis-${{inputs.METIS_VER}} >> $GITHUB_ENV
shell: bash
- name: Env (bis)
run: |
echo CC=clang-${{inputs.CLANG_VER}} >> $GITHUB_ENV
echo CXX=clang++-${{inputs.CLANG_VER}} >> $GITHUB_ENV
echo LLVM_INC=${{env.LLVM_DIR}}/include/c++/v1 >> $GITHUB_ENV
echo LLVM_LIB=${{env.LLVM_DIR}}/lib >> $GITHUB_ENV
echo HYPRE_TGZ=v${{inputs.HYPRE_VER}}.tar.gz >> $GITHUB_ENV
echo METIS_TGZ=metis-${{inputs.METIS_VER}}.tar.gz >> $GITHUB_ENV
LSAN_SUPPRESSIONS="${{github.workspace}}/${{inputs.LSAN_DIR}}/${{inputs.LSAN_FILE}}"
echo "LSAN_OPTIONS=suppressions=$LSAN_SUPPRESSIONS" >> $GITHUB_ENV
shell: bash
- name: Env (ter)
if: ${{ inputs.NO_FLAGS != 'true' }}
run: |
echo LLVM_CXXFLAGS=-stdlib=libc++ -I${{env.LLVM_INC}} -Isystem${{env.LLVM_INC}} >> $GITHUB_ENV
echo LLVM_LDFLAGS=-L${{env.LLVM_LIB}} -lc++abi -Wl,-rpath,${{env.LLVM_LIB}} >> $GITHUB_ENV
shell: bash
- name: Env (quater)
if: ${{ inputs.NO_FLAGS != 'true' }}
run: |
echo CXXFLAGS=${{env.LLVM_CXXFLAGS}} >> $GITHUB_ENV
echo LDFLAGS=${{env.LLVM_LDFLAGS}} >> $GITHUB_ENV
shell: bash
-91
View File
@@ -1,91 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: 'MFEM Compilation'
description: 'MFEM Compilation'
inputs:
par:
description: 'Whether to build for parallel (true/false)'
default: false
sanitizer:
description: 'Sanitizer to use (asan, msan, ubsan)'
default: asan
runs:
using: 'composite'
steps:
- uses: ./.github/actions/sanitize/config
- uses: actions/cache@v4
if: ${{env.DEBUG == 'true'}}
id: debug
with:
path: mfem/build
key: build-${{inputs.par}}-${{inputs.sanitizer}}
- uses: ./.github/actions/sanitize/setup
if: ${{steps.debug.outputs.cache-hit != 'true'}}
with:
par: ${{inputs.par}}
sanitizer: ${{inputs.sanitizer}}
- name: Build with ASAN
if: inputs.sanitizer == 'asan'
run: echo CXXFLAGS=${{env.CXXFLAGS}} ${{env.ASAN_CXXFLAGS}} >> $GITHUB_ENV
shell: bash
- name: Build with MSAN
if: inputs.sanitizer == 'msan'
run: echo CXXFLAGS=${{env.CXXFLAGS}} ${{env.MSAN_CXXFLAGS}} >> $GITHUB_ENV
shell: bash
- name: Build with UBSAN
if: inputs.sanitizer == 'ubsan'
run: echo CXXFLAGS=${{env.CXXFLAGS}} ${{env.UBSAN_CXXFLAGS}} >> $GITHUB_ENV
shell: bash
- uses: mfem/github-actions/build-mfem@v2.5
if: ${{steps.debug.outputs.cache-hit != 'true'}}
env:
CXXFLAGS: ${{env.CXXFLAGS}}
LDFLAGS: ${{env.LDFLAGS}}
with:
mpi: ${{inputs.par == 'false' && 'seq' || 'par'}}
mfem-dir: mfem
os: ${{runner.os}}
library-only: true
build-system: cmake
hypre-dir: ${{env.HYPRE_DIR}}
metis-dir: ${{env.METIS_DIR}}
config-options: >-
-GNinja
-DMPICXX=${{env.CXX}}
-DCMAKE_CXX_STANDARD=17
-DMFEM_USE_MEMALLOC=OFF
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_VERBOSE_MAKEFILE=ON
-DCMAKE_CXX_COMPILER=${{env.CXX}}
-DCMAKE_CXX_FLAGS_RELEASE='-g -O1 -fno-omit-frame-pointer'
- name: Delete object files
if: ${{steps.debug.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: find . -type f -name '*.o' -delete
shell: bash
- uses: actions/upload-artifact@v4
with:
name: build-${{inputs.par}}-${{inputs.sanitizer}}
path: mfem/build
if-no-files-found: error
retention-days: 1
overwrite: false
-33
View File
@@ -1,33 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: 'Install MPI'
description: 'Installs MPI and set up its environment variables'
runs:
using: 'composite'
steps:
- name: Install
run: sudo apt-get install openmpi-bin libopenmpi-dev
shell: bash
- name: Env
run: |
echo PRTE_MCA_rmaps_default_mapping_policy=:oversubscribe >> $GITHUB_ENV
echo MPI_INC=$(mpicxx --showme:compile) >> $GITHUB_ENV
echo MPI_LIB=$(mpicxx --showme:link) >> $GITHUB_ENV
shell: bash
- name: Env (bis)
run: |
echo CXXFLAGS=${{env.CXXFLAGS}} ${{env.MPI_INC}} >> $GITHUB_ENV
echo LDFLAGS=${{env.LDFLAGS}} ${{env.MPI_LIB}} >> $GITHUB_ENV
shell: bash
@@ -1,71 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: 'Restore state'
description: 'Restore state to be able to run checks, tests'
inputs:
par:
description: 'Whether to build for parallel (true/false)'
default: false
sanitizer:
description: 'Sanitizer to use (asan, msan, ubsan)'
default: asan
cache-path:
description: 'path to what needs to be restored'
default: none
cache-skip:
description: 'Skip cache restoration'
default: false
outputs:
cache-hit:
description: 'Output from a specific step'
value: ${{steps.debug.outputs.cache-hit}}
runs:
using: 'composite'
steps:
- uses: ./.github/actions/sanitize/config
- uses: actions/cache@v4
if: ${{env.DEBUG == 'true' && inputs.cache-skip != 'true'}}
id: debug
with:
path: ${{inputs.cache-path}}
key: ${{github.job}}-${{inputs.par}}-${{inputs.sanitizer}}
- uses: ./.github/actions/sanitize/setup
if: ${{steps.debug.outputs.cache-hit != 'true'}}
with:
par: ${{inputs.par}}
sanitizer: ${{inputs.sanitizer}}
- uses: actions/download-artifact@v4
with:
name: build-${{inputs.par}}-${{inputs.sanitizer}}
path: mfem/build
- name: Ninja Patch
working-directory: mfem/build
run: |
sed -i -e 's/CXX_STATIC_LIBRARY_LINKER__mfem_Release.*/CUSTOM_COMMAND/' build.ninja
sed -i -e '/build tests\/unit\/all:/ s/tests\/unit\/[^ ]*unit_tests[^ ]*//g' build.ninja
sed -i -e '/^add_test(\[=\[\(unit_tests\|punit_tests\)\]=\]/ s/)/ "--input-file .\/list-test-names-${{matrix.tag}}" "--min-duration 1")/' tests/unit/CTestTestfile.cmake
shell: bash
- name: Copy Data
if: ${{steps.debug.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: |
ninja cmake_object_order_depends_target_unit_tests
cp -pR ../tests/unit/data tests/unit
shell: bash
-64
View File
@@ -1,64 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: 'Setup state'
description: 'Sets up the state to be able to run build & run'
inputs:
par:
description: 'Whether to build for parallel (true/false)'
default: false
sanitizer:
description: 'Sanitizer to use (asan, msan, ubsan)'
default: asan
runs:
using: 'composite'
steps:
- uses: actions/cache/restore@v4 # Cache for LLVM libcxx
with:
path: ${{env.LLVM_DIR}}
fail-on-cache-miss: true
key: build-libcxx-${{env.LLVM_VER}}-${{inputs.sanitizer}}
- uses: ./.github/actions/sanitize/mpi
if: ${{inputs.par == 'true'}}
- uses: actions/cache/restore@v4 # Cache for Hypre
if: ${{inputs.par == 'true'}}
with:
path: ${{env.HYPRE_DIR}}
fail-on-cache-miss: true
key: ${{runner.os}}-ompi-build-${{env.HYPRE_DIR}}-int32-fp64-v2.5
- uses: actions/cache/restore@v4 # Cache for Metis
if: ${{inputs.par == 'true'}}
with:
path: ${{env.METIS_DIR}}
fail-on-cache-miss: true
key: ${{runner.os}}-build-${{env.METIS_DIR}}-v2.5
- name: Hypre/Metis links
if: ${{inputs.par == 'true'}}
run: ln -s -f ${{env.HYPRE_DIR}} hypre && ln -s -f ${{env.METIS_DIR}} metis-4.0
shell: bash
- uses: actions/cache/restore@v4 # Cache for LSAN suppression file
with:
path: ${{env.LSAN_DIR}}
fail-on-cache-miss: true
key: build-lsan-suppression-file
- uses: actions/checkout@v4 # Checkout the repository
with:
path: mfem
# ref: ${{env.BRANCH}}
# repository: ${{env.REPOSITORY}}
+7 -26
View File
@@ -7,17 +7,18 @@
https://mfem.org
This directory contains the GitHub CI scripts for MFEM.
Note that some of these scripts use the shared MFEM GitHub Actions from the external mfem/github-actions repository:
<https://github.com/mfem/github-actions>
https://github.com/mfem/github-actions
For a particular action, e.g. `mfem/github-actions/build-mfem@v2.5`, the `v2.5` suffix denotes the branch in the above from which the action is taken.
For a particular action, e.g. `mfem/github-actions/build-mfem@v2.1`, the `v2.1` suffix denotes the branch in the above from which the action is taken.
The current CI workflows are:
## `repo-check.yml`
### `repo-check.yml`
Runs a number of static repository-level sanity checks.
@@ -29,39 +30,19 @@ Runs a number of static repository-level sanity checks.
- `branch-history` guards against accidental commits of large files using the `--history` option of the `config/githooks/pre-push` script.
## `mfem-analysis.yml` (`build-analysis`)
### `mfem-analysis.yml` (`build-analysis`)
Checks if the code builds and satisfies minimal requirements.
- `gitignore` builds hypre, METIS, and MFEM using `mfem/github-actions/build-hypre`, `mfem/github-actions/build-metis`, and `mfem/github-actions/build-mfem` and checks for correct `.gitignore` settings by running the `tests/scripts/gitignore` script.
## `builds-and-tests.yml`
### `builds-and-tests.yml`
Runs a matrix of builds and tests runs with different compilers, OS, mfem/hypre settings, etc. Also processes and upload Codecov reports.
Uses the following GitHub Actions from <https://github.com/mfem/github-actions>:
Uses the following GitHub Actions from https://github.com/mfem/github-actions:
- `mfem/github-actions/build-hypre`
- `mfem/github-actions/build-metis`
- `mfem/github-actions/build-mfem`
- `mfem/github-actions/upload-coverage`
## Sanitizer Workflow for MFEM Verification
This workflow validates MFEM unit tests, examples, and miniapps using sanitizer tools.
- `sanitizers.yml` orchestrates:
- Building and caching dependencies: HYPRE, METIS, LSAN suppression file, and LLVM libcxx.
- Launching fine-grained jobs for serial (ASAN, MSAN, UBSAN) and parallel (ASAN, UBSAN) sanitizers.
- `sanitize-tests.yml` is a reusable workflow accepting `par` mode (`true` for parallel) and `sanitizer` (ASAN, MSAN, or UBSAN) as inputs. It executes the following jobs:
- **Build**: Compiles the MFEM library with specified parallel and sanitizer settings.
- **Check**: Runs verification checks.
- Parallel jobs to test the following: **Examples**, **Miniapps** and **Unit tests**
The workflow leverages composite actions in `.github/actions/sanitize/`:
- `config`: Centralizes settings for the sanitizer workflow.
- `mfem`: Manages the MFEM library build process.
- `mpi`: Installs MPI and applies additional compilation flags.
- `restore`: Restores the testing environment state.
- `setup`: Builds or restores cached dependencies.
+9 -60
View File
@@ -58,7 +58,6 @@ jobs:
build-system: [make, cmake]
hypre-target: [int32]
precision: [fp64]
enzyme: [false]
exclude:
- os: ubuntu-latest
build-system: cmake
@@ -81,17 +80,15 @@ jobs:
codecov: YES
- os: ubuntu-latest
target: dbg
config-opts: "CPPFLAGS+=-Og"
config-opts: 'CPPFLAGS+=-Og'
- os: macos-latest
codecov: NO
- os: windows-latest
codecov: NO
# config-opts: '-G "Ninja Multi-Config"'
- os: windows-latest
target: opt
mpi: par
config-opts: "-DBUILD_SHARED_LIBS=ON"
# config-opts: '-DBUILD_SHARED_LIBS=ON -G "Ninja Multi-Config"'
config-opts: '-DBUILD_SHARED_LIBS=ON'
- os: ubuntu-latest
target: opt
codecov: NO
@@ -99,7 +96,7 @@ jobs:
build-system: cmake
hypre-target: int32
precision: fp64
config-opts: "-DCMAKE_INSTALL_PREFIX=../cmake-install"
config-opts: '-DCMAKE_INSTALL_PREFIX=../cmake-install'
# This option can be set to pass additional configuration options to
# the MFEM configuration command.
# config-opts: '-DCMAKE_VERBOSE_MAKEFILE=ON'
@@ -117,37 +114,18 @@ jobs:
build-system: make
hypre-target: int32
precision: fp32
- os: macos-latest
target: opt
codecov: NO
mpi: par
build-system: make
hypre-target: int32
precision: fp32
- os: macos-latest
target: opt
codecov: NO
mpi: par
build-system: make
hypre-target: int32
precision: fp64
enzyme: true
config-opts: MFEM_USE_ENZYME=YES ENZYME_DIR=$(brew --prefix enzyme) LDFLAGS=-L$LLVM_PREFIX/lib/c++
name: ${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}-${{ matrix.hypre-target }}-${{ matrix.precision }}${{ matrix.enzyme && '-enzyme' || '' }}
name: ${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}-${{ matrix.hypre-target }}-${{ matrix.precision }}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.enzyme && true || false }}
steps:
# Fix 'No space left on device' errors for Ubuntu builds.
- name: Run Actions Cleaner
if: matrix.os == 'ubuntu-latest'
uses: easimon/maximize-build-space@v8
with:
overprovision-lvm: "true"
remove-android: "true"
overprovision-lvm: 'true'
remove-android: 'true'
# Checkout MFEM in "mfem" subdirectory. Final path:
# /home/runner/work/mfem/mfem/mfem
@@ -159,24 +137,10 @@ jobs:
# Fetch the complete history for codecov to access commits ID
fetch-depth: 0
- name: Windows environment - PowerShell [debug]
if: matrix.os == 'windows-latest'
run: |
ls env: | fl
- name: Windows environment - Bash [debug]
if: matrix.os == 'windows-latest'
run: |
env
shell: bash
# For info on Xcode see:
# - https://github.com/actions/runner-images/issues/12541
# - https://github.com/actions/runner-images/blob/releases/macos-15-arm64/20250811/images/macos/macos-15-arm64-Readme.md#xcode
- name: Xcode version setup (MacOS)
if: matrix.os == 'macos-latest'
run: |
XCODE_PATH="/Applications/Xcode_16.4.app"
XCODE_PATH="/Applications/Xcode_15.3.app"
echo "> sudo xcode-select -s ${XCODE_PATH}"
sudo xcode-select -s ${XCODE_PATH}
echo "> g++ -v"
@@ -190,8 +154,7 @@ jobs:
- name: get MPI (Linux)
if: matrix.mpi == 'par' && matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install openmpi-bin libopenmpi-dev
export OMPI_MCA_rmaps_base_oversubscribe=1
sudo apt-get install mpich libmpich-dev
- name: get lcov (Linux)
if: matrix.codecov == 'YES' && matrix.os == 'ubuntu-latest'
@@ -228,7 +191,7 @@ jobs:
uses: actions/cache@v4
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-ompi-build-${{ env.HYPRE_TOP_DIR }}-${{ matrix.hypre-target }}-${{ matrix.precision }}-v2.5
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-${{ matrix.hypre-target }}-${{ matrix.precision }}-v2.5
- name: get hypre
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os != 'windows-latest'
@@ -287,20 +250,6 @@ jobs:
run: |
vcpkg install metis-mfem --triplet=x64-windows-static --overlay-ports=${{ env.MFEM_TOP_DIR }}/config/vcpkg/ports
# It's usually fine to build the above TPLs with a different compiler.
#
- name: install Enzyme (macOS w/ Enzyme)
if: matrix.enzyme && matrix.os == 'macos-latest'
run: |
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew update
brew install enzyme
ENZYME_LLVM=$(brew info enzyme | sed -n 's/^Required:.*\(llvm[^ ]*\).*/\1/p')
LLVM_PREFIX=$(brew --prefix $ENZYME_LLVM)
echo "LLVM_PREFIX=$LLVM_PREFIX" >> $GITHUB_ENV
echo "OMPI_CC=$LLVM_PREFIX/bin/clang" >> $GITHUB_ENV
echo "OMPI_CXX=$LLVM_PREFIX/bin/clang++" >> $GITHUB_ENV
# MFEM build and test
- name: build
uses: mfem/github-actions/build-mfem@v2.5
+2 -3
View File
@@ -45,15 +45,14 @@ jobs:
- name: Get MPI (Linux)
run: |
sudo apt-get install openmpi-bin libopenmpi-dev
export OMPI_MCA_rmaps_base_oversubscribe=1
sudo apt-get install mpich libmpich-dev
- name: Cache Hypre Install
id: hypre-cache
uses: actions/cache@v4
with:
path: ${{ env.HYPRE_TOP_DIR }}
key: ${{ runner.os }}-ompi-build-${{ env.HYPRE_TOP_DIR }}-v2.5
key: ${{ runner.os }}-build-${{ env.HYPRE_TOP_DIR }}-v2.5
- name: Get Hypre
if: steps.hypre-cache.outputs.cache-hit != 'true'
+69
View File
@@ -0,0 +1,69 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
name: "Sanitizer"
permissions:
actions: write
on:
push:
branches:
- master
- next
pull_request:
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
Serial:
runs-on: ubuntu-24.04
steps:
- name: MFEM Checkout
uses: actions/checkout@v4
with:
path: mfem
- name: MFEM Build
uses: mfem/github-actions/build-mfem@v2.5
with:
os: ${{ runner.os }}
target: opt
mpi: seq
hypre-dir: unused-hypre-dir
metis-dir: unused-metis-dir
mfem-dir: mfem
build-system: make
library-only: false
config-options:
CXX="clang++-18"
CXXFLAGS="-g -O1 -std=c++11
-fsanitize=address
-fno-omit-frame-pointer
-fsanitize-address-use-after-scope"
- name: MFEM Info
working-directory: mfem
run: make info
- name: MFEM Sanitize
working-directory: mfem
run:
ASAN_OPTIONS="detect_leaks=1,
strict_init_order=1,
strict_string_checks=1,
check_initialization_order=1,
detect_stack_use_after_return=1"
make test
@@ -1,39 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: build-hypre
on:
workflow_call:
jobs:
build-hypre:
runs-on: ubuntu-latest
name: 2.19.0
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/config
- name: Cache
id: cache
uses: actions/cache@v4
with:
path: ${{env.HYPRE_DIR}}
key: ${{runner.os}}-ompi-build-${{env.HYPRE_DIR}}-int32-fp64-v2.5
- name: Setup
if: steps.cache.outputs.cache-hit != 'true'
uses: ./.github/actions/sanitize/mpi
- name: Build
if: steps.cache.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-hypre@v2.5
with:
archive: ${{env.HYPRE_TGZ}}
dir: ${{env.HYPRE_DIR}}
target: int32
precision: fp64
build-system: make
@@ -1,76 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: build-libcxx
on:
workflow_call:
jobs:
build-llvm-libcxx:
runs-on: ubuntu-latest
strategy:
matrix:
sanitizer: [asan, msan, ubsan]
include:
- sanitizer: asan
llvm_use_sanitizer: "Address"
- sanitizer: msan
llvm_use_sanitizer: "MemoryWithOrigins"
- sanitizer: ubsan
llvm_use_sanitizer: "Undefined"
name: ${{matrix.sanitizer}}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/config
with:
NO_FLAGS: true
- name: Cache
id: cache
uses: actions/cache@v4
with:
path: ${{env.LLVM_DIR}}
key: build-libcxx-${{env.LLVM_VER}}-${{matrix.sanitizer}}
- name: Clone
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
run: >
git clone --filter=blob:none --depth=1
--branch llvmorg-${{env.LLVM_VER}}
--no-checkout https://github.com/llvm/llvm-project.git llvm-project
- name: Checkout
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
working-directory: llvm-project
run: |
git sparse-checkout set --cone
git checkout llvmorg-${{env.LLVM_VER}}
git sparse-checkout set cmake llvm/cmake runtimes libcxx libcxxabi
- name: Mkdir
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
run: mkdir ${{env.LLVM_DIR}}
- name: CMake
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
working-directory: ${{env.LLVM_DIR}}
run: >
VERBOSE=1
cmake -GNinja ../llvm-project/runtimes/
-DCMAKE_C_COMPILER=${{env.CC}}
-DCMAKE_CXX_COMPILER=${{env.CXX}}
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DCMAKE_INSTALL_PREFIX=/usr
-DLLVM_USE_SANITIZER=${{matrix.llvm_use_sanitizer}}
-DLLVM_BUILD_32_BITS=OFF
-DLIBCXXABI_USE_LLVM_UNWINDER=OFF
-DLLVM_INCLUDE_TESTS=OFF
-DLIBCXX_INCLUDE_TESTS=OFF
-DLIBCXX_INCLUDE_BENCHMARKS=OFF
-DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi'
- name: Build
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
working-directory: ${{env.LLVM_DIR}}
run: cmake --build . -- cxx cxxabi
-38
View File
@@ -1,38 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: build-file-lsan
on:
workflow_call:
jobs:
build-file-lsan:
runs-on: ubuntu-latest
name: lsan.supp
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/config
- name: Cache
id: cache
uses: actions/cache@v4
with:
path: ${{env.LSAN_DIR}}
key: build-lsan-suppression-file
- name: Setup
if: steps.cache.outputs.cache-hit != 'true'
run: |
mkdir -p ${{env.LSAN_DIR}}
cat << EOF > ${{env.LSAN_DIR}}/${{env.LSAN_FILE}}
leak:libevent_core-2.1.so
leak:ompi_mpi_finalize
leak:ompi_mpi_init
leak:PMPI_Init
leak:strdup
EOF
@@ -1,36 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: build-metis
on:
workflow_call:
jobs:
build-metis:
runs-on: ubuntu-latest
name: 4.0.3
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/config
- name: Cache
id: cache
uses: actions/cache@v4
with:
path: ${{env.METIS_DIR}}
key: ${{runner.os}}-build-${{env.METIS_DIR}}-v2.5
- name: Setup
if: steps.cache.outputs.cache-hit != 'true'
uses: ./.github/actions/sanitize/mpi
- name: Build
if: steps.cache.outputs.cache-hit != 'true'
uses: mfem/github-actions/build-metis@v2.5
with:
archive: ${{env.METIS_TGZ}}
dir: ${{env.METIS_DIR}}
-197
View File
@@ -1,197 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: Sanitize
on:
workflow_call:
inputs:
par:
description: 'Whether to build for parallel (true/false)'
required: false
default: false
type: boolean
sanitizer:
description: 'Sanitizer to use (asan, msan, ubsan)'
required: true
default: asan
type: string
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/mfem
with:
par: ${{inputs.par}}
sanitizer: ${{inputs.sanitizer}}
check:
needs: [build]
runs-on: ubuntu-latest
env:
ex: ${{inputs.par && 'ex1p' || 'ex1'}}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/restore
id: restore
with:
par: ${{inputs.par}}
sanitizer: ${{inputs.sanitizer}}
cache-path: mfem/build/examples/${{env.ex}}
- name: MFEM Check
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: ninja -v check
examples:
needs: [check]
runs-on: ubuntu-latest
env:
exclude: ${{inputs.par && '-E "_ser"' || ''}}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/restore
id: restore
with:
par: ${{inputs.par}}
sanitizer: ${{inputs.sanitizer}}
cache-path: mfem/build/examples/ex1
- name: Build Examples
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: ninja -v examples
- name: Test Examples
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: |
${{env.CTEST}} examples ${{env.exclude}} --show-only
${{env.CTEST}} examples ${{env.exclude}}
miniapps:
needs: [check]
runs-on: ubuntu-latest
env:
exclude: ${{inputs.par && '-E "_ser"' || ''}}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/restore
id: restore
with:
par: ${{inputs.par}}
sanitizer: ${{inputs.sanitizer}}
cache-path: mfem/build/miniapps/meshing/minimal-surface
- name: Build Miniapps
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: ninja -v miniapps
- name: Test Miniapps
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: |
${{env.CTEST}} miniapps ${{env.exclude}} --show-only
${{env.CTEST}} miniapps ${{env.exclude}}
tests-miniapps:
needs: [check]
runs-on: ubuntu-latest
env:
run: ${{inputs.par && '-R "_cpu_np"' || ''}}
exclude: ${{inputs.par && '"unit_tests|debug"' || '"^unit_tests$|debug"'}}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/restore
id: restore
with:
par: ${{inputs.par}}
sanitizer: ${{inputs.sanitizer}}
cache-path: mfem/build/tests/unit/sedov_tests_cpu
- name: Build Tests Unit Miniapps
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: ninja -v tests/unit/all
- name: Run Tests Unit Miniapps
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: |
${{env.CTEST}} tests/unit -E ${{env.exclude}} ${{env.run}} --show-only
${{env.CTEST}} tests/unit -E ${{env.exclude}} ${{env.run}}
tests-unit-build:
needs: [check]
runs-on: ubuntu-latest
env:
unit_tests: ${{inputs.par && 'punit_tests' || 'unit_tests'}}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/restore
id: restore
with:
par: ${{inputs.par}}
sanitizer: ${{inputs.sanitizer}}
cache-path: mfem/build/tests/unit/${{env.unit_tests}}
- name: Build Unit Tests
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: ninja -v ${{env.unit_tests}}
- name: Delete object files
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build/tests/unit
run: find . -type f -name '*.o' -delete
- uses: actions/upload-artifact@v4
with:
name: tests-${{inputs.par}}-${{inputs.sanitizer}}
path: mfem/build/tests/unit/${{env.unit_tests}}
if-no-files-found: error
retention-days: 1
overwrite: false
tests-unit-run:
needs: [tests-unit-build]
runs-on: ubuntu-latest
strategy:
matrix:
tag: [0, 1, 2, 3]
name: tests-unit-run-${{matrix.tag}}
env:
unit_tests: ${{inputs.par && 'punit_tests' || 'unit_tests'}}
np: ${{inputs.par && '_np=2' || ''}}
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/sanitize/restore
id: restore
with:
par: ${{inputs.par}}
sanitizer: ${{inputs.sanitizer}}
cache-path: mfem/build/tests/unit/${{env.unit_tests}}
- uses: actions/download-artifact@v4
if: ${{steps.restore.outputs.cache-hit != 'true'}}
with:
name: tests-${{inputs.par}}-${{inputs.sanitizer}}
path: mfem/build/tests/unit
- name: Split Unit Tests
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build/tests/unit
run: |
chmod 755 ${{env.unit_tests}}
./${{env.unit_tests}} --list-test-names-only | tail -n +2 > list-test-names
shuf list-test-names -o list-test-names
split --verbose -n l/4 -d -a 1 list-test-names list-test-names-
- name: Cat Unit Tests ${{matrix.tag}}
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build/tests/unit
run: cat list-test-names-${{matrix.tag}}
- name: Run Unit Tests ${{matrix.tag}}
if: ${{steps.restore.outputs.cache-hit != 'true'}}
working-directory: mfem/build
run: |
${{env.CTEST}} tests/unit -R "${{env.unit_tests}}${{env.np}}" --show-only
${{env.CTEST}} tests/unit -R "${{env.unit_tests}}${{env.np}}"
-73
View File
@@ -1,73 +0,0 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
---
name: Sanitizers
permissions:
actions: write
on:
push:
branches: ["master", "next"]
pull_request:
workflow_dispatch:
concurrency:
group: ${{github.workflow}}-${{github.ref}}
cancel-in-progress: true
jobs:
# Build steps for dependencies
build-hypre:
uses: ./.github/workflows/sanitize-build-hypre.yml
build-metis:
uses: ./.github/workflows/sanitize-build-metis.yml
build-lsan:
uses: ./.github/workflows/sanitize-build-lsan.yml
build-libcxx:
uses: ./.github/workflows/sanitize-build-libcxx.yml
# Serial sanitizers: asan, msan, ubsan
seq-asan:
needs: [build-libcxx]
uses: ./.github/workflows/sanitize-tests.yml
with:
sanitizer: asan
seq-msan:
needs: [build-libcxx]
uses: ./.github/workflows/sanitize-tests.yml
with:
sanitizer: msan
seq-ubsan:
needs: [build-libcxx]
uses: ./.github/workflows/sanitize-tests.yml
with:
sanitizer: ubsan
# Parallel sanitizers: asan, ubsan
par-asan:
needs: [build-libcxx, build-hypre, build-metis]
uses: ./.github/workflows/sanitize-tests.yml
with:
par: true
sanitizer: asan
par-ubsan:
needs: [build-libcxx, build-hypre, build-metis]
uses: ./.github/workflows/sanitize-tests.yml
with:
par: true
sanitizer: ubsan
+6 -26
View File
@@ -63,7 +63,6 @@ examples/ex3[0-9]
examples/ex3[0-9]p
examples/ex4[0-9]
examples/ex4[0-9]p
examples/vector-dg-diffusion
examples/refined.mesh
examples/displaced.mesh
@@ -81,7 +80,6 @@ examples/sol_p.*
examples/sol_r.*
examples/sol_i.*
examples/ex6p-checkpoint.*
examples/order.*
examples/ex9.mesh
examples/ex9-mesh.*
examples/ex9-init.*
@@ -202,9 +200,6 @@ examples/superlu/sol.*
miniapps/adjoint/cvsRoberts_ASAi_dns
miniapps/adjoint/adjoint_advection_diffusion
miniapps/dfem/dfem-minimal-surface
miniapps/dfem/dfem-minimal-surface-output
miniapps/electromagnetics/volta
miniapps/electromagnetics/tesla
miniapps/electromagnetics/maxwell
@@ -212,7 +207,7 @@ miniapps/electromagnetics/joule
miniapps/electromagnetics/Volta-AMR*
miniapps/electromagnetics/Tesla-AMR*
miniapps/electromagnetics/Maxwell-Parallel*
miniapps/electromagnetics/Joule_[0-9]*
miniapps/electromagnetics/Joule_*
miniapps/gslib/field-diff
miniapps/gslib/field-interp
@@ -233,7 +228,6 @@ miniapps/meshing/fit-node-position
miniapps/meshing/trimmer
miniapps/meshing/reflector
miniapps/meshing/ref321
miniapps/meshing/mesh-bounding-boxes
miniapps/meshing/mesh-optimizer
miniapps/meshing/pmesh-optimizer
miniapps/meshing/pmesh-fitting
@@ -241,8 +235,6 @@ miniapps/meshing/minimal-surface
miniapps/meshing/pminimal-surface
miniapps/meshing/polar-nc
miniapps/meshing/mesh-quality
miniapps/meshing/hpref
miniapps/meshing/phpref
miniapps/meshing/mobius-strip.mesh
miniapps/meshing/klein-bottle.mesh
miniapps/meshing/toroid-*.mesh
@@ -260,17 +252,11 @@ miniapps/meshing/sol.gf
miniapps/meshing/optimized*
miniapps/meshing/perturbed*
miniapps/meshing/polar-nc.mesh
miniapps/meshing/mesh.*
miniapps/meshing/order.*
miniapps/meshing/sol.*
miniapps/meshing/refined.mesh
miniapps/meshing/bounding-box*
miniapps/meshing/jacobian-determinant*
miniapps/mtop/parheat
miniapps/mtop/ParHeat/*
miniapps/mtop/ParHeat*
miniapps/mtop/seqheat
miniapps/mtop/SeqHeat/*
miniapps/mtop/SeqHeat*
miniapps/autodiff/paradiff
miniapps/autodiff/seqadiff
@@ -278,7 +264,7 @@ miniapps/autodiff/seqtest
miniapps/autodiff/par_example
miniapps/autodiff/seq_example
miniapps/autodiff/seq_test
miniapps/autodiff/Example/*
miniapps/autodiff/Exampl*
miniapps/navier/navier_mms
miniapps/navier/navier_kovasznay
@@ -301,7 +287,6 @@ miniapps/nurbs/nurbs_solenoidal
miniapps/nurbs/nurbs_printfunc
miniapps/nurbs/nurbs_patch_ex1
miniapps/nurbs/nurbs_curveint
miniapps/nurbs/nurbs_surface
miniapps/nurbs/refined.mesh
miniapps/nurbs/mesh.*
miniapps/nurbs/sol_?.gf
@@ -320,7 +305,6 @@ miniapps/nurbs/nurbs_naca_cmesh
miniapps/nurbs/naca-cmesh.mesh
miniapps/nurbs/glvis_naca-cmesh.mesh
miniapps/nurbs/Naca_cmesh
miniapps/nurbs/*-Surface.mesh
miniapps/performance/ex1
miniapps/performance/ex1p
@@ -342,7 +326,6 @@ miniapps/shifted/lsf_integral
miniapps/tools/display-basis
miniapps/tools/load-dc
miniapps/tools/convert-dc
miniapps/tools/gridfunction-bounds
miniapps/tools/lor-transfer
miniapps/tools/plor-transfer
miniapps/tools/get-values
@@ -409,15 +392,12 @@ miniapps/spde/ParaView
miniapps/tribol/contact-patch-test
miniapps/diag-smoothers/abs-l1-jacobi
miniapps/diag-smoothers/mg-abs-l1-jacobi
# Unit test binary and outputs
tests/unit/output_meshes
tests/unit/unit_tests
tests/unit/punit_tests
tests/unit/gpu_unit_tests
tests/unit/pgpu_unit_tests
tests/unit/cunit_tests
tests/unit/pcunit_tests
tests/unit/sedov_tests_*
tests/unit/psedov_tests_*
tests/unit/tmop_pa_tests_*
+5 -5
View File
@@ -22,7 +22,7 @@ include:
# the "needs" keyword and express the DAG of jobs for more efficiency.
# - We use setup and setup_baseline phases to download content outside of mfem
# directory.
# - Allocate/Release is where Dane resource are allocated/released once for all.
# - Allocate/Release is where ruby resource are allocated/released once for all.
# - Build and Test is where we build and MFEM for multiple toolchains.
# - Baseline_checks gathers baseline-type test suites execution
# - Baseline_publish, only available on master, allows to update baseline
@@ -53,7 +53,7 @@ variables:
AUTOTEST_COMMIT: "YES"
# Trigger subpipelines:
dane-build-and-test:
ruby-build-and-test:
stage: sub-pipelines
variables:
# Explicitly pass down values that we want to be able to set when triggering
@@ -61,10 +61,10 @@ dane-build-and-test:
AUTOTEST: "${AUTOTEST}"
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
trigger:
include: .gitlab/dane-build-and-test.yml
include: .gitlab/ruby-build-and-test.yml
strategy: depend
dane-baseline:
ruby-baseline:
stage: sub-pipelines
variables:
# Explicitly pass down values that we want to be able to set when triggering
@@ -73,7 +73,7 @@ dane-baseline:
AUTOTEST: "${AUTOTEST}"
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
trigger:
include: .gitlab/dane-baseline.yml
include: .gitlab/ruby-baseline.yml
strategy: depend
lassen-build-and-test:
+3 -3
View File
@@ -24,7 +24,7 @@ and `test type`.
Machines typically include:
* Dane: Intel Sapphire Rapids
* Ruby: 2nd Gen Intel Xeon (Cascade Lake)
* Lassen: Power9 + Nvidia GPU
* Corona: AMD GPU
@@ -76,13 +76,13 @@ with a spack spec of MFEM, within the limits permitted by the MFEM spack
package.
In any build-and-test sub-pipeline a job basically consists in defining the
spack spec to use. Adding a job on Dane for example resumes to:
spack spec to use. Adding a job on ruby for example resumes to:
```yaml
<job_name>:
variables:
SPEC: "<spack_spec>"
extends: .build_and_test_on_dane
extends: .build_and_test_on_ruby
```
The remaining and non trivial work is to make sure this spec is working. To
+1 -1
View File
@@ -24,7 +24,7 @@ variables:
# TODO: add a clean-up mechanism
BUILD_ROOT: ${USER_CI_TOP_DIR}/${CI_PROJECT_NAME}-${MACHINE_NAME}-pipeline-${CI_PIPELINE_ID}
# On LLNL's Dane, there is only one allocation shared among jobs in order to
# On LLNL's ruby, there is only one allocation shared among jobs in order to
# save time and resource. This allocation has to be uniquely named so that we
# are sure to retrieve it.
ALLOC_NAME: ${CI_PROJECT_NAME}_ci_${CI_PIPELINE_ID}
@@ -9,17 +9,17 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# GitLab pipelines configurations for the Dane machine at LLNL
# GitLab pipelines configurations for the Ruby machine at LLNL
variables:
MACHINE_NAME: dane
MACHINE_NAME: ruby
.on_dane:
.on_ruby:
tags:
- shell
- dane
- ruby
rules:
# Don't run dane jobs if...
- if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_DANE == "OFF"'
# Don't run ruby jobs if...
- if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_RUBY == "OFF"'
when: never
# Don't run autotest update if...
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "YES"'
@@ -40,17 +40,16 @@ variables:
- when: on_success
# Spack helped builds
# Generic dane build job, extending build script
.build_and_test_on_dane:
extends: [.on_dane]
# Generic ruby build job, extending build script
.build_and_test_on_ruby:
extends: [.on_ruby]
stage: build_and_test
script:
# THREADS is used by 'tests/gitlab/build_and_test', run below
# Dane has 224 threads/node and we run 7 separate jobs: 224=7*32
- export THREADS=28
- export THREADS=16
- echo ${ALLOC_NAME}
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
- echo ${JOBID}
- echo ${MFEM_DATA_DIR}
- echo ${SPEC}
- srun $( [[ -n "${JOBID}" ]] && echo "--jobid=${JOBID}" ) --reservation=ci -t 60 -N 1 tests/gitlab/build_and_test --spec "${SPEC}" --data-dir "${MFEM_DATA_DIR}" --data
- srun $( [[ -n "${JOBID}" ]] && echo "--jobid=${JOBID}" ) --reservation=ci -t 45 -N 1 tests/gitlab/build_and_test --spec "${SPEC}" --data-dir "${MFEM_DATA_DIR}" --data
+1 -1
View File
@@ -18,7 +18,7 @@
setup_baseline:
tags:
- shell
- dane
- ruby
stage: setup
variables:
GIT_STRATEGY: none
+1 -1
View File
@@ -16,7 +16,7 @@
setup:
tags:
- shell
- dane
- ruby
stage: setup
variables:
GIT_STRATEGY: none
@@ -19,8 +19,8 @@ stages:
- cleanup
- baseline_publish
baselinecheck_mfem_intel_dane:
extends: [.on_dane]
baselinecheck_mfem_intel_ruby:
extends: [.on_ruby]
stage: baseline_check
variables:
# TPLS_DIR is used in .gitlab/scripts/baseline to provide the tpls location
@@ -31,8 +31,8 @@ baselinecheck_mfem_intel_dane:
script:
- echo ${BUILD_ROOT}
- echo ${TPLS_DIR}
# Used by the tests in MFEM/tests, dane has 224 threads/node:
- export MFEM_TEST_NP=192
# Used by the tests in MFEM/tests:
- export MFEM_TEST_NP=48
# The next script uses the following environment variables:
# * BASELINE_TEST, SYS_TYPE, CI_PROJECT_DIR, ARTIFACTS_DIR,
# * BUILD_ROOT, TPLS_DIR, MACHINE_NAME
@@ -44,7 +44,7 @@ baselinecheck_mfem_intel_dane:
allow_failure: true
cleanup:
extends: .on_dane
extends: .on_ruby
stage: cleanup
variables:
GIT_STRATEGY: none
@@ -53,7 +53,7 @@ cleanup:
- rm -rf "${BUILD_ROOT}" || true
report_baseline:
extends: [.on_dane]
extends: [.on_ruby]
stage: baseline_report
script:
- echo ${MACHINE_NAME}
@@ -113,8 +113,8 @@ report_baseline:
exit $err
) 9> autotest.lock
baselinepublish_mfem_dane:
extends: [.on_dane]
baselinepublish_mfem_ruby:
extends: [.on_ruby]
stage: baseline_publish
rules:
# - if: '$CI_COMMIT_BRANCH == "master" || $REBASELINE == "YES"'
@@ -129,5 +129,5 @@ baselinepublish_mfem_dane:
include:
- local: .gitlab/configs/common.yml
- local: .gitlab/configs/dane-config.yml
- local: .gitlab/configs/ruby-config.yml
- local: .gitlab/configs/setup-baseline.yml
@@ -19,54 +19,54 @@ stages:
allocate_resource:
variables:
GIT_STRATEGY: none
extends: .on_dane
extends: .on_ruby
stage: allocate_resource
script:
- echo ${ALLOC_NAME}
- salloc --exclusive --nodes=1 --reservation=ci --time=60 --no-shell --job-name=${ALLOC_NAME}
timeout: 6h
# GitLab jobs for the Dane machine at LLNL
# GitLab jobs for the Ruby machine at LLNL
debug_ser_gcc_10:
variables:
SPEC: "%gcc@10.3.1 +debug~mpi"
extends: .build_and_test_on_dane
extends: .build_and_test_on_ruby
debug_par_gcc_10:
variables:
SPEC: "%gcc@10.3.1 +debug+mpi"
extends: .build_and_test_on_dane
extends: .build_and_test_on_ruby
opt_ser_gcc_10:
variables:
SPEC: "%gcc@10.3.1 ~mpi"
extends: .build_and_test_on_dane
extends: .build_and_test_on_ruby
opt_par_gcc_10:
variables:
SPEC: "%gcc@10.3.1"
extends: .build_and_test_on_dane
extends: .build_and_test_on_ruby
opt_par_gcc_10_sundials:
variables:
SPEC: "%gcc@10.3.1 +sundials"
extends: .build_and_test_on_dane
extends: .build_and_test_on_ruby
opt_par_gcc_10_petsc:
variables:
SPEC: "%gcc@10.3.1 +petsc ^petsc+mumps~superlu-dist"
extends: .build_and_test_on_dane
extends: .build_and_test_on_ruby
opt_par_gcc_10_pumi:
variables:
SPEC: "%gcc@10.3.1 +pumi"
extends: .build_and_test_on_dane
extends: .build_and_test_on_ruby
# Release
release_resource:
variables:
GIT_STRATEGY: none
extends: .on_dane
extends: .on_ruby
stage: release_resource_and_report
script:
- echo ${ALLOC_NAME}
@@ -78,17 +78,17 @@ release_resource:
report_job_success:
stage: release_resource_and_report
extends:
- .on_dane
- .on_ruby
- .report_job_success
report_job_failure:
stage: release_resource_and_report
extends:
- .on_dane
- .on_ruby
- .report_job_failure
include:
- local: .gitlab/configs/common.yml
- local: .gitlab/configs/dane-config.yml
- local: .gitlab/configs/ruby-config.yml
- local: .gitlab/configs/setup-build-and-test.yml
- local: .gitlab/configs/report-build-and-test.yml
+2 -2
View File
@@ -14,7 +14,7 @@
# locals
glob_err=${BASELINE_TEST}.err
base=${BASELINE_TEST}-${SYS_TYPE}
if [[ "${MACHINE_NAME}" == "dane" ]]; then
if [[ "${MACHINE_NAME}" == "ruby" ]]; then
base="${BASELINE_TEST}-${MACHINE_NAME}"
fi
base_diff=${base}.diff
@@ -31,7 +31,7 @@ cd tests
mkdir _${BASELINE_TEST} && cd _${BASELINE_TEST}
# run
if [[ "${MACHINE_NAME}" == "dane" ]]; then
if [[ "${MACHINE_NAME}" == "ruby" ]]; then
salloc --nodes=1 --exclusive --reservation=ci ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
elif [[ ${MACHINE_NAME} == "corona" ]]; then
salloc --nodes=1 -t 60 -p pbatch ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
+2 -2
View File
@@ -11,7 +11,7 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# There will be collision between corona and dane baselines.
# There will be collision between corona and ruby baselines.
# Once the corresponding files have been generated, we can switch to machine
# specific ref.
ARTIFACT_PATH=${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/baseline-${SYS_TYPE}
@@ -21,7 +21,7 @@ PATCH_FILE=${ARTIFACT_PATH}.patch
FULL_FILE=${ARTIFACT_PATH}.out
DIFF_FILE=${ARTIFACT_PATH}.diff
# There will be collision between corona and dane baselines.
# There will be collision between corona and ruby baselines.
# Once the corresponding files have been generated, we can switch to machine
# specific ref.
SAVED_NAME=baseline-${SYS_TYPE}.saved
+108 -222
View File
@@ -8,287 +8,159 @@
https://mfem.org
Version 4.8.1 (development)
Version 4.7.1 (development)
===========================
Starting with this version, MFEM requires a C++17 compiler.
Discretization improvements
---------------------------
- Introduced dFEM: a new MFEM capability for Automatic Differentiation (AD) of
nonlinear finite element operators, based on Enzyme or dual numbers AD at
quadrature points. These features are part of the new mfem::future namespace
and some of the API can change in the future. See the new dFEM minimal surface
miniapp in the miniapps/dfem/ directory for illustration of dFEM's use.
- Using Enzyme for AD in MFEM is tested with clang v19 and requires clang/LLVM
built with plugin support. See INSTALL for more details.
- In the ParMoonolith integration, added support for variational resampling of
H1 vector fields.
Meshing improvements
--------------------
- Added support for higher order meshes in Mesh::MakeSimplicial and
ParMesh::MakeSimplicial.
- Added a new miniapp for interpolating a surface grid of points in 3D using a
smooth NURBS surface, that can then be sampled at arbitrary resolution while
staying close to the original geometry. See miniapps/nurbs/nurbs_surface.
GPU computing
-------------
- The function Vector::SetSubVector(const Array<int> &, const real_t) now
executes on device if either the vector or the array have the device flag
set. This is most often used for setting constant essential boundary
conditions. A new function Vector::SetSubVectorHost has been added in cases
where host execution is always needed (e.g. when the DOFs array is small).
- Introduced MFEM_FOREACH_THREAD_DIRECT, which directly maps loop tasks to GPU
threads, assigning one task per thread.
- Implemented a GPU-accelerated matrix-free AMR derefinement `GridFunction`
update operator. This supports mixed geometry meshes and variable order
spaces, and is the default derefinement operator constructed by
`FiniteElementSpace::Update` and `ParFiniteElementSpace::Update`.
The operator requires `FiniteElementSpace::Nonconforming() == true`.
New and updated examples and miniapps
-------------------------------------
- Added miniapps to demonstrate an implementation of the absolute-value
L(1)-Jacobi preconditioners in partially assembled operators. This includes
Multigrid wrapper to demonstrate the effectiveness of these Jacobi-type
operators as smoothers.
These miniapps can be found in `miniapps/diag-smoothers`.
API changes
-----------
- mfem::internal::tensor and mfem::internal::dual have been moved to
mfem::future::tensor and mfem::future::dual.
- API addition: in class `Operator`, added virtual functions: `AbsMult`, and
`AbsMultTranspose`; in class `Vector`, added `Abs` and `Pow`.
Miscellaneous
-------------
- Added the "gpu", "raja-gpu", and "ceed-gpu" backend aliases/shortcuts which
automatically select between CUDA or HIP.
- The CUDA-specific names used by some of the unit tests like 'cunit_tests' and
'pcunit_tests' were replaced by names using 'gpu' instead of 'c' (short for
CUDA) or 'cuda'. These tests automatically run the CUDA/HIP tests based on the
MFEM build configuration.
- Added the option to enable GPU-aware MPI in MFEM using the environment
variable 'MFEM_GPU_AWARE_MPI' set to any value. Setting this environment
variable is an alternative to calling 'Device::SetGPUAwareMPI(true)'.
- Added parallel Address Sanitizer, serial and parallel Undefined Behavior
Sanitizer and serial Memory Sanitizer GitHub actions tests on Ubuntu.
Version 4.8, released on Apr 9, 2025
====================================
Discretization improvements
---------------------------
- Added high-order basis functions on pyramid-shaped elements for all spaces in
the de Rham complex based on the paper "Orientation embedded high order shape
functions for the exact sequence elements of all shapes" by Fuentes, Keith,
Demkowicz and Nagaraj (doi.org/10.1016/j.camwa.2015.04.027). Positive basis
functions (Bernstein basis) for H1 and L2 on pyramids were also added.
- Added support for parallel p- and hp-refinement on quad/hex meshes. For hp, we
currently support only isotropic refinement with L2 or H1 spaces. See the new
miniapps hpref and phpref in the miniapps/meshing/ directory.
- Added several improvements for hyperbolic problems:
* Assembly of Jacobians in HyperbolicFormIntegrator
* Component-wise upwinded flux (ComponentwiseUpwindFlux)
* Average fluxes in NumericalFlux (formerly RiemannSolver) and FluxFunction
- Added convenience methods to class FiniteElementSpace to directly identify all
degrees of freedom on the exterior faces of the domain, without referencing
boundary element attributes (GetExteriorVDofs and GetExteriorTrueDofs).
- Refactored ALGOIM cut integration rules. The interface is unified with
the interface for moment based cut integration rules.
- Altered (Par)GridFunction::Compute*Error functions to ensure they return
non-negative values and therefore behave as "norms".
- SubMesh and ParSubMesh have been extended to work on nonconforming meshes.
Extracting volume and exterior surface submeshes are both supported.
Discretization improvements
---------------------------
- Added NURBS-based H(div) and H(curl) elements in 2D and 3D. Only on single
patch meshes. Only implemented for serial computations.
- LinearFormIntegrator, BilinearFormIntegrator and NonlinearFormIntegrator now
inherit from a base class Integrator that centralizes the logic for selecting
quadrature rules. This includes a virtual method GetDefaultIntegrationRule,
which should be favored over directly defining a default integration rule in
the element-level assembly routines. The latter is still possible, by leaving
the new virtual method as its default base implementation of returning NULL.
- Added support for boundary constraints to the hybridization class.
- Added NURBS-based H(div) and H(curl) elements in 2D and 3D. Currently only for
single patch meshes in serial.
- Added support for external boundary submeshes with nonconformal mesh adaptation.
- Refactored ALGOIM cut integration rules. The interface is unified with the
interface for moment based cut integration rules.
- Added assembly of Jacobians to `HyperbolicFormIntegrator`.
- FiniteElementSpace has new methods to directly set the prolongation and
restriction operators to user-specified sparse matrices.
- Added average fluxes to `NumericalFlux` (formerly `RiemannSolver`)
and `FluxFunction`.
- Added support for H(div) spaces in class QuadratureInterpolator. Currently only
- Added component-wise upwinded flux (`ComponentwiseUpwindFlux`).
- Added support for H(div) spaces in class QuadratureInterpolator. For now, only
(vector) VALUES, (vector) PHYSICAL_VALUES, and PHYSICAL_MAGNITUDES evaluations
are implemented.
- Added support for boundary constraints to class Hybridization.
- Added support for custom interpolation procedure in FindPointsGSLIB.
- Added GSLIB-based gather-scatter operator.
are implemented. [PR #4669]
Meshing improvements
--------------------
- Added support for nonuniform anisotropic mesh refinement on serial quad/hex
meshes with arbitrary spacing in each direction. This enables in particular
3:1 refinement, as demonstrated in the new meshing miniapp ref321.
- Added native AD support for numerous TMOP metrics that didn't have first or
second derivative implementations.
- Added capabilities for optimization and adaptation of periodic meshes with
TMOP. The internals of TMOP were modified so that the optimization problem is
always solved with respect to mesh displacements.
- The ExodusII reader now handles pyramid and wedge element types. Mixed meshes
are also supported.
- New convenience methods for manipulating boundary attribute markers in class
Mesh: MarkExternalBoundaries, MarkNamedBoundaries, UnmarkInternalBoundaries
and UnmarkNamedBoundaries. See Examples 1/1p and 11p for basic usage.
- Added support for nonuniform anisotropic (nonconforming) mesh refinement with
arbitrary spacing in each direction, for quadrilateral (2D) and hexahedral
(3D) meshes. This enables in particular 3:1 refinement, as demonstrated in the
new meshing miniapp ref321.
- Added a new method, GetExteriorFaceMarker, to the serial and parallel mesh
classes for identifying faces on the exterior of the mesh irrespective of
their presence in the list of "boundary elements".
New and updated examples and miniapps
-------------------------------------
- Added miniapps to demonstrate the H(div) and H(curl) NURBS elements.
- Added native AD support for computing the derivatives of numerous TMOP metrics
that didn't have first or second derivative implementations.
- Added an MFEM example for the eikonal equation. This new solver is based on
the proximal Galerkin method introduced by Keith and Surowiec.
- Added ExodusII output capability which can handle in particular pyramid and
wedge element types. Mixed meshes are also supported.
- Added a new toy miniapp that animates an interesting fidget spiral cone toy.
See miniapps/toys/spiral.cpp.
- Added InverseElementTransformation::InitGuessType::EdgeScan as an alternative
initial guess type. This guess type tries solving with multiple initial guesses
along the r/s/t=0 edges of the element until a valid solution is found or all
initial guess points are exhausted.
- Added new convenience constructors for NURBS patches and knot vectors.
- Added a command line option to all miniapps (`-p` or `--send-port`) for
specifying the GLVis server socket port (19916 by default).
GPU computing
-------------
- Extended FindPointsGSLIB to support general field interpolation on GPUs. Note
that this requires that switch from gslib v1.0.7 to v1.0.9.
- Added support for GPU-accelerated batched linear algebra (using cuBLAS,
hipBLAS, MAGMA, or native MFEM functionality) through the BatchedLinAlg class.
- A new GPU kernel dispatch mechanism was introduced. Users can instantiate
specialized kernels for specific combinations of (for example) polynomial
degree and number of quadrature points using method AddSpecialization in
classes DiffusionIntegrator and MassIntegrator (this functionality may be
added to more integrators in the future).
degree and number of quadrature points using
`DiffusionIntegrator::AddSpecialization` and
`MassIntegrator::AddSpecialization` (this functionality may be added to more
integrators in the future).
- Added BatchInverseElementTransformation to batch InverseElementTransformation
searches. Batch searches are currently limited to meshes with a single element
geometry type of SEGMENT, SQUARE, or CUBE. Additional element geometry types
may be added in the future. Mixed element order meshes are supported. Batch
searches can be performed on the CPU (serial per MPI rank) or GPU. Embedded
elements (SEGMENT in 2D/3D space or SQUARE in 3D space) are supported, however
the existing solvers may struggle to find a valid solution.
- Calls to slower fallback kernels can be reported to `mfem::err` by setting
the environment variable `MFEM_REPORT_KERNELS` to any value other than `NO`
or by explicitly calling `KernelReporter::Enable`. Users can then add
specializations for these kernels to achieve higher performance.
- Calls to slower fallback kernels can be reported to mfem::err by setting the
environment variable MFEM_REPORT_KERNELS to any value other than NO or by
explicitly calling KernelReporter::Enable. For higher performance, users can
then add specializations for these kernels.
- Element assembly kernels have been added for low-order refined to
high-order transfer operators. New kernels can be offloaded as device
kernels. Example usage may be found in lor-transfer.cpp under miniapps/tools.
- Element assembly kernels have been added for low-order refined -> high-order
transfer operators. New kernels can be offloaded as device kernels. Example
usage may be found in lor-transfer.cpp in the miniapps/tools/ directory.
- Added GPU acceleration and element assembly for DivDivIntegrator and
NormalTraceJumpIntegrator.
- Added support for GPU accelerated FindPointsGSLIB. Note that this will require
the users to switch from gslib v1.0.7 to v1.0.9.
- Allow BlockLowerTriangularPreconditioner to run on GPU.
- Use device vectors in GMRES, FGMRES and other iterative methods.
Linear and nonlinear solvers
----------------------------
- Added GPU acceleration of the algebraic hybridization solver for grad-div
problems in H(div). See Example 4.
- Added a self-contained implementation of the Method of Moving Asymptotes (MMA)
for solving optimization problems.
Miscellaneous
-------------
- Added support for SUNDIALS v7. See the section "API changes" for some small
changes related to this new version.
- Changed the name of class IterativeSolverMonitor to IterativeSolverController,
which now allows for specifying convergence by a user defined criterion. For
backward compatibility, the old name is still available.
- Refactored the `ARKStepSolver` class (ARKODE interface) to use
`TimeDependentOperator::Mult` only when the associated ODE operator is
expressed in explicit form (i.e., `TimeDependentOperator::isExplicit()`),
otherwise `TimeDependentOperator::ExplicitMult` is used. A check has been
added to `ARKStepSolver` to verify that the associated ODE operator is not in
explicit form when a mass matrix solver is enabled via a call to either the
`UseMFEMMassLinearSolver` or `UseSundialsMassLinearSolver` methods. This is
because enabling a mass matrix solver assumes that F(u,k,t) = M k in the
associated ODE operator.
- Refactored the ARKStepSolver class (ARKODE interface) to use the Mult() method
of TimeDependentOperator only when the associated ODE operator is expressed in
explicit form (i.e., TimeDependentOperator::isExplicit()), otherwise the
method ExplicitMult() is used. A check has been added to ARKStepSolver to
verify that the associated ODE operator is not in explicit form when a mass
matrix solver is enabled via a call to either the UseMFEMMassLinearSolver or
UseSundialsMassLinearSolver methods. This is because enabling a mass matrix
solver assumes that F(u,k,t) = M k in the associated ODE operator.
- Added support for custom interpolation procedure in FindPointsGSLIB.
- Added ODE solvers selection routines. This creates a uniformity across
examples, miniapps and other executables in regard to ODE (time-integrator)
selection.
- `FiniteElementSpace` has new methods to directly set prolongation and
restriction operators to arbitrary sparse matrices.
- Added new mechanism for retrieving and setting state vectors in ODE solvers.
This is relevant for AB/AM and gen-alpha solvers.
- There are new convenience constructors for NURBS patches and knot vectors.
- Added ODEsolver/ODEsolver2 unit tests to verify order of convergence and
read/write functionality.
- Added convenience methods for manipulating boundary attribute marker arrays;
`(Par)Mesh::MarkExternalBoundaries`, `(Par)Mesh::UnmarkInternalBoundaries`,
`(Par)Mesh::MarkNamedBoundaries`, and `(Par)Mesh::UnmarkNamedBoundaries`.
See examples `ex1.cpp`, `ex1p.cpp`, and `ex11p.cpp` for basic usage.
New and updated examples and miniapps
-------------------------------------
- Added an MFEM example for the eikonal equation (examples/ex40) based on the
proximal Galerkin method introduced by Keith and Surowiec.
- Added `(Par)Mesh::GetExteriorFaceMarker` for identifying faces on the
exterior of the mesh irrespective of their presence in the list of "boundary
elements".
- Added miniapps to demonstrate the H(div) and H(curl) NURBS elements.
- Added methods to `(Par)FiniteElementSpace` to identify all degrees of freedom
located on the exterior of the domain without reference to the list of
"boundary elements"; `GetExteriorVDofs` and `GetExteriorTrueDofs`.
- Fixed element visualization in the Mesh explorer miniapp.
- `LinearFormIntegrator` and `NonlinearFormIntegrator` (including
`BilinearFormIntegrator`) now all inherit from a base class `Integrator`
that combines some logic related to selecting quadrature rules. This includes
a virtual method `Integrator::GetDefaultIntegrationRule`, which should be
favored over directly defining a default integration rule in the element-level
assembly routines (although the latter is still possible, by leaving the new
virtual method as its default base implementation of returning `NULL`).
- Added a command line option to all miniapps (-p or --send-port) for
specifying the GLVis server socket port (19916 by default).
- Added a new toy miniapp that animates an interesting fidget spiral cone toy.
See miniapps/toys/spiral.cpp.
Miscellaneous
-------------
- Updated the benchmarks (in tests/benchmarks) to work with the latest Google
Benchmarks classes (version 1.9.1). Renamed the MFEM_ENABLE_GOOGLE_BENCHMARKS
CMake option to just MFEM_ENABLE_BENCHMARKS.
- Updated the minimum CMake version requirements:
* CMake >= 3.12 for CPU builds,
* CMake >= 3.17 for CUDA builds, and
* CMake >= 3.14 for HIP builds (CMake >= 3.12 may work as well, not tested).
- Various other simplifications, extensions, and bugfixes in the code.
- Changed the name of `IterativeSolverMonitor` to `IterativeSolverController`
which now allows for declaring convergence by a user defined criterion. For
backward compatibility, the old name is still available.
API changes
-----------
- In class GridFunction, fec was renamed to fec_owned.
- API change: 'TMOP_Metric_skew2D' has been marked as deprecated.
- RiemannSolver was renamed to NumericalFlux (the old name has been deprecated
through typedef).
- API change: in class GridFunction, 'fec' was renamed to 'fec_owned'.
- API changes due to SUNDIALS v7:
* the SUNDIALS types realtype and booleantype are no longer defined by v7
and therefore MFEM now uses the new type names sunrealtype and
sunbooleantype, respectively, which MFEM defines when using SUNDIALS < v6
- API change: `RiemannSolver` was renamed to `NumericalFlux` (the old name has
been been deprecated through typedef)
- API change: support for SUNDIALS v7:
* the SUNDIALS types `realtype` and `booleantype` are no longer defined by v7
and therefore MFEM now uses the new type names `sunrealtype` and
`sunbooleantype`, respectively, which MFEM defines when using SUNDIALS < v6
where these types were not defined.
* The SUNDIALS macro SUNLS_SUCCESS and some other *_SUCCESS macros were
removed and replaced by SUN_SUCCESS in v7, so to avoid tedious checks for
SUNDIALS versions, MFEM now defines and uses the constant SUN_SUCCESS when
* The SUNDIALS macro `SUNLS_SUCCESS` and some other `*_SUCCESS` macros were
removed and replaced by `SUN_SUCCESS` in v7, so to avoid tedious checks for
SUNDIALS versions, MFEM now defines and uses the constant `SUN_SUCCESS` when
using SUNDIALS < v7.
* The constants SUN_PREC_*, introduced by SUNDIALS v6 are now introduced by
* The constants `SUN_PREC_*`, introduced by SUNDIALS v6 are now introduced by
MFEM when using SUNDIALS < v6 to avoid tedious version checks.
- TMOP_Metric_skew2D has been marked as deprecated.
Version 4.7, released on May 7, 2024
====================================
@@ -313,6 +185,9 @@ Meshing improvements
- Added support for internal boundary elements in nonconforming meshes.
- Added ExodusII output capability. The writer can handle first-order (Pyramid5,
Wedge6, Hex8, Tet4) and second-order FE types (Pyramid14, Wedge18, Hex27, Tet10).
- The ReadCubit Genesis mesh importer has been rewritten to improve readability.
Discretization improvements
@@ -372,6 +247,15 @@ New and updated examples and miniapps
- Added two new example codes: 38 and 39/39p described above. Substantially
updated Example 18/18p.
- Added ODE solvers selection routines. This creates a uniformity across examples,
miniapps and other executables in regard to ODE(time-integrator) selection.
- Added new mechanism for retrieving and setting state vectors in ODE solvers.
This is relevant for AB/AM and gen-alpha solvers.
- Added ODEsolver/ODEsolver2 unit tests to verify order of convergence and
read/write functionality.
Miscellaneous
-------------
- Updated the Doxygen documentation style, which now requires Doxygen version
@@ -385,6 +269,8 @@ Miscellaneous
- Various other simplifications, extensions, and bugfixes in the code.
- Added GSLIB-based gather-scatter operator.
Version 4.6, released on September 27, 2023
===========================================
+34 -70
View File
@@ -12,14 +12,13 @@
# The variable CMAKE_CXX_STANDARD and related were introduced in CMake v3.1
# Version 3.8 fixes the handling of CMAKE_CXX_STANDARD for try_compile.
# Version 3.8 or newer is required for direct CUDA support.
# Version 3.12 or newer is required for setting maximum policy version.
cmake_minimum_required(VERSION 3.12.0...4.0.0)
cmake_minimum_required(VERSION 3.8)
message(STATUS "CMake version: ${CMAKE_VERSION}")
set(USER_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/config/user.cmake" CACHE PATH
"Path to optional user configuration file.")
# Require C++17 and disable compiler-specific extensions
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to use.")
# Require C++11 and disable compiler-specific extensions
set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ standard to use.")
set(CMAKE_CXX_STANDARD_REQUIRED ON CACHE BOOL
"Force the use of the chosen C++ standard.")
set(CMAKE_CXX_EXTENSIONS OFF CACHE BOOL "Enable C++ standard extensions.")
@@ -59,7 +58,7 @@ project(mfem NONE)
# Current version of MFEM, see also `makefile`.
# mfem_VERSION = (string)
# MFEM_VERSION = (int) [automatically derived from mfem_VERSION]
set(${PROJECT_NAME}_VERSION 4.8.1)
set(${PROJECT_NAME}_VERSION 4.7.1)
# Prohibit in-source build
if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
@@ -105,13 +104,6 @@ endif()
# Include xSDK default CMake file.
include("${CMAKE_CURRENT_SOURCE_DIR}/config/XSDKDefaults.cmake")
# Path to MFEM's CMake modules and utilities.
set(MFEM_CMAKE_PATH ${PROJECT_SOURCE_DIR}/config)
set(CMAKE_MODULE_PATH ${MFEM_CMAKE_PATH}/cmake/modules)
# Load MFEM CMake utilities.
include(MfemCmakeUtilities)
# Enable languages.
enable_language(CXX)
if (MINGW)
@@ -124,15 +116,17 @@ if (MFEM_USE_CUDA)
if (MFEM_USE_HIP)
message(FATAL_ERROR " *** MFEM_USE_HIP cannot be combined with MFEM_USE_CUDA.")
endif()
# CUDAToolkit was added in CMake 3.17, so we require at least CMake 3.17 when
# CUDA is enabled:
if (CMAKE_VERSION VERSION_LESS 3.17.0)
message(FATAL_ERROR "CUDA support requires CMake >= 3.17")
endif()
# Use ${CMAKE_CXX_COMPILER} as the cuda host compiler.
if (NOT CMAKE_CUDA_HOST_COMPILER)
set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER})
endif()
enable_language(CUDA)
set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD} CACHE STRING
"CUDA standard to use.")
set(CMAKE_CUDA_STANDARD_REQUIRED ON CACHE BOOL
"Force the use of the chosen CUDA standard.")
set(CMAKE_CUDA_EXTENSIONS OFF CACHE BOOL "Enable CUDA standard extensions.")
set(CUDA_FLAGS "--expt-extended-lambda")
if (CMAKE_VERSION VERSION_LESS 3.18.0)
set(CUDA_FLAGS "-arch=${CUDA_ARCH} ${CUDA_FLAGS}")
elseif (NOT CMAKE_CUDA_ARCHITECTURES)
@@ -146,33 +140,18 @@ if (MFEM_USE_CUDA)
set(CUDA_ARCH "CMAKE_CUDA_ARCHITECTURES: ${CMAKE_CUDA_ARCHITECTURES}")
endif()
message(STATUS "Using CUDA architecture: ${CUDA_ARCH}")
enable_language(CUDA)
if (CMAKE_VERSION VERSION_LESS 3.18.0)
# backup try to detect if this is clang or nvcc
if(CMAKE_CUDA_COMPILER MATCHES "nvcc$")
# nvcc
set(MFEM_CUDA_COMPILER_IS_NVCC ON)
set(CUDA_FLAGS "${CUDA_FLAGS} --expt-extended-lambda --expt-relaxed-constexpr")
endif()
else()
if (CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
# nvcc
set(MFEM_CUDA_COMPILER_IS_NVCC ON)
set(CUDA_FLAGS "${CUDA_FLAGS} --expt-extended-lambda --expt-relaxed-constexpr")
endif()
if (CMAKE_VERSION VERSION_LESS 3.12.0)
# CMake versions 3.8 and 3.9 require this to work; 3.10 and 3.11 are not
# tested and may not actually need this (but should be ok to keep).
set(CUDA_FLAGS "-ccbin=${CMAKE_CXX_COMPILER} ${CUDA_FLAGS}")
set(CMAKE_CUDA_HOST_LINK_LAUNCHER ${CMAKE_CXX_COMPILER})
endif()
set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD} CACHE STRING
"CUDA standard to use.")
set(CMAKE_CUDA_STANDARD_REQUIRED ON CACHE BOOL
"Force the use of the chosen CUDA standard.")
set(CMAKE_CUDA_EXTENSIONS OFF CACHE BOOL "Enable CUDA standard extensions.")
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${CUDA_FLAGS}")
find_package(CUDAToolkit REQUIRED)
set(CUSPARSE_FOUND TRUE)
set(CUBLAS_FOUND TRUE)
# Initialize CUSPARSE_LIBRARIES and CUBLAS_LIBRARIES:
mfem_culib_set_libraries(CUSPARSE cusparse)
mfem_culib_set_libraries(CUBLAS cublas)
get_target_property(CUSPARSE_LIBRARIES CUDA::cusparse LOCATION)
get_target_property(CUBLAS_LIBRARIES CUDA::cublas LOCATION)
endif()
if (XSDK_ENABLE_C)
@@ -185,6 +164,13 @@ endif()
# Suppress warnings about MACOSX_RPATH
set(CMAKE_MACOSX_RPATH OFF CACHE BOOL "")
# CMake needs to know where to find things
set(MFEM_CMAKE_PATH ${PROJECT_SOURCE_DIR}/config)
set(CMAKE_MODULE_PATH ${MFEM_CMAKE_PATH}/cmake/modules)
# Load MFEM CMake utilities.
include(MfemCmakeUtilities)
string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UC)
mfem_version_to_int(${${PROJECT_NAME}_VERSION} ${PROJECT_NAME_UC}_VERSION)
set(${PROJECT_NAME_UC}_VERSION_STRING ${${PROJECT_NAME}_VERSION})
@@ -269,11 +255,7 @@ if (MFEM_USE_OPENMP OR MFEM_USE_LEGACY_OPENMP)
if (OPENMP_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
if (MFEM_USE_CUDA)
if(MFEM_CUDA_COMPILER_IS_NVCC)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=${OpenMP_CXX_FLAGS}")
else()
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=${OpenMP_CXX_FLAGS}")
endif()
endif()
endif()
@@ -405,11 +387,6 @@ if (MFEM_USE_GSLIB)
find_package(GSLIB REQUIRED)
endif()
# HDF5
if (MFEM_USE_HDF5)
find_package(HDF5 REQUIRED)
endif()
# NetCDF
if (MFEM_USE_NETCDF)
find_package(NetCDF REQUIRED)
@@ -549,10 +526,9 @@ if (MFEM_USE_TRIBOL)
endif()
endif()
# Enzyme
if (MFEM_USE_ENZYME)
find_package(Enzyme REQUIRED HINTS ${ENZYME_DIR})
message(STATUS "Enzyme found in ${ENZYME_DIR}.")
set(ENZYME_INCLUDE_DIRS ${ENZYME_DIR}/include)
find_package(ENZYME REQUIRED)
endif()
# MFEM_TIMER_TYPE
@@ -592,26 +568,20 @@ find_package(Threads REQUIRED)
# integers, the METIS header (with 32-bit indices, as used by mfem) needs to
# be before SuiteSparse.
set(MFEM_TPLS OPENMP HYPRE LAPACK BLAS SuperLUDist STRUMPACK METIS SuiteSparse
SUNDIALS PETSC SLEPC MUMPS AXOM FMS CONDUIT Ginkgo GNUTLS GSLIB HDF5
SUNDIALS PETSC SLEPC MUMPS AXOM FMS CONDUIT Ginkgo GNUTLS GSLIB
NETCDF MPFR PUMI HIOP POSIXCLOCKS MFEMBacktrace ZLIB OCCA CEED RAJA UMPIRE
ADIOS2 MKL_CPARDISO MKL_PARDISO AMGX MAGMA CUSPARSE CUBLAS CALIPER CODIPACK
BENCHMARK PARELAG TRIBOL MPI_CXX HIP HIPBLAS HIPSPARSE MOONOLITH BLITZ
ALGOIM ENZYME)
# Add all created targets and *_FOUND libraries in the variables TPL_TARGETS and
# TPL_LIBRARIES, respectively.
set(TPL_TARGETS)
# Add all *_FOUND libraries in the variable TPL_LIBRARIES.
set(TPL_LIBRARIES "")
set(TPL_INCLUDE_DIRS "")
foreach(TPL IN LISTS MFEM_TPLS)
if (${TPL}_FOUND OR TARGET ${TPL})
if (${TPL}_FOUND)
message(STATUS "MFEM: using package ${TPL}")
if (TARGET ${TPL})
list(APPEND TPL_TARGETS ${TPL})
else()
list(APPEND TPL_LIBRARIES ${${TPL}_LIBRARIES})
list(APPEND TPL_INCLUDE_DIRS ${${TPL}_INCLUDE_DIRS})
endif()
list(APPEND TPL_LIBRARIES ${${TPL}_LIBRARIES})
list(APPEND TPL_INCLUDE_DIRS ${${TPL}_INCLUDE_DIRS})
endif()
endforeach(TPL)
list(REVERSE TPL_LIBRARIES)
@@ -686,10 +656,7 @@ set(MFEM_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
# Declaring the library
mfem_add_library(mfem ${SOURCES} ${HEADERS} ${MASTER_HEADERS})
# message(STATUS "TPL_LIBRARIES = ${TPL_LIBRARIES}")
target_link_libraries(mfem PUBLIC ${TPL_LIBRARIES} ${TPL_TARGETS})
if (TPL_TARGETS)
add_dependencies(mfem ${TPL_TARGETS})
endif()
target_link_libraries(mfem PUBLIC ${TPL_LIBRARIES})
if (MINGW)
target_link_libraries(mfem PRIVATE ws2_32)
endif()
@@ -713,9 +680,6 @@ if (MFEM_USE_MPI)
target_link_libraries(mfem PUBLIC ${MPI_CXX_LINK_FLAGS})
endif()
endif()
if (MFEM_USE_ENZYME)
target_link_libraries(mfem PUBLIC ClangEnzymeFlags)
endif()
set_target_properties(mfem PROPERTIES VERSION "${mfem_VERSION}")
set_target_properties(mfem PROPERTIES SOVERSION "${mfem_VERSION}")
+1 -8
View File
@@ -120,10 +120,7 @@ The MFEM source code has the following structure:
| └── superlu
├── fem
│ ├── ceed
│ ├── dfem
│ ├── eltrans
│ ├── fe
│ ├── gslib
│ ├── integ
│ ├── lor
│ ├── moonolith
@@ -131,7 +128,6 @@ The MFEM source code has the following structure:
│ └── tmop
├── general
├── linalg
│ ├── batched
│ └── simd
├── mesh
│ └── submesh
@@ -139,7 +135,6 @@ The MFEM source code has the following structure:
│ ├── adjoint
│ ├── autodiff
│ ├── common
│ ├── dfem
│ ├── dpg
│ ├── electromagnetics
│ ├── gslib
@@ -551,8 +546,6 @@ Before a PR can be merged, it should satisfy the following:
- [ ] Add a short description of the example in the "Extensive Examples" section of `features.md`.
- [ ] New miniapps:
- [ ] All sample runs at the top of the miniapp source file work.
- [ ] Add to internal testing repo, if sample runs should be included in nightly tests [internally](#tests-at-llnl).
- [ ] Exclude long sample runs from automated testing, with `* ` (one space) before the command.
- [ ] Update top-level `makefile` and `makefile` in corresponding miniapp directory.
- [ ] Add the miniapp binary and any files generated by it to the top-level `.gitignore` file.
- [ ] Update CMake build system:
@@ -747,7 +740,7 @@ and debug build is performed with a simple run of `ex1` to verify the executable
- We mirror the `master` and `next` branches internally (to `gh-master` and
`gh-next`) and run longer nightly tests via cron. On the weekends, a more
extensive test is run which extracts and executes all the different sample
runs from each example and most miniapps.
runs from each example.
- We also mirror PRs on the LLNL GitLab instance. PR mirroring can only be
triggered by _LLNL developers_, but test status is publicly available. Only
+12 -125
View File
@@ -121,20 +121,10 @@ Parallel build:
make -j 4
(For METIS 5, see https://mfem.org/building/#parallel-build-using-metis-5)
Parallel build with fetching of hypre and METIS:
mkdir <mfem-buil-dir> ; cd <mfem-build-dir>
cmake <mfem-source-dir> -DMFEM_USE_MPI=YES -DFETCH_TPLS=YES
make -j 4
CUDA build:
(this build requires CMake 3.17 or newer)
(this build requires CMake 3.8 or newer)
mkdir <mfem-build-dir> ; cd <mfem-build-dir>
cmake <mfem-source-dir> -DMFEM_USE_CUDA=YES -DCUDA_ARCH=sm_70
make -j 4
HIP build:
mkdir <mfem-build-dir> ; cd <mfem-build-dir>
cmake <mfem-source-dir> -DMFEM_USE_HIP=YES -DHIP_ARCH=gfx942 -DCMAKE_CXX_COMPILER=amdclang++ -DCMAKE_HIP_COMPILER=amdclang++
cmake <mfem-source-dir> -DMFEM_USE_CUDA=YES
make -j 4
Example codes (serial/parallel, depending on the build):
@@ -268,7 +258,7 @@ See the configuration file config/defaults.mk for the default settings.
Compilers:
CXX - C++ compiler, serial build
MPICXX - MPI C++ compiler, parallel build
CUDA_CXX - The CUDA compiler, 'nvcc' or 'clang++'
CUDA_CXX - The CUDA compiler, 'nvcc'
Compiler options:
OPTIM_FLAGS - Options for optimized build
@@ -428,10 +418,6 @@ MFEM_USE_GNUTLS = YES/NO
When MFEM_USE_GNUTLS is enabled, the additional build options, GNUTLS_*, are
also used, see below.
MFEM_USE_HDF5 = YES/NO
The HDF5 library is used for input and output of HDF5 files, for example
Cubit mesh files or VTKHDF files for ParaView.
MFEM_USE_NETCDF = YES/NO
NetCDF is the library that is used by the SNL Cubit mesh generator to create
Genesis mesh files. This option enables a reader for these files, which
@@ -613,12 +599,11 @@ MFEM_USE_TRIBOL = YES/NO
MFEM_USE_ENZYME = YES/NO
Enables automatic differentiation support through the LLVM plugin Enzyme.
This requires the compiler to be set to clang (>=14.0.0). We also advise the
use of the link time optimization (LTO) plugin, so functions defined over
multiple files (compilation units) can be differentiated automatically. This
requires to also use LLVM/LLD for linking. The recommended options are in
config/defaults.mk. For more detailed instructions, see the section "Specific
options for Enzyme" below.
This requires the compiler to be set to clang (>=14.0.0). We also advise to
use the link time optimization (LTO) plugin, to enable functions that you
define over multiple files (compilation units) and want to be differentiated
automatically, to work. This requires to also use LLVM/LLD for linking.
Recommended options are in config/defaults.mk.
MFEM_BUILD_TAG = (any value)
An optional tag to characterize the build. Exported to config/config.mk.
@@ -668,7 +653,6 @@ The specific libraries and their options are:
- OpenMP (optional), usually part of compiler, used when either MFEM_USE_OPENMP
or MFEM_USE_LEGACY_OPENMP is set to YES.
Options: OPENMP_OPT, OPENMP_LIB.
Versions: OpenMP >= 3.1 when MFEM_USE_OPENMP=YES.
- High-resolution POSIX clocks: when using MFEM_TIMER_TYPE = 2, it may be
necessary to link with a system library (e.g. librt.so).
@@ -744,9 +728,6 @@ The specific libraries and their options are:
Options: GNUTLS_OPT, GNUTLS_LIB.
Versions: GnuTLS >= 2.12.0, older versions may work too.
- HDF5 (optional), used when MFEM_USE_HDF5 = YES, required for reading and
writing files in VTKHDF format.
- NetCDF (optional), used when MFEM_USE_NETCDF = YES, required for reading Cubit
mesh files. Also requires installation of HDF5 and ZLIB, as explained at the
NetCDF web site. Note that we use the plain vanilla "C" version of NetCDF, you
@@ -842,13 +823,12 @@ The specific libraries and their options are:
- CUDA (optional), used when MFEM_USE_CUDA = YES.
URL: https://developer.nvidia.com/cuda-toolkit
Options: CUDA_CXX, CUDA_ARCH, CUDA_OPT, CUDA_LIB, CUDA_DIR (when CUDA_CXX=clang++).
Options: CUDA_CXX, CUDA_ARCH, CUDA_OPT, CUDA_LIB.
Versions: CUDA >= 10.1.168.
- HIP (optional), used when MFEM_USE_HIP = YES.
URL: https://rocmdocs.amd.com
Options: HIP_CXX, HIP_ARCH, HIP_OPT, HIP_LIB.
Versions: ROCm >= 5.6.1.
- OCCA (optional), used when MFEM_USE_OCCA = YES.
URL: https://libocca.org
@@ -919,7 +899,7 @@ The specific libraries and their options are:
- Enzyme, used when MFEM_USE_ENZYME = YES. Requires LLVM/Clang >= 14.0.0.
URL: https://github.com/EnzymeAD/Enzyme
Options: ENZYME_DIR, ENZYME_OPT, ENZYME_LIB.
Versions: Enzyme >= v0.0.176.
Versions: Enzyme >= v0.0.33.
Building with CMake
@@ -1022,7 +1002,7 @@ Configuration variables (CMake)
===============================
See the configuration file config/defaults.cmake for the default settings.
Note: the option MFEM_USE_CUDA requires CMake version 3.17 or newer!
Note: the option MFEM_USE_CUDA requires CMake version 3.8 or newer!
Non-standard CMake variables for compilers:
CXX - If set, overwrite the auto-detected C++ compiler, serial build
@@ -1053,7 +1033,6 @@ MFEM_USE_STRUMPACK
MFEM_USE_GINKGO
MFEM_USE_AMGX
MFEM_USE_GNUTLS
MFEM_USE_HDF5
MFEM_USE_NETCDF
MFEM_USE_MPFR
MFEM_USE_ZLIB
@@ -1081,9 +1060,6 @@ The following options are CMake specific:
MFEM_ENABLE_TESTING - Enable the ctest framework for testing.
MFEM_ENABLE_EXAMPLES - Build all of the examples by default.
MFEM_ENABLE_MINIAPPS - Build all of the miniapps by default.
FETCH_TPLS - Enable fetching of all supported third-party libraries.
HYPRE_FETCH - Enable fetching of hypre.
METIS_FETCH - Enable fetching of metis.
External libraries (CMake):
---------------------------
@@ -1145,12 +1121,6 @@ The following built-in CMake packages are also used:
set the <LIBNAME>_LIBRARIES option directly; the configuration option
<LIBNAME>_DIR is not supported.
The MFEM CMake build system also provides fetching (automated building) for the
packages/libraries listed below. Note that when fetching is enabled, any related
auto-detection functionality is disabled.
- HYPRE
- METIS
Building without GNU make or CMake
==================================
@@ -1191,89 +1161,6 @@ larger problems, there are two options:
1. Building hypre with '--enable-bigint' defines the local and global indices to
be 64-bit. This is convenient, but requires more memory than necessary.
2. Building hypre with '--enable-mixedint' defines the local indices to be
2. Building hypre with '--enable-mixedint' defines the local indiced to be
32-bit, while using a 64-bit storage for global indices. This option is
currently tested only in ex1p, and may not work in more general settings.
Specific options for HIP
========================
MFEM expects the `ROCM_PATH` environment variable to be set to the path of the
ROCM install, as well as having `$ROCM_PATH/bin` in `PATH`.
Specific options for RAJA+HIP+MPI
=================================
RAJA uses CMake's built-in HIP support (added in CMake 3.21), while MFEM uses
the older HIP C++ library build/linkage. To ensure proper build and linkage
check that `CMAKE_CXX_COMPILER` and `CMAKE_HIP_COMPILER` are set to the same
compiler. This is especially important when using an MPI compiler (for example
crayCC) where some linker flags may get dropped if these two are not identical.
Specific options for Enzyme
===========================
To work properly, MFEM and Enzyme need to use the same LLVM/Clang configuration.
For example, on macOS this can be done by using Homebrew: first install Enzyme,
which in turn installs LLVM as a dependency (as of May 2025, this is LLVM 19):
brew install enzyme
In order to ensure the correct compiler choice for the MFEM makefile build, set
CXX = $(shell brew --prefix llvm@19)/bin/clang++
in the user.mk file (adapted from config/defaults.mk, see the section "Building
with GNU make" above). With MPI, it is convenient to set
MPICXX = OMPI_CXX=$(CXX) mpicxx
for OpenMPI and
MPICXX = MPICH_CXX=$(CXX) mpicxx
for MPICH.
Additionally, the Enzyme directory needs to be set in user.mk as follows:
ENZYME_DIR = $(shell brew --prefix enzyme)
Specifically, a full build on a Mac can be tested by adding the following
user.mk file in the config/ directory
MFEM_USE_ENZYME = YES
ENZYME_DIR = $(shell brew --prefix enzyme)
LLVM_DIR = $(shell brew --prefix llvm@19)
CXX = $(LLVM_DIR)/bin/clang++
MFEM_USE_MPI = YES
MPICXX = OMPI_CXX=$(CXX) mpicxx
and running
make config
make -j
cd miniapps/dfem
make
./dfem-minimal-surface
On Linux systems, for example Ubuntu 24.04, use the package manager to install
the Enzyme dependencies
sudo apt install libclang-dev libzstd-dev llvm-dev clang
and then clone and build Enzyme
cd $HOME
git clone https://github.com/EnzymeAD/Enzyme.git
cd Enzyme/enzyme && mkdir build && cd build
CC=clang CXX=clang++ cmake .. -DLLVM_DIR=/usr/lib/llvm-18/lib/cmake -DCMAKE_INSTALL_PREFIX=$HOME/Enzyme/enzyme/build
make -j
make install
From here, one can proceed in the same way using the following user.mk settings
MFEM_USE_ENZYME = YES
ENZYME_DIR = $(HOME)/Enzyme/enzyme/build
CXX = clang++
MFEM_USE_MPI = YES
MPICXX = OMPI_CXX=$(CXX) mpicxx
On other Linux systems the LLVM packages may have different names, for example
on RHEL9, one needs to "sudo yum install llvm-devel libzstd clang-devel".
-1
View File
@@ -41,7 +41,6 @@ set(MFEM_USE_MAGMA @MFEM_USE_MAGMA@)
set(MFEM_USE_HIOP @MFEM_USE_HIOP@)
set(MFEM_USE_GNUTLS @MFEM_USE_GNUTLS@)
set(MFEM_USE_GSLIB @MFEM_USE_GSLIB@)
set(MFEM_USE_HDF5 @MFEM_USE_HDF5@)
set(MFEM_USE_NETCDF @MFEM_USE_NETCDF@)
set(MFEM_USE_PETSC @MFEM_USE_PETSC@)
set(MFEM_USE_SLEPC @MFEM_USE_SLEPC@)
-3
View File
@@ -132,9 +132,6 @@
// Enable Conduit support.
#cmakedefine MFEM_USE_CONDUIT
// Enable functionality based on the HDF5 library (reading VTKHDF files).
#cmakedefine MFEM_USE_HDF5
// Enable functionality based on the NetCDF library (reading CUBIT files).
#cmakedefine MFEM_USE_NETCDF
+27
View File
@@ -0,0 +1,27 @@
# Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM 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.
message(STATUS "Looking for ENZYME ...")
message(STATUS " in ENZYME_DIR = ${ENZYME_DIR}")
# Make sure the directory and version combination works. Do nothing otherwise.
if(EXISTS "${ENZYME_DIR}/ClangEnzyme-${ENZYME_VERSION}.so")
message(STATUS "Found ENZYME: ${ENZYME_DIR}/ClangEnzyme-${ENZYME_VERSION}.so")
# Set ENZYME_FOUND
set(ENZYME_FOUND TRUE CACHE BOOL "ENZYME was found." FORCE)
# Set CXX flags to accommodate the Enzyme Clang plugin
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -load -Xclang ${ENZYME_DIR}/ClangEnzyme-${ENZYME_VERSION}.so -mllvm -enzyme-loose-types=1")
set(MFEM_USE_ENZYME YES)
else()
endif()
+6 -69
View File
@@ -9,18 +9,15 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# Defines the following variables if fetching of TPLs is disabled (default):
# Defines the following variables:
# - HYPRE_FOUND
# - HYPRE_LIBRARIES
# - HYPRE_INCLUDE_DIRS
# - HYPRE_VERSION
# - HYPRE_USING_CUDA (internal)
# - HYPRE_USING_HIP (internal)
# otherwise, the following are defined:
# - HYPRE (imported library target)
# - HYPRE_VERSION (cache variable)
if (HYPRE_FOUND OR TARGET HYPRE)
if (HYPRE_FOUND)
if (HYPRE_USING_CUDA)
find_package(CUDAToolkit REQUIRED)
endif()
@@ -28,60 +25,6 @@ if (HYPRE_FOUND OR TARGET HYPRE)
find_package(rocsparse REQUIRED)
find_package(rocrand REQUIRED)
endif()
if (HYPRE_LIBRARIES AND HYPRE_INCLUDE_DIRS AND HYPRE_VERSION)
find_package_handle_standard_args(HYPRE
REQUIRED_VARS HYPRE_LIBRARIES HYPRE_INCLUDE_DIRS HYPRE_VERSION
)
return()
endif()
endif()
if (HYPRE_FETCH OR FETCH_TPLS)
set(HYPRE_FETCH_VERSION 2.33.0)
add_library(HYPRE STATIC IMPORTED)
# set options and associated dependencies
set(CMAKE_OPTIONS)
list(APPEND CMAKE_OPTIONS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
if (MFEM_USE_CUDA)
list(APPEND CMAKE_OPTIONS -DHYPRE_WITH_CUDA:BOOL=ON)
find_package(CUDAToolkit REQUIRED)
target_link_libraries(HYPRE INTERFACE CUDA::cusparse CUDA::curand CUDA::cublas)
elseif (MFEM_USE_HIP)
list(APPEND CMAKE_OPTIONS -DHYPRE_WITH_HIP:BOOL=ON)
find_package(rocsparse REQUIRED)
find_package(rocrand REQUIRED)
target_link_libraries(HYPRE INTERFACE rocsparse rocrand)
endif()
if (MFEM_USE_SINGLE)
list(APPEND CMAKE_OPTIONS -DHYPRE_ENABLE_SINGLE:BOOL=ON)
endif()
# define external project and create future include directory so it is present
# to pass CMake checks at end of MFEM configuration step
message(STATUS "Will fetch HYPRE ${HYPRE_FETCH_VERSION} to be built with ${CMAKE_OPTIONS}")
set(PREFIX ${CMAKE_BINARY_DIR}/fetch/hypre)
include(ExternalProject)
ExternalProject_Add(hypre
GIT_REPOSITORY https://github.com/hypre-space/hypre.git
GIT_TAG v${HYPRE_FETCH_VERSION}
GIT_SHALLOW TRUE
UPDATE_DISCONNECTED TRUE
SOURCE_SUBDIR src
PREFIX ${PREFIX}
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${PREFIX} -DCMAKE_INSTALL_LIBDIR:PATH=lib ${CMAKE_OPTIONS})
file(MAKE_DIRECTORY ${PREFIX}/include)
# set imported library target properties
add_dependencies(HYPRE hypre)
set_target_properties(HYPRE PROPERTIES
IMPORTED_LOCATION ${PREFIX}/lib/libHYPRE.a
INTERFACE_INCLUDE_DIRECTORIES ${PREFIX}/include)
# convert HYPRE version to integer
string(REGEX MATCHALL "[0-9]+" HYPRE_SPLIT_VERSION ${HYPRE_FETCH_VERSION})
list(GET HYPRE_SPLIT_VERSION 0 HYPRE_MAJOR_VERSION)
list(GET HYPRE_SPLIT_VERSION 1 HYPRE_MINOR_VERSION)
list(GET HYPRE_SPLIT_VERSION 2 HYPRE_PATCH_VERSION)
math(EXPR HYPRE_VERSION "10000*${HYPRE_MAJOR_VERSION} + 100*${HYPRE_MINOR_VERSION} + ${HYPRE_PATCH_VERSION}")
# set cache variables that would otherwise be set after mfem_find_package call
set(HYPRE_VERSION ${HYPRE_VERSION} CACHE STRING "HYPRE version." FORCE)
return()
endif()
@@ -134,13 +77,11 @@ endif()
if (HYPRE_FOUND AND HYPRE_USING_CUDA)
find_package(CUDAToolkit REQUIRED)
# Initialize CUSPARSE_LIBRARIES, CURAND_LIBRARIES, and CUBLAS_LIBRARIES:
mfem_culib_set_libraries(CUSPARSE cusparse)
mfem_culib_set_libraries(CURAND curand)
mfem_culib_set_libraries(CUBLAS cublas)
mfem_culib_set_libraries(CUSOLVER cusolver)
get_target_property(CUSPARSE_LIBRARIES CUDA::cusparse LOCATION)
get_target_property(CURAND_LIBRARIES CUDA::curand LOCATION)
get_target_property(CUBLAS_LIBRARIES CUDA::cublas LOCATION)
list(APPEND HYPRE_LIBRARIES ${CUSPARSE_LIBRARIES} ${CURAND_LIBRARIES}
${CUBLAS_LIBRARIES} ${CUSOLVER_LIBRARIES})
${CUBLAS_LIBRARIES})
set(HYPRE_LIBRARIES ${HYPRE_LIBRARIES} CACHE STRING
"HYPRE libraries + dependencies." FORCE)
message(STATUS "Updated HYPRE_LIBRARIES: ${HYPRE_LIBRARIES}")
@@ -154,7 +95,3 @@ if (HYPRE_FOUND AND HYPRE_USING_HIP)
"HYPRE libraries + dependencies." FORCE)
message(STATUS "Updated HYPRE_LIBRARIES: ${HYPRE_LIBRARIES}")
endif()
find_package_handle_standard_args(HYPRE
REQUIRED_VARS HYPRE_LIBRARIES HYPRE_INCLUDE_DIRS HYPRE_VERSION
)
+2 -4
View File
@@ -19,10 +19,8 @@ mfem_find_package(MAGMA MAGMA MAGMA_DIR "include" "magma.h" "lib" "magma"
"Paths to headers required by MAGMA." "Libraries required by MAGMA.")
if (MAGMA_FOUND AND MFEM_USE_CUDA)
find_package(CUDAToolkit REQUIRED)
# Initialize CUSPARSE_LIBRARIES and CUBLAS_LIBRARIES:
mfem_culib_set_libraries(CUSPARSE cusparse)
mfem_culib_set_libraries(CUBLAS cublas)
get_target_property(CUSPARSE_LIBRARIES CUDA::cusparse LOCATION)
get_target_property(CUBLAS_LIBRARIES CUDA::cublas LOCATION)
list(APPEND MAGMA_LIBRARIES ${CUSPARSE_LIBRARIES} ${CUBLAS_LIBRARIES})
set(MAGMA_LIBRARIES ${MAGMA_LIBRARIES} CACHE STRING
"MAGMA libraries + dependencies." FORCE)
+1 -29
View File
@@ -9,38 +9,10 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# Defines the following variables if fetching of TPLs is disabled (default):
# Defines the following variables:
# - METIS_FOUND
# - METIS_LIBRARIES
# - METIS_INCLUDE_DIRS
# - METIS_VERSION_5
# otherwise, the following are defined:
# - METIS (imported library target)
# - METIS_VERSION_5 (cache variable)
if (METIS_FETCH OR FETCH_TPLS)
set(METIS_FETCH_VERSION 4.0.3)
add_library(METIS STATIC IMPORTED)
# define external project
message(STATUS "Will fetch METIS ${METIS_FETCH_VERSION} to be built with default options")
set(PREFIX ${CMAKE_BINARY_DIR}/fetch/metis)
include(ExternalProject)
ExternalProject_Add(metis
GIT_REPOSITORY https://github.com/mfem/tpls
GIT_TAG b60352fbe9675d374b00828055e55be4584c7995 # tag from 1/16/25
GIT_SHALLOW TRUE
UPDATE_DISCONNECTED TRUE
PREFIX ${PREFIX}
CONFIGURE_COMMAND tar -xzf ../metis/metis-${METIS_FETCH_VERSION}-mac.tgz --strip=1
INSTALL_COMMAND mkdir -p ${PREFIX}/lib && cp libmetis.a ${PREFIX}/lib/)
# set imported library target properties
add_dependencies(METIS metis)
set_target_properties(METIS PROPERTIES
IMPORTED_LOCATION ${PREFIX}/lib/libmetis.a)
# set cache variables that would otherwise be set after mfem_find_package call
set(METIS_VERSION_5 FALSE CACHE BOOL "Is METIS version 5?")
return()
endif()
include(MfemCmakeUtilities)
mfem_find_package(METIS METIS METIS_DIR "include;Lib" "metis.h"
+9 -20
View File
@@ -123,10 +123,15 @@ macro(add_mfem_miniapp MFEM_EXE_NAME)
# If CUDA is enabled, tag source files to be compiled with nvcc.
if (MFEM_USE_CUDA)
set_source_files_properties(${MAIN_LIST} ${EXTRA_SOURCES_LIST}
PROPERTIES LANGUAGE CUDA)
if (MFEM_CUDA_COMPILER_IS_NVCC)
set_source_files_properties(${MAIN_LIST} ${EXTRA_SOURCES_LIST} PROPERTIES LANGUAGE CUDA)
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0)
list(TRANSFORM EXTRA_OPTIONS_LIST PREPEND "-Xcompiler=")
else()
set(LIST_)
foreach(item IN LISTS EXTRA_OPTIONS_LIST)
list(APPEND LIST_ "-Xcompiler=${item}")
endforeach()
set(EXTRA_OPTIONS_LIST ${LIST_})
endif()
endif()
@@ -152,21 +157,6 @@ macro(add_mfem_miniapp MFEM_EXE_NAME)
endif()
endmacro()
# Macro for setting variables like '<culib>_LIBRARIES' where <culib> is a CUDA
# library like cublas. This macro assumes that the CUDAToolkit module was loaded
# successfully. Example usage:
# mfem_culib_set_libraries(CUBLAS cublas)
macro(mfem_culib_set_libraries _CULIB _culib)
# The following command does not work with older CMake versions, e.g. 3.20:
# get_target_property(${_CULIB}_LIBRARIES CUDA::${_culib} LOCATION)
# Therefore, we use the respective internal variable:
set(${_CULIB}_LIBRARIES ${CUDA_${_culib}_LIBRARY})
if (NOT ${_CULIB}_LIBRARIES)
message(FATAL_ERROR
"Error setting ${_CULIB}_LIBRARIES: ${${_CULIB}_LIBRARIES}")
endif()
endmacro()
# Auxiliary function, used in mfem_find_package().
function(mfem_find_component Prefix DirVar IncSuffixes Header LibSuffixes Lib
@@ -879,8 +869,7 @@ function(mfem_export_mk_files)
MFEM_USE_OCCA MFEM_USE_CEED MFEM_USE_CALIPER MFEM_USE_UMPIRE MFEM_USE_SIMD
MFEM_USE_ADIOS2 MFEM_USE_MKL_CPARDISO MFEM_USE_MKL_PARDISO
MFEM_USE_ADFORWARD MFEM_USE_CODIPACK MFEM_USE_BENCHMARK MFEM_USE_PARELAG
MFEM_USE_TRIBOL MFEM_USE_MOONOLITH MFEM_USE_ALGOIM MFEM_USE_ENZYME
MFEM_USE_HDF5)
MFEM_USE_TRIBOL MFEM_USE_MOONOLITH MFEM_USE_ALGOIM MFEM_USE_ENZYME)
foreach(var ${CONFIG_MK_BOOL_VARS})
if (${var})
set(${var} YES)
@@ -93,17 +93,17 @@ macro (RESOLVE_LIBRARIES LIBS LINK_LINE)
set (_directory_list ${_directory_list} ${libpath})
set (token ${libname})
endif (token MATCHES "^/")
set (_lib "NOTFOUND")
set (_lib "NOTFOUND" CACHE FILEPATH "Cleared" FORCE)
find_library (_lib ${token} HINTS ${_directory_list} ${_root})
if (_lib)
string (REPLACE "//" "/" _lib ${_lib})
string (REPLACE "//" "/" _lib ${_lib})
list (APPEND _libs_found ${_lib})
else (_lib)
message (STATUS "Unable to find library ${token}")
endif (_lib)
unset(_lib CACHE)
endif (token MATCHES "-L([^\" ]+|\"[^\"]+\")")
endforeach (token)
set (_lib "NOTFOUND" CACHE INTERNAL "Scratch variable" FORCE)
# only the LAST occurrence of each library is required since there should be no circular dependencies
if (_libs_found)
list (REVERSE _libs_found)
+1 -4
View File
@@ -23,14 +23,11 @@
#include "_config.hpp"
#endif
#include <cstdint>
#include <climits>
namespace mfem
{
#if (defined(MFEM_USE_CUDA) && defined(__CUDACC__)) || \
(defined(MFEM_USE_HIP) && defined(__HIP__))
(defined(MFEM_USE_HIP) && defined(__HIPCC__))
#define MFEM_HOST_DEVICE __host__ __device__
#else
#define MFEM_HOST_DEVICE
-3
View File
@@ -132,9 +132,6 @@
// Enable Conduit support.
// #define MFEM_USE_CONDUIT
// Enable functionality based on the HDF5 library
// #define MFEM_USE_HDF5
// Enable functionality based on the NetCDF library (reading CUBIT files).
// #define MFEM_USE_NETCDF
+1 -2
View File
@@ -40,7 +40,6 @@ MFEM_USE_GINKGO = @MFEM_USE_GINKGO@
MFEM_USE_AMGX = @MFEM_USE_AMGX@
MFEM_USE_MAGMA = @MFEM_USE_MAGMA@
MFEM_USE_GNUTLS = @MFEM_USE_GNUTLS@
MFEM_USE_HDF5 = @MFEM_USE_HDF5@
MFEM_USE_NETCDF = @MFEM_USE_NETCDF@
MFEM_USE_PETSC = @MFEM_USE_PETSC@
MFEM_USE_SLEPC = @MFEM_USE_SLEPC@
@@ -98,7 +97,7 @@ MFEM_MPIEXEC_NP = @MFEM_MPIEXEC_NP@
MFEM_MPI_NP = @MFEM_MPI_NP@
# The NVCC compiler cannot link with -x=cu
MFEM_LINK_FLAGS := $(filter-out -x=cu -xcuda -xhip, $(MFEM_FLAGS))
MFEM_LINK_FLAGS := $(filter-out -x=cu -xhip, $(MFEM_FLAGS))
# Optional extra configuration
@MFEM_CONFIG_EXTRA@
-9
View File
@@ -43,7 +43,6 @@ option(MFEM_USE_AMGX "Enable AmgX usage" OFF)
option(MFEM_USE_MAGMA "Enable MAGMA usage" OFF)
option(MFEM_USE_GNUTLS "Enable GNUTLS usage" OFF)
option(MFEM_USE_GSLIB "Enable GSLIB usage" OFF)
option(MFEM_USE_HDF5 "Enable HDF5 usage" OFF)
option(MFEM_USE_NETCDF "Enable NETCDF usage" OFF)
option(MFEM_USE_PETSC "Enable PETSc support." OFF)
option(MFEM_USE_SLEPC "Enable SLEPc support." OFF)
@@ -89,12 +88,6 @@ option(MFEM_ENABLE_EXAMPLES "Build all of the examples" OFF)
option(MFEM_ENABLE_MINIAPPS "Build all of the miniapps" OFF)
option(MFEM_ENABLE_BENCHMARKS "Build all of the benchmarks" OFF)
# Allow a user to specify fetching of certain third-party libraries instead of
# searching for existing installations.
option(FETCH_TPLS "Enable fetching of all supported third-party libraries" OFF)
option(HYPRE_FETCH "Enable fetching of hypre" OFF)
option(METIS_FETCH "Enable fetching of METIS" OFF)
# Setting CXX/MPICXX on the command line or in user.cmake will overwrite the
# autodetected C++ compiler.
# set(CXX g++)
@@ -274,8 +267,6 @@ set(TRIBOL_DIR "${MFEM_DIR}/../tribol" CACHE PATH "Path to Tribol")
set(Tribol_REQUIRED_PACKAGES "Axom/core/mint/slam/slic" CACHE STRING
"Additional packages required by Tribol")
set(ENZYME_DIR "${MFEM_DIR}/../enzyme" CACHE PATH "Path to Enzyme")
set(BLAS_INCLUDE_DIRS "" CACHE STRING "Path to BLAS headers.")
set(BLAS_LIBRARIES "" CACHE STRING "The BLAS library.")
set(LAPACK_INCLUDE_DIRS "" CACHE STRING "Path to LAPACK headers.")
+33 -48
View File
@@ -24,7 +24,7 @@ EGREP_BIN = $(shell command -v egrep 2> /dev/null)
CXX = g++
MPICXX = mpicxx
BASE_FLAGS = -std=c++17
BASE_FLAGS = -std=c++11
OPTIM_FLAGS = -O3 $(BASE_FLAGS)
DEBUG_FLAGS = -g $(XCOMPILER)-Wall $(BASE_FLAGS)
@@ -43,23 +43,12 @@ SHARED = NO
# CUDA configuration options
#
# If you set MFEM_USE_ENZYME=YES, must use CUDA_CXX=clang++
# If you set MFEM_USE_ENZYME=YES, CUDA_CXX has to be configured to use cuda with
# clang as its host compiler.
CUDA_CXX = nvcc
CUDA_ARCH = sm_60
# Base CUDA install directory, only needed if building with clang+cuda:
# The default setting is:
# 1. If CUDA_HOME is defined and non-empty, use that.
# 2. If nvcc is in the path, use the directory two levels up from that.
# 3. Use /usr/local/cuda
CUDA_DIR = $(or $(CUDA_HOME),$(patsubst %/,%,$(dir \
$(patsubst %/,%,$(dir $(shell command -v nvcc))))),/usr/local/cuda)
# flags for clang+cuda
CLANG_CUDA_FLAGS = -xcuda --cuda-path=$(CUDA_DIR) --cuda-gpu-arch=$(CUDA_ARCH)
# flags for nvcc
NVCC_FLAGS = -x=cu --expt-extended-lambda --expt-relaxed-constexpr \
-arch=$(CUDA_ARCH)
# Prefixes for passing flags to the host compiler and linker when using
# CUDA_CXX=nvcc
CUDA_FLAGS = -x=cu --expt-extended-lambda -arch=$(CUDA_ARCH)
# Prefixes for passing flags to the host compiler and linker when using CUDA_CXX
CUDA_XCOMPILER = -Xcompiler=
CUDA_XLINKER = -Xlinker=
@@ -156,7 +145,6 @@ MFEM_USE_GINKGO = NO
MFEM_USE_AMGX = NO
MFEM_USE_MAGMA = NO
MFEM_USE_GNUTLS = NO
MFEM_USE_HDF5 = NO
MFEM_USE_NETCDF = NO
MFEM_USE_PETSC = NO
MFEM_USE_SLEPC = NO
@@ -238,7 +226,7 @@ HYPRE_OPT = -I$(HYPRE_DIR)/include
HYPRE_LIB = -L$(HYPRE_DIR)/lib -lHYPRE
ifeq (YES,$(MFEM_USE_CUDA))
# This is only necessary when hypre is built with cuda:
HYPRE_LIB += -lcusolver -lcusparse -lcurand -lcublas
HYPRE_LIB += -lcusparse -lcurand -lcublas
endif
ifeq (YES,$(MFEM_USE_HIP))
# This is only necessary when hypre is built with hip:
@@ -253,7 +241,7 @@ ifeq ($(MFEM_USE_SUPERLU)$(MFEM_USE_STRUMPACK)$(MFEM_USE_MUMPS),NONONO)
METIS_OPT =
METIS_LIB = -L$(METIS_DIR) -lmetis
else
METIS_DIR = @MFEM_DIR@/../metis-5.1.0
METIS_DIR = @MFEM_DIR@/../metis-5.0
METIS_OPT = -I$(METIS_DIR)/include
METIS_LIB = -L$(METIS_DIR)/lib -lmetis
endif
@@ -413,14 +401,9 @@ MAGMA_LIB = -L$(MAGMA_DIR)/lib -l:libmagma.a -lcublas -lcusparse $(LAPACK_LIB)
GNUTLS_OPT =
GNUTLS_LIB = -lgnutls
# HDF5 library configuration
HDF5_DIR = $(HOME)/local
HDF5_OPT = -I$(HDF5_DIR)/include
HDF5_LIB = $(XLINKER)-rpath,$(HDF5_DIR)/lib -L$(HDF5_DIR)/lib -lhdf5_hl -lhdf5 \
$(ZLIB_LIB)
# NetCDF library configuration
NETCDF_DIR = $(HOME)/local
HDF5_DIR = $(HOME)/local
NETCDF_OPT = -I$(NETCDF_DIR)/include -I$(HDF5_DIR)/include $(ZLIB_OPT)
NETCDF_LIB = $(XLINKER)-rpath,$(NETCDF_DIR)/lib -L$(NETCDF_DIR)/lib\
$(XLINKER)-rpath,$(HDF5_DIR)/lib -L$(HDF5_DIR)/lib\
@@ -501,8 +484,8 @@ SIDRE_LIB = \
# Note that PUMI_DIR is needed -- it is used to check for gmi_sim.h
PUMI_DIR = @MFEM_DIR@/../pumi-2.1.0
PUMI_OPT = -I$(PUMI_DIR)/include
PUMI_LIB = -L$(PUMI_DIR)/lib64 -L$(PUMI_DIR)/lib -lpumi -lcrv -lma -lmds -lapf\
-lpcu -lgmi -lparma -llion -lmth -lapf_zoltan -lspr
PUMI_LIB = -L$(PUMI_DIR)/lib -lpumi -lcrv -lma -lmds -lapf -lpcu -lgmi -lparma\
-llion -lmth -lapf_zoltan -lspr
# HIOP
HIOP_DIR = @MFEM_DIR@/../hiop/install
@@ -522,9 +505,6 @@ GSLIB_LIB = -L$(GSLIB_DIR)/lib -lgs
# CUDA library configuration
CUDA_OPT =
CUDA_LIB = -lcusparse -lcublas
CLANG_CUDA_LIB = -L$(CUDA_DIR)/lib64 -L$(CUDA_DIR)/lib \
$(XLINKER)-rpath,$(CUDA_DIR)/lib64,-rpath,$(CUDA_DIR)/lib \
-lcudart -ldl -lrt -pthread
# HIP library configuration
HIP_OPT =
@@ -588,11 +568,7 @@ RAJA_LIB = $(XLINKER)-rpath,$(RAJA_DIR)/lib -L$(RAJA_DIR)/lib -lRAJA $(CAMP_LIB)
# UMPIRE library configuration
UMPIRE_DIR = @MFEM_DIR@/../umpire
UMPIRE_OPT = -I$(UMPIRE_DIR)/include $(if $(CAMP_DIR), -I$(CAMP_DIR)/include)
UMPIRE_LIB = -L$(UMPIRE_DIR)/lib -L$(UMPIRE_DIR)/lib64 -lumpire $(CAMP_LIB)
ifdef FMT_DIR
UMPIRE_OPT += -I$(FMT_DIR)/include
UMPIRE_LIB += -L$(FMT_DIR)/lib -L$(FMT_DIR)/lib64 -lfmt
endif
UMPIRE_LIB = -L$(UMPIRE_DIR)/lib -lumpire $(CAMP_LIB)
# MKL CPardiso library configuration
MKL_CPARDISO_DIR ?=
@@ -624,20 +600,29 @@ TRIBOL_LIB = -L$(TRIBOL_DIR)/lib -ltribol -lredecomp -L$(AXOM_DIR)/lib -laxom_mi
-laxom_slam -laxom_slic -laxom_core
# Enzyme configuration
ENZYME_DIR = @MFEM_DIR@/../enzyme
ENZYME_PLUGIN = $(abspath $(wildcard $(subst \
@MFEM_DIR@,$(MFEM_DIR),$(ENZYME_DIR))/lib/ClangEnzyme-*.$(SO_EXT)))
ifeq ($(MAKECMDGOALS)-$(MFEM_USE_ENZYME),config-YES)
ifeq ($(ENZYME_PLUGIN),)
$(error Unable to find the Enzyme pluging! Please set ENZYME_DIR)
endif
ifneq ($(words $(ENZYME_PLUGIN)),1)
$(error Multiple versions of the Enzyme pluging found! \
Please set ENZYME_PLUGIN directly)
endif
# If you want to enable automatic differentiation at compile time, use the
# options below, adapted to your configuration. To be more flexible, we
# recommend using the Enzyme plugin during link time optimization. One option is
# to add your options to the global compiler/linker flags like
#
# BASE_FLAGS += -flto
# CXX_XLINKER += -fuse-ld=lld -Wl,--lto-legacy-pass-manager\
# -Wl,-mllvm=-load=$(ENZYME_DIR)/LLDEnzyme-$(ENZYME_VERSION).so -Wl,
#
ENZYME_DIR ?= @MFEM_DIR@/../enzyme
ENZYME_VERSION ?= 14
ENZYME_OPT = -fno-experimental-new-pass-manager -Xclang -load -Xclang $(ENZYME_DIR)/ClangEnzyme-$(ENZYME_VERSION).so
ENZYME_LIB = ""
# Google Benchmark, SUNDIALS >= 6.4.0, STRUMPACK, RAJA, UMPIRE, and Tribol require C++14:
ifneq ($(filter YES,$(MFEM_USE_BENCHMARK) $(MFEM_USE_SUNDIALS) $(MFEM_USE_STRUMPACK) $(MFEM_USE_RAJA) $(MFEM_USE_UMPIRE) $(MFEM_USE_TRIBOL)),)
BASE_FLAGS = -std=c++14
endif
# Ginkgo requires C++17:
ifeq ($(MFEM_USE_GINKGO),YES)
BASE_FLAGS = -std=c++17
endif
ENZYME_OPT = -fplugin=$(ENZYME_PLUGIN)
ENZYME_LIB =
# If YES, enable some informational messages
VERBOSE = NO
+3 -3
View File
@@ -17,7 +17,7 @@ We provide two containers, which you can either build or use directly from
In the above, "ghcr.io" means "GitHub Container Registry" and
is the [GitHub packages](https://github.com/features/packages) registry that supports
Docker images and other OCI artifacts.
Docker images and other OCI artifacts.
### Ubuntu
@@ -132,7 +132,7 @@ examples.
> Use this build for a development environment with spack and mfem
This container is also [provided on GitHub packages](https://github.com/mfem/mfem/pkgs/container/mfem-ubuntu-base),
This container is also [provided on GitHub packages](https://github.com/mfem/mfem/pkgs/container/mfem-ubuntu-base),
however you can build it locally too:
```bash
@@ -197,7 +197,7 @@ Average reduction factor = 0.140201
This container is likely ideal for someone that wants to develop mfem itself.
For other use cases, we recommend using the slimmer image. As an example,
if you want to develop with your own code base (and mfem as is in the container)
if you want to develop with your own code base (and mfem as is in the container)
you can bind to somewhere else in the container (e.g., src)
```bash
@@ -1,20 +0,0 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 186a320..39e5356 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.12.0...4.0.0)
project(METIS)
set(GKLIB_PATH "${CMAKE_SOURCE_DIR}/GKlib" CACHE PATH "path to GKlib")
diff --git a/GKlib/CMakeLists.txt b/GKlib/CMakeLists.txt
index 67b600a..44321a6 100644
--- a/GKlib/CMakeLists.txt
+++ b/GKlib/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.12.0...4.0.0)
project(GKlib)
get_filename_component(abs "." ABSOLUTE)
@@ -22,7 +22,6 @@ vcpkg_extract_source_archive_ex(
fix-linux-build-error.patch
install-metisConfig.patch
fix-INT_MIN_define.patch
cmake4.patch
)
vcpkg_configure_cmake(
-38
View File
@@ -1,38 +0,0 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see fem/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
# PYRAMID = 7
#
dimension
3
elements
1
1 7 0 1 2 3 4
boundary
5
1 3 3 2 1 0
2 2 0 1 4
3 2 1 2 4
4 2 2 3 4
5 2 3 0 4
vertices
5
3
-0.5 -0.5 0
0.5 -0.5 0
0.5 0.5 0
-0.5 0.5 0
0 0 0.7071067811865475
+1 -1
View File
@@ -115,7 +115,7 @@ vertices
nodes
FiniteElementSpace
FiniteElementCollection: H1_3D_P2
FiniteElementCollection: Quadratic
VDim: 3
Ordering: 0
-108
View File
@@ -1,108 +0,0 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see fem/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
# PYRAMID = 7
#
dimension
3
elements
16
1 5 12 13 16 15 21 22 25 24
1 6 9 12 8 18 21 17
1 6 11 8 12 20 17 21
1 6 3 2 12 6 5 15
1 6 11 12 2 14 15 5
1 6 3 12 0 4 13 1
1 6 9 0 12 10 1 13
1 7 12 13 22 21 19
1 7 15 16 13 12 7
1 7 12 21 24 15 23
1 7 9 12 21 18 19
1 7 11 20 21 12 23
1 7 9 10 13 12 19
1 7 11 12 15 14 23
1 7 3 6 15 12 7
1 7 3 12 13 4 7
boundary
39
1 3 5 6 3 2
2 2 6 7 3
2 2 7 4 3
3 3 3 4 1 0
4 2 11 12 8
4 2 9 8 12
5 2 3 12 2
5 2 11 2 12
6 3 0 1 10 9
7 2 10 19 9
7 2 18 9 19
8 3 8 9 18 17
9 2 4 13 1
9 2 10 1 13
10 2 4 7 13
10 2 16 13 7
11 3 13 16 25 22
12 2 10 13 19
12 2 22 19 13
13 2 6 15 7
13 2 16 7 15
14 2 6 5 15
14 2 14 15 5
15 2 14 23 15
15 2 24 15 23
16 3 16 15 24 25
17 3 5 2 11 14
18 2 3 0 12
18 2 9 12 0
19 3 11 8 17 20
20 2 14 11 23
20 2 20 23 11
21 2 18 21 17
21 2 20 17 21
22 2 18 19 21
22 2 22 21 19
23 3 21 22 25 24
24 2 20 21 23
24 2 24 23 21
vertices
26
3
0 -1 -1
1 -1 -1
-1 0 -1
0 0 -1
1 0 -1
-1 1 -1
0 1 -1
1 1 -1
-1 -1 0
0 -1 0
1 -1 0
-1 0 0
0 0 0
1 0 0
-1 1 0
0 1 0
1 1 0
-1 -1 1
0 -1 1
1 -1 1
-1 0 1
0 0 1
1 0 1
-1 1 1
0 1 1
1 1 1
+1 -1
View File
@@ -56,7 +56,7 @@ vertices
nodes
FiniteElementSpace
FiniteElementCollection: H1_3D_P2
FiniteElementCollection: Quadratic
VDim: 3
Ordering: 0
+3 -3
View File
@@ -1,9 +1,9 @@
MFEM INLINE mesh v1.0
type = pyramid
nx = 2
ny = 2
nz = 2
nx = 4
ny = 4
nz = 4
sx = 1.0
sy = 1.0
sz = 1.0
+1 -1
View File
@@ -227,7 +227,7 @@ vertices
nodes
FiniteElementSpace
FiniteElementCollection: H1_2D_P2
FiniteElementCollection: Quadratic
VDim: 2
Ordering: 0
+1 -1
View File
@@ -65,7 +65,7 @@ vertices
nodes
FiniteElementSpace
FiniteElementCollection: H1_2D_P2
FiniteElementCollection: Quadratic
VDim: 2
Ordering: 0
+5 -10
View File
@@ -48,7 +48,7 @@ PROJECT_NAME = MFEM
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = v4.8.1
PROJECT_NUMBER = v4.7.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -951,11 +951,7 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
@MFEM_SOURCE_DIR@/fem/ceed/integrators/nlconvection \
@MFEM_SOURCE_DIR@/fem/ceed/interface \
@MFEM_SOURCE_DIR@/fem/ceed/solvers \
@MFEM_SOURCE_DIR@/fem/dfem \
@MFEM_SOURCE_DIR@/fem/eltrans \
@MFEM_SOURCE_DIR@/fem/fe \
@MFEM_SOURCE_DIR@/fem/gslib \
@MFEM_SOURCE_DIR@/fem/integ \
@MFEM_SOURCE_DIR@/fem/lor \
@MFEM_SOURCE_DIR@/fem/moonolith \
@MFEM_SOURCE_DIR@/fem/qinterp \
@@ -973,9 +969,6 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
@MFEM_SOURCE_DIR@/miniapps/adjoint \
@MFEM_SOURCE_DIR@/miniapps/autodiff \
@MFEM_SOURCE_DIR@/miniapps/common \
@MFEM_SOURCE_DIR@/miniapps/dfem \
@MFEM_SOURCE_DIR@/miniapps/dpg \
@MFEM_SOURCE_DIR@/miniapps/dpg/util \
@MFEM_SOURCE_DIR@/miniapps/electromagnetics \
@MFEM_SOURCE_DIR@/miniapps/gslib \
@MFEM_SOURCE_DIR@/miniapps/hdiv-linear-solver \
@@ -993,10 +986,12 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
@MFEM_SOURCE_DIR@/miniapps/performance \
@MFEM_SOURCE_DIR@/miniapps/shifted \
@MFEM_SOURCE_DIR@/miniapps/solvers \
@MFEM_SOURCE_DIR@/miniapps/spde \
@MFEM_SOURCE_DIR@/miniapps/tools \
@MFEM_SOURCE_DIR@/miniapps/toys \
@MFEM_SOURCE_DIR@/miniapps/tribol
@MFEM_SOURCE_DIR@/miniapps/tribol \
@MFEM_SOURCE_DIR@/miniapps/spde \
@MFEM_SOURCE_DIR@/miniapps/dpg \
@MFEM_SOURCE_DIR@/miniapps/dpg/util
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+16 -16
View File
@@ -42,10 +42,10 @@ namespace mfem {
* - mfem::forall functions in forall.hpp
*
* <H3>Example codes</H3>
* - <a class="el" href="ex0_8cpp_source.html">Example 0</a>: simplest example, nodal H1 FEM for the Poisson problem
* - <a class="el" href="ex0p_8cpp_source.html">Example 0p</a>: simplest parallel example, nodal H1 FEM for the Poisson problem
* - <a class="el" href="examples_2ex1_8cpp_source.html">Example 1</a>: nodal H1 FEM for the Poisson problem (same discretization as ex0 but with more sophisticated options)
* - <a class="el" href="examples_2ex1p_8cpp_source.html">Example 1p</a>: parallel nodal H1 FEM for the Poisson problem (same discretization as ex0p but with more sophisticated options)
* - <a class="el" href="ex0_8cpp_source.html">Example 0</a>: simplest example, nodal H1 FEM for the Laplace problem
* - <a class="el" href="ex0p_8cpp_source.html">Example 0p</a>: simplest parallel example, nodal H1 FEM for the Laplace problem
* - <a class="el" href="examples_2ex1_8cpp_source.html">Example 1</a>: nodal H1 FEM for the Laplace problem (same discretization as ex0 but with more sophisticated options)
* - <a class="el" href="examples_2ex1p_8cpp_source.html">Example 1p</a>: parallel nodal H1 FEM for the Laplace problem (same discretization as ex0p but with more sophisticated options)
* - <a class="el" href="ex2_8cpp_source.html">Example 2</a>: vector FEM for linear elasticity
* - <a class="el" href="ex2p_8cpp_source.html">Example 2p</a>: parallel vector FEM for linear elasticity
* - <a class="el" href="ex3_8cpp_source.html">Example 3</a>: Nedelec H(curl) FEM for the definite Maxwell problem
@@ -54,12 +54,12 @@ namespace mfem {
* - <a class="el" href="ex4p_8cpp_source.html">Example 4p</a>: parallel Raviart-Thomas H(div) FEM for the grad-div problem
* - <a class="el" href="ex5_8cpp_source.html">Example 5</a>: mixed pressure-velocity FEM for the Darcy problem
* - <a class="el" href="ex5p_8cpp_source.html">Example 5p</a>: parallel mixed pressure-velocity FEM for the Darcy problem
* - <a class="el" href="ex6_8cpp_source.html">Example 6</a>: non-conforming adaptive mesh refinement for the Poisson problem
* - <a class="el" href="ex6p_8cpp_source.html">Example 6p</a>: parallel non-conforming adaptive mesh refinement for the Poisson problem
* - <a class="el" href="ex7_8cpp_source.html">Example 7</a>: screened Poisson problem on a surface (the unit sphere)
* - <a class="el" href="ex7p_8cpp_source.html">Example 7p</a>: parallel screened Poisson problem on a surface (the unit sphere)
* - <a class="el" href="ex8_8cpp_source.html">Example 8</a>: Discontinuous Petrov-Galerkin (DPG) for the Poisson problem
* - <a class="el" href="ex8p_8cpp_source.html">Example 8p</a>: parallel Discontinuous Petrov-Galerkin (DPG) for the Poisson problem
* - <a class="el" href="ex6_8cpp_source.html">Example 6</a>: non-conforming adaptive mesh refinement for the Laplace problem
* - <a class="el" href="ex6p_8cpp_source.html">Example 6p</a>: parallel non-conforming adaptive mesh refinement for the Laplace problem
* - <a class="el" href="ex7_8cpp_source.html">Example 7</a>: Laplace problem on a surface (the unit sphere)
* - <a class="el" href="ex7p_8cpp_source.html">Example 7p</a>: parallel Laplace problem on a surface (the unit sphere)
* - <a class="el" href="ex8_8cpp_source.html">Example 8</a>: Discontinuous Petrov-Galerkin (DPG) for the Laplace problem
* - <a class="el" href="ex8p_8cpp_source.html">Example 8p</a>: parallel Discontinuous Petrov-Galerkin (DPG) for the Laplace problem
* - <a class="el" href="ex9_8cpp_source.html">Example 9</a>: Discontinuous Galerkin (DG) time-dependent advection
* - <a class="el" href="ex9p_8cpp_source.html">Example 9p</a>: parallel Discontinuous Galerkin (DG) time-dependent advection
* - <a class="el" href="ex10_8cpp_source.html">Example 10</a>: time-dependent implicit nonlinear elasticity
@@ -67,8 +67,8 @@ namespace mfem {
* - <a class="el" href="ex11p_8cpp_source.html">Example 11p</a>: parallel Laplace eigensolver
* - <a class="el" href="ex12p_8cpp_source.html">Example 12p</a>: parallel linear elasticity eigensolver
* - <a class="el" href="ex13p_8cpp_source.html">Example 13p</a>: parallel Maxwell eigensolver
* - <a class="el" href="ex14_8cpp_source.html">Example 14</a>: Discontinuous Galerkin (DG) for the Poisson problem
* - <a class="el" href="ex14p_8cpp_source.html">Example 14p</a>: parallel Discontinuous Galerkin (DG) for the Poisson problem
* - <a class="el" href="ex14_8cpp_source.html">Example 14</a>: Discontinuous Galerkin (DG) for the Laplace problem
* - <a class="el" href="ex14p_8cpp_source.html">Example 14p</a>: parallel Discontinuous Galerkin (DG) for the Laplace problem
* - <a class="el" href="ex15_8cpp_source.html">Example 15</a>: dynamic AMR for Laplace with prescribed time-dependent source
* - <a class="el" href="ex15p_8cpp_source.html">Example 15p</a>: parallel dynamic AMR for Laplace with prescribed time-dependent source
* - <a class="el" href="ex16_8cpp_source.html">Example 16</a>: time-dependent nonlinear heat equation
@@ -90,8 +90,8 @@ namespace mfem {
* - <a class="el" href="ex24p_8cpp_source.html">Example 24p</a>: parallel mixed finite element spaces and interpolators
* - <a class="el" href="ex25_8cpp_source.html">Example 25</a>: simulation of electromagnetic wave propagation using a Perfectly Matched Layer (PML)
* - <a class="el" href="ex25p_8cpp_source.html">Example 25p</a>: parallel simulation of electromagnetic wave propagation using a Perfectly Matched Layer (PML)
* - <a class="el" href="ex26_8cpp_source.html">Example 26</a>: multigrid preconditioner for the Poisson problem using nodal H1 FEM
* - <a class="el" href="ex26p_8cpp_source.html">Example 26p</a>: parallel multigrid preconditioner for the Poisson problem using nodal H1 FEM
* - <a class="el" href="ex26_8cpp_source.html">Example 26</a>: multigrid preconditioner for the Laplace problem using nodal H1 FEM
* - <a class="el" href="ex26p_8cpp_source.html">Example 26p</a>: parallel multigrid preconditioner for the Laplace problem using nodal H1 FEM
* - <a class="el" href="ex27_8cpp_source.html">Example 27</a>: boundary conditions for the Laplace problem
* - <a class="el" href="ex27p_8cpp_source.html">Example 27p</a>: parallel boundary conditions for the Laplace problem
* - <a class="el" href="ex28_8cpp_source.html">Example 28</a>: sliding contact in elasticity
@@ -230,8 +230,8 @@ namespace mfem {
* - <a class="el" href="parheat_8cpp_source.html">Optimization gradients</a>: Gradients of PDE-constrained function
* - <a class="el" href="par__example_8cpp_source.html">Parallel AD</a>: Parallel p-Laplacian example
* - <a class="el" href="seq__example_8cpp_source.html">Serial AD</a>: Serial p-Laplacian example
* - <a class="el" href="miniapps_2performance_2ex1_8cpp_source.html">HPC Example 1</a>: high-performance nodal H1 FEM for the Poisson problem
* - <a class="el" href="miniapps_2performance_2ex1p_8cpp_source.html">HPC Example 1p</a>: high-performance parallel nodal H1 FEM for the Poisson problem
* - <a class="el" href="miniapps_2performance_2ex1_8cpp_source.html">HPC Example 1</a>: high-performance nodal H1 FEM for the Laplace problem
* - <a class="el" href="miniapps_2performance_2ex1p_8cpp_source.html">HPC Example 1p</a>: high-performance parallel nodal H1 FEM for the Laplace problem
* - <a class="el" href="generate__random__field_8cpp_source.html">SPDE Solvers</a>: SPDE solver random field generation
* - <a class="el" href="contact-patch-test_8cpp_source.html">Contact</a>: mortar contact patch test for elasticity
* - <a class="el" href="multidomain_8cpp_source.html">Multidomain miniapp</a>: Multidomain and Submesh demonstration miniapp
+1 -1
View File
@@ -12,7 +12,7 @@
// ex1 --amgx-file precon.json --amgx-preconditioner -d cuda
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
+1 -1
View File
@@ -10,7 +10,7 @@
// mpirun -np 4 ex1p --amgx-file amg_pcg.json
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -7,7 +7,7 @@
// ex0 -m ../data/square-disc.mesh -o 2
//
// Description: This example code demonstrates the most basic usage of MFEM to
// define a simple finite element discretization of the Poisson
// define a simple finite element discretization of the Laplace
// problem -Delta u = 1 with zero Dirichlet boundary conditions.
// General 2D/3D mesh files and finite element polynomial degrees
// can be specified by command line options.
+1 -1
View File
@@ -8,7 +8,7 @@
//
// Description: This example code demonstrates the most basic parallel usage of
// MFEM to define a simple finite element discretization of the
// Poisson problem -Delta u = 1 with zero Dirichlet boundary
// Laplace problem -Delta u = 1 with zero Dirichlet boundary
// conditions. General 2D/3D serial mesh files and finite element
// polynomial degrees can be specified by command line options.
+1 -1
View File
@@ -50,7 +50,7 @@
// ex1 -m ../data/beam-tet.mesh -pa -d ceed-cuda:/gpu/cuda/ref
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
+1 -1
View File
@@ -27,7 +27,7 @@
//
// Description: This example code demonstrates the use of MFEM to define a
// discontinuous Galerkin (DG) finite element discretization of
// the Poisson problem -Delta u = 1 with homogeneous Dirichlet
// the Laplace problem -Delta u = 1 with homogeneous Dirichlet
// boundary conditions. Finite element spaces of any order,
// including zero on regular grids, are supported. The example
// highlights the use of discontinuous spaces and DG-specific face
+1 -1
View File
@@ -26,7 +26,7 @@
//
// Description: This example code demonstrates the use of MFEM to define a
// discontinuous Galerkin (DG) finite element discretization of
// the Poisson problem -Delta u = 1 with homogeneous Dirichlet
// the Laplace problem -Delta u = 1 with homogeneous Dirichlet
// boundary conditions. Finite element spaces of any order,
// including zero on regular grids, are supported. The example
// highlights the use of discontinuous spaces and DG-specific face
+2 -2
View File
@@ -159,7 +159,7 @@ int main(int argc, char *argv[])
FiniteElementSpace fespace(&mesh, &fec);
// 6. As in Example 1p, we set up bilinear and linear forms corresponding to
// the Poisson problem -\Delta u = 1. We don't assemble the discrete
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
// problem yet, this will be done in the inner loop.
BilinearForm a(&fespace);
LinearForm b(&fespace);
@@ -446,7 +446,7 @@ real_t bdr_func(const Vector &pt, real_t t)
return composite_func(pt, t, front, ball);
}
// Laplacian of the exact solution, used for the right hand side.
// Laplace of the exact solution, used for the right hand side.
real_t rhs_func(const Vector &pt, real_t t)
{
return composite_func(pt, t, front_laplace, ball_laplace);
+2 -2
View File
@@ -181,7 +181,7 @@ int main(int argc, char *argv[])
ParFiniteElementSpace fespace(&pmesh, &fec);
// 7. As in Example 1p, we set up bilinear and linear forms corresponding to
// the Poisson problem -\Delta u = 1. We don't assemble the discrete
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
// problem yet, this will be done in the inner loop.
ParBilinearForm a(&fespace);
ParLinearForm b(&fespace);
@@ -507,7 +507,7 @@ real_t bdr_func(const Vector &pt, real_t t)
return composite_func(pt, t, front, ball);
}
// Laplacian of the exact solution, used for the right hand side.
// Laplace of the exact solution, used for the right hand side.
real_t rhs_func(const Vector &pt, real_t t)
{
return composite_func(pt, t, front_laplace, ball_laplace);
+1 -1
View File
@@ -45,7 +45,7 @@
// mpirun -np 4 ex1p -m ../data/beam-tet.mesh -pa -d ceed-cpu
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
+1 -1
View File
@@ -94,7 +94,7 @@ WaveOperator::WaveOperator(FiniteElementSpace &f,
M->AddDomainIntegrator(new MassIntegrator());
M->Assemble();
// Apply BCs
// Apply Bcs
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
K->FormSystemMatrix(ess_tdof_list, Kmat);
M->FormSystemMatrix(ess_tdof_list, Mmat);
+1 -1
View File
@@ -17,7 +17,7 @@
// ex26 -m ../data/beam-hex.mesh -d cuda
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions
// as in Example 1.
//
+1 -1
View File
@@ -14,7 +14,7 @@
// mpirun -np 4 ex26p -d ceed-cuda
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions
// as in Example 1.
//
+1 -1
View File
@@ -10,7 +10,7 @@
// Description: This example code demonstrates the use of MFEM to define a
// finite element discretization of a PDE on a 2 dimensional
// surface embedded in a 3 dimensional domain. In this case we
// solve the Poisson problem -Div(sigma Grad u) = 1, with
// solve the Laplace problem -Div(sigma Grad u) = 1, with
// homogeneous Dirichlet boundary conditions, where sigma is an
// anisotropic diffusion constant defined as a 3x3 matrix
// coefficient.
+1 -1
View File
@@ -10,7 +10,7 @@
// Description: This example code demonstrates the use of MFEM to define a
// finite element discretization of a PDE on a 2 dimensional
// surface embedded in a 3 dimensional domain. In this case we
// solve the Poisson problem -Div(sigma Grad u) = 1, with
// solve the Laplace problem -Div(sigma Grad u) = 1, with
// homogeneous Dirichlet boundary conditions, where sigma is an
// anisotropic diffusion constant defined as a 3x3 matrix
// coefficient.
+3 -3
View File
@@ -390,7 +390,7 @@ public:
/**
@brief Class for surface linear form integrator
@brief Class for surface linearform integrator
Integrator to demonstrate the use of the surface integration rule on an
implicit surface defined by a level-set.
@@ -460,7 +460,7 @@ public:
};
/**
@brief Class for subdomain linear form integrator
@brief Class for subdomain linearform integrator
Integrator to demonstrate the use of the subdomain integration rule within
an area defined by an implicit surface defined by a level-set.
@@ -546,7 +546,7 @@ int main(int argc, char *argv[])
args.AddOption(&ref_levels, "-r", "--refine", "Number of meh refinements");
args.AddOption(&method, "-m", "--method",
"Cut integration method: 0 for moments-based, 1 for Algoim.");
args.AddOption(&inttype, "-i", "--integration-type",
args.AddOption(&inttype, "-i", "--integrationtype",
"IntegrationType to demonstrate");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
+1 -1
View File
@@ -16,7 +16,7 @@
//
// The particular problem being solved here is nearly the same
// as that in example 1 i.e. a simple finite element
// discretization of the Poisson problem -Delta u = 1 with
// discretization of the Laplace problem -Delta u = 1 with
// homogeneous Dirichlet boundary conditions and, in this case,
// an inhomogeneous diffusion coefficient. The diffusion
// coefficient is given a small default value throughout the
+1 -1
View File
@@ -16,7 +16,7 @@
//
// The particular problem being solved here is nearly the same
// as that in example 1 i.e. a simple finite element
// discretization of the Poisson problem -Delta u = 1 with
// discretization of the Laplace problem -Delta u = 1 with
// homogeneous Dirichlet boundary conditions and, in this case,
// an inhomogeneous diffusion coefficient. The diffusion
// coefficient is given a small default value throughout the
+7 -5
View File
@@ -65,7 +65,6 @@ int main(int argc, char *argv[])
bool static_cond = false;
bool hybridization = false;
bool pa = false;
bool ea = false;
const char *device_config = "cpu";
bool visualization = 1;
@@ -84,14 +83,18 @@ int main(int argc, char *argv[])
"--no-hybridization", "Enable hybridization.");
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
"--no-partial-assembly", "Enable Partial Assembly.");
args.AddOption(&ea, "-ea", "--element-assembly", "-no-ea",
"--no-element-assembly", "Enable Element Assembly.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.ParseCheck();
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
kappa = freq * M_PI;
// 2. Enable hardware devices such as GPUs, and programming models such as
@@ -163,7 +166,6 @@ int main(int argc, char *argv[])
Coefficient *beta = new ConstantCoefficient(1.0);
BilinearForm *a = new BilinearForm(fespace);
if (pa) { a->SetAssemblyLevel(AssemblyLevel::PARTIAL); }
if (ea) { a->SetAssemblyLevel(AssemblyLevel::ELEMENT); }
a->AddDomainIntegrator(new DivDivIntegrator(*alpha));
a->AddDomainIntegrator(new VectorFEMassIntegrator(*beta));
+13 -5
View File
@@ -71,7 +71,6 @@ int main(int argc, char *argv[])
bool static_cond = false;
bool hybridization = false;
bool pa = false;
bool ea = false;
const char *device_config = "cpu";
bool visualization = 1;
@@ -90,14 +89,24 @@ int main(int argc, char *argv[])
"--no-hybridization", "Enable hybridization.");
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
"--no-partial-assembly", "Enable Partial Assembly.");
args.AddOption(&ea, "-ea", "--element-assembly", "-no-ea",
"--no-element-assembly", "Enable Element Assembly.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.ParseCheck();
args.Parse();
if (!args.Good())
{
if (myid == 0)
{
args.PrintUsage(cout);
}
return 1;
}
if (myid == 0)
{
args.PrintOptions(cout);
}
kappa = freq * M_PI;
// 3. Enable hardware devices such as GPUs, and programming models such as
@@ -185,7 +194,6 @@ int main(int argc, char *argv[])
Coefficient *beta = new ConstantCoefficient(1.0);
ParBilinearForm *a = new ParBilinearForm(fespace);
if (pa) { a->SetAssemblyLevel(AssemblyLevel::PARTIAL); }
if (ea) { a->SetAssemblyLevel(AssemblyLevel::ELEMENT); }
a->AddDomainIntegrator(new DivDivIntegrator(*alpha));
a->AddDomainIntegrator(new VectorFEMassIntegrator(*beta));
+2 -2
View File
@@ -25,7 +25,7 @@
// ex6 -pa -d ceed-cuda:/gpu/cuda/shared
//
// Description: This is a version of Example 1 with a simple adaptive mesh
// refinement loop. The problem being solved is again the Poisson
// refinement loop. The problem being solved is again the Laplace
// equation -Delta u = 1 with homogeneous Dirichlet boundary
// conditions. The problem is solved on a sequence of meshes which
// are locally refined in a conforming (triangles, tetrahedrons)
@@ -113,7 +113,7 @@ int main(int argc, char *argv[])
FiniteElementSpace fespace(&mesh, &fec);
// 6. As in Example 1, we set up bilinear and linear forms corresponding to
// the Poisson problem -\Delta u = 1. We don't assemble the discrete
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
// problem yet, this will be done in the main loop.
BilinearForm a(&fespace);
if (pa)
+7 -104
View File
@@ -3,7 +3,6 @@
// Compile with: make ex6p
//
// Sample runs: mpirun -np 4 ex6p -m ../data/star-hilbert.mesh -o 2
// mpirun -np 4 ex6p -m ../data/star-hilbert.mesh -pref
// mpirun -np 4 ex6p -m ../data/square-disc.mesh -rm 1 -o 1
// mpirun -np 4 ex6p -m ../data/square-disc.mesh -rm 1 -o 2 -h1
// mpirun -np 4 ex6p -m ../data/square-disc.mesh -o 2 -cs
@@ -29,7 +28,7 @@
// mpirun -np 4 ex6p -pa -d ceed-cuda:/gpu/cuda/shared
//
// Description: This is a version of Example 1 with a simple adaptive mesh
// refinement loop. The problem being solved is again the Poisson
// refinement loop. The problem being solved is again the Laplace
// equation -Delta u = 1 with homogeneous Dirichlet boundary
// conditions. The problem is solved on a sequence of meshes which
// are locally refined in a conforming (triangles, tetrahedrons)
@@ -42,12 +41,6 @@
// from coarse to fine meshes, restarting from a checkpoint, as
// well as persistent GLVis visualization are also illustrated.
//
// There is also the option to use hp-refinement. Real
// applications should use some problem-dependent criteria for
// selecting between h- and p-refinement, but in this example, we
// simply alternate between refinement types to demonstrate the
// capabilities.
//
// We recommend viewing Example 1 before viewing this example.
#include "mfem.hpp"
@@ -76,8 +69,6 @@ int main(int argc, char *argv[])
bool smooth_rt = true;
bool restart = false;
bool visualization = true;
bool rebalance = true;
bool usePRefinement = false;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -99,10 +90,6 @@ int main(int argc, char *argv[])
"Stop after reaching this many degrees of freedom.");
args.AddOption(&smooth_rt, "-rt", "--smooth-rt", "-h1", "--smooth-h1",
"Represent the smooth flux in RT or vector H1 space.");
args.AddOption(&usePRefinement, "-pref", "--p-refine", "-no-pref",
"--no-p-refine", "Alternate between h- and p-refinement.");
args.AddOption(&rebalance, "-reb", "--rebalance", "-no-reb",
"--no-rebalance", "Load balance the nonconforming mesh.");
args.AddOption(&restart, "-res", "--restart", "-no-res", "--no-restart",
"Restart computation from the last checkpoint.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
@@ -122,15 +109,6 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
if (usePRefinement && rebalance)
{
rebalance = false;
if (myid == 0)
{
cout << "Load balancing is not performed with p-refinements.\n";
}
}
// 3. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
@@ -208,7 +186,7 @@ int main(int argc, char *argv[])
ParFiniteElementSpace fespace(pmesh, &fec);
// 11. As in Example 1p, we set up bilinear and linear forms corresponding to
// the Poisson problem -\Delta u = 1. We don't assemble the discrete
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
// problem yet, this will be done in the main loop.
ParBilinearForm a(&fespace);
if (pa)
@@ -343,15 +321,7 @@ int main(int argc, char *argv[])
if (visualization)
{
sout << "parallel " << num_procs << " " << myid << "\n";
if (usePRefinement)
{
std::unique_ptr<GridFunction> vis_x = x.ProlongateToMaxOrder();
sout << "solution\n" << *pmesh << *vis_x << flush;
}
else
{
sout << "solution\n" << *pmesh << x << flush;
}
sout << "solution\n" << *pmesh << x << flush;
}
if (global_dofs >= max_dofs)
@@ -367,31 +337,8 @@ int main(int argc, char *argv[])
// estimator to obtain element errors, then it selects elements to be
// refined and finally it modifies the mesh. The Stop() method can be
// used to determine if a stopping criterion was met.
// Simply alternate between h- and p-refinement.
const bool pRefine = usePRefinement && ((it % 2) == 1);
bool stop = false;
Array<pRefinement> prefinements;
if (pRefine)
{
Array<Refinement> refinements;
refiner.MarkWithoutRefining(*pmesh, refinements);
stop = pmesh->ReduceInt(refinements.Size()) == 0LL;
prefinements.SetSize(refinements.Size());
for (int i=0; i<refinements.Size(); ++i)
{
prefinements[i].index = refinements[i].index;
prefinements[i].delta = 1; // Increase the element order by 1
}
}
else
{
refiner.Apply(*pmesh);
stop = refiner.Stop();
}
if (stop)
refiner.Apply(*pmesh);
if (refiner.Stop())
{
if (myid == 0)
{
@@ -405,20 +352,12 @@ int main(int argc, char *argv[])
// to any GridFunctions over the space. In this case, the update
// matrix is an interpolation matrix so the updated GridFunction will
// still represent the same function as before refinement.
if (pRefine)
{
fespace.PRefineAndUpdate(prefinements);
}
else
{
fespace.Update();
}
fespace.Update();
x.Update();
// 25. Load balance the mesh, and update the space and solution. Currently
// available only for nonconforming meshes.
if (pmesh->Nonconforming() && rebalance)
if (pmesh->Nonconforming())
{
pmesh->Rebalance();
@@ -450,42 +389,6 @@ int main(int argc, char *argv[])
}
}
// Save result
if (usePRefinement)
{
L2_FECollection fecL2(0, dim);
ParFiniteElementSpace l2fespace(pmesh, &fecL2);
ParGridFunction xo(&l2fespace); // Element order field
xo = 0.0;
for (int e=0; e<pmesh->GetNE(); ++e)
{
const int p_elem = fespace.GetElementOrder(e);
Array<int> dofs;
l2fespace.GetElementDofs(e, dofs);
xo[dofs[0]] = p_elem;
}
ostringstream mesh_name, sol_name, order_name;
mesh_name << "mesh." << setfill('0') << setw(6) << myid;
sol_name << "sol." << setfill('0') << setw(6) << myid;
order_name << "order." << setfill('0') << setw(6) << myid;
ofstream mesh_ofs(mesh_name.str().c_str());
mesh_ofs.precision(8);
pmesh->ParPrint(mesh_ofs);
ofstream sol_ofs(sol_name.str().c_str());
sol_ofs.precision(8);
std::unique_ptr<ParGridFunction> vis_x = x.ProlongateToMaxOrder();
vis_x->Save(sol_ofs);
ofstream order_ofs(order_name.str().c_str());
order_ofs.precision(8);
xo.Save(order_ofs);
}
delete smooth_flux_fes;
delete smooth_flux_fec;
delete pmesh;
+2 -2
View File
@@ -9,8 +9,8 @@
//
// Description: This example code demonstrates the use of MFEM to define a
// triangulation of a unit sphere and a simple isoparametric
// finite element discretization of the screened Poisson problem,
// -Delta u + u = f.
// finite element discretization of the Laplace problem with mass
// term, -Delta u + u = f.
//
// The example highlights mesh generation, the use of mesh
// refinement, high-order meshes and finite elements, as well as
+2 -2
View File
@@ -9,8 +9,8 @@
//
// Description: This example code demonstrates the use of MFEM to define a
// triangulation of a unit sphere and a simple isoparametric
// finite element discretization of the screened Poisson problem,
// -Delta u + u = f.
// finite element discretization of the Laplace problem with mass
// term, -Delta u + u = f.
//
// The example highlights mesh generation, the use of mesh
// refinement, high-order meshes and finite elements, as well as
+1 -1
View File
@@ -15,7 +15,7 @@
//
// Description: This example code demonstrates the use of the Discontinuous
// Petrov-Galerkin (DPG) method in its primal 2x2 block form as a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = f with homogeneous Dirichlet boundary conditions. We
// use high-order continuous trial space, a high-order interfacial
// (trace) space, and a high-order discontinuous test space
+1 -1
View File
@@ -14,7 +14,7 @@
//
// Description: This example code demonstrates the use of the Discontinuous
// Petrov-Galerkin (DPG) method in its primal 2x2 block form as a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = f with homogeneous Dirichlet boundary conditions. We
// use high-order continuous trial space, a high-order interfacial
// (trace) space, and a high-order discontinuous test space
+1 -1
View File
@@ -35,7 +35,7 @@
// ex1 -m ../../data/beam-hex.mesh -pa -d cuda
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
+1 -1
View File
@@ -33,7 +33,7 @@
"id": "public-white",
"metadata": {},
"source": [
"This is the simplest MFEM example and a good starting point for new users. The example demonstrates the use of MFEM to define and solve an $H^1$ finite element discretization of the Poisson problem\n",
"This is the simplest MFEM example and a good starting point for new users. The example demonstrates the use of MFEM to define and solve an $H^1$ finite element discretization of the Laplace problem\n",
"\n",
"$$\n",
"-\\Delta u = 1\n",
+1 -1
View File
@@ -189,7 +189,7 @@ clean-build:
clean-exec:
@rm -f refined.mesh displaced.mesh mesh.* ex5.mesh ex6p-checkpoint.*
@rm -rf Example5* Example9* Example15* Example16* Example23* ParaView
@rm -f sphere_refined.* sol.* sol_u.* sol_p.* sol_r.* sol_i.* order.*
@rm -f sphere_refined.* sol.* sol_u.* sol_p.* sol_r.* sol_i.*
@rm -f ex9.mesh ex9-mesh.* ex9-init.* ex9-final.*
@rm -f deformed.* velocity.* elastic_energy.* mode_* mode_deriv_* flux.*
@rm -f ex5-p-*.bp ex9-p-*.bp ex12-p-*.bp ex16-p-*.bp
+2 -8
View File
@@ -16,16 +16,10 @@
// multi-physics applications.
//
// This particular example is only for serial runtimes.
// For non-conforming meshes please have a look at example
// "ex2p.cpp".
#include "example_utils.hpp"
#include "mfem.hpp"
#ifndef MFEM_USE_MOONOLITH
#error This example requires that MFEM is built with MFEM_USE_MOONOLITH=YES
#endif
using namespace mfem;
using namespace std;
@@ -221,8 +215,8 @@ int main(int argc, char *argv[])
mfem::out << "l2 error: src: " << src_err << ", dest: " << dest_err
<< std::endl;
plot(*src_mesh, src_fun, "source", 0);
plot(*dest_mesh, dest_fun, "destination", 1);
plot(*src_mesh, src_fun, "source");
plot(*dest_mesh, dest_fun, "destination");
}
}
else
+16 -54
View File
@@ -8,23 +8,18 @@
// mpirun -np 4 ex1p -s ../../data/inline-hex.mesh -d ../../data/inline-tet.mesh
//
// Description: This example code demonstrates the use of MFEM for transferring
// discrete fields from one conforming finite element mesh to another. The
// discrete fields from one finite element mesh to another. The
// meshes can be of arbitrary shape and completely unrelated with
// each other. This feature can be used for implementing immersed
// domain methods for fluid-structure interaction or general
// multi-physics applications.
//
// This particular example is for parallel runtimes. Vector FE is
// an experimental feature in parallel. For non-conforming meshes
// please have a look at example "ex2p.cpp".
// an experimental feature in parallel.
#include "example_utils.hpp"
#include "mfem.hpp"
#ifndef MFEM_USE_MOONOLITH
#error This example requires that MFEM is built with MFEM_USE_MOONOLITH=YES
#endif
using namespace mfem;
using namespace std;
@@ -55,8 +50,6 @@ int main(int argc, char *argv[])
int dest_fe_order = 1;
bool visualization = true;
bool use_vector_fe = false;
bool use_h1 = true;
bool use_vector_space = false;
bool verbose = false;
bool assemble_mass_and_coupling_together = true;
@@ -79,28 +72,14 @@ int main(int argc, char *argv[])
args.AddOption(&verbose, "-verb", "--verbose", "--no-verb", "--no-verbose",
"Enable/Disable verbose output");
args.AddOption(&use_vector_fe, "-vfe", "--use_vector_fe", "-no-vfe",
"--no-vector_fe",
"Use RT|ND vector finite elements (Experimental)");
args.AddOption(&use_vector_space, "-vfs", "--use_vector_space", "-no-vfs",
"--no-vector_space",
"Use Lagrange vector finite elements (Experimental)");
args.AddOption(&use_h1, "-h1", "--use-h1", "-nh1", "--no-h1",
"Use H1 collection");
"--no-vector_fe", "Use vector finite elements (Experimental)");
args.AddOption(&assemble_mass_and_coupling_together, "-act",
"--assemble_mass_and_coupling_together", "-no-act",
"--no-assemble_mass_and_coupling_together",
"Assemble mass and coupling operators together (better for "
"non-affine elements)");
"Assemble mass and coupling operators together (better for non-affine elements)");
args.Parse();
check_options(args);
if (use_vector_fe && use_vector_space)
{
mfem::err <<
"WARNING: use_vector_fe and use_vector_space options"
"are both true, ignoring use_vector_fe\n";
}
shared_ptr<Mesh> src_mesh, dest_mesh;
ifstream imesh;
@@ -190,30 +169,17 @@ int main(int argc, char *argv[])
}
else
{
if (use_h1)
{
src_fe_coll =
make_shared<H1_FECollection>(source_fe_order, src_mesh->Dimension());
dest_fe_coll =
make_shared<H1_FECollection>(dest_fe_order, dest_mesh->Dimension());
}
else
{
src_fe_coll =
make_shared<L2_FECollection>(source_fe_order, src_mesh->Dimension());
dest_fe_coll =
make_shared<L2_FECollection>(dest_fe_order, dest_mesh->Dimension());
}
src_fe_coll =
make_shared<L2_FECollection>(source_fe_order, src_mesh->Dimension());
dest_fe_coll =
make_shared<L2_FECollection>(dest_fe_order, dest_mesh->Dimension());
}
auto src_fe = make_shared<ParFiniteElementSpace>(
p_src_mesh.get(), src_fe_coll.get(),
use_vector_space ? src_mesh->Dimension() : 1);
auto src_fe =
make_shared<ParFiniteElementSpace>(p_src_mesh.get(), src_fe_coll.get());
auto dest_fe = make_shared<ParFiniteElementSpace>(
p_dest_mesh.get(), dest_fe_coll.get(),
use_vector_space ? dest_mesh->Dimension() : 1);
auto dest_fe =
make_shared<ParFiniteElementSpace>(p_dest_mesh.get(), dest_fe_coll.get());
ParGridFunction src_fun(src_fe.get());
@@ -223,7 +189,7 @@ int main(int argc, char *argv[])
// To be used with vector fe
VectorFunctionCoefficient vector_coeff(dim, &vector_fun);
if (use_vector_fe || use_vector_space)
if (use_vector_fe)
{
src_fun.ProjectCoefficient(vector_coeff);
src_fun.Update();
@@ -243,11 +209,7 @@ int main(int argc, char *argv[])
assemble_mass_and_coupling_together);
assembler.SetVerbose(verbose);
if (use_vector_space)
{
assembler.AddMortarIntegrator(make_shared<LagrangeVectorL2MortarIntegrator>());
}
else if (use_vector_fe)
if (use_vector_fe)
{
assembler.AddMortarIntegrator(make_shared<VectorL2MortarIntegrator>());
}
@@ -281,8 +243,8 @@ int main(int argc, char *argv[])
<< std::endl;
}
plot(*p_src_mesh, src_fun, "source", 0);
plot(*p_dest_mesh, dest_fun, "destination", 1);
plot(*p_src_mesh, src_fun, "source");
plot(*p_dest_mesh, dest_fun, "destination");
}
}
else
+2 -6
View File
@@ -20,10 +20,6 @@
#include "example_utils.hpp"
#include "mfem.hpp"
#ifndef MFEM_USE_MOONOLITH
#error This example requires that MFEM is built with MFEM_USE_MOONOLITH=YES
#endif
using namespace mfem;
using namespace std;
@@ -190,8 +186,8 @@ int main(int argc, char *argv[])
<< std::endl;
}
plot(*p_src_mesh, src_fun, "source", 0);
plot(*p_dest_mesh, dest_fun, "destination", 1);
plot(*p_src_mesh, src_fun, "source");
plot(*p_dest_mesh, dest_fun, "destination");
}
}
else
+1 -15
View File
@@ -84,8 +84,7 @@ void vector_fun(const mfem::Vector &x, mfem::Vector &f)
f = n;
}
inline void plot(mfem::Mesh &mesh, mfem::GridFunction &x, std::string title,
const int plot_number = 0)
inline void plot(mfem::Mesh &mesh, mfem::GridFunction &x, std::string title)
{
using namespace std;
using namespace mfem;
@@ -104,18 +103,5 @@ inline void plot(mfem::Mesh &mesh, mfem::GridFunction &x, std::string title,
sol_sock.precision(8);
sol_sock << "solution\n" << mesh << x
<< "window_title '"<< title << "'\n" << flush;
sol_sock << "window_geometry ";
sol_sock << (plot_number * 600) << " " << 0 << " " << 600 << " " << 600 <<
"\n";
if (mesh.Dimension() == 2)
{
sol_sock << "keys jRmclA\n";
}
else
{
sol_sock << "keys rmclAa\n";
}
sol_sock << flush;
}
+1 -1
View File
@@ -10,7 +10,7 @@
// mpirun -np 4 ex1p -pa -d cuda --petscopts rc_ex1p_device
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
+2 -2
View File
@@ -8,7 +8,7 @@
// mpirun -np 4 ex6p -m ../../data/amr-quad.mesh -nonoverlapping
//
// Description: This is a version of Example 1 with a simple adaptive mesh
// refinement loop. The problem being solved is again the Poisson
// refinement loop. The problem being solved is again the Laplace
// equation -Delta u = 1 with homogeneous Dirichlet boundary
// conditions. The problem is solved on a sequence of meshes which
// are locally refined in a conforming (triangles, tetrahedrons)
@@ -131,7 +131,7 @@ int main(int argc, char *argv[])
ParFiniteElementSpace fespace(&pmesh, &fec);
// 7. As in Example 1p, we set up bilinear and linear forms corresponding to
// the Poisson problem -\Delta u = 1. We don't assemble the discrete
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
// problem yet, this will be done in the main loop.
ParBilinearForm a(&fespace);
ParLinearForm b(&fespace);
+1 -1
View File
@@ -11,7 +11,7 @@
// creating a symbolic link to the above directory in ../../data.
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
+1 -1
View File
@@ -12,7 +12,7 @@
// creating a symbolic link to the above directory in ../../data.
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
+1 -1
View File
@@ -6,7 +6,7 @@
// Sample runs: mpirun -np 8 ex6p
//
// Description: This is a version of Example 1 with a simple adaptive mesh
// refinement loop. The problem being solved is again the Poisson
// refinement loop. The problem being solved is again the Laplace
// equation -Delta u = 1 with homogeneous Dirichlet boundary
// conditions. The problem is solved on a sequence of meshes which
// are adapted in a conforming (tetrahedrons) manner according
+1 -1
View File
@@ -26,7 +26,7 @@
// mpirun -np 4 ex1p -m ../../data/mobius-strip.mesh
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Poisson problem
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
-164
View File
@@ -1,164 +0,0 @@
#include "mfem.hpp"
#include "vector-dg-diffusion.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
class RepeatedCoefficient : public VectorCoefficient
{
Coefficient &coeff;
public:
RepeatedCoefficient(int dim, Coefficient &coeff_)
: VectorCoefficient(dim), coeff(coeff_)
{ }
void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)
{
V.SetSize(vdim);
V = coeff.Eval(T, ip);
}
};
real_t u_fn(const Vector &xvec);
real_t f_fn(const Vector &xvec);
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
const char *mesh_file = "../data/star.mesh";
int ref_levels = 0;
int order = 1;
real_t sigma = -1.0;
real_t kappa = -1.0;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&ref_levels, "-r", "--refine",
"Number of times to refine the mesh uniformly, -1 for auto.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree) >= 0.");
args.AddOption(&sigma, "-s", "--sigma",
"One of the three DG penalty parameters, typically +1/-1."
" See the documentation of class DGDiffusionIntegrator.");
args.AddOption(&kappa, "-k", "--kappa",
"One of the three DG penalty parameters, should be positive."
" Negative values are replaced with (order+1)^2.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.ParseCheck();
if (kappa < 0)
{
kappa = (order+1)*(order+1);
}
Device device(device_config);
device.Print();
Mesh mesh(mesh_file);
const int dim = mesh.Dimension();
{
if (ref_levels < 0)
{
ref_levels = (int)floor(log(50000./mesh.GetNE())/log(2.)/dim);
}
for (int l = 0; l < ref_levels; l++)
{
mesh.UniformRefinement();
}
}
DG_FECollection fec(order, dim);
FiniteElementSpace fespace(&mesh, &fec, dim);
cout << "Number of unknowns: " << fespace.GetVSize() << endl;
FunctionCoefficient scalar_f_coeff(f_fn);
FunctionCoefficient scalar_u_coeff(u_fn);
RepeatedCoefficient f_coeff(dim, scalar_f_coeff);
RepeatedCoefficient u_coeff(dim, scalar_u_coeff);
ConstantCoefficient one(1.0);
ConstantCoefficient zero(5.0);
RepeatedCoefficient zero_vec(dim, zero);
LinearForm b(&fespace);
b.AddDomainIntegrator(new VectorDomainLFIntegrator(f_coeff));
b.AddBdrFaceIntegrator(
new VectorDGDirichletLFIntegrator(u_coeff, one, sigma, kappa));
b.Assemble();
GridFunction x(&fespace);
x = 0.0;
BilinearForm a(&fespace);
a.AddDomainIntegrator(new VectorDiffusionIntegrator(one));
a.AddInteriorFaceIntegrator(new VectorDGDiffusionIntegrator(
one, sigma, kappa, dim));
a.AddBdrFaceIntegrator(new VectorDGDiffusionIntegrator(
one, sigma, kappa, dim));
a.Assemble();
a.Finalize();
const SparseMatrix &A = a.SpMat();
#ifndef MFEM_USE_SUITESPARSE
GSSmoother M(A);
if (sigma == -1.0)
{
PCG(A, M, b, x, 1, 500, 1e-12, 0.0);
}
else
{
GMRES(A, M, b, x, 1, 500, 10, 1e-12, 0.0);
}
#else
UMFPackSolver umf_solver;
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
umf_solver.SetOperator(A);
umf_solver.Mult(b, x);
#endif
ParaViewDataCollection pv("DGDiffusion", &mesh);
pv.SetPrefixPath("ParaView");
pv.SetHighOrderOutput(true);
pv.SetLevelsOfDetail(order);
pv.RegisterField("u", &x);
pv.SetCycle(0);
pv.SetTime(0.0);
pv.Save();
cout << "L2 error: " << x.ComputeL2Error(u_coeff) << '\n';
return 0;
}
constexpr real_t pi = M_PI;
constexpr real_t pi2 = pi*pi;
real_t u_fn(const Vector &xvec)
{
int dim = xvec.Size();
real_t x = pi*xvec[0], y = pi*xvec[1];
if (dim == 2) { return sin(x)*sin(y); }
else { real_t z = pi*xvec[2]; return sin(x)*sin(y)*sin(z); }
}
real_t f_fn(const Vector &xvec)
{
int dim = xvec.Size();
real_t x = pi*xvec[0], y = pi*xvec[1];
if (dim == 2)
{
return 2*pi2*sin(x)*sin(y);
}
else // dim == 3
{
real_t z = pi*xvec[2];
return 3*pi2*sin(x)*sin(y)*sin(z);
}
}
-433
View File
@@ -1,433 +0,0 @@
#include "mfem.hpp"
namespace mfem
{
class VectorDGDiffusionIntegrator : public BilinearFormIntegrator
{
protected:
Coefficient *Q = nullptr;
MatrixCoefficient *MQ = nullptr;
real_t sigma, kappa;
int vdim;
// these are not thread-safe!
Vector shape1, shape2, dshape1dn, dshape2dn, nor, nh, ni;
DenseMatrix jmat, dshape1, dshape2, mq, adjJ;
public:
VectorDGDiffusionIntegrator(real_t s, real_t k, int vd=-1)
: sigma(s), kappa(k), vdim(vd) { }
VectorDGDiffusionIntegrator(Coefficient &q, real_t s, real_t k, int vd=-1)
: Q(&q), sigma(s), kappa(k), vdim(vd) { }
VectorDGDiffusionIntegrator(MatrixCoefficient &mq, real_t s, real_t k,
int vd=-1)
: MQ(&mq), sigma(s), kappa(k), vdim(vd) { }
using BilinearFormIntegrator::AssembleFaceMatrix;
virtual void AssembleFaceMatrix(const FiniteElement &el1,
const FiniteElement &el2,
FaceElementTransformations &Trans,
DenseMatrix &full_elmat);
};
class VectorDGDirichletLFIntegrator : public LinearFormIntegrator
{
protected:
VectorCoefficient &uD;
Coefficient *Q = nullptr;
MatrixCoefficient *MQ = nullptr;
real_t sigma, kappa;
int vdim;
// these are not thread-safe!
Vector shape, dshape_dn, nor, nh, ni, uD_vec;
DenseMatrix dshape, mq, adjJ;
public:
VectorDGDirichletLFIntegrator(VectorCoefficient &u, real_t s, real_t k,
int vd=-1)
: uD(u), sigma(s), kappa(k), vdim(vd) { }
VectorDGDirichletLFIntegrator(VectorCoefficient &u, Coefficient &q, real_t s,
real_t k, int vd=-1)
: uD(u), Q(&q), sigma(s), kappa(k), vdim(vd) { }
VectorDGDirichletLFIntegrator(VectorCoefficient &u, MatrixCoefficient &mq,
real_t s, real_t k, int vd=-1)
: uD(u), MQ(&mq), sigma(s), kappa(k), vdim(vd) { }
using LinearFormIntegrator::AssembleRHSElementVect;
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override
{ MFEM_ABORT("Not implemented."); }
void AssembleRHSElementVect(const FiniteElement &el,
FaceElementTransformations &Tr,
Vector &elvect) override;
};
void VectorDGDiffusionIntegrator::AssembleFaceMatrix(
const FiniteElement &el1, const FiniteElement &el2,
FaceElementTransformations &Trans, DenseMatrix &full_elmat)
{
int dim, ndof1, ndof2, ndofs;
bool kappa_is_nonzero = (kappa != 0.);
real_t w, wq = 0.0;
const int sdim = Trans.GetSpaceDim();
if (vdim < 0) { vdim = sdim; }
dim = el1.GetDim();
ndof1 = el1.GetDof();
nor.SetSize(dim);
nh.SetSize(dim);
ni.SetSize(dim);
adjJ.SetSize(dim);
if (MQ)
{
mq.SetSize(dim);
}
shape1.SetSize(ndof1);
dshape1.SetSize(ndof1, dim);
dshape1dn.SetSize(ndof1);
if (Trans.Elem2No >= 0)
{
ndof2 = el2.GetDof();
shape2.SetSize(ndof2);
dshape2.SetSize(ndof2, dim);
dshape2dn.SetSize(ndof2);
}
else
{
ndof2 = 0;
}
ndofs = ndof1 + ndof2;
DenseMatrix elmat;
elmat.SetSize(ndofs);
elmat = 0.0;
if (kappa_is_nonzero)
{
jmat.SetSize(ndofs);
jmat = 0.;
}
const IntegrationRule *ir = IntRule;
if (ir == nullptr)
{
// a simple choice for the integration order
int order;
if (ndof2)
{
order = 2 * std::max(el1.GetOrder(), el2.GetOrder());
}
else
{
order = 2 * el1.GetOrder();
}
ir = &IntRules.Get(Trans.GetGeometryType(), order);
}
// assemble: < {(Q \nabla u).n},[v] > --> elmat
// kappa < {h^{-1} Q} [u],[v] > --> jmat
for (int p = 0; p < ir->GetNPoints(); p++)
{
const IntegrationPoint &ip = ir->IntPoint(p);
// Set the integration point in the face and the neighboring elements
Trans.SetAllIntPoints(&ip);
// Access the neighboring elements' integration points
// Note: eip2 will only contain valid data if Elem2 exists
const IntegrationPoint &eip1 = Trans.GetElement1IntPoint();
const IntegrationPoint &eip2 = Trans.GetElement2IntPoint();
if (dim == 1)
{
nor(0) = 2 * eip1.x - 1.0;
}
else
{
CalcOrtho(Trans.Jacobian(), nor);
}
el1.CalcShape(eip1, shape1);
el1.CalcDShape(eip1, dshape1);
w = ip.weight / Trans.Elem1->Weight();
if (ndof2)
{
w /= 2;
}
if (!MQ)
{
if (Q)
{
w *= Q->Eval(*Trans.Elem1, eip1);
}
ni.Set(w, nor);
}
else
{
nh.Set(w, nor);
MQ->Eval(mq, *Trans.Elem1, eip1);
mq.MultTranspose(nh, ni);
}
CalcAdjugate(Trans.Elem1->Jacobian(), adjJ);
adjJ.Mult(ni, nh);
if (kappa_is_nonzero)
{
wq = ni * nor;
}
// Note: in the jump term, we use 1/h1 = |nor|/det(J1) which is
// independent of Loc1 and always gives the size of element 1 in
// direction perpendicular to the face. Indeed, for linear transformation
//
// |nor|=measure(face)/measure(ref. face),
//
// det(J1)=measure(element)/measure(ref. element),
//
// and the ratios measure(ref. element)/measure(ref. face)
// are compatible for all element/face pairs.
//
// For example: meas(ref. tetrahedron)/meas(ref. triangle) = 1/3, and
// for any tetrahedron vol(tet)=(1/3)*height*area(base).
//
// For interior faces: q_e/h_e=(q1/h1+q2/h2)/2.
dshape1.Mult(nh, dshape1dn);
for (int i = 0; i < ndof1; i++)
for (int j = 0; j < ndof1; j++)
{
elmat(i, j) += shape1(i) * dshape1dn(j);
}
if (ndof2)
{
el2.CalcShape(eip2, shape2);
el2.CalcDShape(eip2, dshape2);
w = ip.weight / 2 / Trans.Elem2->Weight();
if (!MQ)
{
if (Q)
{
w *= Q->Eval(*Trans.Elem2, eip2);
}
ni.Set(w, nor);
}
else
{
nh.Set(w, nor);
MQ->Eval(mq, *Trans.Elem2, eip2);
mq.MultTranspose(nh, ni);
}
CalcAdjugate(Trans.Elem2->Jacobian(), adjJ);
adjJ.Mult(ni, nh);
if (kappa_is_nonzero)
{
wq += ni * nor;
}
dshape2.Mult(nh, dshape2dn);
for (int i = 0; i < ndof1; i++)
for (int j = 0; j < ndof2; j++)
{
elmat(i, ndof1 + j) += shape1(i) * dshape2dn(j);
}
for (int i = 0; i < ndof2; i++)
for (int j = 0; j < ndof1; j++)
{
elmat(ndof1 + i, j) -= shape2(i) * dshape1dn(j);
}
for (int i = 0; i < ndof2; i++)
for (int j = 0; j < ndof2; j++)
{
elmat(ndof1 + i, ndof1 + j) -= shape2(i) * dshape2dn(j);
}
}
if (kappa_is_nonzero)
{
// only assemble the lower triangular part of jmat
wq *= kappa;
for (int i = 0; i < ndof1; i++)
{
const real_t wsi = wq * shape1(i);
for (int j = 0; j <= i; j++)
{
jmat(i, j) += wsi * shape1(j);
}
}
if (ndof2)
{
for (int i = 0; i < ndof2; i++)
{
const int i2 = ndof1 + i;
const real_t wsi = wq * shape2(i);
for (int j = 0; j < ndof1; j++)
{
jmat(i2, j) -= wsi * shape1(j);
}
for (int j = 0; j <= i; j++)
{
jmat(i2, ndof1 + j) += wsi * shape2(j);
}
}
}
}
}
// elmat := -elmat + sigma*elmat^t + jmat
if (kappa_is_nonzero)
{
for (int i = 0; i < ndofs; i++)
{
for (int j = 0; j < i; j++)
{
real_t aij = elmat(i, j), aji = elmat(j, i), mij = jmat(i, j);
elmat(i, j) = sigma * aji - aij + mij;
elmat(j, i) = sigma * aij - aji + mij;
}
elmat(i, i) = (sigma - 1.) * elmat(i, i) + jmat(i, i);
}
}
else
{
for (int i = 0; i < ndofs; i++)
{
for (int j = 0; j < i; j++)
{
real_t aij = elmat(i, j), aji = elmat(j, i);
elmat(i, j) = sigma * aji - aij;
elmat(j, i) = sigma * aij - aji;
}
elmat(i, i) *= (sigma - 1.);
}
}
// populate full matrix following github issue #2909
full_elmat.SetSize(vdim*(ndof1 + ndof2));
full_elmat = 0.0;
for (int d=0; d<vdim; ++d)
{
for (int j=0; j<ndofs; ++j)
{
int jj = (j < ndof1) ? j + d*ndof1 : j - ndof1 + d*ndof2 + vdim*ndof1;
for (int i=0; i<ndofs; ++i)
{
int ii = (i < ndof1) ? i + d*ndof1 : i - ndof1 + d*ndof2 + vdim*ndof1;
full_elmat(ii, jj) += elmat(i, j);
}
}
}
};
void VectorDGDirichletLFIntegrator::AssembleRHSElementVect(
const FiniteElement &el, FaceElementTransformations &Tr, Vector &elvect)
{
const int dim = el.GetDim();
const int sdim = Tr.GetSpaceDim();
if (vdim < 0) { vdim = sdim; }
const int ndof = el.GetDof();
bool kappa_is_nonzero = (kappa != 0.);
real_t w;
nor.SetSize(dim);
nh.SetSize(dim);
ni.SetSize(dim);
adjJ.SetSize(dim);
if (MQ)
{
mq.SetSize(dim);
}
shape.SetSize(ndof);
dshape.SetSize(ndof, dim);
dshape_dn.SetSize(ndof);
elvect.SetSize(vdim * ndof);
elvect = 0.0;
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
// a simple choice for the integration order; is this OK?
int order = 2*el.GetOrder();
ir = &IntRules.Get(Tr.GetGeometryType(), order);
}
for (int p = 0; p < ir->GetNPoints(); p++)
{
const IntegrationPoint &ip = ir->IntPoint(p);
// Set the integration point in the face and the neighboring element
Tr.SetAllIntPoints(&ip);
// Access the neighboring element's integration point
const IntegrationPoint &eip = Tr.GetElement1IntPoint();
uD.Eval(uD_vec, Tr, ip);
if (dim == 1)
{
nor(0) = 2*eip.x - 1.0;
}
else
{
CalcOrtho(Tr.Jacobian(), nor);
}
el.CalcShape(eip, shape);
el.CalcDShape(eip, dshape);
// compute uD through the face transformation
w = ip.weight / Tr.Elem1->Weight();
if (!MQ)
{
if (Q)
{
w *= Q->Eval(*Tr.Elem1, eip);
}
ni.Set(w, nor);
}
else
{
nh.Set(w, nor);
MQ->Eval(mq, *Tr.Elem1, eip);
mq.MultTranspose(nh, ni);
}
CalcAdjugate(Tr.Elem1->Jacobian(), adjJ);
adjJ.Mult(ni, nh);
dshape.Mult(nh, dshape_dn);
for (int vd = 0; vd < vdim; ++vd)
{
for (int i = 0; i < ndof; ++i)
{
elvect[i + vd*ndof] += sigma * uD_vec[vd] * dshape_dn[i];
}
}
if (kappa_is_nonzero)
{
for (int vd = 0; vd < vdim; ++vd)
{
for (int i = 0; i < ndof; ++i)
{
elvect[i + vd*ndof] += kappa*(ni*nor) * uD_vec[vd] * shape[i];
}
}
}
}
}
} // namespace mfem
-21
View File
@@ -35,7 +35,6 @@ set(SRCS
integ/bilininteg_mass_ea.cpp
integ/bilininteg_mixedcurl_pa.cpp
integ/bilininteg_mixedvecgrad_pa.cpp
integ/bilininteg_trace_jump_ea.cpp
integ/bilininteg_transpose_ea.cpp
integ/bilininteg_vecdiffusion_mf.cpp
integ/bilininteg_vecdiffusion_pa.cpp
@@ -47,7 +46,6 @@ set(SRCS
integ/bilininteg_diffusion_kernels.cpp
integ/bilininteg_elasticity_kernels.cpp
integ/bilininteg_hcurl_kernels.cpp
integ/bilininteg_hdiv_ea.cpp
integ/bilininteg_hdiv_kernels.cpp
integ/bilininteg_hcurlhdiv_kernels.cpp
integ/bilininteg_mass_kernels.cpp
@@ -64,9 +62,7 @@ set(SRCS
datacollection.cpp
dgmassinv.cpp
doftrans.cpp
dfem/doperator.cpp
eltrans.cpp
batchitrans.cpp
estimators.cpp
fe.cpp
fe/face_map_utils.cpp
@@ -77,17 +73,13 @@ set(SRCS
fe/fe_nd.cpp
fe/fe_nurbs.cpp
fe/fe_pos.cpp
fe/fe_pyramid.cpp
fe/fe_rt.cpp
fe/fe_ser.cpp
fe_coll.cpp
fespace.cpp
derefmat_op.cpp
pderefmat_op.cpp
geom.cpp
gridfunc.cpp
hybridization.cpp
hybridization_ext.cpp
intrules.cpp
intrules_cut.cpp
ceed/interface/basis.cpp
@@ -164,7 +156,6 @@ set(SRCS
transfer.cpp
hyperbolic.cpp
integrator.cpp
bounds.cpp
)
set(HDRS
@@ -184,14 +175,6 @@ set(HDRS
dgmassinv.hpp
dgmassinv_kernels.hpp
doftrans.hpp
dfem/doperator.hpp
dfem/fieldoperator.hpp
dfem/integrate.hpp
dfem/parameterspace.hpp
dfem/qfunction_apply.hpp
dfem/qfunction_transform.hpp
dfem/tuple.hpp
dfem/util.hpp
eltrans.hpp
estimators.hpp
fe.hpp
@@ -203,7 +186,6 @@ set(HDRS
fe/fe_nd.hpp
fe/fe_nurbs.hpp
fe/fe_pos.hpp
fe/fe_pyramid.hpp
fe/fe_rt.hpp
fe/fe_ser.hpp
fe_coll.hpp
@@ -212,7 +194,6 @@ set(HDRS
geom.hpp
gridfunc.hpp
hybridization.hpp
hybridization_ext.hpp
intrules.hpp
intrules_cut.hpp
kernel_dispatch.hpp
@@ -249,7 +230,6 @@ set(HDRS
nonlinearform_ext.hpp
nonlininteg.hpp
qfunction.hpp
qinterp/det.hpp
qinterp/eval.hpp
qinterp/eval_hdiv.hpp
qinterp/grad.hpp
@@ -276,7 +256,6 @@ set(HDRS
transfer.hpp
hyperbolic.hpp
integrator.hpp
bounds.hpp
)
if (MFEM_USE_SIDRE)
-2036
View File
File diff suppressed because it is too large Load Diff
+83 -94
View File
@@ -71,11 +71,15 @@ BilinearForm::BilinearForm(FiniteElementSpace * f)
sequence = f->GetSequence();
mat = mat_e = NULL;
extern_bfs = 0;
element_matrices = NULL;
static_cond = NULL;
hybridization = NULL;
precompute_sparsity = 0;
diag_policy = DIAG_KEEP;
assembly = AssemblyLevel::LEGACY;
batch = 1;
ext = NULL;
}
BilinearForm::BilinearForm (FiniteElementSpace * f, BilinearForm * bf, int ps)
@@ -85,11 +89,15 @@ BilinearForm::BilinearForm (FiniteElementSpace * f, BilinearForm * bf, int ps)
sequence = f->GetSequence();
mat_e = NULL;
extern_bfs = 1;
element_matrices = NULL;
static_cond = NULL;
hybridization = NULL;
precompute_sparsity = ps;
diag_policy = DIAG_KEEP;
assembly = AssemblyLevel::LEGACY;
batch = 1;
ext = NULL;
// Copy the pointers to the integrators
domain_integs = bf->domain_integs;
@@ -119,16 +127,16 @@ void BilinearForm::SetAssemblyLevel(AssemblyLevel assembly_level)
break;
case AssemblyLevel::FULL:
SetDiagonalPolicy( DIAG_ONE ); // Only diagonal policy supported on device
ext.reset(new FABilinearFormExtension(this));
ext = new FABilinearFormExtension(this);
break;
case AssemblyLevel::ELEMENT:
ext.reset(new EABilinearFormExtension(this));
ext = new EABilinearFormExtension(this);
break;
case AssemblyLevel::PARTIAL:
ext.reset(new PABilinearFormExtension(this));
ext = new PABilinearFormExtension(this);
break;
case AssemblyLevel::NONE:
ext.reset(new MFBilinearFormExtension(this));
ext = new MFBilinearFormExtension(this);
break;
default:
MFEM_ABORT("BilinearForm: unknown assembly level");
@@ -137,13 +145,14 @@ void BilinearForm::SetAssemblyLevel(AssemblyLevel assembly_level)
void BilinearForm::EnableStaticCondensation()
{
delete static_cond;
if (assembly != AssemblyLevel::LEGACY)
{
static_cond.reset();
static_cond = NULL;
MFEM_WARNING("Static condensation not supported for this assembly level");
return;
}
static_cond.reset(new StaticCondensation(fes));
static_cond = new StaticCondensation(fes);
if (static_cond->ReducesTrueVSize())
{
bool symmetric = false; // TODO
@@ -152,7 +161,8 @@ void BilinearForm::EnableStaticCondensation()
}
else
{
static_cond.reset();
delete static_cond;
static_cond = NULL;
}
}
@@ -160,18 +170,15 @@ void BilinearForm::EnableHybridization(FiniteElementSpace *constr_space,
BilinearFormIntegrator *constr_integ,
const Array<int> &ess_tdof_list)
{
if (assembly != AssemblyLevel::LEGACY && assembly != AssemblyLevel::ELEMENT)
delete hybridization;
if (assembly != AssemblyLevel::LEGACY)
{
delete constr_integ;
hybridization.reset();
hybridization = NULL;
MFEM_WARNING("Hybridization not supported for this assembly level");
return;
}
hybridization.reset(new Hybridization(fes, constr_space));
if (assembly == AssemblyLevel::ELEMENT)
{
hybridization->EnableDeviceExecution();
}
hybridization = new Hybridization(fes, constr_space);
hybridization->SetConstraintIntegrator(constr_integ);
hybridization->Init(ess_tdof_list);
}
@@ -224,8 +231,8 @@ void BilinearForm::Finalize (int skip_zeros)
if (!static_cond) { mat->Finalize(skip_zeros); }
if (mat_e) { mat_e->Finalize(skip_zeros); }
if (static_cond) { static_cond->Finalize(); }
if (hybridization) { hybridization->Finalize(); }
}
if (hybridization) { hybridization->Finalize(); }
}
void BilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi)
@@ -458,14 +465,11 @@ void BilinearForm::Assemble(int skip_zeros)
if (ext)
{
ext->Assemble();
if (hybridization)
{
hybridization->AssembleElementMatrices(GetElementMatrices());
}
return;
}
ElementTransformation *eltrans;
DofTransformation * doftrans;
Mesh *mesh = fes -> GetMesh();
DenseMatrix elmat, *elmat_p;
@@ -502,14 +506,13 @@ void BilinearForm::Assemble(int skip_zeros)
}
}
DofTransformation doftrans;
// Element-wise integration
for (int i = 0; i < fes -> GetNE(); i++)
{
// Set both doftrans (potentially needed to assemble the element
// matrix) and vdofs, which is also needed when the element matrices
// are pre-assembled.
fes->GetElementVDofs(i, vdofs, doftrans);
doftrans = fes->GetElementVDofs(i, vdofs);
if (element_matrices)
{
elmat_p = &(*element_matrices)(i);
@@ -547,7 +550,10 @@ void BilinearForm::Assemble(int skip_zeros)
{
elmat_p = &elmat;
}
doftrans.TransformDual(elmat);
if (doftrans)
{
doftrans->TransformDual(elmat);
}
elmat_p = &elmat;
}
if (static_cond)
@@ -625,14 +631,13 @@ void BilinearForm::Assemble(int skip_zeros)
}
}
DofTransformation doftrans;
for (int i = 0; i < fes -> GetNBE(); i++)
{
const int bdr_attr = mesh->GetBdrAttribute(i);
if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
const FiniteElement &be = *fes->GetBE(i);
fes -> GetBdrElementVDofs (i, vdofs, doftrans);
doftrans = fes -> GetBdrElementVDofs (i, vdofs);
eltrans = fes -> GetBdrElementTransformation (i);
int k = 0;
for (; k < boundary_integs.Size(); k++)
@@ -652,7 +657,10 @@ void BilinearForm::Assemble(int skip_zeros)
boundary_integs[k]->AssembleElementMatrix(be, *eltrans, elemmat);
elmat += elemmat;
}
doftrans.TransformDual(elmat);
if (doftrans)
{
doftrans->TransformDual(elmat);
}
elmat_p = &elmat;
if (!static_cond)
{
@@ -827,19 +835,7 @@ void BilinearForm::FormLinearSystem(const Array<int> &ess_tdof_list, Vector &x,
{
if (ext)
{
if (hybridization)
{
FormSystemMatrix(ess_tdof_list, A);
ConstrainedOperator A_constrained(this, ess_tdof_list);
A_constrained.EliminateRHS(x, b);
hybridization->ReduceRHS(b, B);
X.SetSize(B.Size());
X = 0.0;
}
else
{
ext->FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
}
ext->FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
return;
}
const SparseMatrix *P = fes->GetConformingProlongation();
@@ -907,16 +903,7 @@ void BilinearForm::FormSystemMatrix(const Array<int> &ess_tdof_list,
{
if (ext)
{
if (hybridization)
{
const int remove_zeros = 0;
Finalize(remove_zeros);
A.Reset(&hybridization->GetMatrix(), false);
}
else
{
ext->FormSystemMatrix(ess_tdof_list, A);
}
ext->FormSystemMatrix(ess_tdof_list, A);
return;
}
@@ -957,7 +944,7 @@ void BilinearForm::FormSystemMatrix(const Array<int> &ess_tdof_list,
void BilinearForm::RecoverFEMSolution(const Vector &X,
const Vector &b, Vector &x)
{
if (ext && !hybridization)
if (ext)
{
ext->RecoverFEMSolution(X, b, x);
return;
@@ -1014,26 +1001,16 @@ void BilinearForm::RecoverFEMSolution(const Vector &X,
void BilinearForm::ComputeElementMatrices()
{
if (element_matrices) { return; }
if (auto *ea_ext = dynamic_cast<EABilinearFormExtension*>(ext.get()))
if (element_matrices || domain_integs.Size() == 0 || fes->GetNE() == 0)
{
element_matrices.reset(new DenseTensor);
ea_ext->GetElementMatrices(*element_matrices, ElementDofOrdering::NATIVE, true);
return;
}
if (domain_integs.Size() == 0 || fes->GetNE() == 0)
{
element_matrices.reset(new DenseTensor);
return;
}
int num_elements = fes->GetNE();
int num_dofs_per_el = fes->GetTypicalFE()->GetDof() * fes->GetVDim();
element_matrices.reset(new DenseTensor(num_dofs_per_el, num_dofs_per_el,
num_elements));
element_matrices = new DenseTensor(num_dofs_per_el, num_dofs_per_el,
num_elements);
DenseMatrix tmp;
IsoparametricTransformation eltrans;
@@ -1064,12 +1041,6 @@ void BilinearForm::ComputeElementMatrices()
}
}
const DenseTensor &BilinearForm::GetElementMatrices()
{
ComputeElementMatrices(); // Won't recompute if element_matrices exists
return *element_matrices;
}
void BilinearForm::EliminateEssentialBC(const Array<int> &bdr_attr_is_ess,
const Vector &sol, Vector &rhs,
DiagonalPolicy dpolicy)
@@ -1257,13 +1228,15 @@ void BilinearForm::Update(FiniteElementSpace *nfes)
delete mat_e;
mat_e = NULL;
FreeElementMatrices();
static_cond.reset();
delete static_cond;
static_cond = NULL;
if (full_update)
{
delete mat;
mat = NULL;
hybridization.reset();
delete hybridization;
hybridization = NULL;
sequence = fes->GetSequence();
}
else
@@ -1286,6 +1259,9 @@ BilinearForm::~BilinearForm()
{
delete mat_e;
delete mat;
delete element_matrices;
delete static_cond;
delete hybridization;
if (!extern_bfs)
{
@@ -1297,6 +1273,8 @@ BilinearForm::~BilinearForm()
for (k=0; k < boundary_face_integs.Size(); k++)
{ delete boundary_face_integs[k]; }
}
delete ext;
}
@@ -1323,6 +1301,7 @@ MixedBilinearForm::MixedBilinearForm (FiniteElementSpace *tr_fes,
mat = NULL;
mat_e = NULL;
extern_bfs = 1;
ext = NULL;
// Copy the pointers to the integrators
domain_integs = mbf->domain_integs;
@@ -1352,22 +1331,22 @@ void MixedBilinearForm::SetAssemblyLevel(AssemblyLevel assembly_level)
case AssemblyLevel::LEGACY:
break;
case AssemblyLevel::FULL:
// ext.reset(new FAMixedBilinearFormExtension(this));
// ext = new FAMixedBilinearFormExtension(this);
// Use the original BilinearForm implementation for now
break;
case AssemblyLevel::ELEMENT:
MFEM_ABORT("Element assembly not supported yet... stay tuned!");
// ext.reset(new EAMixedBilinearFormExtension(this));
mfem_error("Element assembly not supported yet... stay tuned!");
// ext = new EAMixedBilinearFormExtension(this);
break;
case AssemblyLevel::PARTIAL:
ext.reset(new PAMixedBilinearFormExtension(this));
ext = new PAMixedBilinearFormExtension(this);
break;
case AssemblyLevel::NONE:
MFEM_ABORT("Matrix-free action not supported yet... stay tuned!");
// ext.reset(new MFMixedBilinearFormExtension(this));
mfem_error("Matrix-free action not supported yet... stay tuned!");
// ext = new MFMixedBilinearFormExtension(this);
break;
default:
MFEM_ABORT("Unknown assembly level");
mfem_error("Unknown assembly level");
}
}
@@ -1525,6 +1504,8 @@ void MixedBilinearForm::Assemble(int skip_zeros)
}
ElementTransformation *eltrans;
DofTransformation * dom_dof_trans;
DofTransformation * ran_dof_trans;
DenseMatrix elmat;
Mesh *mesh = test_fes -> GetMesh();
@@ -1547,12 +1528,11 @@ void MixedBilinearForm::Assemble(int skip_zeros)
}
}
DofTransformation dom_dof_trans, ran_dof_trans;
for (int i = 0; i < test_fes -> GetNE(); i++)
{
const int elem_attr = mesh->GetAttribute(i);
trial_fes->GetElementVDofs (i, trial_vdofs, dom_dof_trans);
test_fes->GetElementVDofs (i, test_vdofs, ran_dof_trans);
dom_dof_trans = trial_fes -> GetElementVDofs (i, trial_vdofs);
ran_dof_trans = test_fes -> GetElementVDofs (i, test_vdofs);
eltrans = test_fes -> GetElementTransformation (i);
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
@@ -1568,7 +1548,10 @@ void MixedBilinearForm::Assemble(int skip_zeros)
elmat += elemmat;
}
}
TransformDual(ran_dof_trans, dom_dof_trans, elmat);
if (ran_dof_trans || dom_dof_trans)
{
TransformDual(ran_dof_trans, dom_dof_trans, elmat);
}
mat -> AddSubMatrix (test_vdofs, trial_vdofs, elmat, skip_zeros);
}
}
@@ -1596,14 +1579,13 @@ void MixedBilinearForm::Assemble(int skip_zeros)
}
}
DofTransformation dom_dof_trans, ran_dof_trans;
for (int i = 0; i < test_fes -> GetNBE(); i++)
{
const int bdr_attr = mesh->GetBdrAttribute(i);
if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
trial_fes->GetBdrElementVDofs (i, trial_vdofs, dom_dof_trans);
test_fes->GetBdrElementVDofs (i, test_vdofs, ran_dof_trans);
dom_dof_trans = trial_fes -> GetBdrElementVDofs (i, trial_vdofs);
ran_dof_trans = test_fes -> GetBdrElementVDofs (i, test_vdofs);
eltrans = test_fes -> GetBdrElementTransformation (i);
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
@@ -1618,7 +1600,10 @@ void MixedBilinearForm::Assemble(int skip_zeros)
*eltrans, elemmat);
elmat += elemmat;
}
TransformDual(ran_dof_trans, dom_dof_trans, elmat);
if (ran_dof_trans || dom_dof_trans)
{
TransformDual(ran_dof_trans, dom_dof_trans, elmat);
}
mat -> AddSubMatrix (test_vdofs, trial_vdofs, elmat, skip_zeros);
}
}
@@ -2358,6 +2343,7 @@ MixedBilinearForm::~MixedBilinearForm()
for (i = 0; i < boundary_trace_face_integs.Size(); i++)
{ delete boundary_trace_face_integs[i]; }
}
delete ext;
}
void DiscreteLinearOperator::SetAssemblyLevel(AssemblyLevel assembly_level)
@@ -2374,16 +2360,16 @@ void DiscreteLinearOperator::SetAssemblyLevel(AssemblyLevel assembly_level)
// Use the original implementation for now
break;
case AssemblyLevel::ELEMENT:
MFEM_ABORT("Element assembly not supported yet... stay tuned!");
mfem_error("Element assembly not supported yet... stay tuned!");
break;
case AssemblyLevel::PARTIAL:
ext.reset(new PADiscreteLinearOperatorExtension(this));
ext = new PADiscreteLinearOperatorExtension(this);
break;
case AssemblyLevel::NONE:
MFEM_ABORT("Matrix-free action not supported yet... stay tuned!");
mfem_error("Matrix-free action not supported yet... stay tuned!");
break;
default:
MFEM_ABORT("Unknown assembly level");
mfem_error("Unknown assembly level");
}
}
@@ -2396,6 +2382,8 @@ void DiscreteLinearOperator::Assemble(int skip_zeros)
}
ElementTransformation *eltrans;
DofTransformation * dom_dof_trans;
DofTransformation * ran_dof_trans;
DenseMatrix elmat;
Mesh *mesh = test_fes->GetMesh();
@@ -2418,13 +2406,11 @@ void DiscreteLinearOperator::Assemble(int skip_zeros)
}
}
DofTransformation dom_dof_trans;
DofTransformation ran_dof_trans;
for (int i = 0; i < test_fes->GetNE(); i++)
{
const int elem_attr = mesh->GetAttribute(i);
trial_fes->GetElementVDofs(i, trial_vdofs, dom_dof_trans);
test_fes->GetElementVDofs(i, test_vdofs, ran_dof_trans);
dom_dof_trans = trial_fes->GetElementVDofs(i, trial_vdofs);
ran_dof_trans = test_fes->GetElementVDofs(i, test_vdofs);
eltrans = test_fes->GetElementTransformation(i);
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
@@ -2440,7 +2426,10 @@ void DiscreteLinearOperator::Assemble(int skip_zeros)
elmat += elemmat;
}
}
TransformPrimal(ran_dof_trans, dom_dof_trans, elemmat);
if (ran_dof_trans || dom_dof_trans)
{
TransformPrimal(ran_dof_trans, dom_dof_trans, elemmat);
}
mat->SetSubMatrix(test_vdofs, trial_vdofs, elemmat, skip_zeros);
}
}

Some files were not shown because too many files have changed in this diff Show More