Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
552d6857cb | ||
|
|
a37d46e917 | ||
|
|
4acdb072b6 | ||
|
|
9dbb184537 | ||
|
|
d67762a1c9 |
@@ -94,16 +94,6 @@ inputs:
|
||||
description: If true, do not set any CXXFLAGS or LDFLAGS.
|
||||
default: false
|
||||
|
||||
# Unfortunately, "uses:" fields cannot have references to variables like
|
||||
# ${{env.MFEM_ACTIONS_VERSION}}, so the branch/tag name has to be hard coded.
|
||||
# Therefore, in the future, when updating the version of the
|
||||
# mfem/github-actions to use, we'll have to replace:
|
||||
# - all definitions of MFEM_ACTIONS_VERSION and
|
||||
# - all "uses:" fields that refer to mfem/github-actions.
|
||||
MFEM_ACTIONS_VERSION:
|
||||
description: Version (branch or tag) of the mfem/github-actions to use.
|
||||
default: v2.7
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
@@ -128,7 +118,6 @@ runs:
|
||||
echo UBSAN_LDFLAGS=${{inputs.UBSAN_LDFLAGS}} >> $GITHUB_ENV
|
||||
echo MSAN_CXXFLAGS=${{inputs.MSAN_CXXFLAGS}} >> $GITHUB_ENV
|
||||
echo MSAN_LDFLAGS=${{inputs.MSAN_LDFLAGS}} >> $GITHUB_ENV
|
||||
echo MFEM_ACTIONS_VERSION=${{inputs.MFEM_ACTIONS_VERSION}} >> $GITHUB_ENV
|
||||
shell: bash
|
||||
|
||||
- name: Env (dir)
|
||||
|
||||
@@ -25,7 +25,7 @@ runs:
|
||||
steps:
|
||||
- uses: ./.github/actions/sanitize/config
|
||||
|
||||
- uses: actions/cache@v5
|
||||
- uses: actions/cache@v4
|
||||
if: ${{env.DEBUG == 'true'}}
|
||||
id: debug
|
||||
with:
|
||||
@@ -53,7 +53,7 @@ runs:
|
||||
run: echo CXXFLAGS=${{env.CXXFLAGS}} ${{env.UBSAN_CXXFLAGS}} >> $GITHUB_ENV
|
||||
shell: bash
|
||||
|
||||
- uses: mfem/github-actions/build-mfem@v2.7
|
||||
- uses: mfem/github-actions/build-mfem@v2.5
|
||||
if: ${{steps.debug.outputs.cache-hit != 'true'}}
|
||||
env:
|
||||
CXXFLAGS: ${{env.CXXFLAGS}}
|
||||
@@ -82,7 +82,7 @@ runs:
|
||||
run: find . -type f -name '*.o' -delete
|
||||
shell: bash
|
||||
|
||||
- uses: actions/upload-artifact@v7
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: build-${{inputs.par}}-${{inputs.sanitizer}}
|
||||
path: mfem/build
|
||||
|
||||
@@ -12,11 +12,6 @@
|
||||
name: 'Install MPI'
|
||||
description: 'Installs MPI and set up its environment variables'
|
||||
|
||||
inputs:
|
||||
NO_FLAGS:
|
||||
description: If true, do not set any CXXFLAGS or LDFLAGS.
|
||||
default: false
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
@@ -32,7 +27,6 @@ runs:
|
||||
shell: bash
|
||||
|
||||
- name: Env (bis)
|
||||
if: ${{ inputs.NO_FLAGS != 'true' }}
|
||||
run: |
|
||||
echo CXXFLAGS=${{env.CXXFLAGS}} ${{env.MPI_INC}} >> $GITHUB_ENV
|
||||
echo LDFLAGS=${{env.LDFLAGS}} ${{env.MPI_LIB}} >> $GITHUB_ENV
|
||||
|
||||
@@ -36,7 +36,7 @@ runs:
|
||||
steps:
|
||||
- uses: ./.github/actions/sanitize/config
|
||||
|
||||
- uses: actions/cache@v5
|
||||
- uses: actions/cache@v4
|
||||
if: ${{env.DEBUG == 'true' && inputs.cache-skip != 'true'}}
|
||||
id: debug
|
||||
with:
|
||||
@@ -49,7 +49,7 @@ runs:
|
||||
par: ${{inputs.par}}
|
||||
sanitizer: ${{inputs.sanitizer}}
|
||||
|
||||
- uses: actions/download-artifact@v8
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-${{inputs.par}}-${{inputs.sanitizer}}
|
||||
path: mfem/build
|
||||
|
||||
@@ -23,7 +23,7 @@ inputs:
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
- uses: actions/cache/restore@v5 # Cache for LLVM libcxx
|
||||
- uses: actions/cache/restore@v4 # Cache for LLVM libcxx
|
||||
with:
|
||||
path: ${{env.LLVM_DIR}}
|
||||
fail-on-cache-miss: true
|
||||
@@ -32,32 +32,32 @@ runs:
|
||||
- uses: ./.github/actions/sanitize/mpi
|
||||
if: ${{inputs.par == 'true'}}
|
||||
|
||||
- uses: actions/cache/restore@v5 # Cache for Hypre
|
||||
- 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-${{env.MFEM_ACTIONS_VERSION}}
|
||||
key: ${{runner.os}}-ompi-build-${{env.HYPRE_DIR}}-int32-fp64-v2.5
|
||||
|
||||
- uses: actions/cache/restore@v5 # Cache for Metis
|
||||
- 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}}-${{env.MFEM_ACTIONS_VERSION}}
|
||||
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@v5 # Cache for LSAN suppression file
|
||||
- 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@v6 # Checkout the repository
|
||||
- uses: actions/checkout@v4 # Checkout the repository
|
||||
with:
|
||||
path: mfem
|
||||
# ref: ${{env.BRANCH}}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
# MFEM Pull Request Review Agent Guide
|
||||
|
||||
## Purpose and scope
|
||||
Review MFEM PRs for correctness, maintainability, performance, portability, test coverage, and MFEM consistency. Use the diff and PR context; reference source files, tests, and CI results when available. Follow `CONTRIBUTING.md`, especially Developer Guidelines, PR rules, checklist, and testing.
|
||||
|
||||
## Critical review pillars
|
||||
- Correctness and numerical behavior
|
||||
- API and user-facing impact
|
||||
- Performance implications
|
||||
- Maintainability and portability
|
||||
|
||||
## Review workflow
|
||||
1. Read the PR description, linked issues, and intended behavior.
|
||||
2. Inspect the diff before commenting.
|
||||
3. Identify affected MFEM components, examples, tests, build or docs changes, and downstream APIs.
|
||||
4. Analyze the code against the critical review pillars.
|
||||
5. Compare the change against nearby code and MFEM patterns; flag unmotivated deviations.
|
||||
6. Check whether tests and documentation were updated appropriately.
|
||||
7. Review CI results and suggest actions.
|
||||
8. Produce a structured review with prioritized findings.
|
||||
9. Always limit conclusions to available evidence.
|
||||
|
||||
## MFEM-specific review checklist
|
||||
- Component-aware scope: identify the touched subsystem (FEM, solvers, preconditioners, linear algebra, mesh, examples, miniapps, build, or docs) and assess its impact against the review pillars.
|
||||
- Numerical and algorithmic behavior: assess issues in convergence, stability, tolerances, precision, iteration limits, and failure handling. If clear opportunities exist to improve the algorithmic approach, call them out with expected impact.
|
||||
- API and user-facing impact: assess backward compatibility, user-visible behavior and default changes, migration impact, deprecations, and whether documentation clearly explains user-facing API changes.
|
||||
- Data structure and memory semantics: assess ownership, lifetime, aliasing, container behavior, and device-host synchronization.
|
||||
- Parallel and serial behavior: assess whether the change preserves equivalent semantics in serial and parallel modes where applicable; if logic is currently mode-specific, check whether extension to the other mode is straightforward (clear abstractions, no hard-wired assumptions), document constraints, and call out expected behavior differences explicitly.
|
||||
- Backend and portability impact: assess likely cross-backend risks in CPU, CUDA, HIP, OCCA, RAJA, partial assembly, fallback paths, compiler compatibility, and platform assumptions.
|
||||
- Build, dependency, and configuration impact: assess CMake or make changes, optional dependency behavior, and feature-flag interactions.
|
||||
- Tests and docs alignment: check available regression or unit coverage evidence for changed behavior, and ensure docs are updated for new flags, APIs, options, or behavior changes.
|
||||
- MFEM developer-guideline fit: keep code lean, simple, general, logically separated, and portable; suggest C++17 improvements when they clearly improve safety, clarity, or maintainability.
|
||||
- New source files, examples, or miniapps: if a PR adds source/header files, verify they are properly wired into the relevant `makefile` and `CMakeLists.txt`, referenced in docs where applicable (including `doc/CodeDocumentation.dox`), and added to top-level `.gitignore` only when generated artifacts require it.
|
||||
- Changelog: verify `CHANGELOG` is updated if the PR introduces significant new features or user-facing changes.
|
||||
- MFEM conventions: use `real_t`; use `mfem::out`/`mfem::err` instead of `std::cout`/`std::cerr` in library code; flag large/binary files; if AI assistance is apparent but undisclosed, suggest following `CONTRIBUTING.md`.
|
||||
- Edge cases: if the PR touches complex or error-prone areas, suggest additional tests for edge cases, failure modes, and parallel behavior.
|
||||
|
||||
## Commenting guidelines
|
||||
- Keep comments concise, actionable, and grounded in the diff.
|
||||
- Focus on correctness, behavior changes, and user impact over style nits.
|
||||
- Be professional, concise, collaborative, technically precise, and avoid unsupported assumptions.
|
||||
|
||||
@@ -13,7 +13,7 @@ Note that some of these scripts use the shared MFEM GitHub Actions from the exte
|
||||
|
||||
<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 (or tag) in the above from which the action is taken.
|
||||
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.
|
||||
|
||||
The current CI workflows are:
|
||||
|
||||
@@ -29,12 +29,16 @@ 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`)
|
||||
|
||||
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`
|
||||
|
||||
Runs a matrix of builds and tests runs with different compilers, OS, mfem/hypre settings, etc. Also processes and upload Codecov reports.
|
||||
|
||||
One matrix job runs `tests/scripts/gitignore` after `make test-noclean` to check generated artifacts against `.gitignore`.
|
||||
|
||||
Uses the following GitHub Actions from <https://github.com/mfem/github-actions>:
|
||||
|
||||
- `mfem/github-actions/build-hypre`
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
remove-docker-images: 'true'
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# It's easier to reference named variables than indexes of the matrix
|
||||
- name: Set Environment
|
||||
|
||||
@@ -40,7 +40,6 @@ env:
|
||||
METIS_ARCHIVE_MAC: metis-4.0.3-mac.tgz
|
||||
METIS_TOP_DIR: metis-4.0.3
|
||||
MFEM_TOP_DIR: mfem
|
||||
MFEM_ACTIONS_VERSION: v2.7
|
||||
|
||||
# Note for future improvements:
|
||||
#
|
||||
@@ -111,7 +110,6 @@ jobs:
|
||||
build-system: make
|
||||
hypre-target: int64
|
||||
precision: fp64
|
||||
gitignore-check: YES
|
||||
- os: ubuntu-latest
|
||||
target: opt
|
||||
codecov: NO
|
||||
@@ -142,10 +140,6 @@ jobs:
|
||||
|
||||
continue-on-error: ${{ matrix.enzyme && true || false }}
|
||||
|
||||
# Enable ccache for all jobs except Windows (would need sccache).
|
||||
env:
|
||||
USE_CCACHE: ${{ matrix.os != 'windows-latest' }}
|
||||
|
||||
steps:
|
||||
# Fix 'No space left on device' errors for Ubuntu builds.
|
||||
- name: Run Actions Cleaner
|
||||
@@ -159,7 +153,7 @@ jobs:
|
||||
# /home/runner/work/mfem/mfem/mfem
|
||||
# Note: Done now to access "install-hypre" and "install-metis" actions.
|
||||
- name: checkout mfem
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: ${{ env.MFEM_TOP_DIR }}
|
||||
# Fetch the complete history for codecov to access commits ID
|
||||
@@ -176,6 +170,20 @@ jobs:
|
||||
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"
|
||||
echo "> sudo xcode-select -s ${XCODE_PATH}"
|
||||
sudo xcode-select -s ${XCODE_PATH}
|
||||
echo "> g++ -v"
|
||||
g++ -v
|
||||
echo "> clang++ -v"
|
||||
clang++ -v
|
||||
|
||||
# Only get MPI if defined for the job.
|
||||
# TODO: It would be nice to have only one step, e.g. with a dedicated
|
||||
# action, but I (@adrienbernede) don't see how at the moment.
|
||||
@@ -217,14 +225,14 @@ jobs:
|
||||
- name: cache hypre
|
||||
id: hypre-cache
|
||||
if: matrix.mpi == 'par'
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.HYPRE_TOP_DIR }}
|
||||
key: ${{ runner.os }}-ompi-build-${{ env.HYPRE_TOP_DIR }}-${{ matrix.hypre-target }}-${{ matrix.precision }}-${{ env.MFEM_ACTIONS_VERSION }}
|
||||
key: ${{ runner.os }}-ompi-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'
|
||||
uses: mfem/github-actions/build-hypre@v2.7
|
||||
uses: mfem/github-actions/build-hypre@v2.5
|
||||
with:
|
||||
archive: ${{ env.HYPRE_ARCHIVE }}
|
||||
dir: ${{ env.HYPRE_TOP_DIR }}
|
||||
@@ -234,7 +242,7 @@ jobs:
|
||||
|
||||
- name: get hypre (Windows)
|
||||
if: matrix.mpi == 'par' && steps.hypre-cache.outputs.cache-hit != 'true' && matrix.os == 'windows-latest'
|
||||
uses: mfem/github-actions/build-hypre@v2.7
|
||||
uses: mfem/github-actions/build-hypre@v2.5
|
||||
with:
|
||||
archive: ${{ env.HYPRE_ARCHIVE }}
|
||||
dir: ${{ env.HYPRE_TOP_DIR }}
|
||||
@@ -247,14 +255,14 @@ jobs:
|
||||
- name: cache metis
|
||||
id: metis-cache
|
||||
if: matrix.mpi == 'par' && matrix.os != 'windows-latest'
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.METIS_TOP_DIR }}
|
||||
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-${{ env.MFEM_ACTIONS_VERSION }}
|
||||
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.5
|
||||
|
||||
- name: install metis
|
||||
if: matrix.mpi == 'par' && matrix.os != 'windows-latest' && steps.metis-cache.outputs.cache-hit != 'true'
|
||||
uses: mfem/github-actions/build-metis@v2.7
|
||||
uses: mfem/github-actions/build-metis@v2.5
|
||||
with:
|
||||
archive: ${{ matrix.os != 'macos-latest' && env.METIS_ARCHIVE || env.METIS_ARCHIVE_MAC }}
|
||||
dir: ${{ env.METIS_TOP_DIR }}
|
||||
@@ -262,7 +270,7 @@ jobs:
|
||||
- name: cache vcpkg (Windows)
|
||||
id: vcpkg-cache
|
||||
if: matrix.os == 'windows-latest'
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vcpkg_cache
|
||||
key: ${{ runner.os }}-${{ matrix.mpi }}-vcpkg-v1
|
||||
@@ -287,62 +295,15 @@ jobs:
|
||||
export HOMEBREW_NO_INSTALL_CLEANUP=1
|
||||
brew update
|
||||
brew install enzyme
|
||||
ENZYME_LLVM=$(brew info enzyme | sed -n 's/^Required.*:.*\(llvm[^ ]*\).*/\1/p')
|
||||
echo "ENZYME_LLVM=$ENZYME_LLVM"
|
||||
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
|
||||
|
||||
# Restore the compiler cache (ccache). The key embeds the run id, so new
|
||||
# runs save a fresh snapshot; the restore-keys prefix warm-starts from the
|
||||
# most recent prior run (incl. the base branch for PRs).
|
||||
- name: cache ccache
|
||||
if: ${{ env.USE_CCACHE == 'true' }}
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .ccache
|
||||
key: ccache-${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}-${{ matrix.hypre-target }}-${{ matrix.precision }}${{ matrix.enzyme && '-enzyme' || '' }}-${{ github.run_id }}
|
||||
restore-keys: |
|
||||
ccache-${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}-${{ matrix.hypre-target }}-${{ matrix.precision }}${{ matrix.enzyme && '-enzyme' || '' }}-
|
||||
|
||||
# Configure ccache and select how it is injected into the MFEM build:
|
||||
# - make: set CXX="ccache g++"; for MPI, OMPI_CXX="ccache g++" so mpicxx
|
||||
# runs ccache around g++ (not ccache around the mpicxx wrapper).
|
||||
# - cmake: set CMAKE_<LANG>_COMPILER_LAUNCHER=ccache.
|
||||
# - enzyme: wrap the brew clang++ via OMPI_CXX.
|
||||
# The chosen options are passed through build-mfem's 'config-options'
|
||||
# input (see the build step below).
|
||||
- name: configure ccache
|
||||
if: ${{ env.USE_CCACHE == 'true' }}
|
||||
run: |
|
||||
command -v ccache >/dev/null 2>&1 || {
|
||||
if [[ "${{ runner.os }}" == "Linux" ]]; then
|
||||
sudo apt-get update && sudo apt-get install -y ccache
|
||||
else
|
||||
brew install ccache
|
||||
fi
|
||||
}
|
||||
echo "CCACHE_DIR=${{ github.workspace }}/.ccache" >> $GITHUB_ENV
|
||||
echo "CCACHE_MAXSIZE=1G" >> $GITHUB_ENV
|
||||
echo "CCACHE_COMPILERCHECK=content" >> $GITHUB_ENV
|
||||
# Ignore header timestamps (restamped by each checkout) so direct mode hits.
|
||||
echo "CCACHE_SLOPPINESS=include_file_mtime,include_file_ctime,time_macros" >> $GITHUB_ENV
|
||||
# Hash absolute paths relative to the workspace.
|
||||
echo "CCACHE_BASEDIR=${{ github.workspace }}" >> $GITHUB_ENV
|
||||
if [[ "${{ matrix.enzyme }}" == "true" ]]; then
|
||||
echo "OMPI_CXX=ccache $LLVM_PREFIX/bin/clang++" >> $GITHUB_ENV
|
||||
elif [[ "${{ matrix.build-system }}" == "cmake" ]]; then
|
||||
echo 'CCACHE_CONFIG_OPTS=-DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache' >> $GITHUB_ENV
|
||||
else
|
||||
echo "OMPI_CXX=ccache g++" >> $GITHUB_ENV
|
||||
echo 'CCACHE_CONFIG_OPTS=CXX="ccache g++" MPICXX="mpicxx"' >> $GITHUB_ENV
|
||||
fi
|
||||
shell: bash
|
||||
|
||||
# MFEM build and test
|
||||
- name: build
|
||||
uses: mfem/github-actions/build-mfem@v2.7
|
||||
uses: mfem/github-actions/build-mfem@v2.5
|
||||
env:
|
||||
VCPKG_DEFAULT_BINARY_CACHE: ${{ github.workspace }}/vcpkg_cache
|
||||
with:
|
||||
@@ -355,14 +316,9 @@ jobs:
|
||||
metis-dir: ${{ env.METIS_TOP_DIR }}
|
||||
mfem-dir: ${{ env.MFEM_TOP_DIR }}
|
||||
precision: ${{ matrix.precision }}
|
||||
config-options: ${{ matrix.config-opts }} ${{ env.CCACHE_CONFIG_OPTS }}
|
||||
config-options: ${{ matrix.config-opts }}
|
||||
library-only: ${{ matrix.target == 'dbg' && matrix.os != 'ubuntu-latest' }}
|
||||
|
||||
- name: ccache stats
|
||||
if: ${{ env.USE_CCACHE == 'true' }}
|
||||
run: ccache -s
|
||||
shell: bash
|
||||
|
||||
# Run checks (and only checks) on debug targets
|
||||
- name: checks
|
||||
if: matrix.build-system == 'make' && matrix.target == 'dbg'
|
||||
@@ -373,13 +329,7 @@ jobs:
|
||||
- name: tests
|
||||
if: matrix.build-system == 'make' && (matrix.target == 'opt' || matrix.os == 'ubuntu-latest')
|
||||
run: |
|
||||
cd ${{ env.MFEM_TOP_DIR }}
|
||||
if [[ "${{ matrix.gitignore-check }}" == "YES" ]]; then
|
||||
make test-noclean
|
||||
else
|
||||
make test
|
||||
fi
|
||||
shell: bash
|
||||
cd ${{ env.MFEM_TOP_DIR }} && make test
|
||||
|
||||
- name: cmake checks
|
||||
if: matrix.build-system == 'cmake' && matrix.target == 'dbg'
|
||||
@@ -424,16 +374,8 @@ jobs:
|
||||
# Code coverage (process and upload reports)
|
||||
- name: codecov
|
||||
if: matrix.codecov == 'YES'
|
||||
uses: mfem/github-actions/upload-coverage@v2.7
|
||||
uses: mfem/github-actions/upload-coverage@v2.5
|
||||
with:
|
||||
name: ${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}-${{ matrix.hypre-target }}-${{ matrix.precision }}
|
||||
name: ${{ matrix.os }}-${{ matrix.build-system }}-${{ matrix.target }}-${{ matrix.mpi }}-${{ matrix.hypre-target }}
|
||||
project_dir: ${{ env.MFEM_TOP_DIR }}
|
||||
directories: "fem general linalg mesh"
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
- name: gitignore
|
||||
if: matrix.gitignore-check == 'YES'
|
||||
run: |
|
||||
cd ${{ env.MFEM_TOP_DIR }}/tests/scripts
|
||||
./runtest gitignore
|
||||
|
||||
@@ -1,42 +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.
|
||||
---
|
||||
# A closed PR's caches can never be restored again, so delete them to free
|
||||
# space against the 10 GB per-repo cache limit.
|
||||
name: Cleanup PR caches
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
|
||||
jobs:
|
||||
cleanup:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Delete caches for the closed PR
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GH_REPO: ${{ github.repository }}
|
||||
PR_REF: refs/pull/${{ github.event.pull_request.number }}/merge
|
||||
run: |
|
||||
echo "Deleting caches for $PR_REF"
|
||||
while :; do
|
||||
ids=$(gh cache list --ref "$PR_REF" --limit 100 --json id --jq '.[].id')
|
||||
[ -n "$ids" ] || break
|
||||
echo "$ids" | while read -r id; do
|
||||
[ -n "$id" ] || continue
|
||||
echo "Deleting cache $id"
|
||||
gh cache delete "$id" || echo " (already gone)"
|
||||
done
|
||||
done
|
||||
@@ -14,19 +14,9 @@ name: "Static Analysis"
|
||||
on:
|
||||
push:
|
||||
branches: ["master", "next"]
|
||||
paths-ignore: &docs-only-paths
|
||||
- "**/*.md"
|
||||
- "doc/**"
|
||||
- ".binder/**"
|
||||
- "CITATION.cff"
|
||||
- "LICENSE"
|
||||
- "NOTICE"
|
||||
- "CHANGELOG"
|
||||
- "INSTALL"
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: ["master"]
|
||||
paths-ignore: *docs-only-paths
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -50,11 +40,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -67,7 +57,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v4
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
@@ -80,4 +70,4 @@ jobs:
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# 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 Analysis"
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- next
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
HYPRE_ARCHIVE: v2.19.0.tar.gz
|
||||
HYPRE_TOP_DIR: hypre-2.19.0
|
||||
METIS_ARCHIVE: metis-4.0.3.tar.gz
|
||||
METIS_TOP_DIR: metis-4.0.3
|
||||
COVERAGE_ENV: mfem-coverage
|
||||
|
||||
jobs:
|
||||
gitignore:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: checkout MFEM
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: mfem
|
||||
|
||||
- name: Get MPI (Linux)
|
||||
run: |
|
||||
sudo apt-get install openmpi-bin libopenmpi-dev
|
||||
export OMPI_MCA_rmaps_base_oversubscribe=1
|
||||
|
||||
- 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
|
||||
|
||||
- name: Get Hypre
|
||||
if: steps.hypre-cache.outputs.cache-hit != 'true'
|
||||
uses: mfem/github-actions/build-hypre@v2.5
|
||||
with:
|
||||
archive: ${{ env.HYPRE_ARCHIVE }}
|
||||
dir: ${{ env.HYPRE_TOP_DIR }}
|
||||
target: int32
|
||||
|
||||
- name: Cache Metis Install
|
||||
id: metis-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.METIS_TOP_DIR }}
|
||||
key: ${{ runner.os }}-build-${{ env.METIS_TOP_DIR }}-v2.5
|
||||
|
||||
- name: Install Metis
|
||||
if: steps.metis-cache.outputs.cache-hit != 'true'
|
||||
uses: mfem/github-actions/build-metis@v2.5
|
||||
with:
|
||||
archive: ${{ env.METIS_ARCHIVE }}
|
||||
dir: ${{ env.METIS_TOP_DIR }}
|
||||
|
||||
# MFEM build and test
|
||||
- name: build-mfem
|
||||
uses: mfem/github-actions/build-mfem@v2.5
|
||||
with:
|
||||
os: ${{ runner.os }}
|
||||
target: opt
|
||||
codecov: NO
|
||||
mpi: par
|
||||
build-system: make
|
||||
hypre-dir: ${{ env.HYPRE_TOP_DIR }}
|
||||
metis-dir: ${{ env.METIS_TOP_DIR }}
|
||||
mfem-dir: mfem
|
||||
|
||||
- name: test (no clean)
|
||||
run: |
|
||||
cd mfem && make test-noclean
|
||||
|
||||
- name: gitignore
|
||||
run: |
|
||||
cd mfem/tests/scripts
|
||||
./runtest gitignore
|
||||
@@ -13,7 +13,6 @@ name: "Checks"
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
pull-requests: read
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -30,11 +29,6 @@ concurrency:
|
||||
# by checking if the workflow trigger is 'push' ("github.event_name == 'push'")
|
||||
# and if we are in a fork ("github.event.pull_request.head.repo.full_name !=
|
||||
# github.repository").
|
||||
#
|
||||
# The logic for the branch-history check is slightly different, since that check
|
||||
# also inspects the PR's labels to allow for overriding failures. In this case,
|
||||
# we run on all 'pull_request' triggers, but only run for 'push' triggers that
|
||||
# do not correspond to any open PRs.
|
||||
|
||||
jobs:
|
||||
file-headers-check:
|
||||
@@ -44,7 +38,7 @@ jobs:
|
||||
github.event.pull_request.head.repo.full_name != github.repository)
|
||||
steps:
|
||||
- name: checkout mfem
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: copyright check
|
||||
id: copyright
|
||||
@@ -99,7 +93,7 @@ jobs:
|
||||
github.event.pull_request.head.repo.full_name != github.repository)
|
||||
steps:
|
||||
- name: checkout mfem
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: get astyle
|
||||
run: |
|
||||
@@ -116,7 +110,7 @@ jobs:
|
||||
github.event.pull_request.head.repo.full_name != github.repository)
|
||||
steps:
|
||||
- name: checkout mfem
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: get doxygen and graphviz
|
||||
run: |
|
||||
@@ -134,35 +128,18 @@ jobs:
|
||||
|
||||
branch-history:
|
||||
if: |
|
||||
github.ref != 'refs/heads/next' && github.ref != 'refs/heads/master'
|
||||
github.ref != 'refs/heads/next' &&
|
||||
github.ref != 'refs/heads/master' &&
|
||||
(github.event_name == 'push' ||
|
||||
github.event.pull_request.head.repo.full_name != github.repository)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: checkout mfem
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: check for pull request
|
||||
id: check_pr
|
||||
if: github.event_name == 'push'
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
pr_exists=$(gh pr list --repo "$GITHUB_REPOSITORY" \
|
||||
--head "$GITHUB_REF_NAME" \
|
||||
--state open \
|
||||
--json number \
|
||||
--jq 'length > 0')
|
||||
echo "pr_exists=$pr_exists" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: branch-history
|
||||
id: branch_history
|
||||
if: |
|
||||
(github.event_name == 'pull_request' ||
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
steps.check_pr.outputs.pr_exists == 'false')
|
||||
continue-on-error: ${{ contains(github.event.pull_request.labels.*.name,
|
||||
'branch-history-override') }}
|
||||
run: |
|
||||
# We override origin to make sure we point to the main repo.
|
||||
# This is to have consistent test results on PRs from forks.
|
||||
@@ -170,9 +147,3 @@ jobs:
|
||||
git remote add origin https://github.com/mfem/mfem.git
|
||||
git checkout -b gh-actions-branch-history
|
||||
./config/githooks/pre-push --history
|
||||
|
||||
- name: report branch-history override
|
||||
if: steps.branch_history.outcome == 'failure'
|
||||
run: |
|
||||
echo "::warning::branch-history check failed, but the" \
|
||||
"'branch-history-override' label is set."
|
||||
|
||||
@@ -17,24 +17,20 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: 2.19.0
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/config
|
||||
with:
|
||||
NO_FLAGS: true
|
||||
- name: Cache
|
||||
id: cache
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.HYPRE_DIR}}
|
||||
key: ${{runner.os}}-ompi-build-${{env.HYPRE_DIR}}-int32-fp64-${{ env.MFEM_ACTIONS_VERSION }}
|
||||
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
|
||||
with:
|
||||
NO_FLAGS: true
|
||||
- name: Build
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
uses: mfem/github-actions/build-hypre@v2.7
|
||||
uses: mfem/github-actions/build-hypre@v2.5
|
||||
with:
|
||||
archive: ${{env.HYPRE_TGZ}}
|
||||
dir: ${{env.HYPRE_DIR}}
|
||||
|
||||
@@ -27,13 +27,13 @@ jobs:
|
||||
llvm_use_sanitizer: "Undefined"
|
||||
name: ${{matrix.sanitizer}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/config
|
||||
with:
|
||||
NO_FLAGS: true
|
||||
- name: Cache
|
||||
id: cache
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.LLVM_DIR}}
|
||||
key: build-libcxx-${{env.LLVM_VER}}-${{matrix.sanitizer}}
|
||||
|
||||
@@ -17,11 +17,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: lsan.supp
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/config
|
||||
- name: Cache
|
||||
id: cache
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.LSAN_DIR}}
|
||||
key: build-lsan-suppression-file
|
||||
|
||||
@@ -17,24 +17,20 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: 4.0.3
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/config
|
||||
with:
|
||||
NO_FLAGS: true
|
||||
- name: Cache
|
||||
id: cache
|
||||
uses: actions/cache@v5
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{env.METIS_DIR}}
|
||||
key: ${{runner.os}}-build-${{env.METIS_DIR}}-${{env.MFEM_ACTIONS_VERSION}}
|
||||
key: ${{runner.os}}-build-${{env.METIS_DIR}}-v2.5
|
||||
- name: Setup
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
uses: ./.github/actions/sanitize/mpi
|
||||
with:
|
||||
NO_FLAGS: true
|
||||
- name: Build
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
uses: mfem/github-actions/build-metis@v2.7
|
||||
uses: mfem/github-actions/build-metis@v2.5
|
||||
with:
|
||||
archive: ${{env.METIS_TGZ}}
|
||||
dir: ${{env.METIS_DIR}}
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/mfem
|
||||
with:
|
||||
par: ${{inputs.par}}
|
||||
@@ -40,7 +40,7 @@ jobs:
|
||||
env:
|
||||
ex: ${{inputs.par && 'ex1p' || 'ex1'}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/restore
|
||||
id: restore
|
||||
with:
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
env:
|
||||
exclude: ${{inputs.par && '-E "_ser"' || ''}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/restore
|
||||
id: restore
|
||||
with:
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
env:
|
||||
exclude: ${{inputs.par && '-E "_ser"' || ''}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/restore
|
||||
id: restore
|
||||
with:
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
run: ${{inputs.par && '-R "_cpu_np"' || ''}}
|
||||
exclude: ${{inputs.par && '"unit_tests|debug"' || '"^unit_tests$|debug"'}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/restore
|
||||
id: restore
|
||||
with:
|
||||
@@ -131,7 +131,7 @@ jobs:
|
||||
env:
|
||||
unit_tests: ${{inputs.par && 'punit_tests' || 'unit_tests'}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/sanitize/restore
|
||||
id: restore
|
||||
with:
|
||||
@@ -146,7 +146,7 @@ jobs:
|
||||
if: ${{steps.restore.outputs.cache-hit != 'true'}}
|
||||
working-directory: mfem/build/tests/unit
|
||||
run: find . -type f -name '*.o' -delete
|
||||
- uses: actions/upload-artifact@v7
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tests-${{inputs.par}}-${{inputs.sanitizer}}
|
||||
path: mfem/build/tests/unit/${{env.unit_tests}}
|
||||
@@ -165,14 +165,14 @@ jobs:
|
||||
unit_tests: ${{inputs.par && 'punit_tests' || 'unit_tests'}}
|
||||
np: ${{inputs.par && '_np=2' || ''}}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- 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@v8
|
||||
- uses: actions/download-artifact@v4
|
||||
if: ${{steps.restore.outputs.cache-hit != 'true'}}
|
||||
with:
|
||||
name: tests-${{inputs.par}}-${{inputs.sanitizer}}
|
||||
|
||||
@@ -17,17 +17,7 @@ permissions:
|
||||
on:
|
||||
push:
|
||||
branches: ["master", "next"]
|
||||
paths-ignore: &docs-only-paths
|
||||
- "**/*.md"
|
||||
- "doc/**"
|
||||
- ".binder/**"
|
||||
- "CITATION.cff"
|
||||
- "LICENSE"
|
||||
- "NOTICE"
|
||||
- "CHANGELOG"
|
||||
- "INSTALL"
|
||||
pull_request:
|
||||
paths-ignore: *docs-only-paths
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
|
||||
+14
-48
@@ -19,15 +19,9 @@ CMakeFiles/
|
||||
# Clangd server cache
|
||||
*.cache*
|
||||
|
||||
#vscode settings
|
||||
/.vscode/
|
||||
|
||||
# Backup files
|
||||
*~
|
||||
|
||||
# clangd index
|
||||
/.cache/
|
||||
|
||||
# Default install location
|
||||
/mfem/
|
||||
|
||||
@@ -85,17 +79,12 @@ examples/sol_u.*
|
||||
examples/sol_p.*
|
||||
examples/sol_r.*
|
||||
examples/sol_i.*
|
||||
examples/sol_z.*
|
||||
examples/ex6p-checkpoint.*
|
||||
examples/order.*
|
||||
examples/ex9.mesh
|
||||
examples/ex9-mesh.*
|
||||
examples/ex9-init.*
|
||||
examples/ex9-final.*
|
||||
examples/ex41.mesh
|
||||
examples/ex41-mesh.*
|
||||
examples/ex41-init.*
|
||||
examples/ex41-final.*
|
||||
examples/deformed.*
|
||||
examples/velocity.*
|
||||
examples/elastic_energy.*
|
||||
@@ -227,9 +216,6 @@ miniapps/electromagnetics/Joule_[0-9]*
|
||||
miniapps/electromagnetics/Lorentz_[0-9]*
|
||||
miniapps/electromagnetics/Lorentz.dat
|
||||
|
||||
miniapps/fluids/schrodinger-flow/schrodinger_flow
|
||||
miniapps/fluids/schrodinger-flow/pschrodinger_flow
|
||||
|
||||
miniapps/gslib/field-diff
|
||||
miniapps/gslib/field-interp
|
||||
miniapps/gslib/findpts
|
||||
@@ -237,7 +223,6 @@ miniapps/gslib/pfindpts
|
||||
miniapps/gslib/schwarz_ex1
|
||||
miniapps/gslib/schwarz_ex1p
|
||||
miniapps/gslib/interpolated.gf
|
||||
miniapps/gslib/particles_redist
|
||||
|
||||
miniapps/meshing/mobius-strip
|
||||
miniapps/meshing/klein-bottle
|
||||
@@ -260,7 +245,6 @@ miniapps/meshing/polar-nc
|
||||
miniapps/meshing/mesh-quality
|
||||
miniapps/meshing/hpref
|
||||
miniapps/meshing/phpref
|
||||
miniapps/meshing/pref321
|
||||
miniapps/meshing/mobius-strip.mesh
|
||||
miniapps/meshing/klein-bottle.mesh
|
||||
miniapps/meshing/toroid-*.mesh
|
||||
@@ -285,8 +269,10 @@ miniapps/meshing/refined.mesh
|
||||
miniapps/meshing/bounding-box*
|
||||
miniapps/meshing/jacobian-determinant*
|
||||
|
||||
miniapps/mtop/ParaView/
|
||||
miniapps/mtop/mtop_test_iso_elasticity
|
||||
miniapps/mtop/parheat
|
||||
miniapps/mtop/ParHeat/*
|
||||
miniapps/mtop/seqheat
|
||||
miniapps/mtop/SeqHeat/*
|
||||
|
||||
miniapps/autodiff/paradiff
|
||||
miniapps/autodiff/seqadiff
|
||||
@@ -296,26 +282,21 @@ miniapps/autodiff/seq_example
|
||||
miniapps/autodiff/seq_test
|
||||
miniapps/autodiff/Example/*
|
||||
|
||||
miniapps/fluids/navier/navier_mms
|
||||
miniapps/fluids/navier/navier_kovasznay
|
||||
miniapps/fluids/navier/navier_kovasznay_vs
|
||||
miniapps/fluids/navier/navier_tgv
|
||||
miniapps/fluids/navier/navier_shear
|
||||
miniapps/fluids/navier/navier_3dfoc
|
||||
miniapps/fluids/navier/navier_turbchan
|
||||
miniapps/fluids/navier/navier_cht
|
||||
miniapps/fluids/navier/navier_bifurcation
|
||||
miniapps/fluids/navier/Navier_Bifurcation_[0-9]*
|
||||
miniapps/fluids/navier/ParaView
|
||||
miniapps/fluids/navier/tgv_out*.txt
|
||||
miniapps/fluids/navier/*_output
|
||||
miniapps/navier/navier_mms
|
||||
miniapps/navier/navier_kovasznay
|
||||
miniapps/navier/navier_kovasznay_vs
|
||||
miniapps/navier/navier_tgv
|
||||
miniapps/navier/navier_shear
|
||||
miniapps/navier/navier_3dfoc
|
||||
miniapps/navier/navier_turbchan
|
||||
miniapps/navier/navier_cht
|
||||
miniapps/navier/tgv_out*.txt
|
||||
miniapps/navier/*_output
|
||||
|
||||
miniapps/nurbs/nurbs_ex1
|
||||
miniapps/nurbs/nurbs_ex1p
|
||||
miniapps/nurbs/nurbs_ex3
|
||||
miniapps/nurbs/nurbs_ex5
|
||||
miniapps/nurbs/nurbs_ex10
|
||||
miniapps/nurbs/nurbs_ex10p
|
||||
miniapps/nurbs/nurbs_ex11p
|
||||
miniapps/nurbs/nurbs_ex24
|
||||
miniapps/nurbs/nurbs_solenoidal
|
||||
@@ -341,14 +322,7 @@ miniapps/nurbs/nurbs_naca_cmesh
|
||||
miniapps/nurbs/naca-cmesh.mesh
|
||||
miniapps/nurbs/glvis_naca-cmesh.mesh
|
||||
miniapps/nurbs/Naca_cmesh
|
||||
miniapps/nurbs/nurbs_mesh_info
|
||||
miniapps/nurbs/k*_*.dat
|
||||
miniapps/nurbs/*-Surface.mesh
|
||||
miniapps/nurbs/*.mesh
|
||||
miniapps/nurbs/*.sol
|
||||
miniapps/nurbs/deformed.*
|
||||
miniapps/nurbs/elastic_energy.*
|
||||
miniapps/nurbs/velocity.*
|
||||
|
||||
miniapps/performance/ex1
|
||||
miniapps/performance/ex1p
|
||||
@@ -370,7 +344,6 @@ miniapps/shifted/lsf_integral
|
||||
miniapps/tools/display-basis
|
||||
miniapps/tools/load-dc
|
||||
miniapps/tools/convert-dc
|
||||
miniapps/tools/compare-dc
|
||||
miniapps/tools/gridfunction-bounds
|
||||
miniapps/tools/lor-transfer
|
||||
miniapps/tools/plor-transfer
|
||||
@@ -441,13 +414,6 @@ miniapps/tribol/contact-patch-test
|
||||
miniapps/diag-smoothers/abs-l1-jacobi
|
||||
miniapps/diag-smoothers/mg-abs-l1-jacobi
|
||||
|
||||
miniapps/contact/contact
|
||||
miniapps/contact/ParaView
|
||||
|
||||
miniapps/plasma/pic/electrostatic-*
|
||||
!miniapps/plasma/pic/electrostatic-*.cpp
|
||||
miniapps/plasma/pic/*.csv
|
||||
|
||||
# Unit test binary and outputs
|
||||
tests/unit/output_meshes
|
||||
tests/unit/unit_tests
|
||||
|
||||
+70
-529
@@ -9,550 +9,91 @@
|
||||
# terms of the BSD-3 license. We welcome feedback and contributions, see file
|
||||
# CONTRIBUTING.md for details.
|
||||
|
||||
# DESCRIPTION:
|
||||
###############################################################################
|
||||
# General GitLab pipelines configurations for supercomputers and Linux clusters
|
||||
# at Lawrence Livermore National Laboratory (LLNL).
|
||||
# This entire pipeline is LLNL-specific
|
||||
#
|
||||
# Important note: This file is a template provided by llnl/radiuss-shared-ci.
|
||||
# Remains to set variable values, change the reference to the radiuss-shared-ci
|
||||
# repo, opt-in and out optional features. The project can then extend it with
|
||||
# additional stages.
|
||||
#
|
||||
# In addition, each project should copy over and complete:
|
||||
# - .gitlab/custom-jobs-and-variables.yml
|
||||
# - .gitlab/subscribed-pipelines.yml
|
||||
#
|
||||
# The jobs should be specified in a file local to the project,
|
||||
# - .gitlab/jobs/${CI_MACHINE}.yml
|
||||
# or generated (see LLNL/Umpire for an example).
|
||||
###############################################################################
|
||||
# MAP OF GITLAB CI
|
||||
#######################
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# File dependencies: direct, through jobs, through variables
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# .gitlab-ci.yml
|
||||
# ├── .build-and-test [job]
|
||||
# │ ├── .gitlab/custom-jobs-and-variables.yml
|
||||
# │ │ ├── .custom_job [job]
|
||||
# │ │ ├── .reproducer_vars [job]
|
||||
# │ │ ├── .report_job_success [job]
|
||||
# │ │ │ └── .gitlab/scripts/report_build_and_test [script]
|
||||
# │ │ │ ├── .gitlab/scripts/safe_create_rundir [script]
|
||||
# │ │ │ └── .gitlab/scripts/git_try_to_push [script]
|
||||
# │ │ ├── .report_job_failure [job]
|
||||
# │ │ │ └── .gitlab/scripts/report_build_and_test [script]
|
||||
# │ │ │ ├── .gitlab/scripts/safe_create_rundir [script]
|
||||
# │ │ │ └── .gitlab/scripts/git_try_to_push [script]
|
||||
# │ │ └── JOB_CMD [var]
|
||||
# │ │ └── tests/gitlab/build_and_test [script]
|
||||
# │ │ └── tests/gitlab/get_mfem_uberenv [script]
|
||||
# │ ├── <radiuss-shared-ci>/pipelines/matrix.yml [conditional]
|
||||
# │ │ ├── .on_matrix [job]
|
||||
# │ │ ├── .matrix_reproducer_init [job]
|
||||
# │ │ ├── .matrix_reproducer_vars [job]
|
||||
# │ │ ├── .matrix_reproducer_job [job]
|
||||
# │ │ ├── .matrix_job_command [job]
|
||||
# │ │ └── .job_on_matrix [job]
|
||||
# │ ├── <radiuss-shared-ci>/pipelines/dane.yml [conditional]
|
||||
# │ │ ├── .on_dane [job]
|
||||
# │ │ ├── .dane_reproducer_init [job]
|
||||
# │ │ ├── .dane_reproducer_vars [job]
|
||||
# │ │ ├── .dane_reproducer_job [job]
|
||||
# │ │ ├── .dane_job_command [job]
|
||||
# │ │ ├── .job_on_dane [job]
|
||||
# │ │ ├── allocate_resources [job]
|
||||
# │ │ └── release_resources [job]
|
||||
# │ ├── <radiuss-shared-ci>/pipelines/tioga.yml [conditional]
|
||||
# │ │ ├── .on_tioga [job]
|
||||
# │ │ ├── .tioga_reproducer_init [job]
|
||||
# │ │ ├── .tioga_reproducer_vars [job]
|
||||
# │ │ ├── .tioga_reproducer_job [job]
|
||||
# │ │ ├── .tioga_job_command [job]
|
||||
# │ │ ├── .job_on_tioga [job]
|
||||
# │ │ ├── allocate_resources [job]
|
||||
# │ │ └── release_resources [job]
|
||||
# │ ├── <artifact>/matrix-jobs.yml [conditional, from 'generate-job-lists']
|
||||
# │ │ ├── .gitlab/jobs/matrix.yml
|
||||
# │ │ │ ├── .matrix_reproducer_vars [job]
|
||||
# │ │ │ ├── setup [job]
|
||||
# │ │ │ │ └── ./tests/gitlab/build_and_test_setup [script]
|
||||
# │ │ │ ├── opt_mpi_cuda_gcc [job]
|
||||
# │ │ │ └── opt_mpi_cuda_hypre_cuda_gcc [job]
|
||||
# │ │ └── .gitlab/jobs/matrix-reports.yml [used conditionally]
|
||||
# │ │ ├── report_job_success
|
||||
# │ │ └── report_job_failure
|
||||
# │ ├── <artifact>/dane-jobs.yml [conditional, from 'generate-job-lists']
|
||||
# │ │ ├── .gitlab/jobs/dane.yml
|
||||
# │ │ │ ├── .dane_reproducer_vars [job]
|
||||
# │ │ │ ├── setup [job]
|
||||
# │ │ │ │ └── ./tests/gitlab/build_and_test_setup [script]
|
||||
# │ │ │ ├── debug_ser_gcc_10 [job]
|
||||
# │ │ │ ├── debug_par_gcc_10 [job]
|
||||
# │ │ │ ├── opt_ser_gcc_10 [job]
|
||||
# │ │ │ ├── opt_par_gcc_10 [job]
|
||||
# │ │ │ ├── opt_par_gcc_10_sundials [job]
|
||||
# │ │ │ ├── opt_par_gcc_10_petsc [job]
|
||||
# │ │ │ └── opt_par_gcc_10_pumi [job]
|
||||
# │ │ └── .gitlab/jobs/dane-reports.yml [used conditionally]
|
||||
# │ │ ├── report_job_success
|
||||
# │ │ └── report_job_failure
|
||||
# │ └── <artifact>/tioga-jobs.yml [conditional, from 'generate-job-lists']
|
||||
# │ ├── .gitlab/jobs/tioga.yml
|
||||
# │ │ ├── .tioga_reproducer_vars [job]
|
||||
# │ │ ├── setup [job]
|
||||
# │ │ │ └── ./tests/gitlab/build_and_test_setup [script]
|
||||
# │ │ └── cce_16_0_1 [job]
|
||||
# │ └── .gitlab/jobs/tioga-reports.yml [used conditionally]
|
||||
# │ ├── report_job_success
|
||||
# │ └── report_job_failure
|
||||
# └── .gitlab/subscribed-pipelines.yml
|
||||
# ├── .machine-check [job]
|
||||
# ├── generate-job-lists [job]
|
||||
# ├── dane-up-check [job]
|
||||
# ├── dane-build-and-test [job]
|
||||
# ├── dane-baseline [job]
|
||||
# │ └── .gitlab/dane-baseline.yml
|
||||
# │ ├── .on_dane [job]
|
||||
# │ ├── baselinecheck_mfem_intel_dane [job]
|
||||
# │ │ └── .gitlab/scripts/baseline [script]
|
||||
# │ ├── cleanup [job]
|
||||
# │ ├── report_baseline [job]
|
||||
# │ │ ├── .gitlab/scripts/safe_create_rundir [script]
|
||||
# │ │ └── .gitlab/scripts/git_try_to_push [script]
|
||||
# │ ├── baselinepublish_mfem_dane [job]
|
||||
# │ │ └── .gitlab/scripts/rebaseline [script]
|
||||
# │ ├── .gitlab/custom-jobs-and-variables.yml
|
||||
# │ │ └── <same as above: see .gitlab-ci.yml/.build-and-test>
|
||||
# │ └── .gitlab/configs/setup-baseline.yml
|
||||
# │ └── setup_baseline [job]
|
||||
# ├── tioga-up-check [job]
|
||||
# ├── tioga-build-and-test [job]
|
||||
# ├── matrix-up-check [job]
|
||||
# └── matrix-build-and-test [job]
|
||||
#
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# File tree hierarchy with file contents highlights
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# In addition to the files in the MFEM repo, the Gitlab CI uses files from the
|
||||
# radiuss/radiuss-shared-ci project, see below, after the <mfem-root> tree.
|
||||
#
|
||||
# <mfem root>
|
||||
# ├── .gitlab-ci.yml [this file]
|
||||
# │ ├── <jobs>
|
||||
# │ │ └── .build-and-test
|
||||
# │ ├── <included files>
|
||||
# │ │ ├── .gitlab/subscribed-pipelines.yml
|
||||
# │ │ ├── .gitlab/custom-jobs-and-variables.yml [by ".build-and-test"]
|
||||
# │ │ ├── <artifact> [by ".build-and-test"]
|
||||
# │ │ │ ├── artifact: '${CI_MACHINE}-jobs.yml'
|
||||
# │ │ │ └── job: 'generate-job-lists'
|
||||
# │ │ └── <external> [by ".build-and-test"]
|
||||
# │ │ ├── project: 'radiuss/radiuss-shared-ci'
|
||||
# │ │ ├── ref: 'v2025.09.1'
|
||||
# │ │ └── file: 'pipelines/${CI_MACHINE}.yml'
|
||||
# │ └── <defined variables>
|
||||
# │ ├── CUSTOM_CI_BUILDS_DIR
|
||||
# │ ├── USER_CI_TOP_DIR
|
||||
# │ ├── SHARED_REPOS_DIR
|
||||
# │ ├── AUTOTEST_ROOT
|
||||
# │ ├── MFEM_DATA_DIR
|
||||
# │ ├── AUTOTEST
|
||||
# │ ├── AUTOTEST_COMMIT
|
||||
# │ ├── REBASELINE
|
||||
# │ ├── GITHUB_PROJECT_NAME
|
||||
# │ └── GITHUB_PROJECT_ORG
|
||||
# ├── .gitlab
|
||||
# │ ├── configs
|
||||
# │ │ └── setup-baseline.yml
|
||||
# │ │ ├── <jobs>
|
||||
# │ │ │ └── setup_baseline
|
||||
# │ │ └── <used variables>
|
||||
# │ │ ├── MACHINE_NAME
|
||||
# │ │ ├── REBASELINE
|
||||
# │ │ ├── AUTOTEST
|
||||
# │ │ ├── AUTOTEST_COMMIT
|
||||
# │ │ ├── BUILD_ROOT
|
||||
# │ │ ├── TPLS_REPO
|
||||
# │ │ ├── TESTS_REPO
|
||||
# │ │ ├── AUTOTEST_ROOT
|
||||
# │ │ └── AUTOTEST_REPO
|
||||
# │ ├── jobs
|
||||
# │ │ ├── matrix-reports.yml
|
||||
# │ │ │ ├── <jobs>
|
||||
# │ │ │ │ ├── report_job_success
|
||||
# │ │ │ │ └── report_job_failure
|
||||
# │ │ │ └── <used jobs>
|
||||
# │ │ │ ├── .on_matrix
|
||||
# │ │ │ ├── .report_job_success
|
||||
# │ │ │ └── .report_job_failure
|
||||
# │ │ ├── matrix.yml
|
||||
# │ │ │ ├── <jobs>
|
||||
# │ │ │ │ ├── .matrix_reproducer_vars
|
||||
# │ │ │ │ ├── setup
|
||||
# │ │ │ │ ├── opt_mpi_cuda_gcc
|
||||
# │ │ │ │ └── opt_mpi_cuda_hypre_cuda_gcc
|
||||
# │ │ │ ├── <used jobs>
|
||||
# │ │ │ │ ├── .reproducer_vars
|
||||
# │ │ │ │ ├── .on_matrix
|
||||
# │ │ │ │ └── .job_on_matrix
|
||||
# │ │ │ ├── <included and used files>
|
||||
# │ │ │ │ └── tests/gitlab/build_and_test_setup [by "setup"]
|
||||
# │ │ │ └── <defined variables>
|
||||
# │ │ │ └── SPEC
|
||||
# │ │ ├── dane-reports.yml
|
||||
# │ │ │ ├── <jobs>
|
||||
# │ │ │ │ ├── report_job_success
|
||||
# │ │ │ │ └── report_job_failure
|
||||
# │ │ │ └── <used jobs>
|
||||
# │ │ │ ├── .on_dane
|
||||
# │ │ │ ├── .report_job_success
|
||||
# │ │ │ └── .report_job_failure
|
||||
# │ │ ├── dane.yml
|
||||
# │ │ │ ├── <jobs>
|
||||
# │ │ │ │ ├── .dane_reproducer_vars
|
||||
# │ │ │ │ ├── setup
|
||||
# │ │ │ │ ├── debug_ser_gcc_10
|
||||
# │ │ │ │ ├── debug_par_gcc_10
|
||||
# │ │ │ │ ├── opt_ser_gcc_10
|
||||
# │ │ │ │ ├── opt_par_gcc_10
|
||||
# │ │ │ │ ├── opt_par_gcc_10_sundials
|
||||
# │ │ │ │ ├── opt_par_gcc_10_petsc
|
||||
# │ │ │ │ └── opt_par_gcc_10_pumi
|
||||
# │ │ │ ├── <used jobs>
|
||||
# │ │ │ │ ├── .reproducer_vars
|
||||
# │ │ │ │ ├── .on_dane
|
||||
# │ │ │ │ └── .job_on_dane
|
||||
# │ │ │ ├── <included and used files>
|
||||
# │ │ │ │ └── tests/gitlab/build_and_test_setup [by "setup"]
|
||||
# │ │ │ └── <defined variables>
|
||||
# │ │ │ ├── SPEC
|
||||
# │ │ │ └── THREADS
|
||||
# │ │ ├── tioga-reports.yml
|
||||
# │ │ │ ├── <jobs>
|
||||
# │ │ │ │ ├── report_job_success
|
||||
# │ │ │ │ └── report_job_failure
|
||||
# │ │ │ └── <used jobs>
|
||||
# │ │ │ ├── .on_tioga
|
||||
# │ │ │ ├── .report_job_success
|
||||
# │ │ │ └── .report_job_failure
|
||||
# │ │ └── tioga.yml
|
||||
# │ │ ├── <jobs>
|
||||
# │ │ │ ├── .tioga_reproducer_vars
|
||||
# │ │ │ ├── setup
|
||||
# │ │ │ └── opt_mpi_rocm_hypre_rocm
|
||||
# │ │ ├── <used jobs>
|
||||
# │ │ │ ├── .reproducer_vars
|
||||
# │ │ │ ├── .on_tioga
|
||||
# │ │ │ └── .job_on_tioga
|
||||
# │ │ ├── <included and used files>
|
||||
# │ │ │ └── tests/gitlab/build_and_test_setup [by "setup"]
|
||||
# │ │ └── <defined variables>
|
||||
# │ │ ├── SPEC
|
||||
# │ │ └── THREADS
|
||||
# │ ├── scripts
|
||||
# │ │ ├── baseline
|
||||
# │ │ │ └── <used variables>
|
||||
# │ │ │ ├── BASELINE_TEST
|
||||
# │ │ │ ├── SYS_TYPE
|
||||
# │ │ │ ├── MACHINE_NAME
|
||||
# │ │ │ ├── CI_PROJECT_DIR
|
||||
# │ │ │ ├── ARTIFACTS_DIR
|
||||
# │ │ │ ├── BUILD_ROOT
|
||||
# │ │ │ └── TPLS_DIR
|
||||
# │ │ ├── git_try_to_push
|
||||
# │ │ ├── rebaseline
|
||||
# │ │ │ └── <used variables>
|
||||
# │ │ │ ├── CI_PROJECT_DIR
|
||||
# │ │ │ ├── ARTIFACTS_DIR
|
||||
# │ │ │ ├── SYS_TYPE
|
||||
# │ │ │ ├── BUILD_ROOT
|
||||
# │ │ │ ├── MACHINE_NAME
|
||||
# │ │ │ └── CI_PIPELINE_ID
|
||||
# │ │ ├── report_build_and_test
|
||||
# │ │ │ ├── <used files>
|
||||
# │ │ │ │ ├── .gitlab/scripts/safe_create_rundir
|
||||
# │ │ │ │ └── .gitlab/scripts/git_try_to_push
|
||||
# │ │ │ └── <used variables>
|
||||
# │ │ │ ├── AUTOTEST_ROOT
|
||||
# │ │ │ ├── CI_COMMIT_REF_SLUG
|
||||
# │ │ │ ├── CI_PROJECT_DIR
|
||||
# │ │ │ ├── CI_PIPELINE_URL
|
||||
# │ │ │ ├── AUTOTEST_COMMIT
|
||||
# │ │ │ └── CI_MACHINE
|
||||
# │ │ └── safe_create_rundir
|
||||
# │ ├── custom-jobs-and-variables.yml
|
||||
# │ │ ├── <jobs>
|
||||
# │ │ │ ├── .custom_job
|
||||
# │ │ │ ├── .reproducer_vars
|
||||
# │ │ │ ├── .report_job_success
|
||||
# │ │ │ └── .report_job_failure
|
||||
# │ │ ├── <used files>
|
||||
# │ │ │ ├── tests/gitlab/build_and_test [in JOB_CMD]
|
||||
# │ │ │ └── .gitlab/scripts/report_build_and_test [by .report_job_*]
|
||||
# │ │ ├── <defined variables>
|
||||
# │ │ │ ├── JOB_CMD
|
||||
# │ │ │ ├── BUILD_ROOT
|
||||
# │ │ │ ├── ALLOC_NAME
|
||||
# │ │ │ ├── TPLS_REPO
|
||||
# │ │ │ ├── TESTS_REPO
|
||||
# │ │ │ ├── AUTOTEST_REPO
|
||||
# │ │ │ ├── MFEM_DATA_REPO
|
||||
# │ │ │ ├── ARTIFACTS_DIR: artifacts
|
||||
# │ │ │ ├── SLURM_OVERLAP: 1
|
||||
# │ │ │ ├── DANE_SHARED_ALLOC
|
||||
# │ │ │ ├── DANE_JOB_ALLOC
|
||||
# │ │ │ ├── TIOGA_SHARED_ALLOC
|
||||
# │ │ │ ├── TIOGA_JOB_ALLOC
|
||||
# │ │ │ └── MATRIX_JOB_ALLOC
|
||||
# │ │ └── <used variables>
|
||||
# │ │ ├── SPEC
|
||||
# │ │ ├── BUILD_ROOT
|
||||
# │ │ └── ...
|
||||
# │ ├── dane-baseline.yml
|
||||
# │ │ ├── <jobs>
|
||||
# │ │ │ ├── .on_dane
|
||||
# │ │ │ ├── baselinecheck_mfem_intel_dane
|
||||
# │ │ │ ├── cleanup
|
||||
# │ │ │ ├── report_baseline
|
||||
# │ │ │ └── baselinepublish_mfem_dane
|
||||
# │ │ ├── <included and used files>
|
||||
# │ │ │ ├── .gitlab/custom-jobs-and-variables.yml
|
||||
# │ │ │ ├── .gitlab/configs/setup-baseline.yml
|
||||
# │ │ │ ├── .gitlab/scripts/rebaseline
|
||||
# │ │ │ ├── .gitlab/scripts/baseline
|
||||
# │ │ │ └── .gitlab/scripts/git_try_to_push
|
||||
# │ │ ├── <defined variables>
|
||||
# │ │ │ ├── BASELINE_TEST: baseline
|
||||
# │ │ │ ├── MACHINE_NAME: dane
|
||||
# │ │ │ ├── TPLS_DIR
|
||||
# │ │ │ └── export MFEM_TEST_NP
|
||||
# │ │ └── <used variables>
|
||||
# │ │ ├── ON_DANE
|
||||
# │ │ ├── AUTOTEST [defined by .gitlab-ci.yml]
|
||||
# │ │ ├── BUILD_ROOT [defined by custom-jobs-and-variables.yml]
|
||||
# │ │ ├── TPLS_DIR [defined by this file]
|
||||
# │ │ ├── ARTIFACTS_DIR [defined by custom-jobs-and-variables.yml]
|
||||
# │ │ ├── MACHINE_NAME [defined by this file]
|
||||
# │ │ ├── AUTOTEST_COMMIT [defined by .gitlab-ci.yml]
|
||||
# │ │ ├── AUTOTEST_ROOT [defined by .gitlab-ci.yml]
|
||||
# │ │ ├── BASELINE_TEST [defined by this file]
|
||||
# │ │ └── REBASELINE [defined by .gitlab-ci.yml]
|
||||
# │ └── subscribed-pipelines.yml
|
||||
# │ ├── <jobs>
|
||||
# │ │ ├── .machine-check
|
||||
# │ │ ├── generate-job-lists
|
||||
# │ │ ├── dane-up-check
|
||||
# │ │ ├── dane-build-and-test
|
||||
# │ │ ├── dane-baseline
|
||||
# │ │ ├── tioga-up-check
|
||||
# │ │ ├── tioga-build-and-test
|
||||
# │ │ ├── matrix-up-check
|
||||
# │ │ └── matrix-build-and-test
|
||||
# │ ├── <used jobs>
|
||||
# │ │ └── .build-and-test [from ".gitlab-ci.yml"]
|
||||
# │ ├── <included files>
|
||||
# │ │ └── .gitlab/dane-baseline.yml [by "dane-baseline"]
|
||||
# │ └── <used variables>
|
||||
# │ ├── GITHUB_PROJECT_ORG
|
||||
# │ ├── GITHUB_PROJECT_NAME
|
||||
# │ ├── AUTOTEST
|
||||
# │ ├── AUTOTEST_COMMIT
|
||||
# │ └── REBASELINE
|
||||
# └── tests
|
||||
# ├── gitlab
|
||||
# │ ├── build_and_test
|
||||
# │ │ ├── <builds and tests a given MFEM spec with uberenv>
|
||||
# │ │ ├── <used files>
|
||||
# │ │ │ ├── tests/uberenv/uberenv.py [deps mode, cloned]
|
||||
# │ │ │ └── tests/gitlab/get_mfem_uberenv [deps mode]
|
||||
# │ │ └── <used variables>
|
||||
# │ │ ├── SYS_TYPE
|
||||
# │ │ ├── THREADS [num. parallel jobs to build MFEM]
|
||||
# │ │ ├── MODULE_LIST [modules to load]
|
||||
# │ │ ├── CI_JOB_ID
|
||||
# │ │ ├── USE_DEV_SHM
|
||||
# │ │ ├── SPACK_DEBUG
|
||||
# │ │ ├── DEBUG_MODE
|
||||
# │ │ ├── REGISTRY_TOKEN
|
||||
# │ │ ├── CI_REGISTRY_USER (defined by Gitlab)
|
||||
# │ │ ├── USER
|
||||
# │ │ ├── CI_REGISTRY_IMAGE (defined by Gitlab)
|
||||
# │ │ └── CI_JOB_TOKEN (defined by Gitlab)
|
||||
# │ ├── build_and_test_setup
|
||||
# │ │ ├── <updates MFEM_DATA_REPO and AUTOTEST_REPO using locks>
|
||||
# │ │ └── <used variables>
|
||||
# │ │ ├── MFEM_DATA_REPO
|
||||
# │ │ ├── SHARED_REPOS_DIR
|
||||
# │ │ ├── AUTOTEST_REPO
|
||||
# │ │ └── AUTOTEST_ROOT
|
||||
# │ └── get_mfem_uberenv
|
||||
# │ ├── <github.com/mfem/mfem-uberenv.git -> tests/uberenv>
|
||||
# │ └── <defines the uberenv hash to use>
|
||||
# └── uberenv [cloned by tests/gitlab/get_mfem_uberenv]
|
||||
# └── uberenv.py
|
||||
#
|
||||
# <root of radiuss/radiuss-shared-ci, ref: 'v2025.09.1'>
|
||||
# └── pipelines
|
||||
# ├── matrix.yml
|
||||
# │ ├── <jobs>
|
||||
# │ │ ├── .on_matrix
|
||||
# │ │ ├── .matrix_reproducer_init
|
||||
# │ │ ├── .matrix_reproducer_vars
|
||||
# │ │ ├── .matrix_reproducer_job
|
||||
# │ │ ├── .matrix_job_command
|
||||
# │ │ └── .job_on_matrix
|
||||
# │ ├── <used jobs>
|
||||
# │ │ └── .custom_job [from .gitlab/custom-jobs-and-variables.yml]
|
||||
# │ └── <used variables>
|
||||
# │ ├── ON_MATRIX
|
||||
# │ ├── ADVANCED_JOB
|
||||
# │ ├── ALL_TARGETS
|
||||
# │ ├── SYS_TYPE
|
||||
# │ ├── LLNL_SERVICE_USER
|
||||
# │ ├── USER
|
||||
# │ ├── GITHUB_PROJECT_NAME
|
||||
# │ ├── GITHUB_PROJECT_ORG
|
||||
# │ ├── MATRIX_JOB_ALLOC
|
||||
# │ └── JOB_CMD
|
||||
# ├── dane.yml
|
||||
# │ ├── <jobs>
|
||||
# │ │ ├── .on_dane
|
||||
# │ │ ├── .dane_reproducer_init
|
||||
# │ │ ├── .dane_reproducer_vars
|
||||
# │ │ ├── .dane_reproducer_job
|
||||
# │ │ ├── .dane_job_command
|
||||
# │ │ ├── .job_on_dane
|
||||
# │ │ ├── allocate_resources
|
||||
# │ │ └── release_resources
|
||||
# │ ├── <used jobs>
|
||||
# │ │ └── .custom_job [from .gitlab/custom-jobs-and-variables.yml]
|
||||
# │ ├── <defined variables>
|
||||
# │ │ └── export JOBID
|
||||
# │ └── <used variables>
|
||||
# │ ├── ON_DANE
|
||||
# │ ├── ADVANCED_JOB
|
||||
# │ ├── ALL_TARGETS
|
||||
# │ ├── SYS_TYPE
|
||||
# │ ├── LLNL_SERVICE_USER
|
||||
# │ ├── USER
|
||||
# │ ├── GITHUB_PROJECT_NAME
|
||||
# │ ├── GITHUB_PROJECT_ORG
|
||||
# │ ├── DANE_JOB_ALLOC
|
||||
# │ ├── JOB_CMD
|
||||
# │ ├── JOBID
|
||||
# │ ├── ALLOC_NAME
|
||||
# │ └── DANE_SHARED_ALLOC
|
||||
# └── tioga.yml
|
||||
# ├── <jobs>
|
||||
# │ ├── .on_tioga
|
||||
# │ ├── .tioga_reproducer_init
|
||||
# │ ├── .tioga_reproducer_vars
|
||||
# │ ├── .tioga_reproducer_job
|
||||
# │ ├── .tioga_job_command
|
||||
# │ ├── .job_on_tioga
|
||||
# │ ├── allocate_resources
|
||||
# │ └── release_resources
|
||||
# ├── <used jobs>
|
||||
# │ └── .custom_job [from .gitlab/custom-jobs-and-variables.yml]
|
||||
# ├── <defined variables>
|
||||
# │ └── PROXY
|
||||
# └── <used variables>
|
||||
# ├── ON_TIOGA
|
||||
# ├── ADVANCED_JOB
|
||||
# ├── ALL_TARGETS
|
||||
# ├── SYS_TYPE
|
||||
# ├── LLNL_SERVICE_USER
|
||||
# ├── USER
|
||||
# ├── GITHUB_PROJECT_NAME
|
||||
# ├── GITHUB_PROJECT_ORG
|
||||
# ├── TIOGA_JOB_ALLOC
|
||||
# ├── JOB_CMD
|
||||
# ├── PROXY
|
||||
# ├── ALLOC_NAME
|
||||
# └── TIOGA_SHARED_ALLOC
|
||||
# at Lawrence Livermore National Laboratory (LLNL). This entire pipeline is
|
||||
# LLNL-specific!
|
||||
|
||||
include:
|
||||
- project: 'lc-templates/id_tokens'
|
||||
file: 'id_tokens.yml'
|
||||
|
||||
# The pipeline is divided into stages. Usually, jobs in a given stage wait for
|
||||
# the preceding stages to complete before to start. However, we sometimes use
|
||||
# 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.
|
||||
# - 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
|
||||
# results
|
||||
stages:
|
||||
- sub-pipelines
|
||||
|
||||
###############################################################################
|
||||
# We define the following GitLab pipeline variables:
|
||||
variables:
|
||||
##### LC GITLAB CONFIGURATION
|
||||
CUSTOM_CI_BUILDS_DIR: "/usr/workspace/mfem/gitlab-runner"
|
||||
|
||||
##### PROJECT VARIABLES
|
||||
USER_CI_TOP_DIR: "${CUSTOM_CI_BUILDS_DIR}/${GITLAB_USER_LOGIN}"
|
||||
SHARED_REPOS_DIR: "${USER_CI_TOP_DIR}/repos"
|
||||
AUTOTEST_ROOT: "${SHARED_REPOS_DIR}"
|
||||
# MFEM_DATA_DIR is setup in '.gitlab/configs/setup-build-and-test.yml' and
|
||||
# used in '.gitlab/configs/<machine>-config.yml':
|
||||
MFEM_DATA_DIR: "${SHARED_REPOS_DIR}/mfem-data"
|
||||
# AUTOTEST: enable (ON/YES) or disable (any other value) test reporting. See
|
||||
# also AUTOTEST_COMMIT.
|
||||
AUTOTEST: "OFF"
|
||||
# AUTOTEST_COMMIT: used only when AUTOTEST is set to ON/YES.
|
||||
# * If AUTOTEST_COMMIT is set to ON/YES, reporting jobs will commit their
|
||||
# files to the MFEM/autotest repo.
|
||||
# * If AUTOTEST_COMMIT is NOT set to ON/YES, reporting jobs will NOT commit
|
||||
# their files to the MFEM/autotest repo. Instead they will just show the
|
||||
# contents of the report files and remove them.
|
||||
AUTOTEST_COMMIT: "ON"
|
||||
# REBASELINE:
|
||||
|
||||
# Defines the default choice for updating the saved baseline results. By default
|
||||
# the baseline can only be updated from the master branch. This variable offers
|
||||
# the option to manually ask for rebaselining from another branch if necessary.
|
||||
REBASELINE: "OFF"
|
||||
REBASELINE: "NO"
|
||||
AUTOTEST: "NO"
|
||||
# AUTOTEST_COMMIT: used only when AUTOTEST is set to YES.
|
||||
# * If AUTOTEST_COMMIT is NOT set to NO, reporting jobs will commit their
|
||||
# files to the MFEM/autotest repo.
|
||||
# * If AUTOTEST_COMMIT is set to NO, reporting jobs will NOT commit their
|
||||
# files to the MFEM/autotest repo. Instead they will just show the contents
|
||||
# of the report files and remove them.
|
||||
AUTOTEST_COMMIT: "YES"
|
||||
|
||||
##### SHARED_CI CONFIGURATION
|
||||
# Required information about GitHub repository
|
||||
GITHUB_PROJECT_NAME: "mfem"
|
||||
GITHUB_PROJECT_ORG: "MFEM"
|
||||
# Override the pattern describing branches that will skip the "draft PR filter
|
||||
# test". Add protected branches here. See default value in
|
||||
# preliminary-ignore-draft-pr.yml.
|
||||
# ALWAYS_RUN_PATTERN: ""
|
||||
|
||||
###############################################################################
|
||||
##### High level stages
|
||||
# We organize the test-pipelines stage with sub-pipelines. Each sub-pipeline
|
||||
# corresponds to a test batch on a given machine.
|
||||
stages:
|
||||
- prerequisites
|
||||
- test-pipelines
|
||||
|
||||
###############################################################################
|
||||
# Template for jobs triggering a build-and-test sub-pipeline:
|
||||
.build-and-test:
|
||||
stage: test-pipelines
|
||||
# Trigger subpipelines:
|
||||
dane-build-and-test:
|
||||
stage: sub-pipelines
|
||||
variables:
|
||||
# Explicitly pass down values that are not always propagated to child
|
||||
# pipelines, e.g. when a variable is set in the "Settings -> CI" web
|
||||
# interface (project variables).
|
||||
# Note: in some cases, this does not work as expected, e.g. when the
|
||||
# variable is not re-defined in the web interface; in such cases, the child
|
||||
# pipeline gets a definition like '${AUTOTEST}', i.e. it behaves as if
|
||||
# AUTOTEST is undefined, even though there is a default value in
|
||||
# .gitlab-ci.yml.
|
||||
# Explicitly pass down values that we want to be able to set when triggering
|
||||
# pipelines manually or using scheduling
|
||||
AUTOTEST: "${AUTOTEST}"
|
||||
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
|
||||
trigger:
|
||||
include:
|
||||
- local: '.gitlab/custom-jobs-and-variables.yml'
|
||||
- project: 'radiuss/radiuss-shared-ci'
|
||||
ref: 'v2025.09.1'
|
||||
file: 'pipelines/${CI_MACHINE}.yml'
|
||||
- artifact: '${CI_MACHINE}-jobs.yml'
|
||||
job: 'generate-job-lists'
|
||||
include: .gitlab/dane-build-and-test.yml
|
||||
strategy: depend
|
||||
forward:
|
||||
pipeline_variables: true
|
||||
|
||||
###############################################################################
|
||||
include:
|
||||
# Sets ID tokens for every job using `default:`
|
||||
- project: 'lc-templates/id_tokens'
|
||||
file: 'id_tokens.yml'
|
||||
# [Optional] checks preliminary to running the actual CI test
|
||||
#- project: 'radiuss/radiuss-shared-ci'
|
||||
# ref: 'v2025.09.1'
|
||||
# file: 'preliminary-ignore-draft-pr.yml'
|
||||
# pipelines subscribed by the project
|
||||
- local: '.gitlab/subscribed-pipelines.yml'
|
||||
dane-baseline:
|
||||
stage: sub-pipelines
|
||||
variables:
|
||||
# Explicitly pass down values that we want to be able to set when triggering
|
||||
# pipelines manually or using scheduling
|
||||
REBASELINE: "${REBASELINE}"
|
||||
AUTOTEST: "${AUTOTEST}"
|
||||
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
|
||||
trigger:
|
||||
include: .gitlab/dane-baseline.yml
|
||||
strategy: depend
|
||||
|
||||
lassen-build-and-test:
|
||||
stage: sub-pipelines
|
||||
variables:
|
||||
# Explicitly pass down values that we want to be able to set when triggering
|
||||
# pipelines manually or using scheduling
|
||||
AUTOTEST: "${AUTOTEST}"
|
||||
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
|
||||
trigger:
|
||||
include: .gitlab/lassen-build-and-test.yml
|
||||
strategy: depend
|
||||
|
||||
corona-build-and-test:
|
||||
stage: sub-pipelines
|
||||
variables:
|
||||
# Explicitly pass down values that we want to be able to set when triggering
|
||||
# pipelines manually or using scheduling
|
||||
AUTOTEST: "${AUTOTEST}"
|
||||
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
|
||||
trigger:
|
||||
include: .gitlab/corona-build-and-test.yml
|
||||
strategy: depend
|
||||
|
||||
+12
-34
@@ -15,9 +15,9 @@ and nightly testing on GitLab.
|
||||
|
||||
## Top level
|
||||
|
||||
The root configuration file is `.gitlab-ci.yml` at the root of MFEM repo. This
|
||||
file only defines three stages, a prerequisites one, and two main stages in
|
||||
which we trigger several sub-pipelines.
|
||||
The root configuration file is `.gitlab-ci.yml` at the root of MFEM repo.
|
||||
This file only defines one stage, in which we trigger several
|
||||
sub-pipelines.
|
||||
|
||||
We use sub-pipelines to isolate the test for one combination of `machine`
|
||||
and `test type`.
|
||||
@@ -25,8 +25,8 @@ and `test type`.
|
||||
Machines typically include:
|
||||
|
||||
* Dane: Intel Sapphire Rapids
|
||||
* Matrix: Intel Sapphire Rapids + Nvidia H100 GPU
|
||||
* Tioga: AMD MI250X GPU
|
||||
* Lassen: Power9 + Nvidia GPU
|
||||
* Corona: AMD GPU
|
||||
|
||||
Test types include:
|
||||
|
||||
@@ -39,31 +39,9 @@ altering the scheduling, execution and displaying of the others.
|
||||
|
||||
## Sub-pipelines
|
||||
|
||||
### build-and-test
|
||||
|
||||
The build-and-test sub-pipelines leverage RADIUSS Shared CI to share most of
|
||||
the CI implementation. RADIUSS Shared CI provides a shared CI infrastructure
|
||||
vetted on most LC systems of interest and efficiently leveraging each machine
|
||||
scheduler to increase CI throughput. The maintenance of RADIUSS Shared CI is
|
||||
shared among several RADIUSS projects.
|
||||
|
||||
Jobs for the build-and-test sub-pipelines are defined in the jobs directory.
|
||||
Because build-and-test jobs leverage Uberenv and Spack to build the
|
||||
dependencies automatically, the jobs essentially consists in a `spack spec`
|
||||
defined in the jobs files, and some scheduling parameters defined in the
|
||||
`.gitlab/custom-jobs-and-variables.yml` file.
|
||||
|
||||
Build-and-test jobs all run the `tests/gitlab/build_and_test` script.
|
||||
|
||||
The build-and-test pipelines are controlled by the
|
||||
`.gitlab/subscribed-pipelines.yml` which defines which machines to run on and
|
||||
implements additional features like machine availability check, and job list
|
||||
generation.
|
||||
|
||||
### baseline
|
||||
|
||||
Baseline sub-pipelines are described by files with names reflecting the
|
||||
machine it runs on, e.g. `dane-baseline`.
|
||||
Each file is this directory is the root configuration file for one
|
||||
sub-pipeline. The naming reflects the corresponding couple (`machine`,
|
||||
`test_type`).
|
||||
|
||||
Those files define the *stages* and the *jobs* for the sub-pipeline. They
|
||||
also contain any configuration that cannot be shared. For the most part
|
||||
@@ -85,11 +63,11 @@ usage function. This should be improved.
|
||||
|
||||
# More testing
|
||||
|
||||
## Adding a new target to a build-and-test pipeline
|
||||
## Adding a new target to a build_and_test pipeline
|
||||
|
||||
`build-and-test` pipelines rely on Spack to install dependencies. Spack is
|
||||
`build_and_test` pipelines rely on Spack to install dependencies. Spack is
|
||||
driven by Uberenv which helps freezing Spack configuration: the goal being to
|
||||
point to a specific commit in Spack and isolate its configuration so that it is
|
||||
point to specific commit in Spack and isolate its configuration so that it is
|
||||
not influenced by the user environment. More documentation about this can be
|
||||
found in `tests/gitlab`.
|
||||
|
||||
@@ -104,7 +82,7 @@ spack spec to use. Adding a job on Dane for example resumes to:
|
||||
<job_name>:
|
||||
variables:
|
||||
SPEC: "<spack_spec>"
|
||||
extends: .job_on_dane
|
||||
extends: .build_and_test_on_dane
|
||||
```
|
||||
|
||||
The remaining and non trivial work is to make sure this spec is working. To
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# 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.
|
||||
|
||||
include:
|
||||
- project: 'lc-templates/id_tokens'
|
||||
file: 'id_tokens.yml'
|
||||
|
||||
# We define the following GitLab pipeline variables:
|
||||
variables:
|
||||
|
||||
# The path to the shared resource between all jobs. For example, external
|
||||
# repositories like 'tests' and 'tpls' are cloned here. Also, 'tpls' is built
|
||||
# once for all targets, so that build happen here. The BUILD_ROOT is unique to
|
||||
# the pipeline, preventing any form of concurrency with other pipelines. This
|
||||
# also means that the BUILD_ROOT directory will never be cleaned.
|
||||
# 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
|
||||
# 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}
|
||||
|
||||
# Git repositories used in the pipeline
|
||||
TPLS_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/tpls.git
|
||||
TESTS_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/tests.git
|
||||
AUTOTEST_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/autotest.git
|
||||
MFEM_DATA_REPO: https://github.com/mfem/data.git
|
||||
|
||||
# Directory used to place artifacts.
|
||||
ARTIFACTS_DIR: artifacts
|
||||
SLURM_OVERLAP: 1
|
||||
@@ -0,0 +1,59 @@
|
||||
# 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.
|
||||
|
||||
# GitLab pipeline configuration for the Corona machine at LLNL
|
||||
variables:
|
||||
MACHINE_NAME: corona
|
||||
|
||||
.on_corona:
|
||||
tags:
|
||||
- shell
|
||||
- corona
|
||||
rules:
|
||||
# Don't run corona jobs if...
|
||||
# Note: This makes corona an "opt-in" machine. To activate builds on corona
|
||||
# for a given GitLab clone of MFEM, go to Setting/CI-CD/variables, and set
|
||||
# "ON_CORONA" to "ON". An LC account on for corona is required to trigger a
|
||||
# pipeline there.
|
||||
- if: '$CI_COMMIT_BRANCH =~ /_cnone/ || $ON_CORONA != "ON"'
|
||||
when: never
|
||||
# Don't run autotest update if...
|
||||
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "YES"'
|
||||
when: never
|
||||
# Report success on success status
|
||||
- if: '$CI_JOB_NAME =~ /report_job_success/ && $AUTOTEST == "YES"'
|
||||
when: on_success
|
||||
# Report failure on failure status
|
||||
- if: '$CI_JOB_NAME =~ /report_job_failure/ && $AUTOTEST == "YES"'
|
||||
when: on_failure
|
||||
# Always release resource
|
||||
- if: '$CI_JOB_NAME =~ /release_resource/'
|
||||
when: always
|
||||
# Always cleanup
|
||||
- if: '$CI_JOB_NAME =~ /cleanup/'
|
||||
when: always
|
||||
# Default is to run if previous stage succeeded
|
||||
- when: on_success
|
||||
|
||||
# Spack helped builds
|
||||
# Generic corona build job, extending build script
|
||||
.build_and_test_on_corona:
|
||||
extends: [.on_corona]
|
||||
stage: build_and_test
|
||||
script:
|
||||
# THREADS is used by 'tests/gitlab/build_and_test', run below
|
||||
- export THREADS=12
|
||||
- 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}" ) -t 15 -N 1 tests/gitlab/build_and_test --spec "${SPEC}" --data-dir "${MFEM_DATA_DIR}" --data
|
||||
@@ -0,0 +1,56 @@
|
||||
# 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.
|
||||
|
||||
# GitLab pipelines configurations for the Dane machine at LLNL
|
||||
variables:
|
||||
MACHINE_NAME: dane
|
||||
|
||||
.on_dane:
|
||||
tags:
|
||||
- shell
|
||||
- dane
|
||||
rules:
|
||||
# Don't run dane jobs if...
|
||||
- if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_DANE == "OFF"'
|
||||
when: never
|
||||
# Don't run autotest update if...
|
||||
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "YES"'
|
||||
when: never
|
||||
# Report success on success status
|
||||
- if: '$CI_JOB_NAME =~ /report_job_success/ && $AUTOTEST == "YES"'
|
||||
when: on_success
|
||||
# Report failure on failure status
|
||||
- if: '$CI_JOB_NAME =~ /report_job_failure/ && $AUTOTEST == "YES"'
|
||||
when: on_failure
|
||||
# Always release resource
|
||||
- if: '$CI_JOB_NAME =~ /release_resource/'
|
||||
when: always
|
||||
# Always cleanup
|
||||
- if: '$CI_JOB_NAME =~ /cleanup/'
|
||||
when: always
|
||||
# Default is to run if previous stage succeeded
|
||||
- when: on_success
|
||||
|
||||
# Spack helped builds
|
||||
# Generic dane build job, extending build script
|
||||
.build_and_test_on_dane:
|
||||
extends: [.on_dane]
|
||||
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
|
||||
- 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
|
||||
@@ -0,0 +1,48 @@
|
||||
# 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.
|
||||
|
||||
# GitLab pipelines configurations for the Lassen machine at LLNL
|
||||
variables:
|
||||
MACHINE_NAME: lassen
|
||||
|
||||
.on_lassen:
|
||||
tags:
|
||||
- shell
|
||||
- lassen
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH =~ /_lnone/ || $ON_LASSEN == "OFF"' #run except if ...
|
||||
when: never
|
||||
# Don't run autotest update if...
|
||||
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "YES"'
|
||||
when: never
|
||||
# Report success on success status
|
||||
- if: '$CI_JOB_NAME =~ /report_job_success/ && $AUTOTEST == "YES"'
|
||||
when: on_success
|
||||
# Report failure on failure status
|
||||
- if: '$CI_JOB_NAME =~ /report_job_failure/ && $AUTOTEST == "YES"'
|
||||
when: on_failure
|
||||
# Always cleanup
|
||||
- if: '$CI_JOB_NAME =~ /cleanup/'
|
||||
when: always
|
||||
- when: on_success
|
||||
|
||||
# Lassen uses a different job scheduler (spectrum lsf) that does not allow
|
||||
# pre-allocation the same way slurm does. We use the pci queue on lassen
|
||||
# to speed-up the allocation.
|
||||
.build_and_test_on_lassen:
|
||||
extends: [.on_lassen]
|
||||
stage: build_and_test
|
||||
script:
|
||||
- echo ${MFEM_DATA_DIR}
|
||||
- echo ${SPEC}
|
||||
# Next script uses 'THREADS': leaving it empty --> it uses 'make all -j'
|
||||
- lalloc 1 -W 45 -q pci --atsdisable tests/gitlab/build_and_test --spec "${SPEC}" --data-dir "${MFEM_DATA_DIR}" --data
|
||||
needs: [setup]
|
||||
@@ -0,0 +1,77 @@
|
||||
# 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.
|
||||
|
||||
# Jobs report
|
||||
.report_job_success:
|
||||
script:
|
||||
- echo ${MACHINE_NAME}
|
||||
- echo ${AUTOTEST}
|
||||
- echo ${AUTOTEST_COMMIT}
|
||||
- echo "AUTOTEST_ROOT ${AUTOTEST_ROOT}"
|
||||
- cd ${AUTOTEST_ROOT}
|
||||
- |
|
||||
(
|
||||
date
|
||||
echo "Waiting to acquire lock on '$PWD/autotest.lock' ..."
|
||||
# try to get an exclusive lock on fd 9 (autotest.lock) repeating the try
|
||||
# every 5 seconds; we may want to add a counter for the number of
|
||||
# retries to interrupt a potential infinite loop
|
||||
while ! flock -n 9; do
|
||||
sleep 5
|
||||
done
|
||||
echo "Acquired lock on '$PWD/autotest.lock'"
|
||||
date
|
||||
# Report SUCCESS while holding the file lock on 'autotest.lock'.
|
||||
# The next script uses the following environment variables:
|
||||
# - MACHINE_NAME, AUTOTEST_ROOT, AUTOTEST_COMMIT
|
||||
# - CI_COMMIT_REF_SLUG, CI_PROJECT_DIR, CI_PIPELINE_URL
|
||||
# It also calls the script '.gitlab/scripts/safe_create_rundir'.
|
||||
${CI_PROJECT_DIR}/.gitlab/scripts/report_build_and_test_success
|
||||
err=$?
|
||||
# sleep for a period to allow NFS to propagate the above changes;
|
||||
# clearly, there is no guarantee that other NFS clients will see the
|
||||
# changes even after the timeout
|
||||
sleep 10
|
||||
exit $err
|
||||
) 9> autotest.lock
|
||||
|
||||
.report_job_failure:
|
||||
script:
|
||||
- echo ${MACHINE_NAME}
|
||||
- echo ${AUTOTEST}
|
||||
- echo ${AUTOTEST_COMMIT}
|
||||
- echo "AUTOTEST_ROOT ${AUTOTEST_ROOT}"
|
||||
- cd ${AUTOTEST_ROOT}
|
||||
- |
|
||||
(
|
||||
date
|
||||
echo "Waiting to acquire lock on '$PWD/autotest.lock' ..."
|
||||
# try to get an exclusive lock on fd 9 (autotest.lock) repeating the try
|
||||
# every 5 seconds; we may want to add a counter for the number of
|
||||
# retries to interrupt a potential infinite loop
|
||||
while ! flock -n 9; do
|
||||
sleep 5
|
||||
done
|
||||
echo "Acquired lock on '$PWD/autotest.lock'"
|
||||
date
|
||||
# Report FAILURE while holding the file lock on 'autotest.lock'.
|
||||
# The next script uses the following environment variables:
|
||||
# - MACHINE_NAME, AUTOTEST_ROOT, AUTOTEST_COMMIT
|
||||
# - CI_COMMIT_REF_SLUG, CI_PROJECT_DIR, CI_PIPELINE_URL
|
||||
# It also calls the script '.gitlab/scripts/safe_create_rundir'.
|
||||
${CI_PROJECT_DIR}/.gitlab/scripts/report_build_and_test_failure
|
||||
err=$?
|
||||
# sleep for a period to allow NFS to propagate the above changes;
|
||||
# clearly, there is no guarantee that other NFS clients will see the
|
||||
# changes even after the timeout
|
||||
sleep 10
|
||||
exit $err
|
||||
) 9> autotest.lock
|
||||
@@ -0,0 +1,90 @@
|
||||
# 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.
|
||||
|
||||
# Setup clones the mfem/data repo in ${SHARED_REPOS_DIR}. The build_and_test
|
||||
# script then symlinks the repo to the parent directory of the MFEM source
|
||||
# directory. Unit tests that depend on the mfem/data repo will then detect that
|
||||
# this directory is present and be enabled.
|
||||
setup:
|
||||
tags:
|
||||
- shell
|
||||
- dane
|
||||
stage: setup
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
script:
|
||||
#
|
||||
# Setup MFEM_DATA_DIR=${SHARED_REPOS_DIR}/mfem-data, see '.gitlab-ci.yml'
|
||||
# and '.gitlab/configs/<machine>-config.yml'
|
||||
#
|
||||
- echo "MACHINE_NAME = ${MACHINE_NAME}"
|
||||
- echo "AUTOTEST = ${AUTOTEST}"
|
||||
- echo "AUTOTEST_COMMIT = ${AUTOTEST_COMMIT}"
|
||||
- echo "SHARED_REPOS_DIR ${SHARED_REPOS_DIR}"
|
||||
- mkdir -p ${SHARED_REPOS_DIR} && cd ${SHARED_REPOS_DIR}
|
||||
- command -v flock || echo "Required command 'flock' not found"
|
||||
- |
|
||||
(
|
||||
date
|
||||
echo "Waiting to acquire lock on '$PWD/mfem-data.lock' ..."
|
||||
# try to get an exclusive lock on fd 9 (mfem-data.lock) repeating the
|
||||
# try every 5 seconds; we may want to add a counter for the number of
|
||||
# retries to interrupt a potential infinite loop
|
||||
while ! flock -n 9; do
|
||||
sleep 5
|
||||
done
|
||||
echo "Acquired lock on '$PWD/mfem-data.lock'"
|
||||
date
|
||||
# clone/update the mfem/data repo while holding the file lock on
|
||||
# 'mfem-data.lock'
|
||||
err=0
|
||||
if [[ ! -d "mfem-data" ]]; then
|
||||
git clone ${MFEM_DATA_REPO} "mfem-data"
|
||||
else
|
||||
cd "mfem-data" && git pull && cd ..
|
||||
fi || err=1
|
||||
# sleep for a period to allow NFS to propagate the above changes;
|
||||
# clearly, there is no guarantee that other NFS clients will see the
|
||||
# changes even after the timeout
|
||||
sleep 10
|
||||
exit $err
|
||||
) 9> mfem-data.lock
|
||||
#
|
||||
# Setup ${AUTOTEST_ROOT}/autotest:
|
||||
#
|
||||
- echo "AUTOTEST_ROOT ${AUTOTEST_ROOT}"
|
||||
- mkdir -p ${AUTOTEST_ROOT} && cd ${AUTOTEST_ROOT}
|
||||
- |
|
||||
(
|
||||
date
|
||||
echo "Waiting to acquire lock on '$PWD/autotest.lock' ..."
|
||||
# try to get an exclusive lock on fd 9 (autotest.lock) repeating the try
|
||||
# every 5 seconds; we may want to add a counter for the number of
|
||||
# retries to interrupt a potential infinite loop
|
||||
while ! flock -n 9; do
|
||||
sleep 5
|
||||
done
|
||||
echo "Acquired lock on '$PWD/autotest.lock'"
|
||||
date
|
||||
# clone/update the autotest repo while holding the file lock on
|
||||
# 'autotest.lock'
|
||||
err=0
|
||||
if [[ ! -d "autotest" ]]; then
|
||||
git clone ${AUTOTEST_REPO}
|
||||
else
|
||||
cd autotest && git pull && cd ..
|
||||
fi || err=1
|
||||
# sleep for a period to allow NFS to propagate the above changes;
|
||||
# clearly, there is no guarantee that other NFS clients will see the
|
||||
# changes even after the timeout
|
||||
sleep 10
|
||||
exit $err
|
||||
) 9> autotest.lock
|
||||
@@ -0,0 +1,67 @@
|
||||
# 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.
|
||||
|
||||
stages:
|
||||
- setup
|
||||
- allocate_resource
|
||||
- build_and_test
|
||||
- release_resource_and_report
|
||||
|
||||
# Slurm shared allocation
|
||||
allocate_resource:
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
extends: .on_corona
|
||||
stage: allocate_resource
|
||||
script:
|
||||
- echo ${ALLOC_NAME}
|
||||
- salloc --exclusive --nodes=1 --partition=mi60 --time=45 --no-shell --job-name=${ALLOC_NAME}
|
||||
timeout: 6h
|
||||
needs: [setup]
|
||||
|
||||
# Build and test jobs, simply provide a spec
|
||||
rocm_gcc_8.3.1:
|
||||
variables:
|
||||
SPEC: "@develop%gcc@8.3.1+rocm amdgpu_target=gfx906"
|
||||
extends: .build_and_test_on_corona
|
||||
needs: [allocate_resource]
|
||||
|
||||
# Release slurm allocation
|
||||
release_resource:
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
extends: .on_corona
|
||||
stage: release_resource_and_report
|
||||
script:
|
||||
- echo ${ALLOC_NAME}
|
||||
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
|
||||
- echo ${JOBID}
|
||||
- ([[ -n "${JOBID}" ]] && scancel ${JOBID})
|
||||
needs: [rocm_gcc_8.3.1]
|
||||
|
||||
# Jobs report
|
||||
report_job_success:
|
||||
stage: release_resource_and_report
|
||||
extends:
|
||||
- .on_corona
|
||||
- .report_job_success
|
||||
|
||||
report_job_failure:
|
||||
stage: release_resource_and_report
|
||||
extends:
|
||||
- .on_corona
|
||||
- .report_job_failure
|
||||
|
||||
include:
|
||||
- local: .gitlab/configs/common.yml
|
||||
- local: .gitlab/configs/corona-config.yml
|
||||
- local: .gitlab/configs/setup-build-and-test.yml
|
||||
- local: .gitlab/configs/report-build-and-test.yml
|
||||
@@ -1,132 +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.
|
||||
|
||||
include:
|
||||
- project: 'lc-templates/id_tokens'
|
||||
file: 'id_tokens.yml'
|
||||
|
||||
# We define the following GitLab pipeline variables:
|
||||
variables:
|
||||
# Set the build-and-test command.
|
||||
# Nested variables are allowed and useful to customize the job command. We
|
||||
# protect variables with quotes so that their value may remain a string even if
|
||||
# they contain whitespaces.
|
||||
JOB_CMD:
|
||||
value: tests/gitlab/build_and_test --spec \"${SPEC}\" --data-dir ${MFEM_DATA_DIR} --data
|
||||
# The path to the shared resource between all jobs in the 'dane-baseline'
|
||||
# pipeline. For example, external repositories like 'tests' and 'tpls' are
|
||||
# cloned here. Also, 'tpls' is built once for all targets, so that build happens
|
||||
# here. The BUILD_ROOT is unique to the pipeline, preventing any form of
|
||||
# concurrency with other pipelines. This directory is removed by the 'cleanup'
|
||||
# stage in the 'dane-baseline' pipeline.
|
||||
BUILD_ROOT: ${USER_CI_TOP_DIR}/${CI_PROJECT_NAME}-${CI_MACHINE}-pipeline-${CI_PIPELINE_ID}
|
||||
|
||||
# On LLNL's dane and tioga, the 'build-and-test' pipelines creates only one
|
||||
# allocation shared among jobs in the pipeline in order to save time and
|
||||
# resources. This allocation has to be uniquely named so that we are sure to
|
||||
# retrieve it and avoid collisions.
|
||||
ALLOC_NAME: ${CI_PROJECT_NAME}_ci_${CI_PIPELINE_ID}
|
||||
|
||||
# Git repositories used in the pipelines:
|
||||
# - TPLS_REPO and TESTS_REPO are used only by the 'dane-baseline' pipeline
|
||||
# - AUTOTEST_REPO is used by all pipelines
|
||||
# - MFEM_DATA_REPO is used only by the 'build-and-test' pipelines
|
||||
TPLS_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/tpls.git
|
||||
TESTS_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/tests.git
|
||||
AUTOTEST_REPO: ssh://git@mybitbucket.llnl.gov:7999/mfem/autotest.git
|
||||
MFEM_DATA_REPO: https://github.com/mfem/data.git
|
||||
|
||||
# Directory used to place artifacts:
|
||||
# - ARTIFACTS_DIR is only used by the 'dane-baseline' pipeline
|
||||
ARTIFACTS_DIR: artifacts
|
||||
SLURM_OVERLAP: 1
|
||||
|
||||
# Dane
|
||||
# Arguments for top level allocation
|
||||
DANE_SHARED_ALLOC: "--exclusive --reservation=ci --time=60 --nodes=1"
|
||||
# Arguments for job level allocation
|
||||
# Note: We repeat the reservation, necessary when jobs are manually re-triggered.
|
||||
DANE_JOB_ALLOC: "--reservation=ci --overlap --nodes=1"
|
||||
|
||||
# Tioga
|
||||
# Arguments for top level allocation
|
||||
TIOGA_SHARED_ALLOC: "--queue=pci --exclusive --time-limit=45m --nodes=1"
|
||||
# Arguments for job level allocation
|
||||
TIOGA_JOB_ALLOC: "--nodes=1 --begin-time=+5s"
|
||||
|
||||
# Matrix
|
||||
# Arguments for top level allocation
|
||||
MATRIX_SHARED_ALLOC: "-p pdebug --exclusive --time=45 --nodes=1 -G 4"
|
||||
# Arguments for job level allocation
|
||||
# Note: We repeat the reservation, necessary when jobs are manually re-triggered.
|
||||
MATRIX_JOB_ALLOC: "--overlap --nodes=1"
|
||||
|
||||
# Configuration shared by build and test jobs specific to this project.
|
||||
# Not all configuration can be shared. Here projects can fine tune the
|
||||
# CI behavior.
|
||||
# See Umpire for an example (export junit test reports).
|
||||
.custom_job:
|
||||
artifacts:
|
||||
reports:
|
||||
|
||||
# Note: this part is not used by the 'dane-baseline' pipeline.
|
||||
# FIXME: BUILD_ROOT, TPLS_REPO, TESTS_REPO are not needed here.
|
||||
# Also, the definition of SHARED_REPOS_DIR is wrong.
|
||||
.reproducer_vars:
|
||||
script:
|
||||
- |
|
||||
echo -e "
|
||||
# Variables \n
|
||||
export SPEC=\"${SPEC//\"/\\\"}\" \n
|
||||
# Directories \n
|
||||
export BUILD_ROOT=\"\${working_dir}\" \n
|
||||
export SHARED_REPOS_DIR=\"\${BUILD_ROOT}/..\" \n
|
||||
export MFEM_DATA_DIR=\"\${SHARED_REPOS_DIR}/mfem-data\" \n
|
||||
# Repositories \n
|
||||
export TPLS_REPO=\"${TPLS_REPO//\"/\\\"}\" \n
|
||||
export TESTS_REPO=\"${TESTS_REPO//\"/\\\"}\" \n
|
||||
export AUTOTEST_REPO=\"${AUTOTEST_REPO//\"/\\\"}\" \n
|
||||
export MFEM_DATA_REPO=\"${MFEM_DATA_REPO//\"/\\\"}\" \n
|
||||
# Setup directories \n
|
||||
./tests/gitlab/build_and_test_setup \n
|
||||
# Using the CI build cache is optional and requires a token. Set it like so: \n
|
||||
# export REGISTRY_TOKEN=\"<your token here>\" \n"
|
||||
#
|
||||
|
||||
# Jobs report
|
||||
.report_job_success:
|
||||
script:
|
||||
- ${CI_PROJECT_DIR}/.gitlab/scripts/report_build_and_test SUCCESS
|
||||
rules:
|
||||
- when: on_success
|
||||
|
||||
.report_job_failure:
|
||||
script:
|
||||
- ${CI_PROJECT_DIR}/.gitlab/scripts/report_build_and_test FAILURE
|
||||
rules:
|
||||
- when: on_failure
|
||||
|
||||
# Keep the following for debugging purposes: renaming this job from
|
||||
# '.show_variables' to 'show_variables' will insert this debug job at the
|
||||
# beginning of all child pipelines.
|
||||
.show_variables:
|
||||
tags: [shell, oslic]
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
stage: .pre
|
||||
script:
|
||||
- |
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
echo "AUTOTEST=${AUTOTEST}"
|
||||
echo "AUTOTEST_COMMIT=${AUTOTEST_COMMIT}"
|
||||
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||
# Fail the job on purpose to prevent the rest of the pipeline from running
|
||||
false
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
variables:
|
||||
BASELINE_TEST: baseline
|
||||
MACHINE_NAME: dane
|
||||
|
||||
stages:
|
||||
- setup
|
||||
@@ -20,25 +19,6 @@ stages:
|
||||
- cleanup
|
||||
- baseline_publish
|
||||
|
||||
.on_dane:
|
||||
tags:
|
||||
- shell
|
||||
- dane
|
||||
rules:
|
||||
# Don't run dane jobs if...
|
||||
- if: '$ON_DANE == "OFF"'
|
||||
when: never
|
||||
# Don't run autotest update if...
|
||||
# Note: in some cases, the content of AUTOTEST can be '${AUTOTEST}', so we
|
||||
# need to treat that value as the default value of 'OFF'.
|
||||
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "ON" && $AUTOTEST != "YES"'
|
||||
when: never
|
||||
# Always cleanup
|
||||
- if: '$CI_JOB_NAME =~ /cleanup/'
|
||||
when: always
|
||||
# Default is to run if previous stage succeeded
|
||||
- when: on_success
|
||||
|
||||
baselinecheck_mfem_intel_dane:
|
||||
extends: [.on_dane]
|
||||
stage: baseline_check
|
||||
@@ -49,9 +29,6 @@ baselinecheck_mfem_intel_dane:
|
||||
# .gitlab/configs/setup-baseline.yml.
|
||||
TPLS_DIR: ${BUILD_ROOT}/tpls
|
||||
script:
|
||||
- echo "AUTOTEST=$AUTOTEST"
|
||||
- echo "AUTOTEST_COMMIT=$AUTOTEST_COMMIT"
|
||||
- echo "AUTOTEST_ROOT=$AUTOTEST_ROOT"
|
||||
- echo ${BUILD_ROOT}
|
||||
- echo ${TPLS_DIR}
|
||||
# Used by the tests in MFEM/tests, dane has 224 threads/node:
|
||||
@@ -102,25 +79,17 @@ report_baseline:
|
||||
mkdir -p ${MACHINE_NAME}
|
||||
rundir="${MACHINE_NAME}/$(date +%Y-%m-%d)-gitlab-${BASELINE_TEST}-${CI_COMMIT_REF_SLUG}"
|
||||
rundir=$(${CI_PROJECT_DIR}/.gitlab/scripts/safe_create_rundir ${rundir})
|
||||
status=0
|
||||
cp ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/* ${rundir} || { status=1; }
|
||||
cp ${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/* ${rundir}
|
||||
printf "%s\n" "" "Pipeline URL:" "$CI_PIPELINE_URL" \
|
||||
>> ${rundir}/pipeline.txt
|
||||
# We create an autotest-email.html file, because that's how we signal
|
||||
# that there was an error / diff (temporary).
|
||||
if [[ $status -ne 0 ]] || \
|
||||
[[ -f ${rundir}/${BASELINE_TEST}.err ]] || \
|
||||
if [[ -f ${rundir}/${BASELINE_TEST}.err ]] || \
|
||||
[[ -f ${rundir}/${BASELINE_TEST}-${MACHINE_NAME}.diff ]]; then
|
||||
cp ${rundir}/pipeline.txt ${rundir}/autotest-email.html
|
||||
fi
|
||||
msg="GitLab CI log for ${BASELINE_TEST} on ${MACHINE_NAME} ($(date +%Y-%m-%d))"
|
||||
# Note: in some cases, the content of AUTOTEST_COMMIT can be
|
||||
# '${AUTOTEST_COMMIT}', so we need to treat that value as the default
|
||||
# value of 'ON'.
|
||||
if [[ "$AUTOTEST_COMMIT" == '${AUTOTEST_COMMIT}' ]]; then
|
||||
AUTOTEST_COMMIT="ON"
|
||||
fi
|
||||
if [[ "$AUTOTEST_COMMIT" == "ON" || "$AUTOTEST_COMMIT" == "YES" ]]; then
|
||||
if [[ "$AUTOTEST_COMMIT" != "NO" ]]; then
|
||||
git pull && \
|
||||
git add ${rundir} && \
|
||||
git commit -m "${msg}" && \
|
||||
@@ -148,8 +117,8 @@ baselinepublish_mfem_dane:
|
||||
extends: [.on_dane]
|
||||
stage: baseline_publish
|
||||
rules:
|
||||
# - if: '$CI_COMMIT_BRANCH == "master" || $REBASELINE == "ON"'
|
||||
- if: '$REBASELINE == "ON"'
|
||||
# - if: '$CI_COMMIT_BRANCH == "master" || $REBASELINE == "YES"'
|
||||
- if: '$REBASELINE == "YES"'
|
||||
when: manual
|
||||
script:
|
||||
- echo ${BUILD_ROOT}
|
||||
@@ -159,5 +128,6 @@ baselinepublish_mfem_dane:
|
||||
- .gitlab/scripts/rebaseline
|
||||
|
||||
include:
|
||||
- local: .gitlab/custom-jobs-and-variables.yml
|
||||
- local: .gitlab/configs/common.yml
|
||||
- local: .gitlab/configs/dane-config.yml
|
||||
- local: .gitlab/configs/setup-baseline.yml
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# 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.
|
||||
|
||||
stages:
|
||||
- setup
|
||||
- allocate_resource
|
||||
- build_and_test
|
||||
- release_resource_and_report
|
||||
|
||||
# Allocate
|
||||
allocate_resource:
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
extends: .on_dane
|
||||
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
|
||||
debug_ser_gcc_10:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +debug~mpi"
|
||||
extends: .build_and_test_on_dane
|
||||
|
||||
debug_par_gcc_10:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +debug+mpi"
|
||||
extends: .build_and_test_on_dane
|
||||
|
||||
opt_ser_gcc_10:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 ~mpi"
|
||||
extends: .build_and_test_on_dane
|
||||
|
||||
opt_par_gcc_10:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1"
|
||||
extends: .build_and_test_on_dane
|
||||
|
||||
opt_par_gcc_10_sundials:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +sundials"
|
||||
extends: .build_and_test_on_dane
|
||||
|
||||
opt_par_gcc_10_petsc:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +petsc ^petsc+mumps~superlu-dist"
|
||||
extends: .build_and_test_on_dane
|
||||
|
||||
opt_par_gcc_10_pumi:
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +pumi"
|
||||
extends: .build_and_test_on_dane
|
||||
|
||||
# Release
|
||||
release_resource:
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
extends: .on_dane
|
||||
stage: release_resource_and_report
|
||||
script:
|
||||
- echo ${ALLOC_NAME}
|
||||
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
|
||||
- echo ${JOBID}
|
||||
- ([[ -n "${JOBID}" ]] && scancel ${JOBID})
|
||||
|
||||
# Jobs report
|
||||
report_job_success:
|
||||
stage: release_resource_and_report
|
||||
extends:
|
||||
- .on_dane
|
||||
- .report_job_success
|
||||
|
||||
report_job_failure:
|
||||
stage: release_resource_and_report
|
||||
extends:
|
||||
- .on_dane
|
||||
- .report_job_failure
|
||||
|
||||
include:
|
||||
- local: .gitlab/configs/common.yml
|
||||
- local: .gitlab/configs/dane-config.yml
|
||||
- local: .gitlab/configs/setup-build-and-test.yml
|
||||
- local: .gitlab/configs/report-build-and-test.yml
|
||||
@@ -1,19 +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.
|
||||
|
||||
# Jobs report
|
||||
report_job_success:
|
||||
extends: [.on_dane, .report_job_success]
|
||||
stage: jobs-stage-3
|
||||
|
||||
report_job_failure:
|
||||
extends: [.on_dane, .report_job_failure]
|
||||
stage: jobs-stage-3
|
||||
@@ -1,92 +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.
|
||||
|
||||
# Override reproducer section to define MFEM specific variables.
|
||||
.dane_reproducer_vars:
|
||||
script:
|
||||
- !reference [.reproducer_vars, script]
|
||||
|
||||
# TODO: Setup script should be defined as a bash script (but then GIT_STRATEGY
|
||||
# cannot be "none" anymore).
|
||||
|
||||
# Setup clones the mfem/data repo in ${SHARED_REPOS_DIR}. The build_and_test
|
||||
# script then symlinks the repo to the parent directory of the MFEM source
|
||||
# directory. Unit tests that depend on the mfem/data repo will then detect that
|
||||
# this directory is present and be enabled.
|
||||
setup:
|
||||
extends: .on_dane
|
||||
stage: jobs-stage-1
|
||||
script:
|
||||
- ./tests/gitlab/build_and_test_setup
|
||||
|
||||
|
||||
########################
|
||||
# Overridden shared jobs
|
||||
########################
|
||||
# When using shared jobs, we can duplicate them here to override description and
|
||||
# add necessary changes.
|
||||
# We keep ${PROJECT_<MACHINE>_VARIANTS} and ${PROJECT_<MACHINE>_DEPS} So that
|
||||
# the comparison with the original job is easier.
|
||||
|
||||
|
||||
############
|
||||
# Extra jobs
|
||||
############
|
||||
# We do not recommend using ${PROJECT_<MACHINE>_VARIANTS} and
|
||||
# ${PROJECT_<MACHINE>_DEPS} in the extra jobs. There is not reason not to fully
|
||||
# describe the spec here.
|
||||
|
||||
.mfem_job_on_dane:
|
||||
extends: .job_on_dane
|
||||
stage: jobs-stage-2
|
||||
variables:
|
||||
# Dane has 224 threads/node and we run 7 separate jobs: 224=7*32
|
||||
THREADS: 28
|
||||
|
||||
debug_ser_gcc_10:
|
||||
extends: .mfem_job_on_dane
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +debug~mpi"
|
||||
|
||||
debug_par_gcc_10:
|
||||
extends: .mfem_job_on_dane
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +debug+mpi"
|
||||
|
||||
opt_ser_gcc_10:
|
||||
extends: .mfem_job_on_dane
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 ~mpi"
|
||||
|
||||
opt_par_gcc_10:
|
||||
extends: .mfem_job_on_dane
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1"
|
||||
|
||||
opt_par_gcc_10_sundials:
|
||||
extends: .mfem_job_on_dane
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +sundials"
|
||||
|
||||
opt_par_gcc_10_petsc:
|
||||
extends: .mfem_job_on_dane
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +petsc ^petsc+mumps~superlu-dist"
|
||||
|
||||
opt_par_gcc_10_pumi:
|
||||
extends: .mfem_job_on_dane
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +pumi"
|
||||
|
||||
opt_par_gcc_10_gslib:
|
||||
extends: .mfem_job_on_dane
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +gslib"
|
||||
@@ -1,19 +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.
|
||||
|
||||
# Jobs report
|
||||
report_job_success:
|
||||
extends: [.on_matrix, .report_job_success]
|
||||
stage: jobs-stage-3
|
||||
|
||||
report_job_failure:
|
||||
extends: [.on_matrix, .report_job_failure]
|
||||
stage: jobs-stage-3
|
||||
@@ -1,70 +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.
|
||||
|
||||
# Override reproducer section to define UMPIRE specific variables.
|
||||
.matrix_reproducer_vars:
|
||||
script:
|
||||
- !reference [.reproducer_vars, script]
|
||||
|
||||
#TODO: Setup script should be defined as a bash script (but then GIT_STRATEGY cannot be "none" anymore).
|
||||
|
||||
# Setup clones the mfem/data repo in ${SHARED_REPOS_DIR}. The build_and_test
|
||||
# script then symlinks the repo to the parent directory of the MFEM source
|
||||
# directory. Unit tests that depend on the mfem/data repo will then detect that
|
||||
# this directory is present and be enabled.
|
||||
setup:
|
||||
extends: .on_matrix
|
||||
stage: jobs-stage-1
|
||||
script:
|
||||
- ./tests/gitlab/build_and_test_setup
|
||||
|
||||
|
||||
########################
|
||||
# Overridden shared jobs
|
||||
########################
|
||||
# When using shared jobs , we can duplicate them here to override description and add necessary changes.
|
||||
# We keep ${PROJECT_<MACHINE>_VARIANTS} and ${PROJECT_<MACHINE>_DEPS} So that
|
||||
# the comparison with the original job is easier.
|
||||
|
||||
|
||||
############
|
||||
# Extra jobs
|
||||
############
|
||||
# We do not recommend using ${PROJECT_<MACHINE>_VARIANTS} and
|
||||
# ${PROJECT_<MACHINE>_DEPS} in the extra jobs. There is not reason not to fully
|
||||
# describe the spec here.
|
||||
|
||||
.mfem_job_on_matrix:
|
||||
extends: .job_on_matrix
|
||||
stage: jobs-stage-2
|
||||
variables:
|
||||
# We run 2 jobs on 1 node that has 112 threads
|
||||
THREADS: 48
|
||||
# These modules need to be consistent with the uberenv configurations:
|
||||
MODULE_LIST: "gcc/10.3.1-magic cuda/12.9.1"
|
||||
|
||||
allocate_resources:
|
||||
timeout: 4h
|
||||
|
||||
opt_mpi_cuda_gcc:
|
||||
extends: .mfem_job_on_matrix
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +mpi +cuda cuda_arch=90"
|
||||
|
||||
opt_mpi_cuda_hypre_cuda_gcc:
|
||||
extends: .mfem_job_on_matrix
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +mpi +cuda cuda_arch=90 ^hypre+cuda"
|
||||
|
||||
opt_mpi_cuda_gcc_gslib:
|
||||
extends: .mfem_job_on_matrix
|
||||
variables:
|
||||
SPEC: "%gcc@10.3.1 +mpi +cuda +gslib cuda_arch=90 ^hypre+cuda"
|
||||
@@ -1,20 +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.
|
||||
|
||||
# Jobs report
|
||||
report_job_success:
|
||||
extends: [.on_tioga, .report_job_success]
|
||||
stage: jobs-stage-3
|
||||
|
||||
report_job_failure:
|
||||
extends: [.on_tioga, .report_job_failure]
|
||||
stage: jobs-stage-3
|
||||
|
||||
@@ -1,70 +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.
|
||||
|
||||
# Override reproducer section to define UMPIRE specific variables.
|
||||
.tioga_reproducer_vars:
|
||||
script:
|
||||
- !reference [.reproducer_vars, script]
|
||||
|
||||
#TODO: Setup script should be defined as a bash script (but then GIT_STRATEGY cannot be "none" anymore).
|
||||
|
||||
# Setup clones the mfem/data repo in ${SHARED_REPOS_DIR}. The build_and_test
|
||||
# script then symlinks the repo to the parent directory of the MFEM source
|
||||
# directory. Unit tests that depend on the mfem/data repo will then detect that
|
||||
# this directory is present and be enabled.
|
||||
setup:
|
||||
extends: .on_tioga
|
||||
stage: jobs-stage-1
|
||||
script:
|
||||
- ./tests/gitlab/build_and_test_setup
|
||||
|
||||
########################
|
||||
# Overridden shared jobs
|
||||
########################
|
||||
# When using shared jobs , we can duplicate them here to override description and add necessary changes.
|
||||
# We keep ${PROJECT_<MACHINE>_VARIANTS} and ${PROJECT_<MACHINE>_DEPS} So that
|
||||
# the comparison with the original job is easier.
|
||||
|
||||
|
||||
############
|
||||
# Extra jobs
|
||||
############
|
||||
# We do not recommend using ${PROJECT_<MACHINE>_VARIANTS} and
|
||||
# ${PROJECT_<MACHINE>_DEPS} in the extra jobs. There is not reason not to fully
|
||||
# describe the spec here.
|
||||
|
||||
# Build and test jobs, simply provide a spec
|
||||
|
||||
#.tioga_job_command:
|
||||
# script:
|
||||
# - echo PROXY="${PROXY}"
|
||||
# - echo TIOGA_JOB_ALLOC="${TIOGA_JOB_ALLOC}"
|
||||
# - "printf '#!/bin/bash\n%s\n' \"${JOB_CMD}\" > flux_script.sh"
|
||||
# - cat flux_script.sh
|
||||
# - ${PROXY} flux watch $( ${PROXY} flux batch -o output.stdout.type=kvs ${TIOGA_JOB_ALLOC} flux_script.sh )
|
||||
# - rm -f flux_script.sh
|
||||
|
||||
.mfem_job_on_tioga:
|
||||
extends: .job_on_tioga
|
||||
stage: jobs-stage-2
|
||||
variables:
|
||||
# We run 1 job on 1 node that has 64 threads
|
||||
THREADS: 64
|
||||
|
||||
opt_mpi_rocm_hypre_rocm:
|
||||
extends: .mfem_job_on_tioga
|
||||
variables:
|
||||
SPEC: "%rocmcc@=6.3.1 +rocm amdgpu_target=gfx90a ^hypre+rocm"
|
||||
|
||||
# cce_16_0_1:
|
||||
# extends: .mfem_job_on_tioga
|
||||
# variables:
|
||||
# SPEC: "%cce@=16.0.1"
|
||||
@@ -0,0 +1,44 @@
|
||||
# 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.
|
||||
|
||||
stages:
|
||||
- setup
|
||||
- build_and_test
|
||||
- report
|
||||
|
||||
opt_mpi_cuda_gcc:
|
||||
variables:
|
||||
SPEC: "%gcc@8.3.1 +mpi +cuda cuda_arch=70"
|
||||
extends: .build_and_test_on_lassen
|
||||
|
||||
opt_mpi_cuda_hypre_cuda_gcc:
|
||||
variables:
|
||||
SPEC: "%gcc@8.3.1 +mpi +cuda cuda_arch=70 ^hypre+cuda~shared cuda_arch=70"
|
||||
extends: .build_and_test_on_lassen
|
||||
|
||||
# Jobs report
|
||||
report_job_success:
|
||||
stage: report
|
||||
extends:
|
||||
- .on_lassen
|
||||
- .report_job_success
|
||||
|
||||
report_job_failure:
|
||||
stage: report
|
||||
extends:
|
||||
- .on_lassen
|
||||
- .report_job_failure
|
||||
|
||||
include:
|
||||
- local: .gitlab/configs/common.yml
|
||||
- local: .gitlab/configs/lassen-config.yml
|
||||
- local: .gitlab/configs/setup-build-and-test.yml
|
||||
- local: .gitlab/configs/report-build-and-test.yml
|
||||
@@ -32,9 +32,11 @@ mkdir _${BASELINE_TEST} && cd _${BASELINE_TEST}
|
||||
|
||||
# run
|
||||
if [[ "${MACHINE_NAME}" == "dane" ]]; then
|
||||
srun --nodes=1 -t 60 --exclusive --reservation=ci ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
|
||||
salloc --nodes=1 --exclusive --reservation=ci ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
|
||||
elif [[ ${MACHINE_NAME} == "corona" ]]; then
|
||||
srun --nodes=1 -t 60 -p pbatch ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
|
||||
salloc --nodes=1 -t 60 -p pbatch ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
|
||||
elif [[ ${MACHINE_NAME} == "lassen" ]]; then
|
||||
lalloc 1 -q pci ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
|
||||
else
|
||||
echo "Unknown machine: MACHINE_NAME=$MACHINE_NAME"
|
||||
exit 1
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 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.
|
||||
|
||||
function info_msg ()
|
||||
{
|
||||
echo "[Information:] ${1}"
|
||||
}
|
||||
|
||||
function error_msg ()
|
||||
{
|
||||
echo "[Error:] ${1}"
|
||||
}
|
||||
|
||||
# Perform a report while holding a lock file to prevent concurrency on
|
||||
# the destination.
|
||||
# Usage:
|
||||
# locked_clone <report_function> <lock_name>
|
||||
function locked_report ()
|
||||
{
|
||||
if ! command -v flock
|
||||
then
|
||||
error_msg "Required command 'flock' not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
info_msg "Will report ${1} while holding a lock in ${2}"
|
||||
|
||||
( date; info_msg "Waiting to acquire lock on '${PWD}/${2}.lock' ..."
|
||||
# try to get an exclusive lock on fd 9 (mfem-data.lock) repeating the
|
||||
# try every 5 seconds; we may want to add a counter for the number of
|
||||
# retries to interrupt a potential infinite loop
|
||||
while ! flock -n 9; do sleep 5; done
|
||||
date; info_msg "Acquired lock on '${PWD}/${2}.lock'"
|
||||
|
||||
report ${1}
|
||||
err=$?
|
||||
|
||||
# sleep for a period to allow NFS to propagate the above changes;
|
||||
# clearly, there is no guarantee that other NFS clients will see the
|
||||
# changes even after the timeout
|
||||
sleep 10
|
||||
exit $err
|
||||
) 9> ${2}.lock
|
||||
}
|
||||
|
||||
function report ()
|
||||
{
|
||||
if [[ "${1}" == "SUCCESS" ]]
|
||||
then
|
||||
info_msg "All the ${MACHINE_NAME} jobs passed"
|
||||
status_msg="The 'build-and-test' jobs on ${MACHINE_NAME} were SUCCESSFUL."
|
||||
elif [[ "${1}" == "FAILURE" ]]
|
||||
then
|
||||
info_msg "At least one failure on ${MACHINE_NAME}"
|
||||
status_msg="Some 'build-and-test' jobs on ${MACHINE_NAME} FAILED."
|
||||
else
|
||||
error_msg "Unknown status: ${1} ... aborting"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ${AUTOTEST_ROOT}/autotest || \
|
||||
{ error_msg "Invalid 'autotest' dir: ${AUTOTEST_ROOT}/autotest"; exit 1; }
|
||||
mkdir -p ${MACHINE_NAME}
|
||||
|
||||
rundir="${MACHINE_NAME}/$(date +%Y-%m-%d)-gitlab-ci-${CI_COMMIT_REF_SLUG}"
|
||||
rundir=$(${CI_PROJECT_DIR}/.gitlab/scripts/safe_create_rundir $rundir)
|
||||
|
||||
printf "%s\n" "${status_msg}" \
|
||||
"Pipeline URL:" "$CI_PIPELINE_URL" > ${rundir}/gitlab.err
|
||||
|
||||
msg="GitLab CI log for build-and-test on ${MACHINE_NAME} ($(date +%Y-%m-%d))"
|
||||
|
||||
if [[ "${1}" == "FAILURE" ]]
|
||||
then
|
||||
# Create 'autotest-email.html' to indicate failure:
|
||||
cp ${rundir}/gitlab.err ${rundir}/autotest-email.html
|
||||
fi
|
||||
|
||||
# Note: in some cases, the content of AUTOTEST_COMMIT can be
|
||||
# '${AUTOTEST_COMMIT}', so we need to treat that value as the default
|
||||
# value of 'ON'.
|
||||
if [[ "$AUTOTEST_COMMIT" == '${AUTOTEST_COMMIT}' ]]; then
|
||||
AUTOTEST_COMMIT="ON"
|
||||
fi
|
||||
if [[ "$AUTOTEST_COMMIT" == "ON" || "$AUTOTEST_COMMIT" == "YES" ]]; then
|
||||
git pull && \
|
||||
git add ${rundir} && \
|
||||
git commit -m "${msg}" && \
|
||||
${CI_PROJECT_DIR}/.gitlab/scripts/git_try_to_push
|
||||
else
|
||||
for file in ${rundir}/*; do
|
||||
echo "------------------------------"
|
||||
echo "Content of '$file'"
|
||||
echo "******************************"
|
||||
cat $file
|
||||
echo "******************************"
|
||||
done
|
||||
rm -rf ${rundir} || true
|
||||
fi
|
||||
}
|
||||
|
||||
export MACHINE_NAME=${CI_MACHINE}
|
||||
info_msg "MACHINE_NAME is ${MACHINE_NAME}"
|
||||
info_msg "AUTOTEST_ROOT is ${AUTOTEST_ROOT}"
|
||||
info_msg "AUTOTEST=$AUTOTEST"
|
||||
info_msg "AUTOTEST_COMMIT=$AUTOTEST_COMMIT"
|
||||
|
||||
cd ${AUTOTEST_ROOT} && locked_report ${1} autotest
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 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.
|
||||
|
||||
echo "Runs if there was at least one failure on ${MACHINE_NAME}"
|
||||
|
||||
cd ${AUTOTEST_ROOT}/autotest || \
|
||||
{ echo "Invalid 'autotest' dir: ${AUTOTEST_ROOT}/autotest"; exit 1; }
|
||||
mkdir -p ${MACHINE_NAME}
|
||||
|
||||
rundir="${MACHINE_NAME}/$(date +%Y-%m-%d)-gitlab-ci-${CI_COMMIT_REF_SLUG}"
|
||||
rundir=$(${CI_PROJECT_DIR}/.gitlab/scripts/safe_create_rundir $rundir)
|
||||
|
||||
printf "%s\n" "Some 'build-and-test' jobs on ${MACHINE_NAME} FAILED." \
|
||||
"Pipeline URL:" "$CI_PIPELINE_URL" > ${rundir}/gitlab.err
|
||||
|
||||
msg="GitLab CI log for build-and-test on ${MACHINE_NAME} ($(date +%Y-%m-%d))"
|
||||
|
||||
# Create 'autotest-email.html' to indicate failure:
|
||||
cp ${rundir}/gitlab.err ${rundir}/autotest-email.html
|
||||
|
||||
if [[ "$AUTOTEST_COMMIT" != "NO" ]]; then
|
||||
git pull && \
|
||||
git add ${rundir} && \
|
||||
git commit -m "${msg}" && \
|
||||
${CI_PROJECT_DIR}/.gitlab/scripts/git_try_to_push
|
||||
else
|
||||
for file in ${rundir}/*; do
|
||||
echo "------------------------------"
|
||||
echo "Content of '$file'"
|
||||
echo "******************************"
|
||||
cat $file
|
||||
echo "******************************"
|
||||
done
|
||||
rm -rf ${rundir} || true
|
||||
fi
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 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.
|
||||
|
||||
echo "Can only run if all the ${MACHINE_NAME} jobs passed"
|
||||
|
||||
cd ${AUTOTEST_ROOT}/autotest || \
|
||||
{ echo "Invalid 'autotest' dir: ${AUTOTEST_ROOT}/autotest"; exit 1; }
|
||||
mkdir -p ${MACHINE_NAME}
|
||||
|
||||
rundir="${MACHINE_NAME}/$(date +%Y-%m-%d)-gitlab-ci-${CI_COMMIT_REF_SLUG}"
|
||||
rundir=$(${CI_PROJECT_DIR}/.gitlab/scripts/safe_create_rundir $rundir)
|
||||
|
||||
printf "%s\n" "The 'build-and-test' jobs on ${MACHINE_NAME} were SUCCESSFUL." \
|
||||
"Pipeline URL:" "$CI_PIPELINE_URL" > ${rundir}/gitlab.out
|
||||
|
||||
msg="GitLab CI log for build-and-test on ${MACHINE_NAME} ($(date +%Y-%m-%d))"
|
||||
|
||||
if [[ "$AUTOTEST_COMMIT" != "NO" ]]; then
|
||||
git pull && \
|
||||
git add ${rundir} && \
|
||||
git commit -m "${msg}" && \
|
||||
${CI_PROJECT_DIR}/.gitlab/scripts/git_try_to_push
|
||||
else
|
||||
for file in ${rundir}/*; do
|
||||
echo "------------------------------"
|
||||
echo "Content of '$file'"
|
||||
echo "******************************"
|
||||
cat $file
|
||||
echo "******************************"
|
||||
done
|
||||
rm -rf ${rundir} || true
|
||||
fi
|
||||
@@ -1,130 +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.
|
||||
|
||||
# The template job to test whether a machine is up.
|
||||
# Expects CI_MACHINE defined to machine name.
|
||||
.machine-check:
|
||||
stage: prerequisites
|
||||
tags: [shell, oslic]
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
script:
|
||||
- |
|
||||
if [[ $(jq '.[env.CI_MACHINE].total_nodes_up' /usr/global/tools/lorenz/data/loginnodeStatus) == 0 ]]
|
||||
then
|
||||
echo -e "\e[31mNo node available on ${CI_MACHINE}\e[0m"
|
||||
false && \
|
||||
curl --url "https://api.github.com/repos/${GITHUB_PROJECT_ORG}/${GITHUB_PROJECT_NAME}/statuses/${CI_COMMIT_SHA}" \
|
||||
--header 'Content-Type: application/json' \
|
||||
--header "authorization: Bearer ${GITHUB_TOKEN}" \
|
||||
--data "{ \"state\": \"failure\", \"target_url\": \"${CI_PIPELINE_URL}\", \"description\": \"GitLab ${CI_MACHINE} down\", \"context\": \"ci/gitlab/${CI_MACHINE}\" }"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
###
|
||||
# Trigger a build-and-test pipeline for a machine.
|
||||
# Comment the jobs for machines you don’t need.
|
||||
###
|
||||
|
||||
# One job to generate the job list for all the subpipelines
|
||||
generate-job-lists:
|
||||
stage: prerequisites
|
||||
tags: [shell, oslic]
|
||||
variables:
|
||||
LOCAL_JOBS_PATH: ".gitlab/jobs"
|
||||
script:
|
||||
- |
|
||||
echo "AUTOTEST=$AUTOTEST"
|
||||
echo "AUTOTEST_COMMIT=$AUTOTEST_COMMIT"
|
||||
echo "AUTOTEST_ROOT=$AUTOTEST_ROOT"
|
||||
- |
|
||||
cat ${LOCAL_JOBS_PATH}/dane.yml > dane-jobs.yml
|
||||
if [[ ${AUTOTEST} == "ON" || ${AUTOTEST} == "YES" ]]
|
||||
then
|
||||
cat ${LOCAL_JOBS_PATH}/dane-reports.yml >> dane-jobs.yml
|
||||
fi
|
||||
- |
|
||||
cat ${LOCAL_JOBS_PATH}/matrix.yml > matrix-jobs.yml
|
||||
if [[ ${AUTOTEST} == "ON" || ${AUTOTEST} == "YES" ]]
|
||||
then
|
||||
cat ${LOCAL_JOBS_PATH}/matrix-reports.yml >> matrix-jobs.yml
|
||||
fi
|
||||
- |
|
||||
cat ${LOCAL_JOBS_PATH}/tioga.yml > tioga-jobs.yml
|
||||
if [[ ${AUTOTEST} == "ON" || ${AUTOTEST} == "YES" ]]
|
||||
then
|
||||
cat ${LOCAL_JOBS_PATH}/tioga-reports.yml >> tioga-jobs.yml
|
||||
fi
|
||||
artifacts:
|
||||
paths:
|
||||
- dane-jobs.yml
|
||||
- matrix-jobs.yml
|
||||
- tioga-jobs.yml
|
||||
|
||||
|
||||
# DANE
|
||||
dane-up-check:
|
||||
variables:
|
||||
CI_MACHINE: "dane"
|
||||
extends: [.machine-check]
|
||||
|
||||
dane-build-and-test:
|
||||
variables:
|
||||
CI_MACHINE: "dane"
|
||||
needs: [dane-up-check, generate-job-lists]
|
||||
extends: [.build-and-test]
|
||||
|
||||
# DANE, MFEM Specific
|
||||
dane-baseline:
|
||||
stage: test-pipelines
|
||||
variables:
|
||||
# Explicitly pass down values that are not always propagated to child
|
||||
# pipelines, e.g. when a variable is set in the "Settings -> CI" web
|
||||
# interface (project variables).
|
||||
# Note: in some cases, this does not work as expected, e.g. when the
|
||||
# variable is not re-defined in the web interface; in such cases, the child
|
||||
# pipeline gets a definition like '${AUTOTEST}', i.e. it behaves as if
|
||||
# AUTOTEST is undefined, even though there is a default value in
|
||||
# .gitlab-ci.yml.
|
||||
AUTOTEST: "${AUTOTEST}"
|
||||
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
|
||||
trigger:
|
||||
include: .gitlab/dane-baseline.yml
|
||||
strategy: depend
|
||||
forward:
|
||||
pipeline_variables: true
|
||||
needs: [dane-up-check]
|
||||
|
||||
|
||||
# TIOGA
|
||||
tioga-up-check:
|
||||
variables:
|
||||
CI_MACHINE: "tioga"
|
||||
extends: [.machine-check]
|
||||
|
||||
tioga-build-and-test:
|
||||
variables:
|
||||
CI_MACHINE: "tioga"
|
||||
needs: [tioga-up-check, generate-job-lists]
|
||||
extends: [.build-and-test]
|
||||
|
||||
|
||||
# Matrix
|
||||
matrix-up-check:
|
||||
variables:
|
||||
CI_MACHINE: "matrix"
|
||||
extends: [.machine-check]
|
||||
|
||||
matrix-build-and-test:
|
||||
variables:
|
||||
CI_MACHINE: "matrix"
|
||||
needs: [matrix-up-check, generate-job-lists]
|
||||
extends: [.build-and-test]
|
||||
@@ -8,168 +8,9 @@
|
||||
https://mfem.org
|
||||
|
||||
|
||||
Version 4.9.1 (development)
|
||||
Version 4.8.1 (development)
|
||||
===========================
|
||||
|
||||
- Added policy for AI-assisted contribution to CONTRIBUTING.md.
|
||||
|
||||
Discretization improvements
|
||||
---------------------------
|
||||
- Improved FindPointsGSLIB surface mesh capability with support for simplices
|
||||
and an option to specify axis-aligned bounding box padding for near-surface
|
||||
point queries.
|
||||
|
||||
- Added GPU-enabled partial assembly for simplicial Bernstein H1 basis based on
|
||||
ragged tensor algorithms (see DOI: 10.1137/11082539X) for mass and diffusion
|
||||
integrators.
|
||||
|
||||
- Replaced legacy simplex quadrature rules with symmetric positive weight rules
|
||||
for triangles (orders 0-25) and tetrahedra (orders 0-20). These rules
|
||||
guarantee all-positive weights and interior quadrature points, improving
|
||||
numerical stability. Higher orders fall back to Grundmann-Moller.
|
||||
* Triangle rules: Witherden and Vincent, DOI: 10.1016/j.camwa.2015.03.017
|
||||
* Tet rules (d=1-13): Witherden and Vincent (same as above)
|
||||
* Tet rules (d=14-20): Chuluunbaatar et al., DOI: 10.1016/j.camwa.2022.08.016
|
||||
|
||||
- Added support for general 1D Gauss-Jacobi quadrature rules and Stroud conical
|
||||
quadrature rules on triangles and tetrahedra.
|
||||
|
||||
- Improved the GridFunction projection routines. Projections work for Scalar,
|
||||
Vector and VectorFE, also NURBS versions. Optionally different types of
|
||||
projections can be selected, default behavior has not changed.
|
||||
|
||||
- Added GridFunction projection methods for trace spaces, i.e., project
|
||||
coefficients on the mesh skeleton.
|
||||
|
||||
- Added methods to estimate function extremum using piecewise linear bounds plus
|
||||
recursive subdivision.
|
||||
|
||||
- Extend FindPointsGSLIB to support surface meshes.
|
||||
|
||||
- Added support for complex-valued mixed bilinear forms via the new classes
|
||||
MixedSesquilinearForm and ParMixedSesquilinearForm, mirroring the existing
|
||||
SesquilinearForm classes. Rectangular complex operators are now also
|
||||
handled correctly by ComplexSparseMatrix::GetSystemMatrix and
|
||||
ComplexHypreParMatrix::GetSystemMatrix, which previously assumed equal
|
||||
trial and test spaces.
|
||||
|
||||
- Added FiniteElementSpace::GetBoundaryLoopEdgeDofs to extract the edge DOFs on
|
||||
the perimeter loop of a set of boundary elements, with a ParFiniteElementSpace
|
||||
overload that reconciles the selection across processor boundaries so the
|
||||
result is partition invariant. This is useful for imposing boundary conditions
|
||||
on boundary edge DOFs.
|
||||
|
||||
- Added a MaxAbs reduction to GroupCommunicator that selects the signed value of
|
||||
largest magnitude across a group, keeping its sign. Equal-magnitude ties
|
||||
resolve deterministically to the positive value.
|
||||
|
||||
Meshing improvements
|
||||
--------------------
|
||||
- Added support for nonuniform anisotropic mesh refinement on parallel quad/hex
|
||||
meshes with arbitrary spacing in each direction. This enables in particular
|
||||
3:1 refinement in parallel, as demonstrated in the new meshing miniapp pref321.
|
||||
|
||||
- Added option to guarantee mesh validity during TMOP-based r-adaptivity, using
|
||||
bounds on the determinant of the mesh transformation Jacobian.
|
||||
|
||||
- Added PA support for TMOP's adaptive limiting functionality. Multiple
|
||||
GridFunctions and Coefficients can be combined to form a composite term.
|
||||
|
||||
- Improved support for 1D NURBS meshes with variable order, including using
|
||||
the patches construct for 1D NURBS meshes.
|
||||
|
||||
- Added the option to include material interfaces (faces separating elements
|
||||
with different element attributes) as additional boundary elements, for
|
||||
parallel visualization, e.g. with GLVis. This is supported by both the Print
|
||||
and PrintAsOne methods of ParMesh. See ParMesh::SetPrintInterfaces().
|
||||
|
||||
Linear and nonlinear solvers
|
||||
----------------------------
|
||||
- Added support for trace spaces in PRefinementTransferOperator. This is used in
|
||||
PRefinement multigrid methods for problems posed on trace spaces (see e.g. the
|
||||
DPG miniapps).
|
||||
|
||||
- Added new class MultiVector: an array of Vectors of different sizes where each
|
||||
Vector can be allocated independently. Also, added associated methods in class
|
||||
Operator: MultMV, MultTransposeMV, and GetGradientMV, that use MultiVector
|
||||
objects for input and/or output parameters. [PR #5249]
|
||||
|
||||
GPU computing
|
||||
-------------
|
||||
- Improved partial assembly for VectorDivergenceIntegrator with shared-memory
|
||||
kernels, kernel registration, and transpose support.
|
||||
|
||||
- Improved partial-assembly diagonal kernels for VectorMassIntegrator (shared-
|
||||
memory specializations) and ElasticityIntegrator (no scratch Q-vector).
|
||||
|
||||
- Added PA gradient and diagonal support for VectorConvectionNLFIntegrator
|
||||
(AssembleGradPA, AddMultGradPA, AssembleGradDiagonalPA).
|
||||
|
||||
- Added device assembly support for 3D H(curl) VectorFEDomainLFIntegrator.
|
||||
|
||||
- Added partial assembly support for MixedScalarWeakGradientIntegrator.
|
||||
|
||||
- Added partial assembly support for MixedDotProductIntegrator.
|
||||
|
||||
- Added partial assembly support for MixedScalarCrossProductIntegrator.
|
||||
|
||||
- Added partial assembly support for MixedScalarWeakCrossProductIntegrator.
|
||||
|
||||
- Added partial assembly support for MixedVectorGradientIntegrator for H1->RT.
|
||||
|
||||
- Added support for device partial assembly CurlInterpolator.
|
||||
This supports 2D and 3D variants:
|
||||
2D H1 (out-of-plane) to RT (in-plane)
|
||||
2D ND (in-plane) to Integral L2 (out-of-plane)
|
||||
3D ND to RT
|
||||
|
||||
- Added NVIDIA cuDSS library interface. Implementation examples have been
|
||||
added to ex1 and ex1p. See https://developer.nvidia.com/cudss for more
|
||||
details. Supported versions >= 0.6.0.
|
||||
|
||||
- Allow specifying GPU kernel launch bounds for native and RAJA GPU backends.
|
||||
|
||||
- Changed VectorFEMassIntegrator to use kernel specialization dispatch for
|
||||
partial assembly.
|
||||
|
||||
- Added support for FiniteElement::MapType::INTEGRAL spaces to
|
||||
QuadratureInterpolator.
|
||||
|
||||
- Added support for FiniteElement::MapType::INTEGRAL spaces to
|
||||
MixedScalarCurlIntegrator.
|
||||
|
||||
New and updated examples and miniapps
|
||||
-------------------------------------
|
||||
- The Lorentz miniapp (in miniapps/electromagnetics) has been updated to
|
||||
leverage the ParticleSet capability.
|
||||
|
||||
- Added (Complex)PRefinementMultigrid solver option in the DPG miniapps.
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
- Fixed signed DOF handling in ParGridFunction reading (read constructor) and
|
||||
saving via SaveAsOne(). Simplified the process of applying the DOF signs by
|
||||
using the new method ApplyDofSigns() in class ParFiniteElementSpace: the
|
||||
method will return immediately if no sign flips are needed.
|
||||
|
||||
- Added support for coefficient-weighted LOR transfer in
|
||||
L2ProjectionGridTransfer. The transfer conserves the weighted mass, for
|
||||
example when transferring velocity while conserving density-weighted momentum.
|
||||
This is illustrated in the lor-transfer and plor-transfer miniapps.
|
||||
|
||||
- Added support for saving DataCollection output on the node-local storage,
|
||||
instead of requiring that the filesystem is shared among all the ranks.
|
||||
|
||||
API changes
|
||||
-----------
|
||||
- Removed ProjectGrad from 2D RT elements. Users should use ProjectCurl instead.
|
||||
This also fixes a bug where ProjectCurl was returning the negative curl,
|
||||
identical to ProjectGrad.
|
||||
|
||||
|
||||
Version 4.9, released on Dec 11, 2025
|
||||
=====================================
|
||||
|
||||
Starting with this version, MFEM requires a C++17 compiler.
|
||||
|
||||
Discretization improvements
|
||||
@@ -178,149 +19,70 @@ Discretization improvements
|
||||
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.
|
||||
miniapp in the miniapps/dfem/ directory for illustration of dFEM's use.
|
||||
|
||||
- Introduced initial support for particle methods in MFEM with new classes
|
||||
Particle, ParticleSet and ParticleVector.
|
||||
* Particle is a convenient interface for individual particle data.
|
||||
* ParticleSet manages and stores particle data in a struct-of-arrays form,
|
||||
carrying particle coordinates and IDs along with an arbitrary number of
|
||||
Vector and integer data for each particle.
|
||||
* ParticleVector is a Vector-derived container that stores vector data for an
|
||||
arbitrary number of particles contiguously based on specified vdim/ordering.
|
||||
See the new particle miniapps in miniapps/gslib/ and miniapps/fluids/navier/.
|
||||
|
||||
- Added a new miniapp and specialized AMG solver (AMGF) for optimization-based
|
||||
contact mechanics. The miniapp solves large-scale frictionless contact using a
|
||||
self-contained Interior Point (IP) solver, mortar-based contact constraints
|
||||
provided by Tribol. The resulting linear systems are solved with the new AMGF
|
||||
solver (see below). Benchmark examples include the two-block, ironing, and
|
||||
beam-sphere problems. See the miniapps/contact/ directory.
|
||||
|
||||
- Added support for boundary integration to the hyperbolic framework. Two new
|
||||
classes BdrHyperbolicDirichletIntegrator and BoundaryHyperbolicFlowIntegrator
|
||||
have been introduced for implementation of weak Dirichlet boundary conditions
|
||||
with a general flux or for the linear case respectively.
|
||||
|
||||
- Added a method to compute piecewise linear bounds on high-order functions on
|
||||
tensor-product elements.
|
||||
|
||||
- Added support for interior face integration enabling DG methods in
|
||||
ParMixedBilinearForm, ParNonlinearForm and ParBlockNonlinearForm.
|
||||
- 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.
|
||||
|
||||
- Introduced IMEX ODE solvers based on a split-operator framework. Added
|
||||
examples ex41 and ex41p demonstrating IMEX DG/CG discretizations of the
|
||||
convection–diffusion equation, with ex41p using DG LOR preconditioning.
|
||||
- Added support for boundary integration to the hyperbolic framework. In this
|
||||
regard, new classes `BdrHyperbolicDirichletIntegrator` and
|
||||
`BoundaryHyperbolicFlowIntegrator` have been introduced for implementation
|
||||
of weak Dirichlet boundary conditions with a general flux or for the linear
|
||||
case respectively.
|
||||
|
||||
- Added method to compute piecewise linear bounds on high-order functions on
|
||||
tensor-product elements.
|
||||
|
||||
- Parallel anisotropic refinement of hexahedral meshes is now supported,
|
||||
provided that neighboring hexahedra are not refined in conflicting directions.
|
||||
A new ParMesh method is added to check for such conflicts, before refinement.
|
||||
|
||||
Meshing improvements
|
||||
--------------------
|
||||
- The TMOP kernel hierarchy has been restructured to reduce compilation time.
|
||||
Most large kernels have been split into smaller specific kernels for each
|
||||
metric. The directory structure has been updated with assemble, metrics, mult
|
||||
and tools subdirectories. New kernel dispatch and specialization system has
|
||||
also been integrated. Unit tests have been revised to ensure --all tests pass.
|
||||
|
||||
- Introduced NC-patch NURBS meshes, which are conforming element-wise but allow
|
||||
for nonconforming patch topology. This new mesh format supports element
|
||||
spacing formulas for refinement, as well as local refinement factors for a
|
||||
subset of knot vectors.
|
||||
|
||||
- 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.
|
||||
|
||||
- Parallel anisotropic refinement of hexahedral meshes is now supported,
|
||||
provided that neighboring hexahedra are not refined in conflicting directions.
|
||||
A new ParMesh method is added to check for such conflicts, before refinement.
|
||||
|
||||
- Added support for higher order meshes in (Par)Mesh::MakeSimplicial.
|
||||
|
||||
Linear and nonlinear solvers
|
||||
----------------------------
|
||||
- Added FilteredSolver: a base class for solvers with filtering. It handles
|
||||
cases where a solver performs well except in small subspaces, by adding a
|
||||
filtering step formulated as a subspace correction.
|
||||
|
||||
- Added AMGFSolver: a derived class of FilteredSolver, specialized for AMG with
|
||||
Filtering (AMGF), providing robust preconditioning for linear systems arising
|
||||
in constrained optimization problems such as frictionless contact.
|
||||
|
||||
Added 'GetResiduals' and 'GetFinalAbsResidualNorm' to 'HyprePCG',
|
||||
'HypreGMRES', and 'HypreFGMRES' to get 'r' and '|r|_p'. Note that the latter
|
||||
computes '|r|_p' from 'r' instead of returning a cached value like the
|
||||
relative 'GetFinalResidualNorm'. These require Hypre >= 2.15.0.
|
||||
|
||||
Changed the default solver parameters for 'HyprePCG' to 'tol=1e-6' and
|
||||
'max_iter=1000'. This matches the default parameters in Hypre 3.0.
|
||||
|
||||
Added various helper functions for querying/modifying Hypre solvers:
|
||||
'HypreSmoother::GetType', 'HypreSmoother::GetSOROptions',
|
||||
'HypreSmoother::GetPolyOptions', 'HypreSmoother::GetWindowParameters',
|
||||
'HypreSmoother::IsOperatorSymmetric', 'HyprePCG::GetTol',
|
||||
'HyprePCG::GetAbsTol', 'HyprePCG::GetMaxIter', 'HyprePCG::SetUseTwoNorm',
|
||||
'HypreGMRES::GetTol', 'HypreGMRES::GetAbsTol', 'HypreGMRES::GetMaxIter',
|
||||
'HypreGMRES::GetKDim', 'HypreFGMRES::GetTol', 'HypreFGMRES::GetMaxIter',
|
||||
'HypreFGMRES::GetKDim', and 'HypreBoomerAMG::GetMaxIter'.
|
||||
|
||||
GPU computing
|
||||
-------------
|
||||
- Added the 'gpu', 'raja-gpu', and 'ceed-gpu' backend aliases/shortcuts which
|
||||
automatically select between CUDA or HIP.
|
||||
|
||||
- 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)'.
|
||||
|
||||
- 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 the finite element
|
||||
space to be nonconforming.
|
||||
- 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.
|
||||
|
||||
- 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 BCs. A new method,
|
||||
SetSubVectorHost, has been added for cases where host execution is always
|
||||
needed (e.g. when the DOFs array is small).
|
||||
|
||||
- Added GPU support in GradientGridFunction and InnerProduct Coefficient classes
|
||||
by implementing their Project methods.
|
||||
|
||||
- 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`.
|
||||
- Added new method: GridFunction::GetGradients, with GPU support, for computing
|
||||
the gradients of a GridFunction on all elements.
|
||||
|
||||
- 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 GPU support in GradientGridFunctionCoefficient and
|
||||
InnerProductCoefficient by implementing their Project methods.
|
||||
|
||||
New and updated examples and miniapps
|
||||
-------------------------------------
|
||||
- Added the miniapps/fluids directory and moved the previous Navier and the new
|
||||
incompressible Schrödinger flow miniapps into it.
|
||||
|
||||
- Introduced the new Incompressible Schrödinger Flow (ISF) miniapp, which models
|
||||
inviscid fluid dynamics by solving the linear Schrödinger equation, leveraging
|
||||
the hydrodynamical analogy to quantum mechanics.
|
||||
|
||||
- New particle-related miniapps:
|
||||
* New transient Navier-Stokes fluid-particles solver NavierParticles in
|
||||
miniapps/fluids/navier/navier_particles, for modeling tracer particles in
|
||||
fluid flow, demonstrating use of the new ParticleSet class.
|
||||
* New Navier miniapp, miniapps/fluids/navier/navier_bifurcation, showing the
|
||||
use of NavierParticles in a 2D bifurcating channel flow.
|
||||
* New FindPointsGSLIB miniapp, miniapps/gslib/particles_redist, showing
|
||||
parallel-redistribution of particle data between MPI ranks.
|
||||
* Particle visualization features in common/particles_extras for viewing
|
||||
particle locations and trajectories (ParticleTrajectories) using GLVis.
|
||||
- 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`.
|
||||
|
||||
- Added a new miniapp (meshing/mesh-bounding-boxes) that computes the bounding
|
||||
boxes for each element of a given mesh, and the bounds on the determinant of
|
||||
@@ -333,44 +95,36 @@ New and updated examples and miniapps
|
||||
of a charged particle, subject to Lorentz forces, in electrostatic and/or
|
||||
magnetostatic fields as computed by the volta or tesla miniapps.
|
||||
|
||||
- Added miniapps to demonstrate an implementation of the absolute-value
|
||||
l1-Jacobi preconditioners in partially assembled operators. This includes
|
||||
Multigrid wrapper to demonstrate the effectiveness of these Jacobi-type
|
||||
operators as smoothers. See the miniapps/diag-smoothers/ directory.
|
||||
|
||||
- Updated the mtop miniapp with a GPU enabled forward and adjoint solver for
|
||||
isotropic linear elasticity.
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
- Introduced MFEM_FETCH_TPLS CMake option to enable downloading, configuring,
|
||||
and building of TPLs alongside MFEM (currently supported TPLs are hypre,
|
||||
METIS, and GSLIB).
|
||||
|
||||
- Added quadrature function support to the VisIt and Conduit data collections.
|
||||
|
||||
- Added access to the internal parallel matrix in Par(Mixed)BilinearForm and
|
||||
related utility methods for elimination of BCs.
|
||||
|
||||
- FindPointsGSLIB has a new constructor that accepts the mesh object and
|
||||
internally calls the Setup() method so users do not have to. The FreeData()
|
||||
method has also been moved to the destructor so users do not need to manually
|
||||
free-up the memory if the destructor is called before MPI_Finalize().
|
||||
|
||||
- Added parallel Address Sanitizer, serial and parallel Undefined Behavior
|
||||
Sanitizer and serial Memory Sanitizer GitHub actions tests on Ubuntu.
|
||||
|
||||
API changes
|
||||
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.
|
||||
- API addition: in class `Operator`, added virtual functions: `AbsMult`, and
|
||||
`AbsMultTranspose`; in class `Vector`, added `Abs` and `Pow`.
|
||||
|
||||
- ParBilinearForm::EliminateEssentialVDofsInRhs() has been deprecated in favor
|
||||
of ParallelEliminateEssentialTDofsInRhs().
|
||||
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.
|
||||
|
||||
- FindPointsGSLIB has a new constructor that accepts the mesh object and
|
||||
internally calls the Setup() method so that the user does not have to.
|
||||
The FreeData() method has also been moved to the destructor so the user does
|
||||
not need to manually free-up the memory if the destructor is called before
|
||||
MPI_Finalize().
|
||||
|
||||
Version 4.8, released on Apr 9, 2025
|
||||
====================================
|
||||
|
||||
+44
-94
@@ -59,7 +59,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.9.1)
|
||||
set(${PROJECT_NAME}_VERSION 4.8.1)
|
||||
|
||||
# Prohibit in-source build
|
||||
if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
|
||||
@@ -88,9 +88,18 @@ if (MFEM_USE_STRUMPACK OR MFEM_USE_MUMPS)
|
||||
# Just needed to find the MPI_Fortran libraries to link with
|
||||
set(XSDK_ENABLE_Fortran ON)
|
||||
endif()
|
||||
# RAJA requires C++20:
|
||||
if ((MFEM_USE_UMPIRE OR MFEM_USE_RAJA) AND ("${CMAKE_CXX_STANDARD}" LESS "20"))
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "C++ standard to use." FORCE)
|
||||
# Ginkgo requires C++17:
|
||||
if ((MFEM_USE_GINKGO) AND ("${CMAKE_CXX_STANDARD}" LESS "17"))
|
||||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ standard to use." FORCE)
|
||||
# Google Benchmark, SUNDIALS, STRUMPACK, Tribol, RAJA and Umpire require C++14:
|
||||
elseif ((MFEM_USE_BENCHMARK OR
|
||||
MFEM_USE_SUNDIALS OR
|
||||
MFEM_USE_STRUMPACK OR
|
||||
MFEM_USE_TRIBOL OR
|
||||
MFEM_USE_RAJA OR
|
||||
MFEM_USE_UMPIRE) AND
|
||||
("${CMAKE_CXX_STANDARD}" LESS "14"))
|
||||
set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to use." FORCE)
|
||||
endif()
|
||||
|
||||
# Include xSDK default CMake file.
|
||||
@@ -124,49 +133,33 @@ if (MFEM_USE_CUDA)
|
||||
if (NOT CMAKE_CUDA_HOST_COMPILER)
|
||||
set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER})
|
||||
endif()
|
||||
if (NOT CMAKE_CUDA_ARCHITECTURES)
|
||||
# make CUDA_ARCH resemble the same form as CMAKE_CUDA_ARCHITECTURES
|
||||
string(REPLACE "sm_" "" CUDA_ARCH_TMP "${CUDA_ARCH}")
|
||||
string(REPLACE "," ";" CUDA_ARCH "${CUDA_ARCH_TMP}")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "${CUDA_ARCH}")
|
||||
if (CMAKE_VERSION VERSION_LESS 3.18.0)
|
||||
set(CUDA_FLAGS "-arch=${CUDA_ARCH} ${CUDA_FLAGS}")
|
||||
elseif (NOT CMAKE_CUDA_ARCHITECTURES)
|
||||
string(REGEX REPLACE "^sm_" "" ARCH_NUMBER "${CUDA_ARCH}")
|
||||
if ("${CUDA_ARCH}" STREQUAL "sm_${ARCH_NUMBER}")
|
||||
set(CMAKE_CUDA_ARCHITECTURES "${ARCH_NUMBER}")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown CUDA_ARCH: ${CUDA_ARCH}")
|
||||
endif()
|
||||
else()
|
||||
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")
|
||||
if ("all" STREQUAL "${CMAKE_CUDA_ARCHITECTURES}"
|
||||
OR "native" STREQUAL "${CMAKE_CUDA_ARCHITECTURES}"
|
||||
OR "all-major" STREQUAL "${CMAKE_CUDA_ARCHITECTURES}")
|
||||
set(CUDA_FLAGS "-arch=${CMAKE_CUDA_ARCHITECTURES} ${CUDA_FLAGS}")
|
||||
else()
|
||||
# build -gencode sequence for multiple architectures
|
||||
foreach(ENTRY IN LISTS CMAKE_CUDA_ARCHITECTURES)
|
||||
set(CUDA_FLAGS
|
||||
"-gencode arch=compute_${ENTRY},code=sm_${ENTRY} ${CUDA_FLAGS}")
|
||||
endforeach()
|
||||
endif()
|
||||
else()
|
||||
# build cuda-gpu-arch sequence for multiple architectures
|
||||
# does not support all/all-major/native
|
||||
foreach(ENTRY IN LISTS CMAKE_CUDA_ARCHITECTURES)
|
||||
set(CUDA_FLAGS "-cuda-gpu-arch=sm_${ENTRY} ${CUDA_FLAGS}")
|
||||
endforeach()
|
||||
endif()
|
||||
# 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()
|
||||
# TODO: all, native, all-major require CMake 3.24+
|
||||
# backport support for CMake 3.18 to 3.24
|
||||
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_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()
|
||||
endif()
|
||||
set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD} CACHE STRING
|
||||
"CUDA standard to use.")
|
||||
@@ -230,13 +223,6 @@ else()
|
||||
set(MFEM_DEBUG OFF)
|
||||
endif()
|
||||
|
||||
# Shadow warnings for clang only; GCC's -Wshadow flags more.
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pedantic -Wall -Wshadow")
|
||||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pedantic -Wall")
|
||||
endif()
|
||||
|
||||
# Shared build on Windows
|
||||
if (WIN32 AND BUILD_SHARED_LIBS)
|
||||
# CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS works only with MSVC?
|
||||
@@ -256,16 +242,10 @@ endif()
|
||||
|
||||
# AMD HIP
|
||||
if (MFEM_USE_HIP)
|
||||
if (NOT CMAKE_HIP_ARCHITECTURES)
|
||||
if (HIP_ARCH)
|
||||
set(CMAKE_HIP_ARCHITECTURES CACHE STRING "HIP targets to compile for" "${HIP_ARCH}")
|
||||
set(GPU_TARGETS "${HIP_ARCH}" CACHE STRING "HIP targets to compile for" FORCE)
|
||||
endif()
|
||||
else()
|
||||
set(HIP_ARCH CACHE STRING "HIP targets to compile for" "${CMAKE_HIP_ARCHITECTURES}")
|
||||
set(GPU_TARGETS "${CMAKE_HIP_ARCHITECTURES}" CACHE STRING "HIP targets to compile for" FORCE)
|
||||
if (HIP_ARCH)
|
||||
message(STATUS "Using HIP architecture: ${HIP_ARCH}")
|
||||
set(GPU_TARGETS "${HIP_ARCH}" CACHE STRING "HIP targets to compile for")
|
||||
endif()
|
||||
message(STATUS "Using HIP architecture: ${CMAKE_HIP_ARCHITECTURES}")
|
||||
if (ROCM_PATH)
|
||||
list(INSERT CMAKE_PREFIX_PATH 0 ${ROCM_PATH})
|
||||
endif()
|
||||
@@ -298,19 +278,8 @@ if (MFEM_USE_OPENMP OR MFEM_USE_LEGACY_OPENMP)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Warn user if deprecated FETCH_TPLS is provided
|
||||
if (DEFINED FETCH_TPLS)
|
||||
message(STATUS "Setting MFEM_FETCH_TPLS to user-provided value of FETCH_TPLS (i.e., MFEM_FETCH_TPLS=${FETCH_TPLS})")
|
||||
set (MFEM_FETCH_TPLS FETCH_TPLS)
|
||||
message(DEPRECATION "The use of FETCH_TPLS is deprecated and will be removed in future verison. Please use MFEM_FETCH_TPLS instead.")
|
||||
endif()
|
||||
|
||||
# Umpire (must be included before hypre, so hypre can use it if needed)
|
||||
# Umpire (must be included before hypre, so hypre can use it if needed)
|
||||
if (MFEM_USE_UMPIRE)
|
||||
# umpire uses FindCUDA, which needs CMP0146=OLD in CMake >= 3.27
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.27.0)
|
||||
cmake_policy(SET CMP0146 OLD)
|
||||
endif()
|
||||
find_package(UMPIRE REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -431,15 +400,6 @@ if (MFEM_USE_STRUMPACK)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# cuDSS can only be enabled in CUDA
|
||||
if (MFEM_USE_CUDSS)
|
||||
if (MFEM_USE_CUDA)
|
||||
find_package(CUDSS REQUIRED)
|
||||
else()
|
||||
message(FATAL_ERROR " *** cuDSS requires that CUDA be enabled.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# GnuTLS
|
||||
if (MFEM_USE_GNUTLS)
|
||||
find_package(_GnuTLS REQUIRED)
|
||||
@@ -638,7 +598,7 @@ find_package(Threads REQUIRED)
|
||||
set(MFEM_TPLS OPENMP HYPRE LAPACK BLAS SuperLUDist STRUMPACK METIS SuiteSparse
|
||||
SUNDIALS PETSC SLEPC MUMPS AXOM FMS CONDUIT Ginkgo GNUTLS GSLIB HDF5
|
||||
NETCDF MPFR PUMI HIOP POSIXCLOCKS MFEMBacktrace ZLIB OCCA CEED RAJA UMPIRE
|
||||
ADIOS2 MKL_CPARDISO MKL_PARDISO AMGX MAGMA CUSPARSE CUBLAS CUDSS CALIPER CODIPACK
|
||||
ADIOS2 MKL_CPARDISO MKL_PARDISO AMGX MAGMA CUSPARSE CUBLAS CALIPER CODIPACK
|
||||
BENCHMARK PARELAG TRIBOL MPI_CXX HIP HIPBLAS HIPSPARSE MOONOLITH BLITZ
|
||||
ALGOIM ENZYME CUDA::cudart)
|
||||
|
||||
@@ -659,8 +619,6 @@ foreach(TPL IN LISTS MFEM_TPLS)
|
||||
endif()
|
||||
endforeach(TPL)
|
||||
|
||||
# reverse to remove the first instance of entries in TPL_LIBRARIES
|
||||
# so later duplicates are kept (for dependency ordering)
|
||||
list(REVERSE TPL_LIBRARIES)
|
||||
list(REMOVE_DUPLICATES TPL_LIBRARIES)
|
||||
list(REVERSE TPL_LIBRARIES)
|
||||
@@ -732,7 +690,6 @@ set(MFEM_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
# Declaring the library
|
||||
mfem_add_library(mfem ${SOURCES} ${HEADERS} ${MASTER_HEADERS})
|
||||
target_compile_features(mfem PUBLIC cxx_std_${CMAKE_CXX_STANDARD})
|
||||
# message(STATUS "TPL_LIBRARIES = ${TPL_LIBRARIES}")
|
||||
target_link_libraries(mfem PUBLIC ${TPL_LIBRARIES} ${TPL_TARGETS})
|
||||
if (TPL_TARGETS)
|
||||
@@ -879,12 +836,11 @@ add_dependencies(exec
|
||||
# - https://cmake.org/Bug/view.php?id=8438
|
||||
|
||||
# Add a target to copy the mfem data directory to the build directory
|
||||
# Implementable as a single copy_directory_if_different command w/ CMake >= 3.26
|
||||
file(GLOB DATA_FILES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/data/*)
|
||||
add_custom_target(copy_data
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory data
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DATA_FILES} data
|
||||
COMMENT "Syncing the data directory ...")
|
||||
add_custom_command(OUTPUT data_is_copied
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/data data
|
||||
COMMAND ${CMAKE_COMMAND} -E touch data_is_copied
|
||||
COMMENT "Copying the data directory ...")
|
||||
add_custom_target(copy_data DEPENDS data_is_copied)
|
||||
# Add 'copy_data' as a prerequisite for all executables, if the source and the
|
||||
# build directories are not the same.
|
||||
if (NOT ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}"))
|
||||
@@ -1016,15 +972,9 @@ install(FILES
|
||||
install(EXPORT ${PROJECT_NAME_UC}Targets
|
||||
DESTINATION ${INSTALL_CMAKE_DIR})
|
||||
|
||||
# Install the data directory if present, i.e. if the copy_data target is built
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data
|
||||
DESTINATION ${MFEM_INSTALL_DIR} OPTIONAL)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Create 'config.mk' from 'config.mk.in' for the build and install locations and
|
||||
# define install rules for 'config.mk' and 'test.mk'
|
||||
#-------------------------------------------------------------------------------
|
||||
if (MFEM_USE_CUDA OR MFEM_USE_HIP)
|
||||
option(MFEM_EXPORT_GPU_CONFIG "Export config.mk for GPU-enabled downstream packages" ON)
|
||||
endif()
|
||||
|
||||
mfem_export_mk_files()
|
||||
|
||||
+60
-74
@@ -3,12 +3,12 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/mfem/mfem/blob/master/LICENSE"><img alt="License" src="https://img.shields.io/badge/License-BSD-blue.svg"></a>
|
||||
<a href="https://github.com/mfem/mfem/releases/latest"><img alt="GitHub release" src="https://img.shields.io/github/v/release/mfem/mfem"></a>
|
||||
<a href="https://github.com/mfem/mfem/actions/workflows/repo-check.yml?query=branch%3Amaster"><img alt="Repo check" src="https://github.com/mfem/mfem/actions/workflows/repo-check.yml/badge.svg?branch=master"></a>
|
||||
<a href="https://github.com/mfem/mfem/actions/workflows/builds-and-tests.yml?query=branch%3Amaster"><img alt="Builds and Tests" src="https://github.com/mfem/mfem/actions/workflows/builds-and-tests.yml/badge.svg?branch=master"></a>
|
||||
<a href="https://github.com/mfem/mfem/blob/master/LICENSE"><img alt="License" src="https://img.shields.io/badge/License-BSD-brightgreen.svg"></a>
|
||||
<a href="https://github.com/mfem/mfem/actions?query=workflow%3Arepo-check+branch%3Amaster"><img alt="Repo check" src="https://github.com/mfem/mfem/actions/workflows/repo-check.yml/badge.svg?branch=master"></a>
|
||||
<a href="https://github.com/mfem/mfem/actions?query=workflow%3Abuild-analysis+branch%3Amaster"><img alt="Build Analysis" src="https://github.com/mfem/mfem/actions/workflows/mfem-analysis.yml/badge.svg?branch=master"></a>
|
||||
<a href="https://github.com/mfem/mfem/actions?query=workflow%3Abuilds-and-tests+branch%3Amaster"><img alt="Builds and Tests" src="https://github.com/mfem/mfem/actions/workflows/builds-and-tests.yml/badge.svg?branch=master"></a>
|
||||
<a href="https://ci.appveyor.com/project/mfem/mfem"><img alt="Build Status" src="https://ci.appveyor.com/api/projects/status/19non9sqm6msi2wy?svg=true"></a>
|
||||
<a href="https://docs.mfem.org/html/index.html"><img alt="Documentation" src="https://img.shields.io/badge/code-documented-brightgreen.svg"></a>
|
||||
<a href="https://docs.mfem.org/html/index.html"><img alt="Doxygen" src="https://img.shields.io/badge/code-documented-brightgreen.svg"></a>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -24,14 +24,6 @@ must be made under this license.
|
||||
Note also that MFEM has a [Code of Conduct](CODE_OF_CONDUCT.md). By participating
|
||||
in the MFEM community, you agree to abide by its rules.
|
||||
|
||||
## AI Policy
|
||||
- Use of AI code generation in MFEM is allowed but must be disclosed, e.g. by
|
||||
selecting the `AI-assisted` label on the PR.
|
||||
- By submitting a PR, the author acknowledges that they have reviewed and
|
||||
understand the changes they are proposing.
|
||||
- PR authors are still responsible for correctness, licensing, and attribution
|
||||
of all changes.
|
||||
|
||||
If you plan on contributing to MFEM, consider reviewing the
|
||||
[issue tracker](https://github.com/mfem/mfem/issues) first to check if a thread
|
||||
already exists for your desired feature or the bug you ran into. Use a pull
|
||||
@@ -84,7 +76,7 @@ Origin](#developers-certificate-of-origin-11) at the end of this file.*
|
||||
follow the [MFEM PR Rules](#mfem-pr-rules).
|
||||
- When your contribution is fully working and ready to be reviewed, add
|
||||
the `ready-for-review` label.
|
||||
- PRs are treated similarly to journal submission, with an "editor" assigning two
|
||||
- PRs are treated similarly to journal submission with an "editor" assigning two
|
||||
reviewers to evaluate the changes.
|
||||
- The reviewers have 3 weeks to evaluate the PR and work with the author to
|
||||
fix issues and implement improvements.
|
||||
@@ -125,7 +117,7 @@ The MFEM source code has the following structure:
|
||||
│ ├── petsc
|
||||
│ ├── pumi
|
||||
│ ├── sundials
|
||||
│ └── superlu
|
||||
| └── superlu
|
||||
├── fem
|
||||
│ ├── ceed
|
||||
│ ├── dfem
|
||||
@@ -147,22 +139,19 @@ The MFEM source code has the following structure:
|
||||
│ ├── adjoint
|
||||
│ ├── autodiff
|
||||
│ ├── common
|
||||
│ ├── contact
|
||||
│ ├── dfem
|
||||
│ ├── diag-smoothers
|
||||
│ ├── dpg
|
||||
│ ├── electromagnetics
|
||||
│ ├── fluids
|
||||
│ ├── gslib
|
||||
│ ├── hdiv-linear-solver
|
||||
│ ├── hooke
|
||||
│ ├── meshing
|
||||
│ ├── mtop
|
||||
│ ├── multidomain
|
||||
│ ├── navier
|
||||
│ ├── nurbs
|
||||
│ ├── parelag
|
||||
│ ├── performance
|
||||
│ ├── plasma
|
||||
│ ├── shifted
|
||||
│ ├── solvers
|
||||
│ ├── spde
|
||||
@@ -193,15 +182,15 @@ respectively.
|
||||
|
||||
- The main finite element classes are:
|
||||
+ [`FiniteElement`](https://docs.mfem.org/html/classmfem_1_1FiniteElement.html)
|
||||
+ [`FiniteElementCollection`](https://docs.mfem.org/html/classmfem_1_1FiniteElementCollection.html)
|
||||
+ [`FiniteElementCollection`](https://docs.mfem.org/html/classmfem_1_1FiniteElement.html)
|
||||
+ [`FiniteElementSpace`](https://docs.mfem.org/html/classmfem_1_1FiniteElementSpace.html)
|
||||
+ [`GridFunction`](https://docs.mfem.org/html/classmfem_1_1GridFunction.html)
|
||||
+ [`BilinearFormIntegrator`](https://docs.mfem.org/html/classmfem_1_1BilinearFormIntegrator.html) and [`LinearFormIntegrator`](https://docs.mfem.org/html/classmfem_1_1LinearFormIntegrator.html)
|
||||
+ [`LinearForm`](https://docs.mfem.org/html/classmfem_1_1LinearForm.html), [`BilinearForm`](https://docs.mfem.org/html/classmfem_1_1BilinearForm.html) and [`MixedBilinearForm`](https://docs.mfem.org/html/classmfem_1_1MixedBilinearForm.html)
|
||||
+ [`LinearForm`](https://docs.mfem.org/html/classmfem_1_1LinearFormIntegrator.html), [`BilinearForm`](https://docs.mfem.org/html/classmfem_1_1BilinearForm.html) and [`MixedBilinearForm`](https://docs.mfem.org/html/classmfem_1_1MixedBilinearForm.html)
|
||||
|
||||
- The main linear algebra classes and sources are
|
||||
+ [`Operator`](https://docs.mfem.org/html/classmfem_1_1Operator.html) and [`BilinearForm`](https://docs.mfem.org/html/classmfem_1_1BilinearForm.html)
|
||||
+ [`Vector`](https://docs.mfem.org/html/classmfem_1_1Vector.html) and [`LinearForm`](https://docs.mfem.org/html/classmfem_1_1LinearForm.html)
|
||||
+ [`Vector`](https://docs.mfem.org/html/classmfem_1_1BilinearForm.html) and [`LinearForm`](https://docs.mfem.org/html/classmfem_1_1LinearForm.html)
|
||||
+ [`DenseMatrix`](https://docs.mfem.org/html/classmfem_1_1DenseMatrix.html) and [`SparseMatrix`](https://docs.mfem.org/html/classmfem_1_1SparseMatrix.html)
|
||||
+ Sparse [smoothers](https://docs.mfem.org/html/sparsesmoothers_8hpp.html) and linear [solvers](https://docs.mfem.org/html/solvers_8hpp.html)
|
||||
|
||||
@@ -213,8 +202,8 @@ shared geometric entities between different tasks. The parallel source files
|
||||
have a `p` prefix, e.g. `pmesh.cpp` vs. the serial `mesh.cpp`.
|
||||
|
||||
- The main parallel classes are
|
||||
+ [`ParMesh`](https://docs.mfem.org/html/classmfem_1_1ParMesh.html)
|
||||
+ [`ParNCMesh`](https://docs.mfem.org/html/classmfem_1_1ParNCMesh.html)
|
||||
+ [`ParMesh`](https://docs.mfem.org/html/solvers_8hpp.html)
|
||||
+ [`ParNCMesh`](https://docs.mfem.org/html/classmfem_1_1ParMesh.html)
|
||||
+ [`ParFiniteElementSpace`](https://docs.mfem.org/html/classmfem_1_1ParFiniteElementSpace.html)
|
||||
+ [`ParGridFunction`](https://docs.mfem.org/html/classmfem_1_1ParGridFunction.html)
|
||||
+ [`ParBilinearForm`](https://docs.mfem.org/html/classmfem_1_1ParBilinearForm.html) and [`ParLinearForm`](https://docs.mfem.org/html/classmfem_1_1ParLinearForm.html)
|
||||
@@ -224,14 +213,14 @@ have a `p` prefix, e.g. `pmesh.cpp` vs. the serial `mesh.cpp`.
|
||||
#### GPU and general device support
|
||||
|
||||
GPU and multi-core CPU support is based on device kernels supporting different
|
||||
backends (CUDA, HIP, OCCA, RAJA, OpenMP, etc.) and an internal lightweight
|
||||
backends (CUDA, OCCA, RAJA, OpenMP, etc.) and an internal lightweight
|
||||
device/host memory manager.
|
||||
|
||||
- The main device-relevant classes and sources are:
|
||||
+ [`Device`](https://docs.mfem.org/html/device_8hpp.html)
|
||||
+ [`MemoryManager`](https://docs.mfem.org/html/mem_manager_8hpp.html)
|
||||
+ the [`mfem::forall`](https://docs.mfem.org/html/forall_8hpp.html) function
|
||||
+ the [`cuda.hpp`](https://docs.mfem.org/html/cuda_8hpp.html), [`hip.hpp`](https://docs.mfem.org/html/hip_8hpp.html) and [`occa.hpp`](https://docs.mfem.org/html/occa_8hpp.html) files
|
||||
+ the [`cuda.hpp`](https://docs.mfem.org/html/cuda_8hpp.html) and [`occa.hpp`](https://docs.mfem.org/html/occa_8hpp.html) files
|
||||
|
||||
#### Utilities, building and documentation
|
||||
- The `general/` directory contains C++ classes that serve as utilities for
|
||||
@@ -245,8 +234,8 @@ device/host memory manager.
|
||||
- `examples` and `miniapps` respectively gather simple and more fully-featured
|
||||
demonstrations of the usage on MFEM. They both rely on `data/` for the
|
||||
collection of meshes.
|
||||
- The `tests/` directory contains a unit test suite, additional tests, and
|
||||
benchmarks.
|
||||
- The `tests/` directory contains a unit test suite and will later contain more
|
||||
tests that run example codes.
|
||||
|
||||
See also the [code overview](https://mfem.org/code-overview/) section on the MFEM
|
||||
website.
|
||||
@@ -280,8 +269,8 @@ Before you can start, you need a GitHub account, here are a few suggestions:
|
||||
the top of https://github.com/mfem.
|
||||
- Consider making your membership public by going to https://github.com/orgs/mfem/people
|
||||
and clicking on the organization visibility drop box next to your name.
|
||||
- Project discussions and announcements will be posted at https://github.com/orgs/mfem/discussions,
|
||||
tagging the `@mfem/everyone` team when appropriate.
|
||||
- Project discussions and announcements will be posted at
|
||||
https://github.com/orgs/mfem/teams/everyone.
|
||||
|
||||
#### Structure
|
||||
- The MFEM source code is in the [mfem](https://github.com/mfem/mfem)
|
||||
@@ -341,12 +330,11 @@ Before you can start, you need a GitHub account, here are a few suggestions:
|
||||
- Well-designed simple code is frequently more general and powerful.
|
||||
- Lean code base is easier to understand by new collaborators.
|
||||
- New features should be added only if they are necessary or generally useful.
|
||||
- Introduction of language constructs not currently used in MFEM should be
|
||||
- Introduction of language constructions not currently used in MFEM should be
|
||||
justified and generally avoided (to maintain portability to various systems
|
||||
and compilers, including early access hardware).
|
||||
- We prefer basic C++. Use C++17 features judiciously, prioritizing readability,
|
||||
consistency with existing MFEM code, and portability to different systems,
|
||||
compilers and device backends.
|
||||
- We prefer basic C++ and the C++03 standard, to keep the code readable by
|
||||
a large audience and to make sure it compiles anywhere.
|
||||
|
||||
- *Keep the code general and reasonably efficient*
|
||||
- The main goal is fast prototyping for research and application development.
|
||||
@@ -389,7 +377,7 @@ Before you can start, you need a GitHub account, here are a few suggestions:
|
||||
- When your branch is ready for other developers to review / comment on
|
||||
the code, create a pull request towards `mfem:master`.
|
||||
|
||||
- Pull requests typically have titles like:
|
||||
- Pull request typically have titles like:
|
||||
|
||||
`Description [new-feature-dev]`
|
||||
|
||||
@@ -410,12 +398,12 @@ Before you can start, you need a GitHub account, here are a few suggestions:
|
||||
- Add a description, appropriate labels and assign yourself to the PR. The MFEM
|
||||
team will add reviewers as appropriate.
|
||||
|
||||
- List outstanding TODO items in the description.
|
||||
- List outstanding TODO items in the description, see PR #222 for an example.
|
||||
|
||||
- When your contribution is fully working and ready to be reviewed, add
|
||||
or request the `ready-for-review` label.
|
||||
the `ready-for-review` label.
|
||||
|
||||
- PRs are treated similarly to journal submission, with an "editor" assigning
|
||||
- PRs are treated similarly to journal submission with an "editor" assigning
|
||||
two reviewers to evaluate the changes. The reviewers have 3 weeks to evaluate
|
||||
the PR and work with the author to implement improvements and fix issues.
|
||||
|
||||
@@ -441,7 +429,7 @@ Before you can start, you need a GitHub account, here are a few suggestions:
|
||||
checks in GitHub Actions enforce MFEM-specific rules which are explained in
|
||||
the error messages and the `tests/scripts` directory.
|
||||
|
||||
- Also note that the tests `branch-history` and `repo-check` found in GitHub
|
||||
- Also note that the tests `branch-history` and `repos-checks` found in GitHub
|
||||
Actions can be triggered automatically before each push using git hooks. See
|
||||
the [git hooks README](config/githooks/README.md) for a detailed explanation.
|
||||
|
||||
@@ -498,15 +486,15 @@ Everyone on the MFEM team can be asked to serve as a reviewer on a PR in their a
|
||||
|
||||
3. To ensure the quality of the PR by making sure that the code adheres to the [Developer Guidelines](#developer-guidelines), e.g. all methods, data members, and functions have documentation, including data ownership and lifetime, new examples/miniapps have a corresponding PR in mfem/web, major features have `CHANGELOG` entries, etc.
|
||||
|
||||
4. To seek help from the editors in case of difficulties.
|
||||
3. To seek help from the editors in case of difficulties.
|
||||
|
||||
5. To complete the review in a timely manner: 3 weeks from assignment.
|
||||
4. To complete the review in a timely manner: 3 weeks from assignment.
|
||||
|
||||
6. To test the PR thoroughly before merging in *next*. The PR author is also encouraged to perform testing and inform the reviewers about the results.
|
||||
5. To test the PR thoroughly before merging in *next*. The PR author is also encouraged to perform testing and inform the reviewers about the results.
|
||||
|
||||
7. To monitor the PR impact on the testing in the *next* branch and alert the editors that the PR is ready for merging in *master*.
|
||||
6. To monitor the PR impact on the testing in the *next* branch and alert the editors that the PR is ready for merging in *master*.
|
||||
|
||||
8. The review of bugfixes should be expedited proportional to their importance. The review window can be much less than three weeks in such cases.
|
||||
7. The review of bugfixes should be expedited proportional to their importance. The review window can be much less than three weeks in such cases.
|
||||
|
||||
#### Responsibilities of Authors
|
||||
|
||||
@@ -532,30 +520,30 @@ Before a PR can be merged, it should satisfy the following:
|
||||
- [ ] Code builds.
|
||||
- [ ] Code passes `make style`.
|
||||
- [ ] Update `CHANGELOG`:
|
||||
- [ ] Is this a new feature users need to be aware of? New or updated example or miniapp?
|
||||
- [ ] Does it make sense to create a new section in the `CHANGELOG` to group with other related features?
|
||||
- [ ] Is this a new feature users need to be aware of? New or updated example or miniapp?
|
||||
- [ ] Does it make sense to create a new section in the `CHANGELOG` to group with other related features?
|
||||
- [ ] Update `INSTALL`:
|
||||
- [ ] Has a new optional library been added? If so, what range of versions of this library are required? (*Make sure the external library is compatible with our BSD license, e.g. it is not licensed under GPL!*)
|
||||
- [ ] Have the version ranges for any required or optional libraries changed?
|
||||
- [ ] Does `make` or `cmake` have a new target?
|
||||
- [ ] Did the requirements or the installation process change? *(rare)*
|
||||
- [ ] Had a new optional library been added? If so, what range of versions of this library are required? (*Make sure the external library is compatible with our BSD license, e.g. it is not licensed under GPL!*)
|
||||
- [ ] Have the version ranges for any required or optional libraries changed?
|
||||
- [ ] Does `make` or `cmake` have a new target?
|
||||
- [ ] Did the requirements or the installation process change? *(rare)*
|
||||
- [ ] Update continuous integration server configurations if necessary (e.g. with new version requirements for each of MFEM's dependencies)
|
||||
- [ ] `.github`
|
||||
- [ ] `.appveyor.yml`
|
||||
- [ ] `.github`
|
||||
- [ ] `.appveyor.yml`
|
||||
- [ ] Update `.gitignore`:
|
||||
- [ ] Check if `make distclean; git status` shows any files that were generated from the source by the project (not an IDE) but we don't want to track in the repository.
|
||||
- [ ] Add new patterns (just for the new files above) and re-run the above test.
|
||||
- [ ] Check if `make distclean; git status` shows any files that were generated from the source by the project (not an IDE) but we don't want to track in the repository.
|
||||
- [ ] Add new patterns (just for the new files above) and re-run the above test.
|
||||
- [ ] New examples:
|
||||
- [ ] All sample runs at the top of the example source file work.
|
||||
- [ ] Update `examples/makefile`:
|
||||
- [ ] All sample runs at the top of the example source file work.
|
||||
- [ ] Update `examples/makefile`:
|
||||
- [ ] Add the example code to the appropriate `SEQ_EXAMPLES` and `PAR_EXAMPLES` variables.
|
||||
- [ ] Add any files generated by it to the `clean` target.
|
||||
- [ ] Add the example binary and any files generated by it to the top-level `.gitignore` file.
|
||||
- [ ] Update `examples/CMakeLists.txt`:
|
||||
- [ ] Update `examples/CMakeLists.txt`:
|
||||
- [ ] Add the example code to the `ALL_EXE_SRCS` variable.
|
||||
- [ ] Make sure `THIS_TEST_OPTIONS` is set correctly for the new example.
|
||||
- [ ] List the new example in `doc/CodeDocumentation.dox`.
|
||||
- [ ] If new examples directory (e.g. `examples/pumi`), list it in `doc/CodeDocumentation.conf.in`
|
||||
- [ ] If new examples directory (e.g.`examples/pumi`), list it in `doc/CodeDocumentation.conf.in`
|
||||
- [ ] Companion pull request for documentation in [mfem/web](https://github.com/mfem/web) repo:
|
||||
- [ ] Update or add example-specific documentation, see e.g. the `src/examples.md`.
|
||||
- [ ] Add the description, labels and screenshots in `src/examples.md` and `src/img`.
|
||||
@@ -572,13 +560,13 @@ Before a PR can be merged, it should satisfy the following:
|
||||
- [ ] Add/update the `CMakeLists.txt` file in the new miniapp directory.
|
||||
- [ ] Consider adding a new test for the new miniapp.
|
||||
- [ ] List the new miniapp in `doc/CodeDocumentation.dox`
|
||||
- [ ] If new miniapps directory (e.g. `miniapps/nurbs`), add it to `MINIAPP_SUBDIRS` in the `makefile`.
|
||||
- [ ] If new miniapps directory (e.g. `miniapps/nurbs`), list it in `doc/CodeDocumentation.conf.in`
|
||||
- [ ] If new miniapps directory (e.g.`miniapps/nurbs`), add it to `MINIAPP_SUBDIRS` in the `makefile`.
|
||||
- [ ] If new miniapps directory (e.g.`miniapps/nurbs`), list it in `doc/CodeDocumentation.conf.in`
|
||||
- [ ] Companion pull request for documentation in [mfem/web](https://github.com/mfem/web) repo:
|
||||
- [ ] Update or add miniapp-specific documentation, see e.g. the `src/meshing.md` and `src/electromagnetics.md` files.
|
||||
- [ ] Add the description, labels and screenshots in `src/examples.md` and `src/img`.
|
||||
- [ ] The miniapps go at the end of the page, and are usually listed only under a specific "Application (PDE)" category.
|
||||
- [ ] Add a short description of the miniapp in the "Extensive Examples" section of `features.md`.
|
||||
- [ ] Update or add miniapp-specific documentation, see e.g. the `src/meshing.md` and `src/electromagnetics.md` files.
|
||||
- [ ] Add the description, labels and screenshots in `src/examples.md` and `src/img`.
|
||||
- [ ] The miniapps go at the end of the page, and are usually listed only under a specific "Application (PDE)" category.
|
||||
- [ ] Add a short description of the miniapp in the "Extensive Examples" section of `features.md`.
|
||||
- [ ] New capability:
|
||||
- [ ] All new public, protected, and private classes, methods, data members, and functions have full Doxygen-style documentation in source comments. Documentation should include descriptions of member data, function arguments and return values, template parameters, and prerequisites for calling new functions.
|
||||
- [ ] Pointer arguments and return values must specify whether ownership is being transferred or lent with the call.
|
||||
@@ -680,7 +668,7 @@ MFEM uses a `master`/`next`-branch workflow as described below:
|
||||
- [ ] Update URL shortlinks:
|
||||
- [ ] Create a shortlink at [http://bit.ly/](http://bit.ly/) for the release tarball, e.g. https://mfem.github.io/releases/mfem-3.1.tgz.
|
||||
- [ ] (LLNL only) Add and commit the new shortlink in the `links` and `links-mfem` files of the internal `mfem/downloads` repo.
|
||||
- [ ] Add the new shortlinks to the MFEM package in `spack`.
|
||||
- [ ] Add the new shortlinks to the MFEM packages in `spack`, `homebrew/science`, `VisIt`, etc.
|
||||
- [ ] Update website in `mfem/web` repo:
|
||||
- Update version and shortlinks in `src/index.md` and `src/download.md`.
|
||||
- Use [cloc-1.62.pl](http://cloc.sourceforge.net/) and `ls -lh` to estimate the SLOC and the tarball size in `src/download.md`.
|
||||
@@ -732,24 +720,22 @@ commit or push, see the [README](config/githooks/README.md) in the `config/githo
|
||||
directory.
|
||||
|
||||
|
||||
### GitHub Actions smoke tests
|
||||
|
||||
### Linux and Mac smoke tests
|
||||
We use GitHub Actions to drive the default tests on the `master` and `next`
|
||||
branches. See the `.github/workflows` files and the logs at
|
||||
[https://github.com/mfem/mfem/actions](https://github.com/mfem/mfem/actions).
|
||||
|
||||
GitHub Actions testing should be kept lightweight, as there is a time
|
||||
constraint on jobs. The current workflows cover Linux, macOS, and Windows
|
||||
configurations.
|
||||
Testing using GitHub Actions should be kept lightweight, as there is a time
|
||||
constraint on jobs. Two virtual machines are configured - Mac (OS X) and Linux.
|
||||
|
||||
- Tests on the `master` branch are triggered whenever a PR is issued on this branch.
|
||||
- Tests on the `next` branch are currently scheduled to run each night.
|
||||
|
||||
### Additional Windows smoke test
|
||||
|
||||
We also use Appveyor to test building with the MS Visual C++ compiler in a Windows
|
||||
environment, as well as to test the CMake build. See the `.appveyor.yml` file
|
||||
and the build logs at
|
||||
### Windows smoke test
|
||||
We use Appveyor to test building with the MS Visual C++ compiler in a Windows
|
||||
environment, as well as to test the CMake build. See the `.appveyor` file and the
|
||||
build logs at
|
||||
[https://ci.appveyor.com/project/mfem/mfem](https://ci.appveyor.com/project/mfem/mfem).
|
||||
|
||||
CMake is used to generate the MSVC Project files and drive the build. A release
|
||||
|
||||
@@ -38,13 +38,14 @@ the option MFEM_USE_METIS.
|
||||
MFEM also includes support for devices such as GPUs, and programming models such
|
||||
as CUDA, HIP, OCCA, OpenMP and RAJA.
|
||||
|
||||
- Starting with version 4.9, MFEM requires a C++17 compiler.
|
||||
- Starting with version 4.0, MFEM requires a C++11 compiler. We recommend using
|
||||
a newer compiler, e.g. GCC version 4.9 or higher.
|
||||
|
||||
- CUDA support requires an NVIDIA GPU and an installation of the CUDA Toolkit
|
||||
https://developer.nvidia.com/cuda-toolkit
|
||||
|
||||
- HIP support requires an AMD GPU and an installation of the ROCm software stack
|
||||
https://rocm.docs.amd.com
|
||||
https://rocmdocs.amd.com
|
||||
|
||||
- OCCA support requires the OCCA library
|
||||
https://libocca.org
|
||||
@@ -82,9 +83,9 @@ Serial build:
|
||||
Parallel build:
|
||||
(download hypre and METIS 4 from above URLs)
|
||||
(build METIS 4 in ../metis-4.0 relative to mfem/)
|
||||
(for METIS 5, see https://mfem.org/building/#parallel-build-using-metis-5)
|
||||
(build hypre in ../hypre relative to mfem/)
|
||||
make parallel -j 4
|
||||
(For METIS 5, see https://mfem.org/building/#parallel-build-using-metis-5)
|
||||
|
||||
CUDA build:
|
||||
make cuda -j 4
|
||||
@@ -114,15 +115,15 @@ Serial build:
|
||||
Parallel build:
|
||||
(download hypre and METIS 4 from above URLs)
|
||||
(build METIS 4 in ../metis-4.0 relative to mfem/)
|
||||
(for METIS 5, see https://mfem.org/building/#parallel-build-using-metis-5)
|
||||
(build hypre in ../hypre relative to mfem/)
|
||||
mkdir <mfem-build-dir> ; cd <mfem-build-dir>
|
||||
cmake <mfem-source-dir> -DMFEM_USE_MPI=YES
|
||||
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-build-dir> ; cd <mfem-build-dir>
|
||||
cmake <mfem-source-dir> -DMFEM_USE_MPI=YES -DMFEM_FETCH_TPLS=YES
|
||||
mkdir <mfem-buil-dir> ; cd <mfem-build-dir>
|
||||
cmake <mfem-source-dir> -DMFEM_USE_MPI=YES -DFETCH_TPLS=YES
|
||||
make -j 4
|
||||
|
||||
CUDA build:
|
||||
@@ -133,8 +134,7 @@ CUDA build:
|
||||
|
||||
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_HIP=YES -DHIP_ARCH=gfx942 -DCMAKE_CXX_COMPILER=amdclang++ -DCMAKE_HIP_COMPILER=amdclang++
|
||||
make -j 4
|
||||
|
||||
Example codes (serial/parallel, depending on the build):
|
||||
@@ -269,7 +269,6 @@ Compilers:
|
||||
CXX - C++ compiler, serial build
|
||||
MPICXX - MPI C++ compiler, parallel build
|
||||
CUDA_CXX - The CUDA compiler, 'nvcc' or 'clang++'
|
||||
HIP_CXX - The HIP compiler, e.g. 'hipcc'
|
||||
|
||||
Compiler options:
|
||||
OPTIM_FLAGS - Options for optimized build
|
||||
@@ -396,11 +395,6 @@ MFEM_USE_STRUMPACK = YES/NO
|
||||
classes. When enabled, this option uses the STRUMPACK_* library options, see
|
||||
below.
|
||||
|
||||
MFEM_USE_CUDSS = YES/NO
|
||||
Enable MFEM functionality based on the cuDSS library. When using cuDSS, CUDA
|
||||
support must be also enabled in MFEM, i.e. MFEM_USE_CUDA=YES must be set.
|
||||
When enabled, this option uses the CUDSS_* library options, see below.
|
||||
|
||||
MFEM_USE_GINKGO = YES/NO
|
||||
Enable MFEM functionality based on the Ginkgo library, which provides
|
||||
iterative linear solvers and preconditioners with OpenMP, CUDA backends, see
|
||||
@@ -560,13 +554,13 @@ MFEM_USE_RAJA = YES/NO
|
||||
MFEM_USE_OCCA = YES/NO
|
||||
Enables support for the OCCA library in MFEM. OCCA is an open-source library
|
||||
which aims to make it easy to program different types of devices (e.g. CPU,
|
||||
GPU, FPGA) by providing a unified API for interacting with JIT-compiled
|
||||
GPU, FPGA) by providing an unified API for interacting with JIT-compiled
|
||||
backends. In order to use the OCCA CUDA backend, CUDA support must be enabled
|
||||
in MFEM as well, i.e. MFEM_USE_CUDA=YES must be set.
|
||||
|
||||
MFEM_USE_GSLIB = YES/NO
|
||||
Enables MFEM functionality based on the GSLIB library, and specifically its
|
||||
FindPoints component, which provides robust algorithms to evaluate finite
|
||||
FindPoints component, which provides a robust algorithms to evaluate finite
|
||||
element functions in a collection of points in physical space. When enabled,
|
||||
the user can use the GSLIB-FindPoints methods as shown in miniapps/gslib.
|
||||
|
||||
@@ -725,24 +719,13 @@ The specific libraries and their options are:
|
||||
Options: STRUMPACK_OPT, STRUMPACK_LIB.
|
||||
Versions: STRUMPACK >= 3.0.0.
|
||||
|
||||
- CUDSS (optional), used when MFEM_USE_CUDSS = YES. Note that CUDSS requires
|
||||
CUDA 12.x toolkit and the cuDSS libraries. The supported communication backend
|
||||
is OpenMPI 4.x (default), and OpenMPI 4.x or a later version must be pre-built.
|
||||
The source files in the cuDSS tarball provide guidance for developing custom
|
||||
MPI implementations.
|
||||
URL: https://developer.nvidia.com/cudss
|
||||
https://docs.nvidia.com/cuda/cudss/advanced_features.html#communication-layer-library-in-cudss
|
||||
Options: CUDSS_OPT, CUDSS_LIB.
|
||||
Versions: cuDSS >= 0.6.0.
|
||||
|
||||
- Ginkgo (optional), used when MFEM_USE_GINKGO = YES. Ginkgo may have additional
|
||||
requirements and module-specific dependencies; see the webpage below.
|
||||
- Ginkgo (optional), used when MFEM_USE_GINKGO = YES. Note that Ginkgo needs a
|
||||
C++ compiler that supports the C++-17 standard. For additional requirements
|
||||
and dependencies of specific modules, see the Ginkgo webpage below.
|
||||
URL: https://ginkgo-project.github.io
|
||||
Options: GINKGO_OPT, GINKGO_LIB, GINKGO_DIR, GINKGO_BUILD_TYPE (Release or
|
||||
Debug).
|
||||
Versions: Ginkgo >= 1.9.0. When building Ginkgo with distributed support, a
|
||||
recent version of the "develop" branch is required (1.11 as defined
|
||||
in include/ginkgo/config.hpp).
|
||||
Versions: Ginkgo >= 1.9.0.
|
||||
|
||||
- AmgX (optional), used when MFEM_USE_AMGX = YES.
|
||||
URL: https://github.com/NVIDIA/AMGX
|
||||
@@ -808,7 +791,7 @@ The specific libraries and their options are:
|
||||
Options: CONDUIT_OPT, CONDUIT_LIB.
|
||||
Versions: Conduit >= 0.3.1.
|
||||
|
||||
- ADIOS2 (optional), used when MFEM_USE_ADIOS2 = YES.
|
||||
- ADIOS2 (optional) used when MFEM_USE_ADIOS2 = YES.
|
||||
URL: https://adios2.readthedocs.io/
|
||||
Versions: ADIOS >= 2.5.0.
|
||||
|
||||
@@ -884,7 +867,7 @@ The specific libraries and their options are:
|
||||
Options: RAJA_DIR, RAJA_OPT, RAJA_LIB.
|
||||
Versions: RAJA >= 2022.10.3.
|
||||
|
||||
- Moonolith (optional), used when MFEM_USE_MOONOLITH = YES.
|
||||
- Moonolith (optional), use when MFEM_USE_MOONOLITH = YES.
|
||||
URL: https://bitbucket.org/zulianp/par_moonolith
|
||||
Options: MOONOLITH_DIR
|
||||
Versions: MOONOLITH >= 1.1.0.
|
||||
@@ -972,7 +955,7 @@ CMAKE_BUILD_TYPE which can be set to standard values like "Debug", and "Release"
|
||||
To use a specific generator use the "-G <generator>" option of cmake:
|
||||
|
||||
cmake <mfem-source-dir> -G "Xcode"
|
||||
cmake <mfem-source-dir> -G "Visual Studio 17 2022"
|
||||
cmake <mfem-source-dir> -G "Visual Studio 12 2013"
|
||||
cmake <mfem-source-dir> -G "MinGW Makefiles"
|
||||
|
||||
With CMake it is possible to build MFEM as a shared library using the standard
|
||||
@@ -1098,10 +1081,9 @@ 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.
|
||||
MFEM_FETCH_TPLS - Enable fetching of all supported third-party libraries.
|
||||
MFEM_FETCH_GSLIB - Enable fetching of gslib.
|
||||
MFEM_FETCH_HYPRE - Enable fetching of hypre.
|
||||
MFEM_FETCH_METIS - Enable fetching of metis.
|
||||
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):
|
||||
---------------------------
|
||||
@@ -1167,7 +1149,6 @@ 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.
|
||||
|
||||
- GSLIB
|
||||
- HYPRE
|
||||
- METIS
|
||||
|
||||
@@ -1217,7 +1198,7 @@ larger problems, there are two options:
|
||||
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`.
|
||||
ROCM install, as well as having `$ROCM_PATH/bin` in `PATH`.
|
||||
|
||||
Specific options for RAJA+HIP+MPI
|
||||
=================================
|
||||
|
||||
@@ -28,7 +28,6 @@ license files. These software products and their licenses are as follows:
|
||||
* AmgXWrapper (linalg/amgxsolver.{hpp,cpp}) -- MIT license
|
||||
* Catch++ (tests/unit/catch.hpp) -- Boost 1.0 license
|
||||
* Gecko (general/gecko.{cpp,hpp}) -- BSD 3-clause license
|
||||
* gslib (fem/gslib.{cpp,hpp}, mesh/bb_grid_map.{cpp,hpp}) -- BSD 3-clause license
|
||||
* Picojson (fem/picojson.h) -- Custom 2-clause license
|
||||
* TinyXML2 (general/tinyxml2.{cpp,h}) -- zlib license
|
||||
* Zstr (general/zstr.hpp) -- MIT license
|
||||
|
||||
@@ -35,7 +35,6 @@ set(MFEM_USE_SUITESPARSE @MFEM_USE_SUITESPARSE@)
|
||||
set(MFEM_USE_SUPERLU @MFEM_USE_SUPERLU@)
|
||||
set(MFEM_USE_MUMPS @MFEM_USE_MUMPS@)
|
||||
set(MFEM_USE_STRUMPACK @MFEM_USE_STRUMPACK@)
|
||||
set(MFEM_USE_CUDSS @MFEM_USE_CUDSS@)
|
||||
set(MFEM_USE_GINKGO @MFEM_USE_GINKGO@)
|
||||
set(MFEM_USE_AMGX @MFEM_USE_AMGX@)
|
||||
set(MFEM_USE_MAGMA @MFEM_USE_MAGMA@)
|
||||
@@ -110,14 +109,6 @@ if (MFEM_USE_RAJA)
|
||||
find_dependency(RAJA)
|
||||
endif()
|
||||
|
||||
if (MFEM_USE_CUDSS)
|
||||
find_dependency(cudss)
|
||||
endif (MFEM_USE_CUDSS)
|
||||
|
||||
if (MFEM_USE_UMPIRE)
|
||||
find_dependency(umpire)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET mfem)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/MFEMTargets.cmake)
|
||||
endif (NOT TARGET mfem)
|
||||
|
||||
@@ -108,15 +108,6 @@
|
||||
// Enable MFEM functionality based on the STRUMPACK library.
|
||||
#cmakedefine MFEM_USE_STRUMPACK
|
||||
|
||||
// Enable MFEM functionality based on the cuDSS library.
|
||||
#cmakedefine MFEM_USE_CUDSS
|
||||
|
||||
// CUDSS communication layer library path
|
||||
#cmakedefine MFEM_CUDSS_COMM_LIB "@MFEM_CUDSS_COMM_LIB@"
|
||||
|
||||
// CUDSS threading layer library path
|
||||
#cmakedefine MFEM_CUDSS_THREADING_LIB "@MFEM_CUDSS_THREADING_LIB@"
|
||||
|
||||
// Enable functionality based on the Ginkgo library.
|
||||
#cmakedefine MFEM_USE_GINKGO
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
if (NOT cudss_DIR AND CUDSS_DIR)
|
||||
set(cudss_DIR ${CUDSS_DIR}/lib/cmake/cudss)
|
||||
endif()
|
||||
message(STATUS "Looking for CUDSS ...")
|
||||
message(STATUS " in CUDSS_DIR = ${CUDSS_DIR}")
|
||||
message(STATUS " cudss_DIR = ${cudss_DIR}")
|
||||
find_package(cudss)
|
||||
set(CUDSS_FOUND ${cudss_FOUND})
|
||||
set(CUDSS_LIBRARIES "cudss")
|
||||
if (CUDSS_FOUND)
|
||||
message(STATUS
|
||||
"Found CUDSS target: ${CUDSS_LIBRARIES} (version: ${cudss_VERSION})")
|
||||
else()
|
||||
set(msg STATUS)
|
||||
if (CUDSS_FIND_REQUIRED)
|
||||
set(msg FATAL_ERROR)
|
||||
endif()
|
||||
message(${msg}
|
||||
"CUDSS not found. Please set CUDSS_DIR to the install prefix.")
|
||||
endif()
|
||||
|
||||
if(CUDSS_FOUND AND TARGET cudss)
|
||||
get_target_property(CUDSS_LIBRARY_LOCATION cudss IMPORTED_LOCATION)
|
||||
if(NOT CUDSS_LIBRARY_LOCATION)
|
||||
get_target_property(CUDSS_LIBRARY_LOCATION cudss IMPORTED_LOCATION_RELEASE)
|
||||
endif()
|
||||
if(CUDSS_LIBRARY_LOCATION)
|
||||
get_filename_component(CUDSS_LIBRARY_DIR "${CUDSS_LIBRARY_LOCATION}" DIRECTORY)
|
||||
else()
|
||||
message(WARNING "Could not determine the location of the cuDSS library.")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "cuDSS target not available; cannot determine library directory.")
|
||||
endif()
|
||||
|
||||
# Set the full name of the cuDSS threading library if OpenMP is enabled.
|
||||
# The threading layer library (libcudss_mtlayer_gomp.so) is located under the
|
||||
# cuDSS library directory by default.
|
||||
if (MFEM_USE_OPENMP)
|
||||
find_file(
|
||||
CUDSS_THREADING_LIB
|
||||
NAMES libcudss_mtlayer_gomp.so
|
||||
PATHS ${CUDSS_LIBRARY_DIR}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
if (NOT DEFINED MFEM_CUDSS_THREADING_LIB AND CUDSS_THREADING_LIB)
|
||||
set(MFEM_CUDSS_THREADING_LIB "${CUDSS_THREADING_LIB}")
|
||||
endif()
|
||||
message(STATUS "CUDSS threading layer library: ${MFEM_CUDSS_THREADING_LIB}")
|
||||
endif()
|
||||
|
||||
# Set the full name of the cuDSS communication library if MFEM use OpenMPI.
|
||||
# The communication layer library (libcudss_commlayer_mpi.so) is located under the
|
||||
# cuDSS library directory by default.
|
||||
# The communication layer library is used pre-built communication layers for OpenMPI
|
||||
# by default.
|
||||
if (MFEM_USE_MPI)
|
||||
find_file(
|
||||
CUDSS_COMM_LIB
|
||||
NAMES libcudss_commlayer_openmpi.so
|
||||
PATHS ${CUDSS_LIBRARY_DIR}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
if (NOT DEFINED MFEM_CUDSS_COMM_LIB AND CUDSS_COMM_LIB)
|
||||
set(MFEM_CUDSS_COMM_LIB "${CUDSS_COMM_LIB}")
|
||||
endif()
|
||||
message(STATUS "CUDSS communication layer library: ${MFEM_CUDSS_COMM_LIB}")
|
||||
endif()
|
||||
@@ -9,45 +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:
|
||||
# - GSLIB_FOUND
|
||||
# - GSLIB_LIBRARIES
|
||||
# - GSLIB_INCLUDE_DIRS
|
||||
# otherwise, the following are defined:
|
||||
# - GSLIB (imported library target)
|
||||
|
||||
if (MFEM_FETCH_GSLIB OR MFEM_FETCH_TPLS)
|
||||
enable_language(C)
|
||||
set(GSLIB_FETCH_VERSION 1.0.9)
|
||||
add_library(GSLIB STATIC IMPORTED)
|
||||
# set options (technically flags because GSLIB does not use cmake)
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
set(GSLIB_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BUILD_TYPE}}")
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set(GSLIB_FLAGS "${GSLIB_FLAGS} -fPIC")
|
||||
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 GSLIB ${GSLIB_FETCH_VERSION} to be built with ${GSLIB_FLAGS}")
|
||||
set(PREFIX ${CMAKE_BINARY_DIR}/fetch/gslib)
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(gslib
|
||||
GIT_REPOSITORY https://github.com/Nek5000/gslib
|
||||
GIT_TAG v${GSLIB_FETCH_VERSION}
|
||||
GIT_SHALLOW TRUE
|
||||
UPDATE_DISCONNECTED TRUE
|
||||
PREFIX ${PREFIX}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND cd ${PREFIX}/src/gslib && $(MAKE) clean && $(MAKE) DESTDIR=${PREFIX} MPI=$<BOOL:${MFEM_USE_MPI}> "CFLAGS=${GSLIB_FLAGS}"
|
||||
INSTALL_COMMAND "")
|
||||
file(MAKE_DIRECTORY ${PREFIX}/include)
|
||||
# set imported library target properties
|
||||
add_dependencies(GSLIB gslib)
|
||||
set_target_properties(GSLIB PROPERTIES
|
||||
IMPORTED_LOCATION ${PREFIX}/lib/libgs.a
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${PREFIX}/include)
|
||||
return()
|
||||
endif()
|
||||
|
||||
include(MfemCmakeUtilities)
|
||||
mfem_find_package(GSLIB GSLIB GSLIB_DIR "include" gslib.h "lib" gs
|
||||
|
||||
@@ -37,24 +37,21 @@ if (HYPRE_FOUND OR TARGET HYPRE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (MFEM_FETCH_HYPRE OR MFEM_FETCH_TPLS)
|
||||
set(HYPRE_FETCH_VERSION 2.33.0)
|
||||
set(HYPRE_FETCH_TAG "v${HYPRE_FETCH_VERSION}" CACHE STRING "Tag, branch, or commit for HYPRE")
|
||||
add_library(HYPRE STATIC IMPORTED)
|
||||
# set options and associated dependencies
|
||||
if (HYPRE_FETCH OR FETCH_TPLS)
|
||||
# Collect all HYPRE_ENABLE variables and pass them to hypre, assuming they are BOOL.
|
||||
set(HYPRE_CMAKE_OPTIONS "")
|
||||
list(APPEND HYPRE_CMAKE_OPTIONS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
|
||||
if (BUILD_SHARED_LIBS)
|
||||
list(APPEND HYPRE_CMAKE_OPTIONS -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON)
|
||||
endif()
|
||||
# collect all HYPRE_ENABLE variables and pass them to hypre, assuming they are BOOL.
|
||||
get_cmake_property(all_vars VARIABLES)
|
||||
foreach(var ${all_vars})
|
||||
if(var MATCHES "^HYPRE_ENABLE")
|
||||
list(APPEND HYPRE_CMAKE_OPTIONS "-D${var}:BOOL=${${var}}")
|
||||
endif()
|
||||
endforeach()
|
||||
# process all MFEM_USE variables that impact hypre
|
||||
|
||||
set(HYPRE_FETCH_VERSION 2.33.0)
|
||||
set(HYPRE_FETCH_TAG "v${HYPRE_FETCH_VERSION}" CACHE STRING "Tag, branch, or commit for HYPRE")
|
||||
add_library(HYPRE STATIC IMPORTED)
|
||||
# set options and associated dependencies
|
||||
list(APPEND HYPRE_CMAKE_OPTIONS -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE})
|
||||
if (MFEM_USE_CUDA)
|
||||
list(APPEND HYPRE_CMAKE_OPTIONS -DHYPRE_ENABLE_CUDA:BOOL=ON -DCMAKE_CUDA_ARCHITECTURES:STRING=${CMAKE_CUDA_ARCHITECTURES})
|
||||
find_package(CUDAToolkit REQUIRED)
|
||||
@@ -98,6 +95,7 @@ if (MFEM_FETCH_HYPRE OR MFEM_FETCH_TPLS)
|
||||
UPDATE_DISCONNECTED TRUE
|
||||
SOURCE_SUBDIR src
|
||||
PREFIX ${HYPRE_INSTALL}
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build . -- -j${CMAKE_BUILD_PARALLEL_LEVEL}
|
||||
CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=${HYPRE_INSTALL} -DCMAKE_INSTALL_LIBDIR:PATH=lib ${HYPRE_CMAKE_OPTIONS})
|
||||
file(MAKE_DIRECTORY ${HYPRE_INSTALL}/include)
|
||||
# set imported library target properties
|
||||
|
||||
@@ -18,19 +18,11 @@
|
||||
# - METIS (imported library target)
|
||||
# - METIS_VERSION_5 (cache variable)
|
||||
|
||||
if (MFEM_FETCH_METIS OR MFEM_FETCH_TPLS)
|
||||
enable_language(C)
|
||||
if (METIS_FETCH OR FETCH_TPLS)
|
||||
set(METIS_FETCH_VERSION 4.0.3)
|
||||
add_library(METIS STATIC IMPORTED)
|
||||
# set options (technically flags because METIS does not use cmake)
|
||||
set(METIS_FLAGS "-Wno-implicit-int -Wno-incompatible-pointer-types")
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
set(METIS_FLAGS "${METIS_FLAGS} ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BUILD_TYPE}}")
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set(METIS_FLAGS "${METIS_FLAGS} -fPIC")
|
||||
endif()
|
||||
# define external project
|
||||
message(STATUS "Will fetch METIS ${METIS_FETCH_VERSION} to be built with ${METIS_FLAGS}")
|
||||
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
|
||||
@@ -40,7 +32,7 @@ if (MFEM_FETCH_METIS OR MFEM_FETCH_TPLS)
|
||||
UPDATE_DISCONNECTED TRUE
|
||||
PREFIX ${PREFIX}
|
||||
CONFIGURE_COMMAND tar -xzf ../metis/metis-${METIS_FETCH_VERSION}-mac.tgz --strip=1
|
||||
BUILD_COMMAND $(MAKE) clean && $(MAKE) "OPTFLAGS=${METIS_FLAGS}"
|
||||
BUILD_COMMAND $(MAKE) COPTIONS=-Wno-incompatible-pointer-types
|
||||
INSTALL_COMMAND mkdir -p ${PREFIX}/lib && cp libmetis.a ${PREFIX}/lib/)
|
||||
# set imported library target properties
|
||||
add_dependencies(METIS metis)
|
||||
|
||||
@@ -22,15 +22,15 @@ include(MfemCmakeUtilities)
|
||||
mfem_find_package(SuiteSparse SuiteSparse SuiteSparse_DIR "" "" "" ""
|
||||
"Paths to headers required by SuiteSparse."
|
||||
"Libraries required by SuiteSparse."
|
||||
ADD_COMPONENT "UMFPACK" "include;include/suitesparse;suitesparse" umfpack.h "lib" umfpack
|
||||
ADD_COMPONENT "KLU" "include;include/suitesparse;suitesparse" klu.h "lib" klu
|
||||
ADD_COMPONENT "AMD" "include;include/suitesparse;suitesparse" amd.h "lib" amd
|
||||
ADD_COMPONENT "BTF" "include;include/suitesparse;suitesparse" btf.h "lib" btf
|
||||
ADD_COMPONENT "CHOLMOD" "include;include/suitesparse;suitesparse" cholmod.h "lib" cholmod
|
||||
ADD_COMPONENT "COLAMD" "include;include/suitesparse;suitesparse" colamd.h "lib" colamd
|
||||
ADD_COMPONENT "CAMD" "include;include/suitesparse;suitesparse" camd.h "lib" camd
|
||||
ADD_COMPONENT "CCOLAMD" "include;include/suitesparse;suitesparse" ccolamd.h "lib" ccolamd
|
||||
ADD_COMPONENT "config" "include;include/suitesparse;suitesparse" SuiteSparse_config.h "lib"
|
||||
ADD_COMPONENT "UMFPACK" "include;suitesparse" umfpack.h "lib" umfpack
|
||||
ADD_COMPONENT "KLU" "include;suitesparse" klu.h "lib" klu
|
||||
ADD_COMPONENT "AMD" "include;suitesparse" amd.h "lib" amd
|
||||
ADD_COMPONENT "BTF" "include;suitesparse" btf.h "lib" btf
|
||||
ADD_COMPONENT "CHOLMOD" "include;suitesparse" cholmod.h "lib" cholmod
|
||||
ADD_COMPONENT "COLAMD" "include;suitesparse" colamd.h "lib" colamd
|
||||
ADD_COMPONENT "CAMD" "include;suitesparse" camd.h "lib" camd
|
||||
ADD_COMPONENT "CCOLAMD" "include;suitesparse" ccolamd.h "lib" ccolamd
|
||||
ADD_COMPONENT "config" "include;suitesparse" SuiteSparse_config.h "lib"
|
||||
suitesparseconfig)
|
||||
|
||||
if (SuiteSparse_FOUND AND METIS_VERSION_5)
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
# - UMPIRE_LIBRARIES
|
||||
# - UMPIRE_INCLUDE_DIRS
|
||||
|
||||
if (NOT umpire_ROOT AND UMPIRE_DIR)
|
||||
set(umpire_ROOT ${UMPIRE_DIR})
|
||||
if (NOT umpire_DIR AND UMPIRE_DIR)
|
||||
set(umpire_DIR ${UMPIRE_DIR}/lib/cmake/umpire)
|
||||
endif()
|
||||
message(STATUS "Looking for UMPIRE ...")
|
||||
message(STATUS " in UMPIRE_DIR = ${UMPIRE_DIR}")
|
||||
message(STATUS " umpire_ROOT = ${umpire_ROOT}")
|
||||
message(STATUS " umpire_DIR = ${umpire_DIR}")
|
||||
find_package(umpire CONFIG)
|
||||
set(UMPIRE_FOUND ${umpire_FOUND})
|
||||
set(UMPIRE_LIBRARIES "umpire")
|
||||
|
||||
@@ -701,6 +701,7 @@ endfunction(mfem_find_library)
|
||||
# Extract compile and link options needed by the given target.
|
||||
#
|
||||
function(mfem_get_target_options Target CompileOptsVar LinkOptsVar)
|
||||
|
||||
if (NOT TARGET ${Target})
|
||||
return()
|
||||
endif()
|
||||
@@ -798,12 +799,7 @@ function(mfem_get_target_options Target CompileOptsVar LinkOptsVar)
|
||||
# message(STATUS "Lib = ${Lib}")
|
||||
# Filter-out generator expressions
|
||||
if (NOT ("${Lib}" MATCHES "^\\$"))
|
||||
if(NOT ("${Lib}" STREQUAL "dl"))
|
||||
list(APPEND LinkOpts "${Lib}")
|
||||
else()
|
||||
# for some reason libdl doesn't include the "-l"
|
||||
list(APPEND LinkOpts "-ldl")
|
||||
endif()
|
||||
list(APPEND LinkOpts "${Lib}")
|
||||
endif()
|
||||
else()
|
||||
mfem_get_target_options(${Lib} COpts LOpts)
|
||||
@@ -892,18 +888,9 @@ function(mfem_export_mk_files)
|
||||
set(${var} NO)
|
||||
endif()
|
||||
endforeach()
|
||||
if (MFEM_USE_CUDA AND MFEM_EXPORT_GPU_CONFIG)
|
||||
set(MFEM_CXX ${CMAKE_CUDA_COMPILER})
|
||||
if(MFEM_CUDA_COMPILER_IS_NVCC)
|
||||
set(MFEM_HOST_CXX ${CMAKE_CUDA_HOST_COMPILER})
|
||||
else()
|
||||
set(MFEM_HOST_CXX ${CMAKE_CXX_COMPILER})
|
||||
endif()
|
||||
else()
|
||||
# mfem doesn't use enable_language(HIP)
|
||||
set(MFEM_CXX ${CMAKE_CXX_COMPILER})
|
||||
set(MFEM_HOST_CXX ${CMAKE_CXX_COMPILER})
|
||||
endif()
|
||||
# TODO: Add support for MFEM_USE_CUDA=YES
|
||||
set(MFEM_CXX ${CMAKE_CXX_COMPILER})
|
||||
set(MFEM_HOST_CXX ${MFEM_CXX})
|
||||
set(MFEM_CPPFLAGS "")
|
||||
get_target_property(cxx_std mfem CXX_STANDARD)
|
||||
# For now, we ignore the setting of the CXX_EXTENSIONS property. If this
|
||||
@@ -913,50 +900,6 @@ function(mfem_export_mk_files)
|
||||
string(STRIP
|
||||
"${cxx_std_flag} ${CMAKE_CXX_FLAGS_${BUILD_TYPE}} ${CMAKE_CXX_FLAGS}"
|
||||
MFEM_CXXFLAGS)
|
||||
if(MFEM_EXPORT_GPU_CONFIG)
|
||||
if (MFEM_USE_CUDA)
|
||||
set(MFEM_CXXFLAGS "${MFEM_CXXFLAGS} ${CMAKE_CUDA_FLAGS}")
|
||||
if (MFEM_CUDA_COMPILER_IS_NVCC)
|
||||
set(MFEM_CXXFLAGS "-x=cu ${MFEM_CXXFLAGS} -ccbin ${CMAKE_CXX_COMPILER} --forward-unknown-to-host-compiler")
|
||||
# The following intentionally hides CUDA deprecation warnings
|
||||
foreach(ENTRY IN LISTS CUDAToolkit_INCLUDE_DIRS)
|
||||
set(MFEM_CXXFLAGS "${MFEM_CXXFLAGS} -isystem ${ENTRY}")
|
||||
endforeach()
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18.0)
|
||||
# architecture flags not part of CMAKE_CUDA_FLAGS
|
||||
if ("all" STREQUAL "${CMAKE_CUDA_ARCHITECTURES}"
|
||||
OR "native" STREQUAL "${CMAKE_CUDA_ARCHITECTURES}"
|
||||
OR "all-major" STREQUAL "${CMAKE_CUDA_ARCHITECTURES}")
|
||||
set(MFEM_CXXFLAGS "${MFEM_CXXFLAGS} -arch=${CMAKE_CUDA_ARCHITECTURES}")
|
||||
else()
|
||||
foreach (ENTRY IN LISTS CMAKE_CUDA_ARCHITECTURES)
|
||||
set(MFEM_CXXFLAGS
|
||||
"${MFEM_CXXFLAGS} -gencode arch=compute_${ENTRY},code=sm_${ENTRY}")
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
set(MFEM_CXXFLAGS "${MFEM_CXXFLAGS} -xcuda --cuda-path=${CUDAToolkit_LIBRARY_ROOT}")
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18.0)
|
||||
# architecture flags not part of CMAKE_CUDA_FLAGS
|
||||
if ("all" STREQUAL "${CMAKE_CUDA_ARCHITECTURES}"
|
||||
OR "native" STREQUAL "${CMAKE_CUDA_ARCHITECTURES}"
|
||||
OR "all-major" STREQUAL "${CMAKE_CUDA_ARCHITECTURES}")
|
||||
# TODO: not supported
|
||||
else()
|
||||
foreach(ENTRY IN LISTS CMAKE_CUDA_ARCHITECTURES)
|
||||
set(MFEM_CXXFLAGS "-cuda-gpu-arch=sm_${ENTRY} ${MFEM_CXXFLAGS}")
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
elseif (MFEM_USE_HIP)
|
||||
set(MFEM_CXXFLAGS "${MFEM_CXXFLAGS} -xhip")
|
||||
foreach(ENTRY IN LISTS CMAKE_HIP_ARCHITECTURES)
|
||||
set(MFEM_CXXFLAGS "--offload-arch=${ENTRY} ${MFEM_CXXFLAGS}")
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
set(MFEM_TPLFLAGS "")
|
||||
foreach(dir ${TPL_INCLUDE_DIRS})
|
||||
set(MFEM_TPLFLAGS "${MFEM_TPLFLAGS} -I${dir}")
|
||||
@@ -987,9 +930,6 @@ function(mfem_export_mk_files)
|
||||
set(MFEM_SHARED NO)
|
||||
set(MFEM_STATIC YES)
|
||||
endif()
|
||||
if (MFEM_USE_CUDA)
|
||||
set(MFEM_EXT_LIBS "${MFEM_EXT_LIBS} -lcudart")
|
||||
endif()
|
||||
set(MFEM_BUILD_TAG "${CMAKE_SYSTEM}")
|
||||
set(MFEM_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
# For the next 4 variables, these are the values for the build-tree version of
|
||||
@@ -998,15 +938,8 @@ function(mfem_export_mk_files)
|
||||
set(MFEM_LIB_DIR "${PROJECT_BINARY_DIR}")
|
||||
set(MFEM_TEST_MK "${PROJECT_SOURCE_DIR}/config/test.mk")
|
||||
set(MFEM_CONFIG_EXTRA "MFEM_BUILD_DIR ?= ${PROJECT_BINARY_DIR}")
|
||||
if (MFEM_USE_CUDA AND MFEM_EXPORT_GPU_CONFIG)
|
||||
if (MFEM_CUDA_COMPILER_IS_NVCC)
|
||||
set(MFEM_XLINKER "-Xlinker=")
|
||||
else()
|
||||
set(MFEM_XLINKER "${CMAKE_CUDA_LINKER_WRAPPER_FLAG}")
|
||||
endif()
|
||||
else()
|
||||
set(MFEM_XLINKER "${CMAKE_CXX_LINKER_WRAPPER_FLAG}")
|
||||
endif()
|
||||
# TODO: CUDA/HIP support:
|
||||
set(MFEM_XLINKER "${CMAKE_CXX_LINKER_WRAPPER_FLAG}")
|
||||
set(MFEM_MPIEXEC ${MPIEXEC})
|
||||
if (NOT MFEM_MPIEXEC)
|
||||
set(MFEM_MPIEXEC "mpirun")
|
||||
@@ -1054,21 +987,16 @@ function(mfem_export_mk_files)
|
||||
# handle interfaces (e.g., SCOREC::apf)
|
||||
if ("${lib}" MATCHES "SCOREC::.*" OR "${lib}" MATCHES "Ginkgo::.*" OR "${lib}" MATCHES "ParMoonolith::.*")
|
||||
elseif (TARGET "${lib}")
|
||||
mfem_get_target_options(${lib} CompileOpts2 LinkOpts2)
|
||||
# remove generator expressions
|
||||
string(GENEX_STRIP "${CompileOpts2}" CompileOpts)
|
||||
string(GENEX_STRIP "${LinkOpts2}" LinkOpts)
|
||||
mfem_get_target_options(${lib} CompileOpts LinkOpts)
|
||||
# Removing duplicates may lead to issues:
|
||||
# list(REMOVE_DUPLICATES CompileOpts)
|
||||
# list(REMOVE_DUPLICATES LinkOpts)
|
||||
# message(WARNING "${lib}[LinkOpts]: ${LinkOpts}")
|
||||
# message(WARNING "${lib}[CompileOpts]: ${CompileOpts}")
|
||||
foreach(LOpt IN LISTS LinkOpts)
|
||||
set(MFEM_EXT_LIBS "${MFEM_EXT_LIBS} ${LOpt}")
|
||||
endforeach()
|
||||
foreach(COpt IN LISTS CompileOpts)
|
||||
set(MFEM_TPLFLAGS "${MFEM_TPLFLAGS} ${COpt}")
|
||||
endforeach()
|
||||
string(REPLACE ";" " " COpts "${CompileOpts}")
|
||||
string(REPLACE ";" " " LOpts "${LinkOpts}")
|
||||
# message(STATUS "${lib}[COpts]: '${COpts}'")
|
||||
# message(STATUS "${lib}[LOpts]: '${LOpts}'")
|
||||
set(MFEM_TPLFLAGS "${MFEM_TPLFLAGS} ${COpts}")
|
||||
set(MFEM_EXT_LIBS "${MFEM_EXT_LIBS} ${LOpts}")
|
||||
# message(FATAL_ERROR "***** interface lib found ... exiting *****")
|
||||
# handle static and shared libs
|
||||
elseif ("${suffix}" STREQUAL "${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
@@ -1076,7 +1004,7 @@ function(mfem_export_mk_files)
|
||||
get_filename_component(fullLibName ${lib} NAME_WE)
|
||||
string(REGEX REPLACE "^lib" "" libname ${fullLibName})
|
||||
set(MFEM_EXT_LIBS
|
||||
"${MFEM_EXT_LIBS} ${shared_link_flag}${dir} -L${dir} -l${libname}")
|
||||
"${MFEM_EXT_LIBS} ${shared_link_flag}${dir} -L${dir} -l${libname}")
|
||||
else()
|
||||
set(MFEM_EXT_LIBS "${MFEM_EXT_LIBS} ${lib}")
|
||||
endif()
|
||||
@@ -1085,7 +1013,7 @@ function(mfem_export_mk_files)
|
||||
# Create the build-tree version of 'config.mk'
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/config/config.mk.in"
|
||||
"${PROJECT_BINARY_DIR}/config/config.mk" @ONLY)
|
||||
"${PROJECT_BINARY_DIR}/config/config.mk")
|
||||
# Copy 'test.mk' from the source-tree to the build-tree
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/config/test.mk"
|
||||
@@ -1103,7 +1031,7 @@ function(mfem_export_mk_files)
|
||||
# Create the install-tree version of 'config.mk'
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/config/config.mk.in"
|
||||
"${PROJECT_BINARY_DIR}/config/config-install.mk" @ONLY)
|
||||
"${PROJECT_BINARY_DIR}/config/config-install.mk")
|
||||
|
||||
# Install rules for 'config.mk' and 'test.mk'
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/config/test.mk
|
||||
|
||||
@@ -157,10 +157,4 @@ constexpr real_t operator""_r(unsigned long long v)
|
||||
#endif
|
||||
#endif // MFEM_USE_MPI not defined
|
||||
|
||||
#ifndef MFEM_USE_CUDA
|
||||
#ifdef MFEM_USE_CUDSS
|
||||
#error Building with cuDSS (MFEM_USE_CUDSS=YES) requires CUDA (MFEM_USE_CUDA=YES)
|
||||
#endif
|
||||
#endif // MFEM_USE_CUDSS not defined
|
||||
|
||||
#endif // MFEM_CONFIG_HPP
|
||||
|
||||
@@ -108,15 +108,6 @@
|
||||
// Enable MFEM functionality based on the STRUMPACK library.
|
||||
// #define MFEM_USE_STRUMPACK
|
||||
|
||||
// Enable MFEM functionality based on the cuDSS library.
|
||||
// #define MFEM_USE_CUDSS
|
||||
|
||||
// CUDSS communication layer library path
|
||||
// #define MFEM_CUDSS_COMM_LIB "@MFEM_CUDSS_COMM_LIB@"
|
||||
|
||||
// CUDSS threading layer library path
|
||||
// #define MFEM_CUDSS_THREADING_LIB "@MFEM_CUDSS_THREADING_LIB@"
|
||||
|
||||
// Enable MFEM features based on the Ginkgo library.
|
||||
// #define MFEM_USE_GINKGO
|
||||
|
||||
|
||||
@@ -36,9 +36,6 @@ MFEM_USE_SUPERLU = @MFEM_USE_SUPERLU@
|
||||
MFEM_USE_SUPERLU5 = @MFEM_USE_SUPERLU5@
|
||||
MFEM_USE_MUMPS = @MFEM_USE_MUMPS@
|
||||
MFEM_USE_STRUMPACK = @MFEM_USE_STRUMPACK@
|
||||
MFEM_USE_CUDSS = @MFEM_USE_CUDSS@
|
||||
MFEM_CUDSS_COMM_LIB = @MFEM_CUDSS_COMM_LIB@
|
||||
MFEM_CUDSS_THREADING_LIB = @MFEM_CUDSS_THREADING_LIB@
|
||||
MFEM_USE_GINKGO = @MFEM_USE_GINKGO@
|
||||
MFEM_USE_AMGX = @MFEM_USE_AMGX@
|
||||
MFEM_USE_MAGMA = @MFEM_USE_MAGMA@
|
||||
|
||||
@@ -38,7 +38,6 @@ option(MFEM_USE_SUPERLU "Enable SuperLU_DIST usage" OFF)
|
||||
option(MFEM_USE_SUPERLU5 "Use the old SuperLU_DIST 5.1 version" OFF)
|
||||
option(MFEM_USE_MUMPS "Enable MUMPS usage" OFF)
|
||||
option(MFEM_USE_STRUMPACK "Enable STRUMPACK usage" OFF)
|
||||
option(MFEM_USE_CUDSS "Enable cuDSS usage" OFF)
|
||||
option(MFEM_USE_GINKGO "Enable Ginkgo usage" OFF)
|
||||
option(MFEM_USE_AMGX "Enable AmgX usage" OFF)
|
||||
option(MFEM_USE_MAGMA "Enable MAGMA usage" OFF)
|
||||
@@ -92,10 +91,9 @@ 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(MFEM_FETCH_TPLS "Enable fetching of all supported third-party libraries" OFF)
|
||||
option(MFEM_FETCH_GSLIB "Enable fetching of GSLIB" OFF)
|
||||
option(MFEM_FETCH_HYPRE "Enable fetching of hypre" OFF)
|
||||
option(MFEM_FETCH_METIS "Enable fetching of METIS" OFF)
|
||||
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.
|
||||
|
||||
+5
-51
@@ -18,7 +18,6 @@
|
||||
# Some choices below are based on the OS type:
|
||||
NOTMAC := $(subst Darwin,,$(shell uname -s))
|
||||
|
||||
ASTYLE_BIN = astyle
|
||||
ETAGS_BIN = $(shell command -v etags 2> /dev/null)
|
||||
EGREP_BIN = $(shell command -v egrep 2> /dev/null)
|
||||
|
||||
@@ -27,10 +26,7 @@ MPICXX = mpicxx
|
||||
|
||||
BASE_FLAGS = -std=c++17
|
||||
OPTIM_FLAGS = -O3 $(BASE_FLAGS)
|
||||
|
||||
# The variable WARNING_FLAGS depends on which compiler is used, and is defined
|
||||
# later in this file.
|
||||
DEBUG_FLAGS = $(strip -g $(addprefix $(XCOMPILER),$(WARNING_FLAGS)) $(BASE_FLAGS))
|
||||
DEBUG_FLAGS = -g $(XCOMPILER)-Wall $(BASE_FLAGS)
|
||||
|
||||
# Prefixes for passing flags to the compiler and linker when using CXX or MPICXX
|
||||
CXX_XCOMPILER =
|
||||
@@ -49,10 +45,6 @@ SHARED = NO
|
||||
#
|
||||
# If you set MFEM_USE_ENZYME=YES, must use CUDA_CXX=clang++
|
||||
CUDA_CXX = nvcc
|
||||
# CUDA compute capability used during compilation, e.g. sm_60. Multiple
|
||||
# architectures can be requested as a comma-separated list, e.g. sm_70,sm_80.
|
||||
# A single value may also be one of the nvcc special values "all",
|
||||
# "all-major", or "native".
|
||||
CUDA_ARCH = sm_60
|
||||
# Base CUDA install directory, only needed if building with clang+cuda:
|
||||
# The default setting is:
|
||||
@@ -61,23 +53,11 @@ CUDA_ARCH = sm_60
|
||||
# 3. Use /usr/local/cuda
|
||||
CUDA_DIR = $(or $(CUDA_HOME),$(patsubst %/,%,$(dir \
|
||||
$(patsubst %/,%,$(dir $(shell command -v nvcc))))),/usr/local/cuda)
|
||||
# Derive nvcc/clang architecture flags from CUDA_ARCH. A comma-separated list
|
||||
# expands into one -gencode / --cuda-gpu-arch flag per architecture; otherwise
|
||||
# use the -arch / --cuda-gpu-arch shorthand.
|
||||
MFEM_COMMA := ,
|
||||
CUDA_ARCH_NUMS = $(patsubst sm_%,%,$(subst $(MFEM_COMMA), ,$(CUDA_ARCH)))
|
||||
NVCC_ARCH_FLAGS = $(strip $(if $(findstring $(MFEM_COMMA),$(CUDA_ARCH)),\
|
||||
$(foreach arch,$(CUDA_ARCH_NUMS),\
|
||||
-gencode arch=compute_$(arch)$(MFEM_COMMA)code=sm_$(arch)),\
|
||||
-arch=$(CUDA_ARCH)))
|
||||
CLANG_ARCH_FLAGS = $(strip $(if $(findstring $(MFEM_COMMA),$(CUDA_ARCH)),\
|
||||
$(foreach arch,$(CUDA_ARCH_NUMS),--cuda-gpu-arch=sm_$(arch)),\
|
||||
--cuda-gpu-arch=$(CUDA_ARCH)))
|
||||
# flags for clang+cuda
|
||||
CLANG_CUDA_FLAGS = -xcuda --cuda-path=$(CUDA_DIR) $(CLANG_ARCH_FLAGS)
|
||||
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 \
|
||||
$(NVCC_ARCH_FLAGS) -isystem "$(CUDA_DIR)/include"
|
||||
-arch=$(CUDA_ARCH) -isystem "$(CUDA_DIR)/include"
|
||||
# Prefixes for passing flags to the host compiler and linker when using
|
||||
# CUDA_CXX=nvcc
|
||||
CUDA_XCOMPILER = -Xcompiler=
|
||||
@@ -172,7 +152,6 @@ MFEM_USE_SUPERLU = NO
|
||||
MFEM_USE_SUPERLU5 = NO
|
||||
MFEM_USE_MUMPS = NO
|
||||
MFEM_USE_STRUMPACK = NO
|
||||
MFEM_USE_CUDSS = NO
|
||||
MFEM_USE_GINKGO = NO
|
||||
MFEM_USE_AMGX = NO
|
||||
MFEM_USE_MAGMA = NO
|
||||
@@ -388,19 +367,6 @@ STRUMPACK_OPT = -I$(STRUMPACK_DIR)/include $(SCOTCH_OPT)
|
||||
STRUMPACK_LIB = -L$(STRUMPACK_DIR)/lib -lstrumpack $(MPI_FORTRAN_LIB)\
|
||||
$(SCOTCH_LIB) $(SCALAPACK_LIB)
|
||||
|
||||
# CUDSS library configuration
|
||||
CUDSS_DIR = @MFEM_DIR@/../cudss
|
||||
CUDSS_INCLUDE_DIR = $(CUDSS_DIR)/include
|
||||
CUDSS_LIBRARY_DIR = $(CUDSS_DIR)/lib
|
||||
CUDSS_OPT = -I$(CUDSS_INCLUDE_DIR)
|
||||
CUDSS_LIB = \
|
||||
$(XLINKER)-rpath,$(CUDSS_LIBRARY_DIR) -L$(CUDSS_LIBRARY_DIR) -lcudss
|
||||
# The cuDSS communication and threading libraries.
|
||||
MFEM_CUDSS_COMM_LIB = $(abspath $(wildcard $(or $(CUDSS_COMM_LIB),\
|
||||
$(subst @MFEM_DIR@,$(MFEM_DIR), $(CUDSS_LIBRARY_DIR)/libcudss_commlayer_openmpi.so))))
|
||||
MFEM_CUDSS_THREADING_LIB = $(abspath $(wildcard $(or $(CUDSS_THREADING_LIB),\
|
||||
$(subst @MFEM_DIR@,$(MFEM_DIR),$(CUDSS_LIBRARY_DIR)/libcudss_mtlayer_gomp.so))))
|
||||
|
||||
# Ginkgo library configuration
|
||||
GINKGO_DIR = @MFEM_DIR@/../ginkgo/install
|
||||
GINKGO_SEARCH_DIR = $(subst @MFEM_DIR@,$(MFEM_DIR),$(GINKGO_DIR))
|
||||
@@ -441,7 +407,7 @@ AMGX_LIB = -L$(AMGX_DIR)/lib -lamgx -lcusparse -lcusolver -lcublas -lnvToolsExt
|
||||
# MAGMA library configuration
|
||||
MAGMA_DIR = @MFEM_DIR@/../magma
|
||||
MAGMA_OPT = -I$(MAGMA_DIR)/include
|
||||
MAGMA_LIB = -L$(MAGMA_DIR)/lib -l:libmagma.a $(LAPACK_LIB)
|
||||
MAGMA_LIB = -L$(MAGMA_DIR)/lib -l:libmagma.a -lcublas -lcusparse $(LAPACK_LIB)
|
||||
|
||||
# GnuTLS library configuration
|
||||
GNUTLS_OPT =
|
||||
@@ -654,7 +620,7 @@ PARELAG_LIB = -L$(PARELAG_DIR)/build/src -lParELAG
|
||||
AXOM_DIR = @MFEM_DIR@/../axom
|
||||
TRIBOL_DIR = @MFEM_DIR@/../tribol
|
||||
TRIBOL_OPT = -I$(TRIBOL_DIR)/include -I$(AXOM_DIR)/include
|
||||
TRIBOL_LIB = -L$(TRIBOL_DIR)/lib -ltribol -ltribol_shared -lredecomp -L$(AXOM_DIR)/lib -laxom_mint\
|
||||
TRIBOL_LIB = -L$(TRIBOL_DIR)/lib -ltribol -lredecomp -L$(AXOM_DIR)/lib -laxom_mint\
|
||||
-laxom_slam -laxom_slic -laxom_core
|
||||
|
||||
# Enzyme configuration
|
||||
@@ -678,15 +644,3 @@ VERBOSE = NO
|
||||
|
||||
# Optional build tag
|
||||
MFEM_BUILD_TAG = $(shell uname -snm)
|
||||
|
||||
# Enable -pedantic flag only for gcc or clang. nvcc complains with -pedantic
|
||||
# because of line directives.
|
||||
PEDANTIC_FLAG = $(if \
|
||||
$(findstring NVIDIA,$(shell $(MFEM_CXX) --version 2>&1)),, \
|
||||
$(if $(or \
|
||||
$(findstring gcc version,$(shell $(MFEM_CXX) -v 2>&1)), \
|
||||
$(findstring clang version,$(shell $(MFEM_CXX) -v 2>&1))),-pedantic,))
|
||||
# Enable shadow warnings for clang only; GCC's -Wshadow flags more.
|
||||
SHADOW_WARNING_FLAG = $(if $(findstring clang,\
|
||||
$(shell $(MFEM_HOST_CXX) --version 2>/dev/null)),-Wshadow,)
|
||||
WARNING_FLAGS = $(PEDANTIC_FLAG) -Wall $(SHADOW_WARNING_FLAG)
|
||||
|
||||
@@ -101,7 +101,7 @@ $ cd ../miniapps
|
||||
$ ls
|
||||
CMakeLists.txt common meshing nurbs shifted toys
|
||||
adjoint electromagnetics mtop parelag solvers
|
||||
autodiff gslib fluids performance tools
|
||||
autodiff gslib navier performance tools
|
||||
```
|
||||
|
||||
And an example in "toys"
|
||||
|
||||
@@ -39,8 +39,3 @@ when a picture was added for documentation.
|
||||
If that is the case, make sure the failure is indeed justified, and rerun the
|
||||
push command with the `--no-verify` option. This will skip the hooks, allowing
|
||||
you to push those changes.
|
||||
|
||||
The `branch-history` check is run automatically through GitHub Actions. If a
|
||||
branch is known to have a large number of changes that are legitimate, the
|
||||
check can be overridden by setting the label 'branch-history-override' on the
|
||||
pull request.
|
||||
|
||||
+2
-14
@@ -85,10 +85,6 @@ groups_serial=(
|
||||
"DPG miniapps:"
|
||||
"miniapps/dpg"
|
||||
"{acoustics,convection-diffusion,diffusion,maxwell}.cpp"'
|
||||
'"isf"
|
||||
"Schrodinger flow miniapps:"
|
||||
"miniapps/fluids/schrodinger-flow"
|
||||
"schrodinger_flow.cpp"'
|
||||
'"gslib"
|
||||
"GSLIB miniapps:"
|
||||
"miniapps/gslib"
|
||||
@@ -170,10 +166,6 @@ groups_parallel=(
|
||||
"miniapps/electromagnetics"
|
||||
"joule.cpp"'
|
||||
# "{joule,maxwell,tesla,volta}.cpp"' # todo: multiline sample runs
|
||||
'"isf"
|
||||
"Schrodinger flow miniapps:"
|
||||
"miniapps/fluids/schrodinger-flow"
|
||||
"pschrodinger_flow.cpp"'
|
||||
'"adjoint"
|
||||
"Adjoint miniapps:"
|
||||
"miniapps/adjoint"
|
||||
@@ -199,7 +191,7 @@ groups_parallel=(
|
||||
# todo: miniapps/multidomain
|
||||
'"navier"
|
||||
"Navier miniapps:"
|
||||
"miniapps/fluids/navier"
|
||||
"miniapps/navier"
|
||||
"navier_cht.cpp"'
|
||||
# todo: add other navier miniapps
|
||||
'"nurbs"
|
||||
@@ -289,10 +281,6 @@ groups_all=(
|
||||
"miniapps/electromagnetics"
|
||||
"joule.cpp"'
|
||||
# "{joule,maxwell,tesla,volta}.cpp"' # todo: multiline sample runs
|
||||
'"isf"
|
||||
"Schrodinger flow miniapps:"
|
||||
"miniapps/fluids/schrodinger-flow"
|
||||
"{,p}schrodinger_flow.cpp"'
|
||||
'"adjoint"
|
||||
"Adjoint miniapps:"
|
||||
"miniapps/adjoint"
|
||||
@@ -320,7 +308,7 @@ groups_all=(
|
||||
# todo: miniapps/multidomain
|
||||
'"navier"
|
||||
"Navier miniapps:"
|
||||
"miniapps/fluids/navier"
|
||||
"miniapps/navier"
|
||||
"navier_cht.cpp"'
|
||||
# todo: add other navier miniapps
|
||||
'"nurbs"
|
||||
|
||||
@@ -1,156 +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
|
||||
2
|
||||
|
||||
elements
|
||||
25
|
||||
3 3 0 1 2 3
|
||||
3 3 1 4 5 2
|
||||
3 3 4 6 7 5
|
||||
3 3 6 8 9 7
|
||||
3 3 8 10 11 9
|
||||
3 3 10 12 13 11
|
||||
3 3 12 14 15 13
|
||||
3 3 14 16 17 15
|
||||
3 3 16 18 19 17
|
||||
3 3 18 20 21 19
|
||||
3 3 20 22 23 21
|
||||
3 3 22 24 25 23
|
||||
3 3 24 26 27 25
|
||||
3 3 26 28 29 27
|
||||
3 3 28 30 31 29
|
||||
3 3 30 32 33 31
|
||||
3 3 32 34 35 33
|
||||
3 3 17 19 36 37
|
||||
3 3 37 36 38 39
|
||||
3 3 39 38 40 41
|
||||
3 3 41 40 42 43
|
||||
3 3 43 42 44 45
|
||||
3 3 45 44 46 47
|
||||
3 3 47 46 48 49
|
||||
3 3 49 48 50 51
|
||||
|
||||
boundary
|
||||
52
|
||||
2 1 0 1
|
||||
2 1 2 3
|
||||
1 1 3 0
|
||||
2 1 1 4
|
||||
2 1 5 2
|
||||
2 1 4 6
|
||||
2 1 7 5
|
||||
2 1 6 8
|
||||
2 1 9 7
|
||||
2 1 8 10
|
||||
2 1 11 9
|
||||
2 1 10 12
|
||||
2 1 13 11
|
||||
2 1 12 14
|
||||
2 1 15 13
|
||||
2 1 14 16
|
||||
2 1 17 15
|
||||
2 1 16 18
|
||||
2 1 18 20
|
||||
2 1 21 19
|
||||
2 1 20 22
|
||||
2 1 23 21
|
||||
2 1 22 24
|
||||
2 1 25 23
|
||||
2 1 24 26
|
||||
2 1 27 25
|
||||
2 1 26 28
|
||||
2 1 29 27
|
||||
2 1 28 30
|
||||
2 1 31 29
|
||||
2 1 30 32
|
||||
2 1 33 31
|
||||
2 1 32 34
|
||||
3 1 34 35
|
||||
2 1 35 33
|
||||
2 1 19 36
|
||||
2 1 37 17
|
||||
2 1 36 38
|
||||
2 1 39 37
|
||||
2 1 38 40
|
||||
2 1 41 39
|
||||
2 1 40 42
|
||||
2 1 43 41
|
||||
2 1 42 44
|
||||
2 1 45 43
|
||||
2 1 44 46
|
||||
2 1 47 45
|
||||
2 1 46 48
|
||||
2 1 49 47
|
||||
2 1 48 50
|
||||
4 1 50 51
|
||||
2 1 51 49
|
||||
|
||||
vertices
|
||||
52
|
||||
2
|
||||
0 0
|
||||
1 0
|
||||
1 1
|
||||
0 1
|
||||
2 0
|
||||
2 1
|
||||
3 0
|
||||
3 1
|
||||
4 0
|
||||
4 1
|
||||
5 0
|
||||
5 1
|
||||
6 0
|
||||
6 1
|
||||
7 0
|
||||
7 1
|
||||
8 0
|
||||
8 1
|
||||
9 0
|
||||
9 1
|
||||
10 0
|
||||
10 1
|
||||
11 0
|
||||
11 1
|
||||
12 0
|
||||
12 1
|
||||
13 0
|
||||
13 1
|
||||
14 0
|
||||
14 1
|
||||
15 0
|
||||
15 1
|
||||
16 0
|
||||
16 1
|
||||
17 0
|
||||
17 1
|
||||
9 2
|
||||
8 2
|
||||
9 3
|
||||
8 3
|
||||
9 4
|
||||
8 4
|
||||
9 5
|
||||
8 5
|
||||
9 6
|
||||
8 6
|
||||
9 7
|
||||
8 7
|
||||
9 8
|
||||
8 8
|
||||
9 9
|
||||
8 9
|
||||
@@ -1,131 +0,0 @@
|
||||
// Define the cube sizes
|
||||
L_outer = 1.0;
|
||||
L_inner = 0.5;
|
||||
|
||||
// Set mesh size and algorithm
|
||||
mesh_size = 0.4;
|
||||
Mesh.Algorithm3D = 1; // Delaunay algorithm for 3D mesh
|
||||
Mesh.CharacteristicLengthFactor = 1.0;
|
||||
Mesh.MshFileVersion = 2.2;
|
||||
|
||||
// Define center point for concentric cubes
|
||||
cx = 0.5;
|
||||
cy = 0.5;
|
||||
cz = 0.5;
|
||||
|
||||
// Define the points (vertices of the outer cube)
|
||||
Point(1) = {cx-L_outer/2, cy-L_outer/2, cz-L_outer/2, mesh_size};
|
||||
Point(2) = {cx+L_outer/2, cy-L_outer/2, cz-L_outer/2, mesh_size};
|
||||
Point(3) = {cx+L_outer/2, cy+L_outer/2, cz-L_outer/2, mesh_size};
|
||||
Point(4) = {cx-L_outer/2, cy+L_outer/2, cz-L_outer/2, mesh_size};
|
||||
Point(5) = {cx-L_outer/2, cy-L_outer/2, cz+L_outer/2, mesh_size};
|
||||
Point(6) = {cx+L_outer/2, cy-L_outer/2, cz+L_outer/2, mesh_size};
|
||||
Point(7) = {cx+L_outer/2, cy+L_outer/2, cz+L_outer/2, mesh_size};
|
||||
Point(8) = {cx-L_outer/2, cy+L_outer/2, cz+L_outer/2, mesh_size};
|
||||
|
||||
// Define the points (vertices of the inner cube)
|
||||
Point(9) = {cx-L_inner/2, cy-L_inner/2, cz-L_inner/2, mesh_size};
|
||||
Point(10) = {cx+L_inner/2, cy-L_inner/2, cz-L_inner/2, mesh_size};
|
||||
Point(11) = {cx+L_inner/2, cy+L_inner/2, cz-L_inner/2, mesh_size};
|
||||
Point(12) = {cx-L_inner/2, cy+L_inner/2, cz-L_inner/2, mesh_size};
|
||||
Point(13) = {cx-L_inner/2, cy-L_inner/2, cz+L_inner/2, mesh_size};
|
||||
Point(14) = {cx+L_inner/2, cy-L_inner/2, cz+L_inner/2, mesh_size};
|
||||
Point(15) = {cx+L_inner/2, cy+L_inner/2, cz+L_inner/2, mesh_size};
|
||||
Point(16) = {cx-L_inner/2, cy+L_inner/2, cz+L_inner/2, mesh_size};
|
||||
|
||||
// Define the lines (edges of the outer cube)
|
||||
Line(1) = {1, 2};
|
||||
Line(2) = {2, 3};
|
||||
Line(3) = {3, 4};
|
||||
Line(4) = {4, 1};
|
||||
Line(5) = {5, 6};
|
||||
Line(6) = {6, 7};
|
||||
Line(7) = {7, 8};
|
||||
Line(8) = {8, 5};
|
||||
Line(9) = {1, 5};
|
||||
Line(10) = {2, 6};
|
||||
Line(11) = {3, 7};
|
||||
Line(12) = {4, 8};
|
||||
|
||||
// Define the lines (edges of the inner cube)
|
||||
Line(13) = {9, 10};
|
||||
Line(14) = {10, 11};
|
||||
Line(15) = {11, 12};
|
||||
Line(16) = {12, 9};
|
||||
Line(17) = {13, 14};
|
||||
Line(18) = {14, 15};
|
||||
Line(19) = {15, 16};
|
||||
Line(20) = {16, 13};
|
||||
Line(21) = {9, 13};
|
||||
Line(22) = {10, 14};
|
||||
Line(23) = {11, 15};
|
||||
Line(24) = {12, 16};
|
||||
|
||||
// Define the surfaces (faces of the outer cube)
|
||||
Line Loop(1) = {1, 2, 3, 4};
|
||||
Plane Surface(1) = {1};
|
||||
|
||||
Line Loop(2) = {5, 6, 7, 8};
|
||||
Plane Surface(2) = {2};
|
||||
|
||||
Line Loop(3) = {9, 5, -10, -1};
|
||||
Plane Surface(3) = {3};
|
||||
|
||||
Line Loop(4) = {10, 6, -11, -2};
|
||||
Plane Surface(4) = {4};
|
||||
|
||||
Line Loop(5) = {11, 7, -12, -3};
|
||||
Plane Surface(5) = {5};
|
||||
|
||||
Line Loop(6) = {12, 8, -9, -4};
|
||||
Plane Surface(6) = {6};
|
||||
|
||||
// Define the surfaces (faces of the inner cube)
|
||||
Line Loop(7) = {13, 14, 15, 16};
|
||||
Plane Surface(7) = {7};
|
||||
|
||||
Line Loop(8) = {17, 18, 19, 20};
|
||||
Plane Surface(8) = {8};
|
||||
|
||||
Line Loop(9) = {21, 17, -22, -13};
|
||||
Plane Surface(9) = {9};
|
||||
|
||||
Line Loop(10) = {22, 18, -23, -14};
|
||||
Plane Surface(10) = {10};
|
||||
|
||||
Line Loop(11) = {23, 19, -24, -15};
|
||||
Plane Surface(11) = {11};
|
||||
|
||||
Line Loop(12) = {24, 20, -21, -16};
|
||||
Plane Surface(12) = {12};
|
||||
|
||||
// Define the volumes
|
||||
Surface Loop(1) = {1, 2, 3, 4, 5, 6};
|
||||
Surface Loop(2) = {7, 8, 9, 10, 11, 12};
|
||||
Volume(1) = {1, 2}; // Outer volume with inner hole
|
||||
Volume(2) = {2}; // Inner volume
|
||||
|
||||
// Assign physical groups
|
||||
Physical Volume(1) = {1}; // Outer volume
|
||||
Physical Volume(2) = {2}; // Inner volume
|
||||
|
||||
// Outer cube surfaces
|
||||
Physical Surface(1) = {1}; // Outer bottom
|
||||
Physical Surface(2) = {2}; // Outer top
|
||||
Physical Surface(3) = {3}; // Outer front
|
||||
Physical Surface(4) = {4}; // Outer right
|
||||
Physical Surface(5) = {5}; // Outer back
|
||||
Physical Surface(6) = {6}; // Outer left
|
||||
|
||||
// Inner cube surfaces
|
||||
Physical Surface(7) = {7}; // Inner bottom (-xy)
|
||||
Physical Surface(8) = {8}; // Inner top (+xy)
|
||||
Physical Surface(9) = {9}; // Inner front (-xz)
|
||||
Physical Surface(10) = {10}; // Inner right (+yz)
|
||||
Physical Surface(11) = {11}; // Inner back (+xz)
|
||||
Physical Surface(12) = {12}; // Inner left (-yz)
|
||||
|
||||
// Mesh control
|
||||
Mesh.OptimizeNetgen = 1;
|
||||
Mesh.Optimize = 1;
|
||||
Mesh.ElementOrder = 1;
|
||||
@@ -1,907 +0,0 @@
|
||||
$MeshFormat
|
||||
2.2 0 8
|
||||
$EndMeshFormat
|
||||
$Nodes
|
||||
138
|
||||
1 0 0 0
|
||||
2 1 0 0
|
||||
3 1 1 0
|
||||
4 0 1 0
|
||||
5 0 0 1
|
||||
6 1 0 1
|
||||
7 1 1 1
|
||||
8 0 1 1
|
||||
9 0.25 0.25 0.25
|
||||
10 0.75 0.25 0.25
|
||||
11 0.75 0.75 0.25
|
||||
12 0.25 0.75 0.25
|
||||
13 0.25 0.25 0.75
|
||||
14 0.75 0.25 0.75
|
||||
15 0.75 0.75 0.75
|
||||
16 0.25 0.75 0.75
|
||||
17 0.3333333333325025 0 0
|
||||
18 0.6666666666657889 0 0
|
||||
19 1 0.3333333333325025 0
|
||||
20 1 0.6666666666657889 0
|
||||
21 0.6666666666675911 1 0
|
||||
22 0.3333333333347203 1 0
|
||||
23 0 0.6666666666675911 0
|
||||
24 0 0.3333333333347203 0
|
||||
25 0.3333333333325025 0 1
|
||||
26 0.6666666666657889 0 1
|
||||
27 1 0.3333333333325025 1
|
||||
28 1 0.6666666666657889 1
|
||||
29 0.6666666666675911 1 1
|
||||
30 0.3333333333347203 1 1
|
||||
31 0 0.6666666666675911 1
|
||||
32 0 0.3333333333347203 1
|
||||
33 0 0 0.3333333333325025
|
||||
34 0 0 0.6666666666657889
|
||||
35 1 0 0.3333333333325025
|
||||
36 1 0 0.6666666666657889
|
||||
37 1 1 0.3333333333325025
|
||||
38 1 1 0.6666666666657889
|
||||
39 0 1 0.3333333333325025
|
||||
40 0 1 0.6666666666657889
|
||||
41 0.5000000000003468 0.25 0.25
|
||||
42 0.75 0.5000000000003468 0.25
|
||||
43 0.5000000000013763 0.75 0.25
|
||||
44 0.25 0.5000000000013763 0.25
|
||||
45 0.5000000000003468 0.25 0.75
|
||||
46 0.75 0.5000000000003468 0.75
|
||||
47 0.5000000000013763 0.75 0.75
|
||||
48 0.25 0.5000000000013763 0.75
|
||||
49 0.25 0.25 0.5000000000003468
|
||||
50 0.75 0.25 0.5000000000003468
|
||||
51 0.75 0.75 0.5000000000003468
|
||||
52 0.25 0.75 0.5000000000003468
|
||||
53 0.7113248654055673 0.4999999999991457 0
|
||||
54 0.2886751345942123 0.5000000000011557 0
|
||||
55 0.5000000000006117 0.7525600817161773 0
|
||||
56 0.4999999999993867 0.2474399182839603 0
|
||||
57 0.2423197548524782 0.7576802451481532 0
|
||||
58 0.757680245147464 0.2423197548520695 0
|
||||
59 0.2423197548507857 0.2423197548513912 0
|
||||
60 0.7576802451491019 0.7576802451486099 0
|
||||
61 0.7113248654055673 0.4999999999991457 1
|
||||
62 0.2886751345942123 0.5000000000011557 1
|
||||
63 0.5000000000006117 0.7525600817161773 1
|
||||
64 0.4999999999993867 0.2474399182839603 1
|
||||
65 0.2423197548524782 0.7576802451481532 1
|
||||
66 0.757680245147464 0.2423197548520695 1
|
||||
67 0.2423197548507857 0.2423197548513912 1
|
||||
68 0.7576802451491019 0.7576802451486099 1
|
||||
69 0.4999999999993203 0 0.301447615129799
|
||||
70 0.4999999999992795 0 0.7028666213189801
|
||||
71 0.7525600817158393 0 0.5007190394076877
|
||||
72 0.2474399182836191 0 0.5007190394076877
|
||||
73 0.7576802451479793 0 0.7576802451479793
|
||||
74 0.2423197548517962 0 0.7576802451477375
|
||||
75 0.7576802451484569 0 0.2423197548510767
|
||||
76 0.2423197548513188 0 0.2423197548513187
|
||||
77 1 0.4999999999993203 0.301447615129799
|
||||
78 1 0.4999999999992795 0.7028666213189801
|
||||
79 1 0.7525600817158394 0.5007190394076877
|
||||
80 1 0.2474399182836191 0.5007190394076877
|
||||
81 1 0.7576802451479794 0.7576802451479794
|
||||
82 1 0.2423197548517962 0.7576802451477376
|
||||
83 1 0.7576802451484569 0.2423197548510768
|
||||
84 1 0.2423197548513188 0.2423197548513188
|
||||
85 0.5000000000008327 1 0.3014476151298047
|
||||
86 0.500000000000961 1 0.7028666213191928
|
||||
87 0.2474399182842484 1 0.5007190394077241
|
||||
88 0.7525600817164384 1 0.5007190394078933
|
||||
89 0.2423197548520873 1 0.7576802451480517
|
||||
90 0.7576802451481496 1 0.2423197548518761
|
||||
91 0.2423197548516099 1 0.2423197548510044
|
||||
92 0.7576802451486874 1 0.7576802451481952
|
||||
93 0 0.5000000000008327 0.3014476151298047
|
||||
94 0 0.500000000000961 0.7028666213191928
|
||||
95 0 0.2474399182842484 0.5007190394077241
|
||||
96 0 0.7525600817164384 0.5007190394078933
|
||||
97 0 0.2423197548520873 0.7576802451480517
|
||||
98 0 0.7576802451481496 0.2423197548518761
|
||||
99 0 0.2423197548516099 0.2423197548510044
|
||||
100 0 0.7576802451486874 0.7576802451481952
|
||||
101 0.3968750000003409 0.603125000000244 0.25
|
||||
102 0.4374999999998713 0.4375000000001287 0.25
|
||||
103 0.5739583333335919 0.5718750000001767 0.25
|
||||
104 0.6093749999999631 0.3906250000003402 0.25
|
||||
105 0.3968750000003409 0.603125000000244 0.75
|
||||
106 0.4374999999998713 0.4375000000001287 0.75
|
||||
107 0.5739583333335919 0.5718750000001767 0.75
|
||||
108 0.6093749999999631 0.3906250000003402 0.75
|
||||
109 0.3806942419826734 0.25 0.3806942419826734
|
||||
110 0.5625000000001735 0.25 0.4375000000000001
|
||||
111 0.4254282069971791 0.25 0.5712615403304835
|
||||
112 0.6093749999998808 0.25 0.6093749999998808
|
||||
113 0.75 0.3806942419826734 0.3806942419826734
|
||||
114 0.75 0.5625000000001735 0.4375000000000001
|
||||
115 0.75 0.4254282069971791 0.5712615403304835
|
||||
116 0.75 0.6093749999998808 0.6093749999998808
|
||||
117 0.3968750000004991 0.75 0.3968750000002804
|
||||
118 0.4375000000000001 0.75 0.5625000000004308
|
||||
119 0.5739583333336153 0.75 0.4281250000000707
|
||||
120 0.6093749999998166 0.75 0.6093749999993661
|
||||
121 0.25 0.3968750000004991 0.3968750000002804
|
||||
122 0.25 0.4375000000000001 0.5625000000004308
|
||||
123 0.25 0.5739583333336153 0.4281250000000707
|
||||
124 0.25 0.6093749999998166 0.6093749999993661
|
||||
125 0.4962939304035875 0.5214350017087855 0.4925553109323813
|
||||
126 0.3432581985549767 0.6471275530923523 0.3554206606168006
|
||||
127 0.6442168181713744 0.5929232373214773 0.3593785632300704
|
||||
128 0.625174517421737 0.3491579444372839 0.3604636129462503
|
||||
129 0.6130544111091688 0.6576364353993367 0.5046720648819553
|
||||
130 0.4281518698369243 0.3632662294430484 0.3548726263205102
|
||||
131 0.3639383531355198 0.3520949250221278 0.4978389662613994
|
||||
132 0.629585530087249 0.3489878162230438 0.5124654846339122
|
||||
133 0.3710853378652663 0.6517586292698121 0.6382643241302075
|
||||
134 0.5917018263727056 0.6522525456211955 0.6390764961119443
|
||||
135 0.3530810314228338 0.4582477062424107 0.6430239639637545
|
||||
136 0.6571010904289998 0.5300774811423468 0.6603970500567977
|
||||
137 0.6484596018596915 0.361399676127967 0.6360267588157177
|
||||
138 0.4782020887035478 0.3534611476388013 0.6141275027013793
|
||||
$EndNodes
|
||||
$Elements
|
||||
760
|
||||
1 2 2 1 1 1 17 59
|
||||
2 2 2 1 1 24 1 59
|
||||
3 2 2 1 1 18 2 58
|
||||
4 2 2 1 1 2 19 58
|
||||
5 2 2 1 1 20 3 60
|
||||
6 2 2 1 1 3 21 60
|
||||
7 2 2 1 1 22 4 57
|
||||
8 2 2 1 1 4 23 57
|
||||
9 2 2 1 1 17 18 56
|
||||
10 2 2 1 1 17 56 59
|
||||
11 2 2 1 1 56 18 58
|
||||
12 2 2 1 1 19 20 53
|
||||
13 2 2 1 1 19 53 58
|
||||
14 2 2 1 1 53 20 60
|
||||
15 2 2 1 1 21 22 55
|
||||
16 2 2 1 1 21 55 60
|
||||
17 2 2 1 1 55 22 57
|
||||
18 2 2 1 1 23 24 54
|
||||
19 2 2 1 1 23 54 57
|
||||
20 2 2 1 1 54 24 59
|
||||
21 2 2 1 1 54 53 55
|
||||
22 2 2 1 1 53 54 56
|
||||
23 2 2 1 1 55 53 60
|
||||
24 2 2 1 1 53 56 58
|
||||
25 2 2 1 1 54 55 57
|
||||
26 2 2 1 1 56 54 59
|
||||
27 2 2 2 2 5 25 67
|
||||
28 2 2 2 2 32 5 67
|
||||
29 2 2 2 2 26 6 66
|
||||
30 2 2 2 2 6 27 66
|
||||
31 2 2 2 2 28 7 68
|
||||
32 2 2 2 2 7 29 68
|
||||
33 2 2 2 2 30 8 65
|
||||
34 2 2 2 2 8 31 65
|
||||
35 2 2 2 2 25 26 64
|
||||
36 2 2 2 2 25 64 67
|
||||
37 2 2 2 2 64 26 66
|
||||
38 2 2 2 2 27 28 61
|
||||
39 2 2 2 2 27 61 66
|
||||
40 2 2 2 2 61 28 68
|
||||
41 2 2 2 2 29 30 63
|
||||
42 2 2 2 2 29 63 68
|
||||
43 2 2 2 2 63 30 65
|
||||
44 2 2 2 2 31 32 62
|
||||
45 2 2 2 2 31 62 65
|
||||
46 2 2 2 2 62 32 67
|
||||
47 2 2 2 2 62 61 63
|
||||
48 2 2 2 2 61 62 64
|
||||
49 2 2 2 2 63 61 68
|
||||
50 2 2 2 2 61 64 66
|
||||
51 2 2 2 2 62 63 65
|
||||
52 2 2 2 2 64 62 67
|
||||
53 2 2 3 3 17 1 76
|
||||
54 2 2 3 3 1 33 76
|
||||
55 2 2 3 3 2 18 75
|
||||
56 2 2 3 3 35 2 75
|
||||
57 2 2 3 3 5 25 74
|
||||
58 2 2 3 3 34 5 74
|
||||
59 2 2 3 3 26 6 73
|
||||
60 2 2 3 3 6 36 73
|
||||
61 2 2 3 3 18 17 69
|
||||
62 2 2 3 3 69 17 76
|
||||
63 2 2 3 3 18 69 75
|
||||
64 2 2 3 3 25 26 70
|
||||
65 2 2 3 3 25 70 74
|
||||
66 2 2 3 3 70 26 73
|
||||
67 2 2 3 3 33 34 72
|
||||
68 2 2 3 3 33 72 76
|
||||
69 2 2 3 3 72 34 74
|
||||
70 2 2 3 3 36 35 71
|
||||
71 2 2 3 3 71 35 75
|
||||
72 2 2 3 3 36 71 73
|
||||
73 2 2 3 3 69 70 71
|
||||
74 2 2 3 3 70 69 72
|
||||
75 2 2 3 3 69 71 75
|
||||
76 2 2 3 3 72 69 76
|
||||
77 2 2 3 3 71 70 73
|
||||
78 2 2 3 3 70 72 74
|
||||
79 2 2 4 4 19 2 84
|
||||
80 2 2 4 4 2 35 84
|
||||
81 2 2 4 4 3 20 83
|
||||
82 2 2 4 4 37 3 83
|
||||
83 2 2 4 4 6 27 82
|
||||
84 2 2 4 4 36 6 82
|
||||
85 2 2 4 4 28 7 81
|
||||
86 2 2 4 4 7 38 81
|
||||
87 2 2 4 4 20 19 77
|
||||
88 2 2 4 4 77 19 84
|
||||
89 2 2 4 4 20 77 83
|
||||
90 2 2 4 4 27 28 78
|
||||
91 2 2 4 4 27 78 82
|
||||
92 2 2 4 4 78 28 81
|
||||
93 2 2 4 4 35 36 80
|
||||
94 2 2 4 4 35 80 84
|
||||
95 2 2 4 4 80 36 82
|
||||
96 2 2 4 4 38 37 79
|
||||
97 2 2 4 4 79 37 83
|
||||
98 2 2 4 4 38 79 81
|
||||
99 2 2 4 4 77 78 79
|
||||
100 2 2 4 4 78 77 80
|
||||
101 2 2 4 4 77 79 83
|
||||
102 2 2 4 4 80 77 84
|
||||
103 2 2 4 4 79 78 81
|
||||
104 2 2 4 4 78 80 82
|
||||
105 2 2 5 5 21 3 90
|
||||
106 2 2 5 5 3 37 90
|
||||
107 2 2 5 5 4 22 91
|
||||
108 2 2 5 5 39 4 91
|
||||
109 2 2 5 5 7 29 92
|
||||
110 2 2 5 5 38 7 92
|
||||
111 2 2 5 5 30 8 89
|
||||
112 2 2 5 5 8 40 89
|
||||
113 2 2 5 5 22 21 85
|
||||
114 2 2 5 5 85 21 90
|
||||
115 2 2 5 5 22 85 91
|
||||
116 2 2 5 5 29 30 86
|
||||
117 2 2 5 5 29 86 92
|
||||
118 2 2 5 5 86 30 89
|
||||
119 2 2 5 5 37 38 88
|
||||
120 2 2 5 5 37 88 90
|
||||
121 2 2 5 5 88 38 92
|
||||
122 2 2 5 5 40 39 87
|
||||
123 2 2 5 5 87 39 91
|
||||
124 2 2 5 5 40 87 89
|
||||
125 2 2 5 5 85 86 87
|
||||
126 2 2 5 5 86 85 88
|
||||
127 2 2 5 5 85 87 91
|
||||
128 2 2 5 5 88 85 90
|
||||
129 2 2 5 5 87 86 89
|
||||
130 2 2 5 5 86 88 92
|
||||
131 2 2 6 6 1 24 99
|
||||
132 2 2 6 6 33 1 99
|
||||
133 2 2 6 6 23 4 98
|
||||
134 2 2 6 6 4 39 98
|
||||
135 2 2 6 6 32 5 97
|
||||
136 2 2 6 6 5 34 97
|
||||
137 2 2 6 6 8 31 100
|
||||
138 2 2 6 6 40 8 100
|
||||
139 2 2 6 6 24 23 93
|
||||
140 2 2 6 6 93 23 98
|
||||
141 2 2 6 6 24 93 99
|
||||
142 2 2 6 6 31 32 94
|
||||
143 2 2 6 6 31 94 100
|
||||
144 2 2 6 6 94 32 97
|
||||
145 2 2 6 6 34 33 95
|
||||
146 2 2 6 6 95 33 99
|
||||
147 2 2 6 6 34 95 97
|
||||
148 2 2 6 6 39 40 96
|
||||
149 2 2 6 6 39 96 98
|
||||
150 2 2 6 6 96 40 100
|
||||
151 2 2 6 6 93 94 95
|
||||
152 2 2 6 6 94 93 96
|
||||
153 2 2 6 6 93 95 99
|
||||
154 2 2 6 6 96 93 98
|
||||
155 2 2 6 6 95 94 97
|
||||
156 2 2 6 6 94 96 100
|
||||
157 2 2 7 7 9 41 102
|
||||
158 2 2 7 7 44 9 102
|
||||
159 2 2 7 7 41 10 104
|
||||
160 2 2 7 7 10 42 104
|
||||
161 2 2 7 7 42 11 103
|
||||
162 2 2 7 7 11 43 103
|
||||
163 2 2 7 7 43 12 101
|
||||
164 2 2 7 7 12 44 101
|
||||
165 2 2 7 7 102 41 104
|
||||
166 2 2 7 7 42 103 104
|
||||
167 2 2 7 7 43 101 103
|
||||
168 2 2 7 7 101 44 102
|
||||
169 2 2 7 7 101 102 103
|
||||
170 2 2 7 7 103 102 104
|
||||
171 2 2 8 8 13 45 106
|
||||
172 2 2 8 8 48 13 106
|
||||
173 2 2 8 8 45 14 108
|
||||
174 2 2 8 8 14 46 108
|
||||
175 2 2 8 8 46 15 107
|
||||
176 2 2 8 8 15 47 107
|
||||
177 2 2 8 8 47 16 105
|
||||
178 2 2 8 8 16 48 105
|
||||
179 2 2 8 8 106 45 108
|
||||
180 2 2 8 8 46 107 108
|
||||
181 2 2 8 8 47 105 107
|
||||
182 2 2 8 8 105 48 106
|
||||
183 2 2 8 8 105 106 107
|
||||
184 2 2 8 8 107 106 108
|
||||
185 2 2 9 9 41 9 109
|
||||
186 2 2 9 9 9 49 109
|
||||
187 2 2 9 9 10 41 110
|
||||
188 2 2 9 9 50 10 110
|
||||
189 2 2 9 9 13 45 111
|
||||
190 2 2 9 9 49 13 111
|
||||
191 2 2 9 9 45 14 112
|
||||
192 2 2 9 9 14 50 112
|
||||
193 2 2 9 9 41 109 110
|
||||
194 2 2 9 9 111 45 112
|
||||
195 2 2 9 9 109 49 111
|
||||
196 2 2 9 9 50 110 112
|
||||
197 2 2 9 9 110 109 111
|
||||
198 2 2 9 9 110 111 112
|
||||
199 2 2 10 10 42 10 113
|
||||
200 2 2 10 10 10 50 113
|
||||
201 2 2 10 10 11 42 114
|
||||
202 2 2 10 10 51 11 114
|
||||
203 2 2 10 10 14 46 115
|
||||
204 2 2 10 10 50 14 115
|
||||
205 2 2 10 10 46 15 116
|
||||
206 2 2 10 10 15 51 116
|
||||
207 2 2 10 10 42 113 114
|
||||
208 2 2 10 10 115 46 116
|
||||
209 2 2 10 10 113 50 115
|
||||
210 2 2 10 10 51 114 116
|
||||
211 2 2 10 10 114 113 115
|
||||
212 2 2 10 10 114 115 116
|
||||
213 2 2 11 11 43 11 119
|
||||
214 2 2 11 11 11 51 119
|
||||
215 2 2 11 11 12 43 117
|
||||
216 2 2 11 11 52 12 117
|
||||
217 2 2 11 11 15 47 120
|
||||
218 2 2 11 11 51 15 120
|
||||
219 2 2 11 11 47 16 118
|
||||
220 2 2 11 11 16 52 118
|
||||
221 2 2 11 11 117 43 119
|
||||
222 2 2 11 11 47 118 120
|
||||
223 2 2 11 11 119 51 120
|
||||
224 2 2 11 11 52 117 118
|
||||
225 2 2 11 11 118 117 119
|
||||
226 2 2 11 11 118 119 120
|
||||
227 2 2 12 12 9 44 121
|
||||
228 2 2 12 12 49 9 121
|
||||
229 2 2 12 12 44 12 123
|
||||
230 2 2 12 12 12 52 123
|
||||
231 2 2 12 12 48 13 122
|
||||
232 2 2 12 12 13 49 122
|
||||
233 2 2 12 12 16 48 124
|
||||
234 2 2 12 12 52 16 124
|
||||
235 2 2 12 12 121 44 123
|
||||
236 2 2 12 12 48 122 124
|
||||
237 2 2 12 12 49 121 122
|
||||
238 2 2 12 12 123 52 124
|
||||
239 2 2 12 12 122 121 123
|
||||
240 2 2 12 12 122 123 124
|
||||
241 4 2 1 1 105 62 106 107
|
||||
242 4 2 1 1 102 54 101 103
|
||||
243 4 2 1 1 118 86 120 119
|
||||
244 4 2 1 1 124 94 123 122
|
||||
245 4 2 1 1 52 39 12 96
|
||||
246 4 2 1 1 52 12 39 87
|
||||
247 4 2 1 1 88 38 15 51
|
||||
248 4 2 1 1 79 15 38 51
|
||||
249 4 2 1 1 80 14 50 36
|
||||
250 4 2 1 1 71 50 14 36
|
||||
251 4 2 1 1 120 88 15 51
|
||||
252 4 2 1 1 116 15 79 51
|
||||
253 4 2 1 1 50 14 112 71
|
||||
254 4 2 1 1 52 117 12 87
|
||||
255 4 2 1 1 111 69 109 110
|
||||
256 4 2 1 1 114 77 115 113
|
||||
257 4 2 1 1 124 123 94 96
|
||||
258 4 2 1 1 120 86 88 119
|
||||
259 4 2 1 1 14 45 64 108
|
||||
260 4 2 1 1 103 54 101 55
|
||||
261 4 2 1 1 62 105 63 107
|
||||
262 4 2 1 1 63 29 15 47
|
||||
263 4 2 1 1 14 45 26 64
|
||||
264 4 2 1 1 51 11 88 37
|
||||
265 4 2 1 1 80 50 10 35
|
||||
266 4 2 1 1 49 33 9 72
|
||||
267 4 2 1 1 71 10 50 35
|
||||
268 4 2 1 1 79 11 51 37
|
||||
269 4 2 1 1 49 9 33 95
|
||||
270 4 2 1 1 12 123 52 96
|
||||
271 4 2 1 1 96 16 52 40
|
||||
272 4 2 1 1 49 13 34 72
|
||||
273 4 2 1 1 87 52 16 40
|
||||
274 4 2 1 1 13 49 34 95
|
||||
275 4 2 1 1 43 101 12 55
|
||||
276 4 2 1 1 43 12 22 55
|
||||
277 4 2 1 1 106 61 108 107
|
||||
278 4 2 1 1 102 103 104 53
|
||||
279 4 2 1 1 50 115 14 80
|
||||
280 4 2 1 1 80 10 50 113
|
||||
281 4 2 1 1 9 109 49 72
|
||||
282 4 2 1 1 47 15 63 107
|
||||
283 4 2 1 1 124 16 52 96
|
||||
284 4 2 1 1 49 121 9 95
|
||||
285 4 2 1 1 15 28 68 46
|
||||
286 4 2 1 1 81 28 15 46
|
||||
287 4 2 1 1 92 15 29 47
|
||||
288 4 2 1 1 27 82 14 46
|
||||
289 4 2 1 1 14 66 27 46
|
||||
290 4 2 1 1 26 45 14 73
|
||||
291 4 2 1 1 78 115 116 114
|
||||
292 4 2 1 1 112 70 111 110
|
||||
293 4 2 1 1 79 11 114 51
|
||||
294 4 2 1 1 71 50 10 110
|
||||
295 4 2 1 1 10 41 104 56
|
||||
296 4 2 1 1 77 80 115 113
|
||||
297 4 2 1 1 69 109 72 111
|
||||
298 4 2 1 1 63 16 30 47
|
||||
299 4 2 1 1 25 45 13 64
|
||||
300 4 2 1 1 52 16 118 87
|
||||
301 4 2 1 1 95 13 49 122
|
||||
302 4 2 1 1 57 12 23 44
|
||||
303 4 2 1 1 119 11 88 51
|
||||
304 4 2 1 1 41 17 9 56
|
||||
305 4 2 1 1 18 41 10 56
|
||||
306 4 2 1 1 21 11 43 55
|
||||
307 4 2 1 1 63 105 16 47
|
||||
308 4 2 1 1 13 45 106 64
|
||||
309 4 2 1 1 9 102 41 56
|
||||
310 4 2 1 1 72 49 13 111
|
||||
311 4 2 1 1 11 103 43 55
|
||||
312 4 2 1 1 70 112 71 110
|
||||
313 4 2 1 1 116 79 78 114
|
||||
314 4 2 1 1 32 13 48 67
|
||||
315 4 2 1 1 16 89 30 47
|
||||
316 4 2 1 1 32 48 13 97
|
||||
317 4 2 1 1 48 16 100 31
|
||||
318 4 2 1 1 121 123 93 122
|
||||
319 4 2 1 1 119 117 118 85
|
||||
320 4 2 1 1 10 19 42 84
|
||||
321 4 2 1 1 17 9 76 41
|
||||
322 4 2 1 1 24 9 59 44
|
||||
323 4 2 1 1 42 19 10 58
|
||||
324 4 2 1 1 10 41 18 75
|
||||
325 4 2 1 1 20 83 11 42
|
||||
326 4 2 1 1 90 11 43 21
|
||||
327 4 2 1 1 53 104 102 56
|
||||
328 4 2 1 1 106 61 64 108
|
||||
329 4 2 1 1 87 118 117 85
|
||||
330 4 2 1 1 95 121 93 122
|
||||
331 4 2 1 1 80 50 115 113
|
||||
332 4 2 1 1 109 49 72 111
|
||||
333 4 2 1 1 78 27 28 46
|
||||
334 4 2 1 1 31 94 48 32
|
||||
335 4 2 1 1 19 77 20 42
|
||||
336 4 2 1 1 23 24 44 93
|
||||
337 4 2 1 1 123 124 52 96
|
||||
338 4 2 1 1 88 120 119 51
|
||||
339 4 2 1 1 91 43 85 117
|
||||
340 4 2 1 1 39 98 12 96
|
||||
341 4 2 1 1 12 91 39 87
|
||||
342 4 2 1 1 15 92 38 88
|
||||
343 4 2 1 1 38 81 15 79
|
||||
344 4 2 1 1 36 80 14 82
|
||||
345 4 2 1 1 14 71 36 73
|
||||
346 4 2 1 1 103 102 54 53
|
||||
347 4 2 1 1 61 106 62 107
|
||||
348 4 2 1 1 86 29 30 47
|
||||
349 4 2 1 1 26 45 70 25
|
||||
350 4 2 1 1 21 85 22 43
|
||||
351 4 2 1 1 94 93 123 122
|
||||
352 4 2 1 1 119 118 86 85
|
||||
353 4 2 1 1 12 96 93 123
|
||||
354 4 2 1 1 115 78 77 114
|
||||
355 4 2 1 1 69 111 70 110
|
||||
356 4 2 1 1 28 27 61 46
|
||||
357 4 2 1 1 48 62 31 32
|
||||
358 4 2 1 1 88 15 92 120
|
||||
359 4 2 1 1 79 81 15 116
|
||||
360 4 2 1 1 71 14 112 73
|
||||
361 4 2 1 1 114 116 79 51
|
||||
362 4 2 1 1 112 50 71 110
|
||||
363 4 2 1 1 91 12 117 87
|
||||
364 4 2 1 1 80 115 14 82
|
||||
365 4 2 1 1 63 15 29 68
|
||||
366 4 2 1 1 64 26 14 66
|
||||
367 4 2 1 1 47 63 105 107
|
||||
368 4 2 1 1 43 103 101 55
|
||||
369 4 2 1 1 35 10 80 84
|
||||
370 4 2 1 1 33 76 9 72
|
||||
371 4 2 1 1 37 11 88 90
|
||||
372 4 2 1 1 35 71 10 75
|
||||
373 4 2 1 1 37 79 11 83
|
||||
374 4 2 1 1 9 99 33 95
|
||||
375 4 2 1 1 68 63 15 107
|
||||
376 4 2 1 1 99 44 93 121
|
||||
377 4 2 1 1 18 69 41 17
|
||||
378 4 2 1 1 10 35 2 84
|
||||
379 4 2 1 1 15 7 28 81
|
||||
380 4 2 1 1 3 37 90 11
|
||||
381 4 2 1 1 108 64 14 66
|
||||
382 4 2 1 1 51 38 79 37
|
||||
383 4 2 1 1 12 4 23 98
|
||||
384 4 2 1 1 12 39 91 4
|
||||
385 4 2 1 1 49 33 72 34
|
||||
386 4 2 1 1 10 71 110 75
|
||||
387 4 2 1 1 114 11 79 83
|
||||
388 4 2 1 1 40 96 16 100
|
||||
389 4 2 1 1 34 13 74 72
|
||||
390 4 2 1 1 16 87 40 89
|
||||
391 4 2 1 1 34 97 13 95
|
||||
392 4 2 1 1 20 19 42 53
|
||||
393 4 2 1 1 54 23 24 44
|
||||
394 4 2 1 1 87 16 118 89
|
||||
395 4 2 1 1 95 97 13 122
|
||||
396 4 2 1 1 57 22 12 55
|
||||
397 4 2 1 1 41 102 104 56
|
||||
398 4 2 1 1 64 45 106 108
|
||||
399 4 2 1 1 101 57 12 55
|
||||
400 4 2 1 1 74 13 5 25
|
||||
401 4 2 1 1 13 34 74 5
|
||||
402 4 2 1 1 8 40 16 100
|
||||
403 4 2 1 1 16 31 65 8
|
||||
404 4 2 1 1 82 36 6 14
|
||||
405 4 2 1 1 102 9 59 56
|
||||
406 4 2 1 1 106 67 13 64
|
||||
407 4 2 1 1 119 88 11 90
|
||||
408 4 2 1 1 95 49 121 122
|
||||
409 4 2 1 1 52 118 117 87
|
||||
410 4 2 1 1 124 16 96 100
|
||||
411 4 2 1 1 80 10 113 84
|
||||
412 4 2 1 1 109 9 76 72
|
||||
413 4 2 1 1 72 13 70 111
|
||||
414 4 2 1 1 99 9 121 95
|
||||
415 4 2 1 1 30 65 16 63
|
||||
416 4 2 1 1 13 67 25 64
|
||||
417 4 2 1 1 11 55 53 103
|
||||
418 4 2 1 1 123 12 44 93
|
||||
419 4 2 1 1 56 104 10 58
|
||||
420 4 2 1 1 10 18 56 58
|
||||
421 4 2 1 1 21 60 11 55
|
||||
422 4 2 1 1 17 59 9 56
|
||||
423 4 2 1 1 16 63 62 105
|
||||
424 4 2 1 1 48 105 16 62
|
||||
425 4 2 1 1 111 45 13 70
|
||||
426 4 2 1 1 119 86 88 85
|
||||
427 4 2 1 1 123 93 94 96
|
||||
428 4 2 1 1 115 78 80 77
|
||||
429 4 2 1 1 111 72 69 70
|
||||
430 4 2 1 1 55 103 54 53
|
||||
431 4 2 1 1 63 61 62 107
|
||||
432 4 2 1 1 14 27 66 6
|
||||
433 4 2 1 1 99 9 1 24
|
||||
434 4 2 1 1 49 33 34 95
|
||||
435 4 2 1 1 96 52 39 40
|
||||
436 4 2 1 1 22 12 91 4
|
||||
437 4 2 1 1 20 11 83 3
|
||||
438 4 2 1 1 29 15 92 7
|
||||
439 4 2 1 1 18 10 75 2
|
||||
440 4 2 1 1 36 50 80 35
|
||||
441 4 2 1 1 18 17 41 56
|
||||
442 4 2 1 1 51 88 38 37
|
||||
443 4 2 1 1 62 31 16 48
|
||||
444 4 2 1 1 62 16 31 65
|
||||
445 4 2 1 1 26 45 25 64
|
||||
446 4 2 1 1 104 58 42 10
|
||||
447 4 2 1 1 29 63 30 47
|
||||
448 4 2 1 1 77 78 79 114
|
||||
449 4 2 1 1 71 69 70 110
|
||||
450 4 2 1 1 42 103 11 53
|
||||
451 4 2 1 1 93 94 95 122
|
||||
452 4 2 1 1 118 87 86 85
|
||||
453 4 2 1 1 61 62 106 64
|
||||
454 4 2 1 1 53 102 54 56
|
||||
455 4 2 1 1 78 82 27 46
|
||||
456 4 2 1 1 94 48 32 97
|
||||
457 4 2 1 1 86 30 89 47
|
||||
458 4 2 1 1 78 28 81 46
|
||||
459 4 2 1 1 26 70 45 73
|
||||
460 4 2 1 1 100 94 48 31
|
||||
461 4 2 1 1 86 92 29 47
|
||||
462 4 2 1 1 76 69 17 41
|
||||
463 4 2 1 1 42 19 77 84
|
||||
464 4 2 1 1 77 83 20 42
|
||||
465 4 2 1 1 18 41 69 75
|
||||
466 4 2 1 1 43 85 90 21
|
||||
467 4 2 1 1 91 43 117 12
|
||||
468 4 2 1 1 48 62 32 67
|
||||
469 4 2 1 1 27 66 61 46
|
||||
470 4 2 1 1 68 28 61 46
|
||||
471 4 2 1 1 54 24 59 44
|
||||
472 4 2 1 1 19 42 53 58
|
||||
473 4 2 1 1 23 54 57 44
|
||||
474 4 2 1 1 12 93 96 98
|
||||
475 4 2 1 1 99 44 121 9
|
||||
476 4 2 1 1 42 58 104 53
|
||||
477 4 2 1 1 21 43 22 55
|
||||
478 4 2 1 1 53 20 11 42
|
||||
479 4 2 1 1 53 11 20 60
|
||||
480 4 2 1 1 106 67 48 13
|
||||
481 4 2 1 1 36 71 50 35
|
||||
482 4 2 1 1 52 87 39 40
|
||||
483 4 2 1 1 48 67 106 62
|
||||
484 4 2 1 1 72 70 13 74
|
||||
485 4 2 1 1 9 33 99 1
|
||||
486 4 2 1 1 3 37 11 83
|
||||
487 4 2 1 1 13 34 5 97
|
||||
488 4 2 1 1 12 39 4 98
|
||||
489 4 2 1 1 14 36 6 73
|
||||
490 4 2 1 1 15 38 92 7
|
||||
491 4 2 1 1 8 40 89 16
|
||||
492 4 2 1 1 75 35 2 10
|
||||
493 4 2 1 1 30 16 65 8
|
||||
494 4 2 1 1 14 27 6 82
|
||||
495 4 2 1 1 26 14 66 6
|
||||
496 4 2 1 1 16 31 8 100
|
||||
497 4 2 1 1 32 13 67 5
|
||||
498 4 2 1 1 13 67 5 25
|
||||
499 4 2 1 1 68 7 28 15
|
||||
500 4 2 1 1 29 15 7 68
|
||||
501 4 2 1 1 57 4 23 12
|
||||
502 4 2 1 1 22 12 4 57
|
||||
503 4 2 1 1 10 19 84 2
|
||||
504 4 2 1 1 9 59 1 24
|
||||
505 4 2 1 1 17 9 59 1
|
||||
506 4 2 1 1 18 10 2 58
|
||||
507 4 2 1 1 11 21 90 3
|
||||
508 4 2 1 1 20 11 3 60
|
||||
509 4 2 1 1 16 62 63 65
|
||||
510 4 2 1 1 11 53 55 60
|
||||
511 4 2 1 1 78 81 79 116
|
||||
512 4 2 1 1 71 112 70 73
|
||||
513 4 2 1 1 86 88 92 120
|
||||
514 4 2 1 1 96 94 124 100
|
||||
515 4 2 1 1 94 97 95 122
|
||||
516 4 2 1 1 89 118 87 86
|
||||
517 4 2 1 1 15 38 7 81
|
||||
518 4 2 1 1 102 44 59 9
|
||||
519 4 2 1 1 59 44 102 54
|
||||
520 4 2 1 1 110 71 69 75
|
||||
521 4 2 1 1 79 77 114 83
|
||||
522 4 2 1 1 76 69 109 72
|
||||
523 4 2 1 1 113 77 80 84
|
||||
524 4 2 1 1 93 99 121 95
|
||||
525 4 2 1 1 87 117 91 85
|
||||
526 4 2 1 1 90 119 43 11
|
||||
527 4 2 1 1 80 78 115 82
|
||||
528 4 2 1 1 88 119 85 90
|
||||
529 4 2 1 1 90 43 119 85
|
||||
530 4 2 1 1 46 108 66 61
|
||||
531 4 2 1 1 46 66 108 14
|
||||
532 4 2 1 1 26 14 6 73
|
||||
533 4 2 1 1 44 101 57 12
|
||||
534 4 2 1 1 44 57 101 54
|
||||
535 4 2 1 1 46 107 68 15
|
||||
536 4 2 1 1 46 68 107 61
|
||||
537 4 2 1 1 9 33 1 76
|
||||
538 4 2 1 1 100 124 48 94
|
||||
539 4 2 1 1 100 48 124 16
|
||||
540 4 2 1 1 25 70 13 45
|
||||
541 4 2 1 1 56 53 104 58
|
||||
542 4 2 1 1 61 64 108 66
|
||||
543 4 2 1 1 106 62 67 64
|
||||
544 4 2 1 1 102 59 54 56
|
||||
545 4 2 1 1 32 13 5 97
|
||||
546 4 2 1 1 30 16 8 89
|
||||
547 4 2 1 1 13 70 25 74
|
||||
548 4 2 1 1 97 122 48 13
|
||||
549 4 2 1 1 75 110 41 69
|
||||
550 4 2 1 1 54 57 101 55
|
||||
551 4 2 1 1 97 48 122 94
|
||||
552 4 2 1 1 47 118 89 86
|
||||
553 4 2 1 1 47 89 118 16
|
||||
554 4 2 1 1 17 9 1 76
|
||||
555 4 2 1 1 11 21 3 60
|
||||
556 4 2 1 1 10 19 2 58
|
||||
557 4 2 1 1 75 41 110 10
|
||||
558 4 2 1 1 61 63 68 107
|
||||
559 4 2 1 1 70 111 45 112
|
||||
560 4 2 1 1 78 115 46 116
|
||||
561 4 2 1 1 77 114 42 113
|
||||
562 4 2 1 1 69 41 109 110
|
||||
563 4 2 1 1 107 61 108 46
|
||||
564 4 2 1 1 103 42 104 53
|
||||
565 4 2 1 1 118 86 47 120
|
||||
566 4 2 1 1 94 124 48 122
|
||||
567 4 2 1 1 117 119 43 85
|
||||
568 4 2 1 1 123 44 121 93
|
||||
569 4 2 1 1 101 54 102 44
|
||||
570 4 2 1 1 48 105 62 106
|
||||
571 4 2 1 1 91 43 12 22
|
||||
572 4 2 1 1 91 43 22 85
|
||||
573 4 2 1 1 93 12 23 98
|
||||
574 4 2 1 1 93 23 12 44
|
||||
575 4 2 1 1 46 81 116 15
|
||||
576 4 2 1 1 46 116 81 78
|
||||
577 4 2 1 1 92 47 120 15
|
||||
578 4 2 1 1 120 47 92 86
|
||||
579 4 2 1 1 46 82 115 78
|
||||
580 4 2 1 1 46 115 82 14
|
||||
581 4 2 1 1 73 45 112 70
|
||||
582 4 2 1 1 73 112 45 14
|
||||
583 4 2 1 1 99 44 9 24
|
||||
584 4 2 1 1 99 44 24 93
|
||||
585 4 2 1 1 84 42 113 77
|
||||
586 4 2 1 1 84 113 42 10
|
||||
587 4 2 1 1 76 41 109 69
|
||||
588 4 2 1 1 109 41 76 9
|
||||
589 4 2 1 1 42 83 114 77
|
||||
590 4 2 1 1 42 114 83 11
|
||||
591 4 2 2 2 135 13 122 131
|
||||
592 4 2 2 2 132 138 125 110
|
||||
593 4 2 2 2 138 108 125 106
|
||||
594 4 2 2 2 136 108 125 137
|
||||
595 4 2 2 2 110 138 125 131
|
||||
596 4 2 2 2 136 107 134 125
|
||||
597 4 2 2 2 122 135 131 125
|
||||
598 4 2 2 2 13 49 122 131
|
||||
599 4 2 2 2 136 108 137 46
|
||||
600 4 2 2 2 110 138 131 111
|
||||
601 4 2 2 2 132 138 110 112
|
||||
602 4 2 2 2 106 107 108 125
|
||||
603 4 2 2 2 138 112 137 45
|
||||
604 4 2 2 2 104 127 125 128
|
||||
605 4 2 2 2 113 115 114 125
|
||||
606 4 2 2 2 131 122 125 121
|
||||
607 4 2 2 2 112 45 14 137
|
||||
608 4 2 2 2 110 131 125 130
|
||||
609 4 2 2 2 115 116 114 125
|
||||
610 4 2 2 2 132 138 112 137
|
||||
611 4 2 2 2 50 137 115 132
|
||||
612 4 2 2 2 104 127 128 42
|
||||
613 4 2 2 2 105 134 125 133
|
||||
614 4 2 2 2 129 120 51 119
|
||||
615 4 2 2 2 104 130 128 125
|
||||
616 4 2 2 2 105 134 133 47
|
||||
617 4 2 2 2 135 106 138 125
|
||||
618 4 2 2 2 106 105 107 125
|
||||
619 4 2 2 2 138 108 106 45
|
||||
620 4 2 2 2 104 130 125 102
|
||||
621 4 2 2 2 104 127 42 103
|
||||
622 4 2 2 2 109 131 49 111
|
||||
623 4 2 2 2 106 135 48 105
|
||||
624 4 2 2 2 126 101 43 125
|
||||
625 4 2 2 2 138 137 125 108
|
||||
626 4 2 2 2 104 127 103 125
|
||||
627 4 2 2 2 116 114 129 51
|
||||
628 4 2 2 2 136 108 46 107
|
||||
629 4 2 2 2 136 108 107 125
|
||||
630 4 2 2 2 52 124 123 125
|
||||
631 4 2 2 2 132 112 110 50
|
||||
632 4 2 2 2 44 121 125 123
|
||||
633 4 2 2 2 131 122 121 49
|
||||
634 4 2 2 2 105 134 47 107
|
||||
635 4 2 2 2 106 13 135 138
|
||||
636 4 2 2 2 52 133 125 118
|
||||
637 4 2 2 2 103 43 101 125
|
||||
638 4 2 2 2 117 43 119 125
|
||||
639 4 2 2 2 105 134 107 125
|
||||
640 4 2 2 2 137 115 132 125
|
||||
641 4 2 2 2 50 137 132 112
|
||||
642 4 2 2 2 106 135 105 125
|
||||
643 4 2 2 2 102 101 44 125
|
||||
644 4 2 2 2 104 130 102 41
|
||||
645 4 2 2 2 138 45 13 111
|
||||
646 4 2 2 2 131 138 135 13
|
||||
647 4 2 2 2 138 112 45 111
|
||||
648 4 2 2 2 131 138 13 111
|
||||
649 4 2 2 2 107 134 15 136
|
||||
650 4 2 2 2 118 52 117 125
|
||||
651 4 2 2 2 101 126 12 44
|
||||
652 4 2 2 2 104 130 41 128
|
||||
653 4 2 2 2 138 137 108 45
|
||||
654 4 2 2 2 133 118 16 47
|
||||
655 4 2 2 2 44 101 126 125
|
||||
656 4 2 2 2 133 134 118 47
|
||||
657 4 2 2 2 133 134 125 118
|
||||
658 4 2 2 2 124 122 123 125
|
||||
659 4 2 2 2 129 118 119 125
|
||||
660 4 2 2 2 102 104 103 125
|
||||
661 4 2 2 2 135 48 13 106
|
||||
662 4 2 2 2 123 122 121 125
|
||||
663 4 2 2 2 103 127 43 125
|
||||
664 4 2 2 2 106 45 13 138
|
||||
665 4 2 2 2 103 11 127 42
|
||||
666 4 2 2 2 127 51 129 114
|
||||
667 4 2 2 2 13 49 131 111
|
||||
668 4 2 2 2 137 108 14 46
|
||||
669 4 2 2 2 15 47 134 107
|
||||
670 4 2 2 2 10 41 128 104
|
||||
671 4 2 2 2 16 118 133 52
|
||||
672 4 2 2 2 46 107 15 136
|
||||
673 4 2 2 2 41 102 9 130
|
||||
674 4 2 2 2 128 50 132 110
|
||||
675 4 2 2 2 10 41 110 128
|
||||
676 4 2 2 2 50 137 112 14
|
||||
677 4 2 2 2 130 102 9 44
|
||||
678 4 2 2 2 105 133 16 47
|
||||
679 4 2 2 2 127 11 103 43
|
||||
680 4 2 2 2 128 130 41 110
|
||||
681 4 2 2 2 116 134 15 51
|
||||
682 4 2 2 2 137 45 14 108
|
||||
683 4 2 2 2 12 126 101 43
|
||||
684 4 2 2 2 133 48 135 105
|
||||
685 4 2 2 2 128 42 10 104
|
||||
686 4 2 2 2 131 9 109 49
|
||||
687 4 2 2 2 118 117 119 125
|
||||
688 4 2 2 2 102 103 101 125
|
||||
689 4 2 2 2 129 118 125 134
|
||||
690 4 2 2 2 125 129 116 114
|
||||
691 4 2 2 2 117 126 43 125
|
||||
692 4 2 2 2 126 117 12 52
|
||||
693 4 2 2 2 52 126 117 125
|
||||
694 4 2 2 2 12 117 126 43
|
||||
695 4 2 2 2 127 51 114 11
|
||||
696 4 2 2 2 114 129 127 125
|
||||
697 4 2 2 2 127 119 43 125
|
||||
698 4 2 2 2 119 11 127 43
|
||||
699 4 2 2 2 127 113 114 125
|
||||
700 4 2 2 2 127 113 42 114
|
||||
701 4 2 2 2 128 130 110 125
|
||||
702 4 2 2 2 15 47 120 134
|
||||
703 4 2 2 2 127 11 114 42
|
||||
704 4 2 2 2 120 47 118 134
|
||||
705 4 2 2 2 44 130 102 125
|
||||
706 4 2 2 2 44 126 12 123
|
||||
707 4 2 2 2 123 44 126 125
|
||||
708 4 2 2 2 129 118 134 120
|
||||
709 4 2 2 2 110 132 128 125
|
||||
710 4 2 2 2 128 127 125 113
|
||||
711 4 2 2 2 128 127 113 42
|
||||
712 4 2 2 2 128 50 110 10
|
||||
713 4 2 2 2 113 42 10 128
|
||||
714 4 2 2 2 129 134 125 116
|
||||
715 4 2 2 2 127 51 11 119
|
||||
716 4 2 2 2 129 134 116 51
|
||||
717 4 2 2 2 127 51 119 129
|
||||
718 4 2 2 2 129 119 127 125
|
||||
719 4 2 2 2 110 131 130 109
|
||||
720 4 2 2 2 109 130 9 131
|
||||
721 4 2 2 2 121 130 9 44
|
||||
722 4 2 2 2 122 48 13 135
|
||||
723 4 2 2 2 44 121 130 125
|
||||
724 4 2 2 2 110 138 111 112
|
||||
725 4 2 2 2 131 138 125 135
|
||||
726 4 2 2 2 115 137 14 46
|
||||
727 4 2 2 2 126 52 12 123
|
||||
728 4 2 2 2 123 126 52 125
|
||||
729 4 2 2 2 50 137 14 115
|
||||
730 4 2 2 2 136 137 115 46
|
||||
731 4 2 2 2 121 9 131 49
|
||||
732 4 2 2 2 121 131 130 125
|
||||
733 4 2 2 2 131 130 9 121
|
||||
734 4 2 2 2 113 132 115 125
|
||||
735 4 2 2 2 113 50 115 132
|
||||
736 4 2 2 2 128 50 10 113
|
||||
737 4 2 2 2 132 113 128 125
|
||||
738 4 2 2 2 128 50 113 132
|
||||
739 4 2 2 2 133 105 135 125
|
||||
740 4 2 2 2 52 124 125 133
|
||||
741 4 2 2 2 133 48 105 16
|
||||
742 4 2 2 2 16 133 124 52
|
||||
743 4 2 2 2 136 137 125 115
|
||||
744 4 2 2 2 132 138 137 125
|
||||
745 4 2 2 2 41 130 9 109
|
||||
746 4 2 2 2 134 120 15 51
|
||||
747 4 2 2 2 129 118 120 119
|
||||
748 4 2 2 2 129 120 134 51
|
||||
749 4 2 2 2 135 122 124 125
|
||||
750 4 2 2 2 135 48 124 122
|
||||
751 4 2 2 2 133 48 16 124
|
||||
752 4 2 2 2 133 135 124 125
|
||||
753 4 2 2 2 133 48 124 135
|
||||
754 4 2 2 2 116 136 134 125
|
||||
755 4 2 2 2 115 136 116 125
|
||||
756 4 2 2 2 46 115 136 116
|
||||
757 4 2 2 2 136 134 15 116
|
||||
758 4 2 2 2 46 136 15 116
|
||||
759 4 2 2 2 109 41 130 110
|
||||
760 4 2 2 2 110 131 109 111
|
||||
$EndElements
|
||||
@@ -1,86 +0,0 @@
|
||||
MFEM NURBS mesh v1.0
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
# Four segments with different NURBS orders, described via patches.
|
||||
elements
|
||||
4
|
||||
1 1 0 1
|
||||
2 1 2 3
|
||||
3 1 4 5
|
||||
4 1 6 7
|
||||
|
||||
boundary
|
||||
0
|
||||
|
||||
edges
|
||||
4
|
||||
0 0 1
|
||||
1 2 3
|
||||
2 4 5
|
||||
3 6 7
|
||||
|
||||
vertices
|
||||
8
|
||||
|
||||
patches
|
||||
|
||||
# Patch 0: linear (order 1, 3 spans)
|
||||
knotvectors
|
||||
1
|
||||
1 4 0 0 .4 .6 1 1
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
controlpoints
|
||||
0.0 0.0 1.0
|
||||
0.6 0.4 1.0
|
||||
0.4 0.6 1.0
|
||||
1.0 1.0 1.0
|
||||
|
||||
# Patch 1: quadratic (order 2, 2 spans)
|
||||
knotvectors
|
||||
1
|
||||
2 4 0 0 0 .5 1 1 1
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
controlpoints
|
||||
1.0 0.0 1.0
|
||||
1.9 0.0 1.21
|
||||
2.0 0.9 1.22
|
||||
2.0 1.0 1.0
|
||||
|
||||
# Patch 2: cubic (order 3, 3 spans)
|
||||
knotvectors
|
||||
1
|
||||
3 6 0 0 0 0 .33 .66 1 1 1 1
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
controlpoints
|
||||
2.0 0.0 1.0
|
||||
2.1 0.2 1.31
|
||||
3.5 0.4 1.32
|
||||
2.5 0.6 1.33
|
||||
2.9 1.0 1.34
|
||||
3.0 1.0 1.0
|
||||
|
||||
# Patch 3: quartic (order 4, 1 span)
|
||||
knotvectors
|
||||
1
|
||||
4 5 0 0 0 0 0 1 1 1 1 1
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
controlpoints
|
||||
3.0 0.0 1.0
|
||||
3.45 0.5 1.41
|
||||
3.50 1.0 1.42
|
||||
3.75 0.8 1.43
|
||||
4.0 0.0 1.0
|
||||
@@ -1,79 +0,0 @@
|
||||
MFEM NURBS mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see fem/geom.hpp):
|
||||
#
|
||||
# SEGMENT = 1
|
||||
# SQUARE = 3
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
# Three segments with different NURBS orders, described via patches.
|
||||
elements
|
||||
3
|
||||
1 1 0 1
|
||||
2 1 2 3
|
||||
3 1 4 5
|
||||
|
||||
boundary
|
||||
6
|
||||
1 0 0
|
||||
1 0 1
|
||||
1 0 2
|
||||
1 0 3
|
||||
1 0 4
|
||||
1 0 5
|
||||
|
||||
edges
|
||||
3
|
||||
0 0 1
|
||||
1 2 3
|
||||
2 4 5
|
||||
|
||||
vertices
|
||||
6
|
||||
|
||||
patches
|
||||
|
||||
# Patch 0: linear (order 1, 2 control points)
|
||||
knotvectors
|
||||
1
|
||||
1 2 0 0 1 1
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
controlpoints
|
||||
0.0 0.0 1.0
|
||||
1.0 1.0 1.0
|
||||
|
||||
# Patch 1: quadratic (order 2, 3 control points)
|
||||
knotvectors
|
||||
1
|
||||
2 3 0 0 0 1 1 1
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
controlpoints
|
||||
1.0 0.0 1.0
|
||||
1.02 1.02 1.2
|
||||
2.0 1.0 1.0
|
||||
|
||||
# Patch 2: cubic (order 3, 4 control points)
|
||||
knotvectors
|
||||
1
|
||||
3 4 0 0 0 0 1 1 1 1
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
controlpoints
|
||||
2.0 0.0 1.0
|
||||
2.03 0.83 1.31
|
||||
2.33 1.03 1.32
|
||||
3.0 1.0 1.0
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
MFEM NURBS mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see fem/geom.hpp):
|
||||
#
|
||||
# SEGMENT = 1
|
||||
# SQUARE = 3
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
elements
|
||||
3
|
||||
1 1 0 1
|
||||
2 1 2 3
|
||||
3 1 4 5
|
||||
|
||||
boundary
|
||||
6
|
||||
1 0 0
|
||||
1 0 1
|
||||
1 0 2
|
||||
1 0 3
|
||||
1 0 4
|
||||
1 0 5
|
||||
|
||||
edges
|
||||
3
|
||||
0 0 1
|
||||
1 2 3
|
||||
2 4 5
|
||||
|
||||
vertices
|
||||
6
|
||||
|
||||
# Edge 0: linear (order 1, 2 control points)
|
||||
# Edge 1: quadratic (order 2, 3 control points)
|
||||
# Edge 2: cubic (order 3, 4 control points)
|
||||
knotvectors
|
||||
3
|
||||
1 2 0 0 1 1
|
||||
2 3 0 0 0 1 1 1
|
||||
3 4 0 0 0 0 1 1 1 1
|
||||
|
||||
# One weight per control point, in the same order as the control points; (2 + 3 + 4) = 9 weights total
|
||||
weights
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1.2
|
||||
1.31
|
||||
1.32
|
||||
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: NURBS
|
||||
VDim: 2
|
||||
Ordering: 1
|
||||
|
||||
0.0 0.0
|
||||
1.0 1.0
|
||||
1.0 0.0
|
||||
2.0 1.0
|
||||
2.0 0.0
|
||||
3.0 1.0
|
||||
1.02 1.02
|
||||
2.03 0.83
|
||||
2.33 1.03
|
||||
@@ -1,79 +0,0 @@
|
||||
MFEM NURBS mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see fem/geom.hpp):
|
||||
#
|
||||
# SEGMENT = 1
|
||||
# SQUARE = 3
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
# Three segments with different NURBS orders, described via patches.
|
||||
elements
|
||||
3
|
||||
1 1 0 1
|
||||
2 1 2 3
|
||||
3 1 4 5
|
||||
|
||||
boundary
|
||||
6
|
||||
1 0 0
|
||||
1 0 1
|
||||
1 0 2
|
||||
1 0 3
|
||||
1 0 4
|
||||
1 0 5
|
||||
|
||||
edges
|
||||
3
|
||||
0 0 1
|
||||
1 2 3
|
||||
2 4 5
|
||||
|
||||
vertices
|
||||
6
|
||||
|
||||
patches
|
||||
|
||||
# Patch 0: linear (order 1, 2 control points)
|
||||
knotvectors
|
||||
1
|
||||
1 2 0 0 1 1
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
controlpoints
|
||||
0.0 0.0 0.01 1.0
|
||||
1.0 1.0 1.01 1.0
|
||||
|
||||
# Patch 1: quadratic (order 2, 3 control points)
|
||||
knotvectors
|
||||
1
|
||||
2 3 0 0 0 1 1 1
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
controlpoints
|
||||
1.0 0.0 0.02 1.0
|
||||
1.02 1.02 0.52 1.2
|
||||
2.0 1.0 1.02 1.0
|
||||
|
||||
# Patch 2: cubic (order 3, 4 control points)
|
||||
knotvectors
|
||||
1
|
||||
3 4 0 0 0 0 1 1 1 1
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
controlpoints
|
||||
2.0 0.0 0.03 1.0
|
||||
2.03 0.83 0.33 1.31
|
||||
2.33 1.03 0.63 1.32
|
||||
3.0 1.0 1.03 1.0
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
MFEM NURBS mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see fem/geom.hpp):
|
||||
#
|
||||
# SEGMENT = 1
|
||||
# SQUARE = 3
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
1
|
||||
|
||||
elements
|
||||
3
|
||||
1 1 0 1
|
||||
2 1 2 3
|
||||
3 1 4 5
|
||||
|
||||
boundary
|
||||
6
|
||||
1 0 0
|
||||
1 0 1
|
||||
1 0 2
|
||||
1 0 3
|
||||
1 0 4
|
||||
1 0 5
|
||||
|
||||
edges
|
||||
3
|
||||
0 0 1
|
||||
1 2 3
|
||||
2 4 5
|
||||
|
||||
vertices
|
||||
6
|
||||
|
||||
# Edge 0: linear (order 1, 2 control points)
|
||||
# Edge 1: quadratic (order 2, 3 control points)
|
||||
# Edge 2: cubic (order 3, 4 control points)
|
||||
knotvectors
|
||||
3
|
||||
1 2 0 0 1 1
|
||||
2 3 0 0 0 1 1 1
|
||||
3 4 0 0 0 0 1 1 1 1
|
||||
|
||||
# One weight per control point, in the same order as the control points; (2 + 3 + 4) = 9 weights total
|
||||
weights
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1.2
|
||||
1.31
|
||||
1.32
|
||||
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: NURBS
|
||||
VDim: 3
|
||||
Ordering: 1
|
||||
|
||||
0.0 0.0 0.01
|
||||
1.0 1.0 1.01
|
||||
1.0 0.0 0.02
|
||||
2.0 1.0 1.02
|
||||
2.0 0.0 0.03
|
||||
3.0 1.0 1.03
|
||||
1.02 1.02 0.52
|
||||
2.03 0.83 0.33
|
||||
2.33 1.03 0.63
|
||||
@@ -1,77 +0,0 @@
|
||||
// Square-in-square 2D geometry for MFEM
|
||||
// Creates concentric squares with different material attributes
|
||||
|
||||
// Define the square sizes
|
||||
L_outer = 2.0;
|
||||
L_inner = 0.5;
|
||||
|
||||
// Set mesh size and algorithm
|
||||
mesh_size = 1.0;
|
||||
Mesh.Algorithm = 6; // Frontal-Delaunay for 2D triangular mesh
|
||||
Mesh.CharacteristicLengthFactor = 1.0;
|
||||
Mesh.MshFileVersion = 2.2;
|
||||
|
||||
// Define center point for concentric squares
|
||||
cx = 0.0;
|
||||
cy = 0.0;
|
||||
|
||||
// Define the points (vertices of the outer square)
|
||||
Point(1) = {cx-L_outer/2, cy-L_outer/2, 0, mesh_size}; // bottom-left outer
|
||||
Point(2) = {cx+L_outer/2, cy-L_outer/2, 0, mesh_size}; // bottom-right outer
|
||||
Point(3) = {cx+L_outer/2, cy+L_outer/2, 0, mesh_size}; // top-right outer
|
||||
Point(4) = {cx-L_outer/2, cy+L_outer/2, 0, mesh_size}; // top-left outer
|
||||
|
||||
// Define the points (vertices of the inner square)
|
||||
Point(5) = {cx-L_inner/2, cy-L_inner/2, 0, mesh_size}; // bottom-left inner
|
||||
Point(6) = {cx+L_inner/2, cy-L_inner/2, 0, mesh_size}; // bottom-right inner
|
||||
Point(7) = {cx+L_inner/2, cy+L_inner/2, 0, mesh_size}; // top-right inner
|
||||
Point(8) = {cx-L_inner/2, cy+L_inner/2, 0, mesh_size}; // top-left inner
|
||||
|
||||
// Define the lines (edges of the outer square)
|
||||
Line(1) = {1, 2}; // bottom edge
|
||||
Line(2) = {2, 3}; // right edge
|
||||
Line(3) = {3, 4}; // top edge
|
||||
Line(4) = {4, 1}; // left edge
|
||||
|
||||
// Define the lines (edges of the inner square)
|
||||
Line(5) = {5, 6}; // bottom edge
|
||||
Line(6) = {6, 7}; // right edge
|
||||
Line(7) = {7, 8}; // top edge
|
||||
Line(8) = {8, 5}; // left edge
|
||||
|
||||
// Define the surfaces
|
||||
// Outer square boundary
|
||||
Line Loop(1) = {1, 2, 3, 4};
|
||||
|
||||
// Inner square boundary (hole in the outer region)
|
||||
Line Loop(2) = {5, 6, 7, 8};
|
||||
|
||||
// Define the surface areas
|
||||
// Outer region (annular region between squares)
|
||||
Plane Surface(1) = {1, 2}; // Outer loop minus inner loop (creates hole)
|
||||
|
||||
// Inner region (solid inner square)
|
||||
Plane Surface(2) = {2}; // Inner loop only
|
||||
|
||||
// Assign physical groups for materials
|
||||
Physical Surface(1) = {1}; // Outer material (annular region)
|
||||
Physical Surface(2) = {2}; // Inner material (solid square)
|
||||
|
||||
// Physical lines for boundary conditions
|
||||
// Outer square boundary edges
|
||||
Physical Line(1) = {1}; // outer bottom
|
||||
Physical Line(2) = {2}; // outer right
|
||||
Physical Line(3) = {3}; // outer top
|
||||
Physical Line(4) = {4}; // outer left
|
||||
|
||||
// Inner square boundary edges
|
||||
Physical Line(5) = {5}; // inner bottom
|
||||
Physical Line(6) = {6}; // inner right
|
||||
Physical Line(7) = {7}; // inner top
|
||||
Physical Line(8) = {8}; // inner left
|
||||
|
||||
// Mesh control for quality
|
||||
Mesh.OptimizeNetgen = 1;
|
||||
Mesh.Optimize = 1;
|
||||
Mesh.ElementOrder = 1;
|
||||
Mesh.RecombineAll = 0; // Keep triangular elements (don't recombine to quads)
|
||||
@@ -1,50 +0,0 @@
|
||||
$MeshFormat
|
||||
2.2 0 8
|
||||
$EndMeshFormat
|
||||
$Nodes
|
||||
13
|
||||
1 -1 -1 0
|
||||
2 1 -1 0
|
||||
3 1 1 0
|
||||
4 -1 1 0
|
||||
5 -0.25 -0.25 0
|
||||
6 0.25 -0.25 0
|
||||
7 0.25 0.25 0
|
||||
8 -0.25 0.25 0
|
||||
9 -2.752797989558076e-12 -1 0
|
||||
10 1 -2.752797989558076e-12 0
|
||||
11 2.752797989558076e-12 1 0
|
||||
12 -1 2.752797989558076e-12 0
|
||||
13 0 0 0
|
||||
$EndNodes
|
||||
$Elements
|
||||
28
|
||||
1 1 2 1 1 1 9
|
||||
2 1 2 1 1 9 2
|
||||
3 1 2 2 2 2 10
|
||||
4 1 2 2 2 10 3
|
||||
5 1 2 3 3 3 11
|
||||
6 1 2 3 3 11 4
|
||||
7 1 2 4 4 4 12
|
||||
8 1 2 4 4 12 1
|
||||
9 1 2 5 5 5 6
|
||||
10 1 2 6 6 6 7
|
||||
11 1 2 7 7 7 8
|
||||
12 1 2 8 8 8 5
|
||||
13 2 2 1 1 6 5 9
|
||||
14 2 2 1 1 5 8 12
|
||||
15 2 2 1 1 7 6 10
|
||||
16 2 2 1 1 8 7 11
|
||||
17 2 2 1 1 9 5 1
|
||||
18 2 2 1 1 5 12 1
|
||||
19 2 2 1 1 6 9 2
|
||||
20 2 2 1 1 10 6 2
|
||||
21 2 2 1 1 7 10 3
|
||||
22 2 2 1 1 11 7 3
|
||||
23 2 2 1 1 8 11 4
|
||||
24 2 2 1 1 8 4 12
|
||||
25 2 2 2 2 5 6 13
|
||||
26 2 2 2 2 8 5 13
|
||||
27 2 2 2 2 6 7 13
|
||||
28 2 2 2 2 7 8 13
|
||||
$EndElements
|
||||
@@ -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
|
||||
2
|
||||
|
||||
elements
|
||||
2
|
||||
1 3 0 1 4 3
|
||||
1 2 1 2 4
|
||||
|
||||
boundary
|
||||
5
|
||||
1 1 0 1
|
||||
1 1 1 2
|
||||
1 1 2 4
|
||||
1 1 4 3
|
||||
1 1 3 0
|
||||
|
||||
vertices
|
||||
5
|
||||
2
|
||||
0 0
|
||||
1 0
|
||||
2 0
|
||||
0 1
|
||||
1 1
|
||||
@@ -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.9.1
|
||||
PROJECT_NUMBER = v4.8.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
|
||||
@@ -973,13 +973,10 @@ 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/contact \
|
||||
@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/fluids/navier \
|
||||
@MFEM_SOURCE_DIR@/miniapps/fluids/schrodinger-flow \
|
||||
@MFEM_SOURCE_DIR@/miniapps/gslib \
|
||||
@MFEM_SOURCE_DIR@/miniapps/hdiv-linear-solver \
|
||||
@MFEM_SOURCE_DIR@/miniapps/hooke \
|
||||
@@ -990,6 +987,7 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
|
||||
@MFEM_SOURCE_DIR@/miniapps/meshing \
|
||||
@MFEM_SOURCE_DIR@/miniapps/mtop \
|
||||
@MFEM_SOURCE_DIR@/miniapps/multidomain \
|
||||
@MFEM_SOURCE_DIR@/miniapps/navier \
|
||||
@MFEM_SOURCE_DIR@/miniapps/nurbs \
|
||||
@MFEM_SOURCE_DIR@/miniapps/parelag \
|
||||
@MFEM_SOURCE_DIR@/miniapps/performance \
|
||||
@@ -1083,8 +1081,7 @@ EXCLUDE_PATTERNS =
|
||||
# ANamespace::AClass, ANamespace::*Test
|
||||
|
||||
EXCLUDE_SYMBOLS = mfem::internal \
|
||||
mfem::kernels::internal \
|
||||
mfem::future::detail
|
||||
mfem::kernels::internal
|
||||
|
||||
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
|
||||
# that contain example code fragments that are included (see the \include
|
||||
|
||||
@@ -117,8 +117,6 @@ namespace mfem {
|
||||
* - <a class="el" href="ex39p_8cpp_source.html">Example 39p</a>: parallel named mesh attributes
|
||||
* - <a class="el" href="ex40_8cpp_source.html">Example 40</a>: eikonal equation
|
||||
* - <a class="el" href="ex40p_8cpp_source.html">Example 40p</a>: parallel eikonal equation
|
||||
* - <a class="el" href="ex41_8cpp_source.html">Example 41</a>: DG/CG IMEX time-dependent advection-diffusion
|
||||
* - <a class="el" href="ex41p_8cpp_source.html">Example 41p</a>: parallel DG/CG IMEX time-dependent advection-diffusion
|
||||
*
|
||||
* <H4>AmgX Examples</H4>
|
||||
* - Variants of Examples
|
||||
@@ -190,8 +188,6 @@ namespace mfem {
|
||||
* <a class="el" href="nurbs__ex1p_8cpp_source.html">1p</a>,
|
||||
* <a class="el" href="nurbs__ex3_8cpp_source.html">3</a>,
|
||||
* <a class="el" href="nurbs__ex5_8cpp_source.html">5</a>,
|
||||
* <a class="el" href="nurbs__ex10_8cpp_source.html">10</a>,
|
||||
* <a class="el" href="nurbs__ex10p_8cpp_source.html">10p</a>,
|
||||
* <a class="el" href="nurbs__ex11p_8cpp_source.html">11p</a>, and
|
||||
* <a class="el" href="nurbs__ex24_8cpp_source.html">24</a>,
|
||||
* demonstrating howto perform NURBS-based Isogeometric Analysis.
|
||||
@@ -200,8 +196,6 @@ namespace mfem {
|
||||
* - <a class="el" href="nurbs__curveint_8cpp_source.html">NURBS Interpolation</a>: NURBS interpolation of given geometry
|
||||
* - <a class="el" href="nurbs__naca__cmesh_8cpp_source.html">NURBS NACA Mesher</a>: generate NURBS based mesh around a NACA foil
|
||||
* - <a class="el" href="nurbs__printfunc_8cpp_source.html">NURBS Printer</a>: print the NURBS-basis
|
||||
* - <a class="el" href="nurbs__mesh_info_8cpp_source.html">NURBS Mesh info</a>: print the info of a NURBS mesh
|
||||
* - <a class="el" href="nurbs__surface_8cpp_source.html">NURBS Surface</a>: interpolate a 3D Surface in a NURBS Patch
|
||||
*
|
||||
* <H3>Miniapps</H3>
|
||||
* - <a class="el" href="volta_8cpp_source.html">Volta</a>: simple electrostatics simulation code
|
||||
@@ -240,15 +234,11 @@ namespace mfem {
|
||||
* - <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="generate__random__field_8cpp_source.html">SPDE Solvers</a>: SPDE solver random field generation
|
||||
* - <a class="el" href="contact-patch-test_8cpp_source.html">Tribol</a>: mortar contact patch test for elasticity
|
||||
* - <a class="el" href="contact_8cpp_source.html">Contact</a>: Frictionless contact examples using <a class="el" href="classmfem_1_1IPSolver.html#details">IP optimization</a> and the <a class="el" href="classmfem_1_1AMGFSolver.html#details">AMGF solver</a>
|
||||
* - <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
|
||||
* - <a class="el" href="pdiffusion_8cpp_source.html">DPG Diffusion example</a>: DPG formulation for the diffusion problem
|
||||
* - <a class="el" href="pmaxwell_8cpp_source.html">DPG Maxwell example</a>: DPG formulation for the indefinite Maxwell problem
|
||||
* - <a class="el" href="lor__elast_8cpp_source.html">LOR Elasticity</a>: solve linear elasticity with LOR preconditioning on GPUs
|
||||
* - <a class="el" href="reflector_8cpp_source.html">Reflector Miniapp</a>: reflect a mesh about a plane
|
||||
* - <a class="el" href="ref321_8cpp_source.html">3:1 Refinement Miniapp</a>: perform 3:1 anisotropic mesh refinements
|
||||
* - <a class="el" href="pref321_8cpp_source.html">3:1 Refinement Miniapp</a>: parallel 3:1 anisotropic mesh refinements
|
||||
*
|
||||
* See also the <a class="el" href="https://mfem.org/examples/">examples documentation</a> online.
|
||||
*/
|
||||
|
||||
@@ -46,7 +46,6 @@ list(APPEND ALL_EXE_SRCS
|
||||
ex38.cpp
|
||||
ex39.cpp
|
||||
ex40.cpp
|
||||
ex41.cpp
|
||||
)
|
||||
|
||||
if (MFEM_USE_MPI)
|
||||
@@ -90,7 +89,6 @@ if (MFEM_USE_MPI)
|
||||
ex37p.cpp
|
||||
ex39p.cpp
|
||||
ex40p.cpp
|
||||
ex41p.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -133,8 +131,6 @@ if (MFEM_ENABLE_TESTING)
|
||||
list(APPEND THIS_TEST_OPTIONS "-dg")
|
||||
elseif(${TEST_NAME} MATCHES "ex37p*")
|
||||
list(APPEND THIS_TEST_OPTIONS "-mi" "3")
|
||||
elseif(${TEST_NAME} MATCHES "ex41p*")
|
||||
list(APPEND THIS_TEST_OPTIONS "-tf" "1.0")
|
||||
endif()
|
||||
|
||||
if (NOT (${TEST_NAME} MATCHES ".*p$"))
|
||||
@@ -215,7 +211,7 @@ if (MFEM_ENABLE_TESTING)
|
||||
add_test(NAME ex1p_ceed_np=${MFEM_MPI_NP}
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MFEM_MPI_NP}
|
||||
${MPIEXEC_PREFLAGS}
|
||||
$<TARGET_FILE:ex1p> "-no-vis" "-d" "ceed-cpu" "-pa" "-a"
|
||||
$<TARGET_FILE:ex1p> "-no-vis" "-d ceed-cpu" "-pa" "-a"
|
||||
${MPIEXEC_POSTFLAGS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -64,7 +64,7 @@ PARALLEL_NAME := Parallel AMGX example
|
||||
$(MFEM_LIB_FILE):
|
||||
$(error The MFEM library is not build)
|
||||
|
||||
clean: clean-build clean-exec
|
||||
clean: clean-build
|
||||
|
||||
clean-build:
|
||||
rm -f *.o *~ $(SEQ_EXAMPLES) $(PAR_EXAMPLES)
|
||||
|
||||
@@ -64,12 +64,12 @@ ex1p-test-par: ex1p
|
||||
$(MFEM_LIB_FILE):
|
||||
$(error The MFEM library is not built)
|
||||
|
||||
clean: clean-build clean-exec
|
||||
clean: clean-build clean-exec $(SUBDIRS_CLEAN)
|
||||
|
||||
clean-build:
|
||||
rm -f *.o *~ $(SEQ_EXAMPLES) $(PAR_EXAMPLES)
|
||||
rm -rf *.dSYM *.TVD.*breakpoints
|
||||
|
||||
clean-exec:
|
||||
@rm -f refined.mesh mesh.*
|
||||
@rm -f sol.*
|
||||
@rm -f refined.mesh displaced.mesh mesh.* ex5.mesh
|
||||
@rm -f sphere_refined.* sol.* sol_u.* sol_p.* sol_r.* sol_i.*
|
||||
|
||||
+21
-34
@@ -50,10 +50,6 @@
|
||||
// ex1 -m ../data/beam-tet.mesh -pa -d ceed-cpu
|
||||
// ex1 -m ../data/beam-tet.mesh -pa -d ceed-cuda:/gpu/cuda/ref
|
||||
//
|
||||
// Device simplices sample runs:
|
||||
// ex1 -pa -d gpu -m ../data/inline-tet.mesh
|
||||
// ex1 -pa -d gpu -m ../data/inline-tri.mesh
|
||||
//
|
||||
// Description: This example code demonstrates the use of MFEM to define a
|
||||
// simple finite element discretization of the Poisson problem
|
||||
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
|
||||
@@ -142,25 +138,25 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// 5. Define a finite element space on the mesh. Here we use continuous
|
||||
// Lagrange finite elements of the specified order.
|
||||
// - If order < 1, we instead use an isoparametric/isogeometric space.
|
||||
// - If the mesh is simplicial and partial assembly is requested,
|
||||
// we use the positive basis, which supports device execution.
|
||||
// Lagrange finite elements of the specified order. If order < 1, we
|
||||
// instead use an isoparametric/isogeometric space.
|
||||
FiniteElementCollection *fec;
|
||||
auto basis_type = (pa && mesh.IsSimplexMesh()) ?
|
||||
BasisType::Positive : BasisType::GaussLobatto;
|
||||
bool delete_fec;
|
||||
if (order > 0)
|
||||
{
|
||||
fec = new H1_FECollection(order, dim, basis_type);
|
||||
fec = new H1_FECollection(order, dim);
|
||||
delete_fec = true;
|
||||
}
|
||||
else if (mesh.GetNodes())
|
||||
{
|
||||
fec = mesh.GetNodes()->OwnFEC();
|
||||
delete_fec = false;
|
||||
cout << "Using isoparametric FEs: " << fec->Name() << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
fec = new H1_FECollection(order = 1, dim, basis_type);
|
||||
fec = new H1_FECollection(order = 1, dim);
|
||||
delete_fec = true;
|
||||
}
|
||||
FiniteElementSpace fespace(&mesh, fec);
|
||||
cout << "Number of finite element unknowns: "
|
||||
@@ -228,29 +224,17 @@ int main(int argc, char *argv[])
|
||||
// 11. Solve the linear system A X = B.
|
||||
if (!pa)
|
||||
{
|
||||
#ifdef MFEM_USE_CUDSS
|
||||
if (Device::Allows(Backend::CUDA_MASK))
|
||||
{
|
||||
// Use cuDSS to solve the system.
|
||||
CuDSSSolver cudss_solver;
|
||||
cudss_solver.SetOperator(*A);
|
||||
cudss_solver.Mult(B, X);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifndef MFEM_USE_SUITESPARSE
|
||||
// Use a simple symmetric Gauss-Seidel preconditioner with PCG.
|
||||
GSSmoother M((SparseMatrix&)(*A));
|
||||
PCG(*A, M, B, X, 1, 200, 1e-12, 0.0);
|
||||
// Use a simple symmetric Gauss-Seidel preconditioner with PCG.
|
||||
GSSmoother M((SparseMatrix&)(*A));
|
||||
PCG(*A, M, B, X, 1, 200, 1e-12, 0.0);
|
||||
#else
|
||||
// If MFEM was compiled with SuiteSparse, use UMFPACK to solve the system.
|
||||
UMFPackSolver umf_solver;
|
||||
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
|
||||
umf_solver.SetOperator(*A);
|
||||
umf_solver.Mult(B, X);
|
||||
// If MFEM was compiled with SuiteSparse, use UMFPACK to solve the system.
|
||||
UMFPackSolver umf_solver;
|
||||
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
|
||||
umf_solver.SetOperator(*A);
|
||||
umf_solver.Mult(B, X);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -289,14 +273,17 @@ int main(int argc, char *argv[])
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
int visport = 19916;
|
||||
socketstream sol_sock(vishost, visport);
|
||||
sol_sock.precision(8);
|
||||
sol_sock << "solution\n" << mesh << x << flush;
|
||||
}
|
||||
|
||||
// 15. Free the used memory.
|
||||
if (order > 0) { delete fec; }
|
||||
if (delete_fec)
|
||||
{
|
||||
delete fec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-2
@@ -5,9 +5,9 @@
|
||||
// Sample runs:
|
||||
// mpirun -np 4 ex12p -m ../data/beam-tri.mesh
|
||||
// mpirun -np 4 ex12p -m ../data/beam-quad.mesh
|
||||
// mpirun -np 4 ex12p -m ../data/beam-tet.mesh -s 464 -n 10 -o 2 -elast
|
||||
// mpirun -np 4 ex12p -m ../data/beam-tet.mesh -s 462 -n 10 -o 2 -elast
|
||||
// mpirun -np 4 ex12p -m ../data/beam-hex.mesh -s 3878
|
||||
// mpirun -np 4 ex12p -m ../data/beam-wedge.mesh -s 82
|
||||
// mpirun -np 4 ex12p -m ../data/beam-wedge.mesh -s 81
|
||||
// mpirun -np 4 ex12p -m ../data/beam-tri.mesh -s 3877 -o 2 -sys
|
||||
// mpirun -np 4 ex12p -m ../data/beam-quad.mesh -s 4544 -n 6 -o 3 -elast
|
||||
// mpirun -np 4 ex12p -m ../data/beam-quad-nurbs.mesh
|
||||
|
||||
+6
-29
@@ -105,7 +105,6 @@ int main(int argc, char *argv[])
|
||||
bool visualization = true;
|
||||
bool visit = false;
|
||||
int vis_steps = 5;
|
||||
bool solve_implicit_state = false;
|
||||
|
||||
int precision = 8;
|
||||
cout.precision(precision);
|
||||
@@ -127,9 +126,6 @@ int main(int argc, char *argv[])
|
||||
"Alpha coefficient.");
|
||||
args.AddOption(&kappa, "-k", "--kappa",
|
||||
"Kappa coefficient offset.");
|
||||
args.AddOption(&solve_implicit_state, "-imp-state", "--implicit-state",
|
||||
"-imp-slope", "--implicit-slope",
|
||||
"Implicitly solve for stage state or slope.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -183,11 +179,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 7. Initialize the conduction operator and the visualization.
|
||||
ConductionOperator oper(fespace, alpha, kappa, u);
|
||||
using ImplicitVariableType = ConductionOperator::ImplicitVariableType;
|
||||
ImplicitVariableType imp_var = solve_implicit_state ?
|
||||
ImplicitVariableType::STATE
|
||||
: ImplicitVariableType::SLOPE;
|
||||
oper.SetImplicitVariableType(imp_var);
|
||||
|
||||
u_gf.SetFromTrueDofs(u);
|
||||
{
|
||||
@@ -325,14 +316,11 @@ void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
|
||||
}
|
||||
|
||||
void ConductionOperator::ImplicitSolve(const real_t dt,
|
||||
const Vector &u, Vector &k)
|
||||
const Vector &u, Vector &du_dt)
|
||||
{
|
||||
// Solve the equation:
|
||||
// M*k = -K(u + dt*k) for k = du/dt, if solving for stage-slope
|
||||
// or
|
||||
// M*k = -dt*K(k) + M*u for k = u_s, if solving for stage-state
|
||||
// where K is linearized by using u from the previous timestep, and
|
||||
// the stage-state and slope relation: du/dt = (u_s - u)/dt.
|
||||
// du_dt = M^{-1}*[-K(u + dt*du_dt)]
|
||||
// for du_dt, where K is linearized by using u from the previous timestep
|
||||
if (!T)
|
||||
{
|
||||
T = Add(1.0, Mmat, dt, Kmat);
|
||||
@@ -340,20 +328,9 @@ void ConductionOperator::ImplicitSolve(const real_t dt,
|
||||
T_solver.SetOperator(*T);
|
||||
}
|
||||
MFEM_VERIFY(dt == current_dt, ""); // SDIRK methods use the same dt
|
||||
|
||||
// Construct current right-hand side for stage state vs. slope solve
|
||||
if (ImplicitVarTypeIsState())
|
||||
{
|
||||
// k, on return, is the stage value u_s
|
||||
Mmat.Mult(u, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
// k, on return, is the stage slope du/dt
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg();
|
||||
}
|
||||
T_solver.Mult(z, k);
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg();
|
||||
T_solver.Mult(z, du_dt);
|
||||
}
|
||||
|
||||
void ConductionOperator::SetParameters(const Vector &u)
|
||||
|
||||
+6
-29
@@ -115,7 +115,6 @@ int main(int argc, char *argv[])
|
||||
bool visit = false;
|
||||
int vis_steps = 5;
|
||||
bool adios2 = false;
|
||||
bool solve_implicit_state = false;
|
||||
|
||||
int precision = 8;
|
||||
cout.precision(precision);
|
||||
@@ -139,9 +138,6 @@ int main(int argc, char *argv[])
|
||||
"Alpha coefficient.");
|
||||
args.AddOption(&kappa, "-k", "--kappa",
|
||||
"Kappa coefficient offset.");
|
||||
args.AddOption(&solve_implicit_state, "-imp-state", "--implicit-state",
|
||||
"-imp-slope", "--implicit-slope",
|
||||
"Implicitly solve for stage state or slope.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -216,11 +212,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 9. Initialize the conduction operator and the VisIt visualization.
|
||||
ConductionOperator oper(fespace, alpha, kappa, u);
|
||||
using ImplicitVariableType = ConductionOperator::ImplicitVariableType;
|
||||
ImplicitVariableType imp_var = solve_implicit_state ?
|
||||
ImplicitVariableType::STATE
|
||||
: ImplicitVariableType::SLOPE;
|
||||
oper.SetImplicitVariableType(imp_var);
|
||||
|
||||
u_gf.SetFromTrueDofs(u);
|
||||
{
|
||||
@@ -416,14 +407,11 @@ void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
|
||||
}
|
||||
|
||||
void ConductionOperator::ImplicitSolve(const real_t dt,
|
||||
const Vector &u, Vector &k)
|
||||
const Vector &u, Vector &du_dt)
|
||||
{
|
||||
// Solve the equation:
|
||||
// M*k = -K(u + dt*k) for k = du/dt, if solving for stage-slope
|
||||
// or
|
||||
// M*k = -dt*K(k) + M*u for k = u_s, if solving for stage-state
|
||||
// where K is linearized by using u from the previous timestep, and
|
||||
// the stage-state and slope relation: du/dt = (u_s - u)/dt.
|
||||
// du_dt = M^{-1}*[-K(u + dt*du_dt)]
|
||||
// for du_dt, where K is linearized by using u from the previous timestep
|
||||
if (!T)
|
||||
{
|
||||
T = Add(1.0, Mmat, dt, Kmat);
|
||||
@@ -431,20 +419,9 @@ void ConductionOperator::ImplicitSolve(const real_t dt,
|
||||
T_solver.SetOperator(*T);
|
||||
}
|
||||
MFEM_VERIFY(dt == current_dt, ""); // SDIRK methods use the same dt
|
||||
|
||||
// Construct current right-hand side for stage state vs. slope solve
|
||||
if (ImplicitVarTypeIsState())
|
||||
{
|
||||
// k, on return, is the stage value u
|
||||
Mmat.Mult(u, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
// k, on return, is the stage slope du/dt
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg();
|
||||
}
|
||||
T_solver.Mult(z, k);
|
||||
Kmat.Mult(u, z);
|
||||
z.Neg();
|
||||
T_solver.Mult(z, du_dt);
|
||||
}
|
||||
|
||||
void ConductionOperator::SetParameters(const Vector &u)
|
||||
|
||||
+34
-60
@@ -42,11 +42,7 @@
|
||||
// mpirun -np 4 ex1p -pa -d ceed-cuda:/gpu/cuda/shared
|
||||
// mpirun -np 4 ex1p -pa -d ceed-cuda:/gpu/cuda/shared -m ../data/square-mixed.mesh
|
||||
// mpirun -np 4 ex1p -pa -d ceed-cuda:/gpu/cuda/shared -m ../data/fichera-mixed.mesh
|
||||
// mpirun -np 4 ex1p -pa -d ceed-cpu -m ../data/beam-tet.mesh
|
||||
//
|
||||
// Device simplices sample runs:
|
||||
// mpirun -np 4 ex1p -pa -d gpu -m ../data/inline-tet.mesh
|
||||
// mpirun -np 4 ex1p -pa -d gpu -m ../data/inline-tri.mesh
|
||||
// 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
|
||||
@@ -87,9 +83,6 @@ int main(int argc, char *argv[])
|
||||
const char *device_config = "cpu";
|
||||
bool visualization = true;
|
||||
bool algebraic_ceed = false;
|
||||
#ifdef MFEM_USE_CUDSS
|
||||
bool cudss_solver = false;
|
||||
#endif
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
@@ -109,10 +102,6 @@ int main(int argc, char *argv[])
|
||||
args.AddOption(&algebraic_ceed, "-a", "--algebraic",
|
||||
"-no-a", "--no-algebraic",
|
||||
"Use algebraic Ceed solver");
|
||||
#endif
|
||||
#ifdef MFEM_USE_CUDSS
|
||||
args.AddOption(&cudss_solver, "-cudss", "--cudss-solver", "-no-cudss",
|
||||
"--no-cudss-solver", "Use the cuDSS Solver.");
|
||||
#endif
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
@@ -169,20 +158,19 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// 7. Define a parallel finite element space on the parallel mesh. Here we
|
||||
// use continuous Lagrange finite elements of the specified order.
|
||||
// - If order < 1, we instead use an isoparametric/isogeometric space.
|
||||
// - If the mesh is simplicial and partial assembly is requested,
|
||||
// we use the positive basis, which supports device execution.
|
||||
// use continuous Lagrange finite elements of the specified order. If
|
||||
// order < 1, we instead use an isoparametric/isogeometric space.
|
||||
FiniteElementCollection *fec;
|
||||
auto basis_type = (pa && pmesh.IsSimplexMesh()) ?
|
||||
BasisType::Positive : BasisType::GaussLobatto;
|
||||
bool delete_fec;
|
||||
if (order > 0)
|
||||
{
|
||||
fec = new H1_FECollection(order, dim, basis_type);
|
||||
fec = new H1_FECollection(order, dim);
|
||||
delete_fec = true;
|
||||
}
|
||||
else if (pmesh.GetNodes())
|
||||
{
|
||||
fec = pmesh.GetNodes()->OwnFEC();
|
||||
delete_fec = false;
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Using isoparametric FEs: " << fec->Name() << endl;
|
||||
@@ -190,7 +178,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
fec = new H1_FECollection(order = 1, dim, basis_type);
|
||||
fec = new H1_FECollection(order = 1, dim);
|
||||
delete_fec = true;
|
||||
}
|
||||
ParFiniteElementSpace fespace(&pmesh, fec);
|
||||
HYPRE_BigInt size = fespace.GlobalTrueVSize();
|
||||
@@ -259,51 +248,33 @@ int main(int argc, char *argv[])
|
||||
// 13. Solve the linear system A X = B.
|
||||
// * With full assembly, use the BoomerAMG preconditioner from hypre.
|
||||
// * With partial assembly, use Jacobi smoothing, for now.
|
||||
#ifdef MFEM_USE_CUDSS
|
||||
if (!pa && (Device::Allows(Backend::CUDA_MASK) && cudss_solver))
|
||||
Solver *prec = NULL;
|
||||
if (pa)
|
||||
{
|
||||
// Solve using a direct solver with cuDSS
|
||||
CuDSSSolver cudss_solver(MPI_COMM_WORLD);
|
||||
cudss_solver.SetMatrixSymType(
|
||||
CuDSSSolver::SYMMETRIC_POSITIVE_DEFINITE);
|
||||
cudss_solver.SetMatrixViewType(CuDSSSolver::UPPER);
|
||||
cudss_solver.SetOperator(*A);
|
||||
cudss_solver.Mult(B, X);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Solver *prec = NULL;
|
||||
if (pa)
|
||||
if (UsesTensorBasis(fespace))
|
||||
{
|
||||
if (UsesTensorBasis(fespace))
|
||||
if (algebraic_ceed)
|
||||
{
|
||||
if (algebraic_ceed)
|
||||
{
|
||||
prec = new ceed::AlgebraicSolver(a, ess_tdof_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
prec = new OperatorJacobiSmoother(a, ess_tdof_list);
|
||||
}
|
||||
prec = new ceed::AlgebraicSolver(a, ess_tdof_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
prec = new OperatorJacobiSmoother(a, ess_tdof_list);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prec = new HypreBoomerAMG;
|
||||
}
|
||||
CGSolver cg(MPI_COMM_WORLD);
|
||||
cg.SetRelTol(1e-12);
|
||||
cg.SetMaxIter(2000);
|
||||
cg.SetPrintLevel(1);
|
||||
if (prec)
|
||||
{
|
||||
cg.SetPreconditioner(*prec);
|
||||
}
|
||||
cg.SetOperator(*A);
|
||||
cg.Mult(B, X);
|
||||
delete prec;
|
||||
}
|
||||
else
|
||||
{
|
||||
prec = new HypreBoomerAMG;
|
||||
}
|
||||
CGSolver cg(MPI_COMM_WORLD);
|
||||
cg.SetRelTol(1e-12);
|
||||
cg.SetMaxIter(2000);
|
||||
cg.SetPrintLevel(1);
|
||||
if (prec) { cg.SetPreconditioner(*prec); }
|
||||
cg.SetOperator(*A);
|
||||
cg.Mult(B, X);
|
||||
delete prec;
|
||||
|
||||
// 14. Recover the parallel grid function corresponding to X. This is the
|
||||
// local finite element solution on each processor.
|
||||
@@ -337,7 +308,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// 17. Free the used memory.
|
||||
if (order > 0) { delete fec; }
|
||||
if (delete_fec)
|
||||
{
|
||||
delete fec;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
LinearForm b(&fespace);
|
||||
b.AddBoundaryIntegrator(new VectorBoundaryLFIntegrator(f));
|
||||
b.AddDomainIntegrator(new VectorBoundaryLFIntegrator(f));
|
||||
|
||||
// 6. Set up the bilinear form a(.,.) on the finite element space
|
||||
// corresponding to the linear elasticity integrator with piece-wise
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
ParLinearForm b(&fespace);
|
||||
b.AddBoundaryIntegrator(new VectorBoundaryLFIntegrator(f));
|
||||
b.AddDomainIntegrator(new VectorBoundaryLFIntegrator(f));
|
||||
|
||||
// 6. Set up the bilinear form a(.,.) on the finite element space
|
||||
// corresponding to the linear elasticity integrator with piece-wise
|
||||
|
||||
@@ -471,13 +471,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
ofstream sol_r_ofs("sol_r.gf");
|
||||
ofstream sol_i_ofs("sol_i.gf");
|
||||
ofstream sol_z_ofs("sol_z.gf");
|
||||
sol_r_ofs.precision(8);
|
||||
sol_i_ofs.precision(8);
|
||||
sol_z_ofs.precision(8);
|
||||
u.real().Save(sol_r_ofs);
|
||||
u.imag().Save(sol_i_ofs);
|
||||
u.Save(sol_z_ofs);
|
||||
}
|
||||
|
||||
// 14. Send the solution by socket to a GLVis server.
|
||||
|
||||
+10
-32
@@ -302,21 +302,15 @@ int main(int argc, char *argv[])
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock_r(vishost, visport);
|
||||
socketstream sol_sock_i(vishost, visport);
|
||||
sol_sock_r << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock_i << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock_r.precision(8);
|
||||
sol_sock_i.precision(8);
|
||||
sol_sock_r << "solution\n" << *pmesh << u_exact->real()
|
||||
<< "window_title 'Exact: Real Part'" << flush;
|
||||
// Make sure all ranks have sent their real solution before initiating
|
||||
// another set of GLVis connections (one from each rank):
|
||||
MPI_Barrier(pmesh->GetComm());
|
||||
socketstream sol_sock_i(vishost, visport);
|
||||
sol_sock_i << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock_i.precision(8);
|
||||
sol_sock_i << "solution\n" << *pmesh << u_exact->imag()
|
||||
<< "window_title 'Exact: Imaginary Part'" << flush;
|
||||
// Make sure all ranks have sent their imaginary solution before initiating
|
||||
// another set of GLVis connections (one from each rank):
|
||||
MPI_Barrier(pmesh->GetComm());
|
||||
}
|
||||
|
||||
// 11. Set up the parallel sesquilinear form a(.,.) on the finite element
|
||||
@@ -513,11 +507,10 @@ int main(int argc, char *argv[])
|
||||
// 15. Save the refined mesh and the solution in parallel. This output can be
|
||||
// viewed later using GLVis: "glvis -np <np> -m mesh -g sol".
|
||||
{
|
||||
ostringstream mesh_name, sol_r_name, sol_i_name, sol_z_name;
|
||||
ostringstream mesh_name, sol_r_name, sol_i_name;
|
||||
mesh_name << "mesh." << setfill('0') << setw(6) << myid;
|
||||
sol_r_name << "sol_r." << setfill('0') << setw(6) << myid;
|
||||
sol_i_name << "sol_i." << setfill('0') << setw(6) << myid;
|
||||
sol_z_name << "sol_z." << setfill('0') << setw(6) << myid;
|
||||
|
||||
ofstream mesh_ofs(mesh_name.str().c_str());
|
||||
mesh_ofs.precision(8);
|
||||
@@ -525,13 +518,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
ofstream sol_r_ofs(sol_r_name.str().c_str());
|
||||
ofstream sol_i_ofs(sol_i_name.str().c_str());
|
||||
ofstream sol_z_ofs(sol_z_name.str().c_str());
|
||||
sol_r_ofs.precision(8);
|
||||
sol_i_ofs.precision(8);
|
||||
sol_z_ofs.precision(8);
|
||||
u.real().Save(sol_r_ofs);
|
||||
u.imag().Save(sol_i_ofs);
|
||||
u.Save(sol_z_ofs);
|
||||
}
|
||||
|
||||
// 16. Send the solution by socket to a GLVis server.
|
||||
@@ -540,21 +530,15 @@ int main(int argc, char *argv[])
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock_r(vishost, visport);
|
||||
socketstream sol_sock_i(vishost, visport);
|
||||
sol_sock_r << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock_i << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock_r.precision(8);
|
||||
sol_sock_i.precision(8);
|
||||
sol_sock_r << "solution\n" << *pmesh << u.real()
|
||||
<< "window_title 'Solution: Real Part'" << flush;
|
||||
// Make sure all ranks have sent their real solution before initiating
|
||||
// another set of GLVis connections (one from each rank):
|
||||
MPI_Barrier(pmesh->GetComm());
|
||||
socketstream sol_sock_i(vishost, visport);
|
||||
sol_sock_i << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock_i.precision(8);
|
||||
sol_sock_i << "solution\n" << *pmesh << u.imag()
|
||||
<< "window_title 'Solution: Imaginary Part'" << flush;
|
||||
// Make sure all ranks have sent their imaginary solution before initiating
|
||||
// another set of GLVis connections (one from each rank):
|
||||
MPI_Barrier(pmesh->GetComm());
|
||||
}
|
||||
if (visualization && exact_sol)
|
||||
{
|
||||
@@ -563,21 +547,15 @@ int main(int argc, char *argv[])
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock_r(vishost, visport);
|
||||
socketstream sol_sock_i(vishost, visport);
|
||||
sol_sock_r << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock_i << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock_r.precision(8);
|
||||
sol_sock_i.precision(8);
|
||||
sol_sock_r << "solution\n" << *pmesh << u_exact->real()
|
||||
<< "window_title 'Error: Real Part'" << flush;
|
||||
// Make sure all ranks have sent their real solution before initiating
|
||||
// another set of GLVis connections (one from each rank):
|
||||
MPI_Barrier(pmesh->GetComm());
|
||||
socketstream sol_sock_i(vishost, visport);
|
||||
sol_sock_i << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock_i.precision(8);
|
||||
sol_sock_i << "solution\n" << *pmesh << u_exact->imag()
|
||||
<< "window_title 'Error: Imaginary Part'" << flush;
|
||||
// Make sure all ranks have sent their imaginary solution before initiating
|
||||
// another set of GLVis connections (one from each rank):
|
||||
MPI_Barrier(pmesh->GetComm());
|
||||
}
|
||||
if (visualization)
|
||||
{
|
||||
|
||||
@@ -95,15 +95,6 @@ int main(int argc, char *argv[])
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
|
||||
if (amg_elast && !static_cond && reorder_space)
|
||||
{
|
||||
if (myid == 0)
|
||||
cerr << "\nThe AMG elasticity solver requires ordering byVDIM! "
|
||||
<< "Ignoring the specified option -nodes/--by-nodes.\n"
|
||||
<< endl;
|
||||
reorder_space = false;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
+52
-11
@@ -5,8 +5,8 @@
|
||||
// Sample runs:
|
||||
// ex37 -alpha 10
|
||||
// ex37 -alpha 10 -pv
|
||||
// ex37 -lambda 0.1 -mu 0.1 -growth 1
|
||||
// ex37 -o 2 -alpha 10.0 -mi 50 -vf 0.4 -ntol 1e-5 -growth 1.5
|
||||
// ex37 -lambda 0.1 -mu 0.1
|
||||
// ex37 -o 2 -alpha 5.0 -mi 50 -vf 0.4 -ntol 1e-5
|
||||
// ex37 -r 6 -o 1 -alpha 25.0 -epsilon 0.02 -mi 50 -ntol 1e-5
|
||||
//
|
||||
// Description: This example code demonstrates the use of MFEM to solve a
|
||||
@@ -55,6 +55,53 @@
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
/**
|
||||
* @brief Bregman projection of ρ = sigmoid(ψ) onto the subspace
|
||||
* ∫_Ω ρ dx = θ vol(Ω) as follows:
|
||||
*
|
||||
* 1. Compute the root of the R → R function
|
||||
* f(c) = ∫_Ω sigmoid(ψ + c) dx - θ vol(Ω)
|
||||
* 2. Set ψ ← ψ + c.
|
||||
*
|
||||
* @param psi a GridFunction to be updated
|
||||
* @param target_volume θ vol(Ω)
|
||||
* @param tol Newton iteration tolerance
|
||||
* @param max_its Newton maximum iteration number
|
||||
* @return real_t Final volume, ∫_Ω sigmoid(ψ)
|
||||
*/
|
||||
real_t proj(GridFunction &psi, real_t target_volume, real_t tol=1e-12,
|
||||
int max_its=10)
|
||||
{
|
||||
MappedGridFunctionCoefficient sigmoid_psi(&psi, sigmoid);
|
||||
MappedGridFunctionCoefficient der_sigmoid_psi(&psi, der_sigmoid);
|
||||
|
||||
LinearForm int_sigmoid_psi(psi.FESpace());
|
||||
int_sigmoid_psi.AddDomainIntegrator(new DomainLFIntegrator(sigmoid_psi));
|
||||
LinearForm int_der_sigmoid_psi(psi.FESpace());
|
||||
int_der_sigmoid_psi.AddDomainIntegrator(new DomainLFIntegrator(
|
||||
der_sigmoid_psi));
|
||||
bool done = false;
|
||||
for (int k=0; k<max_its; k++) // Newton iteration
|
||||
{
|
||||
int_sigmoid_psi.Assemble(); // Recompute f(c) with updated ψ
|
||||
const real_t f = int_sigmoid_psi.Sum() - target_volume;
|
||||
|
||||
int_der_sigmoid_psi.Assemble(); // Recompute df(c) with updated ψ
|
||||
const real_t df = int_der_sigmoid_psi.Sum();
|
||||
|
||||
const real_t dc = -f/df;
|
||||
psi += dc;
|
||||
if (abs(dc) < tol) { done = true; break; }
|
||||
}
|
||||
if (!done)
|
||||
{
|
||||
mfem_warning("Projection reached maximum iteration without converging. "
|
||||
"Result may not be accurate.");
|
||||
}
|
||||
int_sigmoid_psi.Assemble();
|
||||
return int_sigmoid_psi.Sum();
|
||||
}
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------
|
||||
* ALGORITHM PREAMBLE
|
||||
@@ -133,11 +180,10 @@ int main(int argc, char *argv[])
|
||||
int ref_levels = 5;
|
||||
int order = 2;
|
||||
real_t alpha = 1.0;
|
||||
real_t growth = 2;
|
||||
real_t epsilon = 0.01;
|
||||
real_t vol_fraction = 0.5;
|
||||
int max_it = 1e3;
|
||||
real_t itol = 1e-2;
|
||||
real_t itol = 1e-1;
|
||||
real_t ntol = 1e-4;
|
||||
real_t rho_min = 1e-6;
|
||||
real_t lambda = 1.0;
|
||||
@@ -152,8 +198,6 @@ int main(int argc, char *argv[])
|
||||
"Order (degree) of the finite elements.");
|
||||
args.AddOption(&alpha, "-alpha", "--alpha-step-length",
|
||||
"Step length for gradient descent.");
|
||||
args.AddOption(&growth, "-growth", "--alpha-growth-rate",
|
||||
"Growth rate of step length for gradient descent.");
|
||||
args.AddOption(&epsilon, "-epsilon", "--epsilon-thickness",
|
||||
"Length scale for ρ.");
|
||||
args.AddOption(&max_it, "-mi", "--max-it",
|
||||
@@ -288,7 +332,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
FilterSolver->SetEssentialBoundary(ess_bdr_filter);
|
||||
FilterSolver->SetupFEM();
|
||||
FilterSolver->AssembleDiffusionBilinear();
|
||||
|
||||
BilinearForm mass(&control_fes);
|
||||
mass.AddDomainIntegrator(new InverseIntegrator(new MassIntegrator(one)));
|
||||
@@ -342,7 +385,7 @@ int main(int argc, char *argv[])
|
||||
// 11. Iterate:
|
||||
for (int k = 1; k <= max_it; k++)
|
||||
{
|
||||
if (k > 1) { alpha = std::pow((real_t) k,growth); }
|
||||
if (k > 1) { alpha *= ((real_t) k) / ((real_t) k-1); }
|
||||
|
||||
mfem::out << "\nStep = " << k << std::endl;
|
||||
|
||||
@@ -379,9 +422,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Step 5 - Update design variable ψ ← proj(ψ - αG)
|
||||
psi.Add(-alpha, grad);
|
||||
GridFunction alpha_grad(grad);
|
||||
alpha_grad *= alpha;
|
||||
const real_t material_volume = proj(psi, alpha_grad, target_volume);
|
||||
const real_t material_volume = proj(psi, target_volume);
|
||||
|
||||
// Compute ||ρ - ρ_old|| in control fes.
|
||||
real_t norm_increment = zerogf.ComputeL1Error(succ_diff_rho);
|
||||
|
||||
+23
-183
@@ -137,7 +137,7 @@ public:
|
||||
exponent(exponent_), rho_min(rho_min_)
|
||||
{
|
||||
MFEM_ASSERT(rho_min_ >= 0.0, "rho_min must be >= 0");
|
||||
MFEM_ASSERT(rho_min_ < 1.0, "rho_min must be < 1");
|
||||
MFEM_ASSERT(rho_min_ < 1.0, "rho_min must be > 1");
|
||||
MFEM_ASSERT(u, "displacement field is not set");
|
||||
MFEM_ASSERT(rho_filter, "density field is not set");
|
||||
}
|
||||
@@ -231,12 +231,9 @@ private:
|
||||
FiniteElementCollection * fec = nullptr;
|
||||
FiniteElementSpace * fes = nullptr;
|
||||
Array<int> ess_bdr;
|
||||
Array<int> ess_tdof_list;
|
||||
Array<int> neumann_bdr;
|
||||
GridFunction * u = nullptr;
|
||||
LinearForm * b = nullptr;
|
||||
BilinearForm * a = nullptr;
|
||||
OperatorPtr A;
|
||||
bool parallel;
|
||||
#ifdef MFEM_USE_MPI
|
||||
ParMesh * pmesh = nullptr;
|
||||
@@ -270,8 +267,6 @@ public:
|
||||
void ResetFEM();
|
||||
void SetupFEM();
|
||||
|
||||
void UpdateEssentialTDofs();
|
||||
void AssembleDiffusionBilinear(bool update_ess_tdofs=true);
|
||||
void Solve();
|
||||
GridFunction * GetFEMSolution();
|
||||
LinearForm * GetLinearForm() {return b;}
|
||||
@@ -376,130 +371,6 @@ public:
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Bregman projection of ρ = sigmoid(ψ) onto the subspace
|
||||
* ∫_Ω ρ dx = θ vol(Ω) as follows:
|
||||
*
|
||||
* 1. Compute the root of the R → R function
|
||||
* f(c) = ∫_Ω sigmoid(ψ + c) dx - θ vol(Ω)
|
||||
* using the Illinois method
|
||||
* 2. Set ψ ← ψ + c.
|
||||
*
|
||||
* @param psi a GridFunction to be updated
|
||||
* @param alpha_grad alpha multiplied by gradient
|
||||
* @param target_volume θ vol(Ω)
|
||||
* @param tol Illinois iteration tolerance
|
||||
* @param max_its Illinois maximum iteration number
|
||||
* @return real_t Final volume (∫_Ω sigmoid(ψ) dx)
|
||||
*/
|
||||
real_t proj(GridFunction &psi, GridFunction &alpha_grad, real_t target_volume,
|
||||
real_t tol = 1e-12, int max_its = 100)
|
||||
{
|
||||
#ifdef MFEM_USE_MPI
|
||||
FiniteElementSpace *fes = psi.FESpace();
|
||||
ParFiniteElementSpace *pfes = dynamic_cast<ParFiniteElementSpace*>(fes);
|
||||
#endif
|
||||
ConstantCoefficient zero_cf(0.0);
|
||||
real_t a = -alpha_grad.ComputeMaxError(zero_cf);
|
||||
real_t b = -a;
|
||||
real_t y = 0.0;
|
||||
|
||||
MappedGridFunctionCoefficient sigmoid_psi(
|
||||
&psi, [&y](const real_t x) { return sigmoid(x + y); });
|
||||
std::unique_ptr<LinearForm> int_sigmoid_psi;
|
||||
#ifdef MFEM_USE_MPI
|
||||
ParGridFunction *par_psi = dynamic_cast<ParGridFunction *>(&psi);
|
||||
if (par_psi)
|
||||
{
|
||||
int_sigmoid_psi.reset(new ParLinearForm(par_psi->ParFESpace()));
|
||||
}
|
||||
else
|
||||
{
|
||||
int_sigmoid_psi.reset(new LinearForm(psi.FESpace()));
|
||||
}
|
||||
#else
|
||||
int_sigmoid_psi.reset(new LinearForm(psi.FESpace()));
|
||||
#endif
|
||||
int_sigmoid_psi->AddDomainIntegrator(new DomainLFIntegrator(sigmoid_psi));
|
||||
|
||||
y = a;
|
||||
int_sigmoid_psi->Assemble();
|
||||
real_t f_a = int_sigmoid_psi->Sum(); // f_a := f(a) + θ vol(Ω)
|
||||
|
||||
y = b;
|
||||
int_sigmoid_psi->Assemble();
|
||||
real_t f_b = int_sigmoid_psi->Sum(); // f_b := f(b) + θ vol(Ω)
|
||||
#ifdef MFEM_USE_MPI
|
||||
if (pfes)
|
||||
{
|
||||
MPI_Allreduce(MPI_IN_PLACE, &f_a, 1, MPITypeMap<real_t>::mpi_type,
|
||||
MPI_SUM, MPI_COMM_WORLD);
|
||||
MPI_Allreduce(MPI_IN_PLACE, &f_b, 1, MPITypeMap<real_t>::mpi_type,
|
||||
MPI_SUM, MPI_COMM_WORLD);
|
||||
}
|
||||
#endif
|
||||
f_a -= target_volume; // f_a := f(a)
|
||||
f_b -= target_volume; // f_b := f(b)
|
||||
real_t c = 0.0;
|
||||
real_t f_c = 0.0;
|
||||
int side = 0;
|
||||
|
||||
bool done = false;
|
||||
for (int k=0; k < max_its; k++)
|
||||
{
|
||||
c = (f_a * b - f_b * a) / (f_a - f_b);
|
||||
|
||||
if (abs(b - a) < tol * abs(b + a)) { done = true; break; }
|
||||
|
||||
y = c;
|
||||
int_sigmoid_psi->Assemble();
|
||||
f_c = int_sigmoid_psi->Sum(); // f_c := f(c) + θ vol(Ω)
|
||||
#ifdef MFEM_USE_MPI
|
||||
if (pfes)
|
||||
{
|
||||
MPI_Allreduce(MPI_IN_PLACE, &f_c, 1, MPITypeMap<real_t>::mpi_type,
|
||||
MPI_SUM, MPI_COMM_WORLD);
|
||||
}
|
||||
#endif
|
||||
f_c -= target_volume; // f_c := f(c)
|
||||
|
||||
if (f_c * f_b > 0)
|
||||
{
|
||||
b = c;
|
||||
f_b = f_c;
|
||||
if (side == -1) { f_a /= 2.0; }
|
||||
side = -1;
|
||||
}
|
||||
else if (f_c * f_a > 0)
|
||||
{
|
||||
a = c;
|
||||
f_a = f_c;
|
||||
if (side == 1) { f_b /= 2.0; }
|
||||
side = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
done = true; break;
|
||||
}
|
||||
}
|
||||
if (!done)
|
||||
{
|
||||
mfem_warning("Projection reached maximum iteration without converging. "
|
||||
"Result may not be accurate.");
|
||||
}
|
||||
y = 0.0;
|
||||
psi += c;
|
||||
int_sigmoid_psi->Assemble();
|
||||
real_t material_volume = int_sigmoid_psi->Sum();
|
||||
#ifdef MFEM_USE_MPI
|
||||
if (pfes)
|
||||
{
|
||||
MPI_Allreduce(MPI_IN_PLACE, &material_volume, 1,
|
||||
MPITypeMap<real_t>::mpi_type, MPI_SUM, MPI_COMM_WORLD);
|
||||
}
|
||||
#endif
|
||||
return material_volume;
|
||||
}
|
||||
|
||||
// Poisson solver
|
||||
|
||||
@@ -551,8 +422,12 @@ void DiffusionSolver::SetupFEM()
|
||||
}
|
||||
}
|
||||
|
||||
void DiffusionSolver::UpdateEssentialTDofs()
|
||||
void DiffusionSolver::Solve()
|
||||
{
|
||||
OperatorPtr A;
|
||||
Vector B, X;
|
||||
Array<int> ess_tdof_list;
|
||||
|
||||
#ifdef MFEM_USE_MPI
|
||||
if (parallel)
|
||||
{
|
||||
@@ -565,39 +440,7 @@ void DiffusionSolver::UpdateEssentialTDofs()
|
||||
#else
|
||||
fes->GetEssentialTrueDofs(ess_bdr,ess_tdof_list);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DiffusionSolver::AssembleDiffusionBilinear(bool update_ess_tdofs)
|
||||
{
|
||||
if (update_ess_tdofs)
|
||||
{
|
||||
UpdateEssentialTDofs();
|
||||
}
|
||||
#ifdef MFEM_USE_MPI
|
||||
if (parallel)
|
||||
{
|
||||
a = new ParBilinearForm(pfes);
|
||||
}
|
||||
else
|
||||
{
|
||||
a = new BilinearForm(fes);
|
||||
}
|
||||
#else
|
||||
a = new BilinearForm(fes);
|
||||
#endif
|
||||
a->AddDomainIntegrator(new DiffusionIntegrator(*diffcf));
|
||||
if (masscf)
|
||||
{
|
||||
a->AddDomainIntegrator(new MassIntegrator(*masscf));
|
||||
}
|
||||
a->Assemble();
|
||||
a->FormSystemMatrix(ess_tdof_list, A);
|
||||
}
|
||||
|
||||
void DiffusionSolver::Solve()
|
||||
{
|
||||
Vector B, X;
|
||||
|
||||
*u=0.0;
|
||||
if (b)
|
||||
{
|
||||
delete b;
|
||||
@@ -632,33 +475,31 @@ void DiffusionSolver::Solve()
|
||||
|
||||
b->Assemble();
|
||||
|
||||
*u=0.0;
|
||||
if (essbdr_cf)
|
||||
{
|
||||
u->ProjectBdrCoefficient(*essbdr_cf,ess_bdr);
|
||||
}
|
||||
BilinearForm * a = nullptr;
|
||||
|
||||
#ifdef MFEM_USE_MPI
|
||||
if (parallel)
|
||||
{
|
||||
X.SetSize(pfes->TrueVSize());
|
||||
B.SetSize(pfes->TrueVSize());
|
||||
dynamic_cast<ParGridFunction*>(u)->ParallelAssemble(X);
|
||||
dynamic_cast<ParLinearForm*>(b)->ParallelAssemble(B);
|
||||
dynamic_cast<ParBilinearForm*>(a)->ParallelEliminateTDofsInRHS(
|
||||
ess_tdof_list, X, B);
|
||||
a = new ParBilinearForm(pfes);
|
||||
}
|
||||
else
|
||||
{
|
||||
X.NewDataAndSize(u->GetData(), u->Size());
|
||||
B.NewDataAndSize(b->GetData(), b->Size());
|
||||
a->EliminateVDofsInRHS(ess_tdof_list, X, B);
|
||||
a = new BilinearForm(fes);
|
||||
}
|
||||
#else
|
||||
X.NewDataAndSize(u->GetData(), u->Size());
|
||||
B.NewDataAndSize(b->GetData(), b->Size());
|
||||
a->EliminateVDofsInRHS(ess_tdof_list, X, B);
|
||||
a = new BilinearForm(fes);
|
||||
#endif
|
||||
a->AddDomainIntegrator(new DiffusionIntegrator(*diffcf));
|
||||
if (masscf)
|
||||
{
|
||||
a->AddDomainIntegrator(new MassIntegrator(*masscf));
|
||||
}
|
||||
a->Assemble();
|
||||
if (essbdr_cf)
|
||||
{
|
||||
u->ProjectBdrCoefficient(*essbdr_cf,ess_bdr);
|
||||
}
|
||||
a->FormLinearSystem(ess_tdof_list, *u, *b, A, X, B);
|
||||
|
||||
CGSolver * cg = nullptr;
|
||||
Solver * M = nullptr;
|
||||
@@ -687,6 +528,7 @@ void DiffusionSolver::Solve()
|
||||
delete M;
|
||||
delete cg;
|
||||
a->RecoverFEMSolution(X, *b, *u);
|
||||
delete a;
|
||||
}
|
||||
|
||||
GridFunction * DiffusionSolver::GetFEMSolution()
|
||||
@@ -718,8 +560,6 @@ DiffusionSolver::~DiffusionSolver()
|
||||
#endif
|
||||
delete fec; fec = nullptr;
|
||||
delete b;
|
||||
A.Clear();
|
||||
delete a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+60
-11
@@ -4,8 +4,8 @@
|
||||
//
|
||||
// Sample runs:
|
||||
// mpirun -np 4 ex37p -alpha 10 -pv
|
||||
// mpirun -np 4 ex37p -lambda 0.1 -mu 0.1 -growth 1
|
||||
// mpirun -np 4 ex37p -o 2 -alpha 10.0 -mi 50 -vf 0.4 -ntol 1e-5 -growth 1.5
|
||||
// mpirun -np 4 ex37p -lambda 0.1 -mu 0.1
|
||||
// mpirun -np 4 ex37p -o 2 -alpha 5.0 -mi 50 -vf 0.4 -ntol 1e-5
|
||||
// mpirun -np 4 ex37p -r 6 -o 2 -alpha 10.0 -epsilon 0.02 -mi 50 -ntol 1e-5
|
||||
//
|
||||
// Description: This example code demonstrates the use of MFEM to solve a
|
||||
@@ -54,6 +54,61 @@
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
/**
|
||||
* @brief Bregman projection of ρ = sigmoid(ψ) onto the subspace
|
||||
* ∫_Ω ρ dx = θ vol(Ω) as follows:
|
||||
*
|
||||
* 1. Compute the root of the R → R function
|
||||
* f(c) = ∫_Ω sigmoid(ψ + c) dx - θ vol(Ω)
|
||||
* 2. Set ψ ← ψ + c.
|
||||
*
|
||||
* @param psi a GridFunction to be updated
|
||||
* @param target_volume θ vol(Ω)
|
||||
* @param tol Newton iteration tolerance
|
||||
* @param max_its Newton maximum iteration number
|
||||
* @return real_t Final volume, ∫_Ω sigmoid(ψ)
|
||||
*/
|
||||
real_t proj(ParGridFunction &psi, real_t target_volume, real_t tol=1e-12,
|
||||
int max_its=10)
|
||||
{
|
||||
MappedGridFunctionCoefficient sigmoid_psi(&psi, sigmoid);
|
||||
MappedGridFunctionCoefficient der_sigmoid_psi(&psi, der_sigmoid);
|
||||
|
||||
ParLinearForm int_sigmoid_psi(psi.ParFESpace());
|
||||
int_sigmoid_psi.AddDomainIntegrator(new DomainLFIntegrator(sigmoid_psi));
|
||||
ParLinearForm int_der_sigmoid_psi(psi.ParFESpace());
|
||||
int_der_sigmoid_psi.AddDomainIntegrator(new DomainLFIntegrator(
|
||||
der_sigmoid_psi));
|
||||
bool done = false;
|
||||
for (int k=0; k<max_its; k++) // Newton iteration
|
||||
{
|
||||
int_sigmoid_psi.Assemble(); // Recompute f(c) with updated ψ
|
||||
real_t f = int_sigmoid_psi.Sum();
|
||||
MPI_Allreduce(MPI_IN_PLACE, &f, 1, MPITypeMap<real_t>::mpi_type,
|
||||
MPI_SUM, MPI_COMM_WORLD);
|
||||
f -= target_volume;
|
||||
|
||||
int_der_sigmoid_psi.Assemble(); // Recompute df(c) with updated ψ
|
||||
real_t df = int_der_sigmoid_psi.Sum();
|
||||
MPI_Allreduce(MPI_IN_PLACE, &df, 1, MPITypeMap<real_t>::mpi_type,
|
||||
MPI_SUM, MPI_COMM_WORLD);
|
||||
|
||||
const real_t dc = -f/df;
|
||||
psi += dc;
|
||||
if (abs(dc) < tol) { done = true; break; }
|
||||
}
|
||||
if (!done)
|
||||
{
|
||||
mfem_warning("Projection reached maximum iteration without converging. "
|
||||
"Result may not be accurate.");
|
||||
}
|
||||
int_sigmoid_psi.Assemble();
|
||||
real_t material_volume = int_sigmoid_psi.Sum();
|
||||
MPI_Allreduce(MPI_IN_PLACE, &material_volume, 1,
|
||||
MPITypeMap<real_t>::mpi_type, MPI_SUM, MPI_COMM_WORLD);
|
||||
return material_volume;
|
||||
}
|
||||
|
||||
/*
|
||||
* ---------------------------------------------------------------
|
||||
* ALGORITHM PREAMBLE
|
||||
@@ -138,11 +193,10 @@ int main(int argc, char *argv[])
|
||||
int ref_levels = 5;
|
||||
int order = 2;
|
||||
real_t alpha = 1.0;
|
||||
real_t growth = 2;
|
||||
real_t epsilon = 0.01;
|
||||
real_t vol_fraction = 0.5;
|
||||
int max_it = 1e3;
|
||||
real_t itol = 1e-2;
|
||||
real_t itol = 1e-1;
|
||||
real_t ntol = 1e-4;
|
||||
real_t rho_min = 1e-6;
|
||||
real_t lambda = 1.0;
|
||||
@@ -157,8 +211,6 @@ int main(int argc, char *argv[])
|
||||
"Order (degree) of the finite elements.");
|
||||
args.AddOption(&alpha, "-alpha", "--alpha-step-length",
|
||||
"Step length for gradient descent.");
|
||||
args.AddOption(&growth, "-growth", "--alpha-growth-rate",
|
||||
"Growth rate of step length for gradient descent.");
|
||||
args.AddOption(&epsilon, "-epsilon", "--epsilon-thickness",
|
||||
"Length scale for ρ.");
|
||||
args.AddOption(&max_it, "-mi", "--max-it",
|
||||
@@ -307,7 +359,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
FilterSolver->SetEssentialBoundary(ess_bdr_filter);
|
||||
FilterSolver->SetupFEM();
|
||||
FilterSolver->AssembleDiffusionBilinear();
|
||||
|
||||
ParBilinearForm mass(&control_fes);
|
||||
mass.AddDomainIntegrator(new InverseIntegrator(new MassIntegrator(one)));
|
||||
@@ -361,7 +412,7 @@ int main(int argc, char *argv[])
|
||||
// 11. Iterate:
|
||||
for (int k = 1; k <= max_it; k++)
|
||||
{
|
||||
if (k > 1) { alpha = std::pow((real_t) k,growth); }
|
||||
if (k > 1) { alpha *= ((real_t) k) / ((real_t) k-1); }
|
||||
|
||||
if (myid == 0)
|
||||
{
|
||||
@@ -401,9 +452,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
// Step 5 - Update design variable ψ ← proj(ψ - αG)
|
||||
psi.Add(-alpha, grad);
|
||||
ParGridFunction alpha_grad(grad);
|
||||
alpha_grad *= alpha;
|
||||
const real_t material_volume = proj(psi, alpha_grad, target_volume);
|
||||
const real_t material_volume = proj(psi, target_volume);
|
||||
|
||||
// Compute ||ρ - ρ_old|| in control fes.
|
||||
real_t norm_increment = zerogf.ComputeL1Error(succ_diff_rho);
|
||||
|
||||
+1
-5
@@ -9,7 +9,6 @@
|
||||
// ex4 -m ../data/beam-hex.mesh -o 2 -pa
|
||||
// ex4 -m ../data/escher.mesh
|
||||
// ex4 -m ../data/fichera.mesh -o 2 -hb
|
||||
// ex4 -m ../data/fichera.mesh -o 2 -hb -ea
|
||||
// ex4 -m ../data/fichera-q2.vtk
|
||||
// ex4 -m ../data/fichera-q3.mesh -o 2 -sc
|
||||
// ex4 -m ../data/square-disc-nurbs.mesh
|
||||
@@ -19,7 +18,6 @@
|
||||
// ex4 -m ../data/amr-quad.mesh
|
||||
// ex4 -m ../data/amr-hex.mesh
|
||||
// ex4 -m ../data/amr-hex.mesh -o 2 -hb
|
||||
// ex4 -m ../data/amr-hex.mesh -o 2 -hb -ea
|
||||
// ex4 -m ../data/fichera-amr.mesh -o 2 -sc
|
||||
// ex4 -m ../data/ref-prism.mesh -o 1
|
||||
// ex4 -m ../data/octahedron.mesh -o 1
|
||||
@@ -27,8 +25,6 @@
|
||||
//
|
||||
// Device sample runs:
|
||||
// ex4 -m ../data/star.mesh -pa -d cuda
|
||||
// ex4 -m ../data/star.mesh -hb -ea -d cuda
|
||||
// ex4 -m ../data/amr-quad.mesh -hb -ea -d cuda
|
||||
// ex4 -m ../data/star.mesh -pa -d raja-cuda
|
||||
// ex4 -m ../data/star.mesh -pa -d raja-omp
|
||||
// ex4 -m ../data/beam-hex.mesh -pa -d cuda
|
||||
@@ -197,7 +193,7 @@ int main(int argc, char *argv[])
|
||||
cout << "Size of linear system: " << A->Height() << endl;
|
||||
|
||||
// 11. Solve the linear system A X = B.
|
||||
if (!pa && (!ea || hybridization))
|
||||
if (!pa)
|
||||
{
|
||||
#ifndef MFEM_USE_SUITESPARSE
|
||||
// Use a simple symmetric Gauss-Seidel preconditioner with PCG.
|
||||
|
||||
@@ -1,589 +0,0 @@
|
||||
// MFEM Example 41
|
||||
//
|
||||
// Compile with: make ex41
|
||||
//
|
||||
// Sample runs:
|
||||
// ex41
|
||||
// ex41 -cg
|
||||
// ex41 -m ../data/periodic-hexagon.mesh -p 0 -r 2 -dt 0.005 -tf 10
|
||||
// ex41 -m ../data/periodic-square.mesh -p 1 -r 2 -dt 0.005 -tf 9
|
||||
// ex41 -m ../data/periodic-hexagon.mesh -p 1 -r 2 -dt 0.005 -tf 9
|
||||
// ex41 -m ../data/amr-quad.mesh -p 1 -r 2 -dt 0.002 -tf 9
|
||||
// ex41 -m ../data/star-q3.mesh -p 1 -r 2 -dt 0.001 -tf 9
|
||||
// ex41 -m ../data/star-mixed.mesh -p 1 -r 2 -dt 0.005 -tf 9
|
||||
// ex41 -m ../data/disc-nurbs.mesh -p 1 -r 3 -dt 0.005 -tf 9
|
||||
// ex41 -m ../data/disc-nurbs.mesh -p 2 -r 3 -dt 0.005 -tf 9
|
||||
// ex41 -m ../data/periodic-square.mesh -p 3 -r 4 -dt 0.0025 -tf 9 -vs 20
|
||||
// ex41 -m ../data/periodic-cube.mesh -p 0 -r 2 -o 2 -dt 0.01 -tf 8
|
||||
//
|
||||
// Device sample runs:
|
||||
//
|
||||
// Description: This example code solves the time-dependent advection-diffusion
|
||||
// equation du/dt + v.grad(u) - a div(grad(u)) = 0, where v is a
|
||||
// given fluid velocity, a is the diffusion coefficient, and
|
||||
// u0(x)=u(0,x) is a given initial condition.
|
||||
//
|
||||
// The example demonstrates the use of Discontinuous Galerkin (DG)
|
||||
// bilinear forms in MFEM (face integrators), and the use of IMEX
|
||||
// ODE time integrators.
|
||||
//
|
||||
// The option to use continuous finite elements is available too.
|
||||
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// Mesh bounding box
|
||||
Vector bb_min, bb_max;
|
||||
|
||||
// Velocity coefficient
|
||||
template<int problem=0>
|
||||
void velocity_function(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
|
||||
// map to the reference [-1,1] domain
|
||||
Vector X(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
|
||||
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
|
||||
}
|
||||
switch (problem)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// Translations in 1D, 2D, and 3D
|
||||
switch (dim)
|
||||
{
|
||||
case 1: v(0) = 1.0; break;
|
||||
case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.); break;
|
||||
case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case 2:
|
||||
{
|
||||
// Clockwise rotation in 2D around the origin
|
||||
const real_t w = M_PI/2;
|
||||
switch (dim)
|
||||
{
|
||||
case 1: v(0) = 1.0; break;
|
||||
case 2: v(0) = w*X(1); v(1) = -w*X(0); break;
|
||||
case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// Clockwise twisting rotation in 2D around the origin
|
||||
const real_t w = M_PI/2;
|
||||
real_t d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
|
||||
d = d*d;
|
||||
switch (dim)
|
||||
{
|
||||
case 1: v(0) = 1.0; break;
|
||||
case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0); break;
|
||||
case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initial condition
|
||||
template<int problem=0>
|
||||
real_t u0_function(const Vector &x)
|
||||
{
|
||||
int dim = x.Size();
|
||||
|
||||
// map to the reference [-1,1] domain
|
||||
Vector X(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
|
||||
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
|
||||
}
|
||||
|
||||
switch (problem)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
switch (dim)
|
||||
{
|
||||
case 1:
|
||||
return exp(-40.*pow(X(0)-0.5,2));
|
||||
case 2:
|
||||
case 3:
|
||||
{
|
||||
real_t rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
|
||||
if (dim == 3)
|
||||
{
|
||||
const real_t s = (1. + 0.25*cos(2*M_PI*X(2)));
|
||||
rx *= s;
|
||||
ry *= s;
|
||||
}
|
||||
return ( std::erfc(w*(X(0)-cx-rx))*std::erfc(-w*(X(0)-cx+rx)) *
|
||||
std::erfc(w*(X(1)-cy-ry))*std::erfc(-w*(X(1)-cy+ry)) )/16;
|
||||
}
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
real_t x_ = X(0), y_ = X(1), rho, phi;
|
||||
rho = std::hypot(x_, y_);
|
||||
phi = atan2(y_, x_);
|
||||
return pow(sin(M_PI*rho),2)*sin(3*phi);
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
const real_t f = M_PI;
|
||||
return sin(f*X(0))*sin(f*X(1));
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/// Solver for the implicit part of the ODE (the diffusion term).
|
||||
/// Solves systems of the form: (M + dt*S) k = rhs.
|
||||
class Implicit_Solver : public Solver
|
||||
{
|
||||
private:
|
||||
SparseMatrix &M, &S, A;
|
||||
CGSolver linear_solver;
|
||||
BlockILU prec;
|
||||
real_t dt;
|
||||
public:
|
||||
Implicit_Solver(SparseMatrix &M_, SparseMatrix &S_,
|
||||
const FiniteElementSpace &fes)
|
||||
: M(M_),
|
||||
S(S_),
|
||||
prec(fes.GetTypicalFE()->GetDof(),
|
||||
BlockILU::Reordering::MINIMUM_DISCARDED_FILL),
|
||||
dt(1.0)
|
||||
{
|
||||
linear_solver.iterative_mode = false;
|
||||
linear_solver.SetRelTol(1e-9);
|
||||
linear_solver.SetAbsTol(0.0);
|
||||
linear_solver.SetMaxIter(100);
|
||||
linear_solver.SetPrintLevel(0);
|
||||
linear_solver.SetPreconditioner(prec);
|
||||
}
|
||||
|
||||
void SetTimeStep(real_t dt_)
|
||||
{
|
||||
real_t ddt = dt-dt_;
|
||||
|
||||
real_t epsilon;
|
||||
epsilon = std::numeric_limits<real_t>::epsilon();
|
||||
epsilon*=10;
|
||||
|
||||
if (std::abs(ddt) > epsilon)
|
||||
{
|
||||
dt = dt_;
|
||||
// Form operator A = M + dt*S
|
||||
A = S;
|
||||
A *= dt;
|
||||
A += M;
|
||||
|
||||
// this will also call SetOperator on the preconditioner
|
||||
linear_solver.SetOperator(A);
|
||||
}
|
||||
}
|
||||
|
||||
void SetOperator(const Operator &op) override
|
||||
{
|
||||
linear_solver.SetOperator(op);
|
||||
}
|
||||
|
||||
void Mult(const Vector &x, Vector &y) const override
|
||||
{
|
||||
linear_solver.Mult(x, y);
|
||||
}
|
||||
};
|
||||
|
||||
/** A time-dependent operator for the right-hand side of the ODE. The weak
|
||||
form of the advection-diffusion equation is M du/dt = K u - S u + b,
|
||||
where M is the mass matrix, K and S are the advection and diffusion
|
||||
matrices, and b describes the flow on the boundary. In the case of IMEX
|
||||
evolution, the diffusion term is treated implicitly, and the advection
|
||||
term is treated explicitly. */
|
||||
class IMEX_Evolution : public TimeDependentOperator
|
||||
{
|
||||
private:
|
||||
BilinearForm &M, &K, &S;
|
||||
const Vector &b;
|
||||
unique_ptr<Solver> M_prec;
|
||||
CGSolver M_solver;
|
||||
unique_ptr<Implicit_Solver> implicit_solver;
|
||||
|
||||
mutable Vector z;
|
||||
|
||||
public:
|
||||
IMEX_Evolution(BilinearForm &M_, BilinearForm &K_, BilinearForm &S_,
|
||||
const Vector &b_);
|
||||
|
||||
/// Evaluate k1=M^{-1}*G1(u,t); -> k1 = M^{-1}*(K*u + b)
|
||||
void Mult1(const Vector &x, Vector &y) const;
|
||||
|
||||
/// Evaluate k2: M*k2 = G2(u+k2*dt,t); -> (M+S*dt)*k2=-S*u
|
||||
void ImplicitSolve2(const real_t dt, const Vector &x, Vector &k);
|
||||
|
||||
void Mult(const Vector &x, Vector &y) const override
|
||||
{
|
||||
if (TimeDependentOperator::EvalMode::ADDITIVE_TERM_1 == GetEvalMode())
|
||||
{
|
||||
Mult1(x,y);
|
||||
}
|
||||
else
|
||||
{
|
||||
mfem_error("TimeDependentOperator::Mult() is not overridden!");
|
||||
}
|
||||
}
|
||||
|
||||
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override
|
||||
{
|
||||
if (TimeDependentOperator::EvalMode::ADDITIVE_TERM_2 == GetEvalMode())
|
||||
{
|
||||
ImplicitSolve2(dt,x,k);
|
||||
}
|
||||
else
|
||||
{
|
||||
mfem_error("TimeDependentOperator::ImplicitSolve() is not overridden!");
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Parse command-line options.
|
||||
int problem = 0;
|
||||
const char *mesh_file = "../data/periodic-square.mesh";
|
||||
int ref_levels = 2;
|
||||
int order = 3;
|
||||
int ode_solver_type = 64; //IMEXRK3(3,4,3)
|
||||
real_t t_final = 10.0;
|
||||
real_t dt = 0.01;
|
||||
bool paraview = false;
|
||||
bool cg = false;
|
||||
int vis_steps = 50;
|
||||
real_t diffusion_term = 0.01;
|
||||
real_t kappa = -1.0;
|
||||
real_t sigma = -1.0;
|
||||
bool visualization = true;
|
||||
bool visit = false;
|
||||
bool binary = false;
|
||||
int precision = 8;
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh", "Mesh file to use.");
|
||||
args.AddOption(&problem, "-p", "--problem",
|
||||
"Problem setup to use. See options in velocity_function().");
|
||||
args.AddOption(&ref_levels, "-r", "--refine",
|
||||
"Number of times to refine the mesh uniformly.");
|
||||
args.AddOption(&order, "-o", "--order", "Order of the finite elements.");
|
||||
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
|
||||
ODESolver::IMEXTypes.c_str());
|
||||
args.AddOption(&t_final, "-tf", "--t-final", "Final time; start time is 0.");
|
||||
args.AddOption(&dt, "-dt", "--time-step", "Time step.");
|
||||
args.AddOption(&diffusion_term, "-dc", "--diffusion-coeff",
|
||||
"Diffusion coefficient in the PDE.");
|
||||
args.AddOption(¶view, "-paraview", "--paraview-datafiles", "-no-paraview",
|
||||
"--no-paraview-datafiles",
|
||||
"Save data files for ParaView (paraview.org) visualization.");
|
||||
args.AddOption(&vis_steps, "-vs", "--visualization-steps",
|
||||
"Visualize every n-th timestep.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.AddOption(&binary, "-binary", "--binary-datafiles", "-ascii",
|
||||
"--ascii-datafiles",
|
||||
"Use binary (Sidre) or ascii format for VisIt data files.");
|
||||
args.AddOption(&visit, "-visit", "--visit-datafiles", "-no-visit",
|
||||
"--no-visit-datafiles",
|
||||
"Save data files for VisIt (visit.llnl.gov) visualization.");
|
||||
args.AddOption(&cg, "-cg", "--continuous-galerkin", "-dg",
|
||||
"--discontinuous-galerkin",
|
||||
"Use Continuous-Galerkin Finite elements (Default is DG)");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
return 1;
|
||||
}
|
||||
if (kappa < 0)
|
||||
{
|
||||
kappa = (order+1)*(order+1);
|
||||
}
|
||||
args.PrintOptions(cout);
|
||||
|
||||
// 2. Read the mesh from the given mesh file. We can handle geometrically
|
||||
// periodic meshes in this code.
|
||||
Mesh mesh(mesh_file);
|
||||
const int dim = mesh.Dimension();
|
||||
|
||||
// 3. Define the IMEX (Split) ODE solver used for time integration. The IMEX
|
||||
// solvers currently available are: 61 - Forward Backward Euler,
|
||||
// 62 - IMEXRK2(2,2,2), 63 - IMEXRK2(2,3,2), and 64 - IMEX_DIRK_RK3.
|
||||
unique_ptr<ODESolver> ode_solver = ODESolver::SelectIMEX(ode_solver_type);
|
||||
|
||||
// 4. Refine the mesh to increase the resolution. In this example we do
|
||||
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
|
||||
// command-line parameter.
|
||||
for (int lev = 0; lev < ref_levels; lev++) {mesh.UniformRefinement();}
|
||||
if (mesh.NURBSext) {mesh.SetCurvature(max(order, 1));}
|
||||
mesh.GetBoundingBox(bb_min, bb_max, max(order, 1));
|
||||
|
||||
// 5. Define the discontinuous DG finite element space of the given
|
||||
// polynomial order on the refined mesh.
|
||||
FiniteElementCollection *fec = NULL;
|
||||
if (cg)
|
||||
{
|
||||
fec = new H1_FECollection(order, dim);
|
||||
}
|
||||
else
|
||||
{
|
||||
fec = new DG_FECollection(order, dim, BasisType::GaussLobatto);
|
||||
}
|
||||
FiniteElementSpace fes(&mesh, fec);
|
||||
|
||||
cout << "Number of unknowns: " << fes.GetVSize() << endl;
|
||||
|
||||
// 6. Set up and assemble the bilinear and linear forms corresponding to the
|
||||
// DG discretization. The DGTraceIntegrator involves integrals over mesh
|
||||
// interior faces.
|
||||
std::unique_ptr<VectorFunctionCoefficient> velocity;
|
||||
if (0==problem)
|
||||
{
|
||||
velocity.reset(new VectorFunctionCoefficient(dim, velocity_function<0>));
|
||||
}
|
||||
else if (1==problem)
|
||||
{
|
||||
velocity.reset(new VectorFunctionCoefficient(dim, velocity_function<1>));
|
||||
}
|
||||
else if (2==problem)
|
||||
{
|
||||
velocity.reset(new VectorFunctionCoefficient(dim, velocity_function<2>));
|
||||
}
|
||||
else if (3==problem)
|
||||
{
|
||||
velocity.reset(new VectorFunctionCoefficient(dim, velocity_function<3>));
|
||||
}
|
||||
|
||||
ConstantCoefficient diff_coeff(diffusion_term);
|
||||
|
||||
BilinearForm m(&fes);
|
||||
BilinearForm k(&fes);
|
||||
BilinearForm s(&fes);
|
||||
|
||||
Vector b(fes.GetTrueVSize());
|
||||
b = 0.0; //The inflow on the boundaries is set to zero.
|
||||
|
||||
m.AddDomainIntegrator(new MassIntegrator);
|
||||
|
||||
constexpr real_t alpha = -1.0;
|
||||
k.AddDomainIntegrator(new ConvectionIntegrator(*velocity, alpha));
|
||||
|
||||
s.AddDomainIntegrator(new DiffusionIntegrator(diff_coeff));
|
||||
if (!cg)
|
||||
{
|
||||
k.AddInteriorFaceIntegrator(new NonconservativeDGTraceIntegrator(*velocity,
|
||||
alpha));
|
||||
k.AddBdrFaceIntegrator(new NonconservativeDGTraceIntegrator(*velocity, alpha));
|
||||
s.AddInteriorFaceIntegrator(new DGDiffusionIntegrator(diff_coeff, sigma,
|
||||
kappa));
|
||||
s.AddBdrFaceIntegrator(new DGDiffusionIntegrator(diff_coeff, sigma, kappa));
|
||||
}
|
||||
|
||||
|
||||
int skip_zeros = 0;
|
||||
m.Assemble(skip_zeros);
|
||||
k.Assemble(skip_zeros);
|
||||
s.Assemble(skip_zeros);
|
||||
|
||||
m.Finalize(skip_zeros);
|
||||
k.Finalize(skip_zeros);
|
||||
s.Finalize(skip_zeros);
|
||||
|
||||
// 7. Define the initial conditions.
|
||||
std::unique_ptr<FunctionCoefficient> u0;
|
||||
if (0==problem)
|
||||
{
|
||||
u0.reset(new FunctionCoefficient(u0_function<0>));
|
||||
}
|
||||
else if (1==problem)
|
||||
{
|
||||
u0.reset(new FunctionCoefficient(u0_function<1>));
|
||||
}
|
||||
else if (2==problem)
|
||||
{
|
||||
u0.reset(new FunctionCoefficient(u0_function<2>));
|
||||
}
|
||||
else if (3==problem)
|
||||
{
|
||||
u0.reset(new FunctionCoefficient(u0_function<3>));
|
||||
}
|
||||
|
||||
GridFunction u(&fes);
|
||||
u.ProjectCoefficient(*u0);
|
||||
|
||||
// Create data collection for solution output: either VisItDataCollection for
|
||||
// ascii data files, or SidreDataCollection for binary data files.
|
||||
DataCollection *dc = NULL;
|
||||
if (visit)
|
||||
{
|
||||
if (binary)
|
||||
{
|
||||
#ifdef MFEM_USE_SIDRE
|
||||
dc = new SidreDataCollection("Example41", &mesh);
|
||||
#else
|
||||
MFEM_ABORT("Must build with MFEM_USE_SIDRE=YES for binary output.");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
dc = new VisItDataCollection("Example41", &mesh);
|
||||
dc->SetPrecision(precision);
|
||||
}
|
||||
dc->RegisterField("solution", &u);
|
||||
dc->SetCycle(0);
|
||||
dc->SetTime(0.0);
|
||||
dc->Save();
|
||||
}
|
||||
|
||||
// 8. Set up paraview visualization, if desired.
|
||||
unique_ptr<ParaViewDataCollection> pv;
|
||||
if (paraview)
|
||||
{
|
||||
pv = make_unique<ParaViewDataCollection>("Example41", &mesh);
|
||||
pv->SetPrefixPath("ParaView");
|
||||
pv->RegisterField("solution", &u);
|
||||
pv->SetLevelsOfDetail(order);
|
||||
pv->SetDataFormat(VTKFormat::BINARY);
|
||||
pv->SetHighOrderOutput(true);
|
||||
pv->SetCycle(0);
|
||||
pv->SetTime(0.0);
|
||||
pv->Save();
|
||||
}
|
||||
|
||||
socketstream sout;
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
sout.open(vishost, visport);
|
||||
if (!sout)
|
||||
{
|
||||
cout << "Unable to connect to GLVis server at "
|
||||
<< vishost << ':' << visport << endl;
|
||||
visualization = false;
|
||||
cout << "GLVis visualization disabled.\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
sout.precision(precision);
|
||||
sout << "solution\n" << mesh << u;
|
||||
sout << "pause\n";
|
||||
sout << flush;
|
||||
cout << "GLVis visualization paused."
|
||||
<< " Press space (in the GLVis window) to resume it.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// 9. Define the time-dependent evolution operator describing the ODE
|
||||
// right-hand side, and perform time-integration (looping over the time
|
||||
// iterations, ti, with a time-step dt).
|
||||
IMEX_Evolution adv(m, k, s, b);
|
||||
|
||||
real_t t = 0.0;
|
||||
adv.SetTime(t);
|
||||
ode_solver->Init(adv);
|
||||
|
||||
bool done = false;
|
||||
for (int ti = 0; !done; )
|
||||
{
|
||||
real_t dt_real = min(dt, t_final - t);
|
||||
ode_solver->Step(u, t, dt_real);
|
||||
ti++;
|
||||
|
||||
done = (t >= t_final - 1e-8*dt);
|
||||
|
||||
if (done || ti % vis_steps == 0)
|
||||
{
|
||||
cout << "time step: " << ti << ", time: " << t << endl;
|
||||
if (paraview)
|
||||
{
|
||||
pv->SetCycle(ti);
|
||||
pv->SetTime(t);
|
||||
pv->Save();
|
||||
}
|
||||
if (visualization)
|
||||
{
|
||||
sout << "solution\n" << mesh << u << flush;
|
||||
}
|
||||
if (visit)
|
||||
{
|
||||
dc->SetCycle(ti);
|
||||
dc->SetTime(t);
|
||||
dc->Save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
delete fec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Implementation of class IMEX_Evolution
|
||||
IMEX_Evolution::IMEX_Evolution(BilinearForm &M_, BilinearForm &K_,
|
||||
BilinearForm &S_, const Vector &b_)
|
||||
: TimeDependentOperator(M_.FESpace()->GetTrueVSize()),
|
||||
M(M_), K(K_), S(S_), b(b_), z(height)
|
||||
{
|
||||
Array<int> ess_tdof_list;
|
||||
if (M.GetAssemblyLevel() == AssemblyLevel::LEGACY)
|
||||
{
|
||||
M_prec = make_unique<DSmoother>(M.SpMat());
|
||||
M_solver.SetOperator(M.SpMat());
|
||||
implicit_solver = make_unique<Implicit_Solver>(M.SpMat(), S.SpMat(),
|
||||
*M.FESpace());
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("Implicit time integration is not supported with partial assembly");
|
||||
}
|
||||
M_solver.SetPreconditioner(*M_prec);
|
||||
M_solver.iterative_mode = false;
|
||||
M_solver.SetRelTol(1e-9);
|
||||
M_solver.SetAbsTol(0.0);
|
||||
M_solver.SetMaxIter(100);
|
||||
M_solver.SetPrintLevel(0);
|
||||
}
|
||||
|
||||
void IMEX_Evolution::Mult1(const Vector &x, Vector &y) const
|
||||
{
|
||||
// Perform the explicit step
|
||||
// y = M^{-1} (K x + b)
|
||||
K.Mult(x, z);
|
||||
z += b;
|
||||
M_solver.Mult(z, y);
|
||||
}
|
||||
|
||||
void IMEX_Evolution::ImplicitSolve2(const real_t dt, const Vector &x, Vector &k)
|
||||
{
|
||||
// Perform the implicit step
|
||||
// solve for k, k = -(M+dt S)^{-1} S x
|
||||
MFEM_VERIFY(implicit_solver != NULL,
|
||||
"Implicit time integration is not supported with partial assembly");
|
||||
S.Mult(x, z);
|
||||
z.Neg();
|
||||
implicit_solver->SetTimeStep(dt);
|
||||
implicit_solver->Mult(z, k);
|
||||
}
|
||||
@@ -1,737 +0,0 @@
|
||||
// MFEM Example 41 - Parallel Version
|
||||
//
|
||||
// Compile with: make ex41p
|
||||
//
|
||||
// Sample runs:
|
||||
// mpirun -np 4 ex41p
|
||||
// mpirun -np 4 ex41p -cg
|
||||
// mpirun -np 4 ex41p -m ../data/periodic-hexagon.mesh -p 0 -dt 0.005 -tf 10
|
||||
// mpirun -np 4 ex41p -m ../data/periodic-square.mesh -p 1 -dt 0.005 -tf 9
|
||||
// mpirun -np 4 ex41p -m ../data/periodic-hexagon.mesh -p 1 -dt 0.005 -tf 9
|
||||
// mpirun -np 4 ex41p -m ../data/star-q3.mesh -p 1 -rp 1 -dt 0.001 -tf 9
|
||||
// mpirun -np 4 ex41p -m ../data/disc-nurbs.mesh -p 1 -rp 1 -dt 0.005 -tf 9
|
||||
// mpirun -np 4 ex41p -m ../data/disc-nurbs.mesh -p 2 -rp 1 -dt 0.005 -tf 9
|
||||
// mpirun -np 4 ex41p -m ../data/periodic-square.mesh -rp 2 -dt 0.0025 -tf 9 -vs 20
|
||||
// mpirun -np 4 ex41p -m ../data/periodic-cube.mesh -p 0 -rs 2 -o 2 -dt 0.01 -tf 8
|
||||
//
|
||||
// Device sample runs:
|
||||
//
|
||||
// Description: This example code solves the time-dependent advection-diffusion
|
||||
// equation du/dt + v.grad(u) - a div(grad(u)) = 0, where v is a
|
||||
// given fluid velocity, a is the diffusion coefficient, and
|
||||
// u0(x)=u(0,x) is a given initial condition.
|
||||
//
|
||||
// The example demonstrates the use of Discontinuous Galerkin (DG)
|
||||
// bilinear forms in MFEM (face integrators), DG-LOR Preconditioning
|
||||
// and the use of IMEX ODE time integrators.
|
||||
//
|
||||
// The Option to use Continuous Finite Elements is available too.
|
||||
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// Mesh bounding box
|
||||
Vector bb_min, bb_max;
|
||||
|
||||
// Velocity coefficient
|
||||
template<int problem=0>
|
||||
void velocity_function(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
|
||||
// map to the reference [-1,1] domain
|
||||
Vector X(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
|
||||
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
|
||||
}
|
||||
switch (problem)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// Translations in 1D, 2D, and 3D
|
||||
switch (dim)
|
||||
{
|
||||
case 1: v(0) = 1.0; break;
|
||||
case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.); break;
|
||||
case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
case 2:
|
||||
{
|
||||
// Clockwise rotation in 2D around the origin
|
||||
const real_t w = M_PI/2;
|
||||
switch (dim)
|
||||
{
|
||||
case 1: v(0) = 1.0; break;
|
||||
case 2: v(0) = w*X(1); v(1) = -w*X(0); break;
|
||||
case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
// Clockwise twisting rotation in 2D around the origin
|
||||
const real_t w = M_PI/2;
|
||||
real_t d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
|
||||
d = d*d;
|
||||
switch (dim)
|
||||
{
|
||||
case 1: v(0) = 1.0; break;
|
||||
case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0); break;
|
||||
case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Initial condition
|
||||
template<int problem=0>
|
||||
real_t u0_function(const Vector &x)
|
||||
{
|
||||
int dim = x.Size();
|
||||
|
||||
// map to the reference [-1,1] domain
|
||||
Vector X(dim);
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
|
||||
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
|
||||
}
|
||||
|
||||
switch (problem)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
switch (dim)
|
||||
{
|
||||
case 1:
|
||||
return exp(-40.*pow(X(0)-0.5,2));
|
||||
case 2:
|
||||
case 3:
|
||||
{
|
||||
real_t rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
|
||||
if (dim == 3)
|
||||
{
|
||||
const real_t s = (1. + 0.25*cos(2*M_PI*X(2)));
|
||||
rx *= s;
|
||||
ry *= s;
|
||||
}
|
||||
return ( std::erfc(w*(X(0)-cx-rx))*std::erfc(-w*(X(0)-cx+rx)) *
|
||||
std::erfc(w*(X(1)-cy-ry))*std::erfc(-w*(X(1)-cy+ry)) )/16;
|
||||
}
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
real_t x_ = X(0), y_ = X(1), rho, phi;
|
||||
rho = std::hypot(x_, y_);
|
||||
phi = atan2(y_, x_);
|
||||
return pow(sin(M_PI*rho),2)*sin(3*phi);
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
const real_t f = M_PI;
|
||||
return sin(f*X(0))*sin(f*X(1));
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
class Implicit_Solver : public Solver
|
||||
{
|
||||
private:
|
||||
HypreParMatrix &M, &S;
|
||||
HypreParMatrix *A;
|
||||
CGSolver linear_solver;
|
||||
real_t dt;
|
||||
SparseMatrix M_diag;
|
||||
public:
|
||||
Implicit_Solver(HypreParMatrix &M_, HypreParMatrix &S_,
|
||||
const FiniteElementSpace &fes)
|
||||
: M(M_),
|
||||
S(S_),
|
||||
A(nullptr),
|
||||
linear_solver(M.GetComm()),
|
||||
dt(1.0)
|
||||
{
|
||||
linear_solver.iterative_mode = false;
|
||||
linear_solver.SetRelTol(1e-9);
|
||||
linear_solver.SetAbsTol(0.0);
|
||||
linear_solver.SetMaxIter(100);
|
||||
linear_solver.SetPrintLevel(0);
|
||||
|
||||
M.GetDiag(M_diag);
|
||||
}
|
||||
|
||||
void SetTimeStep(real_t dt_)
|
||||
{
|
||||
real_t ddt = dt-dt_;
|
||||
|
||||
// syncronize ddt across all processes
|
||||
MPI_Comm comm = M.GetComm();
|
||||
int myrank;
|
||||
MPI_Comm_rank(comm, &myrank);
|
||||
MPI_Bcast(&ddt, 1, MPI_DOUBLE, 0, comm);
|
||||
|
||||
real_t epsilon;
|
||||
epsilon = std::numeric_limits<real_t>::epsilon();
|
||||
// allow for some tolerance in the time stepping process
|
||||
epsilon*=10;
|
||||
|
||||
if (fabs(ddt) > epsilon)
|
||||
{
|
||||
if (0==myrank)
|
||||
{
|
||||
cout << "Updating Implicit_Solver time step from " << dt
|
||||
<< " to " << dt_ << endl;
|
||||
}
|
||||
|
||||
delete A;
|
||||
dt = dt_;
|
||||
// Form operator A = M + dt*S
|
||||
A = Add(dt, S, 1.0, M);
|
||||
linear_solver.SetOperator(*A);
|
||||
}
|
||||
}
|
||||
|
||||
void SetOperator(const Operator &op) override
|
||||
{
|
||||
linear_solver.SetOperator(op);
|
||||
}
|
||||
|
||||
void Mult(const Vector &x, Vector &y) const override
|
||||
{
|
||||
linear_solver.Mult(x, y);
|
||||
}
|
||||
|
||||
void SetPreconditioner(Solver &precond)
|
||||
{
|
||||
linear_solver.SetPreconditioner(precond);
|
||||
}
|
||||
|
||||
~Implicit_Solver() override
|
||||
{
|
||||
delete A;
|
||||
}
|
||||
};
|
||||
|
||||
/** A time-dependent operator for the right-hand side of the ODE. The DG weak
|
||||
form of the advection-diffusion equation is (M + dt S) du/dt = Su - K u + b
|
||||
, where M and K are the mass and advection matrices, and b describes the
|
||||
flow on the boundary. In the case of IMEX evolution, the diffusion term is
|
||||
treated implicitly, and the advection term is treated explicitly. */
|
||||
class IMEX_Evolution : public TimeDependentOperator
|
||||
{
|
||||
private:
|
||||
OperatorHandle M, K, S, A;
|
||||
const Vector &b;
|
||||
Solver *M_prec;
|
||||
CGSolver M_solver;
|
||||
Implicit_Solver *implicit_solver;
|
||||
LORSolver<HypreBoomerAMG>* lor_solver;
|
||||
|
||||
mutable Vector z;
|
||||
mutable Vector w;
|
||||
|
||||
public:
|
||||
IMEX_Evolution(ParBilinearForm &M_, ParBilinearForm &K_, ParBilinearForm &S_,
|
||||
const Vector &b_, ParBilinearForm &A_);
|
||||
|
||||
virtual
|
||||
~IMEX_Evolution()
|
||||
{
|
||||
delete implicit_solver;
|
||||
delete lor_solver;
|
||||
delete M_prec;
|
||||
}
|
||||
|
||||
void Mult1(const Vector &x, Vector &y) const;
|
||||
|
||||
void ImplicitSolve2(const real_t dt, const Vector &x, Vector &k);
|
||||
|
||||
void Mult(const Vector &x, Vector &y) const override
|
||||
{
|
||||
if (TimeDependentOperator::EvalMode::ADDITIVE_TERM_1 == GetEvalMode())
|
||||
{
|
||||
Mult1(x,y);
|
||||
}
|
||||
else
|
||||
{
|
||||
mfem_error("TimeDependentOperator::Mult() is not overridden!");
|
||||
}
|
||||
}
|
||||
|
||||
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override
|
||||
{
|
||||
if (TimeDependentOperator::EvalMode::ADDITIVE_TERM_2 == GetEvalMode())
|
||||
{
|
||||
ImplicitSolve2(dt,x,k);
|
||||
}
|
||||
else
|
||||
{
|
||||
mfem_error("TimeDependentOperator::ImplicitSolve() is not overridden!");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Initialize MPI and HYPRE.
|
||||
Mpi::Init();
|
||||
int num_procs = Mpi::WorldSize();
|
||||
int myid = Mpi::WorldRank();
|
||||
Hypre::Init();
|
||||
|
||||
// 2. Parse command-line options.
|
||||
int problem = 0;
|
||||
const char *mesh_file = "../data/periodic-square.mesh";
|
||||
int ser_ref_levels = 2;
|
||||
int par_ref_levels = 0;
|
||||
int order = 3;
|
||||
int ode_solver_type = 64; // 61 - Forward Backward Euler
|
||||
// 62 - IMEXRK2(2,2,2)
|
||||
// 63 - IMEXRK2(2,3,2)
|
||||
// 64 - IMEXRK3(3,4,3)
|
||||
real_t t_final = 10.0;
|
||||
real_t dt = 0.01;
|
||||
bool paraview = false;
|
||||
bool cg = false;
|
||||
int vis_steps = 50;
|
||||
bool adios2 = false;
|
||||
bool binary = false;
|
||||
real_t diffusion_term = 0.01;
|
||||
real_t kappa = -1.0;
|
||||
real_t sigma = -1.0;
|
||||
bool visualization = true;
|
||||
bool visit = false;
|
||||
int precision = 16;
|
||||
cout.precision(precision);
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&problem, "-p", "--problem",
|
||||
"Problem setup to use. See options in velocity_function().");
|
||||
args.AddOption(&ser_ref_levels, "-rs", "--refine-serial",
|
||||
"Number of times to refine the mesh uniformly in serial.");
|
||||
args.AddOption(&par_ref_levels, "-rp", "--refine-parallel",
|
||||
"Number of times to refine the mesh uniformly in parallel.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Order (degree) of the finite elements.");
|
||||
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
|
||||
ODESolver::IMEXTypes.c_str());
|
||||
args.AddOption(&t_final, "-tf", "--t-final",
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
"Time step.");
|
||||
args.AddOption(&diffusion_term, "-dc", "--diffusion-coeff",
|
||||
"Diffusion coefficient in the PDE.");
|
||||
args.AddOption(¶view, "-paraview", "--paraview-datafiles", "-no-paraview",
|
||||
"--no-paraview-datafiles",
|
||||
"Save data files for ParaView (paraview.org) visualization.");
|
||||
args.AddOption(&visit, "-visit", "--visit-datafiles", "-no-visit",
|
||||
"--no-visit-datafiles",
|
||||
"Save data files for VisIt (visit.llnl.gov) visualization.");
|
||||
args.AddOption(&adios2, "-adios2", "--adios2-streams", "-no-adios2",
|
||||
"--no-adios2-streams",
|
||||
"Save data using adios2 streams.");
|
||||
args.AddOption(&binary, "-binary", "--binary-datafiles", "-ascii",
|
||||
"--ascii-datafiles",
|
||||
"Use binary (Sidre) or ascii format for VisIt data files.");
|
||||
args.AddOption(&vis_steps, "-vs", "--visualization-steps",
|
||||
"Visualize every n-th timestep.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.AddOption(&cg, "-cg", "--continuous-galerkin", "-dg",
|
||||
"--discontinuous-galerkin",
|
||||
"Use Continuous-Galerkin Finite elements (Default is DG)");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
if (Mpi::Root())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (Mpi::Root())
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
if (kappa < 0)
|
||||
{
|
||||
kappa = (order+1)*(order+1);
|
||||
}
|
||||
|
||||
// 3. Read the mesh from the given mesh file. We can handle geometrically
|
||||
// periodic meshes in this code.
|
||||
Mesh *mesh = new Mesh(mesh_file);
|
||||
const int dim = mesh->Dimension();
|
||||
|
||||
// 4. Define the IMEX (Split) ODE solver used for time integration. The IMEX
|
||||
// solvers currently available are: 55 - Forward Backward Euler,
|
||||
// 56 - IMEXRK2(2,2,2), 57 - IMEXRK2(2,3,2), and
|
||||
unique_ptr<ODESolver> ode_solver = ODESolver::SelectIMEX(ode_solver_type);
|
||||
|
||||
// 5. Refine the mesh to increase the resolution. In this example we do
|
||||
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
|
||||
// command-line parameter.
|
||||
for (int lev = 0; lev < ser_ref_levels; lev++) { mesh->UniformRefinement(); }
|
||||
if (mesh->NURBSext)
|
||||
{
|
||||
mesh->SetCurvature(max(order, 1));
|
||||
}
|
||||
mesh->GetBoundingBox(bb_min, bb_max, max(order, 1));
|
||||
|
||||
|
||||
// 6. Define the parallel mesh by a partitioning of the serial mesh. Refine
|
||||
// this mesh further in parallel to increase the resolution. Once the
|
||||
// parallel mesh is defined, the serial mesh can be deleted.
|
||||
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
|
||||
delete mesh;
|
||||
for (int lev = 0; lev < par_ref_levels; lev++)
|
||||
{
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 7. Define the discontinuous DG finite element space of the given
|
||||
// polynomial order on the refined mesh.
|
||||
FiniteElementCollection *fec = NULL;
|
||||
if (cg)
|
||||
{
|
||||
fec = new H1_FECollection(order, dim);
|
||||
}
|
||||
else
|
||||
{
|
||||
fec = new DG_FECollection(order, dim, BasisType::GaussLobatto);
|
||||
}
|
||||
ParFiniteElementSpace *fes = new ParFiniteElementSpace(pmesh, fec);
|
||||
|
||||
HYPRE_BigInt global_vSize = fes->GlobalTrueVSize();
|
||||
if (Mpi::Root())
|
||||
{
|
||||
cout << "Number of unknowns: " << global_vSize << endl;
|
||||
}
|
||||
|
||||
// 8. Set up and assemble the bilinear and linear forms corresponding to the
|
||||
// DG discretization. The DGTraceIntegrator involves integrals over mesh
|
||||
// interior faces.
|
||||
std::unique_ptr<VectorFunctionCoefficient> velocity;
|
||||
if (0==problem)
|
||||
{
|
||||
velocity.reset(new VectorFunctionCoefficient(dim, velocity_function<0>));
|
||||
}
|
||||
else if (1==problem)
|
||||
{
|
||||
velocity.reset(new VectorFunctionCoefficient(dim, velocity_function<1>));
|
||||
}
|
||||
else if (2==problem)
|
||||
{
|
||||
velocity.reset(new VectorFunctionCoefficient(dim, velocity_function<2>));
|
||||
}
|
||||
else if (3==problem)
|
||||
{
|
||||
velocity.reset(new VectorFunctionCoefficient(dim, velocity_function<3>));
|
||||
}
|
||||
ConstantCoefficient diff_coeff(diffusion_term);
|
||||
ConstantCoefficient dt_diff_coeff(dt*diffusion_term);
|
||||
|
||||
ParBilinearForm *m = new ParBilinearForm(fes);
|
||||
ParBilinearForm *k = new ParBilinearForm(fes);
|
||||
ParBilinearForm *s = new ParBilinearForm(fes);
|
||||
|
||||
m->AddDomainIntegrator(new MassIntegrator());
|
||||
|
||||
constexpr real_t alpha = -1.0;
|
||||
k->AddDomainIntegrator(new ConvectionIntegrator(*velocity, alpha));
|
||||
|
||||
s->AddDomainIntegrator(new DiffusionIntegrator(diff_coeff));
|
||||
|
||||
// For the preconditioner - create billinear form corresponding to
|
||||
// operator (M + dt S)
|
||||
ParBilinearForm *a = new ParBilinearForm(fes);
|
||||
a->AddDomainIntegrator(new MassIntegrator);
|
||||
a->AddDomainIntegrator(new DiffusionIntegrator(dt_diff_coeff));
|
||||
if (!cg)
|
||||
{
|
||||
k->AddInteriorFaceIntegrator(new NonconservativeDGTraceIntegrator(*velocity,
|
||||
alpha));
|
||||
k->AddBdrFaceIntegrator(new NonconservativeDGTraceIntegrator(*velocity, alpha));
|
||||
s->AddInteriorFaceIntegrator(new DGDiffusionIntegrator(diff_coeff, sigma,
|
||||
kappa));
|
||||
s->AddBdrFaceIntegrator(new DGDiffusionIntegrator(diff_coeff, sigma, kappa));
|
||||
a->AddInteriorFaceIntegrator(new DGDiffusionIntegrator(dt_diff_coeff, sigma,
|
||||
kappa));
|
||||
a->AddBdrFaceIntegrator(new DGDiffusionIntegrator(dt_diff_coeff, sigma, kappa));
|
||||
}
|
||||
|
||||
int skip_zeros = 0;
|
||||
m->Assemble(skip_zeros);
|
||||
k->Assemble(skip_zeros);
|
||||
s->Assemble(skip_zeros);
|
||||
a->Assemble();
|
||||
|
||||
m->Finalize(skip_zeros);
|
||||
k->Finalize(skip_zeros);
|
||||
s->Finalize(skip_zeros);
|
||||
a->Finalize(skip_zeros);
|
||||
HypreParVector b(fes);
|
||||
b = 0.0;
|
||||
|
||||
// 9. Define the initial conditions. Set up visualization (if desired).
|
||||
std::unique_ptr<FunctionCoefficient> u0;
|
||||
if (0==problem)
|
||||
{
|
||||
u0.reset(new FunctionCoefficient(u0_function<0>));
|
||||
}
|
||||
else if (1==problem)
|
||||
{
|
||||
u0.reset(new FunctionCoefficient(u0_function<1>));
|
||||
}
|
||||
else if (2==problem)
|
||||
{
|
||||
u0.reset(new FunctionCoefficient(u0_function<2>));
|
||||
}
|
||||
else if (3==problem)
|
||||
{
|
||||
u0.reset(new FunctionCoefficient(u0_function<3>));
|
||||
}
|
||||
ParGridFunction *u = new ParGridFunction(fes);
|
||||
u->ProjectCoefficient(*u0);
|
||||
HypreParVector *U = u->GetTrueDofs();
|
||||
|
||||
DataCollection *dc = NULL;
|
||||
if (visit)
|
||||
{
|
||||
if (binary)
|
||||
{
|
||||
#ifdef MFEM_USE_SIDRE
|
||||
dc = new SidreDataCollection("Example41-Parallel", pmesh);
|
||||
#else
|
||||
MFEM_ABORT("Must build with MFEM_USE_SIDRE=YES for binary output.");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
dc = new VisItDataCollection("Example41-Parallel", pmesh);
|
||||
dc->SetPrecision(precision);
|
||||
// To save the mesh using MFEM's parallel mesh format:
|
||||
// dc->SetFormat(DataCollection::PARALLEL_FORMAT);
|
||||
}
|
||||
dc->RegisterField("solution", u);
|
||||
dc->SetCycle(0);
|
||||
dc->SetTime(0.0);
|
||||
dc->Save();
|
||||
}
|
||||
ParaViewDataCollection *pd = NULL;
|
||||
if (paraview)
|
||||
{
|
||||
pd = new ParaViewDataCollection("Example41P", pmesh);
|
||||
pd->SetPrefixPath("ParaView");
|
||||
pd->RegisterField("solution", u);
|
||||
pd->SetLevelsOfDetail(order);
|
||||
pd->SetDataFormat(VTKFormat::BINARY);
|
||||
pd->SetHighOrderOutput(true);
|
||||
pd->SetCycle(0);
|
||||
pd->SetTime(0.0);
|
||||
pd->Save();
|
||||
}
|
||||
socketstream sout;
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
sout.open(vishost, visport);
|
||||
if (!sout)
|
||||
{
|
||||
if (Mpi::Root())
|
||||
{
|
||||
cout << "Unable to connect to GLVis server at "
|
||||
<< vishost << ':' << visport << endl;
|
||||
}
|
||||
visualization = false;
|
||||
if (Mpi::Root())
|
||||
{
|
||||
cout << "GLVis visualization disabled.\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sout << "parallel " << num_procs << " " << myid << "\n";
|
||||
sout.precision(precision);
|
||||
sout << "solution\n" << *pmesh << *u;
|
||||
sout << "pause\n";
|
||||
sout << flush;
|
||||
if (Mpi::Root())
|
||||
{
|
||||
cout << "GLVis visualization paused."
|
||||
<< " Press space (in the GLVis window) to resume it.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef MFEM_USE_ADIOS2
|
||||
ADIOS2DataCollection *adios2_dc = NULL;
|
||||
if (adios2)
|
||||
{
|
||||
std::string postfix(mesh_file);
|
||||
postfix.erase(0, std::string("../data/").size() );
|
||||
postfix += "_o" + std::to_string(order);
|
||||
const std::string collection_name = "ex41-p-" + postfix + ".bp";
|
||||
|
||||
adios2_dc = new ADIOS2DataCollection(MPI_COMM_WORLD, collection_name, pmesh);
|
||||
// output data substreams are half the number of mpi processes
|
||||
adios2_dc->SetParameter("SubStreams", std::to_string(num_procs/2) );
|
||||
// adios2_dc->SetLevelsOfDetail(2);
|
||||
adios2_dc->RegisterField("solution", u);
|
||||
adios2_dc->SetCycle(0);
|
||||
adios2_dc->SetTime(0.0);
|
||||
adios2_dc->Save();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// 10. Define the time-dependent evolution operator describing the
|
||||
// ODE right-hand side, and perform time-integration (looping
|
||||
// over the time iterations, ti, with a time-step dt).
|
||||
IMEX_Evolution adv(*m, *k, *s, b, *a);
|
||||
|
||||
real_t t = 0.0;
|
||||
adv.SetTime(t);
|
||||
ode_solver->Init(adv);
|
||||
|
||||
|
||||
bool done = false;
|
||||
for (int ti = 0; !done; )
|
||||
{
|
||||
real_t dt_real = min(dt, t_final - t);
|
||||
ode_solver->Step(*U, t, dt_real);
|
||||
ti++;
|
||||
|
||||
done = (t >= t_final - 1e-8*dt);
|
||||
|
||||
if (done || ti % vis_steps == 0)
|
||||
{
|
||||
if (Mpi::Root())
|
||||
{
|
||||
cout << "time step: " << ti << ", time: " << t << endl;
|
||||
}
|
||||
*u = *U;
|
||||
if (visualization)
|
||||
{
|
||||
sout << "parallel " << num_procs << " " << myid << "\n";
|
||||
sout << "solution\n" << *pmesh << *u << flush;
|
||||
}
|
||||
if (paraview)
|
||||
{
|
||||
pd->SetCycle(ti);
|
||||
pd->SetTime(t);
|
||||
pd->Save();
|
||||
}
|
||||
#ifdef MFEM_USE_ADIOS2
|
||||
// transient solutions can be visualized with ParaView
|
||||
if (adios2)
|
||||
{
|
||||
adios2_dc->SetCycle(ti);
|
||||
adios2_dc->SetTime(t);
|
||||
adios2_dc->Save();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// 11. Free the used memory.
|
||||
delete pd;
|
||||
delete U;
|
||||
delete u;
|
||||
delete a;
|
||||
delete s;
|
||||
delete k;
|
||||
delete m;
|
||||
delete fes;
|
||||
delete pmesh;
|
||||
delete dc;
|
||||
delete fec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Implementation of class IMEX_Evolution
|
||||
IMEX_Evolution::IMEX_Evolution(ParBilinearForm &M_, ParBilinearForm &K_,
|
||||
ParBilinearForm &S_, const Vector &b_, ParBilinearForm &A_)
|
||||
: TimeDependentOperator(M_.ParFESpace()->GetTrueVSize()), b(b_),
|
||||
M_solver(M_.ParFESpace()->GetComm()), z(height), w(height)
|
||||
{
|
||||
if (M_.GetAssemblyLevel()==AssemblyLevel::LEGACY)
|
||||
{
|
||||
M.Reset(M_.ParallelAssemble(), true);
|
||||
K.Reset(K_.ParallelAssemble(), true);
|
||||
S.Reset(S_.ParallelAssemble(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
M.Reset(&M_, false);
|
||||
K.Reset(&K_, false);
|
||||
S.Reset(&S_, false);
|
||||
}
|
||||
|
||||
M_solver.SetOperator(*M);
|
||||
|
||||
Array<int> ess_tdof_list;
|
||||
if (M_.GetAssemblyLevel() == AssemblyLevel::LEGACY)
|
||||
{
|
||||
A.Reset(A_.ParallelAssemble(), true);
|
||||
HypreParMatrix &M_mat = *M.As<HypreParMatrix>();
|
||||
HypreParMatrix &S_mat = *S.As<HypreParMatrix>();
|
||||
HypreSmoother *hypre_prec = new HypreSmoother(M_mat, HypreSmoother::Jacobi);
|
||||
M_prec = hypre_prec;
|
||||
|
||||
implicit_solver = new Implicit_Solver(M_mat, S_mat, *M_.FESpace());
|
||||
lor_solver = new LORSolver<HypreBoomerAMG>(A_, ess_tdof_list);
|
||||
lor_solver->GetSolver().SetSystemsOptions(A_.ParFESpace()->GetVDim(), true);
|
||||
implicit_solver -> SetPreconditioner(*lor_solver);
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_ABORT("Implicit time integration is not supported with partial assembly");
|
||||
}
|
||||
M_solver.SetPreconditioner(*M_prec);
|
||||
M_solver.iterative_mode = false;
|
||||
M_solver.SetRelTol(1e-9);
|
||||
M_solver.SetAbsTol(0.0);
|
||||
M_solver.SetMaxIter(100);
|
||||
M_solver.SetPrintLevel(0);
|
||||
}
|
||||
|
||||
void IMEX_Evolution::Mult1(const Vector &x, Vector &y) const
|
||||
{
|
||||
// Perform the explicit step
|
||||
// y = M^{-1} (K x + b)
|
||||
K->Mult(x, z);
|
||||
z += b;
|
||||
M_solver.Mult(z, y);
|
||||
}
|
||||
|
||||
void IMEX_Evolution::ImplicitSolve2(const real_t dt, const Vector &x, Vector &k)
|
||||
{
|
||||
// Perform the implicit step
|
||||
// solve for k, k = -(M+dt S)^{-1} S x
|
||||
MFEM_VERIFY(implicit_solver != NULL,
|
||||
"Implicit time integration is not supported with partial assembly");
|
||||
S->Mult(x, z);
|
||||
z*= -1.0;
|
||||
implicit_solver->SetTimeStep(dt);
|
||||
implicit_solver->Mult(z, k);
|
||||
}
|
||||
+1
-6
@@ -9,7 +9,6 @@
|
||||
// mpirun -np 4 ex4p -m ../data/beam-hex.mesh -o 2 -pa
|
||||
// mpirun -np 4 ex4p -m ../data/escher.mesh -o 2 -sc
|
||||
// mpirun -np 4 ex4p -m ../data/fichera.mesh -o 2 -hb
|
||||
// mpirun -np 4 ex4p -m ../data/fichera.mesh -o 2 -hb -ea
|
||||
// mpirun -np 4 ex4p -m ../data/fichera-q2.vtk
|
||||
// mpirun -np 4 ex4p -m ../data/fichera-q3.mesh -o 2 -sc
|
||||
// mpirun -np 4 ex4p -m ../data/square-disc-nurbs.mesh -o 3
|
||||
@@ -18,18 +17,14 @@
|
||||
// mpirun -np 4 ex4p -m ../data/periodic-cube.mesh -no-bc
|
||||
// mpirun -np 4 ex4p -m ../data/amr-quad.mesh
|
||||
// mpirun -np 3 ex4p -m ../data/amr-quad.mesh -o 2 -hb
|
||||
// mpirun -np 3 ex4p -m ../data/amr-quad.mesh -o 2 -hb -ea
|
||||
// mpirun -np 4 ex4p -m ../data/amr-hex.mesh -o 2 -sc
|
||||
// mpirun -np 4 ex4p -m ../data/amr-hex.mesh -o 2 -hb
|
||||
// mpirun -np 4 ex4p -m ../data/amr-hex.mesh -o 2 -hb -ea
|
||||
// mpirun -np 4 ex4p -m ../data/ref-prism.mesh -o 1
|
||||
// mpirun -np 4 ex4p -m ../data/octahedron.mesh -o 1
|
||||
// mpirun -np 4 ex4p -m ../data/star-surf.mesh -o 3 -hb
|
||||
//
|
||||
// Device sample runs:
|
||||
// mpirun -np 4 ex4p -m ../data/star.mesh -pa -d cuda
|
||||
// mpirun -np 4 ex4p -m ../data/star.mesh -ea -hb -d cuda
|
||||
// mpirun -np 4 ex4p -m ../data/amr-hex.mesh -ea -hb -d cuda
|
||||
// mpirun -np 4 ex4p -m ../data/star.mesh -pa -d raja-cuda
|
||||
// mpirun -np 4 ex4p -m ../data/star.mesh -pa -d raja-omp
|
||||
// mpirun -np 4 ex4p -m ../data/beam-hex.mesh -pa -d cuda
|
||||
@@ -235,7 +230,7 @@ int main(int argc, char *argv[])
|
||||
pcg->SetMaxIter(2000);
|
||||
pcg->SetPrintLevel(1);
|
||||
if (hybridization) { prec = new HypreBoomerAMG(*A.As<HypreParMatrix>()); }
|
||||
else if (pa || ea) { prec = new OperatorJacobiSmoother(*a, ess_tdof_list); }
|
||||
else if (pa) { prec = new OperatorJacobiSmoother(*a, ess_tdof_list); }
|
||||
else
|
||||
{
|
||||
ParFiniteElementSpace *prec_fespace =
|
||||
|
||||
+1
-20
@@ -160,7 +160,6 @@ int main(int argc, char *argv[])
|
||||
bool paraview = false;
|
||||
bool binary = false;
|
||||
int vis_steps = 5;
|
||||
bool solve_implicit_state = false;
|
||||
|
||||
int precision = 8;
|
||||
cout.precision(precision);
|
||||
@@ -188,9 +187,6 @@ int main(int argc, char *argv[])
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
"Time step.");
|
||||
args.AddOption(&solve_implicit_state, "-imp-state", "--implicit-state",
|
||||
"-imp-slope", "--implicit-slope",
|
||||
"Implicitly solve for stage state or slope.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -370,11 +366,6 @@ int main(int argc, char *argv[])
|
||||
// right-hand side, and perform time-integration (looping over the time
|
||||
// iterations, ti, with a time-step dt).
|
||||
FE_Evolution adv(m, k, b);
|
||||
using ImplicitVariableType = FE_Evolution::ImplicitVariableType;
|
||||
ImplicitVariableType imp_var = solve_implicit_state ?
|
||||
ImplicitVariableType::STATE
|
||||
: ImplicitVariableType::SLOPE;
|
||||
adv.SetImplicitVariableType(imp_var);
|
||||
|
||||
real_t t = 0.0;
|
||||
adv.SetTime(t);
|
||||
@@ -468,17 +459,7 @@ void FE_Evolution::ImplicitSolve(const real_t dt, const Vector &x, Vector &k)
|
||||
{
|
||||
MFEM_VERIFY(dg_solver != NULL,
|
||||
"Implicit time integration is not supported with partial assembly");
|
||||
// Construct current right-hand side for stage state vs. slope solve
|
||||
if (ImplicitVarTypeIsState())
|
||||
{
|
||||
// k, on return, is the stage value u
|
||||
M.Mult(x, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
// k, on return, is the stage slope du/dt
|
||||
K.Mult(x, z);
|
||||
}
|
||||
K.Mult(x, z);
|
||||
z += b;
|
||||
dg_solver->SetTimeStep(dt);
|
||||
dg_solver->Mult(z, k);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user