Compare commits
64
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef5f729245 | ||
|
|
6fa5a0b096 | ||
|
|
3bd8349909 | ||
|
|
af82ee8560 | ||
|
|
2ac542c720 | ||
|
|
e6f828a5fe | ||
|
|
4d756edd80 | ||
|
|
cf5bd1f5cc | ||
|
|
7173dd2002 | ||
|
|
50182bf440 | ||
|
|
24bfcc5165 | ||
|
|
302f22f297 | ||
|
|
1637fcd933 | ||
|
|
2563506174 | ||
|
|
60640c3f7e | ||
|
|
f221521203 | ||
|
|
1d9e736af6 | ||
|
|
d80dbfd99a | ||
|
|
3f44043e60 | ||
|
|
b218959bca | ||
|
|
aee7bc9d43 | ||
|
|
31cac320d4 | ||
|
|
e7e0fb0a88 | ||
|
|
ba71d13980 | ||
|
|
5c326a5535 | ||
|
|
9457f7e5b6 | ||
|
|
ff030ee970 | ||
|
|
2be9e1f36c | ||
|
|
7671cd9f36 | ||
|
|
f89a633fda | ||
|
|
4ce1cef6b8 | ||
|
|
c667bf3025 | ||
|
|
e1678afe40 | ||
|
|
c0291398ed | ||
|
|
0b4f10d79d | ||
|
|
8dfd0e1547 | ||
|
|
caf239c99a | ||
|
|
44c33aece0 | ||
|
|
ed49856390 | ||
|
|
4fef6ca298 | ||
|
|
d9d809e81c | ||
|
|
51e85ccd84 | ||
|
|
4304159303 | ||
|
|
6276268e52 | ||
|
|
580ae34842 | ||
|
|
97eaf8efbc | ||
|
|
e6621c9b0c | ||
|
|
461246f80e | ||
|
|
a5941ee72f | ||
|
|
c4c2ceab59 | ||
|
|
88b99a1719 | ||
|
|
7aa7b4ee53 | ||
|
|
bcf87fee29 | ||
|
|
2949dc5a46 | ||
|
|
b0dbadd007 | ||
|
|
6ca1f95979 | ||
|
|
39794585c4 | ||
|
|
65a71259f1 | ||
|
|
3f4e8324d4 | ||
|
|
9fca398741 | ||
|
|
a2b8f7a129 | ||
|
|
a367631ce5 | ||
|
|
d7718f5c57 | ||
|
|
fe88c4685d |
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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,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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
@@ -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}}
|
||||
@@ -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}}"
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -18,7 +18,7 @@
|
||||
setup_baseline:
|
||||
tags:
|
||||
- shell
|
||||
- dane
|
||||
- ruby
|
||||
stage: setup
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
|
||||
@@ -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
|
||||
@@ -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}"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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".
|
||||
|
||||
@@ -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@)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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@
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
@@ -115,7 +115,7 @@ vertices
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: H1_3D_P2
|
||||
FiniteElementCollection: Quadratic
|
||||
VDim: 3
|
||||
Ordering: 0
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -56,7 +56,7 @@ vertices
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: H1_3D_P2
|
||||
FiniteElementCollection: Quadratic
|
||||
VDim: 3
|
||||
Ordering: 0
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -227,7 +227,7 @@ vertices
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: H1_2D_P2
|
||||
FiniteElementCollection: Quadratic
|
||||
VDim: 2
|
||||
Ordering: 0
|
||||
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ vertices
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: H1_2D_P2
|
||||
FiniteElementCollection: Quadratic
|
||||
VDim: 2
|
||||
Ordering: 0
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+83
-94
@@ -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
Reference in New Issue
Block a user