Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e176bb8d06 | ||
|
|
c1509fde91 | ||
|
|
44f25808b9 | ||
|
|
8296bca522 | ||
|
|
d4825be0ca | ||
|
|
ff143322bd | ||
|
|
b08c652314 |
@@ -1,49 +0,0 @@
|
||||
version: '{build}'
|
||||
|
||||
# https://www.appveyor.com/docs/build-environment/#build-worker-images
|
||||
image: Visual Studio 2017
|
||||
|
||||
install:
|
||||
|
||||
# Install MS-MPI
|
||||
- ps: Start-FileDownload 'https://download.microsoft.com/download/B/2/E/B2EB83FE-98C2-4156-834A-E1711E6884FB/MSMpiSetup.exe'
|
||||
- MSMpiSetup.exe -unattend
|
||||
- set PATH=C:\Program Files\Microsoft MPI\Bin;%PATH%
|
||||
|
||||
# Install MS-MPI SDK
|
||||
- ps: Start-FileDownload 'https://download.microsoft.com/download/B/2/E/B2EB83FE-98C2-4156-834A-E1711E6884FB/msmpisdk.msi'
|
||||
- msmpisdk.msi /passive
|
||||
- set PATH=C:\Program Files\Microsoft MPI\Bin;%PATH%
|
||||
|
||||
# Install METIS
|
||||
- ps: Start-FileDownload 'http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-5.1.0.tar.gz'
|
||||
- 7z x metis-5.1.0.tar.gz -so | 7z x -si -ttar > nul
|
||||
- cd metis-5.1.0
|
||||
- ps: ( get-content "GKlib\gk_arch.h") | % { If ($_.ReadCount -ge 52) {$_ -replace "#ifdef __MSC__","#ifdef DISABLE_THIS_ANCIENT_MSC_CHECK"} Else {$_} } | set-content "GKlib\gk_arch.h"
|
||||
- cmake -H. -Bbuild
|
||||
# -DCMAKE_BUILD_TYPE=Release
|
||||
- cmake --build build
|
||||
- cd ..
|
||||
|
||||
# Install hypre
|
||||
- ps: Start-FileDownload 'https://computation.llnl.gov/project/linear_solvers/download/hypre-2.10.0b.tar.gz'
|
||||
- 7z x hypre-2.10.0b.tar.gz -so | 7z x -si -ttar > nul
|
||||
- cd hypre-2.10.0b
|
||||
- cmake -Hsrc -Bbuild -DMPI_C_INCLUDE_PATH="C:\Program Files (x86)\Microsoft SDKs\MPI\Include" -DMPI_C_LIBRARIES="C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x86\msmpi.lib" -DMPI_CXX_LIBRARIES="C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x86\msmpi.lib" -DMPI_CXX_INCLUDE_PATH="C:\Program Files (x86)\Microsoft SDKs\MPI\Include"
|
||||
# - cmake -Hsrc -Bbuild -DCMAKE_BUILD_TYPE=Release -DMPI_C_INCLUDE_PATH="C:\Program Files (x86)\Microsoft SDKs\MPI\Include" -DMPI_C_LIBRARIES="C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x86\msmpi.lib" -DMPI_CXX_LIBRARIES="C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x86\msmpi.lib" -DMPI_CXX_INCLUDE_PATH="C:\Program Files (x86)\Microsoft SDKs\MPI\Include"
|
||||
- cmake --build build
|
||||
- cmake --build build --target install
|
||||
- cd ..
|
||||
|
||||
# MFEM
|
||||
before_build:
|
||||
- cmake -H. -DCMAKE_INSTALL_PREFIX=install -Bbuild_parallel -DMFEM_USE_MPI=TRUE -DMFEM_USE_METIS_5=TRUE -DMPI_CXX_LIBRARIES="C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x86\msmpi.lib" -DMPI_CXX_INCLUDE_PATH="C:\Program Files (x86)\Microsoft SDKs\MPI\Include" -DHYPRE_LIBRARIES=%cd%\hypre-2.10.0b\src\hypre\lib\HYPRE.lib -DHYPRE_INCLUDE_DIRS=%cd%\hypre-2.10.0b\src\hypre\include -DHYPRE_VERSION=21000 -DMETIS_LIBRARIES=%cd%\metis-5.1.0\build\libmetis\Debug\metis.lib -DMETIS_INCLUDE_DIRS=%cd%\metis-5.1.0\include
|
||||
- cmake -H. -DCMAKE_INSTALL_PREFIX=install -Bbuild_serial -DMFEM_USE_MPI=FALSE -DMFEM_USE_METIS_5=TRUE -DMPI_CXX_LIBRARIES="C:\Program Files (x86)\Microsoft SDKs\MPI\Lib\x86\msmpi.lib" -DMPI_CXX_INCLUDE_PATH="C:\Program Files (x86)\Microsoft SDKs\MPI\Include" -DHYPRE_LIBRARIES=%cd%\hypre-2.10.0b\src\hypre\lib\HYPRE.lib -DHYPRE_INCLUDE_DIRS=%cd%\hypre-2.10.0b\src\hypre\include -DHYPRE_VERSION=21000 -DMETIS_LIBRARIES=%cd%\metis-5.1.0\build\libmetis\Debug\metis.lib -DMETIS_INCLUDE_DIRS=%cd%\metis-5.1.0\include
|
||||
|
||||
build_script:
|
||||
- cmake --build build_parallel
|
||||
- cmake --build build_serial
|
||||
|
||||
after_build:
|
||||
# - cmake --build build_parallel --target check
|
||||
- cmake --build build_serial --target check
|
||||
@@ -1,185 +0,0 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Ignore files that are generated from the repository sources by either building
|
||||
# the code or running it. These should be the same as the files erased by
|
||||
# `make distclean`.
|
||||
#
|
||||
# Also ignore OS-specific files like .DS_Store on Mac
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# Object and library files
|
||||
*.o
|
||||
/libmfem.*
|
||||
|
||||
# CMake generated files
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
|
||||
# Backup files
|
||||
*~
|
||||
|
||||
# Default install location
|
||||
/mfem/
|
||||
|
||||
# Generated files in main directory, config/ and docs/
|
||||
/deps.mk
|
||||
config/_config.hpp
|
||||
config/config.mk
|
||||
config/sample-runs-build.log
|
||||
doc/CodeDocumentation.conf
|
||||
doc/CodeDocumentation.html
|
||||
doc/CodeDocumentation
|
||||
|
||||
# Temporary files created by the tests.
|
||||
*.stderr
|
||||
|
||||
# Totalview breakpoint files
|
||||
*.TVD.*breakpoints
|
||||
|
||||
# OS-specific: Mac
|
||||
*.dSYM
|
||||
.DS_Store
|
||||
|
||||
# Example and miniapp binaries and outputs
|
||||
|
||||
examples/ex[1-9]
|
||||
examples/ex[1-9]p
|
||||
examples/ex1[04-9]
|
||||
examples/ex1[0-9]p
|
||||
examples/ex2[0-9]
|
||||
examples/ex2[0-9]p
|
||||
|
||||
examples/refined.mesh
|
||||
examples/displaced.mesh
|
||||
examples/mesh.*
|
||||
examples/ex5.mesh
|
||||
examples/Example5*
|
||||
examples/Example9*
|
||||
examples/Example15*
|
||||
examples/Example16*
|
||||
examples/sphere_refined.*
|
||||
examples/sol.*
|
||||
examples/sol_u.*
|
||||
examples/sol_p.*
|
||||
examples/ex9.mesh
|
||||
examples/ex9-mesh.*
|
||||
examples/ex9-init.*
|
||||
examples/ex9-final.*
|
||||
examples/deformed.*
|
||||
examples/velocity.*
|
||||
examples/elastic_energy.*
|
||||
examples/mode_*
|
||||
examples/ex16.mesh
|
||||
examples/ex16-mesh.*
|
||||
examples/ex16-init.*
|
||||
examples/ex16-final.*
|
||||
examples/vortex-mesh.*
|
||||
examples/vortex.mesh
|
||||
examples/vortex-?-init.*
|
||||
examples/vortex-?-final.*
|
||||
examples/deformation.*
|
||||
examples/pressure.*
|
||||
examples/ex20.dat
|
||||
examples/ex20p_?????.dat
|
||||
examples/gnuplot_ex20.inp
|
||||
examples/gnuplot_ex20p.inp
|
||||
examples/ex22*.mesh
|
||||
examples/ex22*.sol
|
||||
examples/ex22p_*.*
|
||||
|
||||
examples/sundials/ex9
|
||||
examples/sundials/ex1[06]
|
||||
examples/sundials/ex9p
|
||||
examples/sundials/ex1[06]p
|
||||
|
||||
examples/sundials/ex9.mesh
|
||||
examples/sundials/ex9-mesh.*
|
||||
examples/sundials/ex9-init.*
|
||||
examples/sundials/ex9-final.*
|
||||
examples/sundials/Example9*
|
||||
examples/sundials/deformed.*
|
||||
examples/sundials/velocity.*
|
||||
examples/sundials/elastic_energy.*
|
||||
examples/sundials/ex16.mesh
|
||||
examples/sundials/ex16-mesh.*
|
||||
examples/sundials/ex16-init.*
|
||||
examples/sundials/ex16-final.*
|
||||
examples/sundials/Example16*
|
||||
|
||||
examples/petsc/ex[1-69]p
|
||||
examples/petsc/ex10p
|
||||
|
||||
examples/petsc/mesh.*
|
||||
examples/petsc/sol.*
|
||||
examples/petsc/sol_p.*
|
||||
examples/petsc/sol_u.*
|
||||
examples/petsc/Example5*
|
||||
examples/petsc/ex9-mesh.*
|
||||
examples/petsc/ex9-init.*
|
||||
examples/petsc/ex9-final.*
|
||||
examples/petsc/Example9*
|
||||
examples/petsc/deformed.*
|
||||
examples/petsc/velocity.*
|
||||
examples/petsc/elastic_energy.*
|
||||
|
||||
examples/pumi/ex1
|
||||
examples/pumi/ex[126]p
|
||||
|
||||
examples/pumi/refined.mesh
|
||||
examples/pumi/sol.gf
|
||||
examples/pumi/mesh.*
|
||||
examples/pumi/sol.*
|
||||
examples/pumi/displaced.mesh
|
||||
|
||||
miniapps/electromagnetics/volta
|
||||
miniapps/electromagnetics/tesla
|
||||
miniapps/electromagnetics/maxwell
|
||||
miniapps/electromagnetics/joule
|
||||
|
||||
miniapps/electromagnetics/Volta-AMR*
|
||||
miniapps/electromagnetics/Tesla-AMR*
|
||||
miniapps/electromagnetics/Maxwell-Parallel*
|
||||
miniapps/electromagnetics/Joule_*
|
||||
|
||||
miniapps/meshing/mobius-strip
|
||||
miniapps/meshing/klein-bottle
|
||||
miniapps/meshing/toroid
|
||||
miniapps/meshing/mesh-explorer
|
||||
miniapps/meshing/shaper
|
||||
miniapps/meshing/extruder
|
||||
miniapps/meshing/mesh-optimizer
|
||||
miniapps/meshing/pmesh-optimizer
|
||||
|
||||
miniapps/meshing/mobius-strip.mesh
|
||||
miniapps/meshing/klein-bottle.mesh
|
||||
miniapps/meshing/toroid-*.mesh
|
||||
miniapps/meshing/mesh-explorer.mesh
|
||||
miniapps/meshing/partitioning.txt
|
||||
miniapps/meshing/shaper.mesh
|
||||
miniapps/meshing/extruder.mesh
|
||||
miniapps/meshing/optimized*
|
||||
miniapps/meshing/perturbed*
|
||||
|
||||
miniapps/performance/ex1
|
||||
miniapps/performance/ex1p
|
||||
|
||||
miniapps/performance/refined.mesh
|
||||
miniapps/performance/mesh.*
|
||||
miniapps/performance/sol.*
|
||||
|
||||
miniapps/tools/display-basis
|
||||
miniapps/tools/load-dc
|
||||
miniapps/tools/convert-dc
|
||||
miniapps/tools/lor-transfer
|
||||
|
||||
miniapps/nurbs/ex1
|
||||
miniapps/nurbs/ex1p
|
||||
miniapps/nurbs/ex11p
|
||||
miniapps/nurbs/refined.mesh
|
||||
miniapps/nurbs/mesh.*
|
||||
miniapps/nurbs/sol.*
|
||||
miniapps/nurbs/mode_*
|
||||
miniapps/nurbs/Example1*
|
||||
|
||||
# Unit test binary and outputs
|
||||
tests/unit/output_meshes
|
||||
tests/unit/unit_tests
|
||||
@@ -1,207 +1,55 @@
|
||||
sudo: false
|
||||
|
||||
language: cpp
|
||||
|
||||
matrix:
|
||||
include:
|
||||
#
|
||||
# Linux
|
||||
#
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: DEBUG=YES
|
||||
MPI=NO
|
||||
CODECOV=NO
|
||||
MFEM_TEST_TARGET=check
|
||||
#
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
env: DEBUG=NO
|
||||
MPI=NO
|
||||
CODECOV=NO
|
||||
MFEM_TEST_TARGET=test
|
||||
#
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
# sources:
|
||||
# - ubuntu-toolchain-r-test
|
||||
packages:
|
||||
# GCC 4.9
|
||||
# - g++-4.9
|
||||
# MPICH
|
||||
- mpich
|
||||
- libmpich-dev
|
||||
# OpenMPI
|
||||
# - openmpi-bin
|
||||
# - libopenmpi-dev
|
||||
env: DEBUG=YES
|
||||
MPI=YES
|
||||
CODECOV=NO
|
||||
MFEM_TEST_TARGET=check
|
||||
NPROCS=2
|
||||
cache:
|
||||
directories:
|
||||
- $TRAVIS_BUILD_DIR/../hypre-2.10.0b/src/hypre/lib
|
||||
- $TRAVIS_BUILD_DIR/../hypre-2.10.0b/src/hypre/include
|
||||
- $TRAVIS_BUILD_DIR/../metis-4.0
|
||||
before_cache:
|
||||
- cd $TRAVIS_BUILD_DIR/../metis-4.0;
|
||||
mv libmetis.a ..; rm -rf *; mv ../libmetis.a .
|
||||
#
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
# sources:
|
||||
# - ubuntu-toolchain-r-test
|
||||
packages:
|
||||
# GCC 4.9
|
||||
# - g++-4.9
|
||||
# MPICH
|
||||
- mpich
|
||||
- libmpich-dev
|
||||
# OpenMPI
|
||||
# - openmpi-bin
|
||||
# - libopenmpi-dev
|
||||
env: DEBUG=NO
|
||||
MPI=YES
|
||||
CODECOV=YES
|
||||
MFEM_TEST_TARGET=test
|
||||
NPROCS=2
|
||||
cache:
|
||||
directories:
|
||||
- $TRAVIS_BUILD_DIR/../hypre-2.10.0b/src/hypre/lib
|
||||
- $TRAVIS_BUILD_DIR/../hypre-2.10.0b/src/hypre/include
|
||||
- $TRAVIS_BUILD_DIR/../metis-4.0
|
||||
before_cache:
|
||||
- cd $TRAVIS_BUILD_DIR/../metis-4.0;
|
||||
mv libmetis.a ..; rm -rf *; mv ../libmetis.a .
|
||||
#
|
||||
# Mac OS X
|
||||
#
|
||||
- os: osx
|
||||
# osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: DEBUG=YES
|
||||
MPI=NO
|
||||
CODECOV=NO
|
||||
MFEM_TEST_TARGET=check
|
||||
#
|
||||
- os: osx
|
||||
# osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: DEBUG=NO
|
||||
MPI=NO
|
||||
CODECOV=NO
|
||||
MFEM_TEST_TARGET=test
|
||||
#
|
||||
- os: osx
|
||||
# osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: DEBUG=YES
|
||||
MPI=YES
|
||||
CODECOV=NO
|
||||
MFEM_TEST_TARGET=check
|
||||
NPROCS=4
|
||||
TMPDIR=/tmp
|
||||
cache:
|
||||
directories:
|
||||
- $TRAVIS_BUILD_DIR/../hypre-2.10.0b/src/hypre/lib
|
||||
- $TRAVIS_BUILD_DIR/../hypre-2.10.0b/src/hypre/include
|
||||
- $TRAVIS_BUILD_DIR/../metis-4.0
|
||||
- $HOME/local-cached
|
||||
before_cache:
|
||||
- cd $TRAVIS_BUILD_DIR/../metis-4.0;
|
||||
mv libmetis.a ..; rm -rf *; mv ../libmetis.a .
|
||||
#
|
||||
- os: osx
|
||||
# osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: DEBUG=NO
|
||||
MPI=YES
|
||||
CODECOV=YES
|
||||
MFEM_TEST_TARGET=test
|
||||
NPROCS=4
|
||||
TMPDIR=/tmp
|
||||
cache:
|
||||
directories:
|
||||
- $TRAVIS_BUILD_DIR/../hypre-2.10.0b/src/hypre/lib
|
||||
- $TRAVIS_BUILD_DIR/../hypre-2.10.0b/src/hypre/include
|
||||
- $TRAVIS_BUILD_DIR/../metis-4.0
|
||||
- $HOME/local-cached
|
||||
before_cache:
|
||||
- cd $TRAVIS_BUILD_DIR/../metis-4.0;
|
||||
mv libmetis.a ..; rm -rf *; mv ../libmetis.a .
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
env:
|
||||
- DEBUG=YES MPI=YES TMPDIR=/tmp
|
||||
- DEBUG=NO MPI=YES TMPDIR=/tmp
|
||||
- DEBUG=YES MPI=NO
|
||||
- DEBUG=NO MPI=NO
|
||||
|
||||
# Test with GCC on Linux an Clang on Mac
|
||||
matrix:
|
||||
exclude:
|
||||
- compiler: clang
|
||||
os: linux
|
||||
- compiler: gcc
|
||||
os: osx
|
||||
|
||||
before_install:
|
||||
# No addon for brew yet, have to install OSX packages this way.
|
||||
# - if [ $TRAVIS_OS_NAME == "osx" ] && [ $MPI == "YES" ]; then
|
||||
# brew install open-mpi;
|
||||
# fi
|
||||
|
||||
# On Mac OS X, build and cache OpenMPI 2.1.1:
|
||||
- if [ $TRAVIS_OS_NAME == "osx" ] && [ $MPI == "YES" ]; then
|
||||
if [ ! -e $HOME/local-cached/bin/mpicc ]; then
|
||||
mkdir -p $HOME/builds && cd $HOME/builds &&
|
||||
wget https://www.open-mpi.org/software/ompi/v2.1/downloads/openmpi-2.1.1.tar.bz2 &&
|
||||
tar jxf openmpi-2.1.1.tar.bz2 &&
|
||||
mkdir openmpi-build && cd openmpi-build &&
|
||||
../openmpi-2.1.1/configure --prefix=$HOME/local-cached &&
|
||||
make -j3 all && make install;
|
||||
fi;
|
||||
PATH=$HOME/local-cached/bin:$PATH;
|
||||
cd $TRAVIS_BUILD_DIR;
|
||||
fi
|
||||
|
||||
# Update environment to find g++ 4.9 installation first.
|
||||
# - if [ $TRAVIS_OS_NAME == "linux" ]; then
|
||||
# mkdir -p latest-gcc-symlinks;
|
||||
# ln -s /usr/bin/g++-4.9 latest-gcc-symlinks/g++;
|
||||
# ln -s /usr/bin/gcc-4.9 latest-gcc-symlinks/gcc;
|
||||
# ln -s /usr/bin/gcov-4.9 latest-gcc-symlinks/gcov;
|
||||
# export PATH=$PWD/latest-gcc-symlinks:$PATH;
|
||||
# fi
|
||||
|
||||
# Install tool to upload code coverage reports to coveralls.io
|
||||
- if [ "$CODECOV" == "YES" ]; then
|
||||
export PYTHONUSERBASE=$HOME/local;
|
||||
pip install --user cpp-coveralls;
|
||||
pip install --user pyyaml;
|
||||
PATH=$HOME/local/bin:$PATH;
|
||||
fi
|
||||
- if [ $TRAVIS_OS_NAME == "linux" -a "$CXX" == "g++" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
||||
- if [ $TRAVIS_OS_NAME == "linux" ]; then sudo apt-get update; fi || true
|
||||
|
||||
install:
|
||||
# Set MPI compilers, print compiler version
|
||||
- if [ $MPI == "YES" ]; then
|
||||
if [ "$TRAVIS_OS_NAME" == "linux" ]; then
|
||||
export MPICH_CC="$CC";
|
||||
export MPICH_CXX="$CXX";
|
||||
else
|
||||
export OMPI_CC="$CC";
|
||||
export OMPI_CXX="$CXX";
|
||||
mpic++ --showme:version;
|
||||
fi;
|
||||
mpic++ -v;
|
||||
else
|
||||
$CXX -v;
|
||||
fi
|
||||
# g++-4.9
|
||||
- if [ $TRAVIS_OS_NAME == "linux" -a "$CXX" == "g++" ]; then sudo apt-get install -qq g++-4.9; fi
|
||||
- if [ $TRAVIS_OS_NAME == "linux" -a "$CXX" == "g++" ]; then export CXX="g++-4.9"; fi
|
||||
|
||||
# Back out of the mfem directory to install the libraries
|
||||
- cd ..
|
||||
|
||||
# OpenMPI
|
||||
- if [ $TRAVIS_OS_NAME == "linux" ]; then
|
||||
sudo apt-get install openmpi-bin openmpi-common openssh-client openssh-server libopenmpi1.3 libopenmpi-dbg libopenmpi-dev;
|
||||
else
|
||||
travis_wait brew install open-mpi;
|
||||
fi
|
||||
|
||||
# hypre
|
||||
- if [ $MPI == "YES" ]; then
|
||||
if [ ! -e hypre-2.10.0b/src/hypre/lib/libHYPRE.a ]; then
|
||||
wget https://computation.llnl.gov/project/linear_solvers/download/hypre-2.10.0b.tar.gz --no-check-certificate;
|
||||
rm -rf hypre-2.10.0b;
|
||||
tar xvzf hypre-2.10.0b.tar.gz;
|
||||
cd hypre-2.10.0b/src;
|
||||
./configure --disable-fortran --without-fei CC=mpicc CXX=mpic++;
|
||||
make -j3;
|
||||
cd ../..;
|
||||
if [ ! -d hypre-2.10.0b ]; then
|
||||
wget https://computation.llnl.gov/project/linear_solvers/download/hypre-2.10.0b.tar.gz --no-check-certificate;
|
||||
tar xvzf hypre-2.10.0b.tar.gz;
|
||||
cd hypre-2.10.0b/src;
|
||||
./configure --disable-fortran --without-fei CC=mpicc CXX=mpic++;
|
||||
make -j 4;
|
||||
cd ../..;
|
||||
else
|
||||
echo "Reusing cached hypre-2.10.0b/";
|
||||
fi;
|
||||
@@ -210,54 +58,43 @@ install:
|
||||
fi
|
||||
|
||||
# METIS
|
||||
- if [ $MPI == "YES" ]; then
|
||||
if [ ! -e metis-4.0/libmetis.a ]; then
|
||||
wget http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/OLD/metis-4.0.3.tar.gz;
|
||||
tar xvzf metis-4.0.3.tar.gz;
|
||||
make -j3 -C metis-4.0.3/Lib CC="$CC" OPTFLAGS="-O2";
|
||||
rm -rf metis-4.0;
|
||||
mv metis-4.0.3 metis-4.0;
|
||||
else
|
||||
echo "Reusing cached metis-4.0/";
|
||||
fi;
|
||||
- if [ ! -d metis-4.0 ]; then
|
||||
wget http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/OLD/metis-4.0.3.tar.gz;
|
||||
tar xvzf metis-4.0.3.tar.gz;
|
||||
cd metis-4.0.3;
|
||||
make -j 4;
|
||||
cd ..;
|
||||
mv metis-4.0.3 metis-4.0;
|
||||
else
|
||||
echo "Reusing cached metis-4.0/";
|
||||
fi
|
||||
|
||||
# # Delete an expired cache here: https://travis-ci.org/mfem/mfem/caches
|
||||
# cache:
|
||||
# directories:
|
||||
# - $TRAVIS_BUILD_DIR/../hypre-2.10.0b
|
||||
# - $TRAVIS_BUILD_DIR/../metis-4.0
|
||||
|
||||
script:
|
||||
# Compiler
|
||||
- if [ $MPI == "YES" ]; then
|
||||
export MYCXX=mpic++;
|
||||
export OMPI_CXX="$CXX";
|
||||
$MYCXX --showme:version;
|
||||
else
|
||||
export MYCXX="$CXX";
|
||||
fi
|
||||
|
||||
# Print the compiler version
|
||||
- $MYCXX -v
|
||||
|
||||
# Set some variables
|
||||
- cd $TRAVIS_BUILD_DIR;
|
||||
CPPFLAGS="";
|
||||
SKIP_TEST_DIRS="";
|
||||
if [ "$CODECOV" == "YES" ]; then
|
||||
CPPFLAGS="--coverage -g";
|
||||
fi;
|
||||
if [ "$CXX" == "clang++" ]; then
|
||||
export MFEM_PERF_SW=clang;
|
||||
fi
|
||||
|
||||
# Configure the library
|
||||
- make config MFEM_USE_MPI=$MPI MFEM_DEBUG=$DEBUG MFEM_CXX="$MYCXX"
|
||||
MFEM_MPI_NP=$NPROCS CPPFLAGS="$CPPFLAGS"
|
||||
# Show the configuration
|
||||
- make info
|
||||
# Build the library
|
||||
- make -j3
|
||||
# Build the examples and the miniapps
|
||||
- make -j3 all
|
||||
# Run tests
|
||||
- make $MFEM_TEST_TARGET SKIP_TEST_DIRS="$SKIP_TEST_DIRS"
|
||||
|
||||
after_success:
|
||||
- if [ "$CODECOV" == "YES" ]; then
|
||||
coveralls --include fem --include general --include linalg --include
|
||||
mesh --exclude /usr --gcov-options '\-lp' --root $TRAVIS_BUILD_DIR;
|
||||
# Build the code and do a quick check (debug mode) or a full tests run (non-debug mode)
|
||||
- if [ $DEBUG == "NO" ]; then
|
||||
export MFEM_TEST_TARGET="test";
|
||||
else
|
||||
export MFEM_TEST_TARGET="check";
|
||||
fi
|
||||
# Build and check/test MFEM, its examples and miniapps
|
||||
- cd $TRAVIS_BUILD_DIR &&
|
||||
make config MFEM_USE_MPI=$MPI MFEM_DEBUG=$DEBUG MFEM_CXX="$MYCXX" &&
|
||||
make info &&
|
||||
make all -j 4 &&
|
||||
make $MFEM_TEST_TARGET
|
||||
|
||||
@@ -8,462 +8,16 @@
|
||||
http://mfem.org
|
||||
|
||||
|
||||
Version 4.0-RC1, Apr 11, 2019
|
||||
=============================
|
||||
|
||||
Requirements and Limitations
|
||||
----------------------------
|
||||
- This is a release candidate for mfem-4.0.
|
||||
- Use at your own risk -- not everything will work, the API may change.
|
||||
- We are looking for feedback from friendly users.
|
||||
- Unlike previous MFEM releases, this version requires a C++11 compiler.
|
||||
|
||||
- GPU-related limitations:
|
||||
* NVCC is not supported in the CMake build system yet.
|
||||
* Element batching is currently ignored.
|
||||
* Full-assembly (on device), element assembly, and matrix-free bilinear forms
|
||||
are not supported yet.
|
||||
* FunctionCoefficients do not currently work on GPUs.
|
||||
* Partial assembly kernels are not implemented yet for simplices.
|
||||
|
||||
GPU support
|
||||
-----------
|
||||
- Added initial support for hardware devices, such as GPUs, and programming
|
||||
models, such as CUDA, OCCA, RAJA and OpenMP.
|
||||
|
||||
- The GPU/device support is based on MFEM's new backends and kernels working
|
||||
seamlessly with a new lightweight device/host memory manager. The kernels can
|
||||
be implemented either in OCCA, or as a simple wrapper around for-loops, which
|
||||
can then be dispatched to RAJA and native backends. See the files forall.hpp
|
||||
and mem_manager.hpp in the general/ directory.
|
||||
|
||||
- Several of the MFEM example codes (ex1, ex1p, ex6, and ex6p) can now take
|
||||
advantage of GPU acceleration with the backend selectable at runtime. Many of
|
||||
the linear algebra and finite element operations (e.g. partially assembled
|
||||
bilinear forms) have been extended to take advantage of kernel acceleration by
|
||||
simply replacing loops with the MFEM_FORALL() macro.
|
||||
|
||||
- In addition to pure CUDA, the library currently supports OCCA, RAJA and OpenMP
|
||||
kernels, which could be mixed and matched in different parts of the same
|
||||
application. We plan on adding support for more programming models and devices
|
||||
in the future, without the need for significant modifications in user code.
|
||||
The list of current backends is: "occa-cuda", "raja-cuda", "cuda", "occa-omp",
|
||||
"raja-omp", "omp", "occa-cpu", "raja-cpu", and "cpu".
|
||||
|
||||
Discretization improvements
|
||||
---------------------------
|
||||
- Added support for a general "low-order refined"-to-"high-order" transfer of
|
||||
GridFunction data from a "low-order refined" (LOR) space defined on a refined
|
||||
mesh to a "high-order" (HO) finite element space defined on a coarse mesh. See
|
||||
the new classes InterpolationGridTransfer and L2ProjectionGridTransfer and the
|
||||
new LOR Transfer miniapp: miniapps/tools/lor-transfer.cpp.
|
||||
|
||||
- Added support for derefinement of vector (RT + ND) spaces.
|
||||
|
||||
- Added element flux, and flux energy computation in class ElasticityIntegrator,
|
||||
allowing for the use of Zienkiewicz-Zhu type error estimators with the
|
||||
integrator. For an illustration of this addition, see the new Example 22.
|
||||
|
||||
- Added a variety of coefficients which are sums or products of existing
|
||||
coefficients as well as grid function coefficients which return the
|
||||
divergence, gradient, or curl of their GridFunctions.
|
||||
|
||||
Support for wedge elements and meshes with mixed element types
|
||||
--------------------------------------------------------------
|
||||
- Added support for wedge-shaped mesh elements of arbitrary order (with Geometry
|
||||
type PRISM) which have two triangular faces and three quadrilateral faces.
|
||||
Several examples of such meshes can be found in the data/ directory.
|
||||
|
||||
- Added H1 and L2 finite elements of arbitrary order for Wedge elements.
|
||||
|
||||
- Added support for mixed meshes containing triangles and quadrilaterals in 2D
|
||||
or tetrahedra, wedges, and hexahedra in 3D. This includes support for uniform
|
||||
refinement of such meshes. Several examples of such meshes can be found in the
|
||||
data/ directory.
|
||||
|
||||
- Added support for reading and writing linear and quadratic meshes containing
|
||||
wedge elements in VTK mesh format. Several examples of such meshes can be
|
||||
found in the data/ directory.
|
||||
|
||||
Other meshing improvements
|
||||
--------------------------
|
||||
- Improved the uniform refinement of tetrahedral meshes (also part of the
|
||||
uniform refinement of mixed 3D meshes). The previous refinement algorithm is
|
||||
still available as an option in Mesh::UniformRefinement. Both can be used in
|
||||
the updated Mesh Explorer miniapp.
|
||||
|
||||
- The local tetrahedral mesh refinement algorithm in serial and in parallel now
|
||||
follows precisely the paper:
|
||||
|
||||
D. Arnold, A. Mukherjee, and L. Pouly, "Locally Adapted Tetrahedral Meshes
|
||||
Using Bisection", SIAM J. Sci. Comput. 22 (2000), 431–448.
|
||||
|
||||
This guarantees that the shape regularity of the elements will be preserved
|
||||
under refinement.
|
||||
|
||||
- Added support for parallel communication groups on non-conforming meshes.
|
||||
|
||||
- Improved parallel partitioning of non-conforming meshes. If the coarse mesh
|
||||
elements are ordered as a sequence of face-neighbors, the parallel partitions
|
||||
are now guaranteed to be continuous. To that end, inline quadrilateral and
|
||||
hexahedral meshes are now by default ordered along a space-filling curve.
|
||||
|
||||
- A boundary in a NURBS mesh can now be connected with another boundary. Such a
|
||||
periodic NURBS mesh is a simple way to impose periodic boundary conditions.
|
||||
|
||||
- Added support for reading linear and quadratic 2D quadrilateral and triangular
|
||||
Cubit meshes.
|
||||
|
||||
- The TMOP mesh optimization algorithms were extended to support user-defined
|
||||
space-dependent limiting terms. Improved the TMOP objective functions by more
|
||||
accurate normalization of the different terms.
|
||||
|
||||
New and updated examples and miniapps
|
||||
-------------------------------------
|
||||
- Added a new meshing miniapp, Toroid, which can produce a variety of torus
|
||||
shaped meshes by twisting a stack of wedges or hexahedra.
|
||||
|
||||
- Added a new meshing miniapp, Extruder, that demonstrates the capability to
|
||||
produce 3D meshes by extruding 2D meshes.
|
||||
|
||||
- Added a simple miniapp, LOR Transfer, for visualizing the actions of the
|
||||
transfer operators between a high-order and a low-order refined spaces.
|
||||
|
||||
- Added a new example, Example 20/20p, that solves a system of 1D ODEs derived
|
||||
from a Hamiltonian. The example demonstrates the use of the variable order,
|
||||
symplectic integration algorithm implemented in class SIAVSolver.
|
||||
|
||||
- Added a new example, Example 22/22p, that illustrates the use of AMR to solve
|
||||
a linear elasticity problem. This is an extension of Example 2/2p.
|
||||
|
||||
New and improved solvers and preconditioners
|
||||
--------------------------------------------
|
||||
- Added support for parallel ILU preconditioning via hypre's Euclid solver.
|
||||
|
||||
- Added support for STRUMPACK v3 with a small API change in the class
|
||||
STRUMPACKSolver, see "API changes" below.
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
- Added unit tests based on the Catch++ library.
|
||||
|
||||
- Renamed the option MFEM_USE_OPENMP to MFEM_USE_LEGACY_OPENMP. This legacy
|
||||
option is deprecated and planned for removal in a future release. The original
|
||||
option name, MFEM_USE_OPENMP, is now used to enable the new OpenMP backends in
|
||||
the new kernels.
|
||||
|
||||
- Altered the way FGMRES counts its iterations so that it matches GMRES.
|
||||
|
||||
- Various other simplifications, extensions, and bugfixes in the code.
|
||||
|
||||
API changes
|
||||
-----------
|
||||
- In multiple places, use Geometry::Type instead of int, where appropriate.
|
||||
- In multiple places, use Element::Type instead of int, where appropriate.
|
||||
- The Mesh methods GetElementBaseGeometry and GetBdrElementBaseGeometry no
|
||||
longer have a default value for their parameter, they only work with an
|
||||
explicitly given index.
|
||||
- In class Mesh, added methods useful for queries regarding the types of
|
||||
elements present in the mesh: HasGeometry, GetNumGeometries, GetGeometries,
|
||||
and class Mesh::GeometryList.
|
||||
- The struct CoarseFineTransformations (returned by the Mesh method
|
||||
GetRefinementTransforms) now stores the embedding matrices separately for each
|
||||
Geometry::Type.
|
||||
- In class ParMesh, replaced the method GroupNFaces with two new methods:
|
||||
GroupNTriangles and GroupNQuadrilaterals. Also, replaced GroupFace with two
|
||||
methods: GroupTriangle and GroupQuadrilateral.
|
||||
- In class ParMesh, made the two RefineGroups methods protected.
|
||||
- Removed the virtual method Element::GetRefinementFlag, it is only used by the
|
||||
derived class Tetrahedron.
|
||||
- Added new methods: Array::CopyTo, Tetrahedron::Init.
|
||||
- In class STRUMPACKSolver, the method SetMC64Job() was replaced by the new
|
||||
methods: DisableMatching(), EnableMatching(), and EnableParallelMatching().
|
||||
|
||||
|
||||
Version 3.4, released on May 29, 2018
|
||||
Development version, not released yet
|
||||
=====================================
|
||||
|
||||
More general and efficient mesh adaptivity
|
||||
------------------------------------------
|
||||
- Added support for PUMI, the Parallel Unstructured Mesh Infrastructure from
|
||||
https://scorec.rpi.edu/pumi. PUMI is an unstructured, distributed mesh data
|
||||
management system that is capable of handling general non-manifold models and
|
||||
effectively supports automated adaptive analysis. PUMI enables for the first
|
||||
time support for parallel unstructured modifications of MFEM meshes.
|
||||
|
||||
- Significantly reduced MPI communication in the construction of the parallel
|
||||
prolongation matrix in ParFiniteElementSpace, for much improved parallel
|
||||
scaling of non-conforming AMR on hundreds of thousands of MPI tasks. The
|
||||
memory footprint of the ParNCMesh class has also been reduced.
|
||||
|
||||
- In FiniteElementSpace, the fully assembled refinement matrix is now replaced
|
||||
by default by a specialized refinement operator. The operator option is both
|
||||
faster and more memory efficient than using the fully assembled matrix. The
|
||||
old approach is still available and can be enabled, if needed, using the new
|
||||
method FiniteElementSpace::SetUpdateOperatorType().
|
||||
|
||||
Discretization improvements
|
||||
---------------------------
|
||||
- Added support for a general "high-order"-to-"low-order refined" transfer of
|
||||
GridFunction and true-dof data from a "high-order" finite element space
|
||||
defined on a coarse mesh, to a "low-order refined" space defined on a refined
|
||||
mesh. The new methods, GetTransferOperator and GetTrueTransferOperator in the
|
||||
FiniteElementSpace classes, work in both serial and parallel and support
|
||||
matrix-based as well as matrix-free transfer operator representations. They
|
||||
use a new method, GetTransferMatrix, in the FiniteElement class similar to
|
||||
GetLocalInterpolation, that allows the coarse FiniteElement to be different
|
||||
from the fine FiniteElement.
|
||||
|
||||
- Added class ComplexOperator, that implements the action of a complex operator
|
||||
through the equivalent 2x2 real formulation. Both symmetric and antisymmetric
|
||||
block structures are supported.
|
||||
|
||||
- Added classes for general block nonlinear finite element operators (deriving
|
||||
from BlockNonlinearForm and ParBlockNonlinearForm) enabling solution of
|
||||
nonlinear systems with multiple unknowns in different function spaces. Such
|
||||
operators have assemble-based action and also support assembly of the gradient
|
||||
operator to enable inversion with Newton iteration.
|
||||
|
||||
- Added variable order NURBS: for each space each knot vector in the mesh can
|
||||
have a different order. The order information is now part of the finite
|
||||
element space header in the NURBS mesh output, so NURBS meshes in the old
|
||||
format need to be updated.
|
||||
|
||||
- In the classes NonlinearForm and ParNonlinearForm, added support for
|
||||
non-conforming AMR meshes; see also the "API changes" section.
|
||||
|
||||
- New specialized time integrators: symplectic integrators of orders 1-4 for
|
||||
systems of first order ODEs derived from a Hamiltonian and generalized-alpha
|
||||
ODE solver for the filtered Navier–Stokes equations with stabilization. See
|
||||
classes SIASolver and GeneralizedAlphaSolver in linalg/ode.hpp.
|
||||
|
||||
- Inherit finite element classes from the new base class TensorBasisElement,
|
||||
whenever the basis can be represented by a tensor product of 1D bases.
|
||||
|
||||
- Added support for elimination of boundary conditions in block matrices.
|
||||
|
||||
New and updated examples and miniapps
|
||||
-------------------------------------
|
||||
- Added a new serial and parallel example (ex19) that solves the quasi-static
|
||||
incompressible hyperelastic equations. The example demonstrates the use of
|
||||
block nonlinear forms as well as custom block preconditioners.
|
||||
|
||||
- Added a new electromagnetics miniapp, Maxwell, for simulating time-domain
|
||||
electromagnetics phenomena as a coupled first order system of equations.
|
||||
|
||||
- A simple local refinement option has been added to the mesh-explorer miniapp
|
||||
(menu option 'r', sub-option 'l') that selects elements for refinement based
|
||||
on their spatial location - see the function 'region()' in the source file.
|
||||
|
||||
- Added a set of miniapps specifically focused on Isogeometric Analysis (IGA) on
|
||||
NURBS meshes in the miniapps/nurbs directory. Currently the directory contains
|
||||
variable order NURBS versions of examples 1, 1p and 11p.
|
||||
|
||||
- Added PUMI versions of examples ex1, ex1p, ex2 and ex6p in a new examples/pumi
|
||||
directory. The new examples demonstrate the PUMI APIs for parallel and serial
|
||||
mesh loading (ex1 and ex1p), applying BCs using classification (ex2), and
|
||||
performing parallel mesh adaptation (ex6p).
|
||||
|
||||
- Added two new miniapps related to DataCollection I/O in miniapps/tools:
|
||||
load-dc.cpp can be used to visualize fields saved via DataCollection classes;
|
||||
convert-dc.cpp demonstrates how to convert between MFEM's different concrete
|
||||
DataCollection options.
|
||||
|
||||
- Example 10p with its SUNDIALS and PETSc versions have been updated to reflect
|
||||
the change in the behavior of the method ParNonlinearForm::GetLocalGradient()
|
||||
(see the "API changes" section) and now works correctly on non-conforming AMR
|
||||
meshes. Example 10 and its SUNDIALS version have also been updated to support
|
||||
non-conforming ARM meshes.
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
- Documented project workflow and provided contribution guidelines in the new
|
||||
top-level file, CONTRIBUTING.md.
|
||||
|
||||
- Added (optional) Conduit Mesh Blueprint support of MFEM data for both in-core
|
||||
and I/O use cases. This includes a new ConduitDataCollection that provides
|
||||
json, simple binary, and HDF5-based I/O. Support requires Conduit >= v0.3.1
|
||||
and VisIt >= v2.13.1 will read the new Data Collection outputs.
|
||||
|
||||
- Added a new developer tool, config/sample-runs.sh, that extracts the sample
|
||||
runs from all examples and miniapps and runs them. Optionally, it can save the
|
||||
output from the execution to files, allowing comparison between different
|
||||
versions and builds of the library.
|
||||
|
||||
- Support for building a shared version of the MFEM library with GNU make.
|
||||
|
||||
- Added a build option, MFEM_USE_EXCEPTIONS=YES, to throw an exception instead
|
||||
of calling abort on mfem errors.
|
||||
|
||||
- When building with the GnuTLS library, switch to using X.509 certificates for
|
||||
secure socket authentication. Support for the previously used OpenPGP keys has
|
||||
been deprecated in GnuTLS 3.5.x and removed in 3.6.0. For secure communication
|
||||
with the visualization tool GLVis, a new set of certificates can be generated
|
||||
using the latest version of the script 'glvis-keygen.sh' from GLVis.
|
||||
|
||||
- Upgraded MFEM to support Axom 0.2.8. Prior versions are no longer supported.
|
||||
|
||||
API changes
|
||||
-----------
|
||||
- Introduced a new enum, Matrix::DiagonalPolicy, that replaces the integer
|
||||
parameters in many methods that perform elimination of rows and/or columns in
|
||||
matrices. Some examples of such methods are:
|
||||
* class SparseMatrix: EliminateRow(), EliminateCol(), EliminateRowCol(), ...
|
||||
* class BilinearForm: EliminateEssentialBC(), EliminateVDofs(), ...
|
||||
* class StaticCondensation: EliminateReducedTrueDofs()
|
||||
* class BlockMatrix: EliminateRowCol()
|
||||
Calling these methods with an explicitly given (integer) constants, will now
|
||||
generate compilation errors, please use one of the new enum constants instead.
|
||||
|
||||
- Modified the virtual method AbstractSparseMatrix::EliminateZeroRows() and its
|
||||
implementations in derived classes, to accept an optional 'threshold'
|
||||
parameter, replacing previously hard-coded threshold values.
|
||||
|
||||
- In the classes NonlinearForm and ParNonlinearForm:
|
||||
* The method GetLocalGradient() no longer imposes boundary conditions. The
|
||||
motivation for the change is that, in the case of non-conforming AMR,
|
||||
performing the elimination at the local level is incorrect - it must be
|
||||
applied at the true-dof level.
|
||||
* The method SetEssentialVDofs() is now deprecated.
|
||||
|
||||
|
||||
Version 3.3.2, released on Nov 10, 2017
|
||||
=======================================
|
||||
|
||||
High-order mesh optimization
|
||||
----------------------------
|
||||
- Added support for mesh optimization via node-movement based on the Target-
|
||||
Matrix Optimization Paradigm (TMOP) developed by P.Knupp et al. A variety of
|
||||
mesh quality metrics, with their first and second derivatives have been
|
||||
implemented. The combination of targets & quality metrics is used to optimize
|
||||
the physical node positions, i.e., they must be as close as possible to the
|
||||
shape, size and/or alignment of their targets. The optimization of arbitrary
|
||||
high-order meshes in 2D, 3D, serial and parallel is supported.
|
||||
|
||||
- The new Mesh Optimizer miniapp can be used to perform mesh optimization with
|
||||
TMOP in serial and parallel versions. The miniapp also demonstrates the use of
|
||||
nonlinear operators and their coupling to Newton methods for solving
|
||||
minimization problems.
|
||||
|
||||
New and improved solvers and preconditioners
|
||||
--------------------------------------------
|
||||
- MFEM is now included in the xSDK project, the Extreme-scale Scientific
|
||||
Software Development Kit, as of xSDK-0.3.0. Various changes were made to
|
||||
comply with xSDK's community policies, https://xsdk.info/policies, including:
|
||||
xSDK-specific options in CMake, support for user-provided MPI communicators,
|
||||
runtime API for version number, and the ability to disable/redirect output.
|
||||
For more details, see general/globals.hpp and in particular the mfem::err and
|
||||
mfem::out streams replacing std::err and std::out respectively.
|
||||
|
||||
- Added (optional) support for the STRUMPACK parallel sparse direct solver and
|
||||
preconditioner. STRUMPACK uses Hierarchically Semi-Separable (HSS) compression
|
||||
in a fully algebraic manner, with interface similar to SuperLU_DIST. See
|
||||
http://portal.nersc.gov/project/sparse/strumpack for more details.
|
||||
|
||||
- Added a block lower triangular preconditioner based (only) on the actions of
|
||||
each block, see class BlockLowerTriangularPreconditioner.
|
||||
|
||||
- Added an optional operator in LOBPCG to projects vectors onto a desired
|
||||
subspace (e.g. divergence-free). Other small changes in LOBPCG include the
|
||||
ability to set the starting vectors and support for relative tolerance.
|
||||
|
||||
- The Newton solver supports an optional scaling factor, that can limit the
|
||||
increment in the Newton step, see e.g. the Mesh Optimizer miniapp.
|
||||
|
||||
- Updated MFEM integration to support the new SUNDIALS 3.0.0 interface.
|
||||
|
||||
New and updated examples and miniapps
|
||||
-------------------------------------
|
||||
- Added a new serial and parallel example (ex18) that solves the transient Euler
|
||||
equations on a periodic domain with explicit time integrators. In the process
|
||||
extended the NonlinearForm class to allow for integrals over faces and
|
||||
exchanging face-neighbor data in parallel.
|
||||
|
||||
- Added a new meshing miniapp, Shaper, that can be used to resolve complicated
|
||||
material interfaces by mesh refinement, e.g. as a tool for initial mesh
|
||||
generation from prescribed "material()" function. Both conforming and
|
||||
non-conforming (isotropic and anisotropic) refinements are supported.
|
||||
|
||||
- Added a new meshing miniapp, Mesh Optimizer, that demonstrates the use of TMOP
|
||||
for mesh optimization (serial and parallel version.)
|
||||
|
||||
- Added SUNDIALS version of Example 16/16p.
|
||||
|
||||
Discretization improvements
|
||||
---------------------------
|
||||
- Added a FindPoints method of the Mesh and ParMesh classes that returns the
|
||||
elements that contain a given set of points, together with the coordinates of
|
||||
the points in the reference space of the corresponding element. In parallel,
|
||||
if a point is shared by multiple processors, only one of them will mark that
|
||||
point as found. Note that the current implementation of this method is not
|
||||
optimal and/or 100% reliable. See the mesh-explorer miniapp for an example.
|
||||
|
||||
- Added a new class InverseElementTransformation, that supports a number of
|
||||
algorithms for inversion of general ElementTransformations. This class can be
|
||||
used as a more flexible and extensible alternative to ElementTransformation's
|
||||
TransformBack method. It is also used in the FindPoints methods as a tunable
|
||||
and customizable inversion algorithm.
|
||||
|
||||
- Memory optimizations in the NCMesh class, which now uses 50% less memory than
|
||||
before. The average cost of an element in a uniformly refined mesh (including
|
||||
the refinement hierarchy, but excluding the temporary face_list and edge_list)
|
||||
- Memory optimizations in the NCMesh class, which now uses 50% less memory.
|
||||
The average cost of an NC element in a uniformly refined mesh (including the
|
||||
refinement hierarchy, but excluding the temporary face_list and edge_list)
|
||||
is now only about 290 bytes. This also makes the class faster.
|
||||
|
||||
- Added the ability to integrate delta functions on the right-hand side (by
|
||||
sampling the test function at the center of the delta coefficient). Currently
|
||||
this is supported in the DomainLFIntegrator, VectorDomainLFIntegrator and
|
||||
VectorFEDomainLFIntegrator classes.
|
||||
|
||||
- Added five new linear interpolators in fem/bilininteg.cpp to compute products
|
||||
of scalar and vector fields or products with arbitrary coefficients.
|
||||
|
||||
- Added matrix coefficient support to CurlCurlIntegrator.
|
||||
|
||||
- Extend the method NodalFiniteElement::Project for VectorCoefficient to work
|
||||
with arbitrary number of vector components.
|
||||
|
||||
Miscellaneous
|
||||
-------------
|
||||
- Added a .gitignore file that ignores all files erased by "make distclean",
|
||||
i.e. the files that can be generated from the source but we don't want to
|
||||
track in the repository, as well as a few platform-specific files.
|
||||
|
||||
- Added Linux, Mac and Windows CI testing on GitHub with Travis CI and Appveyor.
|
||||
|
||||
- Added a new macro, MFEM_VERSION, defined as a single integer of the form
|
||||
(major*100 + minor)*100 + patch. The convention is that an even number
|
||||
(i.e. even patch number) denotes a "release" version, while an odd number
|
||||
denotes a "development" version. See config/config.hpp.in.
|
||||
|
||||
- Added an option for building in parallel without a METIS dependency. This is
|
||||
used for example the Laghos miniapp, https://github.com/CEED/Laghos.
|
||||
|
||||
- Modified the installation layout: all headers, except the master headers
|
||||
(mfem.hpp and mfem-performance.hpp), are installed in <PREFIX>/include/mfem;
|
||||
the master headers are installed in both <PREFIX>/include/mfem and in
|
||||
<PREFIX>/include. The mfem configuration and testing makefiles (config.mk and
|
||||
test.mk) are installed in <PREFIX>/share/mfem, instead of <PREFIX>.
|
||||
|
||||
- Add three more options for MFEM_TIMER_TYPE.
|
||||
|
||||
- Support independent number of digits for cycle and rank in DataCollection.
|
||||
|
||||
- Converted Sidre usage from "asctoolkit" to "axom" namespace.
|
||||
|
||||
- Various small fixes and styling updates.
|
||||
|
||||
API changes
|
||||
-----------
|
||||
- The methods GetCoeff of VectorArrayCoefficient and MatrixArrayCoefficient now
|
||||
return a pointer to Coefficient (instead of reference). Note that NULL pointer
|
||||
is a valid entry for these two classes - it is treated as the zero function.
|
||||
|
||||
- When building with PETSc, the required PETSc version is now 3.8.0. Newer
|
||||
versions may work too, as long as there are no interface changes in PETSc.
|
||||
|
||||
- The class GeometryRefiner now uses the enum in Quadrature1D for its type
|
||||
specification. In particular, this will affect older versions of GLVis. A
|
||||
simple upgrade to the latest version of GLVis should resolve this issue.
|
||||
- Add a block lower triangular preconditioner in using a matrix-free
|
||||
implementation, see class BlockLowerTriangularPreconditioner.
|
||||
|
||||
|
||||
Version 3.3, released on Jan 28, 2017
|
||||
@@ -619,7 +173,7 @@ Improved file output
|
||||
- Added experimental support for an HDF5-based output file format following the
|
||||
Conduit (https://github.com/LLNL/conduit) mesh blueprint specification for
|
||||
visualization and/or restart capability. This functionality is aimed primarily
|
||||
at user of LLNL's axom project (Sidre component) that run problems at extreme
|
||||
at user of LLNL's ASC Toolkit (Sidre component) that run problems at extreme
|
||||
scales. Users desiring a small scale binary format may want to look at the
|
||||
gzstream functionality instead.
|
||||
|
||||
|
||||
@@ -13,11 +13,6 @@ cmake_minimum_required(VERSION 2.8.11)
|
||||
set(USER_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/config/user.cmake" CACHE PATH
|
||||
"Path to optional user configuration file.")
|
||||
|
||||
# Require C++11 and disable compiler-specific extensions
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# Load user settings before the defaults - this way the defaults will not
|
||||
# overwrite the user set options. If the user has not set all options, we still
|
||||
# have the defaults.
|
||||
@@ -43,14 +38,8 @@ if (NOT CMAKE_CXX_COMPILER)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Project name and version
|
||||
#-------------------------------------------------------------------------------
|
||||
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 3.4.1)
|
||||
project(mfem CXX)
|
||||
set(${PROJECT_NAME}_VERSION 3.3)
|
||||
|
||||
# Prohibit in-source build
|
||||
if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
|
||||
@@ -58,65 +47,18 @@ if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
|
||||
"MFEM does not support in-source CMake builds at this time.")
|
||||
endif (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
|
||||
|
||||
# Set xSDK defaults.
|
||||
set(USE_XSDK_DEFAULTS_DEFAULT OFF)
|
||||
set(XSDK_ENABLE_CXX ON)
|
||||
set(XSDK_ENABLE_C OFF)
|
||||
set(XSDK_ENABLE_Fortran OFF)
|
||||
|
||||
# Check if we need to enable C or Fortran.
|
||||
if (CMAKE_VERSION VERSION_LESS 3.2 OR
|
||||
MFEM_USE_CONDUIT OR
|
||||
MFEM_USE_SIDRE OR
|
||||
MFEM_USE_PETSC)
|
||||
if (CMAKE_VERSION VERSION_LESS 3.2 OR MFEM_USE_SIDRE)
|
||||
# This seems to be needed by:
|
||||
# * find_package(BLAS REQUIRED) and
|
||||
# * find_package(HDF5 REQUIRED) needed, in turn, by:
|
||||
# - find_package(AXOM REQUIRED)
|
||||
# * find_package(PETSc REQUIRED)
|
||||
set(XSDK_ENABLE_C ON)
|
||||
endif()
|
||||
if (MFEM_USE_STRUMPACK)
|
||||
# Just needed to find the MPI_Fortran libraries to link with
|
||||
set(XSDK_ENABLE_Fortran ON)
|
||||
endif()
|
||||
|
||||
# Include xSDK default CMake file.
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/config/XSDKDefaults.cmake")
|
||||
|
||||
# Enable languages.
|
||||
enable_language(CXX)
|
||||
if (XSDK_ENABLE_C)
|
||||
# - find_package(ATK REQUIRED)
|
||||
enable_language(C)
|
||||
endif()
|
||||
if (XSDK_ENABLE_Fortran)
|
||||
enable_language(Fortran)
|
||||
endif()
|
||||
|
||||
# Suppress warnings about MACOSX_RPATH
|
||||
set(CMAKE_MACOSX_RPATH OFF CACHE BOOL "")
|
||||
|
||||
# CMake needs to know where to find things
|
||||
set(MFEM_CMAKE_PATH ${PROJECT_SOURCE_DIR}/config)
|
||||
set(CMAKE_MODULE_PATH ${MFEM_CMAKE_PATH}/cmake/modules)
|
||||
|
||||
# Load MFEM CMake utilities.
|
||||
include(MfemCmakeUtilities)
|
||||
|
||||
string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UC)
|
||||
mfem_version_to_int(${${PROJECT_NAME}_VERSION} ${PROJECT_NAME_UC}_VERSION)
|
||||
set(${PROJECT_NAME_UC}_VERSION_STRING ${${PROJECT_NAME}_VERSION})
|
||||
if (EXISTS ${PROJECT_SOURCE_DIR}/.git)
|
||||
execute_process(
|
||||
COMMAND git describe --all --long --abbrev=40 --dirty --always
|
||||
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE ${PROJECT_NAME_UC}_GIT_STRING
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
if (NOT ${PROJECT_NAME_UC}_GIT_STRING)
|
||||
set(${PROJECT_NAME_UC}_GIT_STRING "(unknown)")
|
||||
endif()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Process configuration options
|
||||
#-------------------------------------------------------------------------------
|
||||
@@ -128,23 +70,25 @@ else()
|
||||
set(MFEM_DEBUG OFF)
|
||||
endif()
|
||||
|
||||
# MPI -> hypre; PETSc (optional)
|
||||
# MPI -> hypre, METIS
|
||||
if (MFEM_USE_MPI)
|
||||
find_package(MPI REQUIRED)
|
||||
set(MPI_CXX_INCLUDE_DIRS ${MPI_CXX_INCLUDE_PATH})
|
||||
# Parallel MFEM depends on hypre
|
||||
include_directories(${MPI_CXX_INCLUDE_PATH})
|
||||
# Parallel MFEM depends on hypre and METIS
|
||||
find_package(HYPRE REQUIRED)
|
||||
set(MFEM_HYPRE_VERSION ${HYPRE_VERSION})
|
||||
include_directories(${HYPRE_INCLUDE_DIRS})
|
||||
find_package(METIS REQUIRED)
|
||||
include_directories(${METIS_INCLUDE_DIRS})
|
||||
if (MFEM_USE_PETSC)
|
||||
find_package(PETSc REQUIRED)
|
||||
message(STATUS "Found PETSc version ${PETSC_VERSION}")
|
||||
if (PETSC_VERSION AND (PETSC_VERSION VERSION_LESS 3.8.0))
|
||||
message(FATAL_ERROR "PETSc version >= 3.8.0 is required")
|
||||
if (PETSC_VERSION AND (PETSC_VERSION VERSION_LESS 3.7.5.99))
|
||||
message(FATAL_ERROR "PETSc version >= 3.7.5.99 is required")
|
||||
endif()
|
||||
set(PETSC_INCLUDE_DIRS ${PETSC_INCLUDES})
|
||||
include_directories(${PETSC_INCLUDES})
|
||||
endif()
|
||||
else()
|
||||
set(PKGS_NEED_MPI SUPERLU PETSC STRUMPACK PUMI)
|
||||
set(PKGS_NEED_MPI SUPERLU PETSC)
|
||||
foreach(PKG IN LISTS PKGS_NEED_MPI)
|
||||
if (MFEM_USE_${PKG})
|
||||
message(STATUS "Disabling package ${PKG} - requires MPI")
|
||||
@@ -153,19 +97,17 @@ else()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if (MFEM_USE_METIS)
|
||||
find_package(METIS REQUIRED)
|
||||
endif()
|
||||
|
||||
# GZSTREAM -> zlib
|
||||
if (MFEM_USE_GZSTREAM)
|
||||
find_package(ZLIB REQUIRED)
|
||||
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Backtrace with libunwind
|
||||
if (MFEM_USE_LIBUNWIND)
|
||||
set(MFEMBacktrace_REQUIRED_PACKAGES "Libunwind" "LIBDL" "CXXABIDemangle")
|
||||
find_package(MFEMBacktrace REQUIRED)
|
||||
include_directories(${LIBUNWIND_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# BLAS, LAPACK
|
||||
@@ -175,17 +117,19 @@ if (MFEM_USE_LAPACK)
|
||||
endif()
|
||||
|
||||
# OpenMP
|
||||
if (MFEM_USE_OPENMP OR MFEM_USE_LEGACY_OPENMP)
|
||||
if (NOT MFEM_THREAD_SAFE AND MFEM_USE_LEGACY_OPENMP)
|
||||
message(FATAL_ERROR " *** MFEM_USE_LEGACY_OPENMP requires MFEM_THREAD_SAFE=ON.")
|
||||
if (MFEM_USE_OPENMP)
|
||||
if (MFEM_THREAD_SAFE)
|
||||
find_package(OpenMP REQUIRED)
|
||||
else()
|
||||
message(FATAL_ERROR " *** MFEM_USE_OPENMP requires MFEM_THREAD_SAFE=ON.")
|
||||
endif()
|
||||
find_package(OpenMP REQUIRED)
|
||||
endif()
|
||||
|
||||
# SuiteSparse (before SUNDIALS which may depend on KLU)
|
||||
if (MFEM_USE_SUITESPARSE)
|
||||
find_package(SuiteSparse REQUIRED
|
||||
UMFPACK KLU AMD BTF CHOLMOD COLAMD CAMD CCOLAMD config)
|
||||
include_directories(${SuiteSparse_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# SUNDIALS
|
||||
@@ -196,82 +140,63 @@ if (MFEM_USE_SUNDIALS)
|
||||
find_package(SUNDIALS REQUIRED
|
||||
NVector_Serial NVector_Parallel NVector_ParHyp CVODE ARKODE KINSOL)
|
||||
endif()
|
||||
include_directories(${SUNDIALS_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Mesquite
|
||||
if (MFEM_USE_MESQUITE)
|
||||
find_package(Mesquite REQUIRED)
|
||||
include_directories(${MESQUITE_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# SuperLU_DIST can only be enabled in parallel
|
||||
# SuperLU_DIST can only be enabled if parallel
|
||||
if (MFEM_USE_SUPERLU)
|
||||
if (MFEM_USE_MPI)
|
||||
find_package(SuperLUDist REQUIRED)
|
||||
include_directories(${SuperLUDist_INCLUDE_DIRS})
|
||||
else()
|
||||
message(FATAL_ERROR " *** SuperLU_DIST requires that MPI be enabled.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# STRUMPACK can only be enabled in parallel
|
||||
if (MFEM_USE_STRUMPACK)
|
||||
if (MFEM_USE_MPI)
|
||||
find_package(STRUMPACK REQUIRED)
|
||||
else()
|
||||
message(FATAL_ERROR " *** STRUMPACK requires that MPI be enabled.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Gecko
|
||||
if (MFEM_USE_GECKO)
|
||||
find_package(Gecko REQUIRED)
|
||||
include_directories(${GECKO_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# GnuTLS
|
||||
if (MFEM_USE_GNUTLS)
|
||||
find_package(_GnuTLS REQUIRED)
|
||||
include_directories(${GNUTLS_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# NetCDF
|
||||
if (MFEM_USE_NETCDF)
|
||||
find_package(NetCDF REQUIRED)
|
||||
include_directories(${NETCDF_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# MPFR
|
||||
if (MFEM_USE_MPFR)
|
||||
find_package(MPFR REQUIRED)
|
||||
endif()
|
||||
|
||||
if (MFEM_USE_CONDUIT)
|
||||
find_package(Conduit REQUIRED conduit relay blueprint )
|
||||
include_directories(${MPFR_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Axom/Sidre
|
||||
if (MFEM_USE_SIDRE)
|
||||
find_package(Axom REQUIRED Sidre SLIC axom_utils)
|
||||
endif()
|
||||
|
||||
# PUMI
|
||||
if (MFEM_USE_PUMI)
|
||||
# If PUMI_DIR was specified, only link to that directory,
|
||||
# i.e. don't link to another installation in /usr/lib by mistake
|
||||
find_package(SCOREC 2.1.0 REQUIRED OPTIONAL_COMPONENTS gmi_sim
|
||||
CONFIG PATHS ${PUMI_DIR} NO_DEFAULT_PATH)
|
||||
if (SCOREC_FOUND)
|
||||
# Define a header file with the MFEM_USE_SIMMETRIX preprocessor variable
|
||||
set(MFEM_USE_SIMMETRIX ${SCOREC_gmi_sim_FOUND})
|
||||
set(PUMI_FOUND ${SCOREC_FOUND})
|
||||
get_target_property(PUMI_INCLUDE_DIRS
|
||||
SCOREC::apf INTERFACE_INCLUDE_DIRECTORIES)
|
||||
set(PUMI_LIBRARIES SCOREC::core)
|
||||
if (NOT MFEM_USE_MPI)
|
||||
find_package(ATK REQUIRED Sidre SLIC common)
|
||||
else()
|
||||
find_package(ATK REQUIRED Sidre SPIO SLIC common)
|
||||
endif()
|
||||
include_directories(${ATK_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# MFEM_TIMER_TYPE
|
||||
if (NOT DEFINED MFEM_TIMER_TYPE)
|
||||
if (APPLE)
|
||||
# use std::clock from <ctime> for UserTime and
|
||||
# use mach_absolute_time from <mach/mach_time.h> for RealTime
|
||||
set(MFEM_TIMER_TYPE 4)
|
||||
set(MFEM_TIMER_TYPE 0) # use std::clock from <ctime>
|
||||
elseif (WIN32)
|
||||
set(MFEM_TIMER_TYPE 3) # QueryPerformanceCounter from <windows.h>
|
||||
else()
|
||||
@@ -285,27 +210,17 @@ if (NOT DEFINED MFEM_TIMER_TYPE)
|
||||
endif()
|
||||
|
||||
# List all possible libraries in order of dependencies.
|
||||
# [METIS < SuiteSparse]:
|
||||
# With newer versions of SuiteSparse which include METIS header using 64-bit
|
||||
# integers, the METIS header (with 32-bit indices, as used by mfem) needs to
|
||||
# be before SuiteSparse.
|
||||
set(MFEM_TPLS MPI_CXX OPENMP BLAS LAPACK METIS HYPRE SuiteSparse SUNDIALS PETSC
|
||||
MESQUITE SuperLUDist STRUMPACK AXOM CONDUIT GECKO GNUTLS NETCDF MPFR PUMI
|
||||
POSIXCLOCKS MFEMBacktrace ZLIB)
|
||||
set(MFEM_TPLS HYPRE OPENMP SUNDIALS MESQUITE SuiteSparse SuperLUDist
|
||||
ParMETIS METIS LAPACK BLAS GECKO GNUTLS NETCDF PETSC MPFR ATK POSIXCLOCKS
|
||||
MFEMBacktrace ZLIB)
|
||||
# Add all *_FOUND libraries in the variable TPL_LIBRARIES.
|
||||
set(TPL_LIBRARIES "")
|
||||
set(TPL_INCLUDE_DIRS "")
|
||||
foreach(TPL IN LISTS MFEM_TPLS)
|
||||
if (${TPL}_FOUND)
|
||||
message(STATUS "MFEM: using package ${TPL}")
|
||||
list(APPEND TPL_LIBRARIES ${${TPL}_LIBRARIES})
|
||||
list(APPEND TPL_INCLUDE_DIRS ${${TPL}_INCLUDE_DIRS})
|
||||
endif()
|
||||
endforeach(TPL)
|
||||
list(REMOVE_DUPLICATES TPL_LIBRARIES)
|
||||
list(REMOVE_DUPLICATES TPL_INCLUDE_DIRS)
|
||||
# message(STATUS "TPL_INCLUDE_DIRS = ${TPL_INCLUDE_DIRS}")
|
||||
include_directories(${TPL_INCLUDE_DIRS})
|
||||
|
||||
if (OPENMP_FOUND)
|
||||
message(STATUS "MFEM: using package OpenMP")
|
||||
@@ -313,14 +228,16 @@ if (OPENMP_FOUND)
|
||||
endif()
|
||||
|
||||
message(STATUS "MFEM build type: CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
|
||||
message(STATUS "MFEM version: v${MFEM_VERSION_STRING}")
|
||||
message(STATUS "MFEM git string: ${MFEM_GIT_STRING}")
|
||||
|
||||
# Windows specific
|
||||
set(_USE_MATH_DEFINES ${WIN32})
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Define and configure the MFEM library
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Headers and sources
|
||||
include(MfemCmakeUtilities)
|
||||
set(SOURCES "")
|
||||
set(HEADERS "")
|
||||
set(MFEM_SOURCE_DIRS general linalg mesh fem)
|
||||
@@ -332,30 +249,21 @@ set(MASTER_HEADERS
|
||||
${PROJECT_SOURCE_DIR}/mfem.hpp
|
||||
${PROJECT_SOURCE_DIR}/mfem-performance.hpp)
|
||||
|
||||
set(_lib_path "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON CACHE BOOL "")
|
||||
set(CMAKE_INSTALL_RPATH "${_lib_path}" CACHE PATH "")
|
||||
set(CMAKE_INSTALL_NAME_DIR "${_lib_path}" CACHE PATH "")
|
||||
|
||||
# Declaring the library
|
||||
add_library(mfem ${SOURCES} ${HEADERS} ${MASTER_HEADERS})
|
||||
# message(STATUS "TPL_LIBRARIES = ${TPL_LIBRARIES}")
|
||||
list(REMOVE_DUPLICATES TPL_LIBRARIES)
|
||||
# message(STATUS " TPL_LIBRARIES = ${TPL_LIBRARIES}")
|
||||
if (CMAKE_VERSION VERSION_GREATER 2.8.11)
|
||||
target_link_libraries(mfem PUBLIC ${TPL_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(mfem ${TPL_LIBRARIES})
|
||||
endif()
|
||||
if (MINGW)
|
||||
target_link_libraries(mfem ws2_32)
|
||||
endif()
|
||||
set_target_properties(mfem PROPERTIES VERSION "${mfem_VERSION}")
|
||||
set_target_properties(mfem PROPERTIES SOVERSION "${mfem_VERSION}")
|
||||
|
||||
# If building out-of-source, define MFEM_BUILD_DIR to point to the build
|
||||
# directory.
|
||||
if (NOT ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}"))
|
||||
target_compile_definitions(mfem PRIVATE
|
||||
"MFEM_BUILD_DIR=${PROJECT_BINARY_DIR}")
|
||||
"-DMFEM_BUILD_DIR=${PROJECT_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
# Generate configuration file in the build directory: config/_config.hpp.
|
||||
@@ -373,11 +281,6 @@ if (NOT ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}"))
|
||||
"// Auto-generated file.
|
||||
#define MFEM_BUILD_DIR ${PROJECT_BINARY_DIR}
|
||||
#include \"${PROJECT_SOURCE_DIR}/${Header}\"
|
||||
")
|
||||
# This version will be installed in the top include directory:
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/InstallHeaders/${Header}"
|
||||
"// Auto-generated file.
|
||||
#include \"mfem/${Header}\"
|
||||
")
|
||||
endforeach()
|
||||
endif()
|
||||
@@ -389,9 +292,6 @@ endif()
|
||||
# Enable testing if required
|
||||
if (MFEM_ENABLE_TESTING)
|
||||
enable_testing()
|
||||
set(MFEM_ALL_TESTS_TARGET_NAME tests)
|
||||
add_mfem_target(${MFEM_ALL_TESTS_TARGET_NAME} OFF)
|
||||
add_subdirectory(tests EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
# Define a target that all examples and miniapps will depend on.
|
||||
@@ -411,9 +311,7 @@ add_subdirectory(miniapps EXCLUDE_FROM_ALL)
|
||||
# Target to build all executables, i.e. everything.
|
||||
add_custom_target(exec)
|
||||
add_dependencies(exec
|
||||
${MFEM_ALL_EXAMPLES_TARGET_NAME}
|
||||
${MFEM_ALL_MINIAPPS_TARGET_NAME}
|
||||
${MFEM_ALL_TESTS_TARGET_NAME})
|
||||
${MFEM_ALL_EXAMPLES_TARGET_NAME} ${MFEM_ALL_MINIAPPS_TARGET_NAME})
|
||||
# Here, we want to "add_dependencies(test exec)". However, dependencies for
|
||||
# 'test' (and other built-in targets) can not be added with add_dependencies():
|
||||
# - https://gitlab.kitware.com/cmake/cmake/issues/8438
|
||||
@@ -434,12 +332,12 @@ endif()
|
||||
# Add 'check' target - quick test
|
||||
if (NOT MFEM_USE_MPI)
|
||||
add_custom_target(check
|
||||
${CMAKE_CTEST_COMMAND} -R '^ex1_ser' -C ${CMAKE_CFG_INTDIR}
|
||||
${CMAKE_CTEST_COMMAND} -R ex1_ser -E performance -C ${CMAKE_CFG_INTDIR}
|
||||
USES_TERMINAL)
|
||||
add_dependencies(check ex1)
|
||||
else()
|
||||
add_custom_target(check
|
||||
${CMAKE_CTEST_COMMAND} -R '^ex1p' -C ${CMAKE_CFG_INTDIR}
|
||||
${CMAKE_CTEST_COMMAND} -R ex1p -E performance -C ${CMAKE_CFG_INTDIR}
|
||||
USES_TERMINAL)
|
||||
add_dependencies(check ex1p)
|
||||
endif()
|
||||
@@ -454,6 +352,7 @@ add_subdirectory(doc)
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
message(STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}")
|
||||
string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UC)
|
||||
set(INSTALL_INCLUDE_DIR include
|
||||
CACHE PATH "Relative path for installing header files.")
|
||||
set(INSTALL_LIB_DIR lib
|
||||
@@ -473,15 +372,11 @@ install(TARGETS ${PROJECT_NAME}
|
||||
DESTINATION ${INSTALL_LIB_DIR})
|
||||
|
||||
# Install the master headers
|
||||
foreach(Header mfem.hpp mfem-performance.hpp)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/InstallHeaders/${Header}
|
||||
DESTINATION ${INSTALL_INCLUDE_DIR})
|
||||
endforeach()
|
||||
install(FILES ${MASTER_HEADERS} DESTINATION ${INSTALL_INCLUDE_DIR}/mfem)
|
||||
install(FILES ${MASTER_HEADERS} DESTINATION ${INSTALL_INCLUDE_DIR})
|
||||
|
||||
# Install the headers; currently, the miniapps headers are excluded
|
||||
install(DIRECTORY ${MFEM_SOURCE_DIRS}
|
||||
DESTINATION ${INSTALL_INCLUDE_DIR}/mfem
|
||||
DESTINATION ${INSTALL_INCLUDE_DIR}
|
||||
FILES_MATCHING PATTERN "*.hpp")
|
||||
|
||||
# Install ${HEADERS}
|
||||
@@ -494,11 +389,11 @@ install(DIRECTORY ${MFEM_SOURCE_DIRS}
|
||||
|
||||
# Install the configuration header files
|
||||
install(FILES ${PROJECT_BINARY_DIR}/config/_config.hpp
|
||||
DESTINATION ${INSTALL_INCLUDE_DIR}/mfem/config
|
||||
DESTINATION ${INSTALL_INCLUDE_DIR}/config
|
||||
RENAME config.hpp)
|
||||
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/config/tconfig.hpp
|
||||
DESTINATION ${INSTALL_INCLUDE_DIR}/mfem/config)
|
||||
DESTINATION ${INSTALL_INCLUDE_DIR}/config)
|
||||
|
||||
# Package the whole thing up nicely
|
||||
include(CMakePackageConfigHelpers)
|
||||
@@ -508,15 +403,11 @@ export(TARGETS ${PROJECT_NAME}
|
||||
FILE "${PROJECT_BINARY_DIR}/MFEMTargets.cmake")
|
||||
|
||||
# Export the package for use from the build-tree (this registers the build-tree
|
||||
# with the CMake user package registry.)
|
||||
# TODO: How do we register the install-tree? Replacing the build-tree?
|
||||
# with a global CMake-registry)
|
||||
export(PACKAGE ${PROJECT_NAME})
|
||||
|
||||
# Extract the include directories required to use MFEM
|
||||
get_target_property(MFEM_TPL_INCLUDE_DIRS mfem INCLUDE_DIRECTORIES)
|
||||
if (NOT MFEM_TPL_INCLUDE_DIRS)
|
||||
set(MFEM_TPL_INCLUDE_DIRS "")
|
||||
endif()
|
||||
|
||||
# This is the build-tree version
|
||||
set(INCLUDE_INSTALL_DIRS ${PROJECT_BINARY_DIR} ${MFEM_TPL_INCLUDE_DIRS})
|
||||
@@ -549,10 +440,3 @@ install(FILES
|
||||
# Install the export set for use with the install-tree
|
||||
install(EXPORT ${PROJECT_NAME_UC}Targets
|
||||
DESTINATION ${INSTALL_CMAKE_DIR})
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Create 'config.mk' from 'config.mk.in' for the build and install locations and
|
||||
# define install rules for 'config.mk' and 'test.mk'
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
mfem_export_mk_files()
|
||||
|
||||
@@ -1,545 +0,0 @@
|
||||
<p align="center">
|
||||
<a href="http://mfem.org/"><img alt="mfem" src="http://mfem.org/img/logo-300.png"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/mfem/mfem/blob/master/COPYRIGHT"><img alt="License" src="https://img.shields.io/badge/License-LGPL--2.1-brightgreen.svg"></a>
|
||||
<a href="https://travis-ci.org/mfem/mfem"><img alt="Build Status" src="https://travis-ci.org/mfem/mfem.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="http://mfem.github.io/doxygen/html/index.html"><img alt="Doxygen" src="https://img.shields.io/badge/code-documented-brightgreen.svg"></a>
|
||||
</p>
|
||||
|
||||
|
||||
# How to Contribute
|
||||
|
||||
The MFEM team welcomes contributions at all levels: bugfixes; code
|
||||
improvements; simplifications; new mesh, discretization or solver
|
||||
capabilities; improved documentation; new examples and miniapps;
|
||||
HPC performance improvements; ...
|
||||
|
||||
Use a pull request (PR) toward the `mfem:master` branch to propose your
|
||||
contribution. If you are planning significant code changes, or have any
|
||||
questions, you can also open an [issue](https://github.com/mfem/mfem/issues)
|
||||
before issuing a PR. We also welcome your [simulation
|
||||
images](http://mfem.org/gallery/), which you can submit via a pull request in
|
||||
[mfem/web](https://github.com/mfem/web).
|
||||
|
||||
See the [Quick Summary](#quick-summary) section for the main highlights of our
|
||||
GitHub workflow. For more details, consult the following sections and refer
|
||||
back to them before issuing pull requests:
|
||||
|
||||
- [Code Overview](#code-overview)
|
||||
- [GitHub Workflow](#github-workflow)
|
||||
- [MFEM Organization](#mfem-organization)
|
||||
- [New Feature Development](#new-feature-development)
|
||||
- [Developer Guidelines](#developer-guidelines)
|
||||
- [Pull Requests](#pull-requests)
|
||||
- [Pull Request Checklist](#pull-request-checklist)
|
||||
- [Master/Next Workflow](#masternext-workflow)
|
||||
- [Releases](#releases)
|
||||
- [Release Checklist](#release-checklist)
|
||||
- [LLNL Workflow](#llnl-workflow)
|
||||
- [Automated Testing](#automated-testing)
|
||||
- [Contact Information](#contact-information)
|
||||
|
||||
Contributing to MFEM requires knowledge of Git and, likely, finite elements. If
|
||||
you are new to Git, see the [GitHub learning
|
||||
resources](https://help.github.com/articles/git-and-github-learning-resources/).
|
||||
To learn more about the finite element method, see our [FEM page](http://mfem.org/fem).
|
||||
|
||||
*By submitting a pull request, you are affirming the [Developer's Certificate of
|
||||
Origin](#developers-certificate-of-origin-11) at the end of this file.*
|
||||
|
||||
|
||||
## Quick Summary
|
||||
|
||||
- We encourage you to [join the MFEM organization](#mfem-organization) and create
|
||||
development branches off `mfem:master`.
|
||||
- Please follow the [developer guidelines](#developer-guidelines), in particular
|
||||
with regards to documentation and code styling.
|
||||
- Pull requests should be issued toward `mfem:master`. Make sure
|
||||
to check the items off the [Pull Request Checklist](#pull-request-checklist).
|
||||
- After approval, MFEM developers merge the PR manually in the [mfem:next branch](#masternext-workflow).
|
||||
- After a week of testing in `mfem:next`, the original PR is merged in `mfem:master`.
|
||||
- We use [milestones](https://github.com/mfem/mfem/milestones) to coordinate the
|
||||
work on different PRs toward a release.
|
||||
- Don't hesitate to [contact us](#contact-information) if you have any questions.
|
||||
|
||||
|
||||
### Code Overview
|
||||
|
||||
- The MFEM library uses object-orient design principles which reflect, in code,
|
||||
the independent mathematical concepts of meshing, linear algebra and finite
|
||||
element spaces and operators.
|
||||
|
||||
- The MFEM source code has the following structure:
|
||||
```
|
||||
.
|
||||
├── config
|
||||
│ └── cmake
|
||||
│ └── modules
|
||||
├── data
|
||||
├── doc
|
||||
│ └── web
|
||||
│ └── examples
|
||||
├── examples
|
||||
│ ├── petsc
|
||||
│ ├── pumi
|
||||
│ └── sundials
|
||||
├── fem
|
||||
├── general
|
||||
├── linalg
|
||||
├── mesh
|
||||
├── miniapps
|
||||
│ ├── common
|
||||
│ ├── electromagnetics
|
||||
│ ├── meshing
|
||||
│ ├── nurbs
|
||||
│ ├── performance
|
||||
│ └── tools
|
||||
└── tests
|
||||
├── unit
|
||||
│ ├── ...
|
||||
└── ...
|
||||
|
||||
```
|
||||
|
||||
- The main directories are `fem/`, `mesh/` and `linalg/` containing the C++
|
||||
classes implementing the finite element, mesh and linear algebra concepts
|
||||
respectively.
|
||||
|
||||
- The main mesh classes are:
|
||||
+ [`Mesh`](http://mfem.github.io/doxygen/html/classmfem_1_1Mesh.html)
|
||||
+ [`NCMesh`](http://mfem.github.io/doxygen/html/classmfem_1_1NCMesh.html)
|
||||
+ [`Element`](http://mfem.github.io/doxygen/html/classmfem_1_1Element.html)
|
||||
+ [`ElementTransformation`](http://mfem.github.io/doxygen/html/classmfem_1_1ElementTransformation.html)
|
||||
|
||||
- The main finite element classes are:
|
||||
+ [`FiniteElement`](http://mfem.github.io/doxygen/html/classmfem_1_1FiniteElement.html)
|
||||
+ [`FiniteElementCollection`](http://mfem.github.io/doxygen/html/classmfem_1_1FiniteElement.html)
|
||||
+ [`FiniteElementSpace`](http://mfem.github.io/doxygen/html/classmfem_1_1FiniteElementSpace.html)
|
||||
+ [`GridFunction`](http://mfem.github.io/doxygen/html/classmfem_1_1GridFunction.html)
|
||||
+ [`BilinearFormIntegrator`](http://mfem.github.io/doxygen/html/classmfem_1_1BilinearFormIntegrator.html) and [`LinearFormIntegrator`](http://mfem.github.io/doxygen/html/classmfem_1_1LinearFormIntegrator.html)
|
||||
+ [`LinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1LinearFormIntegrator.html), [`BilinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1BilinearForm.html) and [`MixedBilinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1MixedBilinearForm.html)
|
||||
|
||||
- The main linear algebra classes and sources are
|
||||
+ [`Operator`](http://mfem.github.io/doxygen/html/classmfem_1_1Operator.html) and [`BilinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1BilinearForm.html)
|
||||
+ [`Vector`](http://mfem.github.io/doxygen/html/classmfem_1_1BilinearForm.html) and [`LinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1LinearForm.html)
|
||||
+ [`DenseMatrix`](http://mfem.github.io/doxygen/html/classmfem_1_1DenseMatrix.html) and [`SparseMatrix`](http://mfem.github.io/doxygen/html/classmfem_1_1SparseMatrix.html)
|
||||
+ Sparse [smoothers](http://mfem.github.io/doxygen/html/sparsesmoothers_8hpp.html) and linear [solvers](http://mfem.github.io/doxygen/html/solvers_8hpp.html)
|
||||
|
||||
- Parallel MPI objects in MFEM inherit their serial counterparts, so a parallel
|
||||
mesh for example is just a serial mesh on each task plus the information on
|
||||
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`](http://mfem.github.io/doxygen/html/solvers_8hpp.html)
|
||||
+ [`ParNCMesh`](http://mfem.github.io/doxygen/html/classmfem_1_1ParMesh.html)
|
||||
+ [`ParFiniteElementSpace`](http://mfem.github.io/doxygen/html/classmfem_1_1ParFiniteElementSpace.html)
|
||||
+ [`ParGridFunction`](http://mfem.github.io/doxygen/html/classmfem_1_1ParGridFunction.html)
|
||||
+ [`ParBilinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1ParBilinearForm.html) and [`ParLinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1ParLinearForm.html)
|
||||
+ [`HypreParMatrix`](http://mfem.github.io/doxygen/html/classmfem_1_1HypreParMatrix.html) and [`HypreParVector`](http://mfem.github.io/doxygen/html/classmfem_1_1HypreParVector.html)
|
||||
+ [`HypreSolver`](http://mfem.github.io/doxygen/html/classmfem_1_1HypreSolver.html) and other [hypre classes](http://mfem.github.io/doxygen/html/hypre_8hpp.html)
|
||||
|
||||
- The `general/` directory contains C++ classes that serve as utilities for
|
||||
communication, error handling, arrays, (Boolean) tables, timing, etc.
|
||||
|
||||
- The `config/` directory contains build-related files, both for the plain
|
||||
Makefile and the CMake build options.
|
||||
|
||||
- The `doc/` directory contains configuration for the Doxygen code documentation
|
||||
that can either be build locally, or browsed online at
|
||||
http://mfem.github.io/doxygen/html/index.html.
|
||||
|
||||
- The `data/` directory contains a collection of small mesh files, that are used
|
||||
in the simple example codes and more fully-featured mini applications in the
|
||||
`examples/` and `miniapps/` directories.
|
||||
|
||||
- The `tests/` directory contains a unit test suite and will later contain more
|
||||
tests that run example codes.
|
||||
|
||||
- See also the [code overview](http://mfem.org/code-overview/) section on the
|
||||
MFEM website.
|
||||
|
||||
## GitHub Workflow
|
||||
|
||||
The GitHub organization, https://github.com/mfem, is the main developer hub for
|
||||
the MFEM project.
|
||||
|
||||
If you plan to make contributions or will like to stay up-to-date with changes
|
||||
in the code, *we strongly encourage you to [join the MFEM organization](#mfem-organization)*.
|
||||
|
||||
This will simplify the workflow (by providing you additional permissions), and
|
||||
will allow us to reach you directly with project announcements.
|
||||
|
||||
|
||||
### MFEM Organization
|
||||
|
||||
- Before you can start, you need a GitHub account, here are a few suggestions:
|
||||
+ Create the account at: github.com/join.
|
||||
+ For easy identification, please add your name and maybe a picture of you at: https://github.com/settings/profile.
|
||||
+ To receive notification, set a primary email at: https://github.com/settings/emails.
|
||||
+ For password-less pull/push over SSH, add your SSH keys at: https://github.com/settings/keys.
|
||||
|
||||
- [Contact us](#contact-information) for an invitation to join the MFEM GitHub
|
||||
organization.
|
||||
|
||||
- You should receive an invitation email, which you can directly accept.
|
||||
Alternatively, *after logging into GitHub*, you can accept the invitation at
|
||||
the top of https://github.com/mfem.
|
||||
|
||||
- Consider making your membership public by going to https://github.com/orgs/mfem/people
|
||||
and clicking on the organization visibility dropbox next to your name.
|
||||
|
||||
- Project discussions and announcements will be posted at
|
||||
https://github.com/orgs/mfem/teams/everyone.
|
||||
|
||||
- The MFEM source code is in the [mfem](https://github.com/mfem/mfem)
|
||||
repository.
|
||||
|
||||
- The website and corresponding documentation are in the
|
||||
[web](https://github.com/mfem/web) repository.
|
||||
|
||||
- The [PyMFEM](https://github.com/mfem/PyMFEM) repository contains a Python
|
||||
wrapper for MFEM.
|
||||
|
||||
- The [data](https://github.com/mfem/data) repository contains additional
|
||||
(large) datafiles for MFEM.
|
||||
|
||||
|
||||
### New Feature Development
|
||||
|
||||
- A new feature should be important enough that at least one person, the
|
||||
proposer, is willing to work on it and be its champion.
|
||||
|
||||
- The proposer creates a branch for the new feature (with suffix `-dev`), off
|
||||
the `master` branch, or another existing feature branch, for example:
|
||||
|
||||
```
|
||||
# Clone assuming you have setup your ssh keys on GitHub:
|
||||
git clone git@github.com:mfem/mfem.git
|
||||
|
||||
# Alternatively, clone using the "https" protocol:
|
||||
git clone https://github.com/mfem/mfem.git
|
||||
|
||||
# Create a new feature branch starting from "master":
|
||||
git checkout master
|
||||
git pull
|
||||
git checkout -b feature-dev
|
||||
|
||||
# Work on "feature-dev", add local commits
|
||||
# ...
|
||||
|
||||
# (One time only) push the branch to github and setup your local
|
||||
# branch to track the github branch (for "git pull"):
|
||||
git push -u origin feature-dev
|
||||
|
||||
```
|
||||
|
||||
- **We prefer that you create the new feature branch inside the MFEM organization
|
||||
as opposed to in a fork.** This allows everyone in the community to collaborate
|
||||
in one central place.
|
||||
|
||||
- If you prefer to work in your fork, please [enable upstream edits](https://help.github.com/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork/).
|
||||
|
||||
- Never use the `next` branch to start a new feature branch!
|
||||
|
||||
- The typical feature branch name is `new-feature-dev`, e.g. `pumi-dev`. While
|
||||
not frequent in MFEM, other suffixes are possible, e.g. `-fix`, `-doc`, etc.
|
||||
|
||||
|
||||
### Developer Guidelines
|
||||
|
||||
- *Keep the code lean and as simple as possible*
|
||||
- Well-designed simple code is frequently more general and powerful.
|
||||
- Lean code base is easier to understand by new collaborators.
|
||||
- New features should be added only if they are necessary or generally useful.
|
||||
- Introduction of language constructions not currently used in MFEM should be
|
||||
justified and generally avoided (so we can build on cutting-edge systems).
|
||||
- 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*
|
||||
- Main goal is fast prototyping for research.
|
||||
- When in doubt, generality wins over efficiency.
|
||||
- Respect the needs of different users (current and/or future).
|
||||
|
||||
- *Keep things separate and logically organized*
|
||||
- General usage features go in MFEM (implemented in as much generality as
|
||||
possible), non-general features go into external apps.
|
||||
- Inside MFEM, compartmentalize between linalg, fem, mesh, GLVis, etc.
|
||||
- Contributions that are project-specific or have external dependencies are
|
||||
allowed (if they are of broader interest), but should be `#ifdef`-ed and not
|
||||
change the code by default.
|
||||
|
||||
- Code specifics
|
||||
- All significant new classes, methods and functions have Doxygen-style
|
||||
documentation in source comments.
|
||||
- Consistent code styling is enforced with `make style` in the top-level
|
||||
directory. This requires [Artistic Style](http://astyle.sourceforge.net) (we
|
||||
specifically use version 2.05.1). See also the file `config/mfem.astylerc`.
|
||||
- Use `mfem::out` and `mfem::err` instead of `std::cout` and `std::cerr` in
|
||||
internal library code. (You can use `std` in examples and miniapps.)
|
||||
- When manually resolving conflicts during a merge, make sure to mention the
|
||||
conflicted files in the commit message.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
- When your branch is ready for other developers to review / comment on
|
||||
the code, create a pull request towards `mfem:master`.
|
||||
|
||||
- Pull request typically have titles like:
|
||||
|
||||
`Description [new-feature-dev]`
|
||||
|
||||
for example:
|
||||
|
||||
`Parallel Unstructured Mesh Infrastructure (PUMI) integration [pumi-dev]`
|
||||
|
||||
Note the branch name suffix (in square brackets).
|
||||
|
||||
- Titles may contain a prefix in square brackets to emphasize the type of PR.
|
||||
Common choices are: `[DON'T MERGE]`, `[WIP]` and `[DISCUSS]`, for example:
|
||||
|
||||
`[DISCUSS] Hybridized DG [hdg-dev]`
|
||||
|
||||
- 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, see PR #222 for an example.
|
||||
|
||||
- Track the Travis CI and Appveyor [continuous integration](#automated-testing)
|
||||
builds at the end of the PR. These should run clean, so address any errors as
|
||||
soon as possible.
|
||||
|
||||
|
||||
### Pull Request Checklist
|
||||
|
||||
Before a PR can be merged, it should satisfy the following:
|
||||
|
||||
- [ ] Code builds.
|
||||
- [ ] Code passes `make style`.
|
||||
- [ ] Update `CHANGELOG`:
|
||||
- [ ] Is this a new feature users need to be aware of? 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`:
|
||||
- [ ] Had a new optional library been added? (*Make sure the external library is licensed under LGPL, not GPL!*)
|
||||
- [ ] Does `make` or `cmake` have a new target?
|
||||
- [ ] Did the requirements or the installation process change? *(rare)*
|
||||
- [ ] Update `.gitignore`:
|
||||
- [ ] Check if `make distclean; git status` shows any files that are generated from the source 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 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`:
|
||||
- [ ] 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`.
|
||||
- [ ] 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`.
|
||||
- [ ] In `examples.md`, list the example under the appropriate categories, add new categories if necessary.
|
||||
- [ ] Add a short description of the example in the "Extensive Examples" section of `features.md`.
|
||||
- [ ] New miniapps:
|
||||
- [ ] All sample runs at the top of the miniapp work.
|
||||
- [ ] Update top-level `makefile` and `makefile` in corresponding miniapp directory.
|
||||
- [ ] Add the miniapp binary and any files generated by it to the top-level `.gitignore` file.
|
||||
- [ ] Update CMake build system:
|
||||
- [ ] Update the `CMakeLists.txt` file in the `miniapps` directory, if the new miniapp is in a new directory.
|
||||
- [ ] 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`
|
||||
- [ ] 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`.
|
||||
- [ ] New capability:
|
||||
- [ ] All significant new classes, methods and functions have Doxygen-style documentation in source comments.
|
||||
- [ ] Consider adding new sample runs in existing examples to highlight the new capability.
|
||||
- [ ] Consider saving cool simulation pictures with the new capability in the Confluence gallery (LLNL only) or submitting them, via pull request, to the gallery section of the `mfem/web` repo.
|
||||
- [ ] If this is a major new feature, consider mentioning in the short summary inside `README` *(rare)*.
|
||||
- [ ] List major new classes in `doc/CodeDocumentation.dox` *(rare)*.
|
||||
- [ ] Update this checklist, if the new pull request affects it.
|
||||
- [ ] Run the unit tests and make sure they all pass `make unittest`.
|
||||
- [ ] (LLNL only) Clone the `tests` repository and run the following tests, see `mfem/tests/README.md`:
|
||||
- [ ] `compilers`
|
||||
- [ ] `memcheck`
|
||||
- [ ] `documentation`
|
||||
- [ ] (LLNL only) After merging:
|
||||
- [ ] Regenerate `README.html` files from companion documentation pull requests.
|
||||
- [ ] Update the `baseline` and `compiler` tests, add new tests if necessary.
|
||||
- [ ] Consider updating the script `mfem/tests/sample-runs` (`sample-runs-serial` and `sample-runs-parallel`).
|
||||
|
||||
### Master/Next Workflow
|
||||
|
||||
MFEM uses a `master`/`next`-branch workflow as described below:
|
||||
|
||||
- The `master` branch should always be of release quality and changes should not
|
||||
be merged until they have been fully tested. This branch is protected, and
|
||||
changes can only be made through pull requests.
|
||||
|
||||
- After approval, a pull request is merged manually (by MFEM developers) in the
|
||||
`next` branch for testing and the `in-next` label is added to the PR.
|
||||
This can be done as follows:
|
||||
|
||||
```
|
||||
# Pull the latest version of the "feature-dev" branch
|
||||
git checkout feature-dev
|
||||
git pull
|
||||
|
||||
# Pull the latest version of the "next" branch
|
||||
git checkout next
|
||||
git pull
|
||||
|
||||
# Merge "feature-dev" into "next", resolving conflicts, if necessary.
|
||||
# Use the "--no-ff" flag to create a new commit with merge message.
|
||||
git merge --no-ff feature-dev
|
||||
|
||||
# Push the "next" branch to the server
|
||||
git push
|
||||
```
|
||||
|
||||
- After a week of testing in `next` (excluding bugfixes), both on GitHub, as
|
||||
well as [internally](#tests-at-llnl) at LLNL, the original PR is merged into
|
||||
`master` (provided there are no issues).
|
||||
|
||||
- After the merge, the feature branch is deleted (unless it is a long-term
|
||||
project with periodic PRs).
|
||||
|
||||
- The `next` branch is used just for integrated testing of all PRs approved for
|
||||
merging into `master` to verify that each works individually and that all of
|
||||
them work as a group. This branch can be discarded at any time, though we
|
||||
typically do that only at the end of a [release cycle](#releases).
|
||||
|
||||
|
||||
### Releases
|
||||
|
||||
- Releases are just tags in the `master` branch, e.g. https://github.com/mfem/mfem/releases/tag/v3.3.2,
|
||||
and have a version that ends in an even "patch" number, e.g. `v3.2.2` or
|
||||
`v3.4` (by convention `v3.4` is the same as `v3.4.0`.) Between releases, the
|
||||
version ends in an odd "patch" number, e.g. `v3.3.3`.
|
||||
|
||||
- We use [milestones](https://github.com/mfem/mfem/milestones) to coordinate the
|
||||
work on different PRs toward a release, see for example the
|
||||
[v3.3.2 release](https://github.com/mfem/mfem/milestone/1?closed=1).
|
||||
|
||||
- After a release is complete, the `next` branch is recreated, e.g. as follows
|
||||
(replace `3.3.2` with current release):
|
||||
- Rename the current `next` branch to `next-pre-v3.3.2`.
|
||||
- Create a new `next` branch starting from the `v3.3.2` release.
|
||||
- Local copies of `next` can then be updated with `git checkout -B next origin/next`.
|
||||
|
||||
### Release Checklist
|
||||
|
||||
- [ ] Update the MFEM version in the following files:
|
||||
- [ ] `CHANGELOG`
|
||||
- [ ] `makefile`
|
||||
- [ ] `CMakeLists.txt`
|
||||
- [ ] `doc/CodeDocumentation.conf.in`
|
||||
- [ ] (LLNL only) Make sure all `README.html` files in the source repo are up to date.
|
||||
- [ ] Tag the repository:
|
||||
|
||||
```
|
||||
git tag -a v3.1 -m "Official release v3.1"
|
||||
git push origin v3.1
|
||||
```
|
||||
- [ ] Create the release tarball and push to `mfem/releases`.
|
||||
- [ ] Recreate the `next` branch as described in previous section.
|
||||
- [ ] Update and push documentation to `mfem/doxygen`.
|
||||
- [ ] Update URL shorlinks:
|
||||
- [ ] Create a shortlink at [https://goo.gl/](https://goo.gl/) for the release tarball, e.g. http://mfem.github.io/releases/mfem-3.1.tgz.
|
||||
- [ ] (LLNL only) Add and commit the new shorlink in the `links` and `links-mfem` files of the internal `mfem/downloads` repo.
|
||||
- [ ] 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`.
|
||||
|
||||
|
||||
## LLNL Workflow
|
||||
|
||||
- The GitHub `master` and `next` branches are mirrored to the LLNL institutional
|
||||
Bitbucket repository as `gh-master` and `gh-next`.
|
||||
|
||||
- `gh-master` is merged into LLNL's internal `master` through pull requests; write
|
||||
permissions to `master` are restricted to ensure this is the only way in which it
|
||||
gets updated.
|
||||
|
||||
- We never push directly from LLNL to GitHub.
|
||||
|
||||
- Versions of the code on LLNL's internal server, from most to least stable:
|
||||
- MFEM official release on mfem.org -- Most stable, tested in many apps.
|
||||
- `mfem:master` -- Recent development version, guaranteed to work.
|
||||
- `mfem:gh-master` -- Stable development version, passed testing, you can use
|
||||
it to build your code between releases.
|
||||
- `mfem:gh-next` -- Bleeding-edge development version, may be broken, use at
|
||||
your own risk.
|
||||
|
||||
## Automated Testing
|
||||
|
||||
MFEM has several levels of automated testing running on GitHub, as well as on
|
||||
local Mac and Linux workstations, and Livermore Computing clusters at LLNL.
|
||||
|
||||
### Linux and Mac smoke tests
|
||||
We use Travis CI to drive the default tests on the `master` and `next`
|
||||
branches. See the `.travis` file and the logs at
|
||||
[https://travis-ci.org/mfem/mfem](https://travis-ci.org/mfem/mfem).
|
||||
|
||||
Testing using Travis CI should be kept lightweight, as there is a 50 minute 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.
|
||||
|
||||
### 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
|
||||
and debug build is performed with a simple run of `ex1` to verify the executable.
|
||||
|
||||
### Tests at LLNL
|
||||
At LLNL, we mirror the `master` and `next` branches internally (to `gh-master`
|
||||
and `gh-next`) and run longer nightly tests via cron. On the weekends, a more
|
||||
extensive test is run which extracts and executes all the different sample runs
|
||||
from each example.
|
||||
|
||||
|
||||
## Contact Information
|
||||
|
||||
- Contact the MFEM team by posting to the [GitHub issue tracker](https://github.com/mfem/mfem).
|
||||
Please perform a search to make sure your question has not been answered already.
|
||||
|
||||
- Email communications should be sent to the MFEM developers mailing list,
|
||||
mfem-dev@llnl.gov.
|
||||
|
||||
|
||||
## [Developer's Certificate of Origin 1.1](https://developercertificate.org/)
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I have the right
|
||||
to submit it under the open source license indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best of my
|
||||
knowledge, is covered under an appropriate open source license and I have
|
||||
the right under that license to submit that work with modifications, whether
|
||||
created in whole or in part by me, under the same open source license
|
||||
(unless I am permitted to submit under a different license), as indicated in
|
||||
the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other person who
|
||||
certified (a), (b) or (c) and I have not modified it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution are public and
|
||||
that a record of the contribution (including all personal information I
|
||||
submit with it, including my sign-off) is maintained indefinitely and may be
|
||||
redistributed consistent with this project or the open source license(s)
|
||||
involved.
|
||||
@@ -18,41 +18,14 @@ requires an MPI C++ compiler, as well as the following external libraries:
|
||||
- METIS (a family of multilevel partitioning algorithms)
|
||||
http://glaros.dtc.umn.edu/gkhome/metis/metis/overview
|
||||
|
||||
The METIS dependency can be disabled but that is not generally recommended, see
|
||||
the option MFEM_USE_METIS.
|
||||
|
||||
MFEM also includes support for devices such as GPUs, and programming models such
|
||||
as CUDA, OCCA, OpenMP and RAJA.
|
||||
|
||||
- Starting with version 4.0, MFEM requires a C++11 compiler
|
||||
|
||||
- CUDA support requires an NVIDIA GPU and an installation of the CUDA Toolkit
|
||||
https://developer.nvidia.com/cuda-toolkit
|
||||
|
||||
- OCCA support requires the OCCA library
|
||||
https://libocca.org
|
||||
|
||||
- OpenMP support requires a compiler implementing the OpenMP API
|
||||
https://www.openmp.org
|
||||
|
||||
- RAJA support requires installation of the RAJA performance portability layer
|
||||
with (optionally) support for CUDA and OpenMP
|
||||
https://github.com/LLNL/RAJA
|
||||
|
||||
The library supports two build systems: one based on GNU make, and a second one
|
||||
based on CMake. Both build systems are described below. Some hints for building
|
||||
without GNU make or CMake can be found at the end of this file.
|
||||
|
||||
In addition to the native build systems, MFEM packages are also available in the
|
||||
following package managers:
|
||||
In addition to the native build systems, MFEM packages are also available in
|
||||
the Homebrew/Science, https://github.com/Homebrew/homebrew-science, and the
|
||||
Spack, https://github.com/LLNL/spack, package managers.
|
||||
|
||||
- Spack, https://github.com/spack/spack
|
||||
- OpenHPC, http://openhpc.community
|
||||
- Homebrew/Science, https://github.com/Homebrew/homebrew-science
|
||||
|
||||
We also recommend downloading and building the MFEM-based GLVis visualization
|
||||
tool which can be used to visualize the meshes and solution in MFEM's examples
|
||||
and miniapps. See http://glvis.org and http://mfem.org/building.
|
||||
|
||||
Quick start with GNU make
|
||||
=========================
|
||||
@@ -65,10 +38,6 @@ Parallel build:
|
||||
(build hypre 2.10.0b in ../hypre-2.10.0b relative to mfem/)
|
||||
make parallel -j 4
|
||||
|
||||
CUDA build:
|
||||
make cuda -j 4
|
||||
(build for a specific compute capability: 'make cuda -j 4 CUDA_ARCH=sm_30')
|
||||
|
||||
Example codes (serial/parallel, depending on the build):
|
||||
cd examples
|
||||
make -j 4
|
||||
@@ -79,6 +48,7 @@ Build everything (library, examples and miniapps) with current configuration:
|
||||
Quick-check the build by running Example 1/1p (optional):
|
||||
make check
|
||||
|
||||
|
||||
Quick start with CMake
|
||||
======================
|
||||
Serial build:
|
||||
@@ -153,10 +123,6 @@ are also defined:
|
||||
make parallel -> Builds parallel optimized version of the library
|
||||
make debug -> Builds serial debug version of the library
|
||||
make pdebug -> Builds parallel debug version of the library
|
||||
make cuda -> Builds serial cuda optimized version of the library
|
||||
make pcuda -> Builds parallel cuda optimized version of the library
|
||||
make cudebug -> Builds serial cuda debug version of the library
|
||||
make pcudebug -> Builds parallel cuda debug version of the library
|
||||
|
||||
Note that any of the above shortcuts accept configuration options, either at the
|
||||
command line or through a user configuration file.
|
||||
@@ -172,7 +138,7 @@ check the results from all the serial/parallel MFEM examples and miniapps use:
|
||||
|
||||
Note that by default MFEM uses "mpirun -np" in its test runs (this is also what
|
||||
is used in the sample runs of its examples and miniapps). The MPI launcher can
|
||||
be changed by the user as described in the "Specifying an MPI job launcher"
|
||||
be changed by the user as described in the "Specifying a MPI job launcher"
|
||||
section at the end of this file.
|
||||
|
||||
Running all the tests may take a while. Implementation details about the check
|
||||
@@ -184,8 +150,8 @@ An optional installation of the library and the headers can be performed with
|
||||
make install [PREFIX=<dir>]
|
||||
|
||||
The library will be installed in $(PREFIX)/lib, the headers in
|
||||
$(PREFIX)/include, and the configuration makefile (config.mk) in
|
||||
$(PREFIX)/share/mfem. The PREFIX option can also be set during configuration.
|
||||
$(PREFIX)/include, and the configuration makefile (config.mk) in $(PREFIX).
|
||||
The PREFIX option can also be set during configuration.
|
||||
|
||||
Information about the current build configuration can be viewed using
|
||||
|
||||
@@ -215,12 +181,9 @@ examples/ directory.
|
||||
|
||||
Configuration options (GNU make)
|
||||
================================
|
||||
See the configuration file config/defaults.mk for the default settings.
|
||||
|
||||
Compilers:
|
||||
CXX - C++ compiler, serial build
|
||||
MPICXX - MPI C++ compiler, parallel build
|
||||
CUDA_CXX - The CUDA compiler, 'nvcc'
|
||||
CXX - C++ compiler, serial build
|
||||
MPICXX - MPI C++ compiler, parallel build
|
||||
|
||||
Compiler options:
|
||||
OPTIM_FLAGS - Options for optimized build
|
||||
@@ -228,14 +191,10 @@ Compiler options:
|
||||
CXXFLAGS - If not set, defined based on the above optimized/debug flags
|
||||
CPPFLAGS - Additional compiler options
|
||||
|
||||
Build options:
|
||||
STATIC - Build a static version of the library (YES/NO), default = YES
|
||||
SHARED - Build a shared version of the library (YES/NO), default = NO
|
||||
|
||||
Installation options:
|
||||
PREFIX - Specify the installation directory. The library (libmfem.a) will be
|
||||
installed in $(PREFIX)/lib, the headers in $(PREFIX)/include, and
|
||||
the configuration makefile (config.mk) in $(PREFIX)/share/mfem.
|
||||
the configuration makefile (config.mk) in $(PREFIX).
|
||||
INSTALL - Specify the install program, e.g /usr/bin/install
|
||||
|
||||
MFEM library features/options (GNU make)
|
||||
@@ -244,21 +203,10 @@ MFEM_USE_MPI = YES/NO
|
||||
Choose parallel/serial build. The parallel build requires proper setup of the
|
||||
HYPRE_* and METIS_* library options, see below.
|
||||
|
||||
MFEM_USE_METIS = YES/NO
|
||||
Enable/disable the use of the METIS library. By default, this option is set
|
||||
to the value of MFEM_USE_MPI. If this option is explicitly disabled in a
|
||||
parallel build, then the only parallel partitioning (domain decomposition)
|
||||
option in the library will be Cartesian partitioning with box meshes, and
|
||||
thus most of the parallel examples and miniapps will fail.
|
||||
|
||||
MFEM_DEBUG = YES/NO
|
||||
Choose debug/optimized build. The debug build enables a number of messages
|
||||
and consistency checks that may simplify bug-hunting.
|
||||
|
||||
MFEM_USE_EXCEPTIONS = YES/NO
|
||||
Enable the use of exceptions. In particular, modifies the default behavior
|
||||
when errors are encountered: throw an exception, instead of aborting.
|
||||
|
||||
MFEM_USE_LIBUNWIND = YES/NO
|
||||
Use libunwind to print a stacktrace whenever mfem_error is raised. The
|
||||
information printed is enough to determine the line numbers where the
|
||||
@@ -276,26 +224,20 @@ MFEM_THREAD_SAFE = YES/NO
|
||||
Use thread-safe implementation for some classes/methods. This comes at the
|
||||
cost of extra memory allocation and de-allocation.
|
||||
|
||||
MFEM_USE_LEGACY_OPENMP = YES/NO
|
||||
Enable (basic) experimental OpenMP support. Requires MFEM_THREAD_SAFE.
|
||||
|
||||
MFEM_USE_OPENMP = YES/NO
|
||||
Enable the OpenMP backend.
|
||||
Enable (basic) experimental OpenMP support. Requires MFEM_THREAD_SAFE.
|
||||
|
||||
MFEM_USE_MEMALLOC = YES/NO
|
||||
Internal MFEM option: enable batch allocation for some small objects.
|
||||
Recommended value is YES.
|
||||
|
||||
MFEM_TIMER_TYPE = 0/1/2/3/4/5/6/NO
|
||||
MFEM_TIMER_TYPE = 0/1/2/3/NO
|
||||
Specify which library functions to use in the class StopWatch used for
|
||||
measuring time. The available options are:
|
||||
0 - use std::clock from <ctime>, standard C++
|
||||
1 - use times from <sys/times.h>
|
||||
2 - use high-resolution POSIX clocks (see option POSIX_CLOCKS_LIB)
|
||||
3 - use QueryPerformanceCounter from <windows.h>
|
||||
4 - use mach_absolute_time from <mach/mach_time.h> + std::clock (Mac)
|
||||
5 - use gettimeofday from <sys/time.h>
|
||||
6 - use MPI_Wtime from <mpi.h>
|
||||
NO - use option 3 if the compiler macro _WIN32 is defined, 0 otherwise
|
||||
|
||||
MFEM_USE_SUNDIALS = YES/NO
|
||||
@@ -319,12 +261,6 @@ MFEM_USE_SUPERLU = YES/NO
|
||||
SuperLURowLocMatrix a distributed CSR matrix class needed by SuperLU. When
|
||||
enabled, this option uses the SUPERLU_* library options, see below.
|
||||
|
||||
MFEM_USE_STRUMPACK = YES/NO
|
||||
Enable MFEM functionality based on the STRUMPACK sparse direct solver and
|
||||
preconditioner through the STRUMPACKSolver and STRUMPACKRowLocMatrix
|
||||
classes. When enabled, this option uses the STRUMPACK_* library options, see
|
||||
below.
|
||||
|
||||
MFEM_USE_GNUTLS = YES/NO
|
||||
Enable secure socket support in class socketstream, using the auxiliary
|
||||
GnuTLS_* classes, based on the GnuTLS library. This option may be useful in
|
||||
@@ -336,9 +272,6 @@ MFEM_USE_GNUTLS = YES/NO
|
||||
the script 'glvis-keygen.sh' in the main GLVis directory can be used to do
|
||||
that:
|
||||
bash glvis-keygen.sh ["Your Name"] ["Your Email"]
|
||||
In MFEM v3.3.2 and earlier, the secure authentication is based on OpenPGP
|
||||
keys, while later versions use X.509 certificates. The latest version of the
|
||||
script 'glvis-keygen.sh' can be used to generate both types of keys.
|
||||
When MFEM_USE_GNUTLS is enabled, the additional build options, GNUTLS_*, are
|
||||
also used, see below.
|
||||
|
||||
@@ -365,13 +298,6 @@ MFEM_USE_SIDRE = YES/NO
|
||||
specification. When enabled, this option requires installation of HDF5 (see
|
||||
also MFEM_USE_NETCDF), Conduit and LLNL's axom project.
|
||||
|
||||
MFEM_USE_CONDUIT = YES/NO
|
||||
Enables support for converting MFEM Mesh and Grid Function objects to and
|
||||
from Conduit Mesh Blueprint Descriptions (https://github.com/LLNL/conduit/)
|
||||
and support for JSON and Binary I/O via Conduit Relay. This option requires
|
||||
an installation of Conduit. If Conduit was built with HDF5 support, it also
|
||||
requires an installation of HDF5 (see also MFEM_USE_NETCDF).
|
||||
|
||||
MFEM_USE_GZSTREAM = YES/NO
|
||||
Enables use of on-the-fly gzip compressed streams. With this feature enabled
|
||||
(YES), MFEM can compress its output files on-the-fly. In addition, it can
|
||||
@@ -382,37 +308,6 @@ MFEM_USE_GZSTREAM = YES/NO
|
||||
able to properly read an input file if it is gzip compressed. In that case,
|
||||
the solution is to uncompress the file with an external tool (such as gunzip)
|
||||
before attempting to use it with MFEM.
|
||||
When enabled, this option uses the ZLIB_* library options, see below.
|
||||
|
||||
MFEM_USE_PUMI = YES/NO
|
||||
Enable the usage of PUMI (https://scorec.rpi.edu/pumi/) in MFEM. The Parallel
|
||||
Unstructured Mesh Infrastructure (PUMI) is an unstructured, distributed mesh
|
||||
data management system that is capable of handling general non-manifold
|
||||
models and effectively supports automated adaptive analysis. PUMI enables
|
||||
support for parallel unstructured mesh modifications in MFEM.
|
||||
|
||||
MFEM_USE_MM = YES/NO
|
||||
Enables support for the MFEM's memory manager (MM), which is required to
|
||||
support devices with different memory spaces.
|
||||
|
||||
MFEM_USE_CUDA = YES/NO
|
||||
Enables support for CUDA devices in MFEM. CUDA is a parallel computing
|
||||
platform and programming model for general computing on graphical processing
|
||||
units (GPUs). This option requires MFEM_USE_MM. The variable CUDA_ARCH is
|
||||
used to specify the CUDA compute capability used during compilation (by
|
||||
default, CUDA_ARCH=sm_60). When enabled, this option uses the CUDA_* build
|
||||
options, see below.
|
||||
|
||||
MFEM_USE_RAJA = YES/NO
|
||||
Enable support for the RAJA performance portability layer in MFEM. RAJA
|
||||
provides a portable abstraction for loops, supporting different programming
|
||||
model backends. When using the RAJA CUDA backend, MFEM_USE_MM is required.
|
||||
|
||||
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 an unified API for interacting with JIT-compiled
|
||||
backends. When using the OCCA CUDA backend, MFEM_USE_MM is required.
|
||||
|
||||
MFEM_BUILD_TAG = (any value)
|
||||
An optional tag to characterize the build. Exported to config/config.mk.
|
||||
@@ -438,8 +333,8 @@ The specific libraries and their options are:
|
||||
URL: http://www.llnl.gov/CASC/hypre
|
||||
Options: HYPRE_OPT, HYPRE_LIB.
|
||||
|
||||
- METIS, used when MFEM_USE_METIS = YES. If using METIS 5, set
|
||||
MFEM_USE_METIS_5 = YES (default is to use METIS 4).
|
||||
- METIS, required for the parallel build, i.e. when MFEM_USE_MPI = YES. If using
|
||||
METIS 5, set MFEM_USE_METIS_5 = YES (default is to use METIS 4).
|
||||
URL: http://glaros.dtc.umn.edu/gkhome/metis/metis/overview
|
||||
Options: METIS_OPT, METIS_LIB.
|
||||
|
||||
@@ -449,8 +344,7 @@ The specific libraries and their options are:
|
||||
http://math-atlas.sourceforge.net (ATLAS)
|
||||
Options: LAPACK_OPT (currently not used/needed), LAPACK_LIB.
|
||||
|
||||
- OpenMP (optional), usually part of compiler, used when either MFEM_USE_OPENMP
|
||||
or MFEM_USE_LEGACY_OPENMP is set to YES.
|
||||
- OpenMP (optional), usually part of compiler, used when MFEM_USE_OPENMP = YES.
|
||||
Options: OPENMP_OPT, OPENMP_LIB.
|
||||
|
||||
- High-resolution POSIX clocks: when using MFEM_TIMER_TYPE = 2, it may be
|
||||
@@ -458,10 +352,7 @@ The specific libraries and their options are:
|
||||
Option: POSIX_CLOCKS_LIB (default = -lrt).
|
||||
|
||||
- SUNDIALS (optional), used when MFEM_USE_SUNDIALS = YES.
|
||||
Beginning with MFEM v3.3, SUNDIALS v2.7.0 is supported.
|
||||
Beginning with MFEM v3.3.2, SUNDIALS v3.0.0 is also supported.
|
||||
If MFEM_USE_MPI is enabled, we expect that SUNDIALS is built with support for
|
||||
both MPI and hypre.
|
||||
In parallel we expect that SUNDIALS is built with support for MPI and hypre.
|
||||
URL: http://computation.llnl.gov/projects/sundials/sundials-software
|
||||
Options: SUNDIALS_OPT, SUNDIALS_LIB.
|
||||
|
||||
@@ -480,15 +371,6 @@ The specific libraries and their options are:
|
||||
URL: http://crd-legacy.lbl.gov/~xiaoye/SuperLU
|
||||
Options: SUPERLU_OPT, SUPERLU_LIB.
|
||||
|
||||
- STRUMPACK (optional), used when MFEM_USE_STRUMPACK = YES. Note that STRUMPACK
|
||||
requires the PT-Scotch and Scalapack libraries as well as ParMETIS, which
|
||||
includes METIS 5 in its distribution. Starting with STRUMPACK v2.2.0, ParMETIS
|
||||
and PT-Scotch are optional dependencies.
|
||||
The support for STRUMPACK was added in MFEM v3.3.2 and it requires STRUMPACK
|
||||
2.0.0 or later.
|
||||
URL: http://portal.nersc.gov/project/sparse/strumpack
|
||||
Options: STRUMPACK_OPT, STRUMPACK_LIB.
|
||||
|
||||
- GnuTLS (optional), used when MFEM_USE_GNUTLS = YES. On most Linux systems,
|
||||
GnuTLS is available as a development package, e.g. gnutls-devel. On Mac OS X,
|
||||
one can get the library through the Homebrew package manager (http://brew.sh).
|
||||
@@ -502,7 +384,7 @@ The specific libraries and their options are:
|
||||
URL: www.unidata.ucar.edu/software/netcdf
|
||||
Options: NETCDF_OPT, NETCDF_LIB.
|
||||
|
||||
- PETSc (optional), used when MFEM_USE_PETSC = YES. Version 3.8 or higher of
|
||||
- PETSc (optional), used when MFEM_USE_PETSC = YES. Version 3.8 or higher of
|
||||
the PETSC dev branch is required. The MFEM and PETSc builds can share common
|
||||
libraries, e.g., hypre and SUNDIALS. Here's an example configuration, assuming
|
||||
PETSc has been cloned on the same level as mfem and hypre:
|
||||
@@ -519,28 +401,6 @@ The specific libraries and their options are:
|
||||
https://support.hdfgroup.org/HDF5 (HDF5)
|
||||
Options: SIDRE_OPT, SIDRE_LIB.
|
||||
|
||||
- Conduit, used when MFEM_USE_CONDUIT = YES. Direct Conduit Mesh Blueprint
|
||||
support requires Conduit >= v0.3.1 and VisIt >= v2.13.1 to read the output.
|
||||
URL: https://github.com/LLNL/conduit (Conduit)
|
||||
https://support.hdfgroup.org/HDF5 (HDF5)
|
||||
Options: CONDUIT_OPT, CONDUIT_LIB.
|
||||
|
||||
- PUMI, used when MFEM_USE_PUMI = YES.
|
||||
URL: https://scorec.rpi.edu/pumi
|
||||
Options: PUMI_OPT, PUMI_LIB.
|
||||
|
||||
- CUDA, used when MFEM_USE_CUDA = YES.
|
||||
URL: https://developer.nvidia.com/cuda-toolkit
|
||||
Options: CUDA_CXX, CUDA_ARCH, CUDA_OPT, CUDA_LIB.
|
||||
|
||||
- OCCA, used when MFEM_USE_OCCA = YES.
|
||||
URL: https://libocca.org
|
||||
Options: OCCA_DIR, OCCA_OPT, OCCA_LIB.
|
||||
|
||||
- RAJA, used when MFEM_USE_RAJA = YES.
|
||||
URL: https://github.com/LLNL/RAJA
|
||||
Options: RAJA_DIR, RAJA_OPT, RAJA_LIB.
|
||||
|
||||
- MPFR (optional), used when MFEM_USE_MPFR = YES.
|
||||
URL: http://mpfr.org, it depends on the GMP library: https://gmplib.org
|
||||
Options: MPFR_OPT, MPFR_LIB.
|
||||
@@ -551,11 +411,6 @@ The specific libraries and their options are:
|
||||
URL: http://www.nongnu.org/libunwind
|
||||
Options: LIBUNWIND_OPT, LIBUNWIND_LIB.
|
||||
|
||||
- ZLIB (optional), used when MFEM_USE_GZSTREAM = YES, or when MFEM_USE_NETCDF =
|
||||
YES (in the default settings for NETCDF_OPT and NETCDF_LIB).
|
||||
URL: https://zlib.net
|
||||
Options: ZLIB_OPT, ZLIB_LIB.
|
||||
|
||||
|
||||
Building with CMake
|
||||
===================
|
||||
@@ -587,12 +442,6 @@ Debug and optimization options are controlled through the CMake variable
|
||||
CMAKE_BUILD_TYPE which can be set to standard values like "Debug", and "Release"
|
||||
(default).
|
||||
|
||||
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 12 2013"
|
||||
cmake <mfem-source-dir> -G "MinGW Makefiles"
|
||||
|
||||
With CMake it is possible to build MFEM as a shared library using the standard
|
||||
CMake option -DBUILD_SHARED_LIBS=1.
|
||||
|
||||
@@ -600,30 +449,15 @@ Once configured, the library can be built simply with (assuming a UNIX type
|
||||
system, where the default is to generate "UNIX Makefiles")
|
||||
|
||||
make -j 4
|
||||
or
|
||||
cmake --build .
|
||||
or
|
||||
cmake --build . --config Release [Visual Studio, Xcode]
|
||||
|
||||
The build can be quick-tested by running
|
||||
|
||||
make check
|
||||
or
|
||||
cmake --build . --target check
|
||||
or
|
||||
cmake --build . --config Release --target check [Visual Studio, Xcode]
|
||||
|
||||
which will simply compile and run Example 1/1p. For more extensive tests that
|
||||
check the results from all the serial/parallel MFEM examples and miniapps use:
|
||||
|
||||
make exec -j 4
|
||||
make test
|
||||
or
|
||||
cmake --build . --target exec
|
||||
cmake --build . --target test
|
||||
or
|
||||
cmake --build . --config Release --target exec [Visual Studio, Xcode]
|
||||
cmake --build . --config Release --target RUN_TESTS [Visual Studio, Xcode]
|
||||
|
||||
Note that running all the tests may take a while.
|
||||
|
||||
@@ -631,11 +465,6 @@ Installation prefix can be configured by setting the standard CMake variable
|
||||
CMAKE_INSTALL_PREFIX. To install the library, use
|
||||
|
||||
make install
|
||||
or
|
||||
cmake --build . --target install
|
||||
or
|
||||
cmake --build . --config Release --target install [Xcode]
|
||||
cmake --build . --config Release --target INSTALL [Visual Studio]
|
||||
|
||||
The library will be installed in <PREFIX>/lib, the headers in <PREFIX>/include,
|
||||
and the configuration CMake files in <PREFIX>/lib/cmake/mfem.
|
||||
@@ -643,8 +472,6 @@ and the configuration CMake files in <PREFIX>/lib/cmake/mfem.
|
||||
|
||||
Configuration variables (CMake)
|
||||
===============================
|
||||
See the configuration file config/defaults.cmake for the default settings.
|
||||
|
||||
Non-standard CMake variables for compilers:
|
||||
CXX - If set, overwrite the auto-detected C++ compiler, serial build
|
||||
MPICXX - If set, overwrite the auto-detected MPI C++ compiler, parallel build
|
||||
@@ -658,30 +485,19 @@ The following options are equivalent to the GNU make options with the same name:
|
||||
[see "MFEM library features/options (GNU make)" above]
|
||||
|
||||
MFEM_USE_MPI
|
||||
MFEM_USE_METIS - Set to ${MFEM_USE_MPI}, can be overwritten.
|
||||
MFEM_USE_LIBUNWIND
|
||||
MFEM_USE_LAPACK
|
||||
MFEM_THREAD_SAFE
|
||||
MFEM_USE_LEGACY_OPENMP
|
||||
MFEM_USE_OPENMP
|
||||
MFEM_USE_MEMALLOC
|
||||
MFEM_TIMER_TYPE - Set automatically, can be overwritten.
|
||||
MFEM_USE_MESQUITE
|
||||
MFEM_USE_SUITESPARSE
|
||||
MFEM_USE_SUPERLU
|
||||
MFEM_USE_STRUMPACK
|
||||
MFEM_USE_GNUTLS
|
||||
MFEM_USE_NETCDF
|
||||
MFEM_USE_MPFR
|
||||
MFEM_USE_GZSTREAM
|
||||
MFEM_USE_PUMI
|
||||
|
||||
The following GNU make options are not supported with CMake yet:
|
||||
|
||||
MFEM_USE_CUDA
|
||||
MFEM_USE_OCCA
|
||||
MFEM_USE_RAJA
|
||||
MFEM_USE_MM
|
||||
|
||||
The following options are CMake specific:
|
||||
|
||||
@@ -720,14 +536,13 @@ The CMake build system adds auto-detection for the following packages/libraries:
|
||||
- METIS - The option MFEM_USE_METIS_5 is auto-detected.
|
||||
- MESQUITE
|
||||
- SuiteSparse
|
||||
- SuperLUDist, STRUMPACK
|
||||
- SuperLUDist
|
||||
- ParMETIS
|
||||
- GNUTLS - Extends the built-in CMake support, to search GNUTLS_DIR as well.
|
||||
- NETCDF
|
||||
- MPFR
|
||||
- LIBUNWIND
|
||||
- POSIXCLOCKS
|
||||
- PUMI
|
||||
|
||||
The following built-in CMake packages are also used:
|
||||
|
||||
@@ -743,15 +558,15 @@ Before using another build system (e.g. Visual Studio) it is necessary to create
|
||||
a proper configuration header file, config/config.hpp, using the template from
|
||||
config/config.hpp.in:
|
||||
|
||||
cp config/config.hpp.in config/_config.hpp
|
||||
cp config/config.hpp.in config/config.hpp
|
||||
|
||||
The file config/_config.hpp can then be edited to enable desired options. The
|
||||
The file config/config.hpp can then be edited to enable desired options. The
|
||||
MFEM library is simply a combination of all object files obtained by compiling
|
||||
the .cpp source files in the source directories: general, linalg, mesh, and fem.
|
||||
|
||||
|
||||
Specifying an MPI job launcher
|
||||
==============================
|
||||
Specifying a MPI job launcher
|
||||
=============================
|
||||
By default, MFEM will use 'mpirun -np #' to launch any of its parallel tests or
|
||||
miniapps, where # is the number of MPI tasks. An alternate MPI launcher can be
|
||||
provided by setting the MFEM_MPIEXEC and MFEM_MPIEXEC_NP config variables.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
@@ -10,7 +10,7 @@
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -112,7 +112,7 @@ modification follow. Pay close attention to the difference between a
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
@@ -146,7 +146,7 @@ such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
@@ -432,7 +432,7 @@ decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
@@ -455,7 +455,7 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
@@ -485,8 +485,7 @@ convey the exclusion of warranty; and each file should have at least the
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -495,10 +494,11 @@ school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random
|
||||
Hacker.
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
|
||||
@@ -12,15 +12,11 @@ to enable the research and development of scalable finite element discretization
|
||||
and solver algorithms through general finite element abstractions, accurate and
|
||||
flexible visualization, and tight integration with the hypre library.
|
||||
|
||||
* For building instructions, see the file INSTALL, or type "make help".
|
||||
For building instructions, see the file INSTALL, or type "make help". Copyright
|
||||
information and licensing restrictions can be found in the file COPYRIGHT.
|
||||
|
||||
* Copyright and licensing information can be found in the file COPYRIGHT.
|
||||
|
||||
* The best starting point for new users interested in MFEM's features is the
|
||||
interactive documentation in examples/README.html.
|
||||
|
||||
* Developers interested in contributing to the library, should read the
|
||||
instructions and documentation in the CONTRIBUTING.md file.
|
||||
The best starting point for new users interested in MFEM's features is the
|
||||
interactive documentation in examples/README.html.
|
||||
|
||||
Conceptually, MFEM can be viewed as a finite element toolbox that provides the
|
||||
building blocks for developing finite element algorithms in a manner similar to
|
||||
@@ -60,8 +56,7 @@ time integrators, etc.
|
||||
For examples of using MFEM, see the examples/ and miniapps/ directories, as well
|
||||
as the OpenGL visualization tool GLVis which is available at http://glvis.org.
|
||||
|
||||
This project is released under the LGPL v2.1 license with static linking
|
||||
exception. See files COPYRIGHT and LICENSE file for full details.
|
||||
This project is released under the LGPL v2.1 license. See LICENSE file for full
|
||||
details.
|
||||
|
||||
LLNL Release Number: LLNL-CODE-443211
|
||||
DOI: 10.11578/dc.20171025.1248
|
||||
|
||||
@@ -1,254 +0,0 @@
|
||||
##################################################################################
|
||||
#
|
||||
# Set defaults for XSDK CMake projects
|
||||
#
|
||||
##################################################################################
|
||||
|
||||
#
|
||||
# This module implements standard behavior for XSDK CMake projects. The main
|
||||
# thing it does in XSDK mode (i.e. USE_XSDK_DEFAULTS=TRUE) is to print out
|
||||
# when the env vars CC, CXX, FC and compiler flags CFLAGS, CXXFLAGS, and
|
||||
# FFLAGS/FCFLAGS are used to select the compilers and compiler flags (raw
|
||||
# CMake does this silently) and to set BUILD_SHARED_LIBS=TRUE and
|
||||
# CMAKE_BUILD_TYPE=DEBUG by default. It does not implement *all* of the
|
||||
# standard XSDK configuration parameters. The parent CMake project must do
|
||||
# that.
|
||||
#
|
||||
# Note that when USE_XSDK_DEFAULTS=TRUE, then the Fortran flags will be read
|
||||
# from either of the env vars FFLAGS or FCFLAGS. If both are set, but are the
|
||||
# same, then FFLAGS it used (which is the same as FCFLAGS). However, if both
|
||||
# are set but are not equal, then a FATAL_ERROR is raised and CMake configure
|
||||
# processing is stopped.
|
||||
#
|
||||
# To be used in a parent project, this module must be included after
|
||||
#
|
||||
# PROJECT(${PROJECT_NAME} NONE)
|
||||
#
|
||||
# is called but before the compilers are defined and processed using:
|
||||
#
|
||||
# ENABLE_LANGUAGE(<LANG>)
|
||||
#
|
||||
# For example, one would do:
|
||||
#
|
||||
# PROJECT(${PROJECT_NAME} NONE)
|
||||
# ...
|
||||
# SET(USE_XSDK_DEFAULTS_DEFAULT TRUE) # Set to false if desired
|
||||
# INCLUDE("${CMAKE_CURRENT_SOURCE_DIR}/stdk/XSDKDefaults.cmake")
|
||||
# ...
|
||||
# ENABLE_LANGUAGE(C)
|
||||
# ENABLE_LANGUAGE(C++)
|
||||
# ENABLE_LANGUAGE(Fortran)
|
||||
#
|
||||
# The variable `USE_XSDK_DEFAULTS_DEFAULT` is used as the default for the
|
||||
# cache var `USE_XSDK_DEFAULTS`. That way, a project can decide if it wants
|
||||
# XSDK defaults turned on or off by default and users can independently decide
|
||||
# if they want the CMake project to use standard XSDK behavior or raw CMake
|
||||
# behavior.
|
||||
#
|
||||
# By default, the XSDKDefaults.cmake module assumes that the project will need
|
||||
# C, C++, and Fortran. If any language is not needed then, set
|
||||
# XSDK_ENABLE_C=OFF, XSDK_ENABLE_CXX=OFF, or XSDK_ENABLE_Fortran=OFF *before*
|
||||
# including this module. Note, these variables are *not* cache vars because a
|
||||
# project either does or does not have C, C++ or Fortran source files, the
|
||||
# user has nothing to do with this so there is no need for cache vars. The
|
||||
# parent CMake project just needs to tell XSDKDefault.cmake what languages is
|
||||
# needs or does not need.
|
||||
#
|
||||
# For example, if the parent CMake project only needs C, then it would do:
|
||||
#
|
||||
# PROJECT(${PROJECT_NAME} NONE)'
|
||||
# ...
|
||||
# SET(USE_XSDK_DEFAULTS_DEFAULT TRUE)
|
||||
# SET(XSDK_ENABLE_CXX OFF)
|
||||
# SET(XSDK_ENABLE_Fortran OFF)
|
||||
# INCLUDE("${CMAKE_CURRENT_SOURCE_DIR}/stdk/XSDKDefaults.cmake")
|
||||
# ...
|
||||
# ENABLE_LANGAUGE(C)
|
||||
#
|
||||
# This module code will announce when it sets any variables.
|
||||
#
|
||||
|
||||
#
|
||||
# Helper functions
|
||||
#
|
||||
|
||||
IF (NOT COMMAND PRINT_VAR)
|
||||
FUNCTION(PRINT_VAR VAR_NAME)
|
||||
MESSAGE("-- " "${VAR_NAME} = '${${VAR_NAME}}'")
|
||||
ENDFUNCTION()
|
||||
ENDIF()
|
||||
|
||||
IF (NOT COMMAND SET_DEFAULT)
|
||||
MACRO(SET_DEFAULT VAR)
|
||||
IF ("${${VAR}}" STREQUAL "")
|
||||
SET(${VAR} ${ARGN})
|
||||
ENDIF()
|
||||
ENDMACRO()
|
||||
ENDIF()
|
||||
|
||||
#
|
||||
# XSDKDefaults.cmake control variables
|
||||
#
|
||||
|
||||
# USE_XSDK_DEFAULTS
|
||||
IF ("${USE_XSDK_DEFAULTS_DEFAULT}" STREQUAL "")
|
||||
SET(USE_XSDK_DEFAULTS_DEFAULT FALSE)
|
||||
ENDIF()
|
||||
SET(USE_XSDK_DEFAULTS ${USE_XSDK_DEFAULTS_DEFAULT} CACHE BOOL
|
||||
"Use XSDK defaults and behavior.")
|
||||
PRINT_VAR(USE_XSDK_DEFAULTS)
|
||||
|
||||
SET_DEFAULT(XSDK_ENABLE_C TRUE)
|
||||
SET_DEFAULT(XSDK_ENABLE_CXX TRUE)
|
||||
SET_DEFAULT(XSDK_ENABLE_Fortran TRUE)
|
||||
|
||||
# Handle the compiler and flags for a language
|
||||
MACRO(XSDK_HANDLE_LANG_DEFAULTS CMAKE_LANG_NAME ENV_LANG_NAME
|
||||
ENV_LANG_FLAGS_NAMES
|
||||
)
|
||||
|
||||
# Announce using env var ${ENV_LANG_NAME}
|
||||
IF (NOT "$ENV{${ENV_LANG_NAME}}" STREQUAL "" AND
|
||||
"${CMAKE_${CMAKE_LANG_NAME}_COMPILER}" STREQUAL ""
|
||||
)
|
||||
MESSAGE("-- " "XSDK: Setting CMAKE_${CMAKE_LANG_NAME}_COMPILER from env var"
|
||||
" ${ENV_LANG_NAME}='$ENV{${ENV_LANG_NAME}}'!")
|
||||
SET(CMAKE_${CMAKE_LANG_NAME}_COMPILER "$ENV{${ENV_LANG_NAME}}" CACHE FILEPATH
|
||||
"XSDK: Set by default from env var ${ENV_LANG_NAME}")
|
||||
ENDIF()
|
||||
|
||||
# Announce using env var ${ENV_LANG_FLAGS_NAME}
|
||||
FOREACH(ENV_LANG_FLAGS_NAME ${ENV_LANG_FLAGS_NAMES})
|
||||
IF (NOT "$ENV{${ENV_LANG_FLAGS_NAME}}" STREQUAL "" AND
|
||||
"${CMAKE_${CMAKE_LANG_NAME}_FLAGS}" STREQUAL ""
|
||||
)
|
||||
MESSAGE("-- " "XSDK: Setting CMAKE_${CMAKE_LANG_NAME}_FLAGS from env var"
|
||||
" ${ENV_LANG_FLAGS_NAME}='$ENV{${ENV_LANG_FLAGS_NAME}}'!")
|
||||
SET(CMAKE_${CMAKE_LANG_NAME}_FLAGS "$ENV{${ENV_LANG_FLAGS_NAME}} " CACHE STRING
|
||||
"XSDK: Set by default from env var ${ENV_LANG_FLAGS_NAME}")
|
||||
# NOTE: CMake adds the space after $ENV{${ENV_LANG_FLAGS_NAME}} so we
|
||||
# duplicate that here!
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
|
||||
ENDMACRO()
|
||||
|
||||
|
||||
#
|
||||
# Set XSDK Defaults
|
||||
#
|
||||
|
||||
# Set default compilers and flags
|
||||
IF (USE_XSDK_DEFAULTS)
|
||||
|
||||
# Handle env vars for languages C, C++, and Fortran
|
||||
|
||||
IF (XSDK_ENABLE_C)
|
||||
XSDK_HANDLE_LANG_DEFAULTS(C CC CFLAGS)
|
||||
ENDIF()
|
||||
|
||||
IF (XSDK_ENABLE_CXX)
|
||||
XSDK_HANDLE_LANG_DEFAULTS(CXX CXX CXXFLAGS)
|
||||
ENDIF()
|
||||
|
||||
IF (XSDK_ENABLE_Fortran)
|
||||
SET(ENV_FFLAGS "$ENV{FFLAGS}")
|
||||
SET(ENV_FCFLAGS "$ENV{FCFLAGS}")
|
||||
IF (
|
||||
(NOT "${ENV_FFLAGS}" STREQUAL "") AND (NOT "${ENV_FCFLAGS}" STREQUAL "")
|
||||
AND
|
||||
("${CMAKE_Fortran_FLAGS}" STREQUAL "")
|
||||
)
|
||||
IF (NOT "${ENV_FFLAGS}" STREQUAL "${ENV_FCFLAGS}")
|
||||
MESSAGE(FATAL_ERROR "Error, env vars FFLAGS='${ENV_FFLAGS}' and"
|
||||
" FCFLAGS='${ENV_FCFLAGS}' are both set in the env but are not equal!")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
XSDK_HANDLE_LANG_DEFAULTS(Fortran FC "FFLAGS;FCFLAGS")
|
||||
ENDIF()
|
||||
|
||||
# Set XSDK defaults for other CMake variables
|
||||
|
||||
IF ("${BUILD_SHARED_LIBS}" STREQUAL "")
|
||||
MESSAGE("-- " "XSDK: Setting default BUILD_SHARED_LIBS=TRUE")
|
||||
SET(BUILD_SHARED_LIBS TRUE CACHE BOOL "Set by default in XSDK mode")
|
||||
ENDIF()
|
||||
|
||||
IF ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
MESSAGE("-- " "XSDK: Setting default CMAKE_BUILD_TYPE=DEBUG")
|
||||
SET(CMAKE_BUILD_TYPE DEBUG CACHE STRING "Set by default in XSDK mode")
|
||||
ENDIF()
|
||||
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_MPI)
|
||||
SET(MFEM_USE_MPI ${TPL_ENABLE_MPI} CACHE BOOL "Enable MPI parallel build" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_METIS)
|
||||
SET(MFEM_USE_METIS ${TPL_ENABLE_METIS} CACHE BOOL "Enable METIS usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_GZSTREAM)
|
||||
SET(MFEM_USE_GZSTREAM ${TPL_ENABLE_GZSTREAM} CACHE BOOL "Enable gzstream for compressed data streams." FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_LIBUNWIND)
|
||||
SET(MFEM_USE_LIBUNWIND ${TPL_ENABLE_LIBUNWIND} CACHE BOOL "Enable backtrace for errors." FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_LAPACK)
|
||||
SET(MFEM_USE_LAPACK ${TPL_ENABLE_LAPACK} CACHE BOOL "Enable LAPACK usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_SUNDIALS)
|
||||
SET(MFEM_USE_SUNDIALS ${TPL_ENABLE_SUNDIALS} CACHE BOOL "Enable SUNDIALS usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_MESQUITE)
|
||||
SET(MFEM_USE_MESQUITE ${TPL_ENABLE_MESQUITE} CACHE BOOL "Enable MESQUITE usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_SUITESPARSE)
|
||||
SET(MFEM_USE_SUITESPARSE ${TPL_ENABLE_SUITESPARSE} CACHE BOOL "Enable SuiteSparse usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_SUPERLU)
|
||||
SET(MFEM_USE_SUPERLU ${TPL_ENABLE_SUPERLU} CACHE BOOL "Enable SuperLU_DIST usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_STRUMPACK)
|
||||
SET(MFEM_USE_STRUMPACK ${TPL_ENABLE_STRUMPACK} CACHE BOOL "Enable STRUMPACK usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_GECKO)
|
||||
SET(MFEM_USE_GECKO ${TPL_ENABLE_GECKO} CACHE BOOL "Enable GECKO usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_GNUTLS)
|
||||
SET(MFEM_USE_GNUTLS ${TPL_ENABLE_GNUTLS} CACHE BOOL "Enable GNUTLS usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_NETCDF)
|
||||
SET(MFEM_USE_NETCDF ${TPL_ENABLE_NETCDF} CACHE BOOL "Enable NETCDF usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_PETSC)
|
||||
SET(MFEM_USE_PETSC ${TPL_ENABLE_PETSC} CACHE BOOL "Enable PETSc support." FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_MPFR)
|
||||
SET(MFEM_USE_MPFR ${TPL_ENABLE_MPFR} CACHE BOOL "Enable MPFR usage." FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_SIDRE)
|
||||
SET(MFEM_USE_SIDRE ${TPL_ENABLE_SIDRE} CACHE BOOL "Enable Axom/Sidre usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_CONDUIT)
|
||||
SET(MFEM_USE_CONDUIT ${TPL_ENABLE_CONDUIT} CACHE BOOL "Enable Conduit usage" FORCE)
|
||||
ENDIF()
|
||||
|
||||
IF (DEFINED TPL_ENABLE_PUMI)
|
||||
SET(MFEM_USE_PUMI ${TPL_ENABLE_PUMI} CACHE BOOL "Enable PUMI" FORCE)
|
||||
ENDIF()
|
||||
@@ -12,43 +12,31 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/MFEMConfigVersion.cmake)
|
||||
|
||||
set(MFEM_VERSION ${PACKAGE_VERSION})
|
||||
set(MFEM_VERSION_INT @MFEM_VERSION@)
|
||||
set(MFEM_GIT_STRING "@MFEM_GIT_STRING@")
|
||||
|
||||
set(MFEM_USE_MPI @MFEM_USE_MPI@)
|
||||
set(MFEM_USE_METIS @MFEM_USE_METIS@)
|
||||
set(MFEM_USE_METIS_5 @MFEM_USE_METIS_5@)
|
||||
set(MFEM_DEBUG @MFEM_DEBUG@)
|
||||
set(MFEM_USE_EXCEPTIONS @MFEM_USE_EXCEPTIONS@)
|
||||
set(MFEM_USE_GZSTREAM @MFEM_USE_GZSTREAM@)
|
||||
set(MFEM_USE_LIBUNWIND @MFEM_USE_LIBUNWIND@)
|
||||
set(MFEM_USE_LAPACK @MFEM_USE_LAPACK@)
|
||||
set(MFEM_THREAD_SAFE @MFEM_THREAD_SAFE@)
|
||||
set(MFEM_USE_OPENMP @MFEM_USE_OPENMP@)
|
||||
set(MFEM_USE_LEGACY_OPENMP @MFEM_USE_LEGACY_OPENMP@)
|
||||
set(MFEM_USE_MEMALLOC @MFEM_USE_MEMALLOC@)
|
||||
set(MFEM_TIMER_TYPE @MFEM_TIMER_TYPE@)
|
||||
set(MFEM_USE_SUNDIALS @MFEM_USE_SUNDIALS@)
|
||||
set(MFEM_USE_MESQUITE @MFEM_USE_MESQUITE@)
|
||||
set(MFEM_USE_SUITESPARSE @MFEM_USE_SUITESPARSE@)
|
||||
set(MFEM_USE_SUPERLU @MFEM_USE_SUPERLU@)
|
||||
set(MFEM_USE_STRUMPACK @MFEM_USE_STRUMPACK@)
|
||||
set(MFEM_USE_GECKO @MFEM_USE_GECKO@)
|
||||
set(MFEM_USE_GNUTLS @MFEM_USE_GNUTLS@)
|
||||
set(MFEM_USE_NETCDF @MFEM_USE_NETCDF@)
|
||||
set(MFEM_USE_PETSC @MFEM_USE_PETSC@)
|
||||
set(MFEM_USE_MPFR @MFEM_USE_MPFR@)
|
||||
set(MFEM_USE_SIDRE @MFEM_USE_SIDRE@)
|
||||
set(MFEM_USE_CONDUIT @MFEM_USE_CONDUIT@)
|
||||
set(MFEM_USE_PUMI @MFEM_USE_PUMI@)
|
||||
|
||||
set(MFEM_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
|
||||
set(MFEM_CXX_FLAGS "@CMAKE_CXX_FLAGS@")
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set(MFEM_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIRS@")
|
||||
foreach (dir ${MFEM_INCLUDE_DIRS})
|
||||
message("DIR = ${dir}")
|
||||
|
||||
set_and_check(MFEM_INCLUDE_DIR "${dir}")
|
||||
endforeach (dir "${MFEM_INCLUDE_DIRS}")
|
||||
|
||||
|
||||
@@ -12,27 +12,6 @@
|
||||
#ifndef MFEM_CONFIG_HEADER
|
||||
#define MFEM_CONFIG_HEADER
|
||||
|
||||
// MFEM version: integer of the form: (major*100 + minor)*100 + patch.
|
||||
#cmakedefine MFEM_VERSION @MFEM_VERSION@
|
||||
|
||||
// MFEM version string of the form "3.3" or "3.3.1".
|
||||
#cmakedefine MFEM_VERSION_STRING "@MFEM_VERSION_STRING@"
|
||||
|
||||
// MFEM version type, see the MFEM_VERSION_TYPE_* constants below.
|
||||
#define MFEM_VERSION_TYPE ((MFEM_VERSION)%2)
|
||||
|
||||
// MFEM version type constants.
|
||||
#define MFEM_VERSION_TYPE_RELEASE 0
|
||||
#define MFEM_VERSION_TYPE_DEVELOPMENT 1
|
||||
|
||||
// Separate MFEM version numbers for major, minor, and patch.
|
||||
#define MFEM_VERSION_MAJOR ((MFEM_VERSION)/10000)
|
||||
#define MFEM_VERSION_MINOR (((MFEM_VERSION)/100)%100)
|
||||
#define MFEM_VERSION_PATCH ((MFEM_VERSION)%100)
|
||||
|
||||
// Description of the git commit used to build MFEM.
|
||||
#cmakedefine MFEM_GIT_STRING "@MFEM_GIT_STRING@"
|
||||
|
||||
// Build the parallel MFEM library.
|
||||
// Requires an MPI compiler, and the libraries HYPRE and METIS.
|
||||
#cmakedefine MFEM_USE_MPI
|
||||
@@ -40,18 +19,12 @@
|
||||
// Enable debug checks in MFEM.
|
||||
#cmakedefine MFEM_DEBUG
|
||||
|
||||
// Throw an exception on errors.
|
||||
#cmakedefine MFEM_USE_EXCEPTIONS
|
||||
|
||||
// Enable gzstream in MFEM.
|
||||
#cmakedefine MFEM_USE_GZSTREAM
|
||||
|
||||
// Enable backtraces for mfem_error through libunwind.
|
||||
#cmakedefine MFEM_USE_LIBUNWIND
|
||||
|
||||
// Enable MFEM features that use the METIS library (parallel MFEM).
|
||||
#cmakedefine MFEM_USE_METIS
|
||||
|
||||
// Enable this option if linking with METIS version 5 (parallel MFEM).
|
||||
#cmakedefine MFEM_USE_METIS_5
|
||||
|
||||
@@ -62,12 +35,9 @@
|
||||
// allocation and de-allocation.
|
||||
#cmakedefine MFEM_THREAD_SAFE
|
||||
|
||||
// Enable the OpenMP backend.
|
||||
// Enable experimental OpenMP support. Requires MFEM_THREAD_SAFE.
|
||||
#cmakedefine MFEM_USE_OPENMP
|
||||
|
||||
// [Deprecated] Enable experimental OpenMP support. Requires MFEM_THREAD_SAFE.
|
||||
#cmakedefine MFEM_USE_LEGACY_OPENMP
|
||||
|
||||
// Enable MFEM functionality based on the Mesquite library.
|
||||
#cmakedefine MFEM_USE_MESQUITE
|
||||
|
||||
@@ -77,9 +47,6 @@
|
||||
// Enable MFEM functionality based on the SuperLU_DIST library.
|
||||
#cmakedefine MFEM_USE_SUPERLU
|
||||
|
||||
// Enable MFEM functionality based on the STRUMPACK library.
|
||||
#cmakedefine MFEM_USE_STRUMPACK
|
||||
|
||||
// Internal MFEM option: enable group/batch allocation for some small objects.
|
||||
#cmakedefine MFEM_USE_MEMALLOC
|
||||
|
||||
@@ -98,25 +65,20 @@
|
||||
// Enable MFEM functionality based on the Sidre library
|
||||
#cmakedefine MFEM_USE_SIDRE
|
||||
|
||||
// Enable MFEM functionality based on Conduit
|
||||
#cmakedefine MFEM_USE_CONDUIT
|
||||
|
||||
// Enable MFEM functionality based on the PUMI library
|
||||
#cmakedefine MFEM_USE_PUMI
|
||||
|
||||
// Which library functions to use in class StopWatch for measuring time.
|
||||
// For a list of the available options, see INSTALL.
|
||||
// The available options are:
|
||||
// 0 - use std::clock from <ctime>
|
||||
// 1 - use times from <sys/times.h>
|
||||
// 2 - use high-resolution POSIX clocks
|
||||
// 3 - use QueryPerformanceCounter from <windows.h>
|
||||
// If not defined, an option is selected automatically.
|
||||
#define MFEM_TIMER_TYPE @MFEM_TIMER_TYPE@
|
||||
|
||||
// Enable MFEM functionality based on the SUNDIALS libraries.
|
||||
#cmakedefine MFEM_USE_SUNDIALS
|
||||
|
||||
// Version of HYPRE used for building MFEM.
|
||||
#cmakedefine MFEM_HYPRE_VERSION @MFEM_HYPRE_VERSION@
|
||||
|
||||
// Macro defined when PUMI is built with support for the Simmetrix SimModSuite
|
||||
// library.
|
||||
#cmakedefine MFEM_USE_SIMMETRIX
|
||||
// Windows specific options
|
||||
// Macro needed to get defines like M_PI from <cmath>. (Visual Studio C++ only?)
|
||||
#cmakedefine _USE_MATH_DEFINES
|
||||
|
||||
#endif // MFEM_CONFIG_HEADER
|
||||
|
||||
@@ -10,14 +10,15 @@
|
||||
# Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
# Defines the following variables:
|
||||
# - AXOM_FOUND
|
||||
# - AXOM_LIBRARIES
|
||||
# - AXOM_INCLUDE_DIRS
|
||||
# - ATK_FOUND
|
||||
# - ATK_LIBRARIES
|
||||
# - ATK_INCLUDE_DIRS
|
||||
|
||||
include(MfemCmakeUtilities)
|
||||
# Note: components are enabled based on the find_package() parameters.
|
||||
mfem_find_package(Axom AXOM AXOM_DIR "include" "" "lib" ""
|
||||
"Paths to headers required by Axom." "Libraries required by Axom."
|
||||
mfem_find_package(ATK ATK ATK_DIR "include" "" "lib" ""
|
||||
"Paths to headers required by ATK." "Libraries required by ATK."
|
||||
ADD_COMPONENT Sidre "include" sidre/sidre.hpp "lib" sidre
|
||||
ADD_COMPONENT SPIO "include" spio/IOManager.hpp "lib" spio
|
||||
ADD_COMPONENT SLIC "include" slic/slic.hpp "lib" slic
|
||||
ADD_COMPONENT axom_utils "include" axom_utils/Utilities.hpp "lib" axom_utils)
|
||||
ADD_COMPONENT common "include" common/ATKMacros.hpp "lib" common)
|
||||
@@ -14,22 +14,9 @@
|
||||
# - CONDUIT_LIBRARIES
|
||||
# - CONDUIT_INCLUDE_DIRS
|
||||
|
||||
# check to see if relay requires hdf5, if so make sure to set HDF5
|
||||
# as a required dep
|
||||
if(EXISTS ${CONDUIT_DIR}/include/conduit/conduit_relay_hdf5.hpp)
|
||||
message(STATUS "Conduit Relay HDF5 Support is ENABLED")
|
||||
# we only need HDF5 if Conduit was built with HDF5 support
|
||||
set(Conduit_REQUIRED_PACKAGES "HDF5" CACHE STRING
|
||||
"Additional packages required by Conduit.")
|
||||
else()
|
||||
message(STATUS "Conduit Relay HDF5 Support is DISABLED")
|
||||
endif()
|
||||
|
||||
include(MfemCmakeUtilities)
|
||||
mfem_find_package(Conduit CONDUIT CONDUIT_DIR
|
||||
"include;include/conduit" conduit.hpp "lib" conduit
|
||||
"Paths to headers required by Conduit." "Libraries required by Conduit."
|
||||
ADD_COMPONENT relay
|
||||
"include;include/conduit" conduit_relay.hpp "lib" conduit_relay
|
||||
ADD_COMPONENT blueprint
|
||||
"include;include/conduit" conduit_blueprint.hpp "lib" conduit_blueprint)
|
||||
"include;include/conduit" conduit_relay.hpp "lib" conduit_relay)
|
||||
|
||||
@@ -13,23 +13,7 @@
|
||||
# - HYPRE_FOUND
|
||||
# - HYPRE_LIBRARIES
|
||||
# - HYPRE_INCLUDE_DIRS
|
||||
# - HYPRE_VERSION
|
||||
|
||||
include(MfemCmakeUtilities)
|
||||
mfem_find_package(HYPRE HYPRE HYPRE_DIR "include" "HYPRE.h" "lib" "HYPRE"
|
||||
"Paths to headers required by HYPRE." "Libraries required by HYPRE.")
|
||||
|
||||
if (HYPRE_FOUND AND (NOT HYPRE_VERSION))
|
||||
try_run(HYPRE_VERSION_RUN_RESULT HYPRE_VERSION_COMPILE_RESULT
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/config/get_hypre_version.cpp
|
||||
CMAKE_FLAGS -DINCLUDE_DIRECTORIES:STRING=${HYPRE_INCLUDE_DIRS}
|
||||
RUN_OUTPUT_VARIABLE HYPRE_VERSION_OUTPUT)
|
||||
if ((HYPRE_VERSION_RUN_RESULT EQUAL 0) AND HYPRE_VERSION_OUTPUT)
|
||||
string(STRIP "${HYPRE_VERSION_OUTPUT}" HYPRE_VERSION)
|
||||
set(HYPRE_VERSION ${HYPRE_VERSION} CACHE STRING "HYPRE version." FORCE)
|
||||
message(STATUS "Found HYPRE version ${HYPRE_VERSION}")
|
||||
else()
|
||||
message(FATAL_ERROR "Unable to determine HYPRE version.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at the
|
||||
# Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights reserved.
|
||||
# See file COPYRIGHT for details.
|
||||
#
|
||||
# This file is part of the MFEM library. For more information and source code
|
||||
# availability see http://mfem.org.
|
||||
#
|
||||
# MFEM is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License (as published by the Free
|
||||
# Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
# Sets the following variables:
|
||||
# - STRUMPACK_FOUND
|
||||
# - STRUMPACK_INCLUDE_DIRS
|
||||
# - STRUMPACK_LIBRARIES
|
||||
|
||||
include(MfemCmakeUtilities)
|
||||
mfem_find_package(STRUMPACK STRUMPACK STRUMPACK_DIR
|
||||
"include" "StrumpackSparseSolverMPIDist.hpp"
|
||||
"lib" "strumpack;strumpack_sparse" # add NAMES_PER_DIR?
|
||||
"Paths to headers required by STRUMPACK."
|
||||
"Libraries required by STRUMPACK."
|
||||
CHECK_BUILD STRUMPACK_VERSION_OK TRUE
|
||||
"
|
||||
#include <StrumpackSparseSolverMPIDist.hpp>
|
||||
using namespace strumpack;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm comm = MPI_COMM_WORLD;
|
||||
StrumpackSparseSolverMPIDist<double,int> solver(comm, argc, argv, false);
|
||||
solver.options().set_from_command_line();
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
)
|
||||
@@ -1,29 +0,0 @@
|
||||
# Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at the
|
||||
# Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights reserved.
|
||||
# See file COPYRIGHT for details.
|
||||
#
|
||||
# This file is part of the MFEM library. For more information and source code
|
||||
# availability see http://mfem.org.
|
||||
#
|
||||
# MFEM is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License (as published by the Free
|
||||
# Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
# Sets the following variables:
|
||||
# - Scotch_FOUND
|
||||
# - Scotch_INCLUDE_DIRS
|
||||
# - Scotch_LIBRARIES
|
||||
|
||||
include(MfemCmakeUtilities)
|
||||
mfem_find_package(Scotch Scotch Scotch_DIR "" "" "" ""
|
||||
"Paths to headers required by Scotch."
|
||||
"Libraries required by Scotch."
|
||||
ADD_COMPONENT "scotch" "include" scotch.h "lib" scotch
|
||||
ADD_COMPONENT "scotcherr" "" "" "lib" scotcherr
|
||||
ADD_COMPONENT "scotcherrexit" "" "" "lib" scotcherrexit
|
||||
ADD_COMPONENT "scotchmetis" "include" "metis.h" "lib" scotchmetis
|
||||
ADD_COMPONENT "ptscotch" "include" ptscotch.h "lib" ptscotch
|
||||
ADD_COMPONENT "ptscotcherr" "" "" "lib" ptscotcherr
|
||||
ADD_COMPONENT "ptscotcherrexit" "" "" "lib" ptscotcherrexit
|
||||
ADD_COMPONENT "ptscotchparmetis" "include" "parmetis.h" "lib" ptscotchparmetis
|
||||
)
|
||||
@@ -9,30 +9,6 @@
|
||||
# terms of the GNU Lesser General Public License (as published by the Free
|
||||
# Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
# Function that converts a version string of the form 'major[.minor[.patch]]' to
|
||||
# the integer ((major * 100) + minor) * 100 + patch.
|
||||
function(mfem_version_to_int VersionString VersionIntVar)
|
||||
if ("${VersionString}" MATCHES "^([0-9]+)(.*)$")
|
||||
set(Major "${CMAKE_MATCH_1}")
|
||||
set(MinorPatchString "${CMAKE_MATCH_2}")
|
||||
else()
|
||||
set(Major 0)
|
||||
endif()
|
||||
if ("${MinorPatchString}" MATCHES "^\\.([0-9]+)(.*)$")
|
||||
set(Minor "${CMAKE_MATCH_1}")
|
||||
set(PatchString "${CMAKE_MATCH_2}")
|
||||
else()
|
||||
set(Minor 0)
|
||||
endif()
|
||||
if ("${PatchString}" MATCHES "^\\.([0-9]+)(.*)$")
|
||||
set(Patch "${CMAKE_MATCH_1}")
|
||||
else()
|
||||
set(Patch 0)
|
||||
endif()
|
||||
math(EXPR VersionInt "(${Major}*100+${Minor})*100+${Patch}")
|
||||
set(${VersionIntVar} ${VersionInt} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# A handy function to add the current source directory to a local
|
||||
# filename. To be used for creating a list of sources.
|
||||
function(convert_filenames_to_full_paths NAMES)
|
||||
@@ -74,8 +50,10 @@ function(add_mfem_examples EXE_SRCS)
|
||||
|
||||
string(REPLACE ".cpp" "" EXE_NAME "${EXE_PREFIX}${SRC_FILENAME}")
|
||||
add_executable(${EXE_NAME} ${SRC_FILE})
|
||||
add_dependencies(${MFEM_ALL_EXAMPLES_TARGET_NAME} ${EXE_NAME})
|
||||
if (EXE_NEEDED_BY)
|
||||
# If given a prefix, don't add the example to the list of examples to build.
|
||||
if (NOT EXE_PREFIX)
|
||||
add_dependencies(${MFEM_ALL_EXAMPLES_TARGET_NAME} ${EXE_NAME})
|
||||
elseif (EXE_NEEDED_BY)
|
||||
add_dependencies(${EXE_NEEDED_BY} ${EXE_NAME})
|
||||
endif()
|
||||
add_dependencies(${EXE_NAME}
|
||||
@@ -83,8 +61,7 @@ function(add_mfem_examples EXE_SRCS)
|
||||
|
||||
target_link_libraries(${EXE_NAME} mfem)
|
||||
if (MFEM_USE_MPI)
|
||||
# Not needed: (mfem already links with MPI_CXX_LIBRARIES)
|
||||
# target_link_libraries(${EXE_NAME} ${MPI_CXX_LIBRARIES})
|
||||
target_link_libraries(${EXE_NAME} ${MPI_CXX_LIBRARIES})
|
||||
|
||||
# Language-specific include directories:
|
||||
if (MPI_CXX_INCLUDE_PATH)
|
||||
@@ -155,7 +132,6 @@ function(add_mfem_miniapp MFEM_EXE_NAME)
|
||||
|
||||
# Handle the MPI separately
|
||||
if (MFEM_USE_MPI)
|
||||
# Add MPI_CXX_LIBRARIES, in case this target does not link with mfem.
|
||||
if(CMAKE_VERSION VERSION_GREATER 2.8.11)
|
||||
target_link_libraries(${MFEM_EXE_NAME} PRIVATE ${MPI_CXX_LIBRARIES})
|
||||
else()
|
||||
@@ -183,26 +159,26 @@ function(mfem_find_component Prefix DirVar IncSuffixes Header LibSuffixes Lib
|
||||
|
||||
if (Lib)
|
||||
if (${DirVar} OR EnvDirVar)
|
||||
find_library(${Prefix}_LIBRARY ${Lib}
|
||||
find_library(${Prefix}_LIBRARIES ${Lib}
|
||||
HINTS ${${DirVar}} ENV ${DirVar}
|
||||
PATH_SUFFIXES ${LibSuffixes}
|
||||
NO_DEFAULT_PATH
|
||||
DOC "${LibDoc}")
|
||||
endif()
|
||||
find_library(${Prefix}_LIBRARY ${Lib}
|
||||
find_library(${Prefix}_LIBRARIES ${Lib}
|
||||
PATH_SUFFIXES ${LibSuffixes}
|
||||
DOC "${LibDoc}")
|
||||
endif()
|
||||
|
||||
if (Header)
|
||||
if (${DirVar} OR EnvDirVar)
|
||||
find_path(${Prefix}_INCLUDE_DIR ${Header}
|
||||
find_path(${Prefix}_INCLUDE_DIRS ${Header}
|
||||
HINTS ${${DirVar}} ENV ${DirVar}
|
||||
PATH_SUFFIXES ${IncSuffixes}
|
||||
NO_DEFAULT_PATH
|
||||
DOC "${IncDoc}")
|
||||
endif()
|
||||
find_path(${Prefix}_INCLUDE_DIR ${Header}
|
||||
find_path(${Prefix}_INCLUDE_DIRS ${Header}
|
||||
PATH_SUFFIXES ${IncSuffixes}
|
||||
DOC "${IncDoc}")
|
||||
endif()
|
||||
@@ -214,9 +190,8 @@ endfunction(mfem_find_component)
|
||||
# successful, optionally checks building (compile + link) one or more given
|
||||
# code snippets. Additionally, a list of required/optional/alternative
|
||||
# packages (given by ${Name}_REQUIRED_PACKAGES) are searched for and added to
|
||||
# the ${Prefix}_INCLUDE_DIRS and ${Prefix}_LIBRARIES lists. The variable
|
||||
# ${Name}_REQUIRED_LIBRARIES can be set to spcecify any additional libraries
|
||||
# that are needed. This function defines the following CACHE variables:
|
||||
# the ${Prefix}_INCLUDE_DIRS and ${Prefix}_LIBRARIES lists. The function
|
||||
# defines the following CACHE variables:
|
||||
#
|
||||
# ${Prefix}_FOUND
|
||||
# ${Prefix}_INCLUDE_DIRS
|
||||
@@ -229,15 +204,6 @@ endfunction(mfem_find_component)
|
||||
function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
|
||||
Lib IncDoc LibDoc)
|
||||
|
||||
# If we have the TPL_ versions of _INCLUDE_DIRS and _LIBRARIES then set the
|
||||
# standard ${Prefix} versions
|
||||
if (TPL_${Prefix}_INCLUDE_DIRS)
|
||||
set(${Prefix}_INCLUDE_DIRS ${TPL_${Prefix}_INCLUDE_DIRS} CACHE STRING "TPL_${Prefix}_INCLUDE_DIRS was found." FORCE)
|
||||
endif()
|
||||
if (TPL_${Prefix}_LIBRARIES)
|
||||
set(${Prefix}_LIBRARIES ${TPL_${Prefix}_LIBRARIES} CACHE STRING "TPL_${Prefix}_LIBRARIES was found." FORCE)
|
||||
endif()
|
||||
|
||||
# Quick return
|
||||
if (${Prefix}_FOUND)
|
||||
return()
|
||||
@@ -264,14 +230,12 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
|
||||
mfem_find_component("${Prefix}" "${DirVar}" "${IncSuffixes}" "${Header}"
|
||||
"${LibSuffixes}" "${Lib}" "${IncDoc}" "${LibDoc}")
|
||||
|
||||
if (((NOT Lib) OR ${Prefix}_LIBRARY) AND
|
||||
((NOT Header) OR ${Prefix}_INCLUDE_DIR))
|
||||
if (((NOT Lib) OR ${Prefix}_LIBRARIES) AND
|
||||
((NOT Header) OR ${Prefix}_INCLUDE_DIRS))
|
||||
set(Found TRUE)
|
||||
else()
|
||||
set(Found FALSE)
|
||||
endif()
|
||||
set(${Prefix}_LIBRARIES ${${Prefix}_LIBRARY})
|
||||
set(${Prefix}_INCLUDE_DIRS ${${Prefix}_INCLUDE_DIR})
|
||||
|
||||
set(ReqVars "")
|
||||
|
||||
@@ -310,22 +274,25 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
|
||||
"${CompLibSuffixes}" "${CompLib}" "" "")
|
||||
if (CompRequired)
|
||||
if (CompLib)
|
||||
list(APPEND ReqVars ${FullPrefix}_LIBRARY)
|
||||
list(APPEND ReqVars ${FullPrefix}_LIBRARIES)
|
||||
endif()
|
||||
if (CompHeader)
|
||||
list(APPEND ReqVars ${FullPrefix}_INCLUDE_DIR)
|
||||
list(APPEND ReqVars ${FullPrefix}_INCLUDE_DIRS)
|
||||
endif()
|
||||
endif(CompRequired)
|
||||
if (((NOT CompLib) OR ${FullPrefix}_LIBRARY) AND
|
||||
((NOT CompHeader) OR ${FullPrefix}_INCLUDE_DIR))
|
||||
if (((NOT CompLib) OR ${FullPrefix}_LIBRARIES) AND
|
||||
((NOT CompHeader) OR ${FullPrefix}_INCLUDE_DIRS))
|
||||
# Component found
|
||||
list(APPEND ${Prefix}_LIBRARIES ${${FullPrefix}_LIBRARY})
|
||||
list(APPEND ${Prefix}_INCLUDE_DIRS ${${FullPrefix}_INCLUDE_DIR})
|
||||
set(${FullPrefix}_FOUND TRUE CACHE BOOL
|
||||
"${Name}/${CompPrefix} was found." FORCE)
|
||||
list(APPEND ${Prefix}_LIBRARIES ${${FullPrefix}_LIBRARIES})
|
||||
list(APPEND ${Prefix}_INCLUDE_DIRS ${${FullPrefix}_INCLUDE_DIRS})
|
||||
if (NOT ${Name}_FIND_QUIETLY)
|
||||
# message(STATUS "${Name}: ${CompPrefix}: found")
|
||||
message(STATUS
|
||||
"${Name}: ${CompPrefix}: ${${FullPrefix}_LIBRARY}")
|
||||
"${Name}: ${CompPrefix}: ${${FullPrefix}_LIBRARIES}")
|
||||
# message(STATUS
|
||||
# "${Name}: ${CompPrefix}: ${${FullPrefix}_INCLUDE_DIR}")
|
||||
# "${Name}: ${CompPrefix}: ${${FullPrefix}_INCLUDE_DIRS}")
|
||||
endif()
|
||||
else()
|
||||
# Let FindPackageHandleStandardArgs() handle errors
|
||||
@@ -378,8 +345,6 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
|
||||
if (NOT ${Name}_FIND_QUIETLY)
|
||||
message(STATUS "${Name}: trying alternative package: ${ReqPackM}")
|
||||
endif()
|
||||
# Do not add ${Required} here, since that will prevent other potential
|
||||
# alternative packages from being found.
|
||||
find_package(${ReqPack} ${Quiet} COMPONENTS ${PackComps})
|
||||
string(TOUPPER ${ReqPack} ReqPACK)
|
||||
if (${ReqPack}_FOUND)
|
||||
@@ -393,7 +358,7 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
|
||||
endif()
|
||||
elseif (Alternative)
|
||||
set(Alternative FALSE)
|
||||
elseif (Found)
|
||||
else()
|
||||
if (NOT ${Name}_FIND_QUIETLY)
|
||||
if (Required)
|
||||
message(STATUS "${Name}: looking for required package: ${ReqPackM}")
|
||||
@@ -403,139 +368,23 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
|
||||
endif()
|
||||
string(TOUPPER ${ReqPack} ReqPACK)
|
||||
if (NOT (${ReqPack}_FOUND OR ${ReqPACK}_FOUND))
|
||||
if (NOT ${ReqPack}_TARGET_NAMES)
|
||||
find_package(${ReqPack} ${Required} ${Quiet} COMPONENTS ${PackComps})
|
||||
else()
|
||||
foreach(_target ${ReqPack} ${${ReqPack}_TARGET_NAMES})
|
||||
# Do not use ${Required} here:
|
||||
find_package(${_target} NAMES ${_target} ${ReqPack} ${Quiet}
|
||||
COMPONENTS ${PackComps})
|
||||
string(TOUPPER ${_target} _TARGET)
|
||||
if (${_target}_FOUND OR ${_TARGET}_FOUND)
|
||||
set(${ReqPack}_FOUND TRUE)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
if (${Required} AND NOT ${ReqPack}_FOUND)
|
||||
message(FATAL_ERROR " *** Required package ${ReqPack} not found."
|
||||
"Checked target names: ${ReqPack} ${${ReqPack}_TARGET_NAMES}")
|
||||
endif()
|
||||
endif()
|
||||
find_package(${ReqPack} ${Required} ${Quiet} COMPONENTS ${PackComps})
|
||||
endif()
|
||||
if (Required AND NOT (${ReqPack}_FOUND OR ${ReqPACK}_FOUND))
|
||||
message(FATAL_ERROR " --------- INTERNAL ERROR")
|
||||
endif()
|
||||
if ("${ReqPack}" STREQUAL "MPI" AND MPI_CXX_FOUND)
|
||||
if ("${ReqPack}" STREQUAL "MPI")
|
||||
list(APPEND ${Prefix}_LIBRARIES ${MPI_CXX_LIBRARIES})
|
||||
list(APPEND ${Prefix}_INCLUDE_DIRS ${MPI_CXX_INCLUDE_PATH})
|
||||
elseif (${ReqPack}_FOUND OR ${ReqPACK}_FOUND)
|
||||
else()
|
||||
if (${ReqPack}_FOUND)
|
||||
set(_Pack ${ReqPack})
|
||||
else()
|
||||
set(_Pack ${ReqPACK})
|
||||
list(APPEND ${Prefix}_LIBRARIES ${${ReqPack}_LIBRARIES})
|
||||
list(APPEND ${Prefix}_INCLUDE_DIRS ${${ReqPack}_INCLUDE_DIRS})
|
||||
elseif (${ReqPACK}_FOUND)
|
||||
list(APPEND ${Prefix}_LIBRARIES ${${ReqPACK}_LIBRARIES})
|
||||
list(APPEND ${Prefix}_INCLUDE_DIRS ${${ReqPACK}_INCLUDE_DIRS})
|
||||
endif()
|
||||
set(_Pack_LIBS)
|
||||
set(_Pack_INCS)
|
||||
# - ${_Pack}_CONFIG is defined by find_package() when a config file was
|
||||
# loaded
|
||||
# - If ${ReqPack}_TARGET_NAMES is defined, use target mode
|
||||
if (NOT ((DEFINED ${_Pack}_CONFIG) OR
|
||||
(DEFINED ${ReqPack}_TARGET_NAMES)))
|
||||
# Defined variables expected:
|
||||
# - ${ReqPack}_LIB_VARS, optional, default: ${_Pack}_LIBRARIES
|
||||
# - ${ReqPack}_INCLUDE_VARS, optional, default: ${_Pack}_INCLUDE_DIRS
|
||||
set(_lib_vars ${${ReqPack}_LIB_VARS})
|
||||
if (NOT _lib_vars)
|
||||
set(_lib_vars ${_Pack}_LIBRARIES)
|
||||
endif()
|
||||
foreach (_var ${_lib_vars})
|
||||
if (${_var})
|
||||
list(APPEND _Pack_LIBS ${${_var}})
|
||||
endif()
|
||||
endforeach()
|
||||
# Includes
|
||||
set(_inc_vars ${${ReqPack}_INCLUDE_VARS})
|
||||
if (NOT _inc_vars)
|
||||
set(_inc_vars ${_Pack}_INCLUDE_DIRS)
|
||||
endif()
|
||||
foreach (_include ${_inc_vars})
|
||||
# message(STATUS "${Name}: ${ReqPack}: ${_include}")
|
||||
if (${_include})
|
||||
list(APPEND _Pack_INCS ${${_include}})
|
||||
endif()
|
||||
endforeach()
|
||||
else()
|
||||
# Target mode: check for a valid target:
|
||||
# - an entry in the variable ${ReqPack}_TARGET_NAMES (optional)
|
||||
# - ${_Pack}
|
||||
# Other optional variables:
|
||||
# - ${ReqPack}_IMPORT_CONFIG, default value: "RELEASE"
|
||||
# - ${ReqPack}_TARGET_FORCE, default value: "FALSE"
|
||||
set(TargetName)
|
||||
foreach (_target ${${ReqPack}_TARGET_NAMES} ${_Pack})
|
||||
if (TARGET ${_target})
|
||||
set(TargetName ${_target})
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
if ("${TargetName}" STREQUAL "")
|
||||
message(FATAL_ERROR " *** ${ReqPack}: unknown target. "
|
||||
"Please set ${ReqPack}_TARGET_NAMES.")
|
||||
endif()
|
||||
get_target_property(IsImported ${TargetName} IMPORTED)
|
||||
if (IsImported)
|
||||
set(ImportConfig ${${ReqPack}_IMPORT_CONFIG})
|
||||
if (NOT ImportConfig)
|
||||
set(ImportConfig RELEASE)
|
||||
endif()
|
||||
get_target_property(ImpConfigs ${TargetName} IMPORTED_CONFIGURATIONS)
|
||||
list(FIND ImpConfigs ${ImportConfig} _Index)
|
||||
if (_Index EQUAL -1)
|
||||
message(FATAL_ERROR " *** ${ReqPack}: configuration "
|
||||
"${ImportConfig} not found. Set ${ReqPack}_IMPORT_CONFIG "
|
||||
"from the list: ${ImpConfigs}.")
|
||||
endif()
|
||||
endif()
|
||||
# Set _Pack_LIBS
|
||||
if (NOT IsImported OR ${ReqPack}_TARGET_FORCE)
|
||||
# Set _Pack_LIBS to be the target itself
|
||||
set(_Pack_LIBS ${TargetName})
|
||||
if (NOT ${Name}_FIND_QUIETLY)
|
||||
message(STATUS "Found ${ReqPack}: ${_Pack_LIBS} (target)")
|
||||
endif()
|
||||
else()
|
||||
# Set _Pack_LIBS from the target properties for ImportConfig
|
||||
foreach (_prop IMPORTED_LOCATION_${ImportConfig}
|
||||
IMPORTED_LINK_INTERFACE_LIBRARIES_${ImportConfig})
|
||||
get_target_property(_value ${TargetName} ${_prop})
|
||||
if (_value)
|
||||
list(APPEND _Pack_LIBS ${_value})
|
||||
endif()
|
||||
endforeach()
|
||||
if (NOT ${Name}_FIND_QUIETLY)
|
||||
message(STATUS
|
||||
"Imported ${ReqPack}[${ImportConfig}]: ${_Pack_LIBS}")
|
||||
endif()
|
||||
endif()
|
||||
# Set _Pack_INCS
|
||||
foreach (_prop INCLUDE_DIRECTORIES)
|
||||
get_target_property(_value ${TargetName} ${_prop})
|
||||
if (_value)
|
||||
list(APPEND _Pack_INCS ${_value})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
# _Pack_LIBS and _Pack_INCS should be fully defined here
|
||||
list(APPEND ${Prefix}_LIBRARIES ${_Pack_LIBS})
|
||||
list(APPEND ${Prefix}_INCLUDE_DIRS ${_Pack_INCS})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (Found AND ${Name}_REQUIRED_LIBRARIES)
|
||||
list(APPEND ${Prefix}_LIBRARIES ${${Name}_REQUIRED_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if (NOT ("${${Prefix}_INCLUDE_DIRS}" STREQUAL ""))
|
||||
list(INSERT ReqVars 0 ${Prefix}_INCLUDE_DIRS)
|
||||
set(ReqHeaders 1)
|
||||
@@ -552,6 +401,12 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
|
||||
if (ReqHeaders)
|
||||
list(REMOVE_DUPLICATES ${Prefix}_INCLUDE_DIRS)
|
||||
endif()
|
||||
# Write the updated values to the cache.
|
||||
set(${Prefix}_LIBRARIES ${${Prefix}_LIBRARIES} CACHE STRING
|
||||
"${LibDoc}" FORCE)
|
||||
set(${Prefix}_INCLUDE_DIRS ${${Prefix}_INCLUDE_DIRS} CACHE STRING
|
||||
"${IncDoc}" FORCE)
|
||||
set(${Prefix}_FOUND TRUE CACHE BOOL "${Name} was found." FORCE)
|
||||
|
||||
# Check for optional "CHECK_BUILD" arguments.
|
||||
set(I 9) # 9 is the number of required arguments
|
||||
@@ -569,10 +424,6 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
|
||||
set(CMAKE_REQUIRED_QUIET ${${Name}_FIND_QUIETLY})
|
||||
check_cxx_source_compiles("${TestSrc}" ${TestVar})
|
||||
if (TestReq)
|
||||
if (NOT ${TestVar})
|
||||
set(Found FALSE)
|
||||
unset(${TestVar} CACHE)
|
||||
endif()
|
||||
list(APPEND ReqVars ${TestVar})
|
||||
endif()
|
||||
elseif("${ARGV${I}}" STREQUAL "ADD_COMPONENT")
|
||||
@@ -583,35 +434,22 @@ function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
|
||||
endif()
|
||||
math(EXPR I "${I}+1")
|
||||
endwhile()
|
||||
else()
|
||||
set(${Prefix}_FOUND FALSE CACHE BOOL "${Name} was not found." FORCE)
|
||||
endif()
|
||||
if ("_x_${ReqVars}" STREQUAL "_x_")
|
||||
set(${Prefix}_FOUND ${Found})
|
||||
set(ReqVars ${Prefix}_FOUND)
|
||||
endif()
|
||||
# foreach(ReqVar ${ReqVars})
|
||||
# message(STATUS " *** ${ReqVar}=${${ReqVar}}")
|
||||
# get_property(IsCached CACHE ${ReqVar} PROPERTY "VALUE" SET)
|
||||
# if (IsCached)
|
||||
# get_property(CachedVal CACHE ${ReqVar} PROPERTY "VALUE")
|
||||
# message(STATUS " *** ${ReqVar}[cached]=${CachedVal}")
|
||||
# endif()
|
||||
# message(STATUS "${ReqVar}=${${ReqVar}}")
|
||||
# endforeach()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(${Name}
|
||||
" *** ${Name} not found. Please set ${DirVar}." ${ReqVars})
|
||||
|
||||
string(TOUPPER ${Name} UName)
|
||||
if (${UName}_FOUND)
|
||||
# Write the ${Prefix}_* variables to the cache.
|
||||
set(${Prefix}_LIBRARIES ${${Prefix}_LIBRARIES} CACHE STRING
|
||||
"${LibDoc}" FORCE)
|
||||
set(${Prefix}_INCLUDE_DIRS ${${Prefix}_INCLUDE_DIRS} CACHE STRING
|
||||
"${IncDoc}" FORCE)
|
||||
set(${Prefix}_FOUND TRUE CACHE BOOL "${Name} was found." FORCE)
|
||||
if (ReqHeaders AND (NOT ${Name}_FIND_QUIETLY))
|
||||
message(STATUS "${Prefix}_INCLUDE_DIRS=${${Prefix}_INCLUDE_DIRS}")
|
||||
endif()
|
||||
if (Found AND ReqLibs AND ReqHeaders AND (NOT ${Name}_FIND_QUIETLY))
|
||||
message(STATUS "${Prefix}_INCLUDE_DIRS=${${Prefix}_INCLUDE_DIRS}")
|
||||
endif()
|
||||
|
||||
endfunction(mfem_find_package)
|
||||
@@ -694,162 +532,3 @@ function(mfem_find_library Name Prefix Lib LibDoc CheckVar CheckSrc)
|
||||
endif()
|
||||
|
||||
endfunction(mfem_find_library)
|
||||
|
||||
|
||||
#
|
||||
# Function that creates 'config.mk' from 'config.mk.in' for the both the
|
||||
# build- and the install-locations and define install rules for 'config.mk'
|
||||
# and 'test.mk'.
|
||||
#
|
||||
function(mfem_export_mk_files)
|
||||
|
||||
# Define a few auxiliary variables (not written to 'config.mk')
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
|
||||
# CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG -> '-Wl,-rpath,'
|
||||
set(shared_link_flag ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG})
|
||||
if (NOT shared_link_flag)
|
||||
set(shared_link_flag "-Wl,-rpath,")
|
||||
endif()
|
||||
|
||||
# Convert Boolean vars to YES/NO without writting the values to cache
|
||||
set(CONFIG_MK_BOOL_VARS MFEM_USE_MPI MFEM_USE_METIS MFEM_USE_METIS_5
|
||||
MFEM_DEBUG MFEM_USE_EXCEPTIONS MFEM_USE_GZSTREAM MFEM_USE_LIBUNWIND
|
||||
MFEM_USE_LAPACK MFEM_THREAD_SAFE MFEM_USE_OPENMP MFEM_USE_LEGACY_OPENMP
|
||||
MFEM_USE_MEMALLOC MFEM_USE_SUNDIALS MFEM_USE_MESQUITE MFEM_USE_SUITESPARSE
|
||||
MFEM_USE_SUPERLU MFEM_USE_STRUMPACK MFEM_USE_GECKO MFEM_USE_GNUTLS
|
||||
MFEM_USE_NETCDF MFEM_USE_PETSC MFEM_USE_MPFR MFEM_USE_SIDRE
|
||||
MFEM_USE_CONDUIT MFEM_USE_PUMI)
|
||||
foreach(var ${CONFIG_MK_BOOL_VARS})
|
||||
if (${var})
|
||||
set(${var} YES)
|
||||
else()
|
||||
set(${var} NO)
|
||||
endif()
|
||||
endforeach()
|
||||
set(MFEM_CXX ${CMAKE_CXX_COMPILER})
|
||||
set(MFEM_CPPFLAGS "")
|
||||
string(STRIP "${CMAKE_CXX_FLAGS_${BUILD_TYPE}} ${CMAKE_CXX_FLAGS}"
|
||||
MFEM_CXXFLAGS)
|
||||
set(MFEM_TPLFLAGS "")
|
||||
foreach(dir ${MFEM_TPL_INCLUDE_DIRS})
|
||||
set(MFEM_TPLFLAGS "${MFEM_TPLFLAGS} -I${dir}")
|
||||
endforeach()
|
||||
# TODO: MFEM_TPLFLAGS: add other TPL flags, in addition to the -I flags.
|
||||
set(MFEM_INCFLAGS "-I\$(MFEM_INC_DIR) \$(MFEM_TPLFLAGS)")
|
||||
set(MFEM_PICFLAG "")
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set(MFEM_PICFLAG "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}")
|
||||
endif()
|
||||
set(MFEM_FLAGS "\$(MFEM_CPPFLAGS) \$(MFEM_CXXFLAGS) \$(MFEM_INCFLAGS)")
|
||||
# TPL link flags: set below
|
||||
set(MFEM_EXT_LIBS "")
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set(MFEM_LIBS "${shared_link_flag}\$(MFEM_LIB_DIR) -L\$(MFEM_LIB_DIR)")
|
||||
set(MFEM_LIBS "${MFEM_LIBS} -lmfem \$(MFEM_EXT_LIBS)")
|
||||
if (APPLE)
|
||||
set(SO_VER ".${mfem_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
else()
|
||||
set(SO_VER "${CMAKE_SHARED_LIBRARY_SUFFIX}.${mfem_VERSION}")
|
||||
endif()
|
||||
set(MFEM_LIB_FILE "\$(MFEM_LIB_DIR)/libmfem${SO_VER}")
|
||||
set(MFEM_SHARED YES)
|
||||
set(MFEM_STATIC NO)
|
||||
else()
|
||||
set(MFEM_LIBS "-L\$(MFEM_LIB_DIR) -lmfem \$(MFEM_EXT_LIBS)")
|
||||
set(MFEM_LIB_FILE "\$(MFEM_LIB_DIR)/libmfem.a")
|
||||
set(MFEM_SHARED NO)
|
||||
set(MFEM_STATIC YES)
|
||||
endif()
|
||||
set(MFEM_BUILD_TAG "${CMAKE_SYSTEM}")
|
||||
set(MFEM_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
# For the next 4 variable, these are the values for the build-tree version of
|
||||
# 'config.mk'
|
||||
set(MFEM_INC_DIR "${PROJECT_BINARY_DIR}")
|
||||
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}")
|
||||
set(MFEM_MPIEXEC ${MPIEXEC})
|
||||
if (NOT MFEM_MPIEXEC)
|
||||
set(MFEM_MPIEXEC "mpirun")
|
||||
endif()
|
||||
set(MFEM_MPIEXEC_NP ${MPIEXEC_NUMPROC_FLAG})
|
||||
if (NOT MFEM_MPIEXEC_NP)
|
||||
set(MFEM_MPIEXEC_NP "-np")
|
||||
endif()
|
||||
# MFEM_MPI_NP is already set
|
||||
# Define the variable 'MFEM_EXT_LIBS': handle PUMI libs
|
||||
if ("${MFEM_USE_PUMI}" STREQUAL "YES")
|
||||
message(STATUS "simmodsuite_dir = '${SIMMODSUITE_DIR}'")
|
||||
get_target_property(liblist ${PUMI_LIBRARIES} INTERFACE_LINK_LIBRARIES)
|
||||
set(pumi_dep_libs "${liblist}")
|
||||
foreach(pumilib ${liblist})
|
||||
get_target_property(libdeps ${pumilib} INTERFACE_LINK_LIBRARIES)
|
||||
if (NOT "${libdeps}" MATCHES "libdeps-NOTFOUND")
|
||||
list(APPEND pumi_dep_libs ${libdeps})
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES pumi_dep_libs)
|
||||
foreach(pumilib ${pumi_dep_libs})
|
||||
unset(lib CACHE)
|
||||
string(REGEX REPLACE "^SCOREC::" "" libname ${pumilib})
|
||||
string(FIND "${pumilib}" ".a" staticlib)
|
||||
string(FIND "${pumilib}" ".so" sharedlib)
|
||||
find_library(lib ${libname} PATHS ${PUMI_DIR}/lib NO_DEFUALT_PATH)
|
||||
if (NOT "${sharedlib}" MATCHES "-1" OR
|
||||
NOT "${staticlib}" MATCHES "-1" )
|
||||
set(MFEM_EXT_LIBS "${pumilib} ${MFEM_EXT_LIBS}")
|
||||
elseif (NOT "${lib}" MATCHES "lib-NOTFOUND")
|
||||
set(MFEM_EXT_LIBS "${lib} ${MFEM_EXT_LIBS}")
|
||||
elseif ("${lib}" MATCHES "lib-NOTFOUND" AND
|
||||
NOT "${libname}" MATCHES "can" AND
|
||||
NOT "${libname}" MATCHES "pthread")
|
||||
message(FATAL_ERROR "SCOREC lib ${libname} not found")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
# Define the variable 'MFEM_EXT_LIBS': handle other (not PUMI) libs
|
||||
foreach(lib ${TPL_LIBRARIES})
|
||||
get_filename_component(suffix ${lib} EXT)
|
||||
# handle interfaces (e.g., SCOREC::apf)
|
||||
if ("${lib}" MATCHES "SCOREC::.*")
|
||||
elseif (NOT "${lib}" MATCHES "SCOREC::.*" AND "${lib}" MATCHES ".*::.*")
|
||||
message(FATAL_ERROR "***** interface lib found ... exiting *****")
|
||||
# handle static and shared libs
|
||||
elseif ("${suffix}" STREQUAL "${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
get_filename_component(dir ${lib} DIRECTORY)
|
||||
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}")
|
||||
else()
|
||||
set(MFEM_EXT_LIBS "${MFEM_EXT_LIBS} ${lib}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Create the build-tree version of 'config.mk'
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/config/config.mk.in"
|
||||
"${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"
|
||||
"${PROJECT_BINARY_DIR}/config/test.mk" COPYONLY)
|
||||
|
||||
# Update variables for the install-tree version of 'config.mk'
|
||||
set(MFEM_INC_DIR "${CMAKE_INSTALL_PREFIX}/include")
|
||||
set(MFEM_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
set(MFEM_TEST_MK "${CMAKE_INSTALL_PREFIX}/share/mfem/test.mk")
|
||||
set(MFEM_CONFIG_EXTRA "")
|
||||
|
||||
# Create the install-tree version of 'config.mk'
|
||||
configure_file(
|
||||
"${PROJECT_SOURCE_DIR}/config/config.mk.in"
|
||||
"${PROJECT_BINARY_DIR}/config/config-install.mk")
|
||||
|
||||
# Install rules for 'config.mk' and 'test.mk'
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/config/test.mk
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mfem/)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/config/config-install.mk
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mfem/ RENAME config.mk)
|
||||
|
||||
endfunction()
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
//
|
||||
// Otherwise, use the local file: _config.hpp.
|
||||
|
||||
#ifndef MFEM_CONFIG_HPP
|
||||
#define MFEM_CONFIG_HPP
|
||||
|
||||
#ifdef MFEM_BUILD_DIR
|
||||
#define MFEM_QUOTE(a) #a
|
||||
#define MFEM_MAKE_PATH(x,y) MFEM_QUOTE(x/y)
|
||||
@@ -26,18 +23,6 @@
|
||||
#include "_config.hpp"
|
||||
#endif
|
||||
|
||||
// Common configuration macros
|
||||
|
||||
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__)
|
||||
#define MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC
|
||||
#endif
|
||||
|
||||
// Windows specific options
|
||||
#ifdef _WIN32
|
||||
// Macro needed to get defines like M_PI from <cmath>. (Visual Studio C++ only?)
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
// Check dependencies:
|
||||
|
||||
// Options that require MPI
|
||||
@@ -45,15 +30,7 @@
|
||||
#ifdef MFEM_USE_SUPERLU
|
||||
#error Building with SuperLU_DIST (MFEM_USE_SUPERLU=YES) requires MPI (MFEM_USE_MPI=YES)
|
||||
#endif
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
#error Building with STRUMPACK (MFEM_USE_STRUMPACK=YES) requires MPI (MFEM_USE_MPI=YES)
|
||||
#endif
|
||||
#ifdef MFEM_USE_PETSC
|
||||
#error Building with PETSc (MFEM_USE_PETSC=YES) requires MPI (MFEM_USE_MPI=YES)
|
||||
#endif
|
||||
#ifdef MFEM_USE_PUMI
|
||||
#error Building with PUMI (MFEM_USE_PUMI=YES) requires MPI (MFEM_USE_MPI=YES)
|
||||
#endif
|
||||
#endif // MFEM_USE_MPI not defined
|
||||
|
||||
#endif // MFEM_CONFIG_HPP
|
||||
|
||||
@@ -12,33 +12,6 @@
|
||||
#ifndef MFEM_CONFIG_HEADER
|
||||
#define MFEM_CONFIG_HEADER
|
||||
|
||||
// MFEM version: integer of the form: (major*100 + minor)*100 + patch.
|
||||
// #define MFEM_VERSION @MFEM_VERSION@
|
||||
|
||||
// MFEM version string of the form "3.3" or "3.3.1".
|
||||
// #define MFEM_VERSION_STRING "@MFEM_VERSION_STRING@"
|
||||
|
||||
// MFEM version type, see the MFEM_VERSION_TYPE_* constants below.
|
||||
#define MFEM_VERSION_TYPE ((MFEM_VERSION)%2)
|
||||
|
||||
// MFEM version type constants.
|
||||
#define MFEM_VERSION_TYPE_RELEASE 0
|
||||
#define MFEM_VERSION_TYPE_DEVELOPMENT 1
|
||||
|
||||
// Separate MFEM version numbers for major, minor, and patch.
|
||||
#define MFEM_VERSION_MAJOR ((MFEM_VERSION)/10000)
|
||||
#define MFEM_VERSION_MINOR (((MFEM_VERSION)/100)%100)
|
||||
#define MFEM_VERSION_PATCH ((MFEM_VERSION)%100)
|
||||
|
||||
// The absolute path of the MFEM source prefix
|
||||
// #define MFEM_SOURCE_DIR "@MFEM_SOURCE_DIR@"
|
||||
|
||||
// The absolute path of the MFEM installation prefix
|
||||
// #define MFEM_INSTALL_DIR "@MFEM_INSTALL_DIR@"
|
||||
|
||||
// Description of the git commit used to build MFEM.
|
||||
// #define MFEM_GIT_STRING "@MFEM_GIT_STRING@"
|
||||
|
||||
// Build the parallel MFEM library.
|
||||
// Requires an MPI compiler, and the libraries HYPRE and METIS.
|
||||
// #define MFEM_USE_MPI
|
||||
@@ -46,18 +19,12 @@
|
||||
// Enable debug checks in MFEM.
|
||||
// #define MFEM_DEBUG
|
||||
|
||||
// Throw an exception on errors.
|
||||
// #define MFEM_USE_EXCEPTIONS
|
||||
|
||||
// Enable gzstream in MFEM.
|
||||
// #define MFEM_USE_GZSTREAM
|
||||
|
||||
// Enable backtraces for mfem_error through libunwind.
|
||||
// #define MFEM_USE_LIBUNWIND
|
||||
|
||||
// Enable MFEM features that use the METIS library (parallel MFEM).
|
||||
// #define MFEM_USE_METIS
|
||||
|
||||
// Enable this option if linking with METIS version 5 (parallel MFEM).
|
||||
// #define MFEM_USE_METIS_5
|
||||
|
||||
@@ -68,17 +35,18 @@
|
||||
// allocation and de-allocation.
|
||||
// #define MFEM_THREAD_SAFE
|
||||
|
||||
// Enable the OpenMP backend.
|
||||
// Enable experimental OpenMP support. Requires MFEM_THREAD_SAFE.
|
||||
// #define MFEM_USE_OPENMP
|
||||
|
||||
// [Deprecated] Enable experimental OpenMP support. Requires MFEM_THREAD_SAFE.
|
||||
// #define MFEM_USE_LEGACY_OPENMP
|
||||
|
||||
// Internal MFEM option: enable group/batch allocation for some small objects.
|
||||
// #define MFEM_USE_MEMALLOC
|
||||
|
||||
// Which library functions to use in class StopWatch for measuring time.
|
||||
// For a list of the available options, see INSTALL.
|
||||
// The available options are:
|
||||
// 0 - use std::clock from <ctime>
|
||||
// 1 - use times from <sys/times.h>
|
||||
// 2 - use high-resolution POSIX clocks
|
||||
// 3 - use QueryPerformanceCounter from <windows.h>
|
||||
// If not defined, an option is selected automatically.
|
||||
// #define MFEM_TIMER_TYPE @MFEM_TIMER_TYPE@
|
||||
|
||||
@@ -94,9 +62,6 @@
|
||||
// Enable MFEM functionality based on the SuperLU library.
|
||||
// #define MFEM_USE_SUPERLU
|
||||
|
||||
// Enable MFEM functionality based on the STRUMPACK library.
|
||||
// #define MFEM_USE_STRUMPACK
|
||||
|
||||
// Enable functionality based on the Gecko library
|
||||
// #define MFEM_USE_GECKO
|
||||
|
||||
@@ -106,9 +71,6 @@
|
||||
// Enable Sidre support
|
||||
// #define MFEM_USE_SIDRE
|
||||
|
||||
// Enable Conduit support
|
||||
// #define MFEM_USE_CONDUIT
|
||||
|
||||
// Enable functionality based on the NetCDF library (reading CUBIT files)
|
||||
// #define MFEM_USE_NETCDF
|
||||
|
||||
@@ -118,27 +80,10 @@
|
||||
// Enable functionality based on the MPFR library.
|
||||
// #define MFEM_USE_MPFR
|
||||
|
||||
// Enable MFEM functionality based on the PUMI library
|
||||
// #define MFEM_USE_PUMI
|
||||
|
||||
// Build the GPU/CUDA-enabled version of the MFEM library.
|
||||
// Requires a CUDA compiler (nvcc).
|
||||
// #define MFEM_USE_CUDA
|
||||
|
||||
// Enable functionality based on the RAJA library.
|
||||
// #define MFEM_USE_RAJA
|
||||
|
||||
// Enable functionality based on the OCCA library.
|
||||
// #define MFEM_USE_OCCA
|
||||
|
||||
// Enable MFEM's internal Memory Manager (needed e.g. for MFEM_USE_CUDA)
|
||||
// #define MFEM_USE_MM
|
||||
|
||||
// Version of HYPRE used for building MFEM.
|
||||
// #define MFEM_HYPRE_VERSION @MFEM_HYPRE_VERSION@
|
||||
|
||||
// Macro defined when PUMI is built with support for the Simmetrix SimModSuite
|
||||
// library.
|
||||
// #define MFEM_USE_SIMMETRIX
|
||||
// Windows specific options
|
||||
#ifdef _WIN32
|
||||
// Macro needed to get defines like M_PI from <cmath>. (Visual Studio C++ only?)
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#endif // MFEM_CONFIG_HEADER
|
||||
|
||||
@@ -10,41 +10,26 @@
|
||||
# Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
# Variables corresponding to defines in config.hpp (YES, NO, or value)
|
||||
MFEM_VERSION = @MFEM_VERSION@
|
||||
MFEM_VERSION_STRING = @MFEM_VERSION_STRING@
|
||||
MFEM_SOURCE_DIR = @MFEM_SOURCE_DIR@
|
||||
MFEM_INSTALL_DIR = @MFEM_INSTALL_DIR@
|
||||
MFEM_GIT_STRING = @MFEM_GIT_STRING@
|
||||
MFEM_USE_MPI = @MFEM_USE_MPI@
|
||||
MFEM_USE_METIS = @MFEM_USE_METIS@
|
||||
MFEM_USE_METIS_5 = @MFEM_USE_METIS_5@
|
||||
MFEM_DEBUG = @MFEM_DEBUG@
|
||||
MFEM_USE_EXCEPTIONS = @MFEM_USE_EXCEPTIONS@
|
||||
MFEM_USE_GZSTREAM = @MFEM_USE_GZSTREAM@
|
||||
MFEM_USE_LIBUNWIND = @MFEM_USE_LIBUNWIND@
|
||||
MFEM_USE_LAPACK = @MFEM_USE_LAPACK@
|
||||
MFEM_THREAD_SAFE = @MFEM_THREAD_SAFE@
|
||||
MFEM_USE_LEGACY_OPENMP = @MFEM_USE_LEGACY_OPENMP@
|
||||
MFEM_USE_OPENMP = @MFEM_USE_OPENMP@
|
||||
MFEM_USE_MEMALLOC = @MFEM_USE_MEMALLOC@
|
||||
MFEM_TIMER_TYPE = @MFEM_TIMER_TYPE@
|
||||
MFEM_USE_SUNDIALS = @MFEM_USE_SUNDIALS@
|
||||
MFEM_USE_MESQUITE = @MFEM_USE_MESQUITE@
|
||||
MFEM_USE_SUITESPARSE = @MFEM_USE_SUITESPARSE@
|
||||
MFEM_USE_SUPERLU = @MFEM_USE_SUPERLU@
|
||||
MFEM_USE_STRUMPACK = @MFEM_USE_STRUMPACK@
|
||||
MFEM_USE_GECKO = @MFEM_USE_GECKO@
|
||||
MFEM_USE_GNUTLS = @MFEM_USE_GNUTLS@
|
||||
MFEM_USE_NETCDF = @MFEM_USE_NETCDF@
|
||||
MFEM_USE_PETSC = @MFEM_USE_PETSC@
|
||||
MFEM_USE_MPFR = @MFEM_USE_MPFR@
|
||||
MFEM_USE_SIDRE = @MFEM_USE_SIDRE@
|
||||
MFEM_USE_CONDUIT = @MFEM_USE_CONDUIT@
|
||||
MFEM_USE_PUMI = @MFEM_USE_PUMI@
|
||||
MFEM_USE_CUDA = @MFEM_USE_CUDA@
|
||||
MFEM_USE_RAJA = @MFEM_USE_RAJA@
|
||||
MFEM_USE_OCCA = @MFEM_USE_OCCA@
|
||||
MFEM_USE_MM = @MFEM_USE_MM@
|
||||
MFEM_USE_MPI = @MFEM_USE_MPI@
|
||||
MFEM_USE_METIS_5 = @MFEM_USE_METIS_5@
|
||||
MFEM_DEBUG = @MFEM_DEBUG@
|
||||
MFEM_USE_GZSTREAM = @MFEM_USE_GZSTREAM@
|
||||
MFEM_USE_LIBUNWIND = @MFEM_USE_LIBUNWIND@
|
||||
MFEM_USE_LAPACK = @MFEM_USE_LAPACK@
|
||||
MFEM_THREAD_SAFE = @MFEM_THREAD_SAFE@
|
||||
MFEM_USE_OPENMP = @MFEM_USE_OPENMP@
|
||||
MFEM_USE_MEMALLOC = @MFEM_USE_MEMALLOC@
|
||||
MFEM_TIMER_TYPE = @MFEM_TIMER_TYPE@
|
||||
MFEM_USE_SUNDIALS = @MFEM_USE_SUNDIALS@
|
||||
MFEM_USE_MESQUITE = @MFEM_USE_MESQUITE@
|
||||
MFEM_USE_SUITESPARSE = @MFEM_USE_SUITESPARSE@
|
||||
MFEM_USE_SUPERLU = @MFEM_USE_SUPERLU@
|
||||
MFEM_USE_GECKO = @MFEM_USE_GECKO@
|
||||
MFEM_USE_GNUTLS = @MFEM_USE_GNUTLS@
|
||||
MFEM_USE_NETCDF = @MFEM_USE_NETCDF@
|
||||
MFEM_USE_PETSC = @MFEM_USE_PETSC@
|
||||
MFEM_USE_MPFR = @MFEM_USE_MPFR@
|
||||
MFEM_USE_SIDRE = @MFEM_USE_SIDRE@
|
||||
|
||||
# Compiler, compile options, and link options
|
||||
MFEM_CXX = @MFEM_CXX@
|
||||
@@ -52,28 +37,17 @@ MFEM_CPPFLAGS = @MFEM_CPPFLAGS@
|
||||
MFEM_CXXFLAGS = @MFEM_CXXFLAGS@
|
||||
MFEM_TPLFLAGS = @MFEM_TPLFLAGS@
|
||||
MFEM_INCFLAGS = @MFEM_INCFLAGS@
|
||||
MFEM_PICFLAG = @MFEM_PICFLAG@
|
||||
MFEM_FLAGS = @MFEM_FLAGS@
|
||||
MFEM_EXT_LIBS = @MFEM_EXT_LIBS@
|
||||
MFEM_LIBS = @MFEM_LIBS@
|
||||
MFEM_LIB_FILE = @MFEM_LIB_FILE@
|
||||
MFEM_STATIC = @MFEM_STATIC@
|
||||
MFEM_SHARED = @MFEM_SHARED@
|
||||
MFEM_BUILD_TAG = @MFEM_BUILD_TAG@
|
||||
MFEM_PREFIX = @MFEM_PREFIX@
|
||||
MFEM_INC_DIR = @MFEM_INC_DIR@
|
||||
MFEM_LIB_DIR = @MFEM_LIB_DIR@
|
||||
|
||||
# Location of test.mk
|
||||
MFEM_TEST_MK = @MFEM_TEST_MK@
|
||||
|
||||
# Command used to launch MPI jobs
|
||||
MFEM_MPIEXEC = @MFEM_MPIEXEC@
|
||||
MFEM_MPIEXEC_NP = @MFEM_MPIEXEC_NP@
|
||||
MFEM_MPI_NP = @MFEM_MPI_NP@
|
||||
|
||||
# The NVCC compiler cannot link with -x=cu
|
||||
MFEM_LINK_FLAGS := $(filter-out -x=cu, $(MFEM_FLAGS))
|
||||
|
||||
# Optional extra configuration
|
||||
@MFEM_CONFIG_EXTRA@
|
||||
|
||||
@@ -18,38 +18,29 @@ if (NOT CMAKE_BUILD_TYPE)
|
||||
"Build type: Debug, Release, RelWithDebInfo, or MinSizeRel." FORCE)
|
||||
endif()
|
||||
|
||||
# MFEM options. Set to mimic the default "defaults.mk" file.
|
||||
# MFEM options. Set to mimic the default "default.mk" file.
|
||||
option(MFEM_USE_MPI "Enable MPI parallel build" OFF)
|
||||
option(MFEM_USE_METIS "Enable METIS usage" ${MFEM_USE_MPI})
|
||||
option(MFEM_USE_EXCEPTIONS "Enable the use of exceptions" OFF)
|
||||
option(MFEM_USE_GZSTREAM "Enable gzstream for compressed data streams." OFF)
|
||||
option(MFEM_USE_LIBUNWIND "Enable backtrace for errors." OFF)
|
||||
option(MFEM_USE_LAPACK "Enable LAPACK usage" OFF)
|
||||
option(MFEM_THREAD_SAFE "Enable thread safety" OFF)
|
||||
option(MFEM_USE_OPENMP "Enable the OpenMP backend" OFF)
|
||||
option(MFEM_USE_LEGACY_OPENMP "Enable legacy OpenMP usage" OFF)
|
||||
option(MFEM_USE_OPENMP "Enable OpenMP usage" OFF)
|
||||
option(MFEM_USE_MEMALLOC "Enable the internal MEMALLOC option." ON)
|
||||
option(MFEM_USE_SUNDIALS "Enable SUNDIALS usage" OFF)
|
||||
option(MFEM_USE_MESQUITE "Enable MESQUITE usage" OFF)
|
||||
option(MFEM_USE_SUITESPARSE "Enable SuiteSparse usage" OFF)
|
||||
option(MFEM_USE_SUPERLU "Enable SuperLU_DIST usage" OFF)
|
||||
option(MFEM_USE_STRUMPACK "Enable STRUMPACK usage" OFF)
|
||||
option(MFEM_USE_GECKO "Enable GECKO usage" OFF)
|
||||
option(MFEM_USE_GNUTLS "Enable GNUTLS usage" OFF)
|
||||
option(MFEM_USE_NETCDF "Enable NETCDF usage" OFF)
|
||||
option(MFEM_USE_PETSC "Enable PETSc support." OFF)
|
||||
option(MFEM_USE_MPFR "Enable MPFR usage." OFF)
|
||||
option(MFEM_USE_SIDRE "Enable Axom/Sidre usage" OFF)
|
||||
option(MFEM_USE_CONDUIT "Enable Conduit usage" OFF)
|
||||
option(MFEM_USE_PUMI "Enable PUMI" OFF)
|
||||
|
||||
set(MFEM_MPI_NP 4 CACHE STRING "Number of processes used for MPI tests")
|
||||
option(MFEM_USE_SIDRE "Enable ATK/Sidre usage" OFF)
|
||||
|
||||
# Allow a user to disable testing, examples, and/or miniapps at CONFIGURE TIME
|
||||
# if they don't want/need them (e.g. if MFEM is "just a dependency" and all they
|
||||
# need is the library, building all that stuff adds unnecessary overhead). Note
|
||||
# that the examples or miniapps can always be built using the targets 'examples'
|
||||
# or 'miniapps', respectively.
|
||||
# need is the library, building all that stuff adds unnecessary overhead). To
|
||||
# match "makefile" behavior, they are all enabled by default.
|
||||
option(MFEM_ENABLE_TESTING "Enable the ctest framework for testing" ON)
|
||||
option(MFEM_ENABLE_EXAMPLES "Build all of the examples" OFF)
|
||||
option(MFEM_ENABLE_MINIAPPS "Build all of the miniapps" OFF)
|
||||
@@ -75,7 +66,7 @@ set(METIS_DIR "${MFEM_DIR}/../metis-4.0" CACHE PATH "Path to the METIS library."
|
||||
|
||||
set(LIBUNWIND_DIR "" CACHE PATH "Path to Libunwind.")
|
||||
|
||||
set(SUNDIALS_DIR "${MFEM_DIR}/../sundials-3.0.0" CACHE PATH
|
||||
set(SUNDIALS_DIR "${MFEM_DIR}/../sundials-2.7.0" CACHE PATH
|
||||
"Path to the SUNDIALS library.")
|
||||
# The following may be necessary, if SUNDIALS was built with KLU:
|
||||
# set(SUNDIALS_REQUIRED_PACKAGES "SuiteSparse/KLU/AMD/BTF/COLAMD/config"
|
||||
@@ -100,34 +91,6 @@ set(SuperLUDist_DIR "${MFEM_DIR}/../SuperLU_DIST_5.1.0" CACHE PATH
|
||||
set(SuperLUDist_REQUIRED_PACKAGES "MPI" "BLAS" "ParMETIS" CACHE STRING
|
||||
"Additional packages required by SuperLU_DIST.")
|
||||
|
||||
set(STRUMPACK_DIR "${MFEM_DIR}/../STRUMPACK-build" CACHE PATH
|
||||
"Path to the STRUMPACK library.")
|
||||
# STRUMPACK may also depend on "OpenMP", depending on how it was compiled.
|
||||
# Starting with v2.2.0 of STRUMPACK, ParMETIS and Scotch are optional.
|
||||
set(STRUMPACK_REQUIRED_PACKAGES "MPI" "MPI_Fortran" "ParMETIS" "METIS"
|
||||
"ScaLAPACK" "Scotch/ptscotch/ptscotcherr/scotch/scotcherr" CACHE STRING
|
||||
"Additional packages required by STRUMPACK.")
|
||||
# If the MPI package does not find all required Fortran libraries:
|
||||
# set(STRUMPACK_REQUIRED_LIBRARIES "gfortran" "mpi_mpifh" CACHE STRING
|
||||
# "Additional libraries required by STRUMPACK.")
|
||||
|
||||
# The Scotch library, required by STRUMPACK <= v2.1.0, optional in STRUMPACK >=
|
||||
# v2.2.0.
|
||||
set(Scotch_DIR "${MFEM_DIR}/../scotch_6.0.4" CACHE PATH
|
||||
"Path to the Scotch and PT-Scotch libraries.")
|
||||
set(Scotch_REQUIRED_PACKAGES "Threads" CACHE STRING
|
||||
"Additional packages required by Scotch.")
|
||||
# Tell the "Threads" package/module to prefer pthreads.
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
set(Threads_LIB_VARS CMAKE_THREAD_LIBS_INIT)
|
||||
|
||||
# The ScaLAPACK library, required by STRUMPACK
|
||||
set(ScaLAPACK_DIR "${MFEM_DIR}/../scalapack-2.0.2/lib/cmake/scalapack-2.0.2"
|
||||
CACHE PATH "Path to the configuration file scalapack-config.cmake")
|
||||
set(ScaLAPACK_TARGET_NAMES scalapack)
|
||||
# set(ScaLAPACK_TARGET_FORCE)
|
||||
# set(ScaLAPACK_IMPORT_CONFIG DEBUG)
|
||||
|
||||
set(GECKO_DIR "${MFEM_DIR}/../gecko" CACHE PATH "Path to the Gecko library.")
|
||||
|
||||
set(GNUTLS_DIR "" CACHE PATH "Path to the GnuTLS library.")
|
||||
@@ -139,20 +102,19 @@ set(NetCDF_REQUIRED_PACKAGES "" CACHE STRING
|
||||
|
||||
set(PETSC_DIR "${MFEM_DIR}/../petsc" CACHE PATH
|
||||
"Path to the PETSc main directory.")
|
||||
set(PETSC_ARCH "arch-linux2-c-debug" CACHE STRING "PETSc build architecture.")
|
||||
set(PETSC_ARCH "arch-linux2-c-debug" CACHE PATH "PETSc build architecture.")
|
||||
|
||||
set(MPFR_DIR "" CACHE PATH "Path to the MPFR library.")
|
||||
|
||||
set(CONDUIT_DIR "${MFEM_DIR}/../conduit" CACHE PATH
|
||||
"Path to the Conduit library.")
|
||||
set(Conduit_REQUIRED_PACKAGES "HDF5" CACHE STRING
|
||||
"Additional packages required by Conduit.")
|
||||
|
||||
set(AXOM_DIR "${MFEM_DIR}/../axom" CACHE PATH "Path to the Axom library.")
|
||||
set(ATK_DIR "${MFEM_DIR}/../asctoolkit" CACHE PATH "Path to the ATK library.")
|
||||
# May need to add "Boost" as requirement.
|
||||
set(Axom_REQUIRED_PACKAGES "Conduit/relay" CACHE STRING
|
||||
"Additional packages required by Axom.")
|
||||
|
||||
set(PUMI_DIR "${MFEM_DIR}/../pumi-2.1.0" CACHE STRING
|
||||
"Directory where PUMI is installed")
|
||||
set(ATK_REQUIRED_PACKAGES "Conduit/relay" CACHE STRING
|
||||
"Additional packages required by ATK.")
|
||||
|
||||
set(BLAS_INCLUDE_DIRS "" CACHE STRING "Path to BLAS headers.")
|
||||
set(BLAS_LIBRARIES "" CACHE STRING "The BLAS library.")
|
||||
|
||||
@@ -21,13 +21,8 @@ NOTMAC := $(subst Darwin,,$(shell uname -s))
|
||||
CXX = g++
|
||||
MPICXX = mpicxx
|
||||
|
||||
BASE_FLAGS = -std=c++11
|
||||
OPTIM_FLAGS = -O3 $(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 =
|
||||
CXX_XLINKER = -Wl,
|
||||
OPTIM_FLAGS = -O3
|
||||
DEBUG_FLAGS = -g -Wall
|
||||
|
||||
# Destination location of make install
|
||||
# PREFIX = $(HOME)/mfem
|
||||
@@ -35,44 +30,15 @@ PREFIX = ./mfem
|
||||
# Install program
|
||||
INSTALL = /usr/bin/install
|
||||
|
||||
STATIC = YES
|
||||
SHARED = NO
|
||||
|
||||
# CUDA configuration options
|
||||
CUDA_CXX = nvcc
|
||||
CUDA_ARCH = sm_60
|
||||
CUDA_FLAGS = -x=cu --expt-extended-lambda -arch=$(CUDA_ARCH)
|
||||
# Prefixes for passing flags to the host compiler and linker when using CUDA_CXX
|
||||
CUDA_XCOMPILER = -Xcompiler=
|
||||
CUDA_XLINKER = -Xlinker=
|
||||
|
||||
ifneq ($(NOTMAC),)
|
||||
AR = ar
|
||||
ARFLAGS = cruv
|
||||
RANLIB = ranlib
|
||||
PICFLAG = $(XCOMPILER)-fPIC
|
||||
SO_EXT = so
|
||||
SO_VER = so.$(MFEM_VERSION_STRING)
|
||||
BUILD_SOFLAGS = -shared $(XLINKER)-soname,libmfem.$(SO_VER)
|
||||
BUILD_RPATH = $(XLINKER)-rpath,$(BUILD_REAL_DIR)
|
||||
INSTALL_SOFLAGS = $(BUILD_SOFLAGS)
|
||||
INSTALL_RPATH = $(XLINKER)-rpath,@MFEM_LIB_DIR@
|
||||
else
|
||||
# Silence "has no symbols" warnings on Mac OS X
|
||||
AR = ar
|
||||
ARFLAGS = Scruv
|
||||
RANLIB = ranlib -no_warning_for_no_symbols
|
||||
PICFLAG = $(XCOMPILER)-fPIC
|
||||
SO_EXT = dylib
|
||||
SO_VER = $(MFEM_VERSION_STRING).dylib
|
||||
MAKE_SOFLAGS = $(XLINKER)-dylib,-install_name,$(1)/libmfem.$(SO_VER),\
|
||||
-compatibility_version,$(MFEM_VERSION_STRING),\
|
||||
-current_version,$(MFEM_VERSION_STRING),\
|
||||
-undefined,dynamic_lookup
|
||||
BUILD_SOFLAGS = $(subst $1 ,,$(call MAKE_SOFLAGS,$(BUILD_REAL_DIR)))
|
||||
BUILD_RPATH = $(XLINKER)-undefined,dynamic_lookup
|
||||
INSTALL_SOFLAGS = $(subst $1 ,,$(call MAKE_SOFLAGS,$(MFEM_LIB_DIR)))
|
||||
INSTALL_RPATH = $(XLINKER)-undefined,dynamic_lookup
|
||||
endif
|
||||
|
||||
# Set CXXFLAGS to overwrite the default selection of DEBUG_FLAGS/OPTIM_FLAGS
|
||||
@@ -88,49 +54,31 @@ endif
|
||||
# Command used to launch MPI jobs
|
||||
MFEM_MPIEXEC = mpirun
|
||||
MFEM_MPIEXEC_NP = -np
|
||||
# Number of mpi tasks for parallel jobs
|
||||
MFEM_MPI_NP = 4
|
||||
|
||||
# MFEM configuration options: YES/NO values, which are exported to config.mk and
|
||||
# config.hpp. The values below are the defaults for generating the actual values
|
||||
# in config.mk and config.hpp.
|
||||
|
||||
MFEM_USE_MPI = NO
|
||||
MFEM_USE_METIS = $(MFEM_USE_MPI)
|
||||
MFEM_USE_METIS_5 = NO
|
||||
MFEM_DEBUG = NO
|
||||
MFEM_USE_EXCEPTIONS = NO
|
||||
MFEM_USE_GZSTREAM = NO
|
||||
MFEM_USE_LIBUNWIND = NO
|
||||
MFEM_USE_LAPACK = NO
|
||||
MFEM_THREAD_SAFE = NO
|
||||
MFEM_USE_OPENMP = NO
|
||||
MFEM_USE_LEGACY_OPENMP = NO
|
||||
MFEM_USE_MEMALLOC = YES
|
||||
MFEM_TIMER_TYPE = $(if $(NOTMAC),2,4)
|
||||
MFEM_USE_SUNDIALS = NO
|
||||
MFEM_USE_MESQUITE = NO
|
||||
MFEM_USE_SUITESPARSE = NO
|
||||
MFEM_USE_SUPERLU = NO
|
||||
MFEM_USE_STRUMPACK = NO
|
||||
MFEM_USE_GECKO = NO
|
||||
MFEM_USE_GNUTLS = NO
|
||||
MFEM_USE_NETCDF = NO
|
||||
MFEM_USE_PETSC = NO
|
||||
MFEM_USE_MPFR = NO
|
||||
MFEM_USE_SIDRE = NO
|
||||
MFEM_USE_CONDUIT = NO
|
||||
MFEM_USE_PUMI = NO
|
||||
MFEM_USE_CUDA = NO
|
||||
MFEM_USE_RAJA = NO
|
||||
MFEM_USE_OCCA = NO
|
||||
MFEM_USE_MM = NO
|
||||
|
||||
# Compile and link options for zlib.
|
||||
ZLIB_DIR =
|
||||
ZLIB_OPT = $(if $(ZLIB_DIR),-I$(ZLIB_DIR)/include)
|
||||
ZLIB_LIB = $(if $(ZLIB_DIR),$(ZLIB_RPATH) -L$(ZLIB_DIR)/lib ,)-lz
|
||||
ZLIB_RPATH = -Wl,-rpath,$(ZLIB_DIR)/lib
|
||||
MFEM_USE_MPI = NO
|
||||
MFEM_USE_METIS_5 = NO
|
||||
MFEM_DEBUG = NO
|
||||
MFEM_USE_GZSTREAM = NO
|
||||
MFEM_USE_LIBUNWIND = NO
|
||||
MFEM_USE_LAPACK = NO
|
||||
MFEM_THREAD_SAFE = NO
|
||||
MFEM_USE_OPENMP = NO
|
||||
MFEM_USE_MEMALLOC = YES
|
||||
MFEM_TIMER_TYPE = $(if $(NOTMAC),2,0)
|
||||
MFEM_USE_SUNDIALS = NO
|
||||
MFEM_USE_MESQUITE = NO
|
||||
MFEM_USE_SUITESPARSE = NO
|
||||
MFEM_USE_SUPERLU = NO
|
||||
MFEM_USE_GECKO = NO
|
||||
MFEM_USE_GNUTLS = NO
|
||||
MFEM_USE_NETCDF = NO
|
||||
MFEM_USE_PETSC = NO
|
||||
MFEM_USE_MPFR = NO
|
||||
MFEM_USE_SIDRE = NO
|
||||
|
||||
LIBUNWIND_OPT = -g
|
||||
LIBUNWIND_LIB = $(if $(NOTMAC),-lunwind -ldl,)
|
||||
@@ -141,7 +89,7 @@ HYPRE_OPT = -I$(HYPRE_DIR)/include
|
||||
HYPRE_LIB = -L$(HYPRE_DIR)/lib -lHYPRE
|
||||
|
||||
# METIS library configuration
|
||||
ifeq ($(MFEM_USE_SUPERLU)$(MFEM_USE_STRUMPACK),NONO)
|
||||
ifeq ($(MFEM_USE_SUPERLU),NO)
|
||||
ifeq ($(MFEM_USE_METIS_5),NO)
|
||||
METIS_DIR = @MFEM_DIR@/../metis-4.0
|
||||
METIS_OPT =
|
||||
@@ -152,10 +100,8 @@ ifeq ($(MFEM_USE_SUPERLU)$(MFEM_USE_STRUMPACK),NONO)
|
||||
METIS_LIB = -L$(METIS_DIR)/lib -lmetis
|
||||
endif
|
||||
else
|
||||
# ParMETIS: currently needed by SuperLU or STRUMPACK. We assume that METIS 5
|
||||
# ParMETIS currently needed only with SuperLU. We assume that METIS 5
|
||||
# (included with ParMETIS) is installed in the same location.
|
||||
# Starting with STRUMPACK v2.2.0, ParMETIS is an optional dependency while
|
||||
# METIS is still required.
|
||||
METIS_DIR = @MFEM_DIR@/../parmetis-4.0.3
|
||||
METIS_OPT = -I$(METIS_DIR)/include
|
||||
METIS_LIB = -L$(METIS_DIR)/lib -lparmetis -lmetis
|
||||
@@ -167,17 +113,17 @@ LAPACK_OPT =
|
||||
LAPACK_LIB = $(if $(NOTMAC),-llapack -lblas,-framework Accelerate)
|
||||
|
||||
# OpenMP configuration
|
||||
OPENMP_OPT = $(XCOMPILER)-fopenmp
|
||||
OPENMP_OPT = -fopenmp
|
||||
OPENMP_LIB =
|
||||
|
||||
# Used when MFEM_TIMER_TYPE = 2
|
||||
POSIX_CLOCKS_LIB = -lrt
|
||||
|
||||
# SUNDIALS library configuration
|
||||
SUNDIALS_DIR = @MFEM_DIR@/../sundials-3.0.0
|
||||
SUNDIALS_DIR = @MFEM_DIR@/../sundials-2.7.0
|
||||
SUNDIALS_OPT = -I$(SUNDIALS_DIR)/include
|
||||
SUNDIALS_LIB = -Wl,-rpath,$(SUNDIALS_DIR)/lib -L$(SUNDIALS_DIR)/lib\
|
||||
-lsundials_arkode -lsundials_cvode -lsundials_nvecserial -lsundials_kinsol
|
||||
-lsundials_arkode -lsundials_cvode -lsundials_nvecserial -lsundials_kinsol
|
||||
|
||||
ifeq ($(MFEM_USE_MPI),YES)
|
||||
SUNDIALS_LIB += -lsundials_nvecparhyp -lsundials_nvecparallel
|
||||
@@ -194,42 +140,14 @@ MESQUITE_LIB = -L$(MESQUITE_DIR)/lib -lmesquite
|
||||
LIB_RT = $(if $(NOTMAC),-lrt,)
|
||||
SUITESPARSE_DIR = @MFEM_DIR@/../SuiteSparse
|
||||
SUITESPARSE_OPT = -I$(SUITESPARSE_DIR)/include
|
||||
SUITESPARSE_LIB = -Wl,-rpath,$(SUITESPARSE_DIR)/lib -L$(SUITESPARSE_DIR)/lib\
|
||||
-lklu -lbtf -lumfpack -lcholmod -lcolamd -lamd -lcamd -lccolamd\
|
||||
-lsuitesparseconfig $(LIB_RT) $(METIS_LIB) $(LAPACK_LIB)
|
||||
SUITESPARSE_LIB = -L$(SUITESPARSE_DIR)/lib -lklu -lbtf -lumfpack -lcholmod\
|
||||
-lcolamd -lamd -lcamd -lccolamd -lsuitesparseconfig $(LIB_RT) $(METIS_LIB)\
|
||||
$(LAPACK_LIB)
|
||||
|
||||
# SuperLU library configuration
|
||||
SUPERLU_DIR = @MFEM_DIR@/../SuperLU_DIST_5.1.0
|
||||
SUPERLU_OPT = -I$(SUPERLU_DIR)/SRC
|
||||
SUPERLU_LIB = -Wl,-rpath,$(SUPERLU_DIR)/SRC -L$(SUPERLU_DIR)/SRC -lsuperlu_dist
|
||||
|
||||
# SCOTCH library configuration (required by STRUMPACK <= v2.1.0, optional in
|
||||
# STRUMPACK >= v2.2.0)
|
||||
SCOTCH_DIR = @MFEM_DIR@/../scotch_6.0.4
|
||||
SCOTCH_OPT = -I$(SCOTCH_DIR)/include
|
||||
SCOTCH_LIB = -L$(SCOTCH_DIR)/lib -lptscotch -lptscotcherr -lscotch -lscotcherr\
|
||||
-lpthread
|
||||
|
||||
# SCALAPACK library configuration (required by STRUMPACK)
|
||||
SCALAPACK_DIR = @MFEM_DIR@/../scalapack-2.0.2
|
||||
SCALAPACK_OPT = -I$(SCALAPACK_DIR)/SRC
|
||||
SCALAPACK_LIB = -L$(SCALAPACK_DIR)/lib -lscalapack $(LAPACK_LIB)
|
||||
|
||||
# MPI Fortran library, needed e.g. by STRUMPACK
|
||||
# MPICH:
|
||||
MPI_FORTRAN_LIB = -lmpifort
|
||||
# OpenMPI:
|
||||
# MPI_FORTRAN_LIB = -lmpi_mpifh
|
||||
# Additional Fortan library:
|
||||
# MPI_FORTRAN_LIB += -lgfortran
|
||||
|
||||
# STRUMPACK library configuration
|
||||
STRUMPACK_DIR = @MFEM_DIR@/../STRUMPACK-build
|
||||
STRUMPACK_OPT = -I$(STRUMPACK_DIR)/include $(SCOTCH_OPT)
|
||||
# If STRUMPACK was build with OpenMP support, the following may be need:
|
||||
# STRUMPACK_OPT += $(OPENMP_OPT)
|
||||
STRUMPACK_LIB = -L$(STRUMPACK_DIR)/lib -lstrumpack $(MPI_FORTRAN_LIB)\
|
||||
$(SCOTCH_LIB) $(SCALAPACK_LIB)
|
||||
SUPERLU_LIB = -L$(SUPERLU_DIR)/SRC -lsuperlu_dist
|
||||
|
||||
# Gecko library configuration
|
||||
GECKO_DIR = @MFEM_DIR@/../gecko
|
||||
@@ -241,83 +159,43 @@ GNUTLS_OPT =
|
||||
GNUTLS_LIB = -lgnutls
|
||||
|
||||
# NetCDF library configuration
|
||||
NETCDF_DIR = $(HOME)/local
|
||||
HDF5_DIR = $(HOME)/local
|
||||
NETCDF_OPT = -I$(NETCDF_DIR)/include -I$(HDF5_DIR)/include $(ZLIB_OPT)
|
||||
NETCDF_LIB = -Wl,-rpath,$(NETCDF_DIR)/lib -L$(NETCDF_DIR)/lib\
|
||||
-Wl,-rpath,$(HDF5_DIR)/lib -L$(HDF5_DIR)/lib\
|
||||
-lnetcdf -lhdf5_hl -lhdf5 $(ZLIB_LIB)
|
||||
NETCDF_DIR = $(HOME)/local
|
||||
HDF5_DIR = $(HOME)/local
|
||||
ZLIB_DIR = $(HOME)/local
|
||||
NETCDF_OPT = -I$(NETCDF_DIR)/include
|
||||
NETCDF_LIB = -L$(NETCDF_DIR)/lib -lnetcdf -L$(HDF5_DIR)/lib -lhdf5_hl -lhdf5\
|
||||
-L$(ZLIB_DIR)/lib -lz
|
||||
|
||||
# PETSc library configuration (version greater or equal to 3.8 or the dev branch)
|
||||
PETSC_ARCH := arch-linux2-c-debug
|
||||
PETSC_DIR := $(MFEM_DIR)/../petsc/$(PETSC_ARCH)
|
||||
PETSC_VARS := $(PETSC_DIR)/lib/petsc/conf/petscvariables
|
||||
PETSC_FOUND := $(if $(wildcard $(PETSC_VARS)),YES,)
|
||||
PETSC_INC_VAR = PETSC_CC_INCLUDES
|
||||
PETSC_LIB_VAR = PETSC_EXTERNAL_LIB_BASIC
|
||||
ifeq ($(PETSC_FOUND),YES)
|
||||
PETSC_OPT := $(shell sed -n "s/$(PETSC_INC_VAR) = *//p" $(PETSC_VARS))
|
||||
PETSC_LIB := $(shell sed -n "s/$(PETSC_LIB_VAR) = *//p" $(PETSC_VARS))
|
||||
PETSC_LIB := -Wl,-rpath,$(abspath $(PETSC_DIR))/lib\
|
||||
-L$(abspath $(PETSC_DIR))/lib -lpetsc $(PETSC_LIB)
|
||||
ifeq ($(MFEM_USE_PETSC),YES)
|
||||
PETSC_DIR := $(MFEM_DIR)/../petsc/arch-linux2-c-debug
|
||||
PETSC_PC := $(PETSC_DIR)/lib/pkgconfig/PETSc.pc
|
||||
$(if $(wildcard $(PETSC_PC)),,$(error PETSc config not found - $(PETSC_PC)))
|
||||
PETSC_OPT := $(shell sed -n "s/Cflags: *//p" $(PETSC_PC))
|
||||
PETSC_LIB := $(shell sed -n "s/Libs.*: *//p" $(PETSC_PC))
|
||||
PETSC_LIB := -Wl,-rpath -Wl,$(abspath $(PETSC_DIR))/lib $(PETSC_LIB)
|
||||
endif
|
||||
|
||||
# MPFR library configuration
|
||||
MPFR_OPT =
|
||||
MPFR_LIB = -lmpfr
|
||||
|
||||
# Conduit and required libraries configuration
|
||||
CONDUIT_DIR = @MFEM_DIR@/../conduit
|
||||
CONDUIT_OPT = -I$(CONDUIT_DIR)/include/conduit
|
||||
CONDUIT_LIB = \
|
||||
-Wl,-rpath,$(CONDUIT_DIR)/lib -L$(CONDUIT_DIR)/lib \
|
||||
-lconduit -lconduit_relay -lconduit_blueprint -ldl
|
||||
|
||||
# Check if Conduit was built with hdf5 support, by looking
|
||||
# for the relay hdf5 header
|
||||
CONDUIT_HDF5_HEADER=$(CONDUIT_DIR)/include/conduit/conduit_relay_hdf5.hpp
|
||||
ifneq (,$(wildcard $(CONDUIT_HDF5_HEADER)))
|
||||
CONDUIT_OPT += -I$(HDF5_DIR)/include
|
||||
CONDUIT_LIB += -Wl,-rpath,$(HDF5_DIR)/lib -L$(HDF5_DIR)/lib \
|
||||
-lhdf5 $(ZLIB_LIB)
|
||||
endif
|
||||
|
||||
# Sidre and required libraries configuration
|
||||
# Be sure to check the HDF5_DIR (set above) is correct
|
||||
SIDRE_DIR = @MFEM_DIR@/../axom
|
||||
SIDRE_DIR = @MFEM_DIR@/../asctoolkit
|
||||
CONDUIT_DIR = @MFEM_DIR@/../conduit
|
||||
SIDRE_OPT = -I$(SIDRE_DIR)/include -I$(CONDUIT_DIR)/include/conduit\
|
||||
-I$(HDF5_DIR)/include
|
||||
SIDRE_LIB = \
|
||||
-Wl,-rpath,$(SIDRE_DIR)/lib -L$(SIDRE_DIR)/lib \
|
||||
-Wl,-rpath,$(CONDUIT_DIR)/lib -L$(CONDUIT_DIR)/lib \
|
||||
-Wl,-rpath,$(HDF5_DIR)/lib -L$(HDF5_DIR)/lib \
|
||||
-lsidre -lslic -laxom_utils -lconduit -lconduit_relay -lhdf5 $(ZLIB_LIB) -ldl
|
||||
SIDRE_LIB = -L$(SIDRE_DIR)/lib \
|
||||
-L$(CONDUIT_DIR)/lib \
|
||||
-Wl,-rpath -Wl,$(CONDUIT_DIR)/lib \
|
||||
-L$(HDF5_DIR)/lib\
|
||||
-Wl,-rpath -Wl,$(HDF5_DIR)/lib \
|
||||
-lsidre -lslic -lcommon -lconduit -lconduit_relay -lhdf5 -lz -ldl
|
||||
|
||||
# PUMI
|
||||
# Note that PUMI_DIR is needed -- it is used to check for gmi_sim.h
|
||||
PUMI_DIR = @MFEM_DIR@/../pumi-2.1.0
|
||||
PUMI_OPT = -I$(PUMI_DIR)/include
|
||||
PUMI_LIB = -L$(PUMI_DIR)/lib -lpumi -lcrv -lma -lmds -lapf -lpcu -lgmi -lparma\
|
||||
-llion -lmth -lapf_zoltan -lspr
|
||||
|
||||
# CUDA library configuration. Since we compile and link with nvcc (when CUDA is
|
||||
# enabled) we only need to explicitly link with the CUDA driver, libcuda.*,
|
||||
# which is usually in a system path.
|
||||
CUDA_OPT =
|
||||
CUDA_LIB = $(if $(NOTMAC),,-L/usr/local/cuda/lib) -lcuda
|
||||
|
||||
# OCCA library configuration
|
||||
OCCA_DIR ?= @MFEM_DIR@/../occa
|
||||
OCCA_OPT = -I$(OCCA_DIR)/include
|
||||
OCCA_LIB = $(XLINKER)-rpath,$(OCCA_DIR)/lib -L$(OCCA_DIR)/lib -locca
|
||||
|
||||
# RAJA library configuration
|
||||
RAJA_DIR ?= @MFEM_DIR@/../raja
|
||||
RAJA_OPT = -I$(RAJA_DIR)/include
|
||||
ifdef CUB_DIR
|
||||
RAJA_OPT += -I$(CUB_DIR)
|
||||
ifeq ($(MFEM_USE_MPI),YES)
|
||||
SIDRE_LIB += -lspio -lcommon
|
||||
endif
|
||||
RAJA_LIB = $(XLINKER)-rpath,$(RAJA_DIR)/lib -L$(RAJA_DIR)/lib -lRAJA
|
||||
|
||||
# If YES, enable some informational messages
|
||||
VERBOSE = NO
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
|
||||
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
|
||||
// reserved. See file COPYRIGHT for details.
|
||||
//
|
||||
// This file is part of the MFEM library. For more information and source code
|
||||
// availability see http://mfem.org.
|
||||
//
|
||||
// MFEM is free software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Lesser General Public License (as published by the Free
|
||||
// Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
#include "HYPRE_config.h"
|
||||
#include <cstdio>
|
||||
|
||||
#ifdef HYPRE_RELEASE_VERSION
|
||||
#define HYPRE_VERSION_STRING HYPRE_RELEASE_VERSION
|
||||
#elif defined(HYPRE_PACKAGE_VERSION)
|
||||
#define HYPRE_VERSION_STRING HYPRE_PACKAGE_VERSION
|
||||
#endif
|
||||
|
||||
// Macros to expand a macro as a string
|
||||
#define STR_EXPAND(s) #s
|
||||
#define STR(s) STR_EXPAND(s)
|
||||
|
||||
// Convert the HYPRE_RELEASE_VERSION macro (string) to integer.
|
||||
// Examples: "2.10.0b" --> 21000, "2.11.2" --> 21102
|
||||
int main()
|
||||
{
|
||||
#ifdef HYPRE_VERSION_STRING
|
||||
const char *ptr = STR(HYPRE_VERSION_STRING);
|
||||
if (*ptr == '"') { ptr++; }
|
||||
int version = 0;
|
||||
for (int i = 0; i < 3; i++, ptr++)
|
||||
{
|
||||
int pv = 0;
|
||||
for (char d; d = *ptr, '0' <= d && d <= '9'; ptr++)
|
||||
{
|
||||
pv = 10*pv + (d - '0');
|
||||
if (pv >= 100) { return 1; }
|
||||
}
|
||||
version = 100*version + pv;
|
||||
}
|
||||
printf("%i\n", version);
|
||||
return 0;
|
||||
#else
|
||||
return 2;
|
||||
#endif
|
||||
}
|
||||
@@ -31,44 +31,17 @@ CONFIG_HPP = _config.hpp
|
||||
CONFIG_MK = config.mk
|
||||
|
||||
.SUFFIXES:
|
||||
.PHONY: all get-hypre-version header config-mk
|
||||
.PHONY: all header config-mk
|
||||
|
||||
all: header config-mk
|
||||
|
||||
MPI = $(MFEM_USE_MPI:NO=)
|
||||
GHV = get_hypre_version
|
||||
GHV_FLAGS = $(subst @MFEM_DIR@,$(if $(MFEM_DIR),$(MFEM_DIR),..),$(HYPRE_OPT))
|
||||
SMX = $(if $(MFEM_USE_PUMI:NO=),MFEM_USE_SIMMETRIX)
|
||||
SMX_PATH = $(PUMI_DIR)/include/gmi_sim.h
|
||||
SMX_FILE = $(subst @MFEM_DIR@,$(if $(MFEM_DIR),$(MFEM_DIR),..),$(SMX_PATH))
|
||||
|
||||
$(GHV): $(SRC)$(GHV).cpp
|
||||
$(call mfem-info, Determining HYPRE version ...)
|
||||
$(MFEM_CXX) ${GHV_FLAGS} $(SRC)$(GHV).cpp -o $(GHV)
|
||||
$(GHV).out: $(GHV)
|
||||
./$(GHV) > $(GHV).out
|
||||
.INTERMEDIATE: $(GHV) $(GHV).out
|
||||
|
||||
get-hypre-version: $(GHV).out
|
||||
$(eval MFEM_HYPRE_VERSION:=$(shell cat $(GHV).out))
|
||||
$(if $(MFEM_HYPRE_VERSION),$(eval export MFEM_HYPRE_VERSION)\
|
||||
$(info HYPRE version: $(MFEM_HYPRE_VERSION)),\
|
||||
$(error Unable to determine HYPRE version))
|
||||
|
||||
check-smx:
|
||||
$(call mfem-info, Checking for Simmetrix header [$(SMX_FILE)] ...)
|
||||
$(eval MFEM_USE_SIMMETRIX:=$(if $(wildcard $(SMX_FILE)),YES,NO))
|
||||
$(call mfem-info, MFEM_USE_SIMMETRIX = $(MFEM_USE_SIMMETRIX))
|
||||
$(eval export MFEM_USE_SIMMETRIX)
|
||||
|
||||
header: $(if $(MPI),get-hypre-version,) $(if $(SMX),check-smx)
|
||||
header:
|
||||
$(call mfem-info, Writing $(CONFIG_HPP) ...)
|
||||
@set -- && \
|
||||
for def in $${MFEM_DEFINES} $(if $(MPI),MFEM_HYPRE_VERSION) $(SMX); do \
|
||||
for def in $${MFEM_DEFINES}; do \
|
||||
eval var=\$$$$def && \
|
||||
if [ "NO" != "$${var}" ]; then \
|
||||
set -- "$$@" -e "s|// \(#define $${def} \)|\1|" && \
|
||||
set -- "$$@" -e "s|// \(#define $${def}\)$$|\1|" && \
|
||||
set -- "$$@" -e "s|// \(#define $${def}\)|\1|" && \
|
||||
set -- "$$@" -e "s#@$${def}@#$${var}#g"; \
|
||||
fi; \
|
||||
done && \
|
||||
@@ -89,4 +62,4 @@ config-mk:
|
||||
sed "$$@" $(SRC)config.mk.in > $(CONFIG_MK)
|
||||
|
||||
clean:
|
||||
rm -f $(CONFIG_HPP) $(CONFIG_MK) sample-runs-build.log
|
||||
rm -f $(CONFIG_HPP) $(CONFIG_MK)
|
||||
|
||||
@@ -1,534 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at the
|
||||
# Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights reserved.
|
||||
# See file COPYRIGHT for details.
|
||||
#
|
||||
# This file is part of the MFEM library. For more information and source code
|
||||
# availability see http://mfem.org.
|
||||
#
|
||||
# MFEM is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU Lesser General Public License (as published by the Free
|
||||
# Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
make="${MAKE:-make}"
|
||||
mpiexec="${MPIEXEC:-mpirun}"
|
||||
mpiexec_np="${MPIEXEC_NP:--np}"
|
||||
run_prefix=""
|
||||
run_vg="valgrind --leak-check=full --show-reachable=yes --track-origins=yes"
|
||||
run_suffix="-no-vis"
|
||||
skip_gen_meshes="yes"
|
||||
cur_dir="${PWD}"
|
||||
mfem_dir="$(cd "$(dirname "$0")"/.. && pwd)"
|
||||
mfem_build_dir=""
|
||||
build_log=""
|
||||
output_dir=""
|
||||
output_sfx=".out"
|
||||
# The group format is: '"group-name" "group-summary-title" "group-directory"
|
||||
# "group-source-patterns"'
|
||||
groups_serial=(
|
||||
'"examples"
|
||||
"Examples:"
|
||||
"examples"
|
||||
"ex{,1,2}[0-9].cpp"'
|
||||
# "ex1.cpp"'
|
||||
'"sundials"
|
||||
"SUNDIALS examples:"
|
||||
"examples/sundials"
|
||||
"ex{9,10,16}.cpp"'
|
||||
'"performance"
|
||||
"Performance miniapps:"
|
||||
"miniapps/performance"
|
||||
"ex1.cpp"'
|
||||
# ""'
|
||||
'"meshing"
|
||||
"Meshing miniapps:"
|
||||
"miniapps/meshing"
|
||||
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp
|
||||
mesh-optimizer.cpp"'
|
||||
)
|
||||
# Parallel groups
|
||||
groups_parallel=(
|
||||
'"examples"
|
||||
"Examples:"
|
||||
"examples"
|
||||
"ex{,1,2}[0-9]p.cpp"'
|
||||
# "ex1p.cpp"'
|
||||
'"sundials"
|
||||
"SUNDIALS examples:"
|
||||
"examples/sundials"
|
||||
"ex{9,10,16}p.cpp"'
|
||||
'"petsc"
|
||||
"PETSc examples:"
|
||||
"examples/petsc"
|
||||
"ex{,1}[0-9]p.cpp"'
|
||||
'"performance"
|
||||
"Performance miniapps:"
|
||||
"miniapps/performance"
|
||||
"ex1p.cpp"'
|
||||
# ""'
|
||||
'"meshing"
|
||||
"Meshing miniapps:"
|
||||
"miniapps/meshing"
|
||||
"pmesh-optimizer.cpp"'
|
||||
'"electromagnetics"
|
||||
"Electromagnetics miniapps:"
|
||||
"miniapps/electromagnetics"
|
||||
"joule.cpp"'
|
||||
# "{volta,tesla,joule}.cpp"' # todo: multiline sample runs
|
||||
)
|
||||
# All groups serial + parallel runs mixed in the same group:
|
||||
groups_all=(
|
||||
'"examples"
|
||||
"Examples:"
|
||||
"examples"
|
||||
"ex\"{,1,2}[0-9]\"{,p}.cpp"'
|
||||
'"sundials"
|
||||
"SUNDIALS examples:"
|
||||
"examples/sundials"
|
||||
"ex\"{9,10,16}\"{,p}.cpp"'
|
||||
'"petsc"
|
||||
"PETSc examples:"
|
||||
"examples/petsc"
|
||||
"ex{,1}[0-9]p.cpp"'
|
||||
'"performance"
|
||||
"Performance miniapps:"
|
||||
"miniapps/performance"
|
||||
"ex1{,p}.cpp"'
|
||||
'"meshing"
|
||||
"Meshing miniapps:"
|
||||
"miniapps/meshing"
|
||||
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp
|
||||
{,p}mesh-optimizer.cpp"'
|
||||
'"electromagnetics"
|
||||
"Electromagnetics miniapps:"
|
||||
"miniapps/electromagnetics"
|
||||
"joule.cpp"'
|
||||
# "{volta,tesla,joule}.cpp"' # todo: multiline sample runs
|
||||
)
|
||||
make_all="all"
|
||||
base_timeformat=$'real: %3Rs user: %3Us sys: %3Ss %%cpu: %P'
|
||||
# separator
|
||||
sep='----------------------------------------------------------------'
|
||||
|
||||
# Command line parameters:
|
||||
opt_help="no"
|
||||
opt_show="no"
|
||||
mfem_config="MFEM_USE_MPI=NO MFEM_DEBUG=NO"
|
||||
groups=()
|
||||
group_name=""
|
||||
group_title=""
|
||||
valgrind="no"
|
||||
make_j="-j $(getconf _NPROCESSORS_ONLN)"
|
||||
color="no"
|
||||
built="no"
|
||||
timing="no"
|
||||
|
||||
# Read the sample runs from the source "$1" and put them in the array variable
|
||||
# "runs".
|
||||
function extract_sample_runs()
|
||||
{
|
||||
local old_IFS="${IFS}" sruns="" pruns=""
|
||||
local src="$1"
|
||||
if [ "${src}" == "" ]; then runs=(); return 1; fi
|
||||
local app=${src%.cpp}
|
||||
local vg_app="${app}"
|
||||
if [ "${valgrind}" == "yes" ]; then vg_app="${run_vg} ${app}"; fi
|
||||
# parallel sample runs are lines matching "^//.* mpirun .* ${app}" with
|
||||
# everything in front of "mpirun" removed:
|
||||
pruns=`grep "^//.* mpirun .* ${app}" "${src}" |
|
||||
sed -e "s/.* mpirun \(.*\) ${app}/${mpiexec} \1 ${app}/g" \
|
||||
-e "s/ -np\(.*\) ${app}/ ${mpiexec_np}\1 ${vg_app}/g"`
|
||||
# serial sample runs are lines that are not parallel sample runs and matching
|
||||
# "^//.* ${app}" with everything in front of "${app}" removed:
|
||||
sruns=`grep -v "^//.* mpirun .* ${app}" "${src}" |
|
||||
grep "^//.* ${app}" |
|
||||
sed -e "s/.* ${app}/${vg_app}/g"`
|
||||
runs="${sruns}${pruns}"
|
||||
if [ "$skip_gen_meshes" == "yes" ]; then
|
||||
runs=`printf "%s" "$runs" | grep -v ".* -m .*\.gen"`
|
||||
fi
|
||||
IFS=$'\n'
|
||||
runs=(${runs})
|
||||
IFS="${old_IFS}"
|
||||
}
|
||||
|
||||
# Echo usage information
|
||||
function help_message()
|
||||
{
|
||||
cat <<EOF
|
||||
|
||||
$0 [options]
|
||||
|
||||
Options:
|
||||
-h|-help Print this usage information and exit
|
||||
-p|-par Build the parallel MFEM library + examples + miniapps.
|
||||
The default is to build the serial MFEM library + examples +
|
||||
miniapps. The build can be customized by setting the variable
|
||||
'mfem_config' or by building separately and using '-b'
|
||||
-g <dir> <pattern>
|
||||
Specify explicitly a group (dir + file pattern) to run; This
|
||||
option can be used multiple times to define multiple groups
|
||||
-v Enable valgrind
|
||||
-o <dir> [${output_dir:-"<empty>: output goes to stdout"}]
|
||||
If not empty, save output to files inside <dir>
|
||||
-d <dir> [${mfem_build_dir}]
|
||||
If <dir> is different from <mfem_dir> then use an
|
||||
out-of-source build in <dir>
|
||||
-j <np> [${make_j}] Specify the number of jobs to use for building
|
||||
-c|-color Always use colors for the status messages: OK, FAILED, etc
|
||||
-b|-built Do NOT rebuild the library and the executables
|
||||
-t|-time Measure and print execution time for each sample run
|
||||
-s|-show Show all configured sample runs and exit
|
||||
-n Dry run: replace "\$sample_run" with "echo \$sample_run"
|
||||
<var>=<value>
|
||||
Set a shell script varible; see below for valid variables
|
||||
* Any other parameter is treated as <mfem_dir>
|
||||
<mfem_dir> [${mfem_dir}] is the MFEM source directory
|
||||
|
||||
This script tests all the sample runs listed in the begining comments of
|
||||
MFEM's serial or parallel example and miniapp codes. The list of sample runs
|
||||
is auto-generated and can be viewed with the -s|-show option.
|
||||
|
||||
The following shell script variables can be set with <var>=<value>:
|
||||
output_dir [${output_dir}]
|
||||
Same as '-o': if not empty, save output to files in that directory
|
||||
output_sfx [${output_sfx}]
|
||||
Suffix to append to the output files
|
||||
mfem_config [${mfem_config}]
|
||||
Set MFEM configuration options
|
||||
make [${make}], mpiexec [${mpiexec}], mpiexec_np [${mpiexec_np}]
|
||||
Their values can also set using the respective uppercase environment
|
||||
variable
|
||||
mfem_build_dir [${mfem_build_dir}]
|
||||
Same as '-d': set this variable to something different from <mfem_dir>
|
||||
to use an out-of-source build
|
||||
|
||||
For other valid variables, see the script source.
|
||||
|
||||
The following environment variables, if non-empty, are used:
|
||||
MAKE, MPIEXEC, MPIEXEC_NP
|
||||
|
||||
Example usage:
|
||||
$0 -s [ Show all configured sample runs ]
|
||||
$0 -o baseline [ Serial build; run and save all built sample runs ]
|
||||
$0 -p -o baseline [ Parallel build; run and save all sample runs ]
|
||||
$0 -b -g examples ex8.cpp [ Use the existing build; run ex8 sample runs ]
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
function show_runs()
|
||||
{
|
||||
echo "${sep}"
|
||||
for group_params in "${groups[@]}"; do
|
||||
eval params=(${group_params})
|
||||
name="${params[0]}"
|
||||
title="${params[1]}"
|
||||
group_dir="${mfem_dir}/${params[2]}"
|
||||
pattern="${params[3]}"
|
||||
printf "group name: [%s]\n" "${name}"
|
||||
printf "summary title: [%s]\n" "${title}"
|
||||
printf "directory: [%s]\n" "${group_dir}"
|
||||
printf "pattern: [%s]\n" "${pattern}"
|
||||
cd "${cur_dir}"; cd "${group_dir}" || exit 1
|
||||
eval sources=(${pattern})
|
||||
eval sources=("${sources[@]}")
|
||||
printf "sources: (%s)\n" "${sources[*]}"
|
||||
printf "sample runs:\n"
|
||||
for src in "${sources[@]}"; do
|
||||
extract_sample_runs "${src}"
|
||||
for run in "${runs[@]}"; do
|
||||
printf " %s\n" "${run}"
|
||||
done
|
||||
done
|
||||
echo "${sep}"
|
||||
done
|
||||
}
|
||||
|
||||
# Process command line parameters
|
||||
while [ $# -gt 0 ]; do
|
||||
|
||||
case "$1" in
|
||||
-h|-help)
|
||||
opt_help="yes"
|
||||
;;
|
||||
-p|-parallel)
|
||||
mfem_config="MFEM_USE_MPI=YES MFEM_DEBUG=NO"
|
||||
;;
|
||||
-g)
|
||||
gbasename="$(basename "$2")"
|
||||
gname="${group_name:-${gbasename}}"
|
||||
gtitle="${group_title:-"Group <${gbasename}>:"}"
|
||||
test_group="\"${gname}\" \"${gtitle}\" \"$2\" \"$3\""
|
||||
groups=("${groups[@]}" "${test_group}")
|
||||
shift 2
|
||||
;;
|
||||
-v)
|
||||
valgrind="yes"
|
||||
;;
|
||||
-o)
|
||||
shift
|
||||
output_dir="$1"
|
||||
;;
|
||||
-d)
|
||||
shift
|
||||
mfem_build_dir="$1"
|
||||
;;
|
||||
-j)
|
||||
shift
|
||||
make_j="-j $1"
|
||||
;;
|
||||
-c|-color)
|
||||
color="yes"
|
||||
;;
|
||||
-b|-built)
|
||||
built="yes"
|
||||
;;
|
||||
-t|-time)
|
||||
timing="yes"
|
||||
;;
|
||||
-s|-show)
|
||||
opt_show="yes"
|
||||
;;
|
||||
-n)
|
||||
run_prefix="echo"
|
||||
;;
|
||||
*=*)
|
||||
eval $1
|
||||
;;
|
||||
*)
|
||||
mfem_dir="$1"
|
||||
;;
|
||||
esac
|
||||
|
||||
shift
|
||||
done # while ...
|
||||
|
||||
mfem_build_dir="${mfem_build_dir:-${mfem_dir}}"
|
||||
|
||||
build_log="${build_log:-${mfem_build_dir}/config/sample-runs-build.log}"
|
||||
|
||||
if [ 0 -eq ${#groups[*]} ]; then
|
||||
groups=("${groups_all[@]}")
|
||||
# These can be used as command line arguments:
|
||||
# 'groups=("${groups_serial[@]}")'
|
||||
# 'groups=("${groups_parallel[@]}")'
|
||||
fi
|
||||
|
||||
if [ "${opt_help}" == "yes" ]; then
|
||||
help_message
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ "${opt_show}" == "yes" ]; then
|
||||
show_runs
|
||||
exit
|
||||
fi
|
||||
|
||||
# Setup colors
|
||||
if [ -t 1 ] && [ -z "${output_dir}" ] || [ "${color}" == "yes" ]; then
|
||||
red='\033[0;31m'
|
||||
green='\033[0;32m'
|
||||
yellow='\033[0;33m'
|
||||
magenta='\033[0;35m'
|
||||
cyan='\033[0;36m'
|
||||
none='\033[0m'
|
||||
else
|
||||
red=
|
||||
green=
|
||||
yellow=
|
||||
magenta=
|
||||
cyan=
|
||||
none=
|
||||
fi
|
||||
|
||||
# Run the given command, saving the rune time in the variable "timer".
|
||||
function timed_run()
|
||||
{
|
||||
timer="$({ time "$@" 1>&3 2>&4; } 2>&1)"
|
||||
} 3>&1 4>&2
|
||||
|
||||
# This function is used to execute the sample runs
|
||||
function go()
|
||||
{
|
||||
local cmd=("$@")
|
||||
local res=""
|
||||
echo $sep
|
||||
echo "<${group}>" "${cmd[@]}"
|
||||
echo $sep
|
||||
if [ "${timing}" == "yes" ]; then
|
||||
timed_run "${cmd[@]}"
|
||||
else
|
||||
"${cmd[@]}"
|
||||
fi
|
||||
if [ "$?" -eq 0 ]; then
|
||||
res="${green} OK ${none}"
|
||||
else
|
||||
res="${red}FAILED${none}"
|
||||
fi
|
||||
printf "[${res}] <${group}> ${cmd[*]}\n"
|
||||
if [ "${timing}" == "yes" ]; then
|
||||
printf "Run time: %s\n" "${timer}"
|
||||
timer=(${timer})
|
||||
timer="${timer[1]}"
|
||||
printf -v line "[$res](%8s) ${cmd[*]}" "$timer"
|
||||
summary=("${summary[@]}" "$line")
|
||||
else
|
||||
summary=("${summary[@]}" "[${res}] ${cmd[*]}")
|
||||
fi
|
||||
echo $sep
|
||||
}
|
||||
|
||||
# This function is used to run a group of sample runs (in the same directory)
|
||||
function go_group()
|
||||
{
|
||||
local res=""
|
||||
if [ $# -eq 0 ]; then return 0; fi
|
||||
local group_output_dir="" output_file="" output=""
|
||||
if [ ! -z "$output_dir" ]; then
|
||||
group_output_dir="${output_dir}/${group_dir}"
|
||||
mkdir -p "${group_output_dir}" || exit 1
|
||||
fi
|
||||
for src in "$@"; do
|
||||
cd "${mfem_dir}/${group_dir}" || exit 1
|
||||
extract_sample_runs "${src}" || continue
|
||||
[ "${#runs[@]}" -eq 0 ] && continue
|
||||
cd "${mfem_build_dir}/${group_dir}" || exit 1
|
||||
if [ ! -x "${src%.cpp}" ]; then
|
||||
res="${magenta} SKIP ${none}"
|
||||
echo $sep
|
||||
printf "[${res}] <${group}> <${src}>\n"
|
||||
echo $sep
|
||||
summary=("${summary[@]}" "[${res}] <${src}>")
|
||||
continue
|
||||
fi
|
||||
if [ ! -z "$output_dir" ]; then
|
||||
output_file="${group_output_dir}/${src}${output_sfx}"
|
||||
: > "${output_file}"
|
||||
output=">> \"${output_file}\" 2>&1"
|
||||
fi
|
||||
for run in "${runs[@]}"; do
|
||||
if [ "${run}" == "" ]; then continue; fi
|
||||
eval go \${run_prefix} \${run} \${run_suffix} $output
|
||||
done
|
||||
done
|
||||
${make} clean-exec
|
||||
}
|
||||
|
||||
# Make sure $mfem_dir exists and we can cd into it
|
||||
cd "$mfem_dir" || exit 1
|
||||
# Make sure $mfem_dir is an absolute path
|
||||
mfem_dir="$PWD"
|
||||
cd "${cur_dir}"
|
||||
if [ "${built}" == "no" ]; then
|
||||
mkdir -p "${mfem_build_dir}" || exit 1
|
||||
fi
|
||||
# Make sure $mfem_build_dir exists and we can cd into it
|
||||
cd "${mfem_build_dir}" || exit 1
|
||||
# Make sure $mfem_build_dir is an absolute path
|
||||
mfem_build_dir="$PWD"
|
||||
# Setup 'output_dir'
|
||||
if [ ! -z "$output_dir" ]; then
|
||||
cd "${cur_dir}"
|
||||
mkdir -p "${output_dir}" && cd "${output_dir}" || exit 1
|
||||
output_dir="$PWD"
|
||||
echo "Sending output to files in: [${output_dir}]"
|
||||
echo "Using suffix: [${output_sfx}]"
|
||||
fi
|
||||
|
||||
TIMEFORMAT="${base_timeformat}"
|
||||
|
||||
function set_echo_log()
|
||||
{
|
||||
local dirname=`dirname "$1"`
|
||||
cd "${cur_dir}"
|
||||
mkdir -p "${dirname}" && cd "${dirname}" || exit 1
|
||||
echo_log="$PWD"/`basename "$1"`
|
||||
}
|
||||
|
||||
# Echo the given command line; then run it sending all output to $echo_log
|
||||
function echo_run()
|
||||
{
|
||||
echo " $@"
|
||||
{ echo " $@"; echo "$sep";
|
||||
"$@"
|
||||
echo "$sep"; } >> "$echo_log" 2>&1
|
||||
}
|
||||
|
||||
# Function that builds the mfem library, examples and miniapps
|
||||
function build_all()
|
||||
{
|
||||
printf "Building MFEM with all examples and miniapps:\n"
|
||||
set_echo_log "${build_log}"
|
||||
echo " ### build log: [$echo_log]"
|
||||
{ echo "$sep"; echo " MFEM build log"; echo "$sep"; } > "$echo_log"
|
||||
echo_run cd "${mfem_build_dir}"
|
||||
if [ "${mfem_dir}" != "${mfem_build_dir}" ]; then
|
||||
echo_run ${make} -f "${mfem_dir}"/makefile config
|
||||
fi
|
||||
# Don't use 'make distclean' as it will delete the default $build_log
|
||||
echo_run ${make} clean || exit 1
|
||||
echo_run ${make} config ${mfem_config} || exit 1
|
||||
echo_run ${make} ${make_j} || exit 1
|
||||
echo_run ${make} ${make_all} ${make_j} || exit 1
|
||||
}
|
||||
|
||||
# Function that runs all sample runs, given by the array variable "groups".
|
||||
function all_go()
|
||||
{
|
||||
for group_params in "${groups[@]}"; do
|
||||
eval params=(${group_params})
|
||||
group="${params[0]}"
|
||||
group_dir="${params[2]}"
|
||||
cd "${mfem_dir}/${group_dir}" || exit 1
|
||||
eval sources=(${params[3]})
|
||||
eval sources=("${sources[@]}")
|
||||
summary=("${summary[@]}" "${params[1]}")
|
||||
go_group "${sources[@]}"
|
||||
done
|
||||
|
||||
printf "Summary:\n--------\n"
|
||||
for line in "${summary[@]}"; do
|
||||
printf "${line}\n"
|
||||
done
|
||||
}
|
||||
|
||||
function main()
|
||||
{
|
||||
# Build all mfem examples and miniapps
|
||||
if [ "${built}" == "no" ]; then
|
||||
if [ "${timing}" == "yes" ]; then
|
||||
timed_run build_all
|
||||
printf "Build time: %s\n" "${timer}"
|
||||
else
|
||||
build_all
|
||||
fi
|
||||
fi
|
||||
|
||||
summary=()
|
||||
PATH=.:$PATH
|
||||
|
||||
# Print the MFEM configuration info
|
||||
cd "${mfem_build_dir}"
|
||||
echo "$sep"
|
||||
echo "MFEM configuration"
|
||||
echo "$sep"
|
||||
${make} info
|
||||
echo "$sep"
|
||||
|
||||
# Run all sample runs.
|
||||
if [ "${timing}" == "yes" ]; then
|
||||
timed_run all_go
|
||||
printf "Total run time: %s\n" "${timer}"
|
||||
else
|
||||
all_go
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
output=""
|
||||
if [ ! -z "$output_dir" ]; then
|
||||
output=">> \"${output_dir}/main${output_sfx}\" 2>&1"
|
||||
fi
|
||||
eval main $output
|
||||
@@ -10,49 +10,14 @@
|
||||
# Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
# Utilities for the "make test" and "make check" targets.
|
||||
|
||||
# Colors used below:
|
||||
# green '\033[0;32m'
|
||||
# red '\033[0;31m'
|
||||
# yellow '\033[0;33m'
|
||||
# no color '\033[0m'
|
||||
COLOR_PRINT = if [ -t 1 ]; then \
|
||||
printf $(1)$(2)'\033[0m'$(3); else printf $(2)$(3); fi
|
||||
PRINT_OK = $(call COLOR_PRINT,'\033[0;32m',OK," ($$1 $$2)\n")
|
||||
PRINT_FAILED = $(call COLOR_PRINT,'\033[0;31m',FAILED," ($$1 $$2)\n")
|
||||
PRINT_SKIP = $(call COLOR_PRINT,'\033[0;33m',SKIP,"\n")
|
||||
|
||||
# Timing support
|
||||
define TIMECMD_detect
|
||||
timecmd=$$(which time 2> /dev/null);
|
||||
if [ -n "$$timecmd" ]; then
|
||||
if $$timecmd --version > /dev/null 2>&1; then
|
||||
echo "$$timecmd" GNU; else echo "$$timecmd" NOTGNU; fi;
|
||||
else timecmd=$$(command -v time);
|
||||
if [ "$$timecmd" = time ]; then
|
||||
echo "$$timecmd" BASH; else echo X NONE; fi;
|
||||
fi
|
||||
endef
|
||||
define TIMECMD.GNU
|
||||
export TIME='%es %MkB %x'; \
|
||||
set -- $$($(1) $(SHELL) -c "$(2)" 2>&1); while [ "$$#" -gt 3 ]; do shift; done
|
||||
endef
|
||||
define TIMECMD.NOTGNU
|
||||
set -- $$($(1) -l $(SHELL) -c "{ $(2); } > /dev/null 2>&1" 2>&1; echo $$?); \
|
||||
set -- "$$1"s "$$(($$7/1024))"kB "$${60}"
|
||||
endef
|
||||
define TIMECMD.BASH
|
||||
TIMEFORMAT=$$'%3Rs'; \
|
||||
set -- $$({ time $(2); } 2>&1; echo $$?); set -- "$$1" "" "$$2"
|
||||
endef
|
||||
define TIMECMD.NONE
|
||||
$(2); set -- "" "" "$$?"
|
||||
endef
|
||||
TIMECMD := $(shell $(TIMECMD_detect))
|
||||
TIMEFUN := TIMECMD.$(word 2,$(TIMECMD))
|
||||
TIMECMD := $(word 1,$(TIMECMD))
|
||||
# Sample use of the timing macro: (returns shell commands as text)
|
||||
# $(call $(TIMEFUN),$(TIMECMD),$(MY_SHELL_COMMANDS))
|
||||
PRINT_OK = $(call COLOR_PRINT,'\033[0;32m',OK,"\n")
|
||||
PRINT_FAILED = $(call COLOR_PRINT,'\033[0;31m',FAILED,"\n")
|
||||
|
||||
ifneq (,$(filter test%,$(MAKECMDGOALS)))
|
||||
MAKEFLAGS += -k
|
||||
@@ -60,21 +25,16 @@ endif
|
||||
# Test runs of the examples/miniapps with parameters - check exit code
|
||||
mfem-test = \
|
||||
printf " $(3) [$(2) $(1) ... ]: "; \
|
||||
$(call $(TIMEFUN),$(TIMECMD),$(2) ./$(1) $(if $(5),,-no-vis )$(4) \
|
||||
> $(1).stderr 2>&1); \
|
||||
if [ "$$3" = 0 ]; \
|
||||
then $(PRINT_OK); else $(PRINT_FAILED); cat $(1).stderr; fi; \
|
||||
rm -f $(1).stderr; exit $$3
|
||||
if ($(2) ./$(1) -no-vis $(4) > /dev/null); \
|
||||
then $(PRINT_OK); else $(PRINT_FAILED); exit 1; fi
|
||||
|
||||
# Test runs of the examples/miniapps - check exit code and if a file exists
|
||||
mfem-test-file = \
|
||||
printf " $(3) [$(2) $(1) ... ]: "; \
|
||||
$(call $(TIMEFUN),$(TIMECMD),$(2) ./$(1) -no-vis > $(1).stderr 2>&1); \
|
||||
if [ "$$3" = 0 ] && [ -e $(4) ]; \
|
||||
then $(PRINT_OK); else $(PRINT_FAILED); cat $(1).stderr; fi; \
|
||||
rm -f $(1).stderr; exit $$3
|
||||
if ($(2) ./$(1) -no-vis > /dev/null) && [ -e $(4) ]; \
|
||||
then $(PRINT_OK); else $(PRINT_FAILED); exit 1; fi
|
||||
|
||||
.PHONY: test test-par-YES test-par-NO test-ser test-par test-clean test-print
|
||||
.PHONY: test test-par-YES test-par-NO
|
||||
|
||||
# What sets of tests to run in serial and parallel
|
||||
test-par-YES: $(PAR_$(MFEM_TESTS):=-test-par) $(SEQ_$(MFEM_TESTS):=-test-seq)
|
||||
@@ -82,12 +42,3 @@ test-par-NO: $(SEQ_$(MFEM_TESTS):=-test-seq)
|
||||
test-ser: test-par-NO
|
||||
test-par: test-par-YES
|
||||
test: all test-par-$(MFEM_USE_MPI) clean-exec
|
||||
test-clean: ; @rm -f *.stderr
|
||||
test-print: mfem-test=printf " $(3) [$(2) ./$(1) -no-vis $(if $(4),$(4) )]\n"
|
||||
test-print: mfem-test-file=printf " $(3) [$(2) ./$(1) -no-vis ]\n"
|
||||
test-print: test-par-$(MFEM_USE_MPI)
|
||||
ifeq ($(MAKECMDGOALS),test-print)
|
||||
.PHONY: $(PAR_$(MFEM_TESTS)) $(SEQ_$(MFEM_TESTS))
|
||||
endif
|
||||
|
||||
clean-exec: test-clean
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
MFEM mesh v1.1
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
17
|
||||
1 3 0 23 30 26
|
||||
1 3 26 30 25 21
|
||||
1 3 30 24 22 25
|
||||
1 3 23 18 24 30
|
||||
1 3 18 1 19 22
|
||||
1 3 22 19 10 20
|
||||
1 3 31 27 20 28
|
||||
1 3 25 22 27 31
|
||||
1 3 21 25 31 29
|
||||
1 3 29 31 28 9
|
||||
1 3 1 2 11 10
|
||||
1 3 2 3 12 11
|
||||
1 3 3 4 13 12
|
||||
2 3 4 5 14 13
|
||||
2 3 5 6 15 14
|
||||
2 3 6 7 16 15
|
||||
2 3 7 8 17 16
|
||||
|
||||
boundary
|
||||
25
|
||||
3 1 0 23
|
||||
1 1 26 0
|
||||
1 1 21 26
|
||||
3 1 23 18
|
||||
3 1 18 1
|
||||
3 1 10 20
|
||||
3 1 20 28
|
||||
1 1 29 21
|
||||
3 1 28 9
|
||||
1 1 9 29
|
||||
3 1 1 2
|
||||
3 1 11 10
|
||||
3 1 2 3
|
||||
3 1 12 11
|
||||
3 1 3 4
|
||||
3 1 13 12
|
||||
3 1 4 5
|
||||
3 1 14 13
|
||||
3 1 5 6
|
||||
3 1 15 14
|
||||
3 1 6 7
|
||||
3 1 16 15
|
||||
3 1 7 8
|
||||
2 1 8 17
|
||||
3 1 17 16
|
||||
|
||||
vertex_parents
|
||||
14
|
||||
18 0 1
|
||||
19 1 10
|
||||
20 9 10
|
||||
21 0 9
|
||||
22 18 20
|
||||
23 0 18
|
||||
24 18 22
|
||||
25 21 22
|
||||
26 0 21
|
||||
27 20 22
|
||||
28 9 20
|
||||
29 9 21
|
||||
30 23 25
|
||||
31 25 28
|
||||
|
||||
coarse_elements
|
||||
3
|
||||
3 0 3 2 1
|
||||
3 8 7 6 9
|
||||
3 17 4 5 18
|
||||
|
||||
vertices
|
||||
32
|
||||
2
|
||||
0 0
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
4 0
|
||||
5 0
|
||||
6 0
|
||||
7 0
|
||||
8 0
|
||||
0 1
|
||||
1 1
|
||||
2 1
|
||||
3 1
|
||||
4 1
|
||||
5 1
|
||||
6 1
|
||||
7 1
|
||||
8 1
|
||||
0.5 0
|
||||
1 0.5
|
||||
0.5 1
|
||||
0 0.5
|
||||
0.5 0.5
|
||||
0.25 0
|
||||
0.5 0.25
|
||||
0.25 0.5
|
||||
0 0.25
|
||||
0.5 0.75
|
||||
0.25 1
|
||||
0 0.75
|
||||
0.25 0.25
|
||||
0.25 0.75
|
||||
@@ -1,87 +0,0 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
elements
|
||||
8
|
||||
1 6 0 9 18 1 10 19
|
||||
1 6 1 10 19 2 11 20
|
||||
1 6 2 11 20 3 12 21
|
||||
1 6 3 12 21 4 13 22
|
||||
2 6 4 13 22 5 14 23
|
||||
2 6 5 14 23 6 15 24
|
||||
2 6 6 15 24 7 16 25
|
||||
2 6 7 16 25 8 17 26
|
||||
|
||||
boundary
|
||||
26
|
||||
1 2 0 18 9
|
||||
2 2 8 17 26
|
||||
3 3 0 9 10 1
|
||||
3 3 1 10 11 2
|
||||
3 3 2 11 12 3
|
||||
3 3 3 12 13 4
|
||||
3 3 4 13 14 5
|
||||
3 3 5 14 15 6
|
||||
3 3 6 15 16 7
|
||||
3 3 7 16 17 8
|
||||
3 3 18 0 1 19
|
||||
3 3 19 1 2 20
|
||||
3 3 20 2 3 21
|
||||
3 3 21 3 4 22
|
||||
3 3 22 4 5 23
|
||||
3 3 23 5 6 24
|
||||
3 3 24 6 7 25
|
||||
3 3 25 7 8 26
|
||||
3 3 9 18 19 10
|
||||
3 3 10 19 20 11
|
||||
3 3 11 20 21 12
|
||||
3 3 12 21 22 13
|
||||
3 3 13 22 23 14
|
||||
3 3 14 23 24 15
|
||||
3 3 15 24 25 16
|
||||
3 3 16 25 26 17
|
||||
|
||||
vertices
|
||||
27
|
||||
3
|
||||
0 0 0
|
||||
1 0 0
|
||||
2 0 0
|
||||
3 0 0
|
||||
4 0 0
|
||||
5 0 0
|
||||
6 0 0
|
||||
7 0 0
|
||||
8 0 0
|
||||
0 1 0
|
||||
1 1 0
|
||||
2 1 0
|
||||
3 1 0
|
||||
4 1 0
|
||||
5 1 0
|
||||
6 1 0
|
||||
7 1 0
|
||||
8 1 0
|
||||
0 0.5 1
|
||||
1 0.5 1
|
||||
2 0.5 1
|
||||
3 0.5 1
|
||||
4 0.5 1
|
||||
5 0.5 1
|
||||
6 0.5 1
|
||||
7 0.5 1
|
||||
8 0.5 1
|
||||
@@ -1,61 +0,0 @@
|
||||
# vtk DataFile Version 3.0
|
||||
Generated by MFEM
|
||||
ASCII
|
||||
DATASET UNSTRUCTURED_GRID
|
||||
POINTS 27 double
|
||||
0 0 0
|
||||
1 0 0
|
||||
2 0 0
|
||||
3 0 0
|
||||
4 0 0
|
||||
5 0 0
|
||||
6 0 0
|
||||
7 0 0
|
||||
8 0 0
|
||||
0 1 0
|
||||
1 1 0
|
||||
2 1 0
|
||||
3 1 0
|
||||
4 1 0
|
||||
5 1 0
|
||||
6 1 0
|
||||
7 1 0
|
||||
8 1 0
|
||||
0 0.5 1
|
||||
1 0.5 1
|
||||
2 0.5 1
|
||||
3 0.5 1
|
||||
4 0.5 1
|
||||
5 0.5 1
|
||||
6 0.5 1
|
||||
7 0.5 1
|
||||
8 0.5 1
|
||||
CELLS 8 56
|
||||
6 0 9 18 1 10 19
|
||||
6 1 10 19 2 11 20
|
||||
6 2 11 20 3 12 21
|
||||
6 3 12 21 4 13 22
|
||||
6 4 13 22 5 14 23
|
||||
6 5 14 23 6 15 24
|
||||
6 6 15 24 7 16 25
|
||||
6 7 16 25 8 17 26
|
||||
CELL_TYPES 8
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
13
|
||||
CELL_DATA 8
|
||||
SCALARS material int
|
||||
LOOKUP_TABLE default
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
2
|
||||
@@ -1,192 +0,0 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
elements
|
||||
14
|
||||
1 4 13 15 21 25
|
||||
1 4 15 13 21 12
|
||||
1 4 21 13 25 22
|
||||
1 4 15 21 25 24
|
||||
1 4 13 15 25 16
|
||||
1 5 0 1 4 3 9 10 13 12
|
||||
1 5 8 9 12 11 17 18 21 20
|
||||
1 5 2 3 6 5 11 12 15 14
|
||||
1 6 3 4 6 12 13 15
|
||||
1 6 4 7 6 13 16 15
|
||||
1 6 12 13 21 9 10 18
|
||||
1 6 13 22 21 10 19 18
|
||||
1 6 11 14 20 12 15 21
|
||||
1 6 15 21 24 14 20 23
|
||||
|
||||
boundary
|
||||
30
|
||||
1 3 5 6 3 2
|
||||
2 2 6 4 3
|
||||
2 2 4 6 7
|
||||
3 3 3 4 1 0
|
||||
4 3 11 12 9 8
|
||||
5 3 2 3 12 11
|
||||
6 3 0 1 10 9
|
||||
7 2 10 18 9
|
||||
7 2 18 10 19
|
||||
8 3 8 9 18 17
|
||||
9 3 1 4 13 10
|
||||
10 3 4 7 16 13
|
||||
11 2 25 13 16
|
||||
11 2 13 25 22
|
||||
12 3 10 13 22 19
|
||||
13 3 7 6 15 16
|
||||
14 3 6 5 14 15
|
||||
15 3 15 14 23 24
|
||||
16 2 15 25 16
|
||||
16 2 25 15 24
|
||||
17 3 5 2 11 14
|
||||
18 3 3 0 9 12
|
||||
19 3 11 8 17 20
|
||||
20 2 20 14 11
|
||||
20 2 14 20 23
|
||||
21 3 17 18 21 20
|
||||
22 3 18 19 22 21
|
||||
23 2 25 21 22
|
||||
23 2 21 25 24
|
||||
24 3 20 21 24 23
|
||||
|
||||
vertices
|
||||
26
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: H1_3D_P2
|
||||
VDim: 3
|
||||
Ordering: 1
|
||||
|
||||
0.028213666146621 -1.0129124616273 -1.0197422793601
|
||||
0.99151103207842 -0.97408353323117 -1.0219424221199
|
||||
-0.98628834960982 -0.048291393648833 -1.0334530425724
|
||||
-0.045286384224892 -0.028259630873799 -0.95961592583917
|
||||
1.0351351283956 0.016103611653671 -1.0465984194074
|
||||
-0.97963495329022 0.975340601895 -0.95050375238061
|
||||
-0.016565482225269 0.98394050155766 -1.0119900547434
|
||||
0.98232264800655 1.0061312792241 -0.97468885016611
|
||||
-1.0111163694877 -1.0328216757625 -0.033904406474903
|
||||
-0.031359497737139 -0.95907832225785 -0.02936147605069
|
||||
1.0216721775476 -0.95571139678359 -0.041445003869012
|
||||
-0.96617995956913 0.013420177670196 -0.047073400672525
|
||||
0.03735491973348 0.024136644229293 -0.035419858060777
|
||||
0.99844568660483 -0.023344853520393 0.043047091318294
|
||||
-1.0075354852248 0.95110015915707 0.040374961402267
|
||||
-0.018023004801944 0.98735854397528 0.035048884851858
|
||||
0.96496833880778 0.98624407089765 0.029059857856424
|
||||
-0.95618249163963 -0.95913625303656 0.99699592567049
|
||||
0.010523111699149 -1.0380611987319 1.0054330066312
|
||||
1.0131589291349 -0.99133288586241 1.0510169859154
|
||||
-0.9992929702159 -0.016950021823868 1.0209834648762
|
||||
-0.030905270343646 -0.024878516234457 0.96677784407511
|
||||
1.0369556044533 0.036727200814101 0.97476146325791
|
||||
-1.0268666699025 0.99100244478387 0.95557046163574
|
||||
0.032850918109418 0.9761234538078 0.99340013005027
|
||||
0.96517252528448 1.018590816239 0.96241486393546
|
||||
0.52641251369336 0.53453492783232 -0.046831832639522
|
||||
0.54842095679127 0.012466884090474 0.52264325135947
|
||||
1.0546647359835 0.51503200008771 0.47661895657821
|
||||
0.008193729444779 0.46320342579585 0.51330736048101
|
||||
0.48446121998846 1.0366433051979 0.46910527980021
|
||||
0.50338134740858 0.53372671722279 1.0016026703109
|
||||
-0.0026805294677615 0.54834160562605 -0.022633473388851
|
||||
0.4992129677441 -0.027650739811361 -0.025983834639192
|
||||
-0.010308592952788 0.043478553090245 0.54404251929373
|
||||
0.52373361142037 0.017260625417003 1.0190168930687
|
||||
0.95156254112601 0.024917951411289 0.48927665714905
|
||||
1.0114961385777 0.53988309084877 0.98077339629239
|
||||
0.01429600397056 1.0255897320394 0.44945099394948
|
||||
-0.0037663174125072 0.46114195337251 0.98693741812483
|
||||
0.53955416269275 0.95254191223583 0.99345054396648
|
||||
1.0344137934711 0.51549308419917 0.0019079259000746
|
||||
0.4635900873147 1.0074141174823 -0.025796540646941
|
||||
1.0393698821347 0.99823230649269 0.53561992818844
|
||||
0.54910938213579 -1.0186136680655 -1.0399189315271
|
||||
0.98251790353097 -0.52159510049969 -1.0488538759761
|
||||
0.51290647936985 0.019199261348695 -1.0180139709264
|
||||
0.039190890220925 -0.51870735888369 -1.0145805133507
|
||||
0.54531239252537 -1.0346180800814 -0.026071808021516
|
||||
1.0111227696296 -0.45961035727523 0.028725982550532
|
||||
-0.0024106570985168 -0.51591348233633 0.042102640075609
|
||||
0.019072471559048 -1.0489699664991 -0.53822694290429
|
||||
1.0197706996463 -1.0138504981995 -0.48532295548357
|
||||
0.97708769380115 0.012869927892461 -0.49512141938321
|
||||
-0.0056951441802084 -0.018287890031934 -0.46456751856022
|
||||
-0.48628377295099 -0.97137148869224 -0.040609835088253
|
||||
-0.52949825478718 0.022831952339038 0.036623532185331
|
||||
-0.9682938832324 -0.51529484749772 0.039498377451673
|
||||
-0.45076946932822 -0.98247022288851 1.0229644412175
|
||||
-0.036635886738077 -0.53934830226935 0.97308384231292
|
||||
-0.47986206617206 -0.041745604947209 0.98161771683954
|
||||
-0.95103283049539 -0.5087813614402 1.0116585971788
|
||||
-0.95395673410967 -0.95082942959853 0.50977751370519
|
||||
0.030673310998827 -0.97366141136736 0.47265974627808
|
||||
-1.0076441270299 0.025157339498401 0.51940553779714
|
||||
-0.45112570035271 0.030354945734143 -1.0244264173787
|
||||
-0.034796683816239 0.47213521944359 -1.0233666383661
|
||||
-0.52309081116691 1.0127369282767 -1.030445962213
|
||||
-1.0052867605351 0.54541603662074 -0.99267176855355
|
||||
-0.53441363093443 1.0101050069556 0.034852372528985
|
||||
-1.0361742412671 0.51952713127248 -0.0075041593052447
|
||||
-1.0224051106721 0.037305149668828 -0.51234883274883
|
||||
-0.0468317149207 0.99936735257506 -0.53290488454513
|
||||
-1.0323944162577 1.0470460939221 -0.49629869163036
|
||||
0.50827771586097 0.51091354087276 -0.96143114171132
|
||||
0.97860428203942 0.53881222049291 -1.0227558970328
|
||||
0.54899092558423 1.0449853148062 -1.0290394971016
|
||||
0.98149990118493 1.0265442789565 -0.45402792714566
|
||||
0.47938502309767 -0.95321110021154 0.46438798044786
|
||||
0.98893120098231 -1.0252040218394 0.52866776747387
|
||||
0.46061993861414 -0.973998097143 0.95264651015888
|
||||
0.98858339184873 -0.49578777734639 0.97955980177082
|
||||
-0.95322811676761 0.49312524158842 0.46350421594559
|
||||
-0.9670648949319 0.52720408663568 1.0147400701319
|
||||
-0.95970724064157 0.9966338243727 0.47198853459547
|
||||
-0.55076990539437 0.95548113087191 1.0002298586837
|
||||
0.48237521727569 -0.51972299404442 -0.98436066769063
|
||||
0.45025863721967 -1.0030842470471 -0.53693975312635
|
||||
0.95356930759735 -0.4606471833773 -0.49721032292582
|
||||
0.48610299886204 0.033102156873792 -0.45204877182841
|
||||
0.016292646434158 -0.4694908623118 -0.53292224425822
|
||||
0.47584088565782 -0.54223454683088 -0.036028525792062
|
||||
-0.53143287785351 -0.4923779387027 0.0039846746250987
|
||||
-0.52957315347157 -1.0359902368858 0.51208876920864
|
||||
-0.024055424472317 -0.49951890320517 0.48579422575422
|
||||
-0.45644746879116 -0.012607240816578 0.51010388839059
|
||||
-0.98394734906033 -0.50309513998218 0.47998268660158
|
||||
-0.53098605261184 -0.48258609846234 0.97544367099181
|
||||
-0.51822144156322 0.45223189569078 -1.0385291075334
|
||||
-0.45871022404172 -0.042734754644334 -0.54302125046961
|
||||
0.041843411838636 0.46222349074669 -0.5097909247037
|
||||
-0.45607118047774 1.0116704457439 -0.45481789885089
|
||||
-1.0244252419565 0.4849586374592 -0.50017994958907
|
||||
-0.52441235366277 0.50157218999229 0.023797604069114
|
||||
0.46467856940869 0.54693057615002 -0.46251054922067
|
||||
0.98669286111723 0.51824862516758 -0.45168929326637
|
||||
0.54790127868275 0.98589193659248 -0.51421705686245
|
||||
0.54233705943277 -0.4508773840935 0.45025142266283
|
||||
1.0203662623874 -0.5304726794563 0.52365051237419
|
||||
0.48446453821555 -0.47976663671026 1.043945324572
|
||||
-0.48793381256969 0.50247088679532 0.48323828733422
|
||||
-0.52670996575095 0.50194146344506 1.0026980744777
|
||||
-0.47523256142428 0.97748358070477 0.48234451559035
|
||||
0.45616661459208 -0.50770850274712 -0.4568053398747
|
||||
-0.52734654471278 -0.51337681044824 0.47594708297402
|
||||
-0.45737625267357 0.47732204026543 -0.54846904515289
|
||||
@@ -1,168 +0,0 @@
|
||||
# vtk DataFile Version 3.0
|
||||
Generated by MFEM
|
||||
ASCII
|
||||
DATASET UNSTRUCTURED_GRID
|
||||
POINTS 116 double
|
||||
0.028213666146621 -1.0129124616273 -1.0197422793601
|
||||
0.99151103207842 -0.97408353323117 -1.0219424221199
|
||||
-0.98628834960982 -0.048291393648833 -1.0334530425724
|
||||
-0.045286384224892 -0.028259630873799 -0.95961592583917
|
||||
1.0351351283956 0.016103611653671 -1.0465984194074
|
||||
-0.97963495329022 0.975340601895 -0.95050375238061
|
||||
-0.016565482225269 0.98394050155766 -1.0119900547434
|
||||
0.98232264800655 1.0061312792241 -0.97468885016611
|
||||
-1.0111163694877 -1.0328216757625 -0.033904406474903
|
||||
-0.031359497737139 -0.95907832225785 -0.02936147605069
|
||||
1.0216721775476 -0.95571139678359 -0.041445003869012
|
||||
-0.96617995956913 0.013420177670196 -0.047073400672525
|
||||
0.03735491973348 0.024136644229293 -0.035419858060777
|
||||
0.99844568660483 -0.023344853520393 0.043047091318294
|
||||
-1.0075354852248 0.95110015915707 0.040374961402267
|
||||
-0.018023004801944 0.98735854397528 0.035048884851858
|
||||
0.96496833880778 0.98624407089765 0.029059857856424
|
||||
-0.95618249163963 -0.95913625303656 0.99699592567049
|
||||
0.010523111699149 -1.0380611987319 1.0054330066312
|
||||
1.0131589291349 -0.99133288586241 1.0510169859154
|
||||
-0.9992929702159 -0.016950021823868 1.0209834648762
|
||||
-0.030905270343646 -0.024878516234457 0.96677784407511
|
||||
1.0369556044533 0.036727200814101 0.97476146325791
|
||||
-1.0268666699025 0.99100244478387 0.95557046163574
|
||||
0.032850918109418 0.9761234538078 0.99340013005027
|
||||
0.96517252528448 1.018590816239 0.96241486393546
|
||||
0.50338134740858 0.53372671722279 1.0016026703109
|
||||
0.54842095679127 0.012466884090474 0.52264325135947
|
||||
0.008193729444779 0.46320342579585 0.51330736048101
|
||||
1.0546647359835 0.51503200008771 0.47661895657821
|
||||
0.48446121998846 1.0366433051979 0.46910527980021
|
||||
0.52641251369336 0.53453492783232 -0.046831832639522
|
||||
-0.0026805294677615 0.54834160562605 -0.022633473388851
|
||||
0.4992129677441 -0.027650739811361 -0.025983834639192
|
||||
-0.010308592952788 0.043478553090245 0.54404251929373
|
||||
1.0114961385777 0.53988309084877 0.98077339629239
|
||||
0.52373361142037 0.017260625417003 1.0190168930687
|
||||
0.95156254112601 0.024917951411289 0.48927665714905
|
||||
-0.0037663174125072 0.46114195337251 0.98693741812483
|
||||
0.53955416269275 0.95254191223583 0.99345054396648
|
||||
0.01429600397056 1.0255897320394 0.44945099394948
|
||||
1.0344137934711 0.51549308419917 0.0019079259000746
|
||||
0.4635900873147 1.0074141174823 -0.025796540646941
|
||||
1.0393698821347 0.99823230649269 0.53561992818844
|
||||
0.54910938213579 -1.0186136680655 -1.0399189315271
|
||||
0.98251790353097 -0.52159510049969 -1.0488538759761
|
||||
0.51290647936985 0.019199261348695 -1.0180139709264
|
||||
0.039190890220925 -0.51870735888369 -1.0145805133507
|
||||
0.54531239252537 -1.0346180800814 -0.026071808021516
|
||||
1.0111227696296 -0.45961035727523 0.028725982550532
|
||||
-0.0024106570985168 -0.51591348233633 0.042102640075609
|
||||
0.019072471559048 -1.0489699664991 -0.53822694290429
|
||||
1.0197706996463 -1.0138504981995 -0.48532295548357
|
||||
0.97708769380115 0.012869927892461 -0.49512141938321
|
||||
-0.0056951441802084 -0.018287890031934 -0.46456751856022
|
||||
-0.48628377295099 -0.97137148869224 -0.040609835088253
|
||||
-0.52949825478718 0.022831952339038 0.036623532185331
|
||||
-0.9682938832324 -0.51529484749772 0.039498377451673
|
||||
-0.45076946932822 -0.98247022288851 1.0229644412175
|
||||
-0.036635886738077 -0.53934830226935 0.97308384231292
|
||||
-0.47986206617206 -0.041745604947209 0.98161771683954
|
||||
-0.95103283049539 -0.5087813614402 1.0116585971788
|
||||
-0.95395673410967 -0.95082942959853 0.50977751370519
|
||||
0.030673310998827 -0.97366141136736 0.47265974627808
|
||||
-1.0076441270299 0.025157339498401 0.51940553779714
|
||||
-0.45112570035271 0.030354945734143 -1.0244264173787
|
||||
-0.034796683816239 0.47213521944359 -1.0233666383661
|
||||
-0.52309081116691 1.0127369282767 -1.030445962213
|
||||
-1.0052867605351 0.54541603662074 -0.99267176855355
|
||||
-0.53441363093443 1.0101050069556 0.034852372528985
|
||||
-1.0361742412671 0.51952713127248 -0.0075041593052447
|
||||
-1.0224051106721 0.037305149668828 -0.51234883274883
|
||||
-0.0468317149207 0.99936735257506 -0.53290488454513
|
||||
-1.0323944162577 1.0470460939221 -0.49629869163036
|
||||
0.50827771586097 0.51091354087276 -0.96143114171132
|
||||
0.97860428203942 0.53881222049291 -1.0227558970328
|
||||
0.54899092558423 1.0449853148062 -1.0290394971016
|
||||
0.98149990118493 1.0265442789565 -0.45402792714566
|
||||
0.47938502309767 -0.95321110021154 0.46438798044786
|
||||
0.98893120098231 -1.0252040218394 0.52866776747387
|
||||
0.46061993861414 -0.973998097143 0.95264651015888
|
||||
0.98858339184873 -0.49578777734639 0.97955980177082
|
||||
-0.95322811676761 0.49312524158842 0.46350421594559
|
||||
-0.9670648949319 0.52720408663568 1.0147400701319
|
||||
-0.95970724064157 0.9966338243727 0.47198853459547
|
||||
-0.55076990539437 0.95548113087191 1.0002298586837
|
||||
0.48237521727569 -0.51972299404442 -0.98436066769063
|
||||
0.45025863721967 -1.0030842470471 -0.53693975312635
|
||||
0.95356930759735 -0.4606471833773 -0.49721032292582
|
||||
0.48610299886204 0.033102156873792 -0.45204877182841
|
||||
0.016292646434158 -0.4694908623118 -0.53292224425822
|
||||
0.47584088565782 -0.54223454683088 -0.036028525792062
|
||||
-0.53143287785351 -0.4923779387027 0.0039846746250987
|
||||
-0.52957315347157 -1.0359902368858 0.51208876920864
|
||||
-0.024055424472317 -0.49951890320517 0.48579422575422
|
||||
-0.45644746879116 -0.012607240816578 0.51010388839059
|
||||
-0.98394734906033 -0.50309513998218 0.47998268660158
|
||||
-0.53098605261184 -0.48258609846234 0.97544367099181
|
||||
-0.51822144156322 0.45223189569078 -1.0385291075334
|
||||
-0.45871022404172 -0.042734754644334 -0.54302125046961
|
||||
0.041843411838636 0.46222349074669 -0.5097909247037
|
||||
-0.45607118047774 1.0116704457439 -0.45481789885089
|
||||
-1.0244252419565 0.4849586374592 -0.50017994958907
|
||||
-0.52441235366277 0.50157218999229 0.023797604069114
|
||||
0.46467856940869 0.54693057615002 -0.46251054922067
|
||||
0.98669286111723 0.51824862516758 -0.45168929326637
|
||||
0.54790127868275 0.98589193659248 -0.51421705686245
|
||||
0.54233705943277 -0.4508773840935 0.45025142266283
|
||||
1.0203662623874 -0.5304726794563 0.52365051237419
|
||||
0.48446453821555 -0.47976663671026 1.043945324572
|
||||
-0.48793381256969 0.50247088679532 0.48323828733422
|
||||
-0.52670996575095 0.50194146344506 1.0026980744777
|
||||
-0.47523256142428 0.97748358070477 0.48234451559035
|
||||
0.45616661459208 -0.50770850274712 -0.4568053398747
|
||||
-0.52734654471278 -0.51337681044824 0.47594708297402
|
||||
-0.45737625267357 0.47732204026543 -0.54846904515289
|
||||
CELLS 14 253
|
||||
10 21 25 13 15 26 29 27 28 30 31
|
||||
10 15 13 21 12 31 27 28 32 33 34
|
||||
10 25 21 13 22 26 27 29 35 36 37
|
||||
10 21 25 15 24 26 30 28 38 39 40
|
||||
10 13 15 25 16 31 30 29 41 42 43
|
||||
27 0 1 4 3 9 10 13 12 44 45 46 47 48 49 33 50 51 52 53 54 90 88 87 89 86 91 113
|
||||
27 8 9 12 11 17 18 21 20 55 50 56 57 58 59 60 61 62 63 34 64 96 94 93 95 92 97 114
|
||||
27 2 3 6 5 11 12 15 14 65 66 67 68 56 32 69 70 71 54 72 73 102 100 99 101 98 103 115
|
||||
18 3 6 4 12 15 13 66 74 46 32 31 33 54 72 53 100 104 89
|
||||
18 4 6 7 13 15 16 74 76 75 31 42 41 53 72 77 104 106 105
|
||||
18 12 21 13 9 18 10 34 27 33 63 78 48 50 59 49 94 107 91
|
||||
18 13 21 22 10 18 19 27 36 37 78 80 79 49 59 81 107 109 108
|
||||
18 11 20 14 12 21 15 64 82 70 34 28 32 56 60 69 95 110 103
|
||||
18 15 24 21 14 23 20 40 38 28 84 83 82 69 85 60 112 111 110
|
||||
CELL_TYPES 14
|
||||
24
|
||||
24
|
||||
24
|
||||
24
|
||||
24
|
||||
29
|
||||
29
|
||||
29
|
||||
32
|
||||
32
|
||||
32
|
||||
32
|
||||
32
|
||||
32
|
||||
CELL_DATA 14
|
||||
SCALARS material int
|
||||
LOOKUP_TABLE default
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
@@ -1,96 +0,0 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
elements
|
||||
14
|
||||
1 4 13 15 21 25
|
||||
1 4 12 13 15 21
|
||||
1 4 13 21 22 25
|
||||
1 4 15 24 21 25
|
||||
1 4 13 15 25 16
|
||||
1 5 0 1 4 3 9 10 13 12
|
||||
1 5 8 9 12 11 17 18 21 20
|
||||
1 5 2 3 6 5 11 12 15 14
|
||||
1 6 3 4 6 12 13 15
|
||||
1 6 4 7 6 13 16 15
|
||||
1 6 12 13 21 9 10 18
|
||||
1 6 13 22 21 10 19 18
|
||||
1 6 11 14 20 12 15 21
|
||||
1 6 15 21 24 14 20 23
|
||||
|
||||
boundary
|
||||
30
|
||||
1 3 5 6 3 2
|
||||
2 2 3 6 4
|
||||
2 2 4 6 7
|
||||
3 3 3 4 1 0
|
||||
4 3 11 12 9 8
|
||||
5 3 2 3 12 11
|
||||
6 3 0 1 10 9
|
||||
7 2 9 10 18
|
||||
7 2 10 19 18
|
||||
8 3 8 9 18 17
|
||||
9 3 1 4 13 10
|
||||
10 3 4 7 16 13
|
||||
11 2 13 16 25
|
||||
11 2 13 25 22
|
||||
12 3 10 13 22 19
|
||||
13 3 7 6 15 16
|
||||
14 3 6 5 14 15
|
||||
15 3 15 14 23 24
|
||||
16 2 16 15 25
|
||||
16 2 15 24 25
|
||||
17 3 5 2 11 14
|
||||
18 3 3 0 9 12
|
||||
19 3 11 8 17 20
|
||||
20 2 11 20 14
|
||||
20 2 14 20 23
|
||||
21 3 17 18 21 20
|
||||
22 3 18 19 22 21
|
||||
23 2 21 22 25
|
||||
23 2 21 25 24
|
||||
24 3 20 21 24 23
|
||||
|
||||
vertices
|
||||
26
|
||||
3
|
||||
0 -1 -1
|
||||
1 -1 -1
|
||||
-1 0 -1
|
||||
0 0 -1
|
||||
1 0 -1
|
||||
-1 1 -1
|
||||
0 1 -1
|
||||
1 1 -1
|
||||
-1 -1 0
|
||||
0 -1 0
|
||||
1 -1 0
|
||||
-1 0 0
|
||||
0 0 0
|
||||
1 0 0
|
||||
-1 1 0
|
||||
0 1 0
|
||||
1 1 0
|
||||
-1 -1 1
|
||||
0 -1 1
|
||||
1 -1 1
|
||||
-1 0 1
|
||||
0 0 1
|
||||
1 0 1
|
||||
-1 1 1
|
||||
0 1 1
|
||||
1 1 1
|
||||
@@ -19,10 +19,10 @@ elements
|
||||
1 5 0 1 4 3 9 10 13 12
|
||||
1 5 3 4 7 6 12 13 16 15
|
||||
1 5 2 3 6 5 11 12 15 14
|
||||
1 5 11 12 15 14 20 21 24 23
|
||||
1 5 12 13 16 15 21 22 25 24
|
||||
1 5 9 10 13 12 18 19 22 21
|
||||
1 5 8 9 12 11 17 18 21 20
|
||||
1 5 9 10 13 12 18 19 22 21
|
||||
1 5 12 13 16 15 21 22 25 24
|
||||
1 5 11 12 15 14 20 21 24 23
|
||||
|
||||
boundary
|
||||
24
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
MFEM INLINE mesh v1.0
|
||||
|
||||
type = wedge
|
||||
nx = 4
|
||||
ny = 4
|
||||
nz = 4
|
||||
sx = 1.0
|
||||
sy = 1.0
|
||||
sz = 1.0
|
||||
@@ -1,182 +0,0 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
30
|
||||
1 3 0 11 26 14
|
||||
1 3 0 14 27 17
|
||||
1 3 0 17 28 20
|
||||
1 3 0 20 29 23
|
||||
1 3 0 23 30 11
|
||||
1 2 1 26 11
|
||||
1 2 26 1 12
|
||||
1 3 26 12 3 13
|
||||
1 2 2 26 13
|
||||
1 2 26 2 14
|
||||
1 2 2 27 14
|
||||
1 2 27 2 15
|
||||
1 3 27 15 5 16
|
||||
1 2 4 27 16
|
||||
1 2 27 4 17
|
||||
1 2 4 28 17
|
||||
1 2 28 4 18
|
||||
1 3 28 18 7 19
|
||||
1 2 6 28 19
|
||||
1 2 28 6 20
|
||||
1 2 6 29 20
|
||||
1 2 29 6 21
|
||||
1 3 29 21 9 22
|
||||
1 2 8 29 22
|
||||
1 2 29 8 23
|
||||
1 2 8 30 23
|
||||
1 2 30 8 24
|
||||
1 3 30 24 10 25
|
||||
1 2 1 30 25
|
||||
1 2 30 1 11
|
||||
|
||||
boundary
|
||||
20
|
||||
1 1 13 2
|
||||
1 1 12 3
|
||||
1 1 16 4
|
||||
1 1 15 5
|
||||
1 1 19 6
|
||||
1 1 18 7
|
||||
1 1 22 8
|
||||
1 1 21 9
|
||||
1 1 25 1
|
||||
1 1 24 10
|
||||
1 1 3 13
|
||||
1 1 1 12
|
||||
1 1 5 16
|
||||
1 1 2 15
|
||||
1 1 7 19
|
||||
1 1 4 18
|
||||
1 1 9 22
|
||||
1 1 6 21
|
||||
1 1 10 25
|
||||
1 1 8 24
|
||||
|
||||
vertices
|
||||
31
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: H1_2D_P2
|
||||
VDim: 2
|
||||
Ordering: 1
|
||||
|
||||
0.01350768617383 -0.0075500592639684
|
||||
1 0
|
||||
0.309017 0.951057
|
||||
1.30902 0.951057
|
||||
-0.809017 0.587785
|
||||
-0.5 1.53884
|
||||
-0.809017 -0.587785
|
||||
-1.61803 0
|
||||
0.309017 -0.951057
|
||||
-0.5 -1.53884
|
||||
1.30902 -0.951057
|
||||
0.4935497789318 -0.012882964767041
|
||||
1.15451 0.475529
|
||||
0.809019 0.951057
|
||||
0.17136163619581 0.48175756223348
|
||||
-0.0954915 1.24495
|
||||
-0.654508 1.06331
|
||||
-0.41734925397369 0.28726550311701
|
||||
-1.21352 0.293893
|
||||
-1.21352 -0.293892
|
||||
-0.39460365124056 -0.30156877530663
|
||||
-0.654508 -1.06331
|
||||
-0.0954915 -1.24495
|
||||
0.14399901886801 -0.48762042397771
|
||||
0.809019 -0.951057
|
||||
1.15451 -0.475529
|
||||
0.6498356311584 0.48434918539882
|
||||
-0.24288407581812 0.75594729997554
|
||||
-0.8152592767797 0.0028387384025541
|
||||
-0.22754482186326 -0.77540708661379
|
||||
0.672255499984 -0.48174474211839
|
||||
0.22829595615988 0.0021164169942289
|
||||
0.60101450815825 0.21860266792331
|
||||
0.41883194868682 0.47605389684094
|
||||
0.07343165966527 0.21396989328966
|
||||
-0.02571592547416 0.63942139993498
|
||||
-0.32229829912758 0.53827901417123
|
||||
-0.17873676879185 0.14412581843398
|
||||
-0.6182337454462 0.14256917811499
|
||||
-0.59596471744054 -0.16569961862581
|
||||
-0.19439899436461 -0.12390276596268
|
||||
-0.33986575323528 -0.53331120777067
|
||||
-0.064647379830725 -0.60235938684263
|
||||
0.091924539036435 -0.25440885597942
|
||||
0.40469418107844 -0.47549896605132
|
||||
0.59442400974309 -0.23815570080881
|
||||
0.83567929699787 0.25605757828544
|
||||
0.73491944894413 -0.013500778246483
|
||||
1.077255 0.2377645
|
||||
0.88696375569985 0.49133008726061
|
||||
1.231765 0.713293
|
||||
1.0590195 0.951057
|
||||
0.72725653289275 0.73104100472096
|
||||
0.50225974659165 0.6904536152084
|
||||
0.559018 0.951057
|
||||
0.23657516510421 0.69857072686934
|
||||
0.011561493903121 0.87524541641085
|
||||
0.10676275 1.0980035
|
||||
-0.17127243181091 0.99863326833074
|
||||
-0.29774575 1.391895
|
||||
-0.577254 1.301075
|
||||
-0.45323351407757 0.93490604288187
|
||||
-0.55200861955087 0.66792304985565
|
||||
-0.7317625 0.8255475
|
||||
-0.58327877079184 0.4240660861124
|
||||
-0.81465656906104 0.28713104760848
|
||||
-1.0112685 0.440839
|
||||
-0.99771272279525 0.1592736885552
|
||||
-1.415775 0.1469465
|
||||
-1.415775 -0.146946
|
||||
-1.0166887889241 -0.16866723370018
|
||||
-0.80412516287867 -0.29582734656
|
||||
-1.0112685 -0.4408385
|
||||
-0.6073309356422 -0.45826153759998
|
||||
-0.55501395481483 -0.68914767547246
|
||||
-0.7317625 -0.8255475
|
||||
-0.45240617124569 -0.93833106759189
|
||||
-0.577254 -1.301075
|
||||
-0.29774575 -1.391895
|
||||
-0.1923419715726 -1.0285844005569
|
||||
0.031614306262131 -0.83601077226744
|
||||
0.10676275 -1.0980035
|
||||
0.22112358843745 -0.69009711121629
|
||||
0.50046759811715 -0.72837571286759
|
||||
0.559018 -0.951057
|
||||
0.71074483315985 -0.70826931724532
|
||||
1.0590195 -0.951057
|
||||
1.231765 -0.713293
|
||||
0.89135027612826 -0.46226040977064
|
||||
0.84948897506491 -0.23986695857234
|
||||
1.077255 -0.2377645
|
||||
0.31586449185434 0.2462788698702
|
||||
-0.13788918217579 0.40149150514309
|
||||
-0.40416548945856 0.0027692745957735
|
||||
-0.14861804521337 -0.3698676302047
|
||||
0.33007376541085 -0.24598293851351
|
||||
0.99473757603443 0.69214841080247
|
||||
-0.38122249894249 1.1629329119286
|
||||
-1.208195003484 -0.0026998371675556
|
||||
-0.35890854853443 -1.1361244276705
|
||||
0.9901912195942 -0.73640851058427
|
||||
@@ -1,201 +0,0 @@
|
||||
# vtk DataFile Version 3.0
|
||||
Generated by MFEM
|
||||
ASCII
|
||||
DATASET UNSTRUCTURED_GRID
|
||||
POINTS 101 double
|
||||
0.01350768617383 -0.0075500592639684 0
|
||||
1 0 0
|
||||
0.309017 0.951057 0
|
||||
1.30902 0.951057 0
|
||||
-0.809017 0.587785 0
|
||||
-0.5 1.53884 0
|
||||
-0.809017 -0.587785 0
|
||||
-1.61803 0 0
|
||||
0.309017 -0.951057 0
|
||||
-0.5 -1.53884 0
|
||||
1.30902 -0.951057 0
|
||||
0.4935497789318 -0.012882964767041 0
|
||||
1.15451 0.475529 0
|
||||
0.809019 0.951057 0
|
||||
0.17136163619581 0.48175756223348 0
|
||||
-0.0954915 1.24495 0
|
||||
-0.654508 1.06331 0
|
||||
-0.41734925397369 0.28726550311701 0
|
||||
-1.21352 0.293893 0
|
||||
-1.21352 -0.293892 0
|
||||
-0.39460365124056 -0.30156877530663 0
|
||||
-0.654508 -1.06331 0
|
||||
-0.0954915 -1.24495 0
|
||||
0.14399901886801 -0.48762042397771 0
|
||||
0.809019 -0.951057 0
|
||||
1.15451 -0.475529 0
|
||||
0.6498356311584 0.48434918539882 0
|
||||
-0.24288407581812 0.75594729997554 0
|
||||
-0.8152592767797 0.0028387384025541 0
|
||||
-0.22754482186326 -0.77540708661379 0
|
||||
0.672255499984 -0.48174474211839 0
|
||||
0.22829595615988 0.0021164169942289 0
|
||||
0.60101450815825 0.21860266792331 0
|
||||
0.41883194868682 0.47605389684094 0
|
||||
0.07343165966527 0.21396989328966 0
|
||||
-0.02571592547416 0.63942139993498 0
|
||||
-0.32229829912758 0.53827901417123 0
|
||||
-0.17873676879185 0.14412581843398 0
|
||||
-0.6182337454462 0.14256917811499 0
|
||||
-0.59596471744054 -0.16569961862581 0
|
||||
-0.19439899436461 -0.12390276596268 0
|
||||
-0.33986575323528 -0.53331120777067 0
|
||||
-0.064647379830725 -0.60235938684263 0
|
||||
0.091924539036435 -0.25440885597942 0
|
||||
0.40469418107844 -0.47549896605132 0
|
||||
0.59442400974309 -0.23815570080881 0
|
||||
0.83567929699787 0.25605757828544 0
|
||||
0.73491944894413 -0.013500778246483 0
|
||||
1.077255 0.2377645 0
|
||||
0.88696375569985 0.49133008726061 0
|
||||
1.231765 0.713293 0
|
||||
1.0590195 0.951057 0
|
||||
0.72725653289275 0.73104100472096 0
|
||||
0.50225974659165 0.6904536152084 0
|
||||
0.559018 0.951057 0
|
||||
0.23657516510421 0.69857072686934 0
|
||||
0.011561493903121 0.87524541641085 0
|
||||
0.10676275 1.0980035 0
|
||||
-0.17127243181091 0.99863326833074 0
|
||||
-0.29774575 1.391895 0
|
||||
-0.577254 1.301075 0
|
||||
-0.45323351407757 0.93490604288187 0
|
||||
-0.55200861955087 0.66792304985565 0
|
||||
-0.7317625 0.8255475 0
|
||||
-0.58327877079184 0.4240660861124 0
|
||||
-0.81465656906104 0.28713104760848 0
|
||||
-1.0112685 0.440839 0
|
||||
-0.99771272279525 0.1592736885552 0
|
||||
-1.415775 0.1469465 0
|
||||
-1.415775 -0.146946 0
|
||||
-1.0166887889241 -0.16866723370018 0
|
||||
-0.80412516287867 -0.29582734656 0
|
||||
-1.0112685 -0.4408385 0
|
||||
-0.6073309356422 -0.45826153759998 0
|
||||
-0.55501395481483 -0.68914767547246 0
|
||||
-0.7317625 -0.8255475 0
|
||||
-0.45240617124569 -0.93833106759189 0
|
||||
-0.577254 -1.301075 0
|
||||
-0.29774575 -1.391895 0
|
||||
-0.1923419715726 -1.0285844005569 0
|
||||
0.031614306262131 -0.83601077226744 0
|
||||
0.10676275 -1.0980035 0
|
||||
0.22112358843745 -0.69009711121629 0
|
||||
0.50046759811715 -0.72837571286759 0
|
||||
0.559018 -0.951057 0
|
||||
0.71074483315985 -0.70826931724532 0
|
||||
1.0590195 -0.951057 0
|
||||
1.231765 -0.713293 0
|
||||
0.89135027612826 -0.46226040977064 0
|
||||
0.84948897506491 -0.23986695857234 0
|
||||
1.077255 -0.2377645 0
|
||||
0.31586449185434 0.2462788698702 0
|
||||
-0.13788918217579 0.40149150514309 0
|
||||
-0.40416548945856 0.0027692745957735 0
|
||||
-0.14861804521337 -0.3698676302047 0
|
||||
0.33007376541085 -0.24598293851351 0
|
||||
0.99473757603443 0.69214841080247 0
|
||||
-0.38122249894249 1.1629329119286 0
|
||||
-1.208195003484 -0.0026998371675556 0
|
||||
-0.35890854853443 -1.1361244276705 0
|
||||
0.9901912195942 -0.73640851058427 0
|
||||
CELLS 30 240
|
||||
9 0 11 26 14 31 32 33 34 91
|
||||
9 0 14 27 17 34 35 36 37 92
|
||||
9 0 17 28 20 37 38 39 40 93
|
||||
9 0 20 29 23 40 41 42 43 94
|
||||
9 0 23 30 11 43 44 45 31 95
|
||||
6 1 26 11 46 32 47
|
||||
6 26 1 12 46 48 49
|
||||
9 26 12 3 13 49 50 51 52 96
|
||||
6 2 26 13 53 52 54
|
||||
6 26 2 14 53 55 33
|
||||
6 2 27 14 56 35 55
|
||||
6 27 2 15 56 57 58
|
||||
9 27 15 5 16 58 59 60 61 97
|
||||
6 4 27 16 62 61 63
|
||||
6 27 4 17 62 64 36
|
||||
6 4 28 17 65 38 64
|
||||
6 28 4 18 65 66 67
|
||||
9 28 18 7 19 67 68 69 70 98
|
||||
6 6 28 19 71 70 72
|
||||
6 28 6 20 71 73 39
|
||||
6 6 29 20 74 41 73
|
||||
6 29 6 21 74 75 76
|
||||
9 29 21 9 22 76 77 78 79 99
|
||||
6 8 29 22 80 79 81
|
||||
6 29 8 23 80 82 42
|
||||
6 8 30 23 83 44 82
|
||||
6 30 8 24 83 84 85
|
||||
9 30 24 10 25 85 86 87 88 100
|
||||
6 1 30 25 89 88 90
|
||||
6 30 1 11 89 47 45
|
||||
CELL_TYPES 30
|
||||
28
|
||||
28
|
||||
28
|
||||
28
|
||||
28
|
||||
22
|
||||
22
|
||||
28
|
||||
22
|
||||
22
|
||||
22
|
||||
22
|
||||
28
|
||||
22
|
||||
22
|
||||
22
|
||||
22
|
||||
28
|
||||
22
|
||||
22
|
||||
22
|
||||
22
|
||||
28
|
||||
22
|
||||
22
|
||||
22
|
||||
22
|
||||
28
|
||||
22
|
||||
22
|
||||
CELL_DATA 30
|
||||
SCALARS material int
|
||||
LOOKUP_TABLE default
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
@@ -1,107 +0,0 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
30
|
||||
1 3 0 11 26 14
|
||||
1 3 0 14 27 17
|
||||
1 3 0 17 28 20
|
||||
1 3 0 20 29 23
|
||||
1 3 0 23 30 11
|
||||
1 2 11 1 26
|
||||
1 2 1 12 26
|
||||
1 3 26 12 3 13
|
||||
1 2 26 13 2
|
||||
1 2 14 26 2
|
||||
1 2 14 2 27
|
||||
1 2 2 15 27
|
||||
1 3 27 15 5 16
|
||||
1 2 27 16 4
|
||||
1 2 17 27 4
|
||||
1 2 17 4 28
|
||||
1 2 4 18 28
|
||||
1 3 28 18 7 19
|
||||
1 2 28 19 6
|
||||
1 2 20 28 6
|
||||
1 2 20 6 29
|
||||
1 2 6 21 29
|
||||
1 3 29 21 9 22
|
||||
1 2 29 22 8
|
||||
1 2 23 29 8
|
||||
1 2 23 8 30
|
||||
1 2 8 24 30
|
||||
1 3 30 24 10 25
|
||||
1 2 30 25 1
|
||||
1 2 11 30 1
|
||||
|
||||
boundary
|
||||
20
|
||||
1 1 13 2
|
||||
1 1 12 3
|
||||
1 1 16 4
|
||||
1 1 15 5
|
||||
1 1 19 6
|
||||
1 1 18 7
|
||||
1 1 22 8
|
||||
1 1 21 9
|
||||
1 1 25 1
|
||||
1 1 24 10
|
||||
1 1 3 13
|
||||
1 1 1 12
|
||||
1 1 5 16
|
||||
1 1 2 15
|
||||
1 1 7 19
|
||||
1 1 4 18
|
||||
1 1 9 22
|
||||
1 1 6 21
|
||||
1 1 10 25
|
||||
1 1 8 24
|
||||
|
||||
vertices
|
||||
31
|
||||
2
|
||||
0 0
|
||||
1 0
|
||||
0.309017 0.951057
|
||||
1.30902 0.951057
|
||||
-0.809017 0.587785
|
||||
-0.5 1.53884
|
||||
-0.809017 -0.587785
|
||||
-1.61803 0
|
||||
0.309017 -0.951057
|
||||
-0.5 -1.53884
|
||||
1.30902 -0.951057
|
||||
0.5 0
|
||||
1.15451 0.475529
|
||||
0.809019 0.951057
|
||||
0.154508 0.475529
|
||||
-0.0954915 1.24495
|
||||
-0.654508 1.06331
|
||||
-0.404508 0.293893
|
||||
-1.21352 0.293893
|
||||
-1.21352 -0.293892
|
||||
-0.404508 -0.293893
|
||||
-0.654508 -1.06331
|
||||
-0.0954915 -1.24495
|
||||
0.154508 -0.475529
|
||||
0.809019 -0.951057
|
||||
1.15451 -0.475529
|
||||
0.654509 0.475529
|
||||
-0.25 0.769421
|
||||
-0.809016 0
|
||||
-0.25 -0.76942
|
||||
0.654509 -0.475529
|
||||
@@ -1,350 +0,0 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
elements
|
||||
6
|
||||
1 5 0 1 2 3 4 5 6 7
|
||||
1 5 4 5 6 7 8 9 10 11
|
||||
1 5 8 9 10 11 12 13 14 15
|
||||
1 5 12 13 14 15 16 17 18 19
|
||||
1 5 16 17 18 19 20 21 22 23
|
||||
1 5 20 21 22 23 3 0 1 2
|
||||
|
||||
boundary
|
||||
24
|
||||
1 3 0 1 5 4
|
||||
1 3 1 2 6 5
|
||||
1 3 2 3 7 6
|
||||
1 3 3 0 4 7
|
||||
1 3 4 5 9 8
|
||||
1 3 5 6 10 9
|
||||
1 3 6 7 11 10
|
||||
1 3 7 4 8 11
|
||||
1 3 8 9 13 12
|
||||
1 3 9 10 14 13
|
||||
1 3 10 11 15 14
|
||||
1 3 11 8 12 15
|
||||
1 3 12 13 17 16
|
||||
1 3 13 14 18 17
|
||||
1 3 14 15 19 18
|
||||
1 3 15 12 16 19
|
||||
1 3 16 17 21 20
|
||||
1 3 17 18 22 21
|
||||
1 3 18 19 23 22
|
||||
1 3 19 16 20 23
|
||||
1 3 20 21 0 3
|
||||
1 3 21 22 1 0
|
||||
1 3 22 23 2 1
|
||||
1 3 23 20 3 2
|
||||
|
||||
vertices
|
||||
24
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: H1_3D_P3
|
||||
VDim: 3
|
||||
Ordering: 1
|
||||
|
||||
0.71715729 -1.7565288e-16 -0.28284271
|
||||
0.71715729 -1.7565288e-16 0.28284271
|
||||
1.2828427 -3.1420584e-16 0.28284271
|
||||
1.2828427 -3.1420584e-16 -0.28284271
|
||||
0.3 0.51961524 -2.7755576e-17
|
||||
0.5 0.8660254 0.4
|
||||
0.7 1.2124356 2.7755576e-17
|
||||
0.5 0.8660254 -0.4
|
||||
-0.35857864 0.62107643 0.28284271
|
||||
-0.64142136 1.1109744 0.28284271
|
||||
-0.64142136 1.1109744 -0.28284271
|
||||
-0.35857864 0.62107643 -0.28284271
|
||||
-1 1.2246468e-16 0.4
|
||||
-1.4 1.7145055e-16 2.7755576e-17
|
||||
-1 1.2246468e-16 -0.4
|
||||
-0.6 7.3478808e-17 -2.7755576e-17
|
||||
-0.64142136 -1.1109744 0.28284271
|
||||
-0.64142136 -1.1109744 -0.28284271
|
||||
-0.35857864 -0.62107643 -0.28284271
|
||||
-0.35857864 -0.62107643 0.28284271
|
||||
0.7 -1.2124356 8.3266727e-17
|
||||
0.5 -0.8660254 -0.4
|
||||
0.3 -0.51961524 -8.3266727e-17
|
||||
0.5 -0.8660254 0.4
|
||||
0.71715729 -1.7565288e-16 -0.12649111
|
||||
0.71715729 -1.7565288e-16 0.12649111
|
||||
0.87350889 -2.1394797e-16 0.28284271
|
||||
1.1264911 -2.7591075e-16 0.28284271
|
||||
1.2828427 -3.1420584e-16 0.12649111
|
||||
1.2828427 -3.1420584e-16 -0.12649111
|
||||
0.87350889 -2.1394797e-16 -0.28284271
|
||||
1.1264911 -2.7591075e-16 -0.28284271
|
||||
0.35527864 0.61536066 0.11055728
|
||||
0.44472136 0.77027999 0.28944272
|
||||
0.55527864 0.96177082 0.28944272
|
||||
0.64472136 1.1166902 0.11055728
|
||||
0.64472136 1.1166902 -0.11055728
|
||||
0.55527864 0.96177082 -0.28944272
|
||||
0.35527864 0.61536066 -0.11055728
|
||||
0.44472136 0.77027999 -0.28944272
|
||||
0.63530452 0.18919442 -0.21528657
|
||||
0.44264573 0.41882944 -0.086151128
|
||||
0.75207276 0.22396814 0.33712267
|
||||
0.66379961 0.62808427 0.39061232
|
||||
1.2815042 0.38163342 0.21528657
|
||||
1.01011 0.95576166 0.086151128
|
||||
1.1647359 0.3468597 -0.33712267
|
||||
0.78895615 0.74650684 -0.39061232
|
||||
-0.43675445 0.75648089 0.28284271
|
||||
-0.56324555 0.97556992 0.28284271
|
||||
-0.64142136 1.1109744 0.12649111
|
||||
-0.64142136 1.1109744 -0.12649111
|
||||
-0.56324555 0.97556992 -0.28284271
|
||||
-0.43675445 0.75648089 -0.28284271
|
||||
-0.35857864 0.62107643 0.12649111
|
||||
-0.35857864 0.62107643 -0.12649111
|
||||
0.14139407 0.59275717 0.086151128
|
||||
-0.15380509 0.64478706 0.21528657
|
||||
0.25201581 1.0565095 0.39061232
|
||||
-0.28197865 1.1821208 0.33712267
|
||||
0.32265887 1.3526618 -0.086151128
|
||||
-0.31024785 1.3006319 -0.21528657
|
||||
0.21203713 0.88890945 -0.39061232
|
||||
-0.18207429 0.76329818 -0.33712267
|
||||
-1.1105573 1.3600404e-16 0.28944272
|
||||
-1.2894427 1.5791119e-16 0.11055728
|
||||
-1.2894427 1.5791119e-16 -0.11055728
|
||||
-1.1105573 1.3600404e-16 -0.28944272
|
||||
-0.88944272 1.0892532e-16 -0.28944272
|
||||
-0.71055728 8.701817e-17 -0.11055728
|
||||
-0.88944272 1.0892532e-16 0.28944272
|
||||
-0.71055728 8.701817e-17 0.11055728
|
||||
-0.56999848 0.53933005 0.33712267
|
||||
-0.87583673 0.26082519 0.39061232
|
||||
-0.97125633 0.91899846 0.21528657
|
||||
-1.3327689 0.39690011 0.086151128
|
||||
-0.88275728 0.83526106 -0.33712267
|
||||
-1.040972 0.31000265 -0.39061232
|
||||
-0.48149943 0.45559264 -0.21528657
|
||||
-0.5840398 0.17392773 -0.086151128
|
||||
-0.64142136 -1.1109744 0.12649111
|
||||
-0.64142136 -1.1109744 -0.12649111
|
||||
-0.56324555 -0.97556992 -0.28284271
|
||||
-0.43675445 -0.75648089 -0.28284271
|
||||
-0.35857864 -0.62107643 -0.12649111
|
||||
-0.35857864 -0.62107643 0.12649111
|
||||
-0.56324555 -0.97556992 0.28284271
|
||||
-0.43675445 -0.75648089 0.28284271
|
||||
-1.040972 -0.31000265 0.39061232
|
||||
-0.88275728 -0.83526106 0.33712267
|
||||
-1.3327689 -0.39690011 -0.086151128
|
||||
-0.97125633 -0.91899846 -0.21528657
|
||||
-0.87583673 -0.26082519 -0.39061232
|
||||
-0.56999848 -0.53933005 -0.33712267
|
||||
-0.5840398 -0.17392773 0.086151128
|
||||
-0.48149943 -0.45559264 0.21528657
|
||||
0.64472136 -1.1166902 -0.11055728
|
||||
0.55527864 -0.96177082 -0.28944272
|
||||
0.44472136 -0.77027999 -0.28944272
|
||||
0.35527864 -0.61536066 -0.11055728
|
||||
0.35527864 -0.61536066 0.11055728
|
||||
0.44472136 -0.77027999 0.28944272
|
||||
0.64472136 -1.1166902 0.11055728
|
||||
0.55527864 -0.96177082 0.28944272
|
||||
-0.31024785 -1.3006319 0.21528657
|
||||
0.32265887 -1.3526618 0.086151128
|
||||
-0.28197865 -1.1821208 -0.33712267
|
||||
0.25201581 -1.0565095 -0.39061232
|
||||
-0.15380509 -0.64478706 -0.21528657
|
||||
0.14139407 -0.59275717 -0.086151128
|
||||
-0.18207429 -0.76329818 0.33712267
|
||||
0.21203713 -0.88890945 0.39061232
|
||||
1.2815042 -0.38163342 -0.21528657
|
||||
1.01011 -0.95576166 -0.086151128
|
||||
0.75207276 -0.22396814 -0.33712267
|
||||
0.66379961 -0.62808427 -0.39061232
|
||||
0.63530452 -0.18919442 0.21528657
|
||||
0.44264573 -0.41882944 0.086151128
|
||||
1.1647359 -0.3468597 0.33712267
|
||||
0.78895615 -0.74650684 0.39061232
|
||||
1.1264911 -2.7591075e-16 -0.12649111
|
||||
1.1264911 -2.7591075e-16 0.12649111
|
||||
0.87350889 -2.1394797e-16 -0.12649111
|
||||
0.87350889 -9.8977972e-16 0.12649111
|
||||
0.66757847 0.19880564 -0.062604414
|
||||
0.71979881 0.21435692 0.18444051
|
||||
0.50377116 0.47666605 0.045623048
|
||||
0.60267418 0.57024766 0.25883814
|
||||
0.89840401 0.26754575 0.303448
|
||||
1.1351729 0.33805581 0.24896124
|
||||
0.75951745 0.71865207 0.30646131
|
||||
0.91439218 0.86519386 0.17030213
|
||||
1.2492302 0.3720222 0.062604414
|
||||
1.1970099 0.35647092 -0.18444051
|
||||
0.9489846 0.89792505 -0.045623048
|
||||
0.85008158 0.80434345 -0.25883814
|
||||
1.0184047 0.30328209 -0.303448
|
||||
0.78163576 0.23277203 -0.24896124
|
||||
0.69323831 0.65593903 -0.30646131
|
||||
0.53836358 0.50939725 -0.17030213
|
||||
0.41055728 0.71110607 -1.3877788e-17
|
||||
0.5 0.8660254 0.17888544
|
||||
0.5 0.8660254 -0.17888544
|
||||
0.58944272 1.0209447 1.3877788e-17
|
||||
0.17196917 0.72093516 0.17030213
|
||||
0.22144071 0.9283315 0.30646131
|
||||
-0.18923139 0.79330244 0.24896124
|
||||
-0.24655235 1.0336054 0.303448
|
||||
0.27154107 1.138364 0.25883814
|
||||
0.30313361 1.2708073 0.045623048
|
||||
-0.28979207 1.2148764 0.18444051
|
||||
-0.30243444 1.2678762 -0.062604414
|
||||
0.29208377 1.2244838 -0.17030213
|
||||
0.24261222 1.0170874 -0.30646131
|
||||
-0.27482155 1.1521165 -0.24896124
|
||||
-0.21750059 0.91181357 -0.303448
|
||||
0.19251187 0.80705498 -0.25883814
|
||||
0.16091933 0.67461165 -0.045623048
|
||||
-0.17426087 0.73054252 -0.18444051
|
||||
-0.1616185 0.67754273 0.062604414
|
||||
-0.43675445 0.75648089 0.12649111
|
||||
-0.56324555 0.97556992 0.12649111
|
||||
-0.43675445 0.75648089 -0.12649111
|
||||
-0.56324555 0.97556992 -0.12649111
|
||||
-0.68090342 0.64426782 0.303448
|
||||
-0.86035138 0.81406069 0.24896124
|
||||
-1.0021297 0.29843537 0.30646131
|
||||
-1.2064759 0.35928993 0.17030213
|
||||
-0.94679579 0.89585401 0.062604414
|
||||
-0.90721782 0.85840551 -0.18444051
|
||||
-1.2521182 0.37288224 -0.045623048
|
||||
-1.1216227 0.33402052 -0.25883814
|
||||
-0.77185234 0.73032329 -0.303448
|
||||
-0.59240437 0.56053041 -0.24896124
|
||||
-0.91467902 0.27239247 -0.30646131
|
||||
-0.71033275 0.21153791 -0.17030213
|
||||
-0.50595997 0.47873709 -0.062604414
|
||||
-0.54553794 0.5161856 0.18444051
|
||||
-0.66469049 0.19794559 0.045623048
|
||||
-0.79518604 0.23680732 0.25883814
|
||||
-1 1.2246468e-16 0.17888544
|
||||
-1.1788854 1.4437183e-16 1.3877788e-17
|
||||
-0.82111456 1.0055753e-16 -1.3877788e-17
|
||||
-1 5.6655389e-16 -0.17888544
|
||||
-1.1216227 -0.33402052 0.25883814
|
||||
-1.2521182 -0.37288224 0.045623048
|
||||
-0.90721782 -0.85840551 0.18444051
|
||||
-0.94679579 -0.89585401 -0.062604414
|
||||
-1.2064759 -0.35928993 -0.17030213
|
||||
-1.0021297 -0.29843537 -0.30646131
|
||||
-0.86035138 -0.81406069 -0.24896124
|
||||
-0.68090342 -0.64426782 -0.303448
|
||||
-0.79518604 -0.23680732 -0.25883814
|
||||
-0.66469049 -0.19794559 -0.045623048
|
||||
-0.54553794 -0.5161856 -0.18444051
|
||||
-0.50595997 -0.47873709 0.062604414
|
||||
-0.71033275 -0.21153791 0.17030213
|
||||
-0.91467902 -0.27239247 0.30646131
|
||||
-0.59240437 -0.56053041 0.24896124
|
||||
-0.77185234 -0.73032329 0.303448
|
||||
-0.56324555 -0.97556992 0.12649111
|
||||
-0.56324555 -0.97556992 -0.12649111
|
||||
-0.43675445 -0.75648089 0.12649111
|
||||
-0.43675445 -0.75648089 -0.12649111
|
||||
-0.30243444 -1.2678762 0.062604414
|
||||
-0.28979207 -1.2148764 -0.18444051
|
||||
0.30313361 -1.2708073 -0.045623048
|
||||
0.27154107 -1.138364 -0.25883814
|
||||
-0.24655235 -1.0336054 -0.303448
|
||||
-0.18923139 -0.79330244 -0.24896124
|
||||
0.22144071 -0.9283315 -0.30646131
|
||||
0.17196917 -0.72093516 -0.17030213
|
||||
-0.1616185 -0.67754273 -0.062604414
|
||||
-0.17426087 -0.73054252 0.18444051
|
||||
0.16091933 -0.67461165 0.045623048
|
||||
0.19251187 -0.80705498 0.25883814
|
||||
-0.21750059 -0.91181357 0.303448
|
||||
-0.27482155 -1.1521165 0.24896124
|
||||
0.24261222 -1.0170874 0.30646131
|
||||
0.29208377 -1.2244838 0.17030213
|
||||
0.58944272 -1.0209447 2.7755576e-17
|
||||
0.5 -0.8660254 -0.17888544
|
||||
0.5 -0.8660254 0.17888544
|
||||
0.41055728 -0.71110607 -2.7755576e-17
|
||||
0.91439218 -0.86519386 -0.17030213
|
||||
0.75951745 -0.71865207 -0.30646131
|
||||
1.1351729 -0.33805581 -0.24896124
|
||||
0.89840401 -0.26754575 -0.303448
|
||||
0.60267418 -0.57024766 -0.25883814
|
||||
0.50377116 -0.47666605 -0.045623048
|
||||
0.71979881 -0.21435692 -0.18444051
|
||||
0.66757847 -0.19880564 0.062604414
|
||||
0.53836358 -0.50939725 0.17030213
|
||||
0.69323831 -0.65593903 0.30646131
|
||||
0.78163576 -0.23277203 0.24896124
|
||||
1.0184047 -0.30328209 0.303448
|
||||
0.85008158 -0.80434345 0.25883814
|
||||
0.9489846 -0.89792505 0.045623048
|
||||
1.1970099 -0.35647092 0.18444051
|
||||
1.2492302 -0.3720222 -0.062604414
|
||||
0.81390971 0.24238325 -0.096279082
|
||||
0.86613006 0.25793453 0.15076584
|
||||
1.0506786 0.31289331 -0.15076584
|
||||
1.102899 0.32844459 0.096279082
|
||||
0.59948901 0.56723386 -0.038527956
|
||||
0.69839202 0.66081546 0.17468714
|
||||
0.75436373 0.71377565 -0.17468714
|
||||
0.85326675 0.80735725 0.038527956
|
||||
0.19149443 0.80278964 0.038527956
|
||||
0.24096597 1.010186 0.17468714
|
||||
0.22308696 0.93523296 -0.17468714
|
||||
0.27255851 1.1426293 -0.038527956
|
||||
-0.1970448 0.82605811 0.096279082
|
||||
-0.25436576 1.066361 0.15076584
|
||||
-0.20968717 0.8790579 -0.15076584
|
||||
-0.26700813 1.1193608 -0.096279082
|
||||
-0.65644288 0.62112337 0.15076584
|
||||
-0.83589085 0.79091624 0.096279082
|
||||
-0.61686491 0.58367486 -0.096279082
|
||||
-0.79631287 0.75346774 -0.15076584
|
||||
-0.92147899 0.2744175 0.17468714
|
||||
-1.1258253 0.33527206 0.038527956
|
||||
-0.79098343 0.23555578 -0.038527956
|
||||
-0.99532971 0.29641033 -0.17468714
|
||||
-0.99532971 -0.29641033 0.17468714
|
||||
-1.1258253 -0.33527206 -0.038527956
|
||||
-0.79098343 -0.23555578 0.038527956
|
||||
-0.92147899 -0.2744175 -0.17468714
|
||||
-0.79631287 -0.75346774 0.15076584
|
||||
-0.83589085 -0.79091624 -0.096279082
|
||||
-0.61686491 -0.58367486 0.096279082
|
||||
-0.65644288 -0.62112337 -0.15076584
|
||||
-0.26700813 -1.1193608 0.096279082
|
||||
-0.25436576 -1.066361 -0.15076584
|
||||
-0.20968717 -0.8790579 0.15076584
|
||||
-0.1970448 -0.82605811 -0.096279082
|
||||
0.27255851 -1.1426293 0.038527956
|
||||
0.24096597 -1.010186 -0.17468714
|
||||
0.22308696 -0.93523296 0.17468714
|
||||
0.19149443 -0.80278964 -0.038527956
|
||||
0.85326675 -0.80735725 -0.038527956
|
||||
0.69839202 -0.66081546 -0.17468714
|
||||
0.75436373 -0.71377565 0.17468714
|
||||
0.59948901 -0.56723386 0.038527956
|
||||
1.102899 -0.32844459 -0.096279082
|
||||
0.86613006 -0.25793453 -0.15076584
|
||||
1.0506786 -0.31289331 0.15076584
|
||||
0.81390971 -0.24238325 0.096279082
|
||||
@@ -1,236 +0,0 @@
|
||||
MFEM mesh v1.0
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
3
|
||||
|
||||
elements
|
||||
6
|
||||
1 6 0 1 2 3 4 5
|
||||
1 6 3 4 5 6 7 8
|
||||
1 6 6 7 8 9 10 11
|
||||
1 6 9 10 11 12 13 14
|
||||
1 6 12 13 14 15 16 17
|
||||
1 6 15 16 17 0 1 2
|
||||
|
||||
boundary
|
||||
18
|
||||
1 3 0 1 4 3
|
||||
1 3 1 2 5 4
|
||||
1 3 2 0 3 5
|
||||
1 3 3 4 7 6
|
||||
1 3 4 5 8 7
|
||||
1 3 5 3 6 8
|
||||
1 3 6 7 10 9
|
||||
1 3 7 8 11 10
|
||||
1 3 8 6 9 11
|
||||
1 3 9 10 13 12
|
||||
1 3 10 11 14 13
|
||||
1 3 11 9 12 14
|
||||
1 3 12 13 16 15
|
||||
1 3 13 14 17 16
|
||||
1 3 14 12 15 17
|
||||
1 3 15 16 1 0
|
||||
1 3 16 17 2 1
|
||||
1 3 17 15 0 2
|
||||
|
||||
vertices
|
||||
18
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: H1_3D_P3
|
||||
VDim: 3
|
||||
Ordering: 1
|
||||
|
||||
0.6 -1.4695762e-16 -9.7971744e-17
|
||||
1.2 -2.9391523e-16 0.34641016
|
||||
1.2 -1.3597293e-15 -0.34641016
|
||||
0.4 0.69282032 0.34641016
|
||||
0.7 1.2124356 2.7755576e-17
|
||||
0.4 0.69282032 -0.34641016
|
||||
-0.6 1.0392305 0.34641016
|
||||
-0.6 1.0392305 -0.34641016
|
||||
-0.3 0.51961524 -3.8651415e-16
|
||||
-1.4 1.7145055e-16 4.8985872e-17
|
||||
-0.8 9.7971744e-17 -0.34641016
|
||||
-0.8 4.5324311e-16 0.34641016
|
||||
-0.6 -1.0392305 -0.34641016
|
||||
-0.3 -0.51961524 -2.220446e-16
|
||||
-0.6 -1.0392305 0.34641016
|
||||
0.4 -0.69282032 -0.34641016
|
||||
0.4 -0.69282032 0.34641016
|
||||
0.7 -1.2124356 7.7509221e-16
|
||||
0.76583592 -8.6777464e-16 0.095745414
|
||||
1.0341641 2.5022695e-15 0.25066475
|
||||
1.2 -1.3597293e-15 0.15491933
|
||||
1.2 -2.9391523e-16 -0.15491933
|
||||
0.76583592 4.9262324e-16 -0.095745414
|
||||
1.0341641 3.4207917e-15 -0.25066475
|
||||
0.48291796 0.83643844 0.25066475
|
||||
0.61708204 1.0688174 0.095745414
|
||||
0.61708204 1.0688174 -0.095745414
|
||||
0.48291796 0.83643844 -0.25066475
|
||||
0.4 0.69282032 0.15491933
|
||||
0.4 0.69282032 -0.15491933
|
||||
0.59098879 0.17599714 0.11416557
|
||||
0.51532795 0.48760104 0.27491822
|
||||
1.2368698 0.36834126 0.27491822
|
||||
1.0048434 0.95077837 0.11416557
|
||||
1.0473544 0.31190335 -0.38908379
|
||||
0.65896232 0.62350725 -0.38908379
|
||||
-0.6 1.0392305 0.15491933
|
||||
-0.6 1.0392305 -0.15491933
|
||||
-0.51708204 0.89561236 -0.25066475
|
||||
-0.38291796 0.66323336 -0.095745414
|
||||
-0.51708204 0.89561236 0.25066475
|
||||
-0.38291796 0.66323336 0.095745414
|
||||
0.21049196 0.88243173 0.38908379
|
||||
-0.25356098 1.0629872 0.38908379
|
||||
0.32097654 1.3456091 -0.11416557
|
||||
-0.29944203 1.2553313 -0.27491822
|
||||
0.16461091 0.69008761 -0.27491822
|
||||
-0.1430764 0.59980988 -0.11416557
|
||||
-1.2341641 6.9922046e-16 -0.095745414
|
||||
-0.96583592 -1.1684711e-15 -0.25066475
|
||||
-0.8 4.5324311e-16 -0.15491933
|
||||
-0.8 9.7971744e-17 0.15491933
|
||||
-1.2341641 -3.9693744e-16 0.095745414
|
||||
-0.96583592 -1.5973885e-15 0.25066475
|
||||
-0.93742781 0.88699007 0.27491822
|
||||
-1.3258199 0.3948307 0.11416557
|
||||
-0.79379344 0.75108386 -0.38908379
|
||||
-0.86945428 0.25892449 -0.38908379
|
||||
-0.44791239 0.42381273 0.11416557
|
||||
-0.67993886 0.20248658 0.27491822
|
||||
-0.51708204 -0.89561236 -0.25066475
|
||||
-0.38291796 -0.66323336 -0.095745414
|
||||
-0.38291796 -0.66323336 0.095745414
|
||||
-0.51708204 -0.89561236 0.25066475
|
||||
-0.6 -1.0392305 -0.15491933
|
||||
-0.6 -1.0392305 0.15491933
|
||||
-1.3258199 -0.3948307 -0.11416557
|
||||
-0.93742781 -0.88699007 -0.27491822
|
||||
-0.67993886 -0.20248658 -0.27491822
|
||||
-0.44791239 -0.42381273 -0.11416557
|
||||
-0.86945428 -0.25892449 0.38908379
|
||||
-0.79379344 -0.75108386 0.38908379
|
||||
0.4 -0.69282032 -0.15491933
|
||||
0.4 -0.69282032 0.15491933
|
||||
0.48291796 -0.83643844 0.25066475
|
||||
0.61708204 -1.0688174 0.095745414
|
||||
0.48291796 -0.83643844 -0.25066475
|
||||
0.61708204 -1.0688174 -0.095745414
|
||||
-0.25356098 -1.0629872 -0.38908379
|
||||
0.21049196 -0.88243173 -0.38908379
|
||||
-0.1430764 -0.59980988 0.11416557
|
||||
0.16461091 -0.69008761 0.27491822
|
||||
-0.29944203 -1.2553313 0.27491822
|
||||
0.32097654 -1.3456091 0.11416557
|
||||
0.59098879 -0.17599714 -0.11416557
|
||||
0.51532795 -0.48760104 -0.27491822
|
||||
1.0473544 -0.31190335 0.38908379
|
||||
0.65896232 -0.62350725 0.38908379
|
||||
1.2368698 -0.36834126 -0.27491822
|
||||
1.0048434 -0.95077837 -0.11416557
|
||||
1 2.4196059e-15 -1.3788671e-16
|
||||
0.5 0.8660254 -8.6542076e-17
|
||||
0.76950592 0.22915975 0.15859651
|
||||
1.0583527 0.31517866 0.23048728
|
||||
0.65062668 0.6156201 0.23048728
|
||||
0.86954463 0.8227593 0.15859651
|
||||
1.1844891 0.35274221 0.091392579
|
||||
1.0997352 0.32750241 -0.20555815
|
||||
0.9092442 0.86032286 -0.024929133
|
||||
0.75456149 0.71396276 -0.24998909
|
||||
0.92121806 0.2743398 -0.24998909
|
||||
0.71712515 0.2135607 -0.024929133
|
||||
0.61926276 0.5859437 -0.20555815
|
||||
0.55502751 0.52516459 0.091392579
|
||||
-0.5 0.8660254 5.1344633e-17
|
||||
0.24102914 1.0104508 0.24998909
|
||||
0.29043935 1.21759 0.024929133
|
||||
-0.26624219 1.1161498 0.20555815
|
||||
-0.28676082 1.2021687 -0.091392579
|
||||
0.27775814 1.1644274 -0.15859651
|
||||
0.20782931 0.87126929 -0.23048728
|
||||
-0.25622363 1.0741497 -0.23048728
|
||||
-0.1862948 0.78099155 -0.15859651
|
||||
0.17729212 0.74325022 -0.091392579
|
||||
0.19781075 0.82926913 0.20555815
|
||||
-0.17361359 0.72782894 0.024929133
|
||||
-0.22302379 0.93496814 0.24998909
|
||||
-1 -1.2098029e-15 1.3788671e-16
|
||||
-0.89772824 0.84942651 0.091392579
|
||||
-0.833493 0.78864741 -0.20555815
|
||||
-1.1996835 0.35726714 -0.024929133
|
||||
-0.99559063 0.29648804 -0.24998909
|
||||
-0.69819427 0.66062834 -0.24998909
|
||||
-0.54351156 0.51426825 -0.024929133
|
||||
-0.8170735 0.24332543 -0.20555815
|
||||
-0.73231963 0.21808563 0.091392579
|
||||
-0.58321113 0.5518318 0.15859651
|
||||
-0.80212907 0.758971 0.23048728
|
||||
-0.85845599 0.25564918 0.23048728
|
||||
-1.1473028 0.34166809 0.15859651
|
||||
-0.5 -0.8660254 8.6542076e-17
|
||||
-1.1473028 -0.34166809 -0.15859651
|
||||
-0.85845599 -0.25564918 -0.23048728
|
||||
-0.80212907 -0.758971 -0.23048728
|
||||
-0.58321113 -0.5518318 -0.15859651
|
||||
-0.73231963 -0.21808563 -0.091392579
|
||||
-0.8170735 -0.24332543 0.20555815
|
||||
-0.54351156 -0.51426825 0.024929133
|
||||
-0.69819427 -0.66062834 0.24998909
|
||||
-0.99559063 -0.29648804 0.24998909
|
||||
-1.1996835 -0.35726714 0.024929133
|
||||
-0.833493 -0.78864741 0.20555815
|
||||
-0.89772824 -0.84942651 -0.091392579
|
||||
0.5 -0.8660254 -5.1344633e-17
|
||||
-0.22302379 -0.93496814 -0.24998909
|
||||
-0.17361359 -0.72782894 -0.024929133
|
||||
0.19781075 -0.82926913 -0.20555815
|
||||
0.17729212 -0.74325022 0.091392579
|
||||
-0.1862948 -0.78099155 0.15859651
|
||||
-0.25622363 -1.0741497 0.23048728
|
||||
0.20782931 -0.87126929 0.23048728
|
||||
0.27775814 -1.1644274 0.15859651
|
||||
-0.28676082 -1.2021687 0.091392579
|
||||
-0.26624219 -1.1161498 -0.20555815
|
||||
0.29043935 -1.21759 -0.024929133
|
||||
0.24102914 -1.0104508 -0.24998909
|
||||
0.55502751 -0.52516459 -0.091392579
|
||||
0.61926276 -0.5859437 0.20555815
|
||||
0.71712515 -0.2135607 0.024929133
|
||||
0.92121806 -0.2743398 0.24998909
|
||||
0.75456149 -0.71396276 0.24998909
|
||||
0.9092442 -0.86032286 0.024929133
|
||||
1.0997352 -0.32750241 0.20555815
|
||||
1.1844891 -0.35274221 -0.091392579
|
||||
0.86954463 -0.8227593 -0.15859651
|
||||
0.65062668 -0.6156201 -0.23048728
|
||||
1.0583527 -0.31517866 -0.23048728
|
||||
0.76950592 -0.22915975 -0.15859651
|
||||
0.95840435 0.28541392 -1.3795119e-16
|
||||
0.72637788 0.68729555 -1.1412456e-16
|
||||
0.23202647 0.97270947 -5.1760042e-17
|
||||
-0.23202647 0.97270947 1.2226691e-17
|
||||
-0.72637788 0.68729555 8.6191148e-17
|
||||
-0.95840435 0.28541392 1.2635125e-16
|
||||
-0.95840435 -0.28541392 1.3795119e-16
|
||||
-0.72637788 -0.68729555 1.1412456e-16
|
||||
-0.23202647 -0.97270947 5.1760042e-17
|
||||
0.23202647 -0.97270947 -1.2226691e-17
|
||||
0.72637788 -0.68729555 -8.6191148e-17
|
||||
0.95840435 -0.28541392 -1.2635125e-16
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = "MFEM"
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = v3.4.1
|
||||
PROJECT_NUMBER = v3.3
|
||||
|
||||
# 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
|
||||
@@ -140,7 +140,7 @@ INLINE_INHERITED_MEMB = NO
|
||||
# shortest path that makes the file name unique will be used
|
||||
# The default value is: YES.
|
||||
|
||||
FULL_PATH_NAMES = YES
|
||||
FULL_PATH_NAMES = NO
|
||||
|
||||
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
|
||||
# Stripping is only done if one of the specified strings matches the left-hand
|
||||
@@ -152,7 +152,7 @@ FULL_PATH_NAMES = YES
|
||||
# will be relative from the directory where doxygen is started.
|
||||
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
|
||||
|
||||
STRIP_FROM_PATH = @MFEM_SOURCE_DIR@
|
||||
STRIP_FROM_PATH =
|
||||
|
||||
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
|
||||
# path mentioned in the documentation of a class, which tells the reader which
|
||||
@@ -767,12 +767,10 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
|
||||
@MFEM_SOURCE_DIR@/fem \
|
||||
@MFEM_SOURCE_DIR@/examples \
|
||||
@MFEM_SOURCE_DIR@/examples/petsc \
|
||||
@MFEM_SOURCE_DIR@/examples/pumi \
|
||||
@MFEM_SOURCE_DIR@/examples/sundials \
|
||||
@MFEM_SOURCE_DIR@/miniapps/common \
|
||||
@MFEM_SOURCE_DIR@/miniapps/meshing \
|
||||
@MFEM_SOURCE_DIR@/miniapps/tools \
|
||||
@MFEM_SOURCE_DIR@/miniapps/nurbs \
|
||||
@MFEM_SOURCE_DIR@/miniapps/electromagnetics \
|
||||
@MFEM_SOURCE_DIR@/miniapps/performance
|
||||
|
||||
@@ -810,8 +808,7 @@ RECURSIVE = NO
|
||||
# Note that relative paths are relative to the directory from which doxygen is
|
||||
# run.
|
||||
|
||||
EXCLUDE = @MFEM_SOURCE_DIR@/config/_config.hpp \
|
||||
@MFEM_SOURCE_DIR@/config/get_hypre_version.cpp
|
||||
EXCLUDE =
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||
@@ -1443,7 +1440,7 @@ FORMULA_TRANSPARENT = YES
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
USE_MATHJAX = YES
|
||||
USE_MATHJAX = NO
|
||||
|
||||
# When MathJax is enabled you can set the default output format to be used for
|
||||
# the MathJax output. See the MathJax site (see:
|
||||
@@ -1466,14 +1463,14 @@ MATHJAX_FORMAT = HTML-CSS
|
||||
# The default value is: http://cdn.mathjax.org/mathjax/latest.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_RELPATH = https://cdn.llnl.gov/mathjax/2.7.2
|
||||
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
|
||||
|
||||
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
|
||||
# extension names that should be enabled during MathJax rendering. For example
|
||||
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
|
||||
MATHJAX_EXTENSIONS =
|
||||
|
||||
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
|
||||
# of code that will be used on startup of the MathJax code. See the MathJax site
|
||||
|
||||
@@ -36,8 +36,8 @@ namespace mfem {
|
||||
* - HypreSolver and other \link hypre.hpp hypre classes\endlink
|
||||
*
|
||||
* <H3>Example codes</H3>
|
||||
* - <a class="el" href="examples_2ex1_8cpp_source.html">Example 1</a>: nodal H1 FEM for the Laplace problem
|
||||
* - <a class="el" href="examples_2ex1p_8cpp_source.html">Example 1p</a>: parallel nodal H1 FEM for the Laplace problem
|
||||
* - <a class="el" href="ex1_8cpp_source.html">Example 1</a>: nodal H1 FEM for the Laplace problem
|
||||
* - <a class="el" href="ex1p_8cpp_source.html">Example 1p</a>: parallel nodal H1 FEM for the Laplace problem
|
||||
* - <a class="el" href="ex2_8cpp_source.html">Example 2</a>: vector FEM for linear elasticity
|
||||
* - <a class="el" href="ex2p_8cpp_source.html">Example 2p</a>: parallel vector FEM for linear elasticity
|
||||
* - <a class="el" href="ex3_8cpp_source.html">Example 3</a>: Nedelec H(curl) FEM for the definite Maxwell problem
|
||||
@@ -56,7 +56,7 @@ namespace mfem {
|
||||
* - <a class="el" href="ex9p_8cpp_source.html">Example 9p</a>: parallel Discontinuous Galerkin (DG) time-dependent advection
|
||||
* - <a class="el" href="ex10_8cpp_source.html">Example 10</a>: time-dependent implicit nonlinear elasticity
|
||||
* - <a class="el" href="ex10p_8cpp_source.html">Example 10p</a>: parallel time-dependent implicit nonlinear elasticity
|
||||
* - <a class="el" href="examples_2ex11p_8cpp_source.html">Example 11p</a>: parallel Laplace eigensolver
|
||||
* - <a class="el" href="ex11p_8cpp_source.html">Example 11p</a>: parallel Laplace eigensolver
|
||||
* - <a class="el" href="ex12p_8cpp_source.html">Example 12p</a>: parallel linear elasticity eigensolver
|
||||
* - <a class="el" href="ex13p_8cpp_source.html">Example 13p</a>: parallel Maxwell eigensolver
|
||||
* - <a class="el" href="ex14_8cpp_source.html">Example 14</a>: Discontinuous Galerkin (DG) for the Laplace problem
|
||||
@@ -67,24 +67,14 @@ namespace mfem {
|
||||
* - <a class="el" href="ex16p_8cpp_source.html">Example 16p</a>: parallel time-dependent nonlinear heat equation
|
||||
* - <a class="el" href="ex17_8cpp_source.html">Example 17</a>: Discontinuous Galerkin (DG) for linear elasticity
|
||||
* - <a class="el" href="ex17p_8cpp_source.html">Example 17p</a>: parallel Discontinuous Galerkin (DG) for linear elasticity
|
||||
* - <a class="el" href="ex18_8cpp_source.html">Example 18</a>: Discontinuous Galerkin (DG) for the Euler equations
|
||||
* - <a class="el" href="ex18p_8cpp_source.html">Example 18p</a>: parallel Discontinuous Galerkin (DG) for the Euler equations
|
||||
* - <a class="el" href="ex19_8cpp_source.html">Example 19</a>: incompressible nonlinear elasticity
|
||||
* - <a class="el" href="ex19p_8cpp_source.html">Example 19p</a>: parallel incompressible nonlinear elasticity
|
||||
* - <a class="el" href="ex20_8cpp_source.html">Example 20</a>: symplectic ODE integration
|
||||
* - <a class="el" href="ex20p_8cpp_source.html">Example 20p</a>: parallel symplectic ODE integration
|
||||
* - <a class="el" href="ex22_8cpp_source.html">Example 22</a>: adaptive mesh refinement for linear elasticity
|
||||
* - <a class="el" href="ex22p_8cpp_source.html">Example 22p</a>: parallel adaptive mesh refinement for linear elasticity
|
||||
*
|
||||
* <H4>SUNDIALS Examples</H4>
|
||||
* - Variants of Examples
|
||||
* <a class="el" href="sundials_2ex9_8cpp_source.html">9</a>,
|
||||
* <a class="el" href="sundials_2ex9p_8cpp_source.html">9p</a>,
|
||||
* <a class="el" href="sundials_2ex10_8cpp_source.html">10</a>,
|
||||
* <a class="el" href="sundials_2ex10p_8cpp_source.html">10p</a>,
|
||||
* <a class="el" href="sundials_2ex16_8cpp_source.html">16</a>,
|
||||
* and
|
||||
* <a class="el" href="sundials_2ex16p_8cpp_source.html">16p</a>
|
||||
* <a class="el" class="el" href="sundials_2ex10p_8cpp_source.html">10p</a>
|
||||
* demonstrating the use of MFEM's \link sundials.hpp SUNDIALS classes\endlink
|
||||
*
|
||||
* <H4>PETSc Examples</H4>
|
||||
@@ -100,31 +90,14 @@ namespace mfem {
|
||||
* <a class="el" href="petsc_2ex10p_8cpp_source.html">10p</a>
|
||||
* demonstrating the use of MFEM's \link petsc.hpp PETSc classes\endlink
|
||||
*
|
||||
* <H4>PUMI Examples</H4>
|
||||
* - Variants of Examples
|
||||
* <a class="el" href="examples_2pumi_2ex1_8cpp_source.html">1</a>,
|
||||
* <a class="el" href="examples_2pumi_2ex1p_8cpp_source.html">1p</a>,
|
||||
* <a class="el" href="pumi_2ex2_8cpp_source.html">2</a>,
|
||||
* and
|
||||
* <a class="el" href="pumi_2ex6p_8cpp_source.html">6p</a>
|
||||
* demonstrating the use of MFEM's \link pumi.hpp PUMI classes\endlink
|
||||
*
|
||||
* <H3>Miniapps</H3>
|
||||
* - <a class="el" href="volta_8cpp_source.html">Volta</a>: simple electrostatics simulation code
|
||||
* - <a class="el" href="tesla_8cpp_source.html">Tesla</a>: simple magnetostatics simulation code
|
||||
* - <a class="el" href="maxwell_8cpp_source.html">Maxwell</a>: simple transient full-wave electromagnetics simulation code
|
||||
* - <a class="el" href="joule_8cpp_source.html">Joule</a>: transient magnetics and Joule heating miniapp
|
||||
* - <a class="el" href="mobius-strip_8cpp_source.html">Mobius Strip</a>: generate various Mobius strip-like meshes
|
||||
* - <a class="el" href="klein-bottle_8cpp_source.html">Klein Bottle</a>: generate three types of Klein bottle surfaces
|
||||
* - <a class="el" href="toroid_8cpp_source.html">Toroid</a>: generate simple toroidal meshes
|
||||
* - <a class="el" href="shaper_8cpp_source.html">Shaper</a>: resolve material interfaces by mesh refinement
|
||||
* - <a class="el" href="extruder_8cpp_source.html">Extruder</a>: extrude a low-dimensional mesh into a higher dimension
|
||||
* - <a class="el" href="mesh-explorer_8cpp_source.html">Mesh Explorer</a>: visualize and manipulate meshes
|
||||
* - <a class="el" href="mesh-optimizer_8cpp_source.html">Mesh Optimizer</a>: optimize high-order meshes, <a class="el" href="mesh-optimizer_8cpp_source.html">serial</a> and <a class="el" href="pmesh-optimizer_8cpp_source.html">parallel</a> versions
|
||||
* - <a class="el" href="display-basis_8cpp_source.html">Display Basis</a>: visualize finite element basis functions
|
||||
* - <a class="el" href="load-dc_8cpp_source.html">Load DC</a>: visualize fields saved via DataCollection classes
|
||||
* - <a class="el" href="convert-dc_8cpp_source.html">Convert DC</a>: convert between diffirent DataCollection formats
|
||||
* - <a class="el" href="lor-transfer_8cpp_source.html">LOR Transfer</a>: map functions between high-order and low-order refined spaces
|
||||
* - <a class="el" href="miniapps_2performance_2ex1_8cpp_source.html">HPC Example 1</a>: high-performance nodal H1 FEM for the Laplace problem
|
||||
* - <a class="el" href="miniapps_2performance_2ex1p_8cpp_source.html">HPC Example 1p</a>: high-performance parallel nodal H1 FEM for the Laplace problem
|
||||
*
|
||||
|
||||
@@ -10,17 +10,17 @@
|
||||
# Software Foundation) version 2.1 dated February 1999.
|
||||
|
||||
MFEM_DIR ?= ..
|
||||
DOXYGEN_CONF = CodeDocumentation.conf
|
||||
DOXYGEN_CONG = CodeDocumentation.conf
|
||||
|
||||
# doxygen uses: graphviz, latex
|
||||
html: $(DOXYGEN_CONF)
|
||||
doxygen $(DOXYGEN_CONF)
|
||||
html: $(DOXYGEN_CONG)
|
||||
doxygen $(DOXYGEN_CONG)
|
||||
rm -f CodeDocumentation.html
|
||||
ln -s CodeDocumentation/html/index.html CodeDocumentation.html
|
||||
|
||||
clean:
|
||||
rm -rf $(DOXYGEN_CONF) CodeDocumentation CodeDocumentation.html *~
|
||||
rm -rf $(DOXYGEN_CONG) CodeDocumentation CodeDocumentation.html *~
|
||||
|
||||
$(DOXYGEN_CONF): $(MFEM_DIR)/doc/$(DOXYGEN_CONF).in
|
||||
$(DOXYGEN_CONG): $(MFEM_DIR)/doc/$(DOXYGEN_CONG).in
|
||||
sed -e 's%@MFEM_SOURCE_DIR@%$(MFEM_DIR)%g' $(<) \
|
||||
> $(DOXYGEN_CONF)
|
||||
> $(DOXYGEN_CONG)
|
||||
|
||||
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 118 KiB |
@@ -24,11 +24,6 @@ list(APPEND ALL_EXE_SRCS
|
||||
ex15.cpp
|
||||
ex16.cpp
|
||||
ex17.cpp
|
||||
ex18.cpp
|
||||
ex19.cpp
|
||||
ex20.cpp
|
||||
ex21.cpp
|
||||
ex22.cpp
|
||||
)
|
||||
|
||||
if (MFEM_USE_MPI)
|
||||
@@ -50,16 +45,11 @@ if (MFEM_USE_MPI)
|
||||
ex15p.cpp
|
||||
ex16p.cpp
|
||||
ex17p.cpp
|
||||
ex18p.cpp
|
||||
ex19p.cpp
|
||||
ex20p.cpp
|
||||
ex21p.cpp
|
||||
ex22p.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# Include the source directory where mfem.hpp and mfem-performance.hpp are.
|
||||
include_directories(BEFORE ${PROJECT_BINARY_DIR})
|
||||
include_directories(${PROJECT_BINARY_DIR})
|
||||
|
||||
# Add one executable per cpp file
|
||||
add_mfem_examples(ALL_EXE_SRCS)
|
||||
@@ -69,6 +59,8 @@ foreach(SRC_FILE ${ALL_EXE_SRCS})
|
||||
get_filename_component(SRC_FILENAME ${SRC_FILE} NAME)
|
||||
string(REPLACE ".cpp" "" TEST_NAME ${SRC_FILENAME})
|
||||
|
||||
string(FIND ${TEST_NAME} "p" is_parallel_test)
|
||||
|
||||
set(THIS_TEST_OPTIONS "-no-vis")
|
||||
if (${TEST_NAME} MATCHES "ex10p*")
|
||||
list(APPEND THIS_TEST_OPTIONS "-tf" "5")
|
||||
@@ -76,38 +68,19 @@ foreach(SRC_FILE ${ALL_EXE_SRCS})
|
||||
list(APPEND THIS_TEST_OPTIONS "-e" "1")
|
||||
endif()
|
||||
|
||||
if (NOT (${TEST_NAME} MATCHES ".*p$"))
|
||||
if (is_parallel_test EQUAL -1)
|
||||
add_test(NAME ${TEST_NAME}_ser
|
||||
COMMAND ${TEST_NAME} ${THIS_TEST_OPTIONS})
|
||||
else()
|
||||
add_test(NAME ${TEST_NAME}_np=4
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MFEM_MPI_NP}
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 4
|
||||
${MPIEXEC_PREFLAGS}
|
||||
$<TARGET_FILE:${TEST_NAME}> ${THIS_TEST_OPTIONS}
|
||||
${MPIEXEC_POSTFLAGS})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# If STRUMPACK is enabled, add a test run that uses it.
|
||||
if (MFEM_USE_STRUMPACK)
|
||||
add_test(NAME ex11p_strumpack_np=4
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MFEM_MPI_NP}
|
||||
${MPIEXEC_PREFLAGS}
|
||||
$<TARGET_FILE:ex11p> "-no-vis" "--strumpack"
|
||||
${MPIEXEC_POSTFLAGS})
|
||||
endif()
|
||||
|
||||
# Include the examples/sundials directory if SUNDIALS is enabled.
|
||||
if (MFEM_USE_SUNDIALS)
|
||||
add_subdirectory(sundials)
|
||||
endif()
|
||||
|
||||
# Include the examples/petsc directory if PETSc is enabled.
|
||||
if (MFEM_USE_PETSC)
|
||||
add_subdirectory(petsc)
|
||||
endif()
|
||||
|
||||
# Include the examples/pumi directory if PUMI is enabled
|
||||
if (MFEM_USE_PUMI)
|
||||
add_subdirectory(pumi)
|
||||
endif()
|
||||
# Include the examples/sundials directory.
|
||||
add_subdirectory(sundials)
|
||||
# Include the examples/petsc directory.
|
||||
add_subdirectory(petsc)
|
||||
|
||||
@@ -4,18 +4,13 @@
|
||||
//
|
||||
// Sample runs: ex1 -m ../data/square-disc.mesh
|
||||
// ex1 -m ../data/star.mesh
|
||||
// ex1 -m ../data/star-mixed.mesh
|
||||
// ex1 -m ../data/escher.mesh
|
||||
// ex1 -m ../data/fichera.mesh
|
||||
// ex1 -m ../data/fichera-mixed.mesh
|
||||
// ex1 -m ../data/toroid-wedge.mesh
|
||||
// ex1 -m ../data/square-disc-p2.vtk -o 2
|
||||
// ex1 -m ../data/square-disc-p3.mesh -o 3
|
||||
// ex1 -m ../data/square-disc-nurbs.mesh -o -1
|
||||
// ex1 -m ../data/star-mixed-p2.mesh -o 2
|
||||
// ex1 -m ../data/disc-nurbs.mesh -o -1
|
||||
// ex1 -m ../data/pipe-nurbs.mesh -o -1
|
||||
// ex1 -m ../data/fichera-mixed-p2.mesh -o 2
|
||||
// ex1 -m ../data/star-surf.mesh
|
||||
// ex1 -m ../data/square-disc-surf.mesh
|
||||
// ex1 -m ../data/inline-segment.mesh
|
||||
@@ -25,14 +20,6 @@
|
||||
// ex1 -m ../data/mobius-strip.mesh
|
||||
// ex1 -m ../data/mobius-strip.mesh -o -1 -sc
|
||||
//
|
||||
// Device sample runs:
|
||||
// > ex1 -pa -d cuda
|
||||
// > ex1 -pa -d raja-cuda
|
||||
// > ex1 -pa -d occa-cuda
|
||||
// > ex1 -pa -d raja-omp
|
||||
// > ex1 -pa -d occa-omp
|
||||
// > ex1 -m ../data/beam-hex.mesh -pa -d cuda
|
||||
//
|
||||
// Description: This example code demonstrates the use of MFEM to define a
|
||||
// simple finite element discretization of the Laplace problem
|
||||
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
|
||||
@@ -61,9 +48,7 @@ int main(int argc, char *argv[])
|
||||
const char *mesh_file = "../data/star.mesh";
|
||||
int order = 1;
|
||||
bool static_cond = false;
|
||||
bool pa = false;
|
||||
const char *device = "cpu";
|
||||
bool visualization = true;
|
||||
bool visualization = 1;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
@@ -73,10 +58,6 @@ int main(int argc, char *argv[])
|
||||
" isoparametric space.");
|
||||
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
|
||||
"--no-static-condensation", "Enable static condensation.");
|
||||
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
|
||||
"--no-partial-assembly", "Enable Partial Assembly.");
|
||||
args.AddOption(&device, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -148,65 +129,48 @@ int main(int argc, char *argv[])
|
||||
b->AddDomainIntegrator(new DomainLFIntegrator(one));
|
||||
b->Assemble();
|
||||
|
||||
// 7. Set device config parameters from the command line options and switch
|
||||
// to working on the device.
|
||||
Device::Configure(device);
|
||||
Device::Print();
|
||||
Device::Enable();
|
||||
|
||||
// 8. Define the solution vector x as a finite element grid function
|
||||
// 7. Define the solution vector x as a finite element grid function
|
||||
// corresponding to fespace. Initialize x with initial guess of zero,
|
||||
// which satisfies the boundary conditions.
|
||||
GridFunction x(fespace);
|
||||
x = 0.0;
|
||||
|
||||
// 9. Set up the bilinear form a(.,.) on the finite element space
|
||||
// 8. Set up the bilinear form a(.,.) on the finite element space
|
||||
// corresponding to the Laplacian operator -Delta, by adding the Diffusion
|
||||
// domain integrator.
|
||||
BilinearForm *a = new BilinearForm(fespace);
|
||||
if (pa) { a->SetAssemblyLevel(AssemblyLevel::PARTIAL); }
|
||||
a->AddDomainIntegrator(new DiffusionIntegrator(one));
|
||||
|
||||
// 10. Assemble the bilinear form and the corresponding linear system,
|
||||
// applying any necessary transformations such as: eliminating boundary
|
||||
// conditions, applying conforming constraints for non-conforming AMR,
|
||||
// static condensation, etc.
|
||||
// 9. Assemble the bilinear form and the corresponding linear system,
|
||||
// applying any necessary transformations such as: eliminating boundary
|
||||
// conditions, applying conforming constraints for non-conforming AMR,
|
||||
// static condensation, etc.
|
||||
if (static_cond) { a->EnableStaticCondensation(); }
|
||||
a->Assemble();
|
||||
|
||||
OperatorPtr A;
|
||||
SparseMatrix A;
|
||||
Vector B, X;
|
||||
a->FormLinearSystem(ess_tdof_list, x, *b, A, X, B);
|
||||
|
||||
cout << "Size of linear system: " << A->Height() << endl;
|
||||
cout << "Size of linear system: " << A.Height() << endl;
|
||||
|
||||
// 11. Solve the linear system A X = B.
|
||||
if (!pa)
|
||||
{
|
||||
#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);
|
||||
// 10. Define a simple symmetric Gauss-Seidel preconditioner and use it to
|
||||
// solve the system A X = B with PCG.
|
||||
GSSmoother M(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);
|
||||
// 10. 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 // No preconditioning for now in partial assembly mode.
|
||||
{
|
||||
CG(*A, B, X, 1, 2000, 1e-12, 0.0);
|
||||
}
|
||||
|
||||
// 12. Recover the solution as a finite element grid function.
|
||||
// 11. Recover the solution as a finite element grid function.
|
||||
a->RecoverFEMSolution(X, *b, x);
|
||||
|
||||
// 13. Switch back to the host.
|
||||
Device::Disable();
|
||||
|
||||
// 14. Save the refined mesh and the solution. This output can be viewed later
|
||||
// 12. Save the refined mesh and the solution. This output can be viewed later
|
||||
// using GLVis: "glvis -m refined.mesh -g sol.gf".
|
||||
ofstream mesh_ofs("refined.mesh");
|
||||
mesh_ofs.precision(8);
|
||||
@@ -215,7 +179,7 @@ int main(int argc, char *argv[])
|
||||
sol_ofs.precision(8);
|
||||
x.Save(sol_ofs);
|
||||
|
||||
// 15. Send the solution by socket to a GLVis server.
|
||||
// 13. Send the solution by socket to a GLVis server.
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
@@ -225,7 +189,7 @@ int main(int argc, char *argv[])
|
||||
sol_sock << "solution\n" << *mesh << x << flush;
|
||||
}
|
||||
|
||||
// 16. Free the used memory.
|
||||
// 14. Free the used memory.
|
||||
delete a;
|
||||
delete b;
|
||||
delete fespace;
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
// ex10 -m ../data/beam-tri.mesh -s 3 -r 2 -o 2 -dt 3
|
||||
// ex10 -m ../data/beam-hex.mesh -s 2 -r 1 -o 2 -dt 3
|
||||
// ex10 -m ../data/beam-tet.mesh -s 2 -r 1 -o 2 -dt 3
|
||||
// ex10 -m ../data/beam-wedge.mesh -s 2 -r 1 -o 2 -dt 3
|
||||
// ex10 -m ../data/beam-quad.mesh -s 14 -r 2 -o 2 -dt 0.03 -vs 20
|
||||
// ex10 -m ../data/beam-hex.mesh -s 14 -r 1 -o 2 -dt 0.05 -vs 20
|
||||
// ex10 -m ../data/beam-quad-amr.mesh -s 3 -r 2 -o 2 -dt 3
|
||||
//
|
||||
// Description: This examples solves a time dependent nonlinear elasticity
|
||||
// problem of the form dv/dt = H(x) + S v, dx/dt = v, where H is a
|
||||
@@ -92,9 +90,9 @@ public:
|
||||
This is the only requirement for high-order SDIRK implicit integration.*/
|
||||
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k);
|
||||
|
||||
double ElasticEnergy(const Vector &x) const;
|
||||
double KineticEnergy(const Vector &v) const;
|
||||
void GetElasticEnergyDensity(const GridFunction &x, GridFunction &w) const;
|
||||
double ElasticEnergy(Vector &x) const;
|
||||
double KineticEnergy(Vector &v) const;
|
||||
void GetElasticEnergyDensity(GridFunction &x, GridFunction &w) const;
|
||||
|
||||
virtual ~HyperelasticOperator();
|
||||
};
|
||||
@@ -134,12 +132,12 @@ public:
|
||||
class ElasticEnergyCoefficient : public Coefficient
|
||||
{
|
||||
private:
|
||||
HyperelasticModel &model;
|
||||
const GridFunction &x;
|
||||
DenseMatrix J;
|
||||
HyperelasticModel &model;
|
||||
GridFunction &x;
|
||||
DenseMatrix J;
|
||||
|
||||
public:
|
||||
ElasticEnergyCoefficient(HyperelasticModel &m, const GridFunction &x_)
|
||||
ElasticEnergyCoefficient(HyperelasticModel &m, GridFunction &x_)
|
||||
: model(m), x(x_) { }
|
||||
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
virtual ~ElasticEnergyCoefficient() { }
|
||||
@@ -223,14 +221,12 @@ int main(int argc, char *argv[])
|
||||
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
|
||||
case 13: ode_solver = new RK3SSPSolver; break;
|
||||
case 14: ode_solver = new RK4Solver; break;
|
||||
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
|
||||
// Implicit A-stable methods (not L-stable)
|
||||
case 22: ode_solver = new ImplicitMidpointSolver; break;
|
||||
case 23: ode_solver = new SDIRK23Solver; break;
|
||||
case 24: ode_solver = new SDIRK34Solver; break;
|
||||
default:
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
delete mesh;
|
||||
return 3;
|
||||
}
|
||||
|
||||
@@ -251,7 +247,7 @@ int main(int argc, char *argv[])
|
||||
H1_FECollection fe_coll(order, dim);
|
||||
FiniteElementSpace fespace(mesh, &fe_coll, dim);
|
||||
|
||||
int fe_size = fespace.GetTrueVSize();
|
||||
int fe_size = fespace.GetVSize();
|
||||
cout << "Number of velocity/deformation unknowns: " << fe_size << endl;
|
||||
Array<int> fe_offset(3);
|
||||
fe_offset[0] = 0;
|
||||
@@ -260,8 +256,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
BlockVector vx(fe_offset);
|
||||
GridFunction v, x;
|
||||
v.MakeTRef(&fespace, vx.GetBlock(0), 0);
|
||||
x.MakeTRef(&fespace, vx.GetBlock(1), 0);
|
||||
v.MakeRef(&fespace, vx.GetBlock(0), 0);
|
||||
x.MakeRef(&fespace, vx.GetBlock(1), 0);
|
||||
|
||||
GridFunction x_ref(&fespace);
|
||||
mesh->GetNodes(x_ref);
|
||||
@@ -274,10 +270,8 @@ int main(int argc, char *argv[])
|
||||
// a beam-like mesh (see description above).
|
||||
VectorFunctionCoefficient velo(dim, InitialVelocity);
|
||||
v.ProjectCoefficient(velo);
|
||||
v.SetTrueVector();
|
||||
VectorFunctionCoefficient deform(dim, InitialDeformation);
|
||||
x.ProjectCoefficient(deform);
|
||||
x.SetTrueVector();
|
||||
|
||||
Array<int> ess_bdr(fespace.GetMesh()->bdr_attributes.Max());
|
||||
ess_bdr = 0;
|
||||
@@ -294,7 +288,6 @@ int main(int argc, char *argv[])
|
||||
int visport = 19916;
|
||||
vis_v.open(vishost, visport);
|
||||
vis_v.precision(8);
|
||||
v.SetFromTrueVector(); x.SetFromTrueVector();
|
||||
visualize(vis_v, mesh, &x, &v, "Velocity", true);
|
||||
vis_w.open(vishost, visport);
|
||||
if (vis_w)
|
||||
@@ -305,8 +298,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
double ee0 = oper.ElasticEnergy(x.GetTrueVector());
|
||||
double ke0 = oper.KineticEnergy(v.GetTrueVector());
|
||||
double ee0 = oper.ElasticEnergy(x);
|
||||
double ke0 = oper.KineticEnergy(v);
|
||||
cout << "initial elastic energy (EE) = " << ee0 << endl;
|
||||
cout << "initial kinetic energy (KE) = " << ke0 << endl;
|
||||
cout << "initial total energy (TE) = " << (ee0 + ke0) << endl;
|
||||
@@ -328,15 +321,14 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (last_step || (ti % vis_steps) == 0)
|
||||
{
|
||||
double ee = oper.ElasticEnergy(x.GetTrueVector());
|
||||
double ke = oper.KineticEnergy(v.GetTrueVector());
|
||||
double ee = oper.ElasticEnergy(x);
|
||||
double ke = oper.KineticEnergy(v);
|
||||
|
||||
cout << "step " << ti << ", t = " << t << ", EE = " << ee << ", KE = "
|
||||
<< ke << ", ΔTE = " << (ee+ke)-(ee0+ke0) << endl;
|
||||
|
||||
if (visualization)
|
||||
{
|
||||
v.SetFromTrueVector(); x.SetFromTrueVector();
|
||||
visualize(vis_v, mesh, &x, &v);
|
||||
if (vis_w)
|
||||
{
|
||||
@@ -349,7 +341,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 9. Save the displaced mesh, the velocity and elastic energy.
|
||||
{
|
||||
v.SetFromTrueVector(); x.SetFromTrueVector();
|
||||
GridFunction *nodes = &x;
|
||||
int owns_nodes = 0;
|
||||
mesh->SwapNodes(nodes, owns_nodes);
|
||||
@@ -450,7 +441,7 @@ ReducedSystemOperator::~ReducedSystemOperator()
|
||||
HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
|
||||
Array<int> &ess_bdr, double visc,
|
||||
double mu, double K)
|
||||
: TimeDependentOperator(2*f.GetTrueVSize(), 0.0), fespace(f),
|
||||
: TimeDependentOperator(2*f.GetVSize(), 0.0), fespace(f),
|
||||
M(&fespace), S(&fespace), H(&fespace),
|
||||
viscosity(visc), z(height/2)
|
||||
{
|
||||
@@ -461,10 +452,8 @@ HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
|
||||
ConstantCoefficient rho0(ref_density);
|
||||
M.AddDomainIntegrator(new VectorMassIntegrator(rho0));
|
||||
M.Assemble(skip_zero_entries);
|
||||
Array<int> ess_tdof_list;
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
SparseMatrix tmp;
|
||||
M.FormSystemMatrix(ess_tdof_list, tmp);
|
||||
M.EliminateEssentialBC(ess_bdr);
|
||||
M.Finalize(skip_zero_entries);
|
||||
|
||||
M_solver.iterative_mode = false;
|
||||
M_solver.SetRelTol(rel_tol);
|
||||
@@ -476,12 +465,13 @@ HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
|
||||
|
||||
model = new NeoHookeanModel(mu, K);
|
||||
H.AddDomainIntegrator(new HyperelasticNLFIntegrator(model));
|
||||
H.SetEssentialTrueDofs(ess_tdof_list);
|
||||
H.SetEssentialBC(ess_bdr);
|
||||
|
||||
ConstantCoefficient visc_coeff(viscosity);
|
||||
S.AddDomainIntegrator(new VectorDiffusionIntegrator(visc_coeff));
|
||||
S.Assemble(skip_zero_entries);
|
||||
S.FormSystemMatrix(ess_tdof_list, tmp);
|
||||
S.EliminateEssentialBC(ess_bdr);
|
||||
S.Finalize(skip_zero_entries);
|
||||
|
||||
reduced_oper = new ReducedSystemOperator(&M, &S, &H);
|
||||
|
||||
@@ -550,18 +540,18 @@ void HyperelasticOperator::ImplicitSolve(const double dt,
|
||||
add(v, dt, dv_dt, dx_dt);
|
||||
}
|
||||
|
||||
double HyperelasticOperator::ElasticEnergy(const Vector &x) const
|
||||
double HyperelasticOperator::ElasticEnergy(Vector &x) const
|
||||
{
|
||||
return H.GetEnergy(x);
|
||||
}
|
||||
|
||||
double HyperelasticOperator::KineticEnergy(const Vector &v) const
|
||||
double HyperelasticOperator::KineticEnergy(Vector &v) const
|
||||
{
|
||||
return 0.5*M.InnerProduct(v, v);
|
||||
}
|
||||
|
||||
void HyperelasticOperator::GetElasticEnergyDensity(
|
||||
const GridFunction &x, GridFunction &w) const
|
||||
GridFunction &x, GridFunction &w) const
|
||||
{
|
||||
ElasticEnergyCoefficient w_coeff(*model, x);
|
||||
w.ProjectCoefficient(w_coeff);
|
||||
|
||||
@@ -7,10 +7,8 @@
|
||||
// mpirun -np 4 ex10p -m ../data/beam-tri.mesh -s 3 -rs 2 -dt 3
|
||||
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 2 -rs 1 -dt 3
|
||||
// mpirun -np 4 ex10p -m ../data/beam-tet.mesh -s 2 -rs 1 -dt 3
|
||||
// mpirun -np 4 ex10p -m ../data/beam-wedge.mesh -s 2 -rs 1 -dt 3
|
||||
// mpirun -np 4 ex10p -m ../data/beam-quad.mesh -s 14 -rs 2 -dt 0.03 -vs 20
|
||||
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 14 -rs 1 -dt 0.05 -vs 20
|
||||
// mpirun -np 4 ex10p -m ../data/beam-quad-amr.mesh -s 3 -rs 2 -dt 3
|
||||
//
|
||||
// Description: This examples solves a time dependent nonlinear elasticity
|
||||
// problem of the form dv/dt = H(x) + S v, dx/dt = v, where H is a
|
||||
@@ -59,7 +57,6 @@ class HyperelasticOperator : public TimeDependentOperator
|
||||
{
|
||||
protected:
|
||||
ParFiniteElementSpace &fespace;
|
||||
Array<int> ess_tdof_list;
|
||||
|
||||
ParBilinearForm M, S;
|
||||
ParNonlinearForm H;
|
||||
@@ -94,10 +91,9 @@ public:
|
||||
This is the only requirement for high-order SDIRK implicit integration.*/
|
||||
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k);
|
||||
|
||||
double ElasticEnergy(const ParGridFunction &x) const;
|
||||
double KineticEnergy(const ParGridFunction &v) const;
|
||||
void GetElasticEnergyDensity(const ParGridFunction &x,
|
||||
ParGridFunction &w) const;
|
||||
double ElasticEnergy(ParGridFunction &x) const;
|
||||
double KineticEnergy(ParGridFunction &v) const;
|
||||
void GetElasticEnergyDensity(ParGridFunction &x, ParGridFunction &w) const;
|
||||
|
||||
virtual ~HyperelasticOperator();
|
||||
};
|
||||
@@ -115,11 +111,10 @@ private:
|
||||
double dt;
|
||||
const Vector *v, *x;
|
||||
mutable Vector w, z;
|
||||
const Array<int> &ess_tdof_list;
|
||||
|
||||
public:
|
||||
ReducedSystemOperator(ParBilinearForm *M_, ParBilinearForm *S_,
|
||||
ParNonlinearForm *H_, const Array<int> &ess_tdof_list);
|
||||
ParNonlinearForm *H_);
|
||||
|
||||
/// Set current dt, v, x values - needed to compute action and Jacobian.
|
||||
void SetParameters(double dt_, const Vector *v_, const Vector *x_);
|
||||
@@ -139,12 +134,12 @@ public:
|
||||
class ElasticEnergyCoefficient : public Coefficient
|
||||
{
|
||||
private:
|
||||
HyperelasticModel &model;
|
||||
const ParGridFunction &x;
|
||||
DenseMatrix J;
|
||||
HyperelasticModel &model;
|
||||
ParGridFunction &x;
|
||||
DenseMatrix J;
|
||||
|
||||
public:
|
||||
ElasticEnergyCoefficient(HyperelasticModel &m, const ParGridFunction &x_)
|
||||
ElasticEnergyCoefficient(HyperelasticModel &m, ParGridFunction &x_)
|
||||
: model(m), x(x_) { }
|
||||
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
virtual ~ElasticEnergyCoefficient() { }
|
||||
@@ -245,7 +240,6 @@ int main(int argc, char *argv[])
|
||||
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
|
||||
case 13: ode_solver = new RK3SSPSolver; break;
|
||||
case 14: ode_solver = new RK4Solver; break;
|
||||
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
|
||||
// Implicit A-stable methods (not L-stable)
|
||||
case 22: ode_solver = new ImplicitMidpointSolver; break;
|
||||
case 23: ode_solver = new SDIRK23Solver; break;
|
||||
@@ -255,7 +249,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
}
|
||||
delete mesh;
|
||||
MPI_Finalize();
|
||||
return 3;
|
||||
}
|
||||
@@ -299,9 +292,7 @@ int main(int argc, char *argv[])
|
||||
true_offset[2] = 2*true_size;
|
||||
|
||||
BlockVector vx(true_offset);
|
||||
ParGridFunction v_gf, x_gf;
|
||||
v_gf.MakeTRef(&fespace, vx, true_offset[0]);
|
||||
x_gf.MakeTRef(&fespace, vx, true_offset[1]);
|
||||
ParGridFunction v_gf(&fespace), x_gf(&fespace);
|
||||
|
||||
ParGridFunction x_ref(&fespace);
|
||||
pmesh->GetNodes(x_ref);
|
||||
@@ -314,12 +305,11 @@ int main(int argc, char *argv[])
|
||||
// boundary conditions on a beam-like mesh (see description above).
|
||||
VectorFunctionCoefficient velo(dim, InitialVelocity);
|
||||
v_gf.ProjectCoefficient(velo);
|
||||
v_gf.SetTrueVector();
|
||||
VectorFunctionCoefficient deform(dim, InitialDeformation);
|
||||
x_gf.ProjectCoefficient(deform);
|
||||
x_gf.SetTrueVector();
|
||||
|
||||
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
|
||||
v_gf.GetTrueDofs(vx.GetBlock(0));
|
||||
x_gf.GetTrueDofs(vx.GetBlock(1));
|
||||
|
||||
Array<int> ess_bdr(fespace.GetMesh()->bdr_attributes.Max());
|
||||
ess_bdr = 0;
|
||||
@@ -375,7 +365,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (last_step || (ti % vis_steps) == 0)
|
||||
{
|
||||
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
|
||||
v_gf.Distribute(vx.GetBlock(0));
|
||||
x_gf.Distribute(vx.GetBlock(1));
|
||||
|
||||
double ee = oper.ElasticEnergy(x_gf);
|
||||
double ke = oper.KineticEnergy(v_gf);
|
||||
@@ -400,7 +391,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 11. Save the displaced mesh, the velocity and elastic energy.
|
||||
{
|
||||
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
|
||||
GridFunction *nodes = &x_gf;
|
||||
int owns_nodes = 0;
|
||||
pmesh->SwapNodes(nodes, owns_nodes);
|
||||
@@ -468,11 +458,9 @@ void visualize(ostream &out, ParMesh *mesh, ParGridFunction *deformed_nodes,
|
||||
|
||||
|
||||
ReducedSystemOperator::ReducedSystemOperator(
|
||||
ParBilinearForm *M_, ParBilinearForm *S_, ParNonlinearForm *H_,
|
||||
const Array<int> &ess_tdof_list_)
|
||||
ParBilinearForm *M_, ParBilinearForm *S_, ParNonlinearForm *H_)
|
||||
: Operator(M_->ParFESpace()->TrueVSize()), M(M_), S(S_), H(H_),
|
||||
Jacobian(NULL), dt(0.0), v(NULL), x(NULL), w(height), z(height),
|
||||
ess_tdof_list(ess_tdof_list_)
|
||||
Jacobian(NULL), dt(0.0), v(NULL), x(NULL), w(height), z(height)
|
||||
{ }
|
||||
|
||||
void ReducedSystemOperator::SetParameters(double dt_, const Vector *v_,
|
||||
@@ -489,7 +477,6 @@ void ReducedSystemOperator::Mult(const Vector &k, Vector &y) const
|
||||
H->Mult(z, y);
|
||||
M->TrueAddMult(k, y);
|
||||
S->TrueAddMult(w, y);
|
||||
y.SetSubVector(ess_tdof_list, 0.0);
|
||||
}
|
||||
|
||||
Operator &ReducedSystemOperator::GetGradient(const Vector &k) const
|
||||
@@ -501,8 +488,6 @@ Operator &ReducedSystemOperator::GetGradient(const Vector &k) const
|
||||
localJ->Add(dt*dt, H->GetLocalGradient(z));
|
||||
Jacobian = M->ParallelAssemble(localJ);
|
||||
delete localJ;
|
||||
HypreParMatrix *Je = Jacobian->EliminateRowsCols(ess_tdof_list);
|
||||
delete Je;
|
||||
return *Jacobian;
|
||||
}
|
||||
|
||||
@@ -527,11 +512,9 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
|
||||
ConstantCoefficient rho0(ref_density);
|
||||
M.AddDomainIntegrator(new VectorMassIntegrator(rho0));
|
||||
M.Assemble(skip_zero_entries);
|
||||
M.EliminateEssentialBC(ess_bdr);
|
||||
M.Finalize(skip_zero_entries);
|
||||
Mmat = M.ParallelAssemble();
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
HypreParMatrix *Me = Mmat->EliminateRowsCols(ess_tdof_list);
|
||||
delete Me;
|
||||
|
||||
M_solver.iterative_mode = false;
|
||||
M_solver.SetRelTol(rel_tol);
|
||||
@@ -544,14 +527,15 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
|
||||
|
||||
model = new NeoHookeanModel(mu, K);
|
||||
H.AddDomainIntegrator(new HyperelasticNLFIntegrator(model));
|
||||
H.SetEssentialTrueDofs(ess_tdof_list);
|
||||
H.SetEssentialBC(ess_bdr);
|
||||
|
||||
ConstantCoefficient visc_coeff(viscosity);
|
||||
S.AddDomainIntegrator(new VectorDiffusionIntegrator(visc_coeff));
|
||||
S.Assemble(skip_zero_entries);
|
||||
S.EliminateEssentialBC(ess_bdr);
|
||||
S.Finalize(skip_zero_entries);
|
||||
|
||||
reduced_oper = new ReducedSystemOperator(&M, &S, &H, ess_tdof_list);
|
||||
reduced_oper = new ReducedSystemOperator(&M, &S, &H);
|
||||
|
||||
HypreSmoother *J_hypreSmoother = new HypreSmoother;
|
||||
J_hypreSmoother->SetType(HypreSmoother::l1Jacobi);
|
||||
@@ -588,7 +572,6 @@ void HyperelasticOperator::Mult(const Vector &vx, Vector &dvx_dt) const
|
||||
if (viscosity != 0.0)
|
||||
{
|
||||
S.TrueAddMult(v, z);
|
||||
z.SetSubVector(ess_tdof_list, 0.0);
|
||||
}
|
||||
z.Neg(); // z = -z
|
||||
M_solver.Mult(z, dv_dt);
|
||||
@@ -618,12 +601,12 @@ void HyperelasticOperator::ImplicitSolve(const double dt,
|
||||
add(v, dt, dv_dt, dx_dt);
|
||||
}
|
||||
|
||||
double HyperelasticOperator::ElasticEnergy(const ParGridFunction &x) const
|
||||
double HyperelasticOperator::ElasticEnergy(ParGridFunction &x) const
|
||||
{
|
||||
return H.GetEnergy(x);
|
||||
}
|
||||
|
||||
double HyperelasticOperator::KineticEnergy(const ParGridFunction &v) const
|
||||
double HyperelasticOperator::KineticEnergy(ParGridFunction &v) const
|
||||
{
|
||||
double loc_energy = 0.5*M.InnerProduct(v, v);
|
||||
double energy;
|
||||
@@ -633,7 +616,7 @@ double HyperelasticOperator::KineticEnergy(const ParGridFunction &v) const
|
||||
}
|
||||
|
||||
void HyperelasticOperator::GetElasticEnergyDensity(
|
||||
const ParGridFunction &x, ParGridFunction &w) const
|
||||
ParGridFunction &x, ParGridFunction &w) const
|
||||
{
|
||||
ElasticEnergyCoefficient w_coeff(*model, x);
|
||||
w.ProjectCoefficient(w_coeff);
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
//
|
||||
// Sample runs: mpirun -np 4 ex11p -m ../data/square-disc.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/star.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/star-mixed.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/escher.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/fichera.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/fichera-mixed.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/toroid-wedge.mesh -o 2
|
||||
// mpirun -np 4 ex11p -m ../data/square-disc-p2.vtk -o 2
|
||||
// mpirun -np 4 ex11p -m ../data/square-disc-p3.mesh -o 3
|
||||
// mpirun -np 4 ex11p -m ../data/square-disc-nurbs.mesh -o -1
|
||||
@@ -18,11 +15,6 @@
|
||||
// mpirun -np 4 ex11p -m ../data/star-surf.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/square-disc-surf.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/inline-segment.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/inline-quad.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/inline-tri.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/inline-hex.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/inline-tet.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/inline-wedge.mesh -s 83
|
||||
// mpirun -np 4 ex11p -m ../data/amr-quad.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/amr-hex.mesh
|
||||
// mpirun -np 4 ex11p -m ../data/mobius-strip.mesh -n 8
|
||||
@@ -40,9 +32,9 @@
|
||||
//
|
||||
// The example highlights the use of the LOBPCG eigenvalue solver
|
||||
// together with the BoomerAMG preconditioner in HYPRE, as well as
|
||||
// optionally the SuperLU or STRUMPACK parallel direct solvers.
|
||||
// Reusing a single GLVis visualization window for multiple
|
||||
// eigenfunctions is also illustrated.
|
||||
// optionally the SuperLU parallel direct solver. Reusing a single
|
||||
// GLVis visualization window for multiple eigenfunctions is also
|
||||
// illustrated.
|
||||
//
|
||||
// We recommend viewing Example 1 before viewing this example.
|
||||
|
||||
@@ -69,7 +61,6 @@ int main(int argc, char *argv[])
|
||||
int nev = 5;
|
||||
int seed = 75;
|
||||
bool slu_solver = false;
|
||||
bool sp_solver = false;
|
||||
bool visualization = 1;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
@@ -89,36 +80,19 @@ int main(int argc, char *argv[])
|
||||
#ifdef MFEM_USE_SUPERLU
|
||||
args.AddOption(&slu_solver, "-slu", "--superlu", "-no-slu",
|
||||
"--no-superlu", "Use the SuperLU Solver.");
|
||||
#endif
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
args.AddOption(&sp_solver, "-sp", "--strumpack", "-no-sp",
|
||||
"--no-strumpack", "Use the STRUMPACK Solver.");
|
||||
#endif
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.Parse();
|
||||
if (slu_solver && sp_solver)
|
||||
if (!args.Good())
|
||||
{
|
||||
if (myid == 0)
|
||||
cout << "WARNING: Both SuperLU and STRUMPACK have been selected,"
|
||||
<< " please choose either one." << endl
|
||||
<< " Defaulting to SuperLU." << endl;
|
||||
sp_solver = false;
|
||||
}
|
||||
// The command line options are also passed to the STRUMPACK
|
||||
// solver. So do not exit if some options are not recognized.
|
||||
if (!sp_solver)
|
||||
{
|
||||
if (!args.Good())
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
}
|
||||
MPI_Finalize();
|
||||
return 1;
|
||||
args.PrintUsage(cout);
|
||||
}
|
||||
MPI_Finalize();
|
||||
return 1;
|
||||
}
|
||||
if (myid == 0)
|
||||
{
|
||||
@@ -211,20 +185,12 @@ int main(int argc, char *argv[])
|
||||
HypreParMatrix *A = a->ParallelAssemble();
|
||||
HypreParMatrix *M = m->ParallelAssemble();
|
||||
|
||||
#if defined(MFEM_USE_SUPERLU) || defined(MFEM_USE_STRUMPACK)
|
||||
Operator * Arow = NULL;
|
||||
#ifdef MFEM_USE_SUPERLU
|
||||
Operator * Arow = NULL;
|
||||
if (slu_solver)
|
||||
{
|
||||
Arow = new SuperLURowLocMatrix(*A);
|
||||
}
|
||||
#endif
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
if (sp_solver)
|
||||
{
|
||||
Arow = new STRUMPACKRowLocMatrix(*A);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
delete a;
|
||||
@@ -234,41 +200,23 @@ int main(int argc, char *argv[])
|
||||
// preconditioner for A to be used within the solver. Set the matrices
|
||||
// which define the generalized eigenproblem A x = lambda M x.
|
||||
Solver * precond = NULL;
|
||||
if (!slu_solver && !sp_solver)
|
||||
if (!slu_solver)
|
||||
{
|
||||
HypreBoomerAMG * amg = new HypreBoomerAMG(*A);
|
||||
amg->SetPrintLevel(0);
|
||||
precond = amg;
|
||||
}
|
||||
#ifdef MFEM_USE_SUPERLU
|
||||
else
|
||||
{
|
||||
#ifdef MFEM_USE_SUPERLU
|
||||
if (slu_solver)
|
||||
{
|
||||
SuperLUSolver * superlu = new SuperLUSolver(MPI_COMM_WORLD);
|
||||
superlu->SetPrintStatistics(false);
|
||||
superlu->SetSymmetricPattern(true);
|
||||
superlu->SetColumnPermutation(superlu::PARMETIS);
|
||||
superlu->SetOperator(*Arow);
|
||||
precond = superlu;
|
||||
}
|
||||
#endif
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
if (sp_solver)
|
||||
{
|
||||
STRUMPACKSolver * strumpack = new STRUMPACKSolver(argc, argv, MPI_COMM_WORLD);
|
||||
strumpack->SetPrintFactorStatistics(true);
|
||||
strumpack->SetPrintSolveStatistics(false);
|
||||
strumpack->SetKrylovSolver(strumpack::KrylovSolver::DIRECT);
|
||||
strumpack->SetReorderingStrategy(strumpack::ReorderingStrategy::METIS);
|
||||
strumpack->DisableMatching();
|
||||
strumpack->SetOperator(*Arow);
|
||||
strumpack->SetFromCommandLine();
|
||||
precond = strumpack;
|
||||
}
|
||||
#endif
|
||||
SuperLUSolver * superlu = new SuperLUSolver(MPI_COMM_WORLD);
|
||||
superlu->SetPrintStatistics(false);
|
||||
superlu->SetSymmetricPattern(true);
|
||||
superlu->SetColumnPermutation(superlu::PARMETIS);
|
||||
superlu->SetOperator(*Arow);
|
||||
precond = superlu;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
HypreLOBPCG * lobpcg = new HypreLOBPCG(MPI_COMM_WORLD);
|
||||
lobpcg->SetNumModes(nev);
|
||||
@@ -359,7 +307,7 @@ int main(int argc, char *argv[])
|
||||
delete precond;
|
||||
delete M;
|
||||
delete A;
|
||||
#if defined(MFEM_USE_SUPERLU) || defined(MFEM_USE_STRUMPACK)
|
||||
#ifdef MFEM_USE_SUPERLU
|
||||
delete Arow;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2,16 +2,14 @@
|
||||
//
|
||||
// Compile with: make ex12p
|
||||
//
|
||||
// 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 79 -n 10 -o 2 -elast
|
||||
// mpirun -np 4 ex12p -m ../data/beam-hex.mesh -s 3876
|
||||
// mpirun -np 4 ex12p -m ../data/beam-wedge.mesh -s 79
|
||||
// mpirun -np 4 ex12p -m ../data/beam-tri.mesh -s 3876 -o 2 -sys
|
||||
// mpirun -np 4 ex12p -m ../data/beam-quad.mesh -s 4526 -n 6 -o 3 -elast
|
||||
// mpirun -np 4 ex12p -m ../data/beam-quad-nurbs.mesh
|
||||
// mpirun -np 4 ex12p -m ../data/beam-hex-nurbs.mesh
|
||||
// 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 -n 10 -o 2 -elast
|
||||
// mpirun -np 4 ex12p -m ../data/beam-hex.mesh -s 3876
|
||||
// mpirun -np 4 ex12p -m ../data/beam-tri.mesh -o 2 -sys
|
||||
// mpirun -np 4 ex12p -m ../data/beam-quad.mesh -n 6 -o 3 -elast
|
||||
// mpirun -np 4 ex12p -m ../data/beam-quad-nurbs.mesh
|
||||
// mpirun -np 4 ex12p -m ../data/beam-hex-nurbs.mesh
|
||||
//
|
||||
// Description: This example code solves the linear elasticity eigenvalue
|
||||
// problem for a multi-material cantilever beam.
|
||||
@@ -110,9 +108,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 4. Select the order of the finite element discretization space. For NURBS
|
||||
// meshes, we increase the order by degree elevation.
|
||||
if (mesh->NURBSext)
|
||||
if (mesh->NURBSext && order > mesh->NURBSext->GetOrder())
|
||||
{
|
||||
mesh->DegreeElevate(order, order);
|
||||
mesh->DegreeElevate(order - mesh->NURBSext->GetOrder());
|
||||
}
|
||||
|
||||
// 5. Refine the serial mesh on all processors to increase the resolution. In
|
||||
|
||||
@@ -110,7 +110,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 6. Define a parallel finite element space on the parallel mesh. Here we
|
||||
// use the Nedelec finite elements of the specified order.
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
//
|
||||
// Sample runs: ex14 -m ../data/inline-quad.mesh -o 0
|
||||
// ex14 -m ../data/star.mesh -r 4 -o 2
|
||||
// ex14 -m ../data/star-mixed.mesh -r 4 -o 2
|
||||
// ex14 -m ../data/escher.mesh -s 1
|
||||
// ex14 -m ../data/fichera.mesh -s 1 -k 1
|
||||
// ex14 -m ../data/fichera-mixed.mesh -s 1 -k 1
|
||||
// ex14 -m ../data/square-disc-p2.vtk -r 3 -o 2
|
||||
// ex14 -m ../data/square-disc-p3.mesh -r 2 -o 3
|
||||
// ex14 -m ../data/square-disc-nurbs.mesh -o 1
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
//
|
||||
// Sample runs: mpirun -np 4 ex14p -m ../data/inline-quad.mesh -o 0
|
||||
// mpirun -np 4 ex14p -m ../data/star.mesh -o 2
|
||||
// mpirun -np 4 ex14p -m ../data/star-mixed.mesh -o 2
|
||||
// mpirun -np 4 ex14p -m ../data/escher.mesh -s 1
|
||||
// mpirun -np 4 ex14p -m ../data/fichera.mesh -s 1 -k 1
|
||||
// mpirun -np 4 ex14p -m ../data/fichera-mixed.mesh -s 1 -k 1
|
||||
// mpirun -np 4 ex14p -m ../data/square-disc-p2.vtk -o 2
|
||||
// mpirun -np 4 ex14p -m ../data/square-disc-p3.mesh -o 3
|
||||
// mpirun -np 4 ex14p -m ../data/square-disc-nurbs.mesh -o 1
|
||||
|
||||
@@ -135,8 +135,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
mesh.UniformRefinement();
|
||||
}
|
||||
// Make sure tet-only meshes are marked for local refinement.
|
||||
mesh.Finalize(true);
|
||||
|
||||
// 4. All boundary attributes will be used for essential (Dirichlet) BC.
|
||||
MFEM_VERIFY(mesh.bdr_attributes.Size() > 0,
|
||||
|
||||
@@ -151,8 +151,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
// Make sure tet-only meshes are marked for local refinement.
|
||||
mesh->Finalize(true);
|
||||
|
||||
// 5. Define a parallel mesh by partitioning the serial mesh. Once the
|
||||
// parallel mesh is defined, the serial mesh can be deleted.
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
// ex16 -s 3 -a 0.5 -k 0.5 -o 4
|
||||
// ex16 -s 14 -dt 1.0e-4 -tf 4.0e-2 -vs 40
|
||||
// ex16 -m ../data/fichera-q2.mesh
|
||||
// ex16 -m ../data/fichera-mixed.mesh
|
||||
// ex16 -m ../data/escher.mesh
|
||||
// ex16 -m ../data/beam-tet.mesh -tf 10 -dt 0.1
|
||||
// ex16 -m ../data/amr-quad.mesh -o 4 -r 0
|
||||
@@ -158,14 +157,12 @@ int main(int argc, char *argv[])
|
||||
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
|
||||
case 13: ode_solver = new RK3SSPSolver; break;
|
||||
case 14: ode_solver = new RK4Solver; break;
|
||||
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
|
||||
// Implicit A-stable methods (not L-stable)
|
||||
case 22: ode_solver = new ImplicitMidpointSolver; break;
|
||||
case 23: ode_solver = new SDIRK23Solver; break;
|
||||
case 24: ode_solver = new SDIRK34Solver; break;
|
||||
default:
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
delete mesh;
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// MFEM Example 16 - Parallel Version
|
||||
// MFEM Example 16 - Parallel Version
|
||||
//
|
||||
// Compile with: make ex16p
|
||||
//
|
||||
@@ -10,7 +10,6 @@
|
||||
// mpirun -np 8 ex16p -s 3 -a 0.5 -k 0.5 -o 4
|
||||
// mpirun -np 4 ex16p -s 14 -dt 1.0e-4 -tf 4.0e-2 -vs 40
|
||||
// mpirun -np 16 ex16p -m ../data/fichera-q2.mesh
|
||||
// mpirun -np 16 ex16p -m ../data/fichera-mixed.mesh
|
||||
// mpirun -np 16 ex16p -m ../data/escher-p2.mesh
|
||||
// mpirun -np 8 ex16p -m ../data/beam-tet.mesh -tf 10 -dt 0.1
|
||||
// mpirun -np 4 ex16p -m ../data/amr-quad.mesh -o 4 -rs 0 -rp 0
|
||||
@@ -174,14 +173,12 @@ int main(int argc, char *argv[])
|
||||
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
|
||||
case 13: ode_solver = new RK3SSPSolver; break;
|
||||
case 14: ode_solver = new RK4Solver; break;
|
||||
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
|
||||
// Implicit A-stable methods (not L-stable)
|
||||
case 22: ode_solver = new ImplicitMidpointSolver; break;
|
||||
case 23: ode_solver = new SDIRK23Solver; break;
|
||||
case 24: ode_solver = new SDIRK34Solver; break;
|
||||
default:
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
delete mesh;
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
// ex17 -m ../data/beam-quad.mesh
|
||||
// ex17 -m ../data/beam-tet.mesh
|
||||
// ex17 -m ../data/beam-hex.mesh
|
||||
// ex17 -m ../data/beam-wedge.mesh
|
||||
// ex17 -m ../data/beam-quad.mesh -r 2 -o 3
|
||||
// ex17 -m ../data/beam-quad.mesh -r 2 -o 2 -a 1 -k 1
|
||||
// ex17 -m ../data/beam-hex.mesh -r 2 -o 2
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
// mpirun -np 4 ex17p -m ../data/beam-quad.mesh
|
||||
// mpirun -np 4 ex17p -m ../data/beam-tet.mesh
|
||||
// mpirun -np 4 ex17p -m ../data/beam-hex.mesh
|
||||
// mpirun -np 4 ex17p -m ../data/beam-wedge.mesh
|
||||
// mpirun -np 4 ex17p -m ../data/beam-quad.mesh -rs 2 -rp 2 -o 3 -elast
|
||||
// mpirun -np 4 ex17p -m ../data/beam-quad.mesh -rs 2 -rp 3 -o 2 -a 1 -k 1
|
||||
// mpirun -np 4 ex17p -m ../data/beam-hex.mesh -rs 2 -rp 1 -o 2
|
||||
|
||||
@@ -1,309 +0,0 @@
|
||||
// MFEM Example 18
|
||||
//
|
||||
// Compile with: make ex18
|
||||
//
|
||||
// Sample runs:
|
||||
//
|
||||
// ex18 -p 1 -r 2 -o 1 -s 3
|
||||
// ex18 -p 1 -r 1 -o 3 -s 4
|
||||
// ex18 -p 1 -r 0 -o 5 -s 6
|
||||
// ex18 -p 2 -r 1 -o 1 -s 3
|
||||
// ex18 -p 2 -r 0 -o 3 -s 3
|
||||
//
|
||||
// Description: This example code solves the compressible Euler system of
|
||||
// equations, a model nonlinear hyperbolic PDE, with a
|
||||
// discontinuous Galerkin (DG) formulation.
|
||||
//
|
||||
// Specifically, it solves for an exact solution of the equations
|
||||
// whereby a vortex is transported by a uniform flow. Since all
|
||||
// boundaries are periodic here, the method's accuracy can be
|
||||
// assessed by measuring the difference between the solution and
|
||||
// the initial condition at a later time when the vortex returns
|
||||
// to its initial location.
|
||||
//
|
||||
// Note that as the order of the spatial discretization increases,
|
||||
// the timestep must become smaller. This example currently uses a
|
||||
// simple estimate derived by Cockburn and Shu for the 1D RKDG
|
||||
// method. An additional factor can be tuned by passing the --cfl
|
||||
// (or -c shorter) flag.
|
||||
//
|
||||
// The example demonstrates user-defined bilinear and nonlinear
|
||||
// form integrators for systems of equations that are defined with
|
||||
// block vectors, and how these are used with an operator for
|
||||
// explicit time integrators. In this case the system also
|
||||
// involves an external approximate Riemann solver for the DG
|
||||
// interface flux. It also demonstrates how to use GLVis for
|
||||
// in-situ visualization of vector grid functions.
|
||||
//
|
||||
// We recommend viewing examples 9, 14 and 17 before viewing this
|
||||
// example.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
// Classes FE_Evolution, RiemannSolver, DomainIntegrator and FaceIntegrator
|
||||
// shared between the serial and parallel version of the example.
|
||||
#include "ex18.hpp"
|
||||
|
||||
// Choice for the problem setup. See InitialCondition in ex18.hpp.
|
||||
int problem;
|
||||
|
||||
// Equation constant parameters.
|
||||
const int num_equation = 4;
|
||||
const double specific_heat_ratio = 1.4;
|
||||
const double gas_constant = 1.0;
|
||||
|
||||
// Maximum characteristic speed (updated by integrators)
|
||||
double max_char_speed;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Parse command-line options.
|
||||
problem = 1;
|
||||
const char *mesh_file = "../data/periodic-square.mesh";
|
||||
int ref_levels = 1;
|
||||
int order = 3;
|
||||
int ode_solver_type = 4;
|
||||
double t_final = 2.0;
|
||||
double dt = -0.01;
|
||||
double cfl = 0.3;
|
||||
bool visualization = true;
|
||||
int vis_steps = 50;
|
||||
|
||||
int precision = 8;
|
||||
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(&ref_levels, "-r", "--refine",
|
||||
"Number of times to refine the mesh uniformly.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Order (degree) of the finite elements.");
|
||||
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
|
||||
"ODE solver: 1 - Forward Euler,\n\t"
|
||||
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
|
||||
args.AddOption(&t_final, "-tf", "--t-final",
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
"Time step. Positive number skips CFL timestep calculation.");
|
||||
args.AddOption(&cfl, "-c", "--cfl-number",
|
||||
"CFL number for timestep calculation.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.AddOption(&vis_steps, "-vs", "--visualization-steps",
|
||||
"Visualize every n-th timestep.");
|
||||
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
return 1;
|
||||
}
|
||||
args.PrintOptions(cout);
|
||||
|
||||
// 2. Read the mesh from the given mesh file. This example requires a 2D
|
||||
// periodic mesh, such as ../data/periodic-square.mesh.
|
||||
Mesh mesh(mesh_file, 1, 1);
|
||||
const int dim = mesh.Dimension();
|
||||
|
||||
MFEM_ASSERT(dim == 2, "Need a two-dimensional mesh for the problem definition");
|
||||
|
||||
// 3. Define the ODE solver used for time integration. Several explicit
|
||||
// Runge-Kutta methods are available.
|
||||
ODESolver *ode_solver = NULL;
|
||||
switch (ode_solver_type)
|
||||
{
|
||||
case 1: ode_solver = new ForwardEulerSolver; break;
|
||||
case 2: ode_solver = new RK2Solver(1.0); break;
|
||||
case 3: ode_solver = new RK3SSPSolver; break;
|
||||
case 4: ode_solver = new RK4Solver; break;
|
||||
case 6: ode_solver = new RK6Solver; break;
|
||||
default:
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
return 3;
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 5. Define the discontinuous DG finite element space of the given
|
||||
// polynomial order on the refined mesh.
|
||||
DG_FECollection fec(order, dim);
|
||||
// Finite element space for a scalar (thermodynamic quantity)
|
||||
FiniteElementSpace fes(&mesh, &fec);
|
||||
// Finite element space for a mesh-dim vector quantity (momentum)
|
||||
FiniteElementSpace dfes(&mesh, &fec, dim, Ordering::byNODES);
|
||||
// Finite element space for all variables together (total thermodynamic state)
|
||||
FiniteElementSpace vfes(&mesh, &fec, num_equation, Ordering::byNODES);
|
||||
|
||||
// This example depends on this ordering of the space.
|
||||
MFEM_ASSERT(fes.GetOrdering() == Ordering::byNODES, "");
|
||||
|
||||
cout << "Number of unknowns: " << vfes.GetVSize() << endl;
|
||||
|
||||
// 6. Define the initial conditions, save the corresponding mesh and grid
|
||||
// functions to a file. This can be opened with GLVis with the -gc option.
|
||||
|
||||
// The solution u has components {density, x-momentum, y-momentum, energy}.
|
||||
// These are stored contiguously in the BlockVector u_block.
|
||||
Array<int> offsets(num_equation + 1);
|
||||
for (int k = 0; k <= num_equation; k++) { offsets[k] = k * vfes.GetNDofs(); }
|
||||
BlockVector u_block(offsets);
|
||||
|
||||
// Momentum grid function on dfes for visualization.
|
||||
GridFunction mom(&dfes, u_block.GetData() + offsets[1]);
|
||||
|
||||
// Initialize the state.
|
||||
VectorFunctionCoefficient u0(num_equation, InitialCondition);
|
||||
GridFunction sol(&vfes, u_block.GetData());
|
||||
sol.ProjectCoefficient(u0);
|
||||
|
||||
// Output the initial solution.
|
||||
{
|
||||
ofstream mesh_ofs("vortex.mesh");
|
||||
mesh_ofs.precision(precision);
|
||||
mesh_ofs << mesh;
|
||||
|
||||
for (int k = 0; k < num_equation; k++)
|
||||
{
|
||||
GridFunction uk(&fes, u_block.GetBlock(k));
|
||||
ostringstream sol_name;
|
||||
sol_name << "vortex-" << k << "-init.gf";
|
||||
ofstream sol_ofs(sol_name.str().c_str());
|
||||
sol_ofs.precision(precision);
|
||||
sol_ofs << uk;
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Set up the nonlinear form corresponding to the DG discretization of the
|
||||
// flux divergence, and assemble the corresponding mass matrix.
|
||||
MixedBilinearForm Aflux(&dfes, &fes);
|
||||
Aflux.AddDomainIntegrator(new DomainIntegrator(dim));
|
||||
Aflux.Assemble();
|
||||
|
||||
NonlinearForm A(&vfes);
|
||||
RiemannSolver rsolver;
|
||||
A.AddInteriorFaceIntegrator(new FaceIntegrator(rsolver, dim));
|
||||
|
||||
// 8. 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).
|
||||
FE_Evolution euler(vfes, A, Aflux.SpMat());
|
||||
|
||||
// Visualize the density
|
||||
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 << mom;
|
||||
sout << "pause\n";
|
||||
sout << flush;
|
||||
cout << "GLVis visualization paused."
|
||||
<< " Press space (in the GLVis window) to resume it.\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the minimum element size.
|
||||
double hmin = 0.0;
|
||||
if (cfl > 0)
|
||||
{
|
||||
hmin = mesh.GetElementSize(0, 1);
|
||||
for (int i = 1; i < mesh.GetNE(); i++)
|
||||
{
|
||||
hmin = min(mesh.GetElementSize(i, 1), hmin);
|
||||
}
|
||||
}
|
||||
|
||||
// Start the timer.
|
||||
tic_toc.Clear();
|
||||
tic_toc.Start();
|
||||
|
||||
double t = 0.0;
|
||||
euler.SetTime(t);
|
||||
ode_solver->Init(euler);
|
||||
|
||||
if (cfl > 0)
|
||||
{
|
||||
// Find a safe dt, using a temporary vector. Calling Mult() computes the
|
||||
// maximum char speed at all quadrature points on all faces.
|
||||
Vector z(A.Width());
|
||||
max_char_speed = 0.;
|
||||
A.Mult(sol, z);
|
||||
dt = cfl * hmin / max_char_speed / (2*order+1);
|
||||
}
|
||||
|
||||
// Integrate in time.
|
||||
bool done = false;
|
||||
for (int ti = 0; !done; )
|
||||
{
|
||||
double dt_real = min(dt, t_final - t);
|
||||
|
||||
ode_solver->Step(sol, t, dt_real);
|
||||
if (cfl > 0)
|
||||
{
|
||||
dt = cfl * hmin / max_char_speed / (2*order+1);
|
||||
}
|
||||
ti++;
|
||||
|
||||
done = (t >= t_final - 1e-8*dt);
|
||||
if (done || ti % vis_steps == 0)
|
||||
{
|
||||
cout << "time step: " << ti << ", time: " << t << endl;
|
||||
if (visualization)
|
||||
{
|
||||
sout << "solution\n" << mesh << mom << flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tic_toc.Stop();
|
||||
cout << " done, " << tic_toc.RealTime() << "s." << endl;
|
||||
|
||||
// 9. Save the final solution. This output can be viewed later using GLVis:
|
||||
// "glvis -m vortex.mesh -g vortex-1-final.gf".
|
||||
for (int k = 0; k < num_equation; k++)
|
||||
{
|
||||
GridFunction uk(&fes, u_block.GetBlock(k));
|
||||
ostringstream sol_name;
|
||||
sol_name << "vortex-" << k << "-final.gf";
|
||||
ofstream sol_ofs(sol_name.str().c_str());
|
||||
sol_ofs.precision(precision);
|
||||
sol_ofs << uk;
|
||||
}
|
||||
|
||||
// 10. Compute the L2 solution error summed for all components.
|
||||
if (t_final == 2.0)
|
||||
{
|
||||
const double error = sol.ComputeLpError(2, u0);
|
||||
cout << "Solution error: " << error << endl;
|
||||
}
|
||||
|
||||
// Free the used memory.
|
||||
delete ode_solver;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,570 +0,0 @@
|
||||
// MFEM Example 18 - Serial/Parallel Shared Code
|
||||
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// Problem definition
|
||||
extern int problem;
|
||||
|
||||
// Maximum characteristic speed (updated by integrators)
|
||||
extern double max_char_speed;
|
||||
|
||||
extern const int num_equation;
|
||||
extern const double specific_heat_ratio;
|
||||
extern const double gas_constant;
|
||||
|
||||
// Time-dependent operator for the right-hand side of the ODE representing the
|
||||
// DG weak form.
|
||||
class FE_Evolution : public TimeDependentOperator
|
||||
{
|
||||
private:
|
||||
const int dim;
|
||||
|
||||
FiniteElementSpace &vfes;
|
||||
Operator &A;
|
||||
SparseMatrix &Aflux;
|
||||
DenseTensor Me_inv;
|
||||
|
||||
mutable Vector state;
|
||||
mutable DenseMatrix f;
|
||||
mutable DenseTensor flux;
|
||||
mutable Vector z;
|
||||
|
||||
void GetFlux(const DenseMatrix &state, DenseTensor &flux) const;
|
||||
|
||||
public:
|
||||
FE_Evolution(FiniteElementSpace &_vfes,
|
||||
Operator &_A, SparseMatrix &_Aflux);
|
||||
|
||||
virtual void Mult(const Vector &x, Vector &y) const;
|
||||
|
||||
virtual ~FE_Evolution() { }
|
||||
};
|
||||
|
||||
// Implements a simple Rusanov flux
|
||||
class RiemannSolver
|
||||
{
|
||||
private:
|
||||
Vector flux1;
|
||||
Vector flux2;
|
||||
|
||||
public:
|
||||
RiemannSolver();
|
||||
double Eval(const Vector &state1, const Vector &state2,
|
||||
const Vector &nor, Vector &flux);
|
||||
};
|
||||
|
||||
|
||||
// Constant (in time) mixed bilinear form multiplying the flux grid function.
|
||||
// The form is (vec(v), grad(w)) where the trial space = vector L2 space (mesh
|
||||
// dim) and test space = scalar L2 space.
|
||||
class DomainIntegrator : public BilinearFormIntegrator
|
||||
{
|
||||
private:
|
||||
Vector shape;
|
||||
DenseMatrix flux;
|
||||
DenseMatrix dshapedr;
|
||||
DenseMatrix dshapedx;
|
||||
|
||||
public:
|
||||
DomainIntegrator(const int dim);
|
||||
|
||||
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe,
|
||||
const FiniteElement &test_fe,
|
||||
ElementTransformation &Tr,
|
||||
DenseMatrix &elmat);
|
||||
};
|
||||
|
||||
// Interior face term: <F.n(u),[w]>
|
||||
class FaceIntegrator : public NonlinearFormIntegrator
|
||||
{
|
||||
private:
|
||||
RiemannSolver rsolver;
|
||||
Vector shape1;
|
||||
Vector shape2;
|
||||
Vector funval1;
|
||||
Vector funval2;
|
||||
Vector nor;
|
||||
Vector fluxN;
|
||||
IntegrationPoint eip1;
|
||||
IntegrationPoint eip2;
|
||||
|
||||
public:
|
||||
FaceIntegrator(RiemannSolver &rsolver_, const int dim);
|
||||
|
||||
virtual void AssembleFaceVector(const FiniteElement &el1,
|
||||
const FiniteElement &el2,
|
||||
FaceElementTransformations &Tr,
|
||||
const Vector &elfun, Vector &elvect);
|
||||
};
|
||||
|
||||
// Implementation of class FE_Evolution
|
||||
FE_Evolution::FE_Evolution(FiniteElementSpace &_vfes,
|
||||
Operator &_A, SparseMatrix &_Aflux)
|
||||
: TimeDependentOperator(_A.Height()),
|
||||
dim(_vfes.GetFE(0)->GetDim()),
|
||||
vfes(_vfes),
|
||||
A(_A),
|
||||
Aflux(_Aflux),
|
||||
Me_inv(vfes.GetFE(0)->GetDof(), vfes.GetFE(0)->GetDof(), vfes.GetNE()),
|
||||
state(num_equation),
|
||||
f(num_equation, dim),
|
||||
flux(vfes.GetNDofs(), dim, num_equation),
|
||||
z(A.Height())
|
||||
{
|
||||
// Standard local assembly and inversion for energy mass matrices.
|
||||
const int dof = vfes.GetFE(0)->GetDof();
|
||||
DenseMatrix Me(dof);
|
||||
DenseMatrixInverse inv(&Me);
|
||||
MassIntegrator mi;
|
||||
for (int i = 0; i < vfes.GetNE(); i++)
|
||||
{
|
||||
mi.AssembleElementMatrix(*vfes.GetFE(i), *vfes.GetElementTransformation(i), Me);
|
||||
inv.Factor();
|
||||
inv.GetInverseMatrix(Me_inv(i));
|
||||
}
|
||||
}
|
||||
|
||||
void FE_Evolution::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
// 0. Reset wavespeed computation before operator application.
|
||||
max_char_speed = 0.;
|
||||
|
||||
// 1. Create the vector z with the face terms -<F.n(u), [w]>.
|
||||
A.Mult(x, z);
|
||||
|
||||
// 2. Add the element terms.
|
||||
// i. computing the flux approximately as a grid function by interpolating
|
||||
// at the solution nodes.
|
||||
// ii. multiplying this grid function by a (constant) mixed bilinear form for
|
||||
// each of the num_equation, computing (F(u), grad(w)) for each equation.
|
||||
|
||||
DenseMatrix xmat(x.GetData(), vfes.GetNDofs(), num_equation);
|
||||
GetFlux(xmat, flux);
|
||||
|
||||
for (int k = 0; k < num_equation; k++)
|
||||
{
|
||||
Vector fk(flux(k).GetData(), dim * vfes.GetNDofs());
|
||||
Vector zk(z.GetData() + k * vfes.GetNDofs(), vfes.GetNDofs());
|
||||
Aflux.AddMult(fk, zk);
|
||||
}
|
||||
|
||||
// 3. Multiply element-wise by the inverse mass matrices.
|
||||
Vector zval;
|
||||
Array<int> vdofs;
|
||||
const int dof = vfes.GetFE(0)->GetDof();
|
||||
DenseMatrix zmat, ymat(dof, num_equation);
|
||||
|
||||
for (int i = 0; i < vfes.GetNE(); i++)
|
||||
{
|
||||
// Return the vdofs ordered byNODES
|
||||
vfes.GetElementVDofs(i, vdofs);
|
||||
z.GetSubVector(vdofs, zval);
|
||||
zmat.UseExternalData(zval.GetData(), dof, num_equation);
|
||||
mfem::Mult(Me_inv(i), zmat, ymat);
|
||||
y.SetSubVector(vdofs, ymat.GetData());
|
||||
}
|
||||
}
|
||||
|
||||
// Physicality check (at end)
|
||||
bool StateIsPhysical(const Vector &state, const int dim);
|
||||
|
||||
// Pressure (EOS) computation
|
||||
inline double ComputePressure(const Vector &state, int dim)
|
||||
{
|
||||
const double den = state(0);
|
||||
const Vector den_vel(state.GetData() + 1, dim);
|
||||
const double den_energy = state(1 + dim);
|
||||
|
||||
double den_vel2 = 0;
|
||||
for (int d = 0; d < dim; d++) { den_vel2 += den_vel(d) * den_vel(d); }
|
||||
den_vel2 /= den;
|
||||
|
||||
return (specific_heat_ratio - 1.0) * (den_energy - 0.5 * den_vel2);
|
||||
}
|
||||
|
||||
// Compute the vector flux F(u)
|
||||
void ComputeFlux(const Vector &state, int dim, DenseMatrix &flux)
|
||||
{
|
||||
const double den = state(0);
|
||||
const Vector den_vel(state.GetData() + 1, dim);
|
||||
const double den_energy = state(1 + dim);
|
||||
|
||||
MFEM_ASSERT(StateIsPhysical(state, dim), "");
|
||||
|
||||
const double pres = ComputePressure(state, dim);
|
||||
|
||||
for (int d = 0; d < dim; d++)
|
||||
{
|
||||
flux(0, d) = den_vel(d);
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
flux(1+i, d) = den_vel(i) * den_vel(d) / den;
|
||||
}
|
||||
flux(1+d, d) += pres;
|
||||
}
|
||||
|
||||
const double H = (den_energy + pres) / den;
|
||||
for (int d = 0; d < dim; d++)
|
||||
{
|
||||
flux(1+dim, d) = den_vel(d) * H;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the scalar F(u).n
|
||||
void ComputeFluxDotN(const Vector &state, const Vector &nor,
|
||||
Vector &fluxN)
|
||||
{
|
||||
// NOTE: nor in general is not a unit normal
|
||||
const int dim = nor.Size();
|
||||
const double den = state(0);
|
||||
const Vector den_vel(state.GetData() + 1, dim);
|
||||
const double den_energy = state(1 + dim);
|
||||
|
||||
MFEM_ASSERT(StateIsPhysical(state, dim), "");
|
||||
|
||||
const double pres = ComputePressure(state, dim);
|
||||
|
||||
double den_velN = 0;
|
||||
for (int d = 0; d < dim; d++) { den_velN += den_vel(d) * nor(d); }
|
||||
|
||||
fluxN(0) = den_velN;
|
||||
for (int d = 0; d < dim; d++)
|
||||
{
|
||||
fluxN(1+d) = den_velN * den_vel(d) / den + pres * nor(d);
|
||||
}
|
||||
|
||||
const double H = (den_energy + pres) / den;
|
||||
fluxN(1 + dim) = den_velN * H;
|
||||
}
|
||||
|
||||
// Compute the maximum characteristic speed.
|
||||
inline double ComputeMaxCharSpeed(const Vector &state, const int dim)
|
||||
{
|
||||
const double den = state(0);
|
||||
const Vector den_vel(state.GetData() + 1, dim);
|
||||
|
||||
double den_vel2 = 0;
|
||||
for (int d = 0; d < dim; d++) { den_vel2 += den_vel(d) * den_vel(d); }
|
||||
den_vel2 /= den;
|
||||
|
||||
const double pres = ComputePressure(state, dim);
|
||||
const double sound = sqrt(specific_heat_ratio * pres / den);
|
||||
const double vel = sqrt(den_vel2 / den);
|
||||
|
||||
return vel + sound;
|
||||
}
|
||||
|
||||
// Compute the flux at solution nodes.
|
||||
void FE_Evolution::GetFlux(const DenseMatrix &x, DenseTensor &flux) const
|
||||
{
|
||||
const int dof = flux.SizeI();
|
||||
const int dim = flux.SizeJ();
|
||||
|
||||
for (int i = 0; i < dof; i++)
|
||||
{
|
||||
for (int k = 0; k < num_equation; k++) { state(k) = x(i, k); }
|
||||
ComputeFlux(state, dim, f);
|
||||
|
||||
for (int d = 0; d < dim; d++)
|
||||
{
|
||||
for (int k = 0; k < num_equation; k++)
|
||||
{
|
||||
flux(i, d, k) = f(k, d);
|
||||
}
|
||||
}
|
||||
|
||||
// Update max char speed
|
||||
const double mcs = ComputeMaxCharSpeed(state, dim);
|
||||
if (mcs > max_char_speed) { max_char_speed = mcs; }
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of class RiemannSolver
|
||||
RiemannSolver::RiemannSolver() :
|
||||
flux1(num_equation),
|
||||
flux2(num_equation) { }
|
||||
|
||||
double RiemannSolver::Eval(const Vector &state1, const Vector &state2,
|
||||
const Vector &nor, Vector &flux)
|
||||
{
|
||||
// NOTE: nor in general is not a unit normal
|
||||
const int dim = nor.Size();
|
||||
|
||||
MFEM_ASSERT(StateIsPhysical(state1, dim), "");
|
||||
MFEM_ASSERT(StateIsPhysical(state2, dim), "");
|
||||
|
||||
const double maxE1 = ComputeMaxCharSpeed(state1, dim);
|
||||
const double maxE2 = ComputeMaxCharSpeed(state2, dim);
|
||||
|
||||
const double maxE = max(maxE1, maxE2);
|
||||
|
||||
ComputeFluxDotN(state1, nor, flux1);
|
||||
ComputeFluxDotN(state2, nor, flux2);
|
||||
|
||||
double normag = 0;
|
||||
for (int i = 0; i < dim; i++)
|
||||
{
|
||||
normag += nor(i) * nor(i);
|
||||
}
|
||||
normag = sqrt(normag);
|
||||
|
||||
for (int i = 0; i < num_equation; i++)
|
||||
{
|
||||
flux(i) = 0.5 * (flux1(i) + flux2(i))
|
||||
- 0.5 * maxE * (state2(i) - state1(i)) * normag;
|
||||
}
|
||||
|
||||
return maxE;
|
||||
}
|
||||
|
||||
// Implementation of class DomainIntegrator
|
||||
DomainIntegrator::DomainIntegrator(const int dim) : flux(num_equation, dim) { }
|
||||
|
||||
void DomainIntegrator::AssembleElementMatrix2(const FiniteElement &trial_fe,
|
||||
const FiniteElement &test_fe,
|
||||
ElementTransformation &Tr,
|
||||
DenseMatrix &elmat)
|
||||
{
|
||||
// Assemble the form (vec(v), grad(w))
|
||||
|
||||
// Trial space = vector L2 space (mesh dim)
|
||||
// Test space = scalar L2 space
|
||||
|
||||
const int dof_trial = trial_fe.GetDof();
|
||||
const int dof_test = test_fe.GetDof();
|
||||
const int dim = trial_fe.GetDim();
|
||||
|
||||
shape.SetSize(dof_trial);
|
||||
dshapedr.SetSize(dof_test, dim);
|
||||
dshapedx.SetSize(dof_test, dim);
|
||||
|
||||
elmat.SetSize(dof_test, dof_trial * dim);
|
||||
elmat = 0.0;
|
||||
|
||||
const int maxorder = max(trial_fe.GetOrder(), test_fe.GetOrder());
|
||||
const int intorder = 2 * maxorder;
|
||||
const IntegrationRule *ir = &IntRules.Get(trial_fe.GetGeomType(), intorder);
|
||||
|
||||
for (int i = 0; i < ir->GetNPoints(); i++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(i);
|
||||
|
||||
// Calculate the shape functions
|
||||
trial_fe.CalcShape(ip, shape);
|
||||
shape *= ip.weight;
|
||||
|
||||
// Compute the physical gradients of the test functions
|
||||
Tr.SetIntPoint(&ip);
|
||||
test_fe.CalcDShape(ip, dshapedr);
|
||||
Mult(dshapedr, Tr.AdjugateJacobian(), dshapedx);
|
||||
|
||||
for (int d = 0; d < dim; d++)
|
||||
{
|
||||
for (int j = 0; j < dof_test; j++)
|
||||
{
|
||||
for (int k = 0; k < dof_trial; k++)
|
||||
{
|
||||
elmat(j, k + d * dof_trial) += shape(k) * dshapedx(j, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of class FaceIntegrator
|
||||
FaceIntegrator::FaceIntegrator(RiemannSolver &rsolver_, const int dim) :
|
||||
rsolver(rsolver_),
|
||||
funval1(num_equation),
|
||||
funval2(num_equation),
|
||||
nor(dim),
|
||||
fluxN(num_equation) { }
|
||||
|
||||
void FaceIntegrator::AssembleFaceVector(const FiniteElement &el1,
|
||||
const FiniteElement &el2,
|
||||
FaceElementTransformations &Tr,
|
||||
const Vector &elfun, Vector &elvect)
|
||||
{
|
||||
// Compute the term <F.n(u),[w]> on the interior faces.
|
||||
const int dof1 = el1.GetDof();
|
||||
const int dof2 = el2.GetDof();
|
||||
|
||||
shape1.SetSize(dof1);
|
||||
shape2.SetSize(dof2);
|
||||
|
||||
elvect.SetSize((dof1 + dof2) * num_equation);
|
||||
elvect = 0.0;
|
||||
|
||||
DenseMatrix elfun1_mat(elfun.GetData(), dof1, num_equation);
|
||||
DenseMatrix elfun2_mat(elfun.GetData() + dof1 * num_equation, dof2,
|
||||
num_equation);
|
||||
|
||||
DenseMatrix elvect1_mat(elvect.GetData(), dof1, num_equation);
|
||||
DenseMatrix elvect2_mat(elvect.GetData() + dof1 * num_equation, dof2,
|
||||
num_equation);
|
||||
|
||||
// Integration order calculation from DGTraceIntegrator
|
||||
int intorder;
|
||||
if (Tr.Elem2No >= 0)
|
||||
intorder = (min(Tr.Elem1->OrderW(), Tr.Elem2->OrderW()) +
|
||||
2*max(el1.GetOrder(), el2.GetOrder()));
|
||||
else
|
||||
{
|
||||
intorder = Tr.Elem1->OrderW() + 2*el1.GetOrder();
|
||||
}
|
||||
if (el1.Space() == FunctionSpace::Pk)
|
||||
{
|
||||
intorder++;
|
||||
}
|
||||
const IntegrationRule *ir = &IntRules.Get(Tr.FaceGeom, intorder);
|
||||
|
||||
for (int i = 0; i < ir->GetNPoints(); i++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir->IntPoint(i);
|
||||
|
||||
Tr.Loc1.Transform(ip, eip1);
|
||||
Tr.Loc2.Transform(ip, eip2);
|
||||
|
||||
// Calculate basis functions on both elements at the face
|
||||
el1.CalcShape(eip1, shape1);
|
||||
el2.CalcShape(eip2, shape2);
|
||||
|
||||
// Interpolate elfun at the point
|
||||
elfun1_mat.MultTranspose(shape1, funval1);
|
||||
elfun2_mat.MultTranspose(shape2, funval2);
|
||||
|
||||
Tr.Face->SetIntPoint(&ip);
|
||||
|
||||
// Get the normal vector and the flux on the face
|
||||
CalcOrtho(Tr.Face->Jacobian(), nor);
|
||||
const double mcs = rsolver.Eval(funval1, funval2, nor, fluxN);
|
||||
|
||||
// Update max char speed
|
||||
if (mcs > max_char_speed) { max_char_speed = mcs; }
|
||||
|
||||
fluxN *= ip.weight;
|
||||
for (int k = 0; k < num_equation; k++)
|
||||
{
|
||||
for (int s = 0; s < dof1; s++)
|
||||
{
|
||||
elvect1_mat(s, k) -= fluxN(k) * shape1(s);
|
||||
}
|
||||
for (int s = 0; s < dof2; s++)
|
||||
{
|
||||
elvect2_mat(s, k) += fluxN(k) * shape2(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the state is physical - enabled in debug mode
|
||||
bool StateIsPhysical(const Vector &state, const int dim)
|
||||
{
|
||||
const double den = state(0);
|
||||
const Vector den_vel(state.GetData() + 1, dim);
|
||||
const double den_energy = state(1 + dim);
|
||||
|
||||
if (den < 0)
|
||||
{
|
||||
cout << "Negative density: ";
|
||||
for (int i = 0; i < state.Size(); i++)
|
||||
{
|
||||
cout << state(i) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
return false;
|
||||
}
|
||||
if (den_energy <= 0)
|
||||
{
|
||||
cout << "Negative energy: ";
|
||||
for (int i = 0; i < state.Size(); i++)
|
||||
{
|
||||
cout << state(i) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
double den_vel2 = 0;
|
||||
for (int i = 0; i < dim; i++) { den_vel2 += den_vel(i) * den_vel(i); }
|
||||
den_vel2 /= den;
|
||||
|
||||
const double pres = (specific_heat_ratio - 1.0) * (den_energy - 0.5 * den_vel2);
|
||||
|
||||
if (pres <= 0)
|
||||
{
|
||||
cout << "Negative pressure: " << pres << ", state: ";
|
||||
for (int i = 0; i < state.Size(); i++)
|
||||
{
|
||||
cout << state(i) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initial condition
|
||||
void InitialCondition(const Vector &x, Vector &y)
|
||||
{
|
||||
MFEM_ASSERT(x.Size() == 2, "");
|
||||
|
||||
double radius = 0, Minf = 0, beta = 0;
|
||||
if (problem == 1)
|
||||
{
|
||||
// "Fast vortex"
|
||||
radius = 0.2;
|
||||
Minf = 0.5;
|
||||
beta = 1. / 5.;
|
||||
}
|
||||
else if (problem == 2)
|
||||
{
|
||||
// "Slow vortex"
|
||||
radius = 0.2;
|
||||
Minf = 0.05;
|
||||
beta = 1. / 50.;
|
||||
}
|
||||
else
|
||||
{
|
||||
mfem_error("Cannot recognize problem."
|
||||
"Options are: 1 - fast vortex, 2 - slow vortex");
|
||||
}
|
||||
|
||||
const double xc = 0.0, yc = 0.0;
|
||||
|
||||
// Nice units
|
||||
const double vel_inf = 1.;
|
||||
const double den_inf = 1.;
|
||||
|
||||
// Derive remainder of background state from this and Minf
|
||||
const double pres_inf = (den_inf / specific_heat_ratio) * (vel_inf / Minf) *
|
||||
(vel_inf / Minf);
|
||||
const double temp_inf = pres_inf / (den_inf * gas_constant);
|
||||
|
||||
double r2rad = 0.0;
|
||||
r2rad += (x(0) - xc) * (x(0) - xc);
|
||||
r2rad += (x(1) - yc) * (x(1) - yc);
|
||||
r2rad /= (radius * radius);
|
||||
|
||||
const double shrinv1 = 1.0 / (specific_heat_ratio - 1.);
|
||||
|
||||
const double velX = vel_inf * (1 - beta * (x(1) - yc) / radius * exp(
|
||||
-0.5 * r2rad));
|
||||
const double velY = vel_inf * beta * (x(0) - xc) / radius * exp(-0.5 * r2rad);
|
||||
const double vel2 = velX * velX + velY * velY;
|
||||
|
||||
const double specific_heat = gas_constant * specific_heat_ratio * shrinv1;
|
||||
const double temp = temp_inf - 0.5 * (vel_inf * beta) *
|
||||
(vel_inf * beta) / specific_heat * exp(-r2rad);
|
||||
|
||||
const double den = den_inf * pow(temp/temp_inf, shrinv1);
|
||||
const double pres = den * gas_constant * temp;
|
||||
const double energy = shrinv1 * pres / den + 0.5 * vel2;
|
||||
|
||||
y(0) = den;
|
||||
y(1) = den * velX;
|
||||
y(2) = den * velY;
|
||||
y(3) = den * energy;
|
||||
}
|
||||
@@ -1,364 +0,0 @@
|
||||
// MFEM Example 18 - Parallel Version
|
||||
//
|
||||
// Compile with: make ex18
|
||||
//
|
||||
// Sample runs:
|
||||
//
|
||||
// mpirun -np 4 ex18p -p 1 -rs 2 -rp 1 -o 1 -s 3
|
||||
// mpirun -np 4 ex18p -p 1 -rs 1 -rp 1 -o 3 -s 4
|
||||
// mpirun -np 4 ex18p -p 1 -rs 1 -rp 1 -o 5 -s 6
|
||||
// mpirun -np 4 ex18p -p 2 -rs 1 -rp 1 -o 1 -s 3
|
||||
// mpirun -np 4 ex18p -p 2 -rs 1 -rp 1 -o 3 -s 3
|
||||
//
|
||||
// Description: This example code solves the compressible Euler system of
|
||||
// equations, a model nonlinear hyperbolic PDE, with a
|
||||
// discontinuous Galerkin (DG) formulation.
|
||||
//
|
||||
// Specifically, it solves for an exact solution of the equations
|
||||
// whereby a vortex is transported by a uniform flow. Since all
|
||||
// boundaries are periodic here, the method's accuracy can be
|
||||
// assessed by measuring the difference between the solution and
|
||||
// the initial condition at a later time when the vortex returns
|
||||
// to its initial location.
|
||||
//
|
||||
// Note that as the order of the spatial discretization increases,
|
||||
// the timestep must become smaller. This example currently uses a
|
||||
// simple estimate derived by Cockburn and Shu for the 1D RKDG
|
||||
// method. An additional factor can be tuned by passing the --cfl
|
||||
// (or -c shorter) flag.
|
||||
//
|
||||
// The example demonstrates user-defined bilinear and nonlinear
|
||||
// form integrators for systems of equations that are defined with
|
||||
// block vectors, and how these are used with an operator for
|
||||
// explicit time integrators. In this case the system also
|
||||
// involves an external approximate Riemann solver for the DG
|
||||
// interface flux. It also demonstrates how to use GLVis for
|
||||
// in-situ visualization of vector grid functions.
|
||||
//
|
||||
// We recommend viewing examples 9, 14 and 17 before viewing this
|
||||
// example.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
// Classes FE_Evolution, RiemannSolver, DomainIntegrator and FaceIntegrator
|
||||
// shared between the serial and parallel version of the example.
|
||||
#include "ex18.hpp"
|
||||
|
||||
// Choice for the problem setup. See InitialCondition in ex18.hpp.
|
||||
int problem;
|
||||
|
||||
// Equation constant parameters.
|
||||
const int num_equation = 4;
|
||||
const double specific_heat_ratio = 1.4;
|
||||
const double gas_constant = 1.0;
|
||||
|
||||
// Maximum characteristic speed (updated by integrators)
|
||||
double max_char_speed;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Initialize MPI.
|
||||
MPI_Session mpi(argc, argv);
|
||||
|
||||
// 2. Parse command-line options.
|
||||
problem = 1;
|
||||
const char *mesh_file = "../data/periodic-square.mesh";
|
||||
int ser_ref_levels = 0;
|
||||
int par_ref_levels = 1;
|
||||
int order = 3;
|
||||
int ode_solver_type = 4;
|
||||
double t_final = 2.0;
|
||||
double dt = -0.01;
|
||||
double cfl = 0.3;
|
||||
bool visualization = true;
|
||||
int vis_steps = 50;
|
||||
|
||||
int precision = 8;
|
||||
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 before parallel"
|
||||
" partitioning, -1 for auto.");
|
||||
args.AddOption(&par_ref_levels, "-rp", "--refine-parallel",
|
||||
"Number of times to refine the mesh uniformly after parallel"
|
||||
" partitioning.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Order (degree) of the finite elements.");
|
||||
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
|
||||
"ODE solver: 1 - Forward Euler,\n\t"
|
||||
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
|
||||
args.AddOption(&t_final, "-tf", "--t-final",
|
||||
"Final time; start time is 0.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
"Time step. Positive number skips CFL timestep calculation.");
|
||||
args.AddOption(&cfl, "-c", "--cfl-number",
|
||||
"CFL number for timestep calculation.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.AddOption(&vis_steps, "-vs", "--visualization-steps",
|
||||
"Visualize every n-th timestep.");
|
||||
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
if (mpi.Root()) { args.PrintUsage(cout); }
|
||||
return 1;
|
||||
}
|
||||
if (mpi.Root()) { args.PrintOptions(cout); }
|
||||
|
||||
// 3. Read the mesh from the given mesh file. This example requires a 2D
|
||||
// periodic mesh, such as ../data/periodic-square.mesh.
|
||||
Mesh mesh(mesh_file, 1, 1);
|
||||
const int dim = mesh.Dimension();
|
||||
|
||||
MFEM_ASSERT(dim == 2, "Need a two-dimensional mesh for the problem definition");
|
||||
|
||||
// 4. Define the ODE solver used for time integration. Several explicit
|
||||
// Runge-Kutta methods are available.
|
||||
ODESolver *ode_solver = NULL;
|
||||
switch (ode_solver_type)
|
||||
{
|
||||
case 1: ode_solver = new ForwardEulerSolver; break;
|
||||
case 2: ode_solver = new RK2Solver(1.0); break;
|
||||
case 3: ode_solver = new RK3SSPSolver; break;
|
||||
case 4: ode_solver = new RK4Solver; break;
|
||||
case 6: ode_solver = new RK6Solver; break;
|
||||
default:
|
||||
if (mpi.Root())
|
||||
{
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
// 5. Refine the mesh in serial to increase the resolution. In this example
|
||||
// we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
|
||||
// a command-line parameter.
|
||||
for (int lev = 0; lev < ser_ref_levels; lev++)
|
||||
{
|
||||
mesh.UniformRefinement();
|
||||
}
|
||||
|
||||
// 6. Define a 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(MPI_COMM_WORLD, mesh);
|
||||
mesh.Clear();
|
||||
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.
|
||||
DG_FECollection fec(order, dim);
|
||||
// Finite element space for a scalar (thermodynamic quantity)
|
||||
ParFiniteElementSpace fes(&pmesh, &fec);
|
||||
// Finite element space for a mesh-dim vector quantity (momentum)
|
||||
ParFiniteElementSpace dfes(&pmesh, &fec, dim, Ordering::byNODES);
|
||||
// Finite element space for all variables together (total thermodynamic state)
|
||||
ParFiniteElementSpace vfes(&pmesh, &fec, num_equation, Ordering::byNODES);
|
||||
|
||||
// This example depends on this ordering of the space.
|
||||
MFEM_ASSERT(fes.GetOrdering() == Ordering::byNODES, "");
|
||||
|
||||
HYPRE_Int glob_size = vfes.GlobalTrueVSize();
|
||||
if (mpi.Root()) { cout << "Number of unknowns: " << glob_size << endl; }
|
||||
|
||||
// 8. Define the initial conditions, save the corresponding mesh and grid
|
||||
// functions to a file. This can be opened with GLVis with the -gc option.
|
||||
|
||||
// The solution u has components {density, x-momentum, y-momentum, energy}.
|
||||
// These are stored contiguously in the BlockVector u_block.
|
||||
Array<int> offsets(num_equation + 1);
|
||||
for (int k = 0; k <= num_equation; k++) { offsets[k] = k * vfes.GetNDofs(); }
|
||||
BlockVector u_block(offsets);
|
||||
|
||||
// Momentum grid function on dfes for visualization.
|
||||
ParGridFunction mom(&dfes, u_block.GetData() + offsets[1]);
|
||||
|
||||
// Initialize the state.
|
||||
VectorFunctionCoefficient u0(num_equation, InitialCondition);
|
||||
ParGridFunction sol(&vfes, u_block.GetData());
|
||||
sol.ProjectCoefficient(u0);
|
||||
|
||||
// Output the initial solution.
|
||||
{
|
||||
ostringstream mesh_name;
|
||||
mesh_name << "vortex-mesh." << setfill('0') << setw(6) << mpi.WorldRank();
|
||||
ofstream mesh_ofs(mesh_name.str().c_str());
|
||||
mesh_ofs.precision(precision);
|
||||
mesh_ofs << pmesh;
|
||||
|
||||
for (int k = 0; k < num_equation; k++)
|
||||
{
|
||||
ParGridFunction uk(&fes, u_block.GetBlock(k));
|
||||
ostringstream sol_name;
|
||||
sol_name << "vortex-" << k << "-init."
|
||||
<< setfill('0') << setw(6) << mpi.WorldRank();
|
||||
ofstream sol_ofs(sol_name.str().c_str());
|
||||
sol_ofs.precision(precision);
|
||||
sol_ofs << uk;
|
||||
}
|
||||
}
|
||||
|
||||
// 9. Set up the nonlinear form corresponding to the DG discretization of the
|
||||
// flux divergence, and assemble the corresponding mass matrix.
|
||||
MixedBilinearForm Aflux(&dfes, &fes);
|
||||
Aflux.AddDomainIntegrator(new DomainIntegrator(dim));
|
||||
Aflux.Assemble();
|
||||
|
||||
ParNonlinearForm A(&vfes);
|
||||
RiemannSolver rsolver;
|
||||
A.AddInteriorFaceIntegrator(new FaceIntegrator(rsolver, dim));
|
||||
|
||||
// 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).
|
||||
FE_Evolution euler(vfes, A, Aflux.SpMat());
|
||||
|
||||
// Visualize the density
|
||||
socketstream sout;
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
|
||||
MPI_Barrier(pmesh.GetComm());
|
||||
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 " << mpi.WorldSize() << " " << mpi.WorldRank() << "\n";
|
||||
sout.precision(precision);
|
||||
sout << "solution\n" << pmesh << mom;
|
||||
sout << "pause\n";
|
||||
sout << flush;
|
||||
if (mpi.Root())
|
||||
{
|
||||
cout << "GLVis visualization paused."
|
||||
<< " Press space (in the GLVis window) to resume it.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the minimum element size.
|
||||
double hmin;
|
||||
if (cfl > 0)
|
||||
{
|
||||
double my_hmin = pmesh.GetElementSize(0, 1);
|
||||
for (int i = 1; i < pmesh.GetNE(); i++)
|
||||
{
|
||||
my_hmin = min(pmesh.GetElementSize(i, 1), my_hmin);
|
||||
}
|
||||
// Reduce to find the global minimum element size
|
||||
MPI_Allreduce(&my_hmin, &hmin, 1, MPI_DOUBLE, MPI_MIN, pmesh.GetComm());
|
||||
}
|
||||
|
||||
// Start the timer.
|
||||
tic_toc.Clear();
|
||||
tic_toc.Start();
|
||||
|
||||
double t = 0.0;
|
||||
euler.SetTime(t);
|
||||
ode_solver->Init(euler);
|
||||
|
||||
if (cfl > 0)
|
||||
{
|
||||
// Find a safe dt, using a temporary vector. Calling Mult() computes the
|
||||
// maximum char speed at all quadrature points on all faces.
|
||||
max_char_speed = 0.;
|
||||
Vector z(sol.Size());
|
||||
A.Mult(sol, z);
|
||||
// Reduce to find the global maximum wave speed
|
||||
{
|
||||
double all_max_char_speed;
|
||||
MPI_Allreduce(&max_char_speed, &all_max_char_speed,
|
||||
1, MPI_DOUBLE, MPI_MAX, pmesh.GetComm());
|
||||
max_char_speed = all_max_char_speed;
|
||||
}
|
||||
dt = cfl * hmin / max_char_speed / (2*order+1);
|
||||
}
|
||||
|
||||
// Integrate in time.
|
||||
bool done = false;
|
||||
for (int ti = 0; !done; )
|
||||
{
|
||||
double dt_real = min(dt, t_final - t);
|
||||
|
||||
ode_solver->Step(sol, t, dt_real);
|
||||
if (cfl > 0)
|
||||
{
|
||||
// Reduce to find the global maximum wave speed
|
||||
{
|
||||
double all_max_char_speed;
|
||||
MPI_Allreduce(&max_char_speed, &all_max_char_speed,
|
||||
1, MPI_DOUBLE, MPI_MAX, pmesh.GetComm());
|
||||
max_char_speed = all_max_char_speed;
|
||||
}
|
||||
dt = cfl * hmin / max_char_speed / (2*order+1);
|
||||
}
|
||||
ti++;
|
||||
|
||||
done = (t >= t_final - 1e-8*dt);
|
||||
if (done || ti % vis_steps == 0)
|
||||
{
|
||||
if (mpi.Root())
|
||||
{
|
||||
cout << "time step: " << ti << ", time: " << t << endl;
|
||||
}
|
||||
if (visualization)
|
||||
{
|
||||
MPI_Barrier(pmesh.GetComm());
|
||||
sout << "parallel " << mpi.WorldSize() << " " << mpi.WorldRank() << "\n";
|
||||
sout << "solution\n" << pmesh << mom << flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tic_toc.Stop();
|
||||
if (mpi.Root()) { cout << " done, " << tic_toc.RealTime() << "s." << endl; }
|
||||
|
||||
// 11. Save the final solution. This output can be viewed later using GLVis:
|
||||
// "glvis -np 4 -m vortex-mesh -g vortex-1-final".
|
||||
for (int k = 0; k < num_equation; k++)
|
||||
{
|
||||
ParGridFunction uk(&fes, u_block.GetBlock(k));
|
||||
ostringstream sol_name;
|
||||
sol_name << "vortex-" << k << "-final."
|
||||
<< setfill('0') << setw(6) << mpi.WorldRank();
|
||||
ofstream sol_ofs(sol_name.str().c_str());
|
||||
sol_ofs.precision(precision);
|
||||
sol_ofs << uk;
|
||||
}
|
||||
|
||||
// 12. Compute the L2 solution error summed for all components.
|
||||
if (t_final == 2.0)
|
||||
{
|
||||
const double error = sol.ComputeLpError(2, u0);
|
||||
if (mpi.Root()) { cout << "Solution error: " << error << endl; }
|
||||
}
|
||||
|
||||
// Free the used memory.
|
||||
delete ode_solver;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,538 +0,0 @@
|
||||
// MFEM Example 19
|
||||
//
|
||||
// Compile with: make ex19
|
||||
//
|
||||
// Sample runs:
|
||||
// ex19 -m ../data/beam-quad.mesh
|
||||
// ex19 -m ../data/beam-tri.mesh
|
||||
// ex19 -m ../data/beam-hex.mesh
|
||||
// ex19 -m ../data/beam-tet.mesh
|
||||
// ex19 -m ../data/beam-wedge.mesh
|
||||
//
|
||||
// Description: This examples solves a quasi-static incompressible nonlinear
|
||||
// elasticity problem of the form 0 = H(x), where H is an
|
||||
// incompressible hyperelastic model and x is a block state vector
|
||||
// containing displacement and pressure variables. The geometry of
|
||||
// the domain is assumed to be as follows:
|
||||
//
|
||||
// +---------------------+
|
||||
// boundary --->| |<--- boundary
|
||||
// attribute 1 | | attribute 2
|
||||
// (fixed) +---------------------+ (fixed, nonzero)
|
||||
//
|
||||
// The example demonstrates the use of block nonlinear operators
|
||||
// (the class RubberOperator defining H(x)) as well as a nonlinear
|
||||
// Newton solver for the quasi-static problem. Each Newton step
|
||||
// requires the inversion of a Jacobian matrix, which is done
|
||||
// through a (preconditioned) inner solver. The specialized block
|
||||
// preconditioner is implemented as a user-defined solver.
|
||||
//
|
||||
// We recommend viewing examples 2, 5, and 10 before viewing this
|
||||
// example.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// Custom block preconditioner for the Jacobian of the incompressible nonlinear
|
||||
// elasticity operator. It has the form
|
||||
//
|
||||
// P^-1 = [ K^-1 0 ][ I -B^T ][ I 0 ]
|
||||
// [ 0 I ][ 0 I ][ 0 -\gamma S^-1 ]
|
||||
//
|
||||
// where the original Jacobian has the form
|
||||
//
|
||||
// J = [ K B^T ]
|
||||
// [ B 0 ]
|
||||
//
|
||||
// and K^-1 is an approximation of the inverse of the displacement part of the
|
||||
// Jacobian and S^-1 is an approximation of the inverse of the Schur
|
||||
// complement S = B K^-1 B^T. The Schur complement is approximated using
|
||||
// a mass matrix of the pressure variables.
|
||||
class JacobianPreconditioner : public Solver
|
||||
{
|
||||
protected:
|
||||
// Finite element spaces for setting up preconditioner blocks
|
||||
Array<FiniteElementSpace *> spaces;
|
||||
|
||||
// Offsets for extracting block vector segments
|
||||
Array<int> &block_offsets;
|
||||
|
||||
// Jacobian for block access
|
||||
BlockOperator *jacobian;
|
||||
|
||||
// Scaling factor for the pressure mass matrix in the block preconditioner
|
||||
double gamma;
|
||||
|
||||
// Objects for the block preconditioner application
|
||||
SparseMatrix *pressure_mass;
|
||||
Solver *mass_pcg;
|
||||
Solver *mass_prec;
|
||||
Solver *stiff_pcg;
|
||||
Solver *stiff_prec;
|
||||
|
||||
public:
|
||||
JacobianPreconditioner(Array<FiniteElementSpace *> &fes,
|
||||
SparseMatrix &mass, Array<int> &offsets);
|
||||
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
virtual void SetOperator(const Operator &op);
|
||||
|
||||
virtual ~JacobianPreconditioner();
|
||||
};
|
||||
|
||||
// After spatial discretization, the rubber model can be written as:
|
||||
// 0 = H(x)
|
||||
// where x is the block vector representing the deformation and pressure and
|
||||
// H(x) is the nonlinear incompressible neo-Hookean operator.
|
||||
class RubberOperator : public Operator
|
||||
{
|
||||
protected:
|
||||
// Finite element spaces
|
||||
Array<FiniteElementSpace *> spaces;
|
||||
|
||||
// Block nonlinear form
|
||||
BlockNonlinearForm *Hform;
|
||||
|
||||
// Pressure mass matrix for the preconditioner
|
||||
SparseMatrix *pressure_mass;
|
||||
|
||||
// Newton solver for the hyperelastic operator
|
||||
NewtonSolver newton_solver;
|
||||
|
||||
// Solver for the Jacobian solve in the Newton method
|
||||
Solver *j_solver;
|
||||
|
||||
// Preconditioner for the Jacobian
|
||||
Solver *j_prec;
|
||||
|
||||
// Shear modulus coefficient
|
||||
Coefficient μ
|
||||
|
||||
// Block offsets for variable access
|
||||
Array<int> &block_offsets;
|
||||
|
||||
public:
|
||||
RubberOperator(Array<FiniteElementSpace *> &fes, Array<Array<int> *>&ess_bdr,
|
||||
Array<int> &block_trueOffsets, double rel_tol, double abs_tol,
|
||||
int iter, Coefficient &mu);
|
||||
|
||||
// Required to use the native newton solver
|
||||
virtual Operator &GetGradient(const Vector &xp) const;
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
|
||||
// Driver for the newton solver
|
||||
void Solve(Vector &xp) const;
|
||||
|
||||
virtual ~RubberOperator();
|
||||
};
|
||||
|
||||
// Visualization driver
|
||||
void visualize(ostream &out, Mesh *mesh, GridFunction *deformed_nodes,
|
||||
GridFunction *field, const char *field_name = NULL,
|
||||
bool init_vis = false);
|
||||
|
||||
// Configuration definition functions
|
||||
void ReferenceConfiguration(const Vector &x, Vector &y);
|
||||
void InitialDeformation(const Vector &x, Vector &y);
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Parse command-line options
|
||||
const char *mesh_file = "../data/beam-hex.mesh";
|
||||
int ref_levels = 0;
|
||||
int order = 2;
|
||||
bool visualization = true;
|
||||
double newton_rel_tol = 1e-4;
|
||||
double newton_abs_tol = 1e-6;
|
||||
int newton_iter = 500;
|
||||
double mu = 1.0;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&ref_levels, "-r", "--refine",
|
||||
"Number of times to refine the mesh uniformly.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Order (degree) of the finite elements.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.AddOption(&newton_rel_tol, "-rel", "--relative-tolerance",
|
||||
"Relative tolerance for the Newton solve.");
|
||||
args.AddOption(&newton_abs_tol, "-abs", "--absolute-tolerance",
|
||||
"Absolute tolerance for the Newton solve.");
|
||||
args.AddOption(&newton_iter, "-it", "--newton-iterations",
|
||||
"Maximum iterations for the Newton solve.");
|
||||
args.AddOption(&mu, "-mu", "--shear-modulus",
|
||||
"Shear modulus for the neo-Hookean material.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
return 1;
|
||||
}
|
||||
args.PrintOptions(cout);
|
||||
|
||||
// 2. Read the mesh from the given mesh file. We can handle triangular,
|
||||
// quadrilateral, tetrahedral and hexahedral meshes with the same code.
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
int dim = mesh->Dimension();
|
||||
|
||||
// 3. 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();
|
||||
}
|
||||
|
||||
// 4. Define the shear modulus for the incompressible Neo-Hookean material
|
||||
ConstantCoefficient c_mu(mu);
|
||||
|
||||
// 5. Define the finite element spaces for displacement and pressure
|
||||
// (Taylor-Hood elements). By default, the displacement (u/x) is a second
|
||||
// order vector field, while the pressure (p) is a linear scalar function.
|
||||
H1_FECollection quad_coll(order, dim);
|
||||
H1_FECollection lin_coll(order-1, dim);
|
||||
|
||||
FiniteElementSpace R_space(mesh, &quad_coll, dim, Ordering::byVDIM);
|
||||
FiniteElementSpace W_space(mesh, &lin_coll);
|
||||
|
||||
Array<FiniteElementSpace *> spaces(2);
|
||||
spaces[0] = &R_space;
|
||||
spaces[1] = &W_space;
|
||||
|
||||
int R_size = R_space.GetVSize();
|
||||
int W_size = W_space.GetVSize();
|
||||
|
||||
// 6. Define the Dirichlet conditions (set to boundary attribute 1 and 2)
|
||||
Array<Array<int> *> ess_bdr(2);
|
||||
|
||||
Array<int> ess_bdr_u(R_space.GetMesh()->bdr_attributes.Max());
|
||||
Array<int> ess_bdr_p(W_space.GetMesh()->bdr_attributes.Max());
|
||||
|
||||
ess_bdr_p = 0;
|
||||
ess_bdr_u = 0;
|
||||
ess_bdr_u[0] = 1;
|
||||
ess_bdr_u[1] = 1;
|
||||
|
||||
ess_bdr[0] = &ess_bdr_u;
|
||||
ess_bdr[1] = &ess_bdr_p;
|
||||
|
||||
// 7. Print the mesh statistics
|
||||
std::cout << "***********************************************************\n";
|
||||
std::cout << "dim(u) = " << R_size << "\n";
|
||||
std::cout << "dim(p) = " << W_size << "\n";
|
||||
std::cout << "dim(u+p) = " << R_size + W_size << "\n";
|
||||
std::cout << "***********************************************************\n";
|
||||
|
||||
// 8. Define the block structure of the solution vector (u then p)
|
||||
Array<int> block_offsets(3);
|
||||
block_offsets[0] = 0;
|
||||
block_offsets[1] = R_space.GetVSize();
|
||||
block_offsets[2] = W_space.GetVSize();
|
||||
block_offsets.PartialSum();
|
||||
|
||||
BlockVector xp(block_offsets);
|
||||
|
||||
// 9. Define grid functions for the current configuration, reference
|
||||
// configuration, final deformation, and pressure
|
||||
GridFunction x_gf(&R_space);
|
||||
GridFunction x_ref(&R_space);
|
||||
GridFunction x_def(&R_space);
|
||||
GridFunction p_gf(&W_space);
|
||||
|
||||
x_gf.MakeRef(&R_space, xp.GetBlock(0), 0);
|
||||
p_gf.MakeRef(&W_space, xp.GetBlock(1), 0);
|
||||
|
||||
VectorFunctionCoefficient deform(dim, InitialDeformation);
|
||||
VectorFunctionCoefficient refconfig(dim, ReferenceConfiguration);
|
||||
|
||||
x_gf.ProjectCoefficient(deform);
|
||||
x_ref.ProjectCoefficient(refconfig);
|
||||
p_gf = 0.0;
|
||||
|
||||
// 10. Initialize the incompressible neo-Hookean operator
|
||||
RubberOperator oper(spaces, ess_bdr, block_offsets,
|
||||
newton_rel_tol, newton_abs_tol, newton_iter, c_mu);
|
||||
|
||||
// 11. Solve the Newton system
|
||||
oper.Solve(xp);
|
||||
|
||||
// 12. Compute the final deformation
|
||||
subtract(x_gf, x_ref, x_def);
|
||||
|
||||
// 13. Visualize the results if requested
|
||||
socketstream vis_u, vis_p;
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
vis_u.open(vishost, visport);
|
||||
vis_u.precision(8);
|
||||
visualize(vis_u, mesh, &x_gf, &x_def, "Deformation", true);
|
||||
vis_p.open(vishost, visport);
|
||||
vis_p.precision(8);
|
||||
visualize(vis_p, mesh, &x_gf, &p_gf, "Pressure", true);
|
||||
}
|
||||
|
||||
// 14. Save the displaced mesh, the final deformation, and the pressure
|
||||
{
|
||||
GridFunction *nodes = &x_gf;
|
||||
int owns_nodes = 0;
|
||||
mesh->SwapNodes(nodes, owns_nodes);
|
||||
|
||||
ofstream mesh_ofs("deformed.mesh");
|
||||
mesh_ofs.precision(8);
|
||||
mesh->Print(mesh_ofs);
|
||||
|
||||
ofstream pressure_ofs("pressure.sol");
|
||||
pressure_ofs.precision(8);
|
||||
p_gf.Save(pressure_ofs);
|
||||
|
||||
ofstream deformation_ofs("deformation.sol");
|
||||
deformation_ofs.precision(8);
|
||||
x_def.Save(deformation_ofs);
|
||||
}
|
||||
|
||||
// 15. Free the used memory
|
||||
delete mesh;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
JacobianPreconditioner::JacobianPreconditioner(Array<FiniteElementSpace *> &fes,
|
||||
SparseMatrix &mass,
|
||||
Array<int> &offsets)
|
||||
: Solver(offsets[2]), block_offsets(offsets), pressure_mass(&mass)
|
||||
{
|
||||
fes.Copy(spaces);
|
||||
|
||||
gamma = 0.00001;
|
||||
|
||||
// The mass matrix and preconditioner do not change every Newton cycle, so we
|
||||
// only need to define them once
|
||||
GSSmoother *mass_prec_gs = new GSSmoother(*pressure_mass);
|
||||
|
||||
mass_prec = mass_prec_gs;
|
||||
|
||||
CGSolver *mass_pcg_iter = new CGSolver();
|
||||
mass_pcg_iter->SetRelTol(1e-12);
|
||||
mass_pcg_iter->SetAbsTol(1e-12);
|
||||
mass_pcg_iter->SetMaxIter(200);
|
||||
mass_pcg_iter->SetPrintLevel(0);
|
||||
mass_pcg_iter->SetPreconditioner(*mass_prec);
|
||||
mass_pcg_iter->SetOperator(*pressure_mass);
|
||||
mass_pcg_iter->iterative_mode = false;
|
||||
|
||||
mass_pcg = mass_pcg_iter;
|
||||
|
||||
// The stiffness matrix does change every Newton cycle, so we will define it
|
||||
// during SetOperator
|
||||
stiff_pcg = NULL;
|
||||
stiff_prec = NULL;
|
||||
}
|
||||
|
||||
void JacobianPreconditioner::Mult(const Vector &k, Vector &y) const
|
||||
{
|
||||
// Extract the blocks from the input and output vectors
|
||||
Vector disp_in(k.GetData() + block_offsets[0],
|
||||
block_offsets[1]-block_offsets[0]);
|
||||
Vector pres_in(k.GetData() + block_offsets[1],
|
||||
block_offsets[2]-block_offsets[1]);
|
||||
|
||||
Vector disp_out(y.GetData() + block_offsets[0],
|
||||
block_offsets[1]-block_offsets[0]);
|
||||
Vector pres_out(y.GetData() + block_offsets[1],
|
||||
block_offsets[2]-block_offsets[1]);
|
||||
|
||||
Vector temp(block_offsets[1]-block_offsets[0]);
|
||||
Vector temp2(block_offsets[1]-block_offsets[0]);
|
||||
|
||||
// Perform the block elimination for the preconditioner
|
||||
mass_pcg->Mult(pres_in, pres_out);
|
||||
pres_out *= -gamma;
|
||||
|
||||
jacobian->GetBlock(0,1).Mult(pres_out, temp);
|
||||
subtract(disp_in, temp, temp2);
|
||||
|
||||
stiff_pcg->Mult(temp2, disp_out);
|
||||
}
|
||||
|
||||
void JacobianPreconditioner::SetOperator(const Operator &op)
|
||||
{
|
||||
jacobian = (BlockOperator *) &op;
|
||||
|
||||
// Initialize the stiffness preconditioner and solver
|
||||
if (stiff_prec == NULL)
|
||||
{
|
||||
GSSmoother *stiff_prec_gs = new GSSmoother();
|
||||
|
||||
stiff_prec = stiff_prec_gs;
|
||||
|
||||
GMRESSolver *stiff_pcg_iter = new GMRESSolver();
|
||||
stiff_pcg_iter->SetRelTol(1e-8);
|
||||
stiff_pcg_iter->SetAbsTol(1e-8);
|
||||
stiff_pcg_iter->SetMaxIter(200);
|
||||
stiff_pcg_iter->SetPrintLevel(0);
|
||||
stiff_pcg_iter->SetPreconditioner(*stiff_prec);
|
||||
stiff_pcg_iter->iterative_mode = false;
|
||||
|
||||
stiff_pcg = stiff_pcg_iter;
|
||||
}
|
||||
|
||||
// At each Newton cycle, compute the new stiffness preconditioner by updating
|
||||
// the iterative solver which, in turn, updates its preconditioner
|
||||
stiff_pcg->SetOperator(jacobian->GetBlock(0,0));
|
||||
}
|
||||
|
||||
JacobianPreconditioner::~JacobianPreconditioner()
|
||||
{
|
||||
delete mass_pcg;
|
||||
delete mass_prec;
|
||||
delete stiff_prec;
|
||||
delete stiff_pcg;
|
||||
}
|
||||
|
||||
|
||||
RubberOperator::RubberOperator(Array<FiniteElementSpace *> &fes,
|
||||
Array<Array<int> *> &ess_bdr,
|
||||
Array<int> &offsets,
|
||||
double rel_tol,
|
||||
double abs_tol,
|
||||
int iter,
|
||||
Coefficient &c_mu)
|
||||
: Operator(fes[0]->GetVSize() + fes[1]->GetVSize()),
|
||||
newton_solver(), mu(c_mu), block_offsets(offsets)
|
||||
{
|
||||
Array<Vector *> rhs(2);
|
||||
rhs = NULL; // Set all entries in the array
|
||||
|
||||
fes.Copy(spaces);
|
||||
|
||||
// Define the block nonlinear form
|
||||
Hform = new BlockNonlinearForm(spaces);
|
||||
|
||||
// Add the incompressible neo-Hookean integrator
|
||||
Hform->AddDomainIntegrator(new IncompressibleNeoHookeanIntegrator(mu));
|
||||
|
||||
// Set the essential boundary conditions
|
||||
Hform->SetEssentialBC(ess_bdr, rhs);
|
||||
|
||||
// Compute the pressure mass stiffness matrix
|
||||
BilinearForm *a = new BilinearForm(spaces[1]);
|
||||
ConstantCoefficient one(1.0);
|
||||
a->AddDomainIntegrator(new MassIntegrator(one));
|
||||
a->Assemble();
|
||||
a->Finalize();
|
||||
pressure_mass = a->LoseMat();
|
||||
delete a;
|
||||
|
||||
// Initialize the Jacobian preconditioner
|
||||
JacobianPreconditioner *jac_prec =
|
||||
new JacobianPreconditioner(fes, *pressure_mass, block_offsets);
|
||||
j_prec = jac_prec;
|
||||
|
||||
// Set up the Jacobian solver
|
||||
GMRESSolver *j_gmres = new GMRESSolver();
|
||||
j_gmres->iterative_mode = false;
|
||||
j_gmres->SetRelTol(1e-12);
|
||||
j_gmres->SetAbsTol(1e-12);
|
||||
j_gmres->SetMaxIter(300);
|
||||
j_gmres->SetPrintLevel(0);
|
||||
j_gmres->SetPreconditioner(*j_prec);
|
||||
j_solver = j_gmres;
|
||||
|
||||
// Set the newton solve parameters
|
||||
newton_solver.iterative_mode = true;
|
||||
newton_solver.SetSolver(*j_solver);
|
||||
newton_solver.SetOperator(*this);
|
||||
newton_solver.SetPrintLevel(1);
|
||||
newton_solver.SetRelTol(rel_tol);
|
||||
newton_solver.SetAbsTol(abs_tol);
|
||||
newton_solver.SetMaxIter(iter);
|
||||
}
|
||||
|
||||
// Solve the Newton system
|
||||
void RubberOperator::Solve(Vector &xp) const
|
||||
{
|
||||
Vector zero;
|
||||
newton_solver.Mult(zero, xp);
|
||||
MFEM_VERIFY(newton_solver.GetConverged(),
|
||||
"Newton Solver did not converge.");
|
||||
}
|
||||
|
||||
// compute: y = H(x,p)
|
||||
void RubberOperator::Mult(const Vector &k, Vector &y) const
|
||||
{
|
||||
Hform->Mult(k, y);
|
||||
}
|
||||
|
||||
// Compute the Jacobian from the nonlinear form
|
||||
Operator &RubberOperator::GetGradient(const Vector &xp) const
|
||||
{
|
||||
return Hform->GetGradient(xp);
|
||||
}
|
||||
|
||||
RubberOperator::~RubberOperator()
|
||||
{
|
||||
delete Hform;
|
||||
delete pressure_mass;
|
||||
delete j_solver;
|
||||
delete j_prec;
|
||||
}
|
||||
|
||||
|
||||
// Inline visualization
|
||||
void visualize(ostream &out, Mesh *mesh, GridFunction *deformed_nodes,
|
||||
GridFunction *field, const char *field_name, bool init_vis)
|
||||
{
|
||||
if (!out)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GridFunction *nodes = deformed_nodes;
|
||||
int owns_nodes = 0;
|
||||
|
||||
mesh->SwapNodes(nodes, owns_nodes);
|
||||
|
||||
out << "solution\n" << *mesh << *field;
|
||||
|
||||
mesh->SwapNodes(nodes, owns_nodes);
|
||||
|
||||
if (init_vis)
|
||||
{
|
||||
out << "window_size 800 800\n";
|
||||
out << "window_title '" << field_name << "'\n";
|
||||
if (mesh->SpaceDimension() == 2)
|
||||
{
|
||||
out << "view 0 0\n"; // view from top
|
||||
out << "keys jlA\n"; // turn off perspective and light, +anti-aliasing
|
||||
}
|
||||
out << "keys cmA\n"; // show colorbar and mesh, +anti-aliasing
|
||||
out << "autoscale value\n"; // update value-range; keep mesh-extents fixed
|
||||
}
|
||||
out << flush;
|
||||
}
|
||||
|
||||
void ReferenceConfiguration(const Vector &x, Vector &y)
|
||||
{
|
||||
// Set the reference, stress free, configuration
|
||||
y = x;
|
||||
}
|
||||
|
||||
void InitialDeformation(const Vector &x, Vector &y)
|
||||
{
|
||||
// Set the initial configuration. Having this different from the reference
|
||||
// configuration can help convergence
|
||||
y = x;
|
||||
y[1] = x[1] + 0.25*x[0];
|
||||
}
|
||||
@@ -1,592 +0,0 @@
|
||||
// MFEM Example 19 - Parallel Version
|
||||
//
|
||||
// Compile with: make ex19p
|
||||
//
|
||||
// Sample runs:
|
||||
// mpirun -np 2 ex19p -m ../data/beam-quad.mesh
|
||||
// mpirun -np 2 ex19p -m ../data/beam-tri.mesh
|
||||
// mpirun -np 2 ex19p -m ../data/beam-hex.mesh
|
||||
// mpirun -np 2 ex19p -m ../data/beam-tet.mesh
|
||||
// mpirun -np 2 ex19p -m ../data/beam-wedge.mesh
|
||||
//
|
||||
// Description: This examples solves a quasi-static incompressible nonlinear
|
||||
// elasticity problem of the form 0 = H(x), where H is an
|
||||
// incompressible hyperelastic model and x is a block state vector
|
||||
// containing displacement and pressure variables. The geometry of
|
||||
// the domain is assumed to be as follows:
|
||||
//
|
||||
// +---------------------+
|
||||
// boundary --->| |<--- boundary
|
||||
// attribute 1 | | attribute 2
|
||||
// (fixed) +---------------------+ (fixed, nonzero)
|
||||
//
|
||||
// The example demonstrates the use of block nonlinear operators
|
||||
// (the class RubberOperator defining H(x)) as well as a nonlinear
|
||||
// Newton solver for the quasi-static problem. Each Newton step
|
||||
// requires the inversion of a Jacobian matrix, which is done
|
||||
// through a (preconditioned) inner solver. The specialized block
|
||||
// preconditioner is implemented as a user-defined solver.
|
||||
//
|
||||
// We recommend viewing examples 2, 5, and 10 before viewing this
|
||||
// example.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// Custom block preconditioner for the Jacobian of the incompressible nonlinear
|
||||
// elasticity operator. It has the form
|
||||
//
|
||||
// P^-1 = [ K^-1 0 ][ I -B^T ][ I 0 ]
|
||||
// [ 0 I ][ 0 I ][ 0 -\gamma S^-1 ]
|
||||
//
|
||||
// where the original Jacobian has the form
|
||||
//
|
||||
// J = [ K B^T ]
|
||||
// [ B 0 ]
|
||||
//
|
||||
// and K^-1 is an approximation of the inverse of the displacement part of the
|
||||
// Jacobian and S^-1 is an approximation of the inverse of the Schur
|
||||
// complement S = B K^-1 B^T. The Schur complement is approximated using
|
||||
// a mass matrix of the pressure variables.
|
||||
class JacobianPreconditioner : public Solver
|
||||
{
|
||||
protected:
|
||||
// Finite element spaces for setting up preconditioner blocks
|
||||
Array<ParFiniteElementSpace *> spaces;
|
||||
|
||||
// Offsets for extracting block vector segments
|
||||
Array<int> &block_trueOffsets;
|
||||
|
||||
// Jacobian for block access
|
||||
BlockOperator *jacobian;
|
||||
|
||||
// Scaling factor for the pressure mass matrix in the block preconditioner
|
||||
double gamma;
|
||||
|
||||
// Objects for the block preconditioner application
|
||||
Operator *pressure_mass;
|
||||
Solver *mass_pcg;
|
||||
Solver *mass_prec;
|
||||
Solver *stiff_pcg;
|
||||
Solver *stiff_prec;
|
||||
|
||||
public:
|
||||
JacobianPreconditioner(Array<ParFiniteElementSpace *> &fes,
|
||||
Operator &mass, Array<int> &offsets);
|
||||
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
virtual void SetOperator(const Operator &op);
|
||||
|
||||
virtual ~JacobianPreconditioner();
|
||||
};
|
||||
|
||||
// After spatial discretization, the rubber model can be written as:
|
||||
// 0 = H(x)
|
||||
// where x is the block vector representing the deformation and pressure and
|
||||
// H(x) is the nonlinear incompressible neo-Hookean operator.
|
||||
class RubberOperator : public Operator
|
||||
{
|
||||
protected:
|
||||
// Finite element spaces
|
||||
Array<ParFiniteElementSpace *> spaces;
|
||||
|
||||
// Block nonlinear form
|
||||
ParBlockNonlinearForm *Hform;
|
||||
|
||||
// Pressure mass matrix for the preconditioner
|
||||
Operator *pressure_mass;
|
||||
|
||||
// Newton solver for the hyperelastic operator
|
||||
NewtonSolver newton_solver;
|
||||
|
||||
// Solver for the Jacobian solve in the Newton method
|
||||
Solver *j_solver;
|
||||
|
||||
// Preconditioner for the Jacobian
|
||||
Solver *j_prec;
|
||||
|
||||
// Shear modulus coefficient
|
||||
Coefficient μ
|
||||
|
||||
// Block offsets for variable access
|
||||
Array<int> &block_trueOffsets;
|
||||
|
||||
public:
|
||||
RubberOperator(Array<ParFiniteElementSpace *> &fes, Array<Array<int> *>&ess_bdr,
|
||||
Array<int> &block_trueOffsets, double rel_tol, double abs_tol,
|
||||
int iter, Coefficient &mu);
|
||||
|
||||
// Required to use the native newton solver
|
||||
virtual Operator &GetGradient(const Vector &xp) const;
|
||||
virtual void Mult(const Vector &k, Vector &y) const;
|
||||
|
||||
// Driver for the newton solver
|
||||
void Solve(Vector &xp) const;
|
||||
|
||||
virtual ~RubberOperator();
|
||||
};
|
||||
|
||||
// Visualization driver
|
||||
void visualize(ostream &out, ParMesh *mesh, ParGridFunction *deformed_nodes,
|
||||
ParGridFunction *field, const char *field_name = NULL,
|
||||
bool init_vis = false);
|
||||
|
||||
// Configuration definition functions
|
||||
void ReferenceConfiguration(const Vector &x, Vector &y);
|
||||
void InitialDeformation(const Vector &x, Vector &y);
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Initialize MPI
|
||||
int num_procs, myid;
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
|
||||
|
||||
// 2. Parse command-line options
|
||||
const char *mesh_file = "../data/beam-hex.mesh";
|
||||
int ser_ref_levels = 0;
|
||||
int par_ref_levels = 0;
|
||||
int order = 2;
|
||||
bool visualization = true;
|
||||
double newton_rel_tol = 1e-4;
|
||||
double newton_abs_tol = 1e-6;
|
||||
int newton_iter = 500;
|
||||
double mu = 1.0;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
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(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.AddOption(&newton_rel_tol, "-rel", "--relative-tolerance",
|
||||
"Relative tolerance for the Newton solve.");
|
||||
args.AddOption(&newton_abs_tol, "-abs", "--absolute-tolerance",
|
||||
"Absolute tolerance for the Newton solve.");
|
||||
args.AddOption(&newton_iter, "-it", "--newton-iterations",
|
||||
"Maximum iterations for the Newton solve.");
|
||||
args.AddOption(&mu, "-mu", "--shear-modulus",
|
||||
"Shear modulus for the neo-Hookean material.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
}
|
||||
MPI_Finalize();
|
||||
return 1;
|
||||
}
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
// can handle triangular, quadrilateral, tetrahedral and hexahedral meshes
|
||||
// with the same code.
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
int dim = mesh->Dimension();
|
||||
|
||||
// 4. Refine the mesh in serial to increase the resolution. In this example
|
||||
// we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
|
||||
// a command-line parameter.
|
||||
for (int lev = 0; lev < ser_ref_levels; lev++)
|
||||
{
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 5. Define a 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();
|
||||
}
|
||||
|
||||
// 6. Define the shear modulus for the incompressible Neo-Hookean material
|
||||
ConstantCoefficient c_mu(mu);
|
||||
|
||||
// 7. Define the finite element spaces for displacement and pressure
|
||||
// (Taylor-Hood elements). By default, the displacement (u/x) is a second
|
||||
// order vector field, while the pressure (p) is a linear scalar function.
|
||||
H1_FECollection quad_coll(order, dim);
|
||||
H1_FECollection lin_coll(order-1, dim);
|
||||
|
||||
ParFiniteElementSpace R_space(pmesh, &quad_coll, dim, Ordering::byVDIM);
|
||||
ParFiniteElementSpace W_space(pmesh, &lin_coll);
|
||||
|
||||
Array<ParFiniteElementSpace *> spaces(2);
|
||||
spaces[0] = &R_space;
|
||||
spaces[1] = &W_space;
|
||||
|
||||
HYPRE_Int glob_R_size = R_space.GlobalTrueVSize();
|
||||
HYPRE_Int glob_W_size = W_space.GlobalTrueVSize();
|
||||
|
||||
// 8. Define the Dirichlet conditions (set to boundary attribute 1 and 2)
|
||||
Array<Array<int> *> ess_bdr(2);
|
||||
|
||||
Array<int> ess_bdr_u(R_space.GetMesh()->bdr_attributes.Max());
|
||||
Array<int> ess_bdr_p(W_space.GetMesh()->bdr_attributes.Max());
|
||||
|
||||
ess_bdr_p = 0;
|
||||
ess_bdr_u = 0;
|
||||
ess_bdr_u[0] = 1;
|
||||
ess_bdr_u[1] = 1;
|
||||
|
||||
ess_bdr[0] = &ess_bdr_u;
|
||||
ess_bdr[1] = &ess_bdr_p;
|
||||
|
||||
// 9. Print the mesh statistics
|
||||
if (myid == 0)
|
||||
{
|
||||
std::cout << "***********************************************************\n";
|
||||
std::cout << "dim(u) = " << glob_R_size << "\n";
|
||||
std::cout << "dim(p) = " << glob_W_size << "\n";
|
||||
std::cout << "dim(u+p) = " << glob_R_size + glob_W_size << "\n";
|
||||
std::cout << "***********************************************************\n";
|
||||
}
|
||||
|
||||
// 10. Define the block structure of the solution vector (u then p)
|
||||
Array<int> block_trueOffsets(3);
|
||||
block_trueOffsets[0] = 0;
|
||||
block_trueOffsets[1] = R_space.TrueVSize();
|
||||
block_trueOffsets[2] = W_space.TrueVSize();
|
||||
block_trueOffsets.PartialSum();
|
||||
|
||||
BlockVector xp(block_trueOffsets);
|
||||
|
||||
// 11. Define grid functions for the current configuration, reference
|
||||
// configuration, final deformation, and pressure
|
||||
ParGridFunction x_gf(&R_space);
|
||||
ParGridFunction x_ref(&R_space);
|
||||
ParGridFunction x_def(&R_space);
|
||||
ParGridFunction p_gf(&W_space);
|
||||
|
||||
VectorFunctionCoefficient deform(dim, InitialDeformation);
|
||||
VectorFunctionCoefficient refconfig(dim, ReferenceConfiguration);
|
||||
|
||||
x_gf.ProjectCoefficient(deform);
|
||||
x_ref.ProjectCoefficient(refconfig);
|
||||
p_gf = 0.0;
|
||||
|
||||
// 12. Set up the block solution vectors
|
||||
x_gf.GetTrueDofs(xp.GetBlock(0));
|
||||
p_gf.GetTrueDofs(xp.GetBlock(1));
|
||||
|
||||
// 13. Initialize the incompressible neo-Hookean operator
|
||||
RubberOperator oper(spaces, ess_bdr, block_trueOffsets,
|
||||
newton_rel_tol, newton_abs_tol, newton_iter, c_mu);
|
||||
|
||||
// 14. Solve the Newton system
|
||||
oper.Solve(xp);
|
||||
|
||||
// 15. Distribute the shared degrees of freedom
|
||||
x_gf.Distribute(xp.GetBlock(0));
|
||||
p_gf.Distribute(xp.GetBlock(1));
|
||||
|
||||
// 16. Compute the final deformation
|
||||
subtract(x_gf, x_ref, x_def);
|
||||
|
||||
// 17. Visualize the results if requested
|
||||
socketstream vis_u, vis_p;
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
vis_u.open(vishost, visport);
|
||||
vis_u.precision(8);
|
||||
visualize(vis_u, pmesh, &x_gf, &x_def, "Deformation", true);
|
||||
// Make sure all ranks have sent their 'u' solution before initiating
|
||||
// another set of GLVis connections (one from each rank):
|
||||
MPI_Barrier(pmesh->GetComm());
|
||||
vis_p.open(vishost, visport);
|
||||
vis_p.precision(8);
|
||||
visualize(vis_p, pmesh, &x_gf, &p_gf, "Pressure", true);
|
||||
}
|
||||
|
||||
// 18. Save the displaced mesh, the final deformation, and the pressure
|
||||
{
|
||||
GridFunction *nodes = &x_gf;
|
||||
int owns_nodes = 0;
|
||||
pmesh->SwapNodes(nodes, owns_nodes);
|
||||
|
||||
ostringstream mesh_name, pressure_name, deformation_name;
|
||||
mesh_name << "mesh." << setfill('0') << setw(6) << myid;
|
||||
pressure_name << "pressure." << setfill('0') << setw(6) << myid;
|
||||
deformation_name << "deformation." << setfill('0') << setw(6) << myid;
|
||||
|
||||
ofstream mesh_ofs(mesh_name.str().c_str());
|
||||
mesh_ofs.precision(8);
|
||||
pmesh->Print(mesh_ofs);
|
||||
|
||||
ofstream pressure_ofs(pressure_name.str().c_str());
|
||||
pressure_ofs.precision(8);
|
||||
p_gf.Save(pressure_ofs);
|
||||
|
||||
ofstream deformation_ofs(deformation_name.str().c_str());
|
||||
deformation_ofs.precision(8);
|
||||
x_def.Save(deformation_ofs);
|
||||
}
|
||||
|
||||
// 19. Free the used memory
|
||||
delete pmesh;
|
||||
|
||||
MPI_Finalize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
JacobianPreconditioner::JacobianPreconditioner(Array<ParFiniteElementSpace *>
|
||||
&fes,
|
||||
Operator &mass,
|
||||
Array<int> &offsets)
|
||||
: Solver(offsets[2]), block_trueOffsets(offsets), pressure_mass(&mass)
|
||||
{
|
||||
fes.Copy(spaces);
|
||||
|
||||
gamma = 0.00001;
|
||||
|
||||
// The mass matrix and preconditioner do not change every Newton cycle, so
|
||||
// we only need to define them once
|
||||
HypreBoomerAMG *mass_prec_amg = new HypreBoomerAMG();
|
||||
mass_prec_amg->SetPrintLevel(0);
|
||||
|
||||
mass_prec = mass_prec_amg;
|
||||
|
||||
CGSolver *mass_pcg_iter = new CGSolver(spaces[0]->GetComm());
|
||||
mass_pcg_iter->SetRelTol(1e-12);
|
||||
mass_pcg_iter->SetAbsTol(1e-12);
|
||||
mass_pcg_iter->SetMaxIter(200);
|
||||
mass_pcg_iter->SetPrintLevel(0);
|
||||
mass_pcg_iter->SetPreconditioner(*mass_prec);
|
||||
mass_pcg_iter->SetOperator(*pressure_mass);
|
||||
mass_pcg_iter->iterative_mode = false;
|
||||
|
||||
mass_pcg = mass_pcg_iter;
|
||||
|
||||
// The stiffness matrix does change every Newton cycle, so we will define it
|
||||
// during SetOperator
|
||||
stiff_pcg = NULL;
|
||||
stiff_prec = NULL;
|
||||
}
|
||||
|
||||
void JacobianPreconditioner::Mult(const Vector &k, Vector &y) const
|
||||
{
|
||||
// Extract the blocks from the input and output vectors
|
||||
Vector disp_in(k.GetData() + block_trueOffsets[0],
|
||||
block_trueOffsets[1]-block_trueOffsets[0]);
|
||||
Vector pres_in(k.GetData() + block_trueOffsets[1],
|
||||
block_trueOffsets[2]-block_trueOffsets[1]);
|
||||
|
||||
Vector disp_out(y.GetData() + block_trueOffsets[0],
|
||||
block_trueOffsets[1]-block_trueOffsets[0]);
|
||||
Vector pres_out(y.GetData() + block_trueOffsets[1],
|
||||
block_trueOffsets[2]-block_trueOffsets[1]);
|
||||
|
||||
Vector temp(block_trueOffsets[1]-block_trueOffsets[0]);
|
||||
Vector temp2(block_trueOffsets[1]-block_trueOffsets[0]);
|
||||
|
||||
// Perform the block elimination for the preconditioner
|
||||
mass_pcg->Mult(pres_in, pres_out);
|
||||
pres_out *= -gamma;
|
||||
|
||||
jacobian->GetBlock(0,1).Mult(pres_out, temp);
|
||||
subtract(disp_in, temp, temp2);
|
||||
|
||||
stiff_pcg->Mult(temp2, disp_out);
|
||||
}
|
||||
|
||||
void JacobianPreconditioner::SetOperator(const Operator &op)
|
||||
{
|
||||
jacobian = (BlockOperator *) &op;
|
||||
|
||||
// Initialize the stiffness preconditioner and solver
|
||||
if (stiff_prec == NULL)
|
||||
{
|
||||
HypreBoomerAMG *stiff_prec_amg = new HypreBoomerAMG();
|
||||
stiff_prec_amg->SetPrintLevel(0);
|
||||
stiff_prec_amg->SetElasticityOptions(spaces[0]);
|
||||
|
||||
stiff_prec = stiff_prec_amg;
|
||||
|
||||
GMRESSolver *stiff_pcg_iter = new GMRESSolver(spaces[0]->GetComm());
|
||||
stiff_pcg_iter->SetRelTol(1e-8);
|
||||
stiff_pcg_iter->SetAbsTol(1e-8);
|
||||
stiff_pcg_iter->SetMaxIter(200);
|
||||
stiff_pcg_iter->SetPrintLevel(0);
|
||||
stiff_pcg_iter->SetPreconditioner(*stiff_prec);
|
||||
stiff_pcg_iter->iterative_mode = false;
|
||||
|
||||
stiff_pcg = stiff_pcg_iter;
|
||||
}
|
||||
|
||||
// At each Newton cycle, compute the new stiffness AMG preconditioner by
|
||||
// updating the iterative solver which, in turn, updates its preconditioner
|
||||
stiff_pcg->SetOperator(jacobian->GetBlock(0,0));
|
||||
}
|
||||
|
||||
JacobianPreconditioner::~JacobianPreconditioner()
|
||||
{
|
||||
delete mass_pcg;
|
||||
delete mass_prec;
|
||||
delete stiff_prec;
|
||||
delete stiff_pcg;
|
||||
}
|
||||
|
||||
|
||||
RubberOperator::RubberOperator(Array<ParFiniteElementSpace *> &fes,
|
||||
Array<Array<int> *> &ess_bdr,
|
||||
Array<int> &trueOffsets,
|
||||
double rel_tol,
|
||||
double abs_tol,
|
||||
int iter,
|
||||
Coefficient &c_mu)
|
||||
: Operator(fes[0]->TrueVSize() + fes[1]->TrueVSize()),
|
||||
newton_solver(fes[0]->GetComm()), mu(c_mu), block_trueOffsets(trueOffsets)
|
||||
{
|
||||
Array<Vector *> rhs(2);
|
||||
rhs = NULL; // Set all entries in the array
|
||||
|
||||
fes.Copy(spaces);
|
||||
|
||||
// Define the block nonlinear form
|
||||
Hform = new ParBlockNonlinearForm(spaces);
|
||||
|
||||
// Add the incompressible neo-Hookean integrator
|
||||
Hform->AddDomainIntegrator(new IncompressibleNeoHookeanIntegrator(mu));
|
||||
|
||||
// Set the essential boundary conditions
|
||||
Hform->SetEssentialBC(ess_bdr, rhs);
|
||||
|
||||
// Compute the pressure mass stiffness matrix
|
||||
ParBilinearForm *a = new ParBilinearForm(spaces[1]);
|
||||
ConstantCoefficient one(1.0);
|
||||
OperatorHandle mass(Operator::Hypre_ParCSR);
|
||||
a->AddDomainIntegrator(new MassIntegrator(one));
|
||||
a->Assemble();
|
||||
a->Finalize();
|
||||
a->ParallelAssemble(mass);
|
||||
delete a;
|
||||
|
||||
mass.SetOperatorOwner(false);
|
||||
pressure_mass = mass.Ptr();
|
||||
|
||||
// Initialize the Jacobian preconditioner
|
||||
JacobianPreconditioner *jac_prec =
|
||||
new JacobianPreconditioner(fes, *pressure_mass, block_trueOffsets);
|
||||
j_prec = jac_prec;
|
||||
|
||||
// Set up the Jacobian solver
|
||||
GMRESSolver *j_gmres = new GMRESSolver(spaces[0]->GetComm());
|
||||
j_gmres->iterative_mode = false;
|
||||
j_gmres->SetRelTol(1e-12);
|
||||
j_gmres->SetAbsTol(1e-12);
|
||||
j_gmres->SetMaxIter(300);
|
||||
j_gmres->SetPrintLevel(0);
|
||||
j_gmres->SetPreconditioner(*j_prec);
|
||||
j_solver = j_gmres;
|
||||
|
||||
// Set the newton solve parameters
|
||||
newton_solver.iterative_mode = true;
|
||||
newton_solver.SetSolver(*j_solver);
|
||||
newton_solver.SetOperator(*this);
|
||||
newton_solver.SetPrintLevel(1);
|
||||
newton_solver.SetRelTol(rel_tol);
|
||||
newton_solver.SetAbsTol(abs_tol);
|
||||
newton_solver.SetMaxIter(iter);
|
||||
}
|
||||
|
||||
// Solve the Newton system
|
||||
void RubberOperator::Solve(Vector &xp) const
|
||||
{
|
||||
Vector zero;
|
||||
newton_solver.Mult(zero, xp);
|
||||
MFEM_VERIFY(newton_solver.GetConverged(),
|
||||
"Newton Solver did not converge.");
|
||||
}
|
||||
|
||||
// compute: y = H(x,p)
|
||||
void RubberOperator::Mult(const Vector &k, Vector &y) const
|
||||
{
|
||||
Hform->Mult(k, y);
|
||||
}
|
||||
|
||||
// Compute the Jacobian from the nonlinear form
|
||||
Operator &RubberOperator::GetGradient(const Vector &xp) const
|
||||
{
|
||||
return Hform->GetGradient(xp);
|
||||
}
|
||||
|
||||
RubberOperator::~RubberOperator()
|
||||
{
|
||||
delete Hform;
|
||||
delete pressure_mass;
|
||||
delete j_solver;
|
||||
delete j_prec;
|
||||
}
|
||||
|
||||
|
||||
// Inline visualization
|
||||
void visualize(ostream &out, ParMesh *mesh, ParGridFunction *deformed_nodes,
|
||||
ParGridFunction *field, const char *field_name, bool init_vis)
|
||||
{
|
||||
if (!out)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GridFunction *nodes = deformed_nodes;
|
||||
int owns_nodes = 0;
|
||||
|
||||
mesh->SwapNodes(nodes, owns_nodes);
|
||||
|
||||
out << "parallel " << mesh->GetNRanks() << " " << mesh->GetMyRank() << "\n";
|
||||
out << "solution\n" << *mesh << *field;
|
||||
|
||||
mesh->SwapNodes(nodes, owns_nodes);
|
||||
|
||||
if (init_vis)
|
||||
{
|
||||
out << "window_size 800 800\n";
|
||||
out << "window_title '" << field_name << "'\n";
|
||||
if (mesh->SpaceDimension() == 2)
|
||||
{
|
||||
out << "view 0 0\n"; // view from top
|
||||
out << "keys jlA\n"; // turn off perspective and light, +anti-aliasing
|
||||
}
|
||||
out << "keys cmA\n"; // show colorbar and mesh, +anti-aliasing
|
||||
out << "autoscale value\n"; // update value-range; keep mesh-extents fixed
|
||||
}
|
||||
out << flush;
|
||||
}
|
||||
|
||||
void ReferenceConfiguration(const Vector &x, Vector &y)
|
||||
{
|
||||
// Set the reference, stress free, configuration
|
||||
y = x;
|
||||
}
|
||||
|
||||
void InitialDeformation(const Vector &x, Vector &y)
|
||||
{
|
||||
// Set the initial configuration. Having this different from the reference
|
||||
// configuration can help convergence
|
||||
y = x;
|
||||
y[1] = x[1] + 0.25*x[0];
|
||||
}
|
||||
@@ -4,19 +4,14 @@
|
||||
//
|
||||
// Sample runs: mpirun -np 4 ex1p -m ../data/square-disc.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/star.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/star-mixed.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/escher.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/fichera.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/fichera-mixed.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/toroid-wedge.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/square-disc-p2.vtk -o 2
|
||||
// mpirun -np 4 ex1p -m ../data/square-disc-p3.mesh -o 3
|
||||
// mpirun -np 4 ex1p -m ../data/square-disc-nurbs.mesh -o -1
|
||||
// mpirun -np 4 ex1p -m ../data/star-mixed-p2.mesh -o 2
|
||||
// mpirun -np 4 ex1p -m ../data/disc-nurbs.mesh -o -1
|
||||
// mpirun -np 4 ex1p -m ../data/pipe-nurbs.mesh -o -1
|
||||
// mpirun -np 4 ex1p -m ../data/ball-nurbs.mesh -o 2
|
||||
// mpirun -np 4 ex1p -m ../data/fichera-mixed-p2.mesh -o 2
|
||||
// mpirun -np 4 ex1p -m ../data/star-surf.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/square-disc-surf.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/inline-segment.mesh
|
||||
@@ -25,11 +20,6 @@
|
||||
// mpirun -np 4 ex1p -m ../data/mobius-strip.mesh
|
||||
// mpirun -np 4 ex1p -m ../data/mobius-strip.mesh -o -1 -sc
|
||||
//
|
||||
// Device sample runs:
|
||||
// > mpirun -np 4 ex1p -pa -d cuda
|
||||
// > mpirun -np 4 ex1p -pa -d occa-cuda
|
||||
// > mpirun -np 4 ex1p -pa -d raja-omp
|
||||
//
|
||||
// Description: This example code demonstrates the use of MFEM to define a
|
||||
// simple finite element discretization of the Laplace problem
|
||||
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
|
||||
@@ -64,9 +54,7 @@ int main(int argc, char *argv[])
|
||||
const char *mesh_file = "../data/star.mesh";
|
||||
int order = 1;
|
||||
bool static_cond = false;
|
||||
bool pa = false;
|
||||
const char *device = "cpu";
|
||||
bool visualization = true;
|
||||
bool visualization = 1;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
@@ -76,10 +64,6 @@ int main(int argc, char *argv[])
|
||||
" isoparametric space.");
|
||||
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
|
||||
"--no-static-condensation", "Enable static condensation.");
|
||||
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
|
||||
"--no-partial-assembly", "Enable Partial Assembly.");
|
||||
args.AddOption(&device, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -177,58 +161,49 @@ int main(int argc, char *argv[])
|
||||
b->AddDomainIntegrator(new DomainLFIntegrator(one));
|
||||
b->Assemble();
|
||||
|
||||
// 9. Set device config parameters from the command line options and switch
|
||||
// to working on the device.
|
||||
Device::Configure(device);
|
||||
if (myid == 0) { Device::Print(); }
|
||||
Device::Enable();
|
||||
|
||||
// 10. Define the solution vector x as a parallel finite element grid function
|
||||
// corresponding to fespace. Initialize x with initial guess of zero,
|
||||
// which satisfies the boundary conditions.
|
||||
// 9. Define the solution vector x as a parallel finite element grid function
|
||||
// corresponding to fespace. Initialize x with initial guess of zero,
|
||||
// which satisfies the boundary conditions.
|
||||
ParGridFunction x(fespace);
|
||||
x = 0.0;
|
||||
|
||||
// 11. Set up the parallel bilinear form a(.,.) on the finite element space
|
||||
// 10. Set up the parallel bilinear form a(.,.) on the finite element space
|
||||
// corresponding to the Laplacian operator -Delta, by adding the Diffusion
|
||||
// domain integrator.
|
||||
ParBilinearForm *a = new ParBilinearForm(fespace);
|
||||
if (pa) { a->SetAssemblyLevel(AssemblyLevel::PARTIAL); }
|
||||
a->AddDomainIntegrator(new DiffusionIntegrator(one));
|
||||
|
||||
// 12. Assemble the parallel bilinear form and the corresponding linear
|
||||
// 11. Assemble the parallel bilinear form and the corresponding linear
|
||||
// system, applying any necessary transformations such as: parallel
|
||||
// assembly, eliminating boundary conditions, applying conforming
|
||||
// constraints for non-conforming AMR, static condensation, etc.
|
||||
if (static_cond) { a->EnableStaticCondensation(); }
|
||||
a->Assemble();
|
||||
|
||||
OperatorPtr A;
|
||||
HypreParMatrix A;
|
||||
Vector B, X;
|
||||
a->FormLinearSystem(ess_tdof_list, x, *b, A, X, B);
|
||||
|
||||
// 13. Solve the linear system A X = B.
|
||||
// * With full assembly, use the BoomerAMG preconditioner from hypre.
|
||||
// * With partial assembly, use no preconditioner, for now.
|
||||
Solver *prec = NULL;
|
||||
if (!pa) { 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;
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Size of linear system: " << A.GetGlobalNumRows() << endl;
|
||||
}
|
||||
|
||||
// 14. Recover the parallel grid function corresponding to X. This is the
|
||||
// 12. Define and apply a parallel PCG solver for AX=B with the BoomerAMG
|
||||
// preconditioner from hypre.
|
||||
HypreSolver *amg = new HypreBoomerAMG(A);
|
||||
HyprePCG *pcg = new HyprePCG(A);
|
||||
pcg->SetTol(1e-12);
|
||||
pcg->SetMaxIter(200);
|
||||
pcg->SetPrintLevel(2);
|
||||
pcg->SetPreconditioner(*amg);
|
||||
pcg->Mult(B, X);
|
||||
|
||||
// 13. Recover the parallel grid function corresponding to X. This is the
|
||||
// local finite element solution on each processor.
|
||||
a->RecoverFEMSolution(X, *b, x);
|
||||
|
||||
// 15. Switch back to the host.
|
||||
Device::Disable();
|
||||
|
||||
// 16. Save the refined mesh and the solution in parallel. This output can
|
||||
// 14. 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_name;
|
||||
@@ -244,7 +219,7 @@ int main(int argc, char *argv[])
|
||||
x.Save(sol_ofs);
|
||||
}
|
||||
|
||||
// 17. Send the solution by socket to a GLVis server.
|
||||
// 15. Send the solution by socket to a GLVis server.
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
@@ -255,7 +230,9 @@ int main(int argc, char *argv[])
|
||||
sol_sock << "solution\n" << *pmesh << x << flush;
|
||||
}
|
||||
|
||||
// 18. Free the used memory.
|
||||
// 16. Free the used memory.
|
||||
delete pcg;
|
||||
delete amg;
|
||||
delete a;
|
||||
delete b;
|
||||
delete fespace;
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
// ex2 -m ../data/beam-quad.mesh
|
||||
// ex2 -m ../data/beam-tet.mesh
|
||||
// ex2 -m ../data/beam-hex.mesh
|
||||
// ex2 -m ../data/beam-wedge.mesh
|
||||
// ex2 -m ../data/beam-quad.mesh -o 3 -sc
|
||||
// ex2 -m ../data/beam-quad-nurbs.mesh
|
||||
// ex2 -m ../data/beam-hex-nurbs.mesh
|
||||
@@ -85,9 +84,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 3. Select the order of the finite element discretization space. For NURBS
|
||||
// meshes, we increase the order by degree elevation.
|
||||
if (mesh->NURBSext)
|
||||
if (mesh->NURBSext && order > mesh->NURBSext->GetOrder())
|
||||
{
|
||||
mesh->DegreeElevate(order, order);
|
||||
mesh->DegreeElevate(order - mesh->NURBSext->GetOrder());
|
||||
}
|
||||
|
||||
// 4. Refine the mesh to increase the resolution. In this example we do
|
||||
|
||||
@@ -1,298 +0,0 @@
|
||||
// MFEM Example 20
|
||||
//
|
||||
// Compile with: make ex20
|
||||
//
|
||||
// Sample runs: ex20
|
||||
//
|
||||
// Description: This example demonstrates the use of the variable order,
|
||||
// symplectic ODE integration algorithm. Symplectic integration
|
||||
// algorithms are designed to conserve energy when integrating, in
|
||||
// time, systems of ODEs which are derived from Hamiltonian
|
||||
// systems.
|
||||
//
|
||||
// Hamiltonian systems define the energy of a system as a function
|
||||
// of time (t), a set of generalized coordinates (q), and their
|
||||
// corresponding generalized momenta (p).
|
||||
//
|
||||
// H(q,p,t) = T(p) + V(q,t)
|
||||
//
|
||||
// Hamilton's equations then specify how q and p evolve in time:
|
||||
//
|
||||
// dq/dt = dH/dp
|
||||
// dp/dt = -dH/dq
|
||||
//
|
||||
// To use the symplectic integration classes we need to define an
|
||||
// mfem::Operator P which evaluates the action of dH/dp, and an
|
||||
// mfem::TimeDependentOperator F which computes -dH/dq.
|
||||
//
|
||||
// This example offers five simple 1D Hamiltonians:
|
||||
// 0) Simple Harmonic Oscillator (mass on a spring)
|
||||
// H = ( p^2 / m + q^2 / k ) / 2
|
||||
// 1) Pendulum
|
||||
// H = ( p^2 / m - k ( 1 - cos(q) ) ) / 2
|
||||
// 2) Gaussian Potential Well
|
||||
// H = ( p^2 / m ) / 2 - k exp(-q^2 / 2)
|
||||
// 3) Quartic Potential
|
||||
// H = ( p^2 / m + k ( 1 + q^2 ) q^2 ) / 2
|
||||
// 4) Negative Quartic Potential
|
||||
// H = ( p^2 / m + k ( 1 - q^2 /8 ) q^2 ) / 2
|
||||
//
|
||||
// In all cases these Hamiltonians are shifted by constant values
|
||||
// so that the energy will remain positive. The mean and standard
|
||||
// deviation of the computed energies at each time step are
|
||||
// displayed upon completion.
|
||||
//
|
||||
// We then use GLVis to visualize the results in a non-standard way
|
||||
// by defining the axes to be q, p, and t rather than x, y, and z.
|
||||
// In this space we build a ribbon-like mesh with nodes at (0,0,t)
|
||||
// and (q,p,t). Finally we plot the energy as a function of time
|
||||
// as a scalar field on this ribbon-like mesh.
|
||||
//
|
||||
// For a more traditional plot of the results, including q, p, and
|
||||
// H, can be obtained by selecting the "-gp" option. This creates
|
||||
// a data file and input deck for the GnuPlot application (not
|
||||
// included with MFEM). To visualize these results on most Linux
|
||||
// systems type the command "gnuplot gnuplot_ex20.inp". The data
|
||||
// file, named "ex20.dat", should be simple enough to display with
|
||||
// other plotting programs as well.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// Constants used in the Hamiltonian
|
||||
static int prob_ = 0;
|
||||
static double m_ = 1.0;
|
||||
static double k_ = 1.0;
|
||||
|
||||
// Hamiltonian functional, see below for implementation
|
||||
double hamiltonian(double q, double p, double t);
|
||||
|
||||
class GradT : public Operator
|
||||
{
|
||||
public:
|
||||
GradT() : Operator(1) {}
|
||||
void Mult(const Vector &x, Vector &y) const { y.Set(1.0/m_, x); }
|
||||
};
|
||||
|
||||
class NegGradV : public TimeDependentOperator
|
||||
{
|
||||
public:
|
||||
NegGradV() : TimeDependentOperator(1) {}
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Parse command-line options.
|
||||
int order = 1;
|
||||
int nsteps = 100;
|
||||
double dt = 0.1;
|
||||
bool visualization = true;
|
||||
bool gnuplot = false;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Time integration order.");
|
||||
args.AddOption(&prob_, "-p", "--problem-type",
|
||||
"Problem Type:\n"
|
||||
"\t 0 - Simple Harmonic Oscillator\n"
|
||||
"\t 1 - Pendulum\n"
|
||||
"\t 2 - Gaussian Potential Well\n"
|
||||
"\t 3 - Quartic Potential\n"
|
||||
"\t 4 - Negative Quartic Potential");
|
||||
args.AddOption(&nsteps, "-n", "--number-of-steps",
|
||||
"Number of time steps.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
"Time step size.");
|
||||
args.AddOption(&m_, "-m", "--mass",
|
||||
"Mass.");
|
||||
args.AddOption(&k_, "-k", "--spring-const",
|
||||
"Spring constant.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.AddOption(&gnuplot, "-gp", "--gnuplot", "-no-gp", "--no-gnuplot",
|
||||
"Enable or disable GnuPlot visualization.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
return 1;
|
||||
}
|
||||
args.PrintOptions(cout);
|
||||
|
||||
// 2. Create and Initialize the Symplectic Integration Solver
|
||||
SIAVSolver siaSolver(order);
|
||||
GradT P;
|
||||
NegGradV F;
|
||||
siaSolver.Init(P,F);
|
||||
|
||||
// 3. Set the initial conditions
|
||||
double t = 0.0;
|
||||
Vector q(1), p(1);
|
||||
Vector e(nsteps+1);
|
||||
q(0) = 0.0;
|
||||
p(0) = 1.0;
|
||||
|
||||
// 4. Prepare GnuPlot output file if needed
|
||||
ofstream ofs;
|
||||
if (gnuplot)
|
||||
{
|
||||
ofs.open("ex20.dat");
|
||||
ofs << t << "\t" << q(0) << "\t" << p(0) << endl;
|
||||
}
|
||||
|
||||
// 5. Create a Mesh for visualization in phase space
|
||||
int nverts = (visualization) ? 2*(nsteps+1) : 0;
|
||||
int nelems = (visualization) ? nsteps : 0;
|
||||
Mesh mesh(2, nverts, nelems, 0, 3);
|
||||
|
||||
int v[4];
|
||||
Vector x0(3); x0 = 0.0;
|
||||
Vector x1(3); x1 = 0.0;
|
||||
|
||||
// 6. Perform time-stepping
|
||||
double e_mean = 0.0;
|
||||
|
||||
for (int i = 0; i < nsteps; i++)
|
||||
{
|
||||
// 6a. Record initial state
|
||||
if (i == 0)
|
||||
{
|
||||
e[0] = hamiltonian(q(0),p(0),t);
|
||||
e_mean += e[0];
|
||||
|
||||
if (visualization)
|
||||
{
|
||||
x1[0] = q(0);
|
||||
x1[1] = p(0);
|
||||
x1[2] = 0.0;
|
||||
mesh.AddVertex(x0);
|
||||
mesh.AddVertex(x1);
|
||||
}
|
||||
}
|
||||
|
||||
// 6b. Advance the state of the system
|
||||
siaSolver.Step(q,p,t,dt);
|
||||
e[i+1] = hamiltonian(q(0),p(0),t);
|
||||
e_mean += e[i+1];
|
||||
|
||||
// 6c. Record the state of the system
|
||||
if (gnuplot)
|
||||
{
|
||||
ofs << t << "\t" << q(0) << "\t" << p(0) << "\t" << e[i+1] << endl;
|
||||
}
|
||||
|
||||
// 6d. Add results to GLVis visualization
|
||||
if (visualization)
|
||||
{
|
||||
x0[2] = t;
|
||||
x1[0] = q(0);
|
||||
x1[1] = p(0);
|
||||
x1[2] = t;
|
||||
mesh.AddVertex(x0);
|
||||
mesh.AddVertex(x1);
|
||||
v[0] = 2*i;
|
||||
v[1] = 2*(i+1);
|
||||
v[2] = 2*(i+1)+1;
|
||||
v[3] = 2*i+1;
|
||||
mesh.AddQuad(v);
|
||||
}
|
||||
}
|
||||
|
||||
// 7. Compute and display mean and standard deviation of the energy
|
||||
e_mean /= (nsteps + 1);
|
||||
double e_var = 0.0;
|
||||
for (int i=0; i<=nsteps; i++)
|
||||
{
|
||||
e_var += pow(e[i] - e_mean, 2);
|
||||
}
|
||||
e_var /= (nsteps + 1);
|
||||
double e_sd = sqrt(e_var);
|
||||
cout << endl << "Mean and standard deviation of the energy" << endl;
|
||||
cout << e_mean << "\t" << e_sd << endl;
|
||||
|
||||
// 8. Finalize the GnuPlot output
|
||||
if (gnuplot)
|
||||
{
|
||||
ofs.close();
|
||||
|
||||
ofs.open("gnuplot_ex20.inp");
|
||||
ofs << "plot 'ex20.dat' using 1:2 w l t 'q', "
|
||||
<< "'ex20.dat' using 1:3 w l t 'p', "
|
||||
<< "'ex20.dat' using 1:4 w l t 'H'" << endl;
|
||||
ofs.close();
|
||||
}
|
||||
|
||||
// 9. Finalize the GLVis output
|
||||
if (visualization)
|
||||
{
|
||||
H1_FECollection fec(order = 1, 2);
|
||||
FiniteElementSpace fespace(&mesh, &fec);
|
||||
GridFunction energy(&fespace);
|
||||
energy = 0.0;
|
||||
for (int i = 0; i <= nsteps; i++)
|
||||
{
|
||||
energy[2*i+0] = e[i];
|
||||
energy[2*i+1] = e[i];
|
||||
}
|
||||
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sock(vishost, visport);
|
||||
sock.precision(8);
|
||||
sock << "solution\n" << mesh << energy
|
||||
<< "window_title 'Energy in Phase Space'\n"
|
||||
<< "keys\n maac\n" << "axis_labels 'q' 'p' 't'\n"<< flush;
|
||||
}
|
||||
}
|
||||
|
||||
double hamiltonian(double q, double p, double t)
|
||||
{
|
||||
double h = 1.0 - 0.5 / m_ + 0.5 * p * p / m_;
|
||||
switch (prob_)
|
||||
{
|
||||
case 1:
|
||||
h += k_ * (1.0 - cos(q));
|
||||
break;
|
||||
case 2:
|
||||
h += k_ * (1.0 - exp(-0.5 * q * q));
|
||||
break;
|
||||
case 3:
|
||||
h += 0.5 * k_ * (1.0 + q * q) * q * q;
|
||||
break;
|
||||
case 4:
|
||||
h += 0.5 * k_ * (1.0 - 0.125 * q * q) * q * q;
|
||||
break;
|
||||
default:
|
||||
h += 0.5 * k_ * q * q;
|
||||
break;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void NegGradV::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
switch (prob_)
|
||||
{
|
||||
case 1:
|
||||
y(0) = - k_* sin(x(0));
|
||||
break;
|
||||
case 2:
|
||||
y(0) = - k_ * x(0) * exp(-0.5 * x(0) * x(0));
|
||||
break;
|
||||
case 3:
|
||||
y(0) = - k_ * (1.0 + 2.0 * x(0) * x(0)) * x(0);
|
||||
break;
|
||||
case 4:
|
||||
y(0) = - k_ * (1.0 - 0.25 * x(0) * x(0)) * x(0);
|
||||
break;
|
||||
default:
|
||||
y(0) = - k_ * x(0);
|
||||
break;
|
||||
};
|
||||
}
|
||||
@@ -1,364 +0,0 @@
|
||||
// MFEM Example 20 - Parallel Version
|
||||
//
|
||||
// Compile with: make ex20p
|
||||
//
|
||||
// Sample runs: mpirun -np 4 ex20p
|
||||
//
|
||||
// Description: This example demonstrates the use of the variable order,
|
||||
// symplectic ODE integration algorithm. Symplectic integration
|
||||
// algorithms are designed to conserve energy when integrating, in
|
||||
// time, systems of ODEs which are derived from Hamiltonian
|
||||
// systems.
|
||||
//
|
||||
// Hamiltonian systems define the energy of a system as a function
|
||||
// of time (t), a set of generalized coordinates (q), and their
|
||||
// corresponding generalized momenta (p).
|
||||
//
|
||||
// H(q,p,t) = T(p) + V(q,t)
|
||||
//
|
||||
// Hamilton's equations then specify how q and p evolve in time:
|
||||
//
|
||||
// dq/dt = dH/dp
|
||||
// dp/dt = -dH/dq
|
||||
//
|
||||
// To use the symplectic integration classes we need to define an
|
||||
// mfem::Operator P which evaluates the action of dH/dp, and an
|
||||
// mfem::TimeDependentOperator F which computes -dH/dq.
|
||||
//
|
||||
// This example offers five simple 1D Hamiltonians:
|
||||
// 0) Simple Harmonic Oscillator (mass on a spring)
|
||||
// H = ( p^2 / m + q^2 / k ) / 2
|
||||
// 1) Pendulum
|
||||
// H = ( p^2 / m - k ( 1 - cos(q) ) ) / 2
|
||||
// 2) Gaussian Potential Well
|
||||
// H = ( p^2 / m ) / 2 - k exp(-q^2 / 2)
|
||||
// 3) Quartic Potential
|
||||
// H = ( p^2 / m + k ( 1 + q^2 ) q^2 ) / 2
|
||||
// 4) Negative Quartic Potential
|
||||
// H = ( p^2 / m + k ( 1 - q^2 /8 ) q^2 ) / 2
|
||||
//
|
||||
// In all cases these Hamiltonians are shifted by constant values
|
||||
// so that the energy will remain positive. The mean and standard
|
||||
// deviation of the computed energies at each time step are
|
||||
// displayed upon completion. When run in parallel the same
|
||||
// Hamiltonian system is evolved on each processor but starting
|
||||
// from different initial conditions.
|
||||
//
|
||||
// We then use GLVis to visualize the results in a non-standard way
|
||||
// by defining the axes to be q, p, and t rather than x, y, and z.
|
||||
// In this space we build a ribbon-like mesh on each processor with
|
||||
// nodes at (0,0,t) and (q,p,t). When these ribbons are bonded
|
||||
// together on the t-axis they resemble a Rotini pasta. Finally we
|
||||
// plot the energy as a function of time as a scalar field on this
|
||||
// Rotini-like mesh.
|
||||
//
|
||||
// For a more traditional plot of the results, including q, p, and
|
||||
// H from each processor, can be obtained by selecting the "-gp"
|
||||
// option. This creates a collection of data files and an input
|
||||
// deck for the GnuPlot application (not included with MFEM). To
|
||||
// visualize these results on most linux systems type the command
|
||||
// "gnuplot gnuplot_ex20p.inp". The data files, named
|
||||
// "ex20p_?????.dat", should be simple enough to display with other
|
||||
// plotting programs as well.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// Constants used in the Hamiltonian
|
||||
static int prob_ = 0;
|
||||
static double m_ = 1.0;
|
||||
static double k_ = 1.0;
|
||||
|
||||
// Hamiltonian functional, see below for implementation
|
||||
double hamiltonian(double q, double p, double t);
|
||||
|
||||
class GradT : public Operator
|
||||
{
|
||||
public:
|
||||
GradT() : Operator(1) {}
|
||||
void Mult(const Vector &x, Vector &y) const { y.Set(1.0/m_, x); }
|
||||
};
|
||||
|
||||
class NegGradV : public TimeDependentOperator
|
||||
{
|
||||
public:
|
||||
NegGradV() : TimeDependentOperator(1) {}
|
||||
void Mult(const Vector &x, Vector &y) const;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Initialize MPI.
|
||||
int num_procs, myid;
|
||||
MPI_Comm comm = MPI_COMM_WORLD;
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_size(comm, &num_procs);
|
||||
MPI_Comm_rank(comm, &myid);
|
||||
|
||||
// 2. Parse command-line options.
|
||||
int order = 1;
|
||||
int nsteps = 100;
|
||||
double dt = 0.1;
|
||||
bool visualization = true;
|
||||
bool gnuplot = false;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Time integration order.");
|
||||
args.AddOption(&prob_, "-p", "--problem-type",
|
||||
"Problem Type:\n"
|
||||
"\t 0 - Simple Harmonic Oscillator\n"
|
||||
"\t 1 - Pendulum\n"
|
||||
"\t 2 - Gaussian Potential Well\n"
|
||||
"\t 3 - Quartic Potential\n"
|
||||
"\t 4 - Negative Quartic Potential");
|
||||
args.AddOption(&nsteps, "-n", "--number-of-steps",
|
||||
"Number of time steps.");
|
||||
args.AddOption(&dt, "-dt", "--time-step",
|
||||
"Time step size.");
|
||||
args.AddOption(&m_, "-m", "--mass",
|
||||
"Mass.");
|
||||
args.AddOption(&k_, "-k", "--spring-const",
|
||||
"Spring constant.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.AddOption(&gnuplot, "-gp", "--gnuplot", "-no-gp", "--no-gnuplot",
|
||||
"Enable or disable GnuPlot visualization.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
}
|
||||
MPI_Finalize();
|
||||
return 1;
|
||||
}
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
|
||||
// 3. Create and Initialize the Symplectic Integration Solver
|
||||
SIAVSolver siaSolver(order);
|
||||
GradT P;
|
||||
NegGradV F;
|
||||
siaSolver.Init(P,F);
|
||||
|
||||
// 4. Set the initial conditions
|
||||
double t = 0.0;
|
||||
Vector q(1), p(1);
|
||||
Vector e(nsteps+1);
|
||||
q(0) = sin(2.0*M_PI*(double)myid/num_procs);
|
||||
p(0) = cos(2.0*M_PI*(double)myid/num_procs);
|
||||
|
||||
// 5. Prepare GnuPlot output file if needed
|
||||
ostringstream oss;
|
||||
ofstream ofs;
|
||||
if (gnuplot)
|
||||
{
|
||||
oss << "ex20p_" << setfill('0') << setw(5) << myid << ".dat";
|
||||
ofs.open(oss.str().c_str());
|
||||
ofs << t << "\t" << q(0) << "\t" << p(0) << endl;
|
||||
}
|
||||
|
||||
// 6. Create a Mesh for visualization in phase space
|
||||
int nverts = (visualization) ? (num_procs+1)*(nsteps+1) : 0;
|
||||
int nelems = (visualization) ? (nsteps * num_procs) : 0;
|
||||
Mesh mesh(2, nverts, nelems, 0, 3);
|
||||
|
||||
int *part = (visualization) ? (new int[nelems]) : NULL;
|
||||
int v[4];
|
||||
Vector x0(3); x0 = 0.0;
|
||||
Vector x1(3); x1 = 0.0;
|
||||
|
||||
// 7. Perform time-stepping
|
||||
double e_mean = 0.0;
|
||||
|
||||
for (int i = 0; i < nsteps; i++)
|
||||
{
|
||||
// 7a. Record initial state
|
||||
if (i == 0)
|
||||
{
|
||||
e[0] = hamiltonian(q(0),p(0),t);
|
||||
e_mean += e[0];
|
||||
|
||||
if (visualization)
|
||||
{
|
||||
mesh.AddVertex(x0);
|
||||
for (int j = 0; j < num_procs; j++)
|
||||
{
|
||||
x1[0] = q(0);
|
||||
x1[1] = p(0);
|
||||
x1[2] = 0.0;
|
||||
mesh.AddVertex(x1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 7b. Advance the state of the system
|
||||
siaSolver.Step(q,p,t,dt);
|
||||
e[i+1] = hamiltonian(q(0),p(0),t);
|
||||
e_mean += e[i+1];
|
||||
|
||||
// 7c. Record the state of the system
|
||||
if (gnuplot)
|
||||
{
|
||||
ofs << t << "\t" << q(0) << "\t" << p(0) << "\t" << e[i+1] << endl;
|
||||
}
|
||||
|
||||
// 7d. Add results to GLVis visualization
|
||||
if (visualization)
|
||||
{
|
||||
x0[2] = t;
|
||||
mesh.AddVertex(x0);
|
||||
for (int j = 0; j < num_procs; j++)
|
||||
{
|
||||
x1[0] = q(0);
|
||||
x1[1] = p(0);
|
||||
x1[2] = t;
|
||||
mesh.AddVertex(x1);
|
||||
v[0] = (num_procs + 1) * i;
|
||||
v[1] = (num_procs + 1) * (i + 1);
|
||||
v[2] = (num_procs + 1) * (i + 1) + j + 1;
|
||||
v[3] = (num_procs + 1) * i + j + 1;
|
||||
mesh.AddQuad(v);
|
||||
part[num_procs * i + j] = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 8. Compute and display mean and standard deviation of the energy
|
||||
e_mean /= (nsteps + 1);
|
||||
double e_var = 0.0;
|
||||
for (int i = 0; i <= nsteps; i++)
|
||||
{
|
||||
e_var += pow(e[i] - e_mean, 2);
|
||||
}
|
||||
e_var /= (nsteps + 1);
|
||||
double e_sd = sqrt(e_var);
|
||||
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << endl << "Mean and standard deviation of the energy" << endl;
|
||||
}
|
||||
for (int i = 0; i < num_procs; i++)
|
||||
{
|
||||
if (myid == i)
|
||||
{
|
||||
cout << myid << ": " << e_mean << "\t" << e_sd << endl;
|
||||
}
|
||||
MPI_Barrier(comm);
|
||||
}
|
||||
|
||||
// 9. Finalize the GnuPlot output
|
||||
if (gnuplot)
|
||||
{
|
||||
ofs.close();
|
||||
if (myid == 0)
|
||||
{
|
||||
ofs.open("gnuplot_ex20p.inp");
|
||||
for (int i = 0; i < num_procs; i++)
|
||||
{
|
||||
ostringstream ossi;
|
||||
ossi << "ex20p_" << setfill('0') << setw(5) << i << ".dat";
|
||||
if (i == 0)
|
||||
{
|
||||
ofs << "plot";
|
||||
}
|
||||
ofs << " '" << ossi.str() << "' using 1:2 w l t 'q" << i << "',"
|
||||
<< " '" << ossi.str() << "' using 1:3 w l t 'p" << i << "',"
|
||||
<< " '" << ossi.str() << "' using 1:4 w l t 'H" << i << "'";
|
||||
if (i < num_procs-1)
|
||||
{
|
||||
ofs << ",";
|
||||
}
|
||||
else
|
||||
{
|
||||
ofs << ";" << endl;
|
||||
}
|
||||
}
|
||||
ofs.close();
|
||||
}
|
||||
}
|
||||
|
||||
// 10. Finalize the GLVis output
|
||||
if (visualization)
|
||||
{
|
||||
mesh.FinalizeQuadMesh(1);
|
||||
ParMesh pmesh(comm, mesh, part);
|
||||
delete [] part;
|
||||
|
||||
H1_FECollection fec(order = 1, 2);
|
||||
ParFiniteElementSpace fespace(&pmesh, &fec);
|
||||
ParGridFunction energy(&fespace);
|
||||
energy = 0.0;
|
||||
for (int i = 0; i <= nsteps; i++)
|
||||
{
|
||||
energy[2*i+0] = e[i];
|
||||
energy[2*i+1] = e[i];
|
||||
}
|
||||
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sock(vishost, visport);
|
||||
sock.precision(8);
|
||||
sock << "parallel " << num_procs << " " << myid << "\n"
|
||||
<< "solution\n" << pmesh << energy
|
||||
<< "window_title 'Energy in Phase Space'\n"
|
||||
<< "keys\n maac\n" << "axis_labels 'q' 'p' 't'\n"<< flush;
|
||||
}
|
||||
|
||||
MPI_Finalize();
|
||||
}
|
||||
|
||||
double hamiltonian(double q, double p, double t)
|
||||
{
|
||||
double h = 1.0 - 0.5 / m_ + 0.5 * p * p / m_;
|
||||
switch (prob_)
|
||||
{
|
||||
case 1:
|
||||
h += k_ * (1.0 - cos(q));
|
||||
break;
|
||||
case 2:
|
||||
h += k_ * (1.0 - exp(-0.5 * q * q));
|
||||
break;
|
||||
case 3:
|
||||
h += 0.5 * k_ * (1.0 + q * q) * q * q;
|
||||
break;
|
||||
case 4:
|
||||
h += 0.5 * k_ * (1.0 - 0.125 * q * q) * q * q;
|
||||
break;
|
||||
default:
|
||||
h += 0.5 * k_ * q * q;
|
||||
break;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void NegGradV::Mult(const Vector &x, Vector &y) const
|
||||
{
|
||||
switch (prob_)
|
||||
{
|
||||
case 1:
|
||||
y(0) = - k_* sin(x(0));
|
||||
break;
|
||||
case 2:
|
||||
y(0) = - k_ * x(0) * exp(-0.5 * x(0) * x(0));
|
||||
break;
|
||||
case 3:
|
||||
y(0) = - k_ * (1.0 + 2.0 * x(0) * x(0)) * x(0);
|
||||
break;
|
||||
case 4:
|
||||
y(0) = - k_ * (1.0 - 0.25 * x(0) * x(0)) * x(0);
|
||||
break;
|
||||
default:
|
||||
y(0) = - k_ * x(0);
|
||||
break;
|
||||
};
|
||||
}
|
||||
@@ -1,477 +0,0 @@
|
||||
// MFEM Example 21
|
||||
//
|
||||
// Compile with: make ex21
|
||||
//
|
||||
// Sample runs: ex21 -m ../data/inline-segment.mesh -o 3
|
||||
// ex21 -m ../data/inline-tri.mesh -o 3
|
||||
// ex21 -m ../data/inline-quad.mesh -o 3
|
||||
// ex21 -m ../data/inline-quad.mesh -o 3 -p 1
|
||||
// ex21 -m ../data/inline-quad.mesh -o 3 -p 2
|
||||
// ex21 -m ../data/inline-tet.mesh -o 2
|
||||
// ex21 -m ../data/inline-hex.mesh -o 2
|
||||
// ex21 -m ../data/inline-hex.mesh -o 2 -p 1
|
||||
// ex21 -m ../data/inline-hex.mesh -o 2 -p 2
|
||||
// ex21 -m ../data/star.mesh -o 2 -sigma 10.0
|
||||
//
|
||||
// Description: This example code demonstrates the use of MFEM to define and
|
||||
// solve simple complex-valued linear systems. We implement three
|
||||
// variants of a damped harmonic oscillator:
|
||||
//
|
||||
// 1) A scalar H1 field
|
||||
// -Div(a Grad u) - omega^2 b u + i omega c u = 0
|
||||
//
|
||||
// 2) A vector H(Curl) field
|
||||
// Curl(a Curl u) - omega^2 b u + i omega c u = 0
|
||||
//
|
||||
// 3) A vector H(Div) field
|
||||
// -Grad(a Div u) - omega^2 b u + i omega c u = 0
|
||||
//
|
||||
// In each case the field is driven by a forced oscillation, with
|
||||
// angular frequency omega, imposed at the boundary or a portion
|
||||
// of the boundary.
|
||||
//
|
||||
// In electromagnetics the coefficients are typically named the
|
||||
// permeability, mu = 1/a, permittivity, epsilon = b, and
|
||||
// conductivity, sigma = c. The user can specify these constants
|
||||
// using either set of names.
|
||||
//
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
static double mu_ = 1.0;
|
||||
static double epsilon_ = 1.0;
|
||||
static double sigma_ = 20.0;
|
||||
static double omega_ = 10.0;
|
||||
|
||||
double u0_real_exact(const Vector &);
|
||||
double u0_imag_exact(const Vector &);
|
||||
|
||||
void u1_real_exact(const Vector &, Vector &);
|
||||
void u1_imag_exact(const Vector &, Vector &);
|
||||
|
||||
void u2_real_exact(const Vector &, Vector &);
|
||||
void u2_imag_exact(const Vector &, Vector &);
|
||||
|
||||
bool check_for_inline_mesh(const char * mesh_file);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Parse command-line options.
|
||||
const char *mesh_file = "../data/inline-quad.mesh";
|
||||
int ref_levels = 0;
|
||||
int order = 1;
|
||||
int prob = 0;
|
||||
double freq = -1.0;
|
||||
double a_coef = 0.0;
|
||||
bool visualization = 1;
|
||||
bool herm_conv = true;
|
||||
bool exact_sol = true;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&ref_levels, "-r", "--refine",
|
||||
"Number of times to refine the mesh uniformly.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&prob, "-p", "--problem-type",
|
||||
"Choose from 0: H_1, 1: H(Curl), or 2: H(Div) "
|
||||
"damped harmonic oscillator.");
|
||||
args.AddOption(&a_coef, "-a", "--stiffness-coef",
|
||||
"Stiffness coefficient (spring constant or 1/mu).");
|
||||
args.AddOption(&epsilon_, "-b", "--mass-coef",
|
||||
"Mass coefficient (or epsilon).");
|
||||
args.AddOption(&sigma_, "-c", "--damping-coef",
|
||||
"Damping coefficient (or sigma).");
|
||||
args.AddOption(&mu_, "-mu", "--permeability",
|
||||
"Permeability of free space (or 1/(spring constant)).");
|
||||
args.AddOption(&epsilon_, "-eps", "--permittivity",
|
||||
"Permittivity of free space (or mass constant).");
|
||||
args.AddOption(&sigma_, "-sigma", "--conductivity",
|
||||
"Conductivity (or damping constant).");
|
||||
args.AddOption(&freq, "-f", "--frequency",
|
||||
"Frequency (in Hz).");
|
||||
args.AddOption(&herm_conv, "-herm", "--hermitian", "-no-herm",
|
||||
"--no-hermitian", "Use convention for Hermitian operators.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
return 1;
|
||||
}
|
||||
args.PrintOptions(cout);
|
||||
|
||||
if ( a_coef != 0.0 )
|
||||
{
|
||||
mu_ = 1.0 / a_coef;
|
||||
}
|
||||
if ( freq > 0.0 )
|
||||
{
|
||||
omega_ = 2.0 * M_PI * freq;
|
||||
}
|
||||
|
||||
exact_sol = check_for_inline_mesh(mesh_file);
|
||||
if (exact_sol)
|
||||
{
|
||||
cout << "Identified an 'inline' mesh" << endl;
|
||||
}
|
||||
|
||||
ComplexOperator::Convention conv =
|
||||
herm_conv ? ComplexOperator::HERMITIAN : ComplexOperator::BLOCK_SYMMETRIC;
|
||||
|
||||
// 2. Read the mesh from the given mesh file. We can handle triangular,
|
||||
// quadrilateral, tetrahedral, hexahedral, surface and volume meshes
|
||||
// with the same code.
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
int dim = mesh->Dimension();
|
||||
|
||||
// 3. Refine the mesh to increase resolution. In this example we do
|
||||
// 'ref_levels' of uniform refinement where the user specifies
|
||||
// the number of levels with the '-r' option.
|
||||
for (int l = 0; l < ref_levels; l++)
|
||||
{
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 4. Define a finite element space on the mesh. Here we use continuous
|
||||
// Lagrange, Nedelec, or Raviart-Thomas finite elements of the specified
|
||||
// order.
|
||||
if (dim == 1 && prob != 0 )
|
||||
{
|
||||
cout << "Switching to problem type 0, H1 basis functions, "
|
||||
<< "for 1 dimensional mesh." << endl;
|
||||
prob = 0;
|
||||
}
|
||||
|
||||
FiniteElementCollection *fec;
|
||||
switch (prob)
|
||||
{
|
||||
case 0: fec = new H1_FECollection(order, dim); break;
|
||||
case 1: fec = new ND_FECollection(order, dim); break;
|
||||
case 2: fec = new RT_FECollection(order - 1, dim); break;
|
||||
}
|
||||
FiniteElementSpace *fespace = new FiniteElementSpace(mesh, fec);
|
||||
cout << "Number of finite element unknowns: " << fespace->GetTrueVSize()
|
||||
<< endl;
|
||||
|
||||
// 5. Determine the list of true (i.e. conforming) essential boundary dofs.
|
||||
// In this example, the boundary conditions are defined based on the type
|
||||
// of mesh and the problem type.
|
||||
Array<int> ess_tdof_list;
|
||||
Array<int> ess_bdr;
|
||||
if (mesh->bdr_attributes.Size())
|
||||
{
|
||||
ess_bdr.SetSize(mesh->bdr_attributes.Max());
|
||||
ess_bdr = 1;
|
||||
if (exact_sol)
|
||||
{
|
||||
switch (prob)
|
||||
{
|
||||
case 0: ess_bdr = 0; ess_bdr[0] = 1; break;
|
||||
default: ess_bdr = 1; ess_bdr[2] = 0; break;
|
||||
}
|
||||
}
|
||||
fespace->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
}
|
||||
|
||||
// 6. Set up the linear form b(.) which corresponds to the
|
||||
// right-hand side of the FEM linear system.
|
||||
ComplexLinearForm b(fespace, conv);
|
||||
b.Vector::operator=(0.0);
|
||||
|
||||
// 7. Define the solution vector u as a finite element grid function
|
||||
// corresponding to fespace. Initialize u with initial guess of 1+0i
|
||||
// or the exact solution if it is known.
|
||||
ComplexGridFunction u(fespace);
|
||||
ComplexGridFunction * u_exact = NULL;
|
||||
if (exact_sol) { u_exact = new ComplexGridFunction(fespace); }
|
||||
|
||||
FunctionCoefficient u0_r(u0_real_exact);
|
||||
FunctionCoefficient u0_i(u0_imag_exact);
|
||||
VectorFunctionCoefficient u1_r(dim, u1_real_exact);
|
||||
VectorFunctionCoefficient u1_i(dim, u1_imag_exact);
|
||||
VectorFunctionCoefficient u2_r(dim, u2_real_exact);
|
||||
VectorFunctionCoefficient u2_i(dim, u2_imag_exact);
|
||||
|
||||
ConstantCoefficient zeroCoef(0.0);
|
||||
ConstantCoefficient oneCoef(1.0);
|
||||
|
||||
Vector zeroVec(dim); zeroVec = 0.0;
|
||||
Vector oneVec(dim); oneVec = 0.0; oneVec[(prob==2)?(dim-1):0] = 1.0;
|
||||
VectorConstantCoefficient zeroVecCoef(zeroVec);
|
||||
VectorConstantCoefficient oneVecCoef(oneVec);
|
||||
|
||||
switch (prob)
|
||||
{
|
||||
case 0:
|
||||
u.ProjectBdrCoefficient(oneCoef, zeroCoef, ess_bdr);
|
||||
if (exact_sol) { u_exact->ProjectCoefficient(u0_r, u0_i); }
|
||||
break;
|
||||
case 1:
|
||||
u.ProjectBdrCoefficientTangent(oneVecCoef, zeroVecCoef, ess_bdr);
|
||||
if (exact_sol) { u_exact->ProjectCoefficient(u1_r, u1_i); }
|
||||
break;
|
||||
case 2:
|
||||
u.ProjectBdrCoefficientNormal(oneVecCoef, zeroVecCoef, ess_bdr);
|
||||
if (exact_sol) { u_exact->ProjectCoefficient(u2_r, u2_i); }
|
||||
break;
|
||||
}
|
||||
|
||||
if (visualization && exact_sol)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock_r(vishost, visport);
|
||||
socketstream sol_sock_i(vishost, visport);
|
||||
sol_sock_r.precision(8);
|
||||
sol_sock_i.precision(8);
|
||||
sol_sock_r << "solution\n" << *mesh << u_exact->real()
|
||||
<< "window_title 'Exact Real Part'" << flush;
|
||||
sol_sock_i << "solution\n" << *mesh << u_exact->imag()
|
||||
<< "window_title 'Exact Imaginary Part'" << flush;
|
||||
}
|
||||
|
||||
// 8. Set up the sesquilinear form a(.,.) on the finite element
|
||||
// space corresponding to the damped harmonic oscillator operator
|
||||
// of the appropriate type:
|
||||
//
|
||||
// 0) A scalar H1 field
|
||||
// -Div(a Grad) - omega^2 b + i omega c
|
||||
//
|
||||
// 1) A vector H(Curl) field
|
||||
// Curl(a Curl) - omega^2 b + i omega c
|
||||
//
|
||||
// 2) A vector H(Div) field
|
||||
// -Grad(a Div) - omega^2 b + i omega c
|
||||
//
|
||||
ConstantCoefficient stiffnessCoef(1.0/mu_);
|
||||
ConstantCoefficient massCoef(-omega_ * omega_ * epsilon_);
|
||||
ConstantCoefficient lossCoef(omega_ * sigma_);
|
||||
ConstantCoefficient negMassCoef(omega_ * omega_ * epsilon_);
|
||||
|
||||
SesquilinearForm *a = new SesquilinearForm(fespace, conv);
|
||||
switch (prob)
|
||||
{
|
||||
case 0:
|
||||
a->AddDomainIntegrator(new DiffusionIntegrator(stiffnessCoef),
|
||||
NULL);
|
||||
a->AddDomainIntegrator(new MassIntegrator(massCoef),
|
||||
new MassIntegrator(lossCoef));
|
||||
break;
|
||||
case 1:
|
||||
a->AddDomainIntegrator(new CurlCurlIntegrator(stiffnessCoef),
|
||||
NULL);
|
||||
a->AddDomainIntegrator(new VectorFEMassIntegrator(massCoef),
|
||||
new VectorFEMassIntegrator(lossCoef));
|
||||
break;
|
||||
case 2:
|
||||
a->AddDomainIntegrator(new DivDivIntegrator(stiffnessCoef),
|
||||
NULL);
|
||||
a->AddDomainIntegrator(new VectorFEMassIntegrator(massCoef),
|
||||
new VectorFEMassIntegrator(lossCoef));
|
||||
break;
|
||||
}
|
||||
|
||||
// 9. Assemble the bilinear form and the corresponding linear
|
||||
// system, applying any necessary transformations such as:
|
||||
// assembly, eliminating boundary conditions, applying conforming
|
||||
// constraints for non-conforming AMR, etc.
|
||||
a->Assemble();
|
||||
|
||||
OperatorHandle A;
|
||||
Vector B, U;
|
||||
|
||||
a->FormLinearSystem(ess_tdof_list, u, b, A, U, B);
|
||||
u = 0.0;
|
||||
U = 0.0;
|
||||
|
||||
{
|
||||
ComplexSparseMatrix * Asp =
|
||||
dynamic_cast<ComplexSparseMatrix*>(A.Ptr());
|
||||
|
||||
cout << "Size of linear system: "
|
||||
<< 2 * Asp->real().Width() << endl << endl;
|
||||
}
|
||||
|
||||
// 10. Define and apply a GMRES solver for AU=B.
|
||||
{
|
||||
GMRESSolver gmres;
|
||||
gmres.SetOperator(*A.Ptr());
|
||||
gmres.SetRelTol(1e-12);
|
||||
gmres.SetMaxIter(1000);
|
||||
gmres.SetPrintLevel(1);
|
||||
gmres.Mult(B, U);
|
||||
}
|
||||
|
||||
// 11. Recover the solution as a finite element grid function and
|
||||
// compute the errors if the exact solution is known.
|
||||
a->RecoverFEMSolution(U, b, u);
|
||||
|
||||
if (exact_sol)
|
||||
{
|
||||
double err_r = -1.0;
|
||||
double err_i = -1.0;
|
||||
|
||||
switch (prob)
|
||||
{
|
||||
case 0:
|
||||
err_r = u.real().ComputeL2Error(u0_r);
|
||||
err_i = u.imag().ComputeL2Error(u0_i);
|
||||
break;
|
||||
case 1:
|
||||
err_r = u.real().ComputeL2Error(u1_r);
|
||||
err_i = u.imag().ComputeL2Error(u1_i);
|
||||
break;
|
||||
case 2:
|
||||
err_r = u.real().ComputeL2Error(u2_r);
|
||||
err_i = u.imag().ComputeL2Error(u2_i);
|
||||
break;
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
cout << "|| Re (u_h - u) ||_{L^2} = " << err_r << endl;
|
||||
cout << "|| Im (u_h - u) ||_{L^2} = " << err_i << endl;
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
// 12. Save the refined mesh and the solution. This output can be
|
||||
// viewed later using GLVis: "glvis -m mesh -g sol".
|
||||
{
|
||||
ofstream mesh_ofs("refined.mesh");
|
||||
mesh_ofs.precision(8);
|
||||
mesh->Print(mesh_ofs);
|
||||
|
||||
ofstream sol_r_ofs("sol_r.gf");
|
||||
ofstream sol_i_ofs("sol_i.gf");
|
||||
sol_r_ofs.precision(8);
|
||||
sol_i_ofs.precision(8);
|
||||
u.real().Save(sol_r_ofs);
|
||||
u.imag().Save(sol_i_ofs);
|
||||
}
|
||||
|
||||
// 13. Send the solution by socket to a GLVis server.
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock_r(vishost, visport);
|
||||
socketstream sol_sock_i(vishost, visport);
|
||||
sol_sock_r.precision(8);
|
||||
sol_sock_i.precision(8);
|
||||
sol_sock_r << "solution\n" << *mesh << u.real()
|
||||
<< "window_title 'Comp Real Part'" << flush;
|
||||
sol_sock_i << "solution\n" << *mesh << u.imag()
|
||||
<< "window_title 'Comp Imaginary Part'" << flush;
|
||||
}
|
||||
if (visualization && exact_sol)
|
||||
{
|
||||
*u_exact -= u;
|
||||
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock_r(vishost, visport);
|
||||
socketstream sol_sock_i(vishost, visport);
|
||||
sol_sock_r.precision(8);
|
||||
sol_sock_i.precision(8);
|
||||
sol_sock_r << "solution\n" << *mesh << u_exact->real()
|
||||
<< "window_title 'Exact-Comp Real Part'" << flush;
|
||||
sol_sock_i << "solution\n" << *mesh << u_exact->imag()
|
||||
<< "window_title 'Exact-Comp Imaginary Part'" << flush;
|
||||
}
|
||||
if (visualization)
|
||||
{
|
||||
GridFunction u_t(fespace);
|
||||
u_t = u.real();
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock(vishost, visport);
|
||||
sol_sock.precision(8);
|
||||
sol_sock << "solution\n" << *mesh << u_t
|
||||
<< "window_title 'Harmonic Solution (t = 0.0 T)'"
|
||||
<< "pause\n" << flush;
|
||||
|
||||
cout << "GLVis visualization paused."
|
||||
<< " Press space (in the GLVis window) to resume it.\n";
|
||||
int num_frames = 32;
|
||||
int i = 0;
|
||||
while (sol_sock)
|
||||
{
|
||||
double t = (double)(i % num_frames) / num_frames;
|
||||
ostringstream oss;
|
||||
oss << "Harmonic Solution (t = " << t << " T)";
|
||||
|
||||
add(cos( 2.0 * M_PI * t), u.real(),
|
||||
sin(-2.0 * M_PI * t), u.imag(), u_t);
|
||||
sol_sock << "solution\n" << *mesh << u_t
|
||||
<< "window_title '" << oss.str() << "'" << flush;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// 14. Free the used memory.
|
||||
delete a;
|
||||
delete u_exact;
|
||||
delete fespace;
|
||||
delete fec;
|
||||
delete mesh;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool check_for_inline_mesh(const char * mesh_file)
|
||||
{
|
||||
string file(mesh_file);
|
||||
size_t p0 = file.find_last_of("/");
|
||||
string s0 = file.substr((p0==string::npos)?0:(p0+1),7);
|
||||
return s0 == "inline-";
|
||||
}
|
||||
|
||||
complex<double> u0_exact(const Vector &x)
|
||||
{
|
||||
int dim = x.Size();
|
||||
complex<double> i(0.0, 1.0);
|
||||
complex<double> alpha = (epsilon_ * omega_ - i * sigma_);
|
||||
complex<double> kappa = std::sqrt(mu_ * omega_* alpha);
|
||||
return std::exp(-i * kappa * x[dim - 1]);
|
||||
}
|
||||
|
||||
double u0_real_exact(const Vector &x)
|
||||
{
|
||||
return u0_exact(x).real();
|
||||
}
|
||||
|
||||
double u0_imag_exact(const Vector &x)
|
||||
{
|
||||
return u0_exact(x).imag();
|
||||
}
|
||||
|
||||
void u1_real_exact(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
v.SetSize(dim); v = 0.0; v[0] = u0_real_exact(x);
|
||||
}
|
||||
|
||||
void u1_imag_exact(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
v.SetSize(dim); v = 0.0; v[0] = u0_imag_exact(x);
|
||||
}
|
||||
|
||||
void u2_real_exact(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
v.SetSize(dim); v = 0.0; v[dim-1] = u0_real_exact(x);
|
||||
}
|
||||
|
||||
void u2_imag_exact(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
v.SetSize(dim); v = 0.0; v[dim-1] = u0_imag_exact(x);
|
||||
}
|
||||
@@ -1,658 +0,0 @@
|
||||
// MFEM Example 21 - Parallel Version
|
||||
//
|
||||
// Compile with: make ex21p
|
||||
//
|
||||
// Sample runs: mpirun -np 4 ex21p -m ../data/inline-segment.mesh -o 3
|
||||
// mpirun -np 4 ex21p -m ../data/inline-tri.mesh -o 3
|
||||
// mpirun -np 4 ex21p -m ../data/inline-quad.mesh -o 3
|
||||
// mpirun -np 4 ex21p -m ../data/inline-quad.mesh -o 3 -p 1
|
||||
// mpirun -np 4 ex21p -m ../data/inline-quad.mesh -o 3 -p 2
|
||||
// mpirun -np 4 ex21p -m ../data/inline-tet.mesh -o 2
|
||||
// mpirun -np 4 ex21p -m ../data/inline-hex.mesh -o 2
|
||||
// mpirun -np 4 ex21p -m ../data/inline-hex.mesh -o 2 -p 1
|
||||
// mpirun -np 4 ex21p -m ../data/inline-hex.mesh -o 2 -p 2
|
||||
// mpirun -np 4 ex21p -m ../data/star.mesh -o 2 -sigma 10.0
|
||||
//
|
||||
// Description: This example code demonstrates the use of MFEM to define and
|
||||
// solve simple complex-valued linear systems. We implement three
|
||||
// variants of a damped harmonic oscillator:
|
||||
//
|
||||
// 1) A scalar H1 field
|
||||
// -Div(a Grad u) - omega^2 b u + i omega c u = 0
|
||||
//
|
||||
// 2) A vector H(Curl) field
|
||||
// Curl(a Curl u) - omega^2 b u + i omega c u = 0
|
||||
//
|
||||
// 3) A vector H(Div) field
|
||||
// -Grad(a Div u) - omega^2 b u + i omega c u = 0
|
||||
//
|
||||
// In each case the field is driven by a forced oscillation, with
|
||||
// angular frequency omega, imposed at the boundary or a portion
|
||||
// of the boundary.
|
||||
//
|
||||
// In electromagnetics the coefficients are typically named the
|
||||
// permeability, mu = 1/a, permittivity, epsilon = b, and
|
||||
// conductivity, sigma = c. The user can specify these constants
|
||||
// using either set of names.
|
||||
//
|
||||
//#define MFEM_STRUMPACK_SRC
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "mfem.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
static double mu_ = 1.0;
|
||||
static double epsilon_ = 1.0;
|
||||
static double sigma_ = 20.0;
|
||||
static double omega_ = 10.0;
|
||||
|
||||
double u0_real_exact(const Vector &);
|
||||
double u0_imag_exact(const Vector &);
|
||||
|
||||
void u1_real_exact(const Vector &, Vector &);
|
||||
void u1_imag_exact(const Vector &, Vector &);
|
||||
|
||||
void u2_real_exact(const Vector &, Vector &);
|
||||
void u2_imag_exact(const Vector &, Vector &);
|
||||
|
||||
bool check_for_inline_mesh(const char * mesh_file);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Initialize MPI.
|
||||
int num_procs, myid;
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm comm = MPI_COMM_WORLD;
|
||||
MPI_Comm_size(comm, &num_procs);
|
||||
MPI_Comm_rank(comm, &myid);
|
||||
|
||||
// 2. Parse command-line options.
|
||||
const char *mesh_file = "../data/inline-quad.mesh";
|
||||
int ser_ref_levels = 1;
|
||||
int par_ref_levels = 1;
|
||||
int order = 1;
|
||||
int prob = 0;
|
||||
double freq = -1.0;
|
||||
double a_coef = 0.0;
|
||||
bool visualization = 1;
|
||||
bool herm_conv = true;
|
||||
bool exact_sol = true;
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
bool strumpack = false;
|
||||
#endif
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
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",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&prob, "-p", "--problem-type",
|
||||
"Choose from 0: H_1, 1: H(Curl), or 2: H(Div) "
|
||||
"damped harmonic oscillator.");
|
||||
args.AddOption(&a_coef, "-a", "--stiffness-coef",
|
||||
"Stiffness coefficient (spring constant or 1/mu).");
|
||||
args.AddOption(&epsilon_, "-b", "--mass-coef",
|
||||
"Mass coefficient (or epsilon).");
|
||||
args.AddOption(&sigma_, "-c", "--damping-coef",
|
||||
"Damping coefficient (or sigma).");
|
||||
args.AddOption(&mu_, "-mu", "--permeability",
|
||||
"Permeability of free space (or 1/(spring constant)).");
|
||||
args.AddOption(&epsilon_, "-eps", "--permittivity",
|
||||
"Permittivity of free space (or mass constant).");
|
||||
args.AddOption(&sigma_, "-sigma", "--conductivity",
|
||||
"Conductivity (or damping constant).");
|
||||
args.AddOption(&freq, "-f", "--frequency",
|
||||
"Frequency (in Hz).");
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
args.AddOption(&strumpack, "-strumpack", "--strumpack-solver",
|
||||
"-no-strumpack", "--no-strumpack-solver",
|
||||
"Use STRUMPACK's double complex linear solver.");
|
||||
#endif
|
||||
args.AddOption(&herm_conv, "-herm", "--hermitian", "-no-herm",
|
||||
"--no-hermitian", "Use convention for Hermitian operators.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
}
|
||||
MPI_Finalize();
|
||||
return 1;
|
||||
}
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
|
||||
if ( a_coef != 0.0 )
|
||||
{
|
||||
mu_ = 1.0 / a_coef;
|
||||
}
|
||||
if ( freq > 0.0 )
|
||||
{
|
||||
omega_ = 2.0 * M_PI * freq;
|
||||
}
|
||||
|
||||
exact_sol = check_for_inline_mesh(mesh_file);
|
||||
if (myid == 0 && exact_sol)
|
||||
{
|
||||
cout << "Identified an 'inline' mesh" << endl;
|
||||
}
|
||||
|
||||
ComplexOperator::Convention conv =
|
||||
herm_conv ? ComplexOperator::HERMITIAN : ComplexOperator::BLOCK_SYMMETRIC;
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
|
||||
// and volume meshes with the same code.
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
int dim = mesh->Dimension();
|
||||
|
||||
// 4. Refine the serial mesh on all processors to increase the resolution.
|
||||
for (int l = 0; l < ser_ref_levels; l++)
|
||||
{
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 5. Define a 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 l = 0; l < par_ref_levels; l++)
|
||||
{
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
|
||||
// 6. Define a parallel finite element space on the parallel
|
||||
// mesh. Here we use continuous Lagrange, Nedelec, or
|
||||
// Raviart-Thomas finite elements of the specified order.
|
||||
if (dim == 1 && prob != 0 )
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Switching to problem type 0, H1 basis functions, "
|
||||
<< "for 1 dimensional mesh." << endl;
|
||||
}
|
||||
prob = 0;
|
||||
}
|
||||
|
||||
FiniteElementCollection *fec;
|
||||
switch (prob)
|
||||
{
|
||||
case 0: fec = new H1_FECollection(order, dim); break;
|
||||
case 1: fec = new ND_FECollection(order, dim); break;
|
||||
case 2: fec = new RT_FECollection(order - 1, dim); break;
|
||||
}
|
||||
ParFiniteElementSpace *fespace = new ParFiniteElementSpace(pmesh, fec);
|
||||
HYPRE_Int size = fespace->GlobalTrueVSize();
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Number of finite element unknowns: " << size << endl;
|
||||
}
|
||||
|
||||
// 7. Determine the list of true (i.e. parallel conforming) essential
|
||||
// boundary dofs. In this example, the boundary conditions are defined
|
||||
// based on the type of mesh and the problem type.
|
||||
Array<int> ess_tdof_list;
|
||||
Array<int> ess_bdr;
|
||||
if (pmesh->bdr_attributes.Size())
|
||||
{
|
||||
ess_bdr.SetSize(pmesh->bdr_attributes.Max());
|
||||
ess_bdr = 1;
|
||||
if (exact_sol)
|
||||
{
|
||||
switch (prob)
|
||||
{
|
||||
case 0: ess_bdr = 0; ess_bdr[0] = 1; break;
|
||||
default: ess_bdr = 1; ess_bdr[2] = 0; break;
|
||||
}
|
||||
}
|
||||
fespace->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
}
|
||||
|
||||
// 8. Set up the parallel linear form b(.) which corresponds to the
|
||||
// right-hand side of the FEM linear system.
|
||||
ParComplexLinearForm b(fespace, conv);
|
||||
b.Vector::operator=(0.0);
|
||||
|
||||
// 9. Define the solution vector u as a parallel finite element
|
||||
// grid function corresponding to fespace. Initialize u with
|
||||
// initial guess of 1+0i or the exact solution if it is known.
|
||||
ParComplexGridFunction u(fespace);
|
||||
ParComplexGridFunction * u_exact = NULL;
|
||||
if (exact_sol) { u_exact = new ParComplexGridFunction(fespace); }
|
||||
|
||||
FunctionCoefficient u0_r(u0_real_exact);
|
||||
FunctionCoefficient u0_i(u0_imag_exact);
|
||||
VectorFunctionCoefficient u1_r(dim, u1_real_exact);
|
||||
VectorFunctionCoefficient u1_i(dim, u1_imag_exact);
|
||||
VectorFunctionCoefficient u2_r(dim, u2_real_exact);
|
||||
VectorFunctionCoefficient u2_i(dim, u2_imag_exact);
|
||||
|
||||
ConstantCoefficient zeroCoef(0.0);
|
||||
ConstantCoefficient oneCoef(1.0);
|
||||
|
||||
Vector zeroVec(dim); zeroVec = 0.0;
|
||||
Vector oneVec(dim); oneVec = 0.0; oneVec[(prob==2)?(dim-1):0] = 1.0;
|
||||
VectorConstantCoefficient zeroVecCoef(zeroVec);
|
||||
VectorConstantCoefficient oneVecCoef(oneVec);
|
||||
|
||||
switch (prob)
|
||||
{
|
||||
case 0:
|
||||
u.ProjectBdrCoefficient(oneCoef, zeroCoef, ess_bdr);
|
||||
if (exact_sol) { u_exact->ProjectCoefficient(u0_r, u0_i); }
|
||||
break;
|
||||
case 1:
|
||||
u.ProjectBdrCoefficientTangent(oneVecCoef, zeroVecCoef, ess_bdr);
|
||||
if (exact_sol) { u_exact->ProjectCoefficient(u1_r, u1_i); }
|
||||
break;
|
||||
case 2:
|
||||
u.ProjectBdrCoefficientNormal(oneVecCoef, zeroVecCoef, ess_bdr);
|
||||
if (exact_sol) { u_exact->ProjectCoefficient(u2_r, u2_i); }
|
||||
break;
|
||||
}
|
||||
|
||||
if (visualization && exact_sol)
|
||||
{
|
||||
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;
|
||||
sol_sock_i << "solution\n" << *pmesh << u_exact->imag()
|
||||
<< "window_title 'Exact Imaginary Part'" << flush;
|
||||
}
|
||||
|
||||
// 10. Set up the parallel sesquilinear form a(.,.) on the finite element
|
||||
// space corresponding to the damped harmonic oscillator operator
|
||||
// of the appropriate type:
|
||||
//
|
||||
// 0) A scalar H1 field
|
||||
// -Div(a Grad) - omega^2 b + i omega c
|
||||
//
|
||||
// 1) A vector H(Curl) field
|
||||
// Curl(a Curl) - omega^2 b + i omega c
|
||||
//
|
||||
// 2) A vector H(Div) field
|
||||
// -Grad(a Div) - omega^2 b + i omega c
|
||||
//
|
||||
ConstantCoefficient stiffnessCoef(1.0/mu_);
|
||||
ConstantCoefficient massCoef(-omega_ * omega_ * epsilon_);
|
||||
ConstantCoefficient lossCoef(omega_ * sigma_);
|
||||
ConstantCoefficient negMassCoef(omega_ * omega_ * epsilon_);
|
||||
|
||||
ParSesquilinearForm *a = new ParSesquilinearForm(fespace, conv);
|
||||
switch (prob)
|
||||
{
|
||||
case 0:
|
||||
a->AddDomainIntegrator(new DiffusionIntegrator(stiffnessCoef),
|
||||
NULL);
|
||||
a->AddDomainIntegrator(new MassIntegrator(massCoef),
|
||||
new MassIntegrator(lossCoef));
|
||||
break;
|
||||
case 1:
|
||||
a->AddDomainIntegrator(new CurlCurlIntegrator(stiffnessCoef),
|
||||
NULL);
|
||||
a->AddDomainIntegrator(new VectorFEMassIntegrator(massCoef),
|
||||
new VectorFEMassIntegrator(lossCoef));
|
||||
break;
|
||||
case 2:
|
||||
a->AddDomainIntegrator(new DivDivIntegrator(stiffnessCoef),
|
||||
NULL);
|
||||
a->AddDomainIntegrator(new VectorFEMassIntegrator(massCoef),
|
||||
new VectorFEMassIntegrator(lossCoef));
|
||||
break;
|
||||
}
|
||||
|
||||
// 10a. Set up the parallel bilinear form for the preconditioner
|
||||
// corresponding to the appropriate operator if the STRUMPACK solver
|
||||
// has not been selected.
|
||||
//
|
||||
// 0) A scalar H1 field
|
||||
// -Div(a Grad) - omega^2 b + omega c
|
||||
//
|
||||
// 1) A vector H(Curl) field
|
||||
// Curl(a Curl) + omega^2 b + omega c
|
||||
//
|
||||
// 2) A vector H(Div) field
|
||||
// -Grad(a Div) - omega^2 b + omega c
|
||||
//
|
||||
ParBilinearForm *pcOp = NULL;
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
if (!strumpack)
|
||||
#endif
|
||||
{
|
||||
pcOp = new ParBilinearForm(fespace);
|
||||
switch (prob)
|
||||
{
|
||||
case 0:
|
||||
pcOp->AddDomainIntegrator(new DiffusionIntegrator(stiffnessCoef));
|
||||
pcOp->AddDomainIntegrator(new MassIntegrator(massCoef));
|
||||
pcOp->AddDomainIntegrator(new MassIntegrator(lossCoef));
|
||||
break;
|
||||
case 1:
|
||||
pcOp->AddDomainIntegrator(new CurlCurlIntegrator(stiffnessCoef));
|
||||
pcOp->AddDomainIntegrator(new VectorFEMassIntegrator(negMassCoef));
|
||||
pcOp->AddDomainIntegrator(new VectorFEMassIntegrator(lossCoef));
|
||||
break;
|
||||
case 2:
|
||||
pcOp->AddDomainIntegrator(new DivDivIntegrator(stiffnessCoef));
|
||||
pcOp->AddDomainIntegrator(new VectorFEMassIntegrator(massCoef));
|
||||
pcOp->AddDomainIntegrator(new VectorFEMassIntegrator(lossCoef));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 11. Assemble the parallel bilinear form and the corresponding linear
|
||||
// system, applying any necessary transformations such as: parallel
|
||||
// assembly, eliminating boundary conditions, applying conforming
|
||||
// constraints for non-conforming AMR, etc.
|
||||
a->Assemble();
|
||||
if (pcOp) { pcOp->Assemble(); }
|
||||
|
||||
OperatorHandle A;
|
||||
Vector B, U;
|
||||
|
||||
a->FormLinearSystem(ess_tdof_list, u, b, A, U, B);
|
||||
u = 0.0;
|
||||
U = 0.0;
|
||||
|
||||
OperatorHandle PCOp;
|
||||
if (pcOp) { pcOp->FormSystemMatrix(ess_tdof_list, PCOp); }
|
||||
|
||||
if (myid == 0)
|
||||
{
|
||||
ComplexHypreParMatrix * Ahyp =
|
||||
dynamic_cast<ComplexHypreParMatrix*>(A.Ptr());
|
||||
|
||||
cout << "Size of linear system: "
|
||||
<< 2 * Ahyp->real().GetGlobalNumRows() << endl << endl;
|
||||
}
|
||||
|
||||
// 12. Define and apply a parallel FGMRES solver for AU=B with a
|
||||
// block diagonal preconditioner based on the appropriate multigrid
|
||||
// preconditioner from hypre or simply use STRUMPACK.
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
if (!strumpack)
|
||||
#endif
|
||||
{
|
||||
Array<HYPRE_Int> blockTrueOffsets;
|
||||
blockTrueOffsets.SetSize(3);
|
||||
blockTrueOffsets[0] = 0;
|
||||
blockTrueOffsets[1] = PCOp.Ptr()->Height();
|
||||
blockTrueOffsets[2] = PCOp.Ptr()->Height();
|
||||
blockTrueOffsets.PartialSum();
|
||||
|
||||
BlockDiagonalPreconditioner BDP(blockTrueOffsets);
|
||||
|
||||
Operator * pc_r = NULL;
|
||||
Operator * pc_i = NULL;
|
||||
|
||||
switch (prob)
|
||||
{
|
||||
case 0:
|
||||
pc_r =
|
||||
new HypreBoomerAMG(dynamic_cast<HypreParMatrix&>(*PCOp.Ptr()));
|
||||
pc_i = new ScaledOperator(pc_r,
|
||||
(conv == ComplexOperator::HERMITIAN) ?
|
||||
1.0:-1.0);
|
||||
break;
|
||||
case 1:
|
||||
pc_r = new HypreAMS(dynamic_cast<HypreParMatrix&>(*PCOp.Ptr()),
|
||||
fespace);
|
||||
pc_i = new ScaledOperator(pc_r,
|
||||
(conv == ComplexOperator::HERMITIAN) ?
|
||||
1.0:-1.0);
|
||||
break;
|
||||
case 2:
|
||||
if (dim == 2 )
|
||||
{
|
||||
pc_r = new HypreAMS(dynamic_cast<HypreParMatrix&>(*PCOp.Ptr()),
|
||||
fespace);
|
||||
}
|
||||
else
|
||||
{
|
||||
pc_r = new HypreADS(dynamic_cast<HypreParMatrix&>(*PCOp.Ptr()),
|
||||
fespace);
|
||||
}
|
||||
pc_i = new ScaledOperator(pc_r,
|
||||
(conv == ComplexOperator::HERMITIAN) ?
|
||||
1.0:-1.0);
|
||||
break;
|
||||
}
|
||||
BDP.SetDiagonalBlock(0, pc_r);
|
||||
BDP.SetDiagonalBlock(1, pc_i);
|
||||
BDP.owns_blocks = 0;
|
||||
|
||||
FGMRESSolver fgmres(MPI_COMM_WORLD);
|
||||
fgmres.SetPreconditioner(BDP);
|
||||
fgmres.SetOperator(*A.Ptr());
|
||||
fgmres.SetRelTol(1e-12);
|
||||
fgmres.SetMaxIter(1000);
|
||||
fgmres.SetPrintLevel(1);
|
||||
fgmres.Mult(B, U);
|
||||
}
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
else
|
||||
{
|
||||
ComplexHypreParMatrix * Ahyp =
|
||||
dynamic_cast<ComplexHypreParMatrix*>(A.Ptr());
|
||||
|
||||
STRUMPACKRowLocCmplxMatrix A_strmp(Ahyp->real(), Ahyp->imag());
|
||||
|
||||
STRUMPACKCmplxSolver strmp(argc, argv, comm);
|
||||
|
||||
strmp.SetPrintFactorStatistics(true);
|
||||
strmp.SetPrintSolveStatistics(true);
|
||||
// strmp.SetKrylovSolver(strumpack::KrylovSolver::AUTO); // core dump
|
||||
strmp.SetKrylovSolver(strumpack::KrylovSolver::DIRECT); // core dump
|
||||
// strmp.SetKrylovSolver(strumpack::KrylovSolver::REFINE); // core dump
|
||||
// strmp.SetKrylovSolver(strumpack::KrylovSolver::PREC_GMRES); // index out of range asserts from strumpack::DenseMatrix
|
||||
// strmp.SetKrylovSolver(strumpack::KrylovSolver::GMRES); // WORKS
|
||||
strmp.SetReorderingStrategy(strumpack::ReorderingStrategy::METIS);
|
||||
strmp.SetOperator(A_strmp);
|
||||
strmp.SetFromCommandLine();
|
||||
strmp.Mult(B, U);
|
||||
}
|
||||
#endif
|
||||
|
||||
// 13. Recover the parallel grid function corresponding to U. This is the
|
||||
// local finite element solution on each processor.
|
||||
a->RecoverFEMSolution(U, b, u);
|
||||
|
||||
if (exact_sol)
|
||||
{
|
||||
double err_r = -1.0;
|
||||
double err_i = -1.0;
|
||||
|
||||
switch (prob)
|
||||
{
|
||||
case 0:
|
||||
err_r = u.real().ComputeL2Error(u0_r);
|
||||
err_i = u.imag().ComputeL2Error(u0_i);
|
||||
break;
|
||||
case 1:
|
||||
err_r = u.real().ComputeL2Error(u1_r);
|
||||
err_i = u.imag().ComputeL2Error(u1_i);
|
||||
break;
|
||||
case 2:
|
||||
err_r = u.real().ComputeL2Error(u2_r);
|
||||
err_i = u.imag().ComputeL2Error(u2_i);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( myid == 0 )
|
||||
{
|
||||
cout << endl;
|
||||
cout << "|| Re (u_h - u) ||_{L^2} = " << err_r << endl;
|
||||
cout << "|| Im (u_h - u) ||_{L^2} = " << err_i << endl;
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 14. 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;
|
||||
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;
|
||||
|
||||
ofstream mesh_ofs(mesh_name.str().c_str());
|
||||
mesh_ofs.precision(8);
|
||||
pmesh->Print(mesh_ofs);
|
||||
|
||||
ofstream sol_r_ofs(sol_r_name.str().c_str());
|
||||
ofstream sol_i_ofs(sol_i_name.str().c_str());
|
||||
sol_r_ofs.precision(8);
|
||||
sol_i_ofs.precision(8);
|
||||
u.real().Save(sol_r_ofs);
|
||||
u.imag().Save(sol_i_ofs);
|
||||
}
|
||||
|
||||
// 15. Send the solution by socket to a GLVis server.
|
||||
if (visualization)
|
||||
{
|
||||
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 'Comp Real Part'" << flush;
|
||||
sol_sock_i << "solution\n" << *pmesh << u.imag()
|
||||
<< "window_title 'Comp Imaginary Part'" << flush;
|
||||
}
|
||||
if (visualization && exact_sol)
|
||||
{
|
||||
*u_exact -= u;
|
||||
|
||||
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-Comp Real Part'" << flush;
|
||||
sol_sock_i << "solution\n" << *pmesh << u_exact->imag()
|
||||
<< "window_title 'Exact-Comp Imaginary Part'" << flush;
|
||||
}
|
||||
if (visualization)
|
||||
{
|
||||
ParGridFunction u_t(fespace);
|
||||
u_t = u.real();
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock(vishost, visport);
|
||||
sol_sock << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock.precision(8);
|
||||
sol_sock << "solution\n" << *pmesh << u_t
|
||||
<< "window_title 'Harmonic Solution (t = 0.0 T)'"
|
||||
<< "pause\n" << flush;
|
||||
if (myid == 0)
|
||||
cout << "GLVis visualization paused."
|
||||
<< " Press space (in the GLVis window) to resume it.\n";
|
||||
int num_frames = 32;
|
||||
int i = 0;
|
||||
while (sol_sock)
|
||||
{
|
||||
double t = (double)(i % num_frames) / num_frames;
|
||||
ostringstream oss;
|
||||
oss << "Harmonic Solution (t = " << t << " T)";
|
||||
|
||||
add(cos( 2.0 * M_PI * t), u.real(),
|
||||
sin(-2.0 * M_PI * t), u.imag(), u_t);
|
||||
sol_sock << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock << "solution\n" << *pmesh << u_t
|
||||
<< "window_title '" << oss.str() << "'" << flush;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// 16. Free the used memory.
|
||||
delete a;
|
||||
delete u_exact;
|
||||
delete pcOp;
|
||||
delete fespace;
|
||||
delete fec;
|
||||
delete pmesh;
|
||||
|
||||
MPI_Finalize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool check_for_inline_mesh(const char * mesh_file)
|
||||
{
|
||||
string file(mesh_file);
|
||||
size_t p0 = file.find_last_of("/");
|
||||
string s0 = file.substr((p0==string::npos)?0:(p0+1),7);
|
||||
return s0 == "inline-";
|
||||
}
|
||||
|
||||
complex<double> u0_exact(const Vector &x)
|
||||
{
|
||||
int dim = x.Size();
|
||||
complex<double> i(0.0, 1.0);
|
||||
complex<double> alpha = (epsilon_ * omega_ - i * sigma_);
|
||||
complex<double> kappa = std::sqrt(mu_ * omega_* alpha);
|
||||
return std::exp(-i * kappa * x[dim - 1]);
|
||||
}
|
||||
|
||||
double u0_real_exact(const Vector &x)
|
||||
{
|
||||
return u0_exact(x).real();
|
||||
}
|
||||
|
||||
double u0_imag_exact(const Vector &x)
|
||||
{
|
||||
return u0_exact(x).imag();
|
||||
}
|
||||
|
||||
void u1_real_exact(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
v.SetSize(dim); v = 0.0; v[0] = u0_real_exact(x);
|
||||
}
|
||||
|
||||
void u1_imag_exact(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
v.SetSize(dim); v = 0.0; v[0] = u0_imag_exact(x);
|
||||
}
|
||||
|
||||
void u2_real_exact(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
v.SetSize(dim); v = 0.0; v[dim-1] = u0_real_exact(x);
|
||||
}
|
||||
|
||||
void u2_imag_exact(const Vector &x, Vector &v)
|
||||
{
|
||||
int dim = x.Size();
|
||||
v.SetSize(dim); v = 0.0; v[dim-1] = u0_imag_exact(x);
|
||||
}
|
||||
@@ -1,310 +0,0 @@
|
||||
// MFEM Example 22
|
||||
//
|
||||
// Compile with: make ex22
|
||||
//
|
||||
// Sample runs: ex22
|
||||
// ex22 -o 3
|
||||
// ex22 -m ../data/beam-quad.mesh
|
||||
// ex22 -m ../data/beam-quad.mesh -o 3
|
||||
// ex22 -m ../data/beam-quad.mesh -o 3 -f 1
|
||||
// ex22 -m ../data/beam-tet.mesh
|
||||
// ex22 -m ../data/beam-tet.mesh -o 2
|
||||
// ex22 -m ../data/beam-hex.mesh
|
||||
// ex22 -m ../data/beam-hex.mesh -o 2
|
||||
//
|
||||
// Description: This is a version of Example 2 with a simple adaptive mesh
|
||||
// refinement loop. The problem being solved is again the linear
|
||||
// elasticity describing a multi-material cantilever beam.
|
||||
// The problem is solved on a sequence of meshes which
|
||||
// are locally refined in a conforming (triangles, tetrahedrons)
|
||||
// or non-conforming (quadrilaterals, hexahedra) manner according
|
||||
// to a simple ZZ error estimator.
|
||||
//
|
||||
// The example demonstrates MFEM's capability to work with both
|
||||
// conforming and nonconforming refinements, in 2D and 3D, on
|
||||
// linear and curved meshes. Interpolation of functions from
|
||||
// coarse to fine meshes, as well as persistent GLVis
|
||||
// visualization are also illustrated.
|
||||
//
|
||||
// We recommend viewing Examples 2 and 6 before viewing this
|
||||
// example.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Parse command-line options.
|
||||
const char *mesh_file = "../data/beam-tri.mesh";
|
||||
int order = 1;
|
||||
bool static_cond = false;
|
||||
int flux_averaging = 0;
|
||||
bool visualization = 1;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
|
||||
"--no-static-condensation", "Enable static condensation.");
|
||||
args.AddOption(&flux_averaging, "-f", "--flux-averaging",
|
||||
"Flux averaging: 0 - global, 1 - by mesh attribute.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
return 1;
|
||||
}
|
||||
args.PrintOptions(cout);
|
||||
|
||||
// 2. Read the mesh from the given mesh file. We can handle triangular,
|
||||
// quadrilateral, tetrahedral, and hexahedral meshes with the same code.
|
||||
Mesh mesh(mesh_file, 1, 1);
|
||||
int dim = mesh.Dimension();
|
||||
MFEM_VERIFY(mesh.SpaceDimension() == dim, "invalid mesh");
|
||||
|
||||
if (mesh.attributes.Max() < 2 || mesh.bdr_attributes.Max() < 2)
|
||||
{
|
||||
cerr << "\nInput mesh should have at least two materials and "
|
||||
<< "two boundary attributes! (See schematic in ex2.cpp)\n"
|
||||
<< endl;
|
||||
return 3;
|
||||
}
|
||||
|
||||
// 3. Since a NURBS mesh can currently only be refined uniformly, we need to
|
||||
// convert it to a piecewise-polynomial curved mesh. First we refine the
|
||||
// NURBS mesh a bit more and then project the curvature to quadratic Nodes.
|
||||
if (mesh.NURBSext)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
mesh.UniformRefinement();
|
||||
}
|
||||
mesh.SetCurvature(2);
|
||||
}
|
||||
|
||||
// 4. Define a finite element space on the mesh. The polynomial order is
|
||||
// one (linear) by default, but this can be changed on the command line.
|
||||
H1_FECollection fec(order, dim);
|
||||
FiniteElementSpace fespace(&mesh, &fec, dim);
|
||||
|
||||
// 5. As in Example 2, we set up the linear form b(.) which corresponds to
|
||||
// the right-hand side of the FEM linear system. In this case, b_i equals
|
||||
// the boundary integral of f*phi_i where f represents a "pull down"
|
||||
// force on the Neumann part of the boundary and phi_i are the basis
|
||||
// functions in the finite element fespace. The force is defined by the
|
||||
// VectorArrayCoefficient object f, which is a vector of Coefficient
|
||||
// objects. The fact that f is non-zero on boundary attribute 2 is
|
||||
// indicated by the use of piece-wise constants coefficient for its last
|
||||
// component. We don't assemble the discrete problem yet, this will be
|
||||
// done in the main loop.
|
||||
VectorArrayCoefficient f(dim);
|
||||
for (int i = 0; i < dim-1; i++)
|
||||
{
|
||||
f.Set(i, new ConstantCoefficient(0.0));
|
||||
}
|
||||
{
|
||||
Vector pull_force(mesh.bdr_attributes.Max());
|
||||
pull_force = 0.0;
|
||||
pull_force(1) = -1.0e-2;
|
||||
f.Set(dim-1, new PWConstCoefficient(pull_force));
|
||||
}
|
||||
|
||||
LinearForm b(&fespace);
|
||||
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
|
||||
// constants coefficient lambda and mu.
|
||||
Vector lambda(mesh.attributes.Max());
|
||||
lambda = 1.0;
|
||||
lambda(0) = lambda(1)*50;
|
||||
PWConstCoefficient lambda_func(lambda);
|
||||
Vector mu(mesh.attributes.Max());
|
||||
mu = 1.0;
|
||||
mu(0) = mu(1)*50;
|
||||
PWConstCoefficient mu_func(mu);
|
||||
|
||||
BilinearForm a(&fespace);
|
||||
BilinearFormIntegrator *integ =
|
||||
new ElasticityIntegrator(lambda_func,mu_func);
|
||||
a.AddDomainIntegrator(integ);
|
||||
if (static_cond) { a.EnableStaticCondensation(); }
|
||||
|
||||
// 7. The solution vector x and the associated finite element grid function
|
||||
// will be maintained over the AMR iterations. We initialize it to zero.
|
||||
Vector zero_vec(dim);
|
||||
zero_vec = 0.0;
|
||||
VectorConstantCoefficient zero_vec_coeff(zero_vec);
|
||||
GridFunction x(&fespace);
|
||||
x = 0.0;
|
||||
|
||||
// 8. Determine the list of true (i.e. conforming) essential boundary dofs.
|
||||
// In this example, the boundary conditions are defined by marking only
|
||||
// boundary attribute 1 from the mesh as essential and converting it to a
|
||||
// list of true dofs. The conversion to true dofs will be done in the
|
||||
// main loop.
|
||||
Array<int> ess_bdr(mesh.bdr_attributes.Max());
|
||||
ess_bdr = 0;
|
||||
ess_bdr[0] = 1;
|
||||
|
||||
// 9. Connect to GLVis.
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock;
|
||||
if (visualization)
|
||||
{
|
||||
sol_sock.open(vishost, visport);
|
||||
sol_sock.precision(8);
|
||||
}
|
||||
|
||||
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
|
||||
// that uses the ComputeElementFlux method of the ElasticityIntegrator to
|
||||
// recover a smoothed flux (stress) that is subtracted from the element
|
||||
// flux to get an error indicator. We need to supply the space for the
|
||||
// smoothed flux: an (H1)^tdim (i.e., vector-valued) space is used here.
|
||||
// Here, tdim represents the number of components for a symmetric (dim x
|
||||
// dim) tensor.
|
||||
const int tdim = dim*(dim+1)/2;
|
||||
FiniteElementSpace flux_fespace(&mesh, &fec, tdim);
|
||||
ZienkiewiczZhuEstimator estimator(*integ, x, flux_fespace);
|
||||
estimator.SetFluxAveraging(flux_averaging);
|
||||
|
||||
// 11. A refiner selects and refines elements based on a refinement strategy.
|
||||
// The strategy here is to refine elements with errors larger than a
|
||||
// fraction of the maximum element error. Other strategies are possible.
|
||||
// The refiner will call the given error estimator.
|
||||
ThresholdRefiner refiner(estimator);
|
||||
refiner.SetTotalErrorFraction(0.7);
|
||||
|
||||
// 12. The main AMR loop. In each iteration we solve the problem on the
|
||||
// current mesh, visualize the solution, and refine the mesh.
|
||||
const int max_dofs = 50000;
|
||||
const int max_amr_itr = 20;
|
||||
for (int it = 0; it <= max_amr_itr; it++)
|
||||
{
|
||||
int cdofs = fespace.GetTrueVSize();
|
||||
cout << "\nAMR iteration " << it << endl;
|
||||
cout << "Number of unknowns: " << cdofs << endl;
|
||||
|
||||
// 13. Assemble the stiffness matrix and the right-hand side.
|
||||
a.Assemble();
|
||||
b.Assemble();
|
||||
|
||||
// 14. Set Dirichlet boundary values in the GridFunction x.
|
||||
// Determine the list of Dirichlet true DOFs in the linear system.
|
||||
Array<int> ess_tdof_list;
|
||||
x.ProjectBdrCoefficient(zero_vec_coeff, ess_bdr);
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
|
||||
// 15. Create the linear system: eliminate boundary conditions, constrain
|
||||
// hanging nodes and possibly apply other transformations. The system
|
||||
// will be solved for true (unconstrained) DOFs only.
|
||||
SparseMatrix A;
|
||||
Vector B, X;
|
||||
const int copy_interior = 1;
|
||||
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
|
||||
|
||||
#ifndef MFEM_USE_SUITESPARSE
|
||||
// 16. Define a simple symmetric Gauss-Seidel preconditioner and use it to
|
||||
// solve the linear system with PCG.
|
||||
GSSmoother M(A);
|
||||
PCG(A, M, B, X, 3, 2000, 1e-12, 0.0);
|
||||
#else
|
||||
// 16. If MFEM was compiled with SuiteSparse, use UMFPACK to solve the
|
||||
// the linear system.
|
||||
UMFPackSolver umf_solver;
|
||||
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
|
||||
umf_solver.SetOperator(A);
|
||||
umf_solver.Mult(B, X);
|
||||
#endif
|
||||
|
||||
// 17. After solving the linear system, reconstruct the solution as a
|
||||
// finite element GridFunction. Constrained nodes are interpolated
|
||||
// from true DOFs (it may therefore happen that x.Size() >= X.Size()).
|
||||
a.RecoverFEMSolution(X, b, x);
|
||||
|
||||
// 18. Send solution by socket to the GLVis server.
|
||||
if (visualization && sol_sock.good())
|
||||
{
|
||||
GridFunction nodes(&fespace), *nodes_p = &nodes;
|
||||
mesh.GetNodes(nodes);
|
||||
nodes += x;
|
||||
int own_nodes = 0;
|
||||
mesh.SwapNodes(nodes_p, own_nodes);
|
||||
x.Neg(); // visualize the backward displacement
|
||||
sol_sock << "solution\n" << mesh << x << flush;
|
||||
x.Neg();
|
||||
mesh.SwapNodes(nodes_p, own_nodes);
|
||||
if (it == 0)
|
||||
{
|
||||
sol_sock << "keys '" << ((dim == 2) ? "Rjl" : "") << "m'" << endl;
|
||||
}
|
||||
sol_sock << "window_title 'AMR iteration: " << it << "'\n"
|
||||
<< "pause" << endl;
|
||||
cout << "Visualization paused. "
|
||||
"Press <space> in the GLVis window to continue." << endl;
|
||||
}
|
||||
|
||||
if (cdofs > max_dofs)
|
||||
{
|
||||
cout << "Reached the maximum number of dofs. Stop." << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// 19. Call the refiner to modify the mesh. The refiner calls the error
|
||||
// estimator to obtain element errors, then it selects elements to be
|
||||
// refined and finally it modifies the mesh. The Stop() method can be
|
||||
// used to determine if a stopping criterion was met.
|
||||
refiner.Apply(mesh);
|
||||
if (refiner.Stop())
|
||||
{
|
||||
cout << "Stopping criterion satisfied. Stop." << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// 20. Update the space to reflect the new state of the mesh. Also,
|
||||
// interpolate the solution x so that it lies in the new space but
|
||||
// represents the same function. This saves solver iterations later
|
||||
// since we'll have a good initial guess of x in the next step.
|
||||
// Internally, FiniteElementSpace::Update() calculates an
|
||||
// interpolation matrix which is then used by GridFunction::Update().
|
||||
fespace.Update();
|
||||
x.Update();
|
||||
|
||||
// 21. Inform also the bilinear and linear forms that the space has
|
||||
// changed.
|
||||
a.Update();
|
||||
b.Update();
|
||||
}
|
||||
|
||||
{
|
||||
ofstream mesh_ref_out("ex22_reference.mesh");
|
||||
mesh_ref_out.precision(16);
|
||||
mesh.Print(mesh_ref_out);
|
||||
|
||||
ofstream mesh_out("ex22_deformed.mesh");
|
||||
mesh_out.precision(16);
|
||||
GridFunction nodes(&fespace), *nodes_p = &nodes;
|
||||
mesh.GetNodes(nodes);
|
||||
nodes += x;
|
||||
int own_nodes = 0;
|
||||
mesh.SwapNodes(nodes_p, own_nodes);
|
||||
mesh.Print(mesh_out);
|
||||
mesh.SwapNodes(nodes_p, own_nodes);
|
||||
|
||||
ofstream x_out("ex22_displacement.sol");
|
||||
x_out.precision(16);
|
||||
x.Save(x_out);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,366 +0,0 @@
|
||||
// MFEM Example 22
|
||||
//
|
||||
// Compile with: make ex22p
|
||||
//
|
||||
// Sample runs: mpirun -np 4 ex22p
|
||||
// mpirun -np 4 ex22p -o 3
|
||||
// mpirun -np 4 ex22p -m ../data/beam-quad.mesh
|
||||
// mpirun -np 4 ex22p -m ../data/beam-quad.mesh -o 3
|
||||
// mpirun -np 4 ex22p -m ../data/beam-tet.mesh
|
||||
// mpirun -np 4 ex22p -m ../data/beam-tet.mesh -o 2
|
||||
// mpirun -np 4 ex22p -m ../data/beam-hex.mesh
|
||||
// mpirun -np 4 ex22p -m ../data/beam-hex.mesh -o 2
|
||||
//
|
||||
// Description: This is a version of Example 2p with a simple adaptive mesh
|
||||
// refinement loop. The problem being solved is again the linear
|
||||
// elasticity describing a multi-material cantilever beam.
|
||||
// The problem is solved on a sequence of meshes which
|
||||
// are locally refined in a conforming (triangles, tetrahedrons)
|
||||
// or non-conforming (quadrilaterals, hexahedra) manner according
|
||||
// to a simple ZZ error estimator.
|
||||
//
|
||||
// The example demonstrates MFEM's capability to work with both
|
||||
// conforming and nonconforming refinements, in 2D and 3D, on
|
||||
// linear and curved meshes. Interpolation of functions from
|
||||
// coarse to fine meshes, as well as persistent GLVis
|
||||
// visualization are also illustrated.
|
||||
//
|
||||
// We recommend viewing Examples 2p and 6p before viewing this
|
||||
// example.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 0. Initialize MPI.
|
||||
int num_procs, myid;
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
|
||||
|
||||
// 1. Parse command-line options.
|
||||
const char *mesh_file = "../data/beam-tri.mesh";
|
||||
int serial_ref_levels = 0;
|
||||
int order = 1;
|
||||
bool static_cond = false;
|
||||
bool visualization = 1;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&serial_ref_levels, "-rs", "--refine-serial",
|
||||
"Number of uniform serial refinements (before parallel"
|
||||
" partitioning)");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
|
||||
"--no-static-condensation", "Enable static condensation.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
}
|
||||
MPI_Finalize();
|
||||
return 1;
|
||||
}
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
|
||||
// 2. Read the mesh from the given mesh file. We can handle triangular,
|
||||
// quadrilateral, tetrahedral, and hexahedral meshes with the same code.
|
||||
Mesh mesh(mesh_file, 1, 1);
|
||||
int dim = mesh.Dimension();
|
||||
MFEM_VERIFY(mesh.SpaceDimension() == dim, "invalid mesh");
|
||||
|
||||
if (mesh.attributes.Max() < 2 || mesh.bdr_attributes.Max() < 2)
|
||||
{
|
||||
cerr << "\nInput mesh should have at least two materials and "
|
||||
<< "two boundary attributes! (See schematic in ex2.cpp)\n"
|
||||
<< endl;
|
||||
MPI_Finalize();
|
||||
return 3;
|
||||
}
|
||||
|
||||
// 3. Refine the mesh before parallel partitioning. Since a NURBS mesh can
|
||||
// currently only be refined uniformly, we need to convert it to a
|
||||
// piecewise-polynomial curved mesh. First we refine the NURBS mesh a bit
|
||||
// more and then project the curvature to quadratic Nodes.
|
||||
if (mesh.NURBSext && serial_ref_levels == 0)
|
||||
{
|
||||
serial_ref_levels = 2;
|
||||
}
|
||||
for (int i = 0; i < serial_ref_levels; i++)
|
||||
{
|
||||
mesh.UniformRefinement();
|
||||
}
|
||||
if (mesh.NURBSext)
|
||||
{
|
||||
mesh.SetCurvature(2);
|
||||
}
|
||||
mesh.EnsureNCMesh();
|
||||
|
||||
ParMesh pmesh(MPI_COMM_WORLD, mesh);
|
||||
mesh.Clear();
|
||||
|
||||
// 4. Define a finite element space on the mesh. The polynomial order is
|
||||
// one (linear) by default, but this can be changed on the command line.
|
||||
H1_FECollection fec(order, dim);
|
||||
ParFiniteElementSpace fespace(&pmesh, &fec, dim);
|
||||
|
||||
// 5. As in Example 2, we set up the linear form b(.) which corresponds to
|
||||
// the right-hand side of the FEM linear system. In this case, b_i equals
|
||||
// the boundary integral of f*phi_i where f represents a "pull down"
|
||||
// force on the Neumann part of the boundary and phi_i are the basis
|
||||
// functions in the finite element fespace. The force is defined by the
|
||||
// VectorArrayCoefficient object f, which is a vector of Coefficient
|
||||
// objects. The fact that f is non-zero on boundary attribute 2 is
|
||||
// indicated by the use of piece-wise constants coefficient for its last
|
||||
// component. We don't assemble the discrete problem yet, this will be
|
||||
// done in the main loop.
|
||||
VectorArrayCoefficient f(dim);
|
||||
for (int i = 0; i < dim-1; i++)
|
||||
{
|
||||
f.Set(i, new ConstantCoefficient(0.0));
|
||||
}
|
||||
{
|
||||
Vector pull_force(pmesh.bdr_attributes.Max());
|
||||
pull_force = 0.0;
|
||||
pull_force(1) = -1.0e-2;
|
||||
f.Set(dim-1, new PWConstCoefficient(pull_force));
|
||||
}
|
||||
|
||||
ParLinearForm b(&fespace);
|
||||
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
|
||||
// constants coefficient lambda and mu.
|
||||
Vector lambda(pmesh.attributes.Max());
|
||||
lambda = 1.0;
|
||||
lambda(0) = lambda(1)*50;
|
||||
PWConstCoefficient lambda_func(lambda);
|
||||
Vector mu(pmesh.attributes.Max());
|
||||
mu = 1.0;
|
||||
mu(0) = mu(1)*50;
|
||||
PWConstCoefficient mu_func(mu);
|
||||
|
||||
ParBilinearForm a(&fespace);
|
||||
BilinearFormIntegrator *integ =
|
||||
new ElasticityIntegrator(lambda_func,mu_func);
|
||||
a.AddDomainIntegrator(integ);
|
||||
if (static_cond) { a.EnableStaticCondensation(); }
|
||||
|
||||
// 7. The solution vector x and the associated finite element grid function
|
||||
// will be maintained over the AMR iterations. We initialize it to zero.
|
||||
Vector zero_vec(dim);
|
||||
zero_vec = 0.0;
|
||||
VectorConstantCoefficient zero_vec_coeff(zero_vec);
|
||||
ParGridFunction x(&fespace);
|
||||
x = 0.0;
|
||||
|
||||
// 8. Determine the list of true (i.e. conforming) essential boundary dofs.
|
||||
// In this example, the boundary conditions are defined by marking only
|
||||
// boundary attribute 1 from the mesh as essential and converting it to a
|
||||
// list of true dofs. The conversion to true dofs will be done in the
|
||||
// main loop.
|
||||
Array<int> ess_bdr(pmesh.bdr_attributes.Max());
|
||||
ess_bdr = 0;
|
||||
ess_bdr[0] = 1;
|
||||
|
||||
// 9. GLVis visualization.
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock;
|
||||
|
||||
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
|
||||
// that uses the ComputeElementFlux method of the ElasticityIntegrator to
|
||||
// recover a smoothed flux (stress) that is subtracted from the element
|
||||
// flux to get an error indicator. We need to supply the space for the
|
||||
// smoothed flux: an (H1)^tdim (i.e., vector-valued) space is used here.
|
||||
// Here, tdim represents the number of components for a symmetric (dim x
|
||||
// dim) tensor.
|
||||
const int tdim = dim*(dim+1)/2;
|
||||
L2_FECollection flux_fec(order, dim);
|
||||
ParFiniteElementSpace flux_fespace(&pmesh, &flux_fec, tdim);
|
||||
ParFiniteElementSpace smooth_flux_fespace(&pmesh, &fec, tdim);
|
||||
L2ZienkiewiczZhuEstimator estimator(*integ, x, flux_fespace,
|
||||
smooth_flux_fespace);
|
||||
|
||||
// 11. A refiner selects and refines elements based on a refinement strategy.
|
||||
// The strategy here is to refine elements with errors larger than a
|
||||
// fraction of the maximum element error. Other strategies are possible.
|
||||
// The refiner will call the given error estimator.
|
||||
ThresholdRefiner refiner(estimator);
|
||||
refiner.SetTotalErrorFraction(0.7);
|
||||
|
||||
// 12. The main AMR loop. In each iteration we solve the problem on the
|
||||
// current mesh, visualize the solution, and refine the mesh.
|
||||
const int max_dofs = 50000;
|
||||
const int max_amr_itr = 20;
|
||||
for (int it = 0; it <= max_amr_itr; it++)
|
||||
{
|
||||
HYPRE_Int global_dofs = fespace.GlobalTrueVSize();
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "\nAMR iteration " << it << endl;
|
||||
cout << "Number of unknowns: " << global_dofs << endl;
|
||||
}
|
||||
|
||||
// 13. Assemble the stiffness matrix and the right-hand side.
|
||||
a.Assemble();
|
||||
b.Assemble();
|
||||
|
||||
// 14. Set Dirichlet boundary values in the GridFunction x.
|
||||
// Determine the list of Dirichlet true DOFs in the linear system.
|
||||
Array<int> ess_tdof_list;
|
||||
x.ProjectBdrCoefficient(zero_vec_coeff, ess_bdr);
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
|
||||
// 15. Create the linear system: eliminate boundary conditions, constrain
|
||||
// hanging nodes and possibly apply other transformations. The system
|
||||
// will be solved for true (unconstrained) DOFs only.
|
||||
|
||||
HypreParMatrix A;
|
||||
Vector B, X;
|
||||
const int copy_interior = 1;
|
||||
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
|
||||
|
||||
// 16. Define and apply a parallel PCG solver for AX=B with the BoomerAMG
|
||||
// preconditioner from hypre.
|
||||
HypreBoomerAMG amg;
|
||||
amg.SetPrintLevel(0);
|
||||
// amg.SetSystemsOptions(dim); // optional
|
||||
CGSolver pcg(A.GetComm());
|
||||
pcg.SetPreconditioner(amg);
|
||||
pcg.SetOperator(A);
|
||||
pcg.SetRelTol(1e-6);
|
||||
pcg.SetMaxIter(500);
|
||||
pcg.SetPrintLevel(3); // print the first and the last iterations only
|
||||
pcg.Mult(B, X);
|
||||
|
||||
// 17. After solving the linear system, reconstruct the solution as a
|
||||
// finite element GridFunction. Constrained nodes are interpolated
|
||||
// from true DOFs (it may therefore happen that x.Size() >= X.Size()).
|
||||
a.RecoverFEMSolution(X, b, x);
|
||||
|
||||
// 18. Send solution by socket to the GLVis server.
|
||||
if (visualization && it == 0)
|
||||
{
|
||||
sol_sock.open(vishost, visport);
|
||||
sol_sock.precision(8);
|
||||
}
|
||||
if (visualization && sol_sock.good())
|
||||
{
|
||||
GridFunction nodes(&fespace), *nodes_p = &nodes;
|
||||
pmesh.GetNodes(nodes);
|
||||
nodes += x;
|
||||
int own_nodes = 0;
|
||||
pmesh.SwapNodes(nodes_p, own_nodes);
|
||||
x.Neg(); // visualize the backward displacement
|
||||
sol_sock << "parallel " << num_procs << ' ' << myid << '\n';
|
||||
sol_sock << "solution\n" << pmesh << x << flush;
|
||||
x.Neg();
|
||||
pmesh.SwapNodes(nodes_p, own_nodes);
|
||||
if (it == 0)
|
||||
{
|
||||
sol_sock << "keys '" << ((dim == 2) ? "Rjl" : "") << "m'" << endl;
|
||||
}
|
||||
sol_sock << "window_title 'AMR iteration: " << it << "'\n"
|
||||
<< "pause" << endl;
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Visualization paused. "
|
||||
"Press <space> in the GLVis window to continue." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (global_dofs > max_dofs)
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Reached the maximum number of dofs. Stop." << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 19. Call the refiner to modify the mesh. The refiner calls the error
|
||||
// estimator to obtain element errors, then it selects elements to be
|
||||
// refined and finally it modifies the mesh. The Stop() method can be
|
||||
// used to determine if a stopping criterion was met.
|
||||
refiner.Apply(pmesh);
|
||||
if (refiner.Stop())
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Stopping criterion satisfied. Stop." << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 20. Update the space to reflect the new state of the mesh. Also,
|
||||
// interpolate the solution x so that it lies in the new space but
|
||||
// represents the same function. This saves solver iterations later
|
||||
// since we'll have a good initial guess of x in the next step.
|
||||
// Internally, FiniteElementSpace::Update() calculates an
|
||||
// interpolation matrix which is then used by GridFunction::Update().
|
||||
fespace.Update();
|
||||
x.Update();
|
||||
|
||||
// 21. Load balance the mesh, and update the space and solution. Currently
|
||||
// available only for nonconforming meshes.
|
||||
if (pmesh.Nonconforming())
|
||||
{
|
||||
pmesh.Rebalance();
|
||||
|
||||
// Update the space and the GridFunction. This time the update matrix
|
||||
// redistributes the GridFunction among the processors.
|
||||
fespace.Update();
|
||||
x.Update();
|
||||
}
|
||||
|
||||
// 22. Inform also the bilinear and linear forms that the space has
|
||||
// changed.
|
||||
a.Update();
|
||||
b.Update();
|
||||
}
|
||||
|
||||
{
|
||||
ostringstream mref_name, mesh_name, sol_name;
|
||||
mref_name << "ex22p_reference_mesh." << setfill('0') << setw(6) << myid;
|
||||
mesh_name << "ex22p_deformed_mesh." << setfill('0') << setw(6) << myid;
|
||||
sol_name << "ex22p_displacement." << setfill('0') << setw(6) << myid;
|
||||
|
||||
ofstream mesh_ref_out(mref_name.str().c_str());
|
||||
mesh_ref_out.precision(16);
|
||||
pmesh.Print(mesh_ref_out);
|
||||
|
||||
ofstream mesh_out(mesh_name.str().c_str());
|
||||
mesh_out.precision(16);
|
||||
GridFunction nodes(&fespace), *nodes_p = &nodes;
|
||||
pmesh.GetNodes(nodes);
|
||||
nodes += x;
|
||||
int own_nodes = 0;
|
||||
pmesh.SwapNodes(nodes_p, own_nodes);
|
||||
pmesh.Print(mesh_out);
|
||||
pmesh.SwapNodes(nodes_p, own_nodes);
|
||||
|
||||
ofstream x_out(sol_name.str().c_str());
|
||||
x_out.precision(16);
|
||||
x.Save(x_out);
|
||||
}
|
||||
|
||||
MPI_Finalize();
|
||||
return 0;
|
||||
}
|
||||
@@ -6,7 +6,6 @@
|
||||
// mpirun -np 4 ex2p -m ../data/beam-quad.mesh
|
||||
// mpirun -np 4 ex2p -m ../data/beam-tet.mesh
|
||||
// mpirun -np 4 ex2p -m ../data/beam-hex.mesh
|
||||
// mpirun -np 4 ex2p -m ../data/beam-wedge.mesh
|
||||
// mpirun -np 4 ex2p -m ../data/beam-tri.mesh -o 2 -sys
|
||||
// mpirun -np 4 ex2p -m ../data/beam-quad.mesh -o 3 -elast
|
||||
// mpirun -np 4 ex2p -m ../data/beam-quad.mesh -o 3 -sc
|
||||
@@ -108,9 +107,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 4. Select the order of the finite element discretization space. For NURBS
|
||||
// meshes, we increase the order by degree elevation.
|
||||
if (mesh->NURBSext)
|
||||
if (mesh->NURBSext && order > mesh->NURBSext->GetOrder())
|
||||
{
|
||||
mesh->DegreeElevate(order, order);
|
||||
mesh->DegreeElevate(order - mesh->NURBSext->GetOrder());
|
||||
}
|
||||
|
||||
// 5. Refine the serial mesh on all processors to increase the resolution. In
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
// ex3 -m ../data/beam-tet.mesh
|
||||
// ex3 -m ../data/beam-hex.mesh
|
||||
// ex3 -m ../data/escher.mesh
|
||||
// ex3 -m ../data/escher.mesh -o 2
|
||||
// ex3 -m ../data/fichera.mesh
|
||||
// ex3 -m ../data/fichera-q2.vtk
|
||||
// ex3 -m ../data/fichera-q3.mesh
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
// mpirun -np 4 ex3p -m ../data/beam-tet.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/beam-hex.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/escher.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/escher.mesh -o 2
|
||||
// mpirun -np 4 ex3p -m ../data/fichera.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/fichera-q2.vtk
|
||||
// mpirun -np 4 ex3p -m ../data/fichera-q3.mesh
|
||||
|
||||
@@ -1,334 +0,0 @@
|
||||
// MFEM Example 3 - Parallel Version
|
||||
//
|
||||
// Compile with: make ex3p
|
||||
//
|
||||
// Sample runs: mpirun -np 4 ex3p -m ../data/star.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/square-disc.mesh -o 2
|
||||
// mpirun -np 4 ex3p -m ../data/beam-tet.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/beam-hex.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/escher.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/escher.mesh -o 2
|
||||
// mpirun -np 4 ex3p -m ../data/fichera.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/fichera-q2.vtk
|
||||
// mpirun -np 4 ex3p -m ../data/fichera-q3.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/square-disc-nurbs.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/beam-hex-nurbs.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/amr-quad.mesh -o 2
|
||||
// mpirun -np 4 ex3p -m ../data/amr-hex.mesh
|
||||
// mpirun -np 4 ex3p -m ../data/star-surf.mesh -o 2
|
||||
// mpirun -np 4 ex3p -m ../data/mobius-strip.mesh -o 2 -f 0.1
|
||||
// mpirun -np 4 ex3p -m ../data/klein-bottle.mesh -o 2 -f 0.1
|
||||
//
|
||||
// Description: This example code solves a simple electromagnetic diffusion
|
||||
// problem corresponding to the second order definite Maxwell
|
||||
// equation curl curl E + E = f with boundary condition
|
||||
// E x n = <given tangential field>. Here, we use a given exact
|
||||
// solution E and compute the corresponding r.h.s. f.
|
||||
// We discretize with Nedelec finite elements in 2D or 3D.
|
||||
//
|
||||
// The example demonstrates the use of H(curl) finite element
|
||||
// spaces with the curl-curl and the (vector finite element) mass
|
||||
// bilinear form, as well as the computation of discretization
|
||||
// error when the exact solution is known. Static condensation is
|
||||
// also illustrated.
|
||||
//
|
||||
// We recommend viewing examples 1-2 before viewing this example.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
// Exact solution, E, and r.h.s., f. See below for implementation.
|
||||
void E_exact(const Vector &, Vector &);
|
||||
void f_exact(const Vector &, Vector &);
|
||||
double freq = 1.0, kappa;
|
||||
int dim;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Initialize MPI.
|
||||
int num_procs, myid;
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
|
||||
|
||||
// 2. Parse command-line options.
|
||||
const char *mesh_file = "../data/beam-tet.mesh";
|
||||
int order = 1;
|
||||
bool static_cond = false;
|
||||
bool visualization = 1;
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
bool use_strumpack = false;
|
||||
#endif
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&freq, "-f", "--frequency", "Set the frequency for the exact"
|
||||
" solution.");
|
||||
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
|
||||
"--no-static-condensation", "Enable static condensation.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
args.AddOption(&use_strumpack, "-strumpack", "--strumpack-solver",
|
||||
"-no-strumpack", "--no-strumpack-solver",
|
||||
"Use STRUMPACK's double complex linear solver.");
|
||||
#endif
|
||||
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
}
|
||||
MPI_Finalize();
|
||||
return 1;
|
||||
}
|
||||
if (myid == 0)
|
||||
{
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
kappa = freq * M_PI;
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
|
||||
// and volume meshes with the same code.
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
dim = mesh->Dimension();
|
||||
int sdim = mesh->SpaceDimension();
|
||||
|
||||
// 4. Refine the serial mesh on all processors to increase the resolution. In
|
||||
// this example we do 'ref_levels' of uniform refinement. We choose
|
||||
// 'ref_levels' to be the largest number that gives a final mesh with no
|
||||
// more than 1,000 elements.
|
||||
{
|
||||
int ref_levels =
|
||||
(int)floor(log(100000./mesh->GetNE())/log(2.)/dim);
|
||||
for (int l = 0; l < ref_levels; l++)
|
||||
{
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Define a 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. Tetrahedral
|
||||
// meshes need to be reoriented before we can define high-order Nedelec
|
||||
// spaces on them.
|
||||
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
|
||||
delete mesh;
|
||||
{
|
||||
int par_ref_levels = 2;
|
||||
for (int l = 0; l < par_ref_levels; l++)
|
||||
{
|
||||
pmesh->UniformRefinement();
|
||||
}
|
||||
}
|
||||
pmesh->ReorientTetMesh();
|
||||
|
||||
// 6. Define a parallel finite element space on the parallel mesh. Here we
|
||||
// use the Nedelec finite elements of the specified order.
|
||||
FiniteElementCollection *fec = new ND_FECollection(order, dim);
|
||||
ParFiniteElementSpace *fespace = new ParFiniteElementSpace(pmesh, fec);
|
||||
HYPRE_Int size = fespace->GlobalTrueVSize();
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Number of finite element unknowns: " << size << endl;
|
||||
}
|
||||
|
||||
// 7. Determine the list of true (i.e. parallel conforming) essential
|
||||
// boundary dofs. In this example, the boundary conditions are defined
|
||||
// by marking all the boundary attributes from the mesh as essential
|
||||
// (Dirichlet) and converting them to a list of true dofs.
|
||||
Array<int> ess_tdof_list;
|
||||
if (pmesh->bdr_attributes.Size())
|
||||
{
|
||||
Array<int> ess_bdr(pmesh->bdr_attributes.Max());
|
||||
ess_bdr = 1;
|
||||
fespace->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
}
|
||||
|
||||
// 8. Set up the parallel linear form b(.) which corresponds to the
|
||||
// right-hand side of the FEM linear system, which in this case is
|
||||
// (f,phi_i) where f is given by the function f_exact and phi_i are the
|
||||
// basis functions in the finite element fespace.
|
||||
VectorFunctionCoefficient f(sdim, f_exact);
|
||||
ParLinearForm *b = new ParLinearForm(fespace);
|
||||
b->AddDomainIntegrator(new VectorFEDomainLFIntegrator(f));
|
||||
b->Assemble();
|
||||
|
||||
// 9. Define the solution vector x as a parallel finite element grid function
|
||||
// corresponding to fespace. Initialize x by projecting the exact
|
||||
// solution. Note that only values from the boundary edges will be used
|
||||
// when eliminating the non-homogeneous boundary condition to modify the
|
||||
// r.h.s. vector b.
|
||||
ParGridFunction x(fespace);
|
||||
VectorFunctionCoefficient E(sdim, E_exact);
|
||||
x.ProjectCoefficient(E);
|
||||
|
||||
// 10. Set up the parallel bilinear form corresponding to the EM diffusion
|
||||
// operator curl muinv curl + sigma I, by adding the curl-curl and the
|
||||
// mass domain integrators.
|
||||
Coefficient *muinv = new ConstantCoefficient(1.0);
|
||||
Coefficient *sigma = new ConstantCoefficient(-1.0);
|
||||
ParBilinearForm *a = new ParBilinearForm(fespace);
|
||||
a->AddDomainIntegrator(new CurlCurlIntegrator(*muinv));
|
||||
a->AddDomainIntegrator(new VectorFEMassIntegrator(*sigma));
|
||||
|
||||
// 11. Assemble the parallel bilinear form and the corresponding linear
|
||||
// system, applying any necessary transformations such as: parallel
|
||||
// assembly, eliminating boundary conditions, applying conforming
|
||||
// constraints for non-conforming AMR, static condensation, etc.
|
||||
if (static_cond) { a->EnableStaticCondensation(); }
|
||||
a->Assemble();
|
||||
|
||||
HypreParMatrix A;
|
||||
Vector B, X;
|
||||
a->FormLinearSystem(ess_tdof_list, x, *b, A, X, B);
|
||||
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "Size of linear system: " << A.GetGlobalNumRows() << endl;
|
||||
}
|
||||
|
||||
StopWatch chrono;
|
||||
chrono.Clear();
|
||||
chrono.Start();
|
||||
|
||||
#ifdef MFEM_USE_STRUMPACK
|
||||
if (use_strumpack)
|
||||
{
|
||||
Operator * Arow = new STRUMPACKRowLocMatrix(A);
|
||||
|
||||
STRUMPACKSolver * strumpack = new STRUMPACKSolver(argc, argv, MPI_COMM_WORLD);
|
||||
strumpack->SetPrintFactorStatistics(true);
|
||||
strumpack->SetPrintSolveStatistics(false);
|
||||
strumpack->SetKrylovSolver(strumpack::KrylovSolver::DIRECT);
|
||||
strumpack->SetReorderingStrategy(strumpack::ReorderingStrategy::METIS);
|
||||
// strumpack->SetMC64Job(strumpack::MC64Job::NONE);
|
||||
// strumpack->SetSymmetricPattern(true);
|
||||
strumpack->SetOperator(*Arow);
|
||||
strumpack->SetFromCommandLine();
|
||||
//Solver * precond = strumpack;
|
||||
|
||||
strumpack->Mult(B, X);
|
||||
|
||||
delete strumpack;
|
||||
delete Arow;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// 12. Define and apply a parallel PCG solver for AX=B with the AMS
|
||||
// preconditioner from hypre.
|
||||
ParFiniteElementSpace *prec_fespace =
|
||||
(a->StaticCondensationIsEnabled() ? a->SCParFESpace() : fespace);
|
||||
HypreSolver *ams = new HypreAMS(A, prec_fespace);
|
||||
HyprePCG *pcg = new HyprePCG(A);
|
||||
pcg->SetTol(1e-12);
|
||||
pcg->SetMaxIter(500);
|
||||
pcg->SetPrintLevel(2);
|
||||
pcg->SetPreconditioner(*ams);
|
||||
pcg->Mult(B, X);
|
||||
|
||||
delete pcg;
|
||||
delete ams;
|
||||
}
|
||||
|
||||
chrono.Stop();
|
||||
cout << "Solver time " << chrono.RealTime() << endl;
|
||||
|
||||
// 13. Recover the parallel grid function corresponding to X. This is the
|
||||
// local finite element solution on each processor.
|
||||
a->RecoverFEMSolution(X, *b, x);
|
||||
|
||||
// 14. Compute and print the L^2 norm of the error.
|
||||
{
|
||||
double err = x.ComputeL2Error(E);
|
||||
if (myid == 0)
|
||||
{
|
||||
cout << "\n|| E_h - E ||_{L^2} = " << err << '\n' << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// 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_name;
|
||||
mesh_name << "mesh." << setfill('0') << setw(6) << myid;
|
||||
sol_name << "sol." << setfill('0') << setw(6) << myid;
|
||||
|
||||
ofstream mesh_ofs(mesh_name.str().c_str());
|
||||
mesh_ofs.precision(8);
|
||||
pmesh->Print(mesh_ofs);
|
||||
|
||||
ofstream sol_ofs(sol_name.str().c_str());
|
||||
sol_ofs.precision(8);
|
||||
x.Save(sol_ofs);
|
||||
}
|
||||
|
||||
// 16. Send the solution by socket to a GLVis server.
|
||||
if (visualization)
|
||||
{
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock(vishost, visport);
|
||||
sol_sock << "parallel " << num_procs << " " << myid << "\n";
|
||||
sol_sock.precision(8);
|
||||
sol_sock << "solution\n" << *pmesh << x << flush;
|
||||
}
|
||||
|
||||
// 17. Free the used memory.
|
||||
delete a;
|
||||
delete sigma;
|
||||
delete muinv;
|
||||
delete b;
|
||||
delete fespace;
|
||||
delete fec;
|
||||
delete pmesh;
|
||||
|
||||
MPI_Finalize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void E_exact(const Vector &x, Vector &E)
|
||||
{
|
||||
if (dim == 3)
|
||||
{
|
||||
E(0) = sin(kappa * x(1));
|
||||
E(1) = sin(kappa * x(2));
|
||||
E(2) = sin(kappa * x(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
E(0) = sin(kappa * x(1));
|
||||
E(1) = sin(kappa * x(0));
|
||||
if (x.Size() == 3) { E(2) = 0.0; }
|
||||
}
|
||||
}
|
||||
|
||||
void f_exact(const Vector &x, Vector &f)
|
||||
{
|
||||
if (dim == 3)
|
||||
{
|
||||
f(0) = (1. + kappa * kappa) * sin(kappa * x(1));
|
||||
f(1) = (1. + kappa * kappa) * sin(kappa * x(2));
|
||||
f(2) = (1. + kappa * kappa) * sin(kappa * x(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
f(0) = (1. + kappa * kappa) * sin(kappa * x(1));
|
||||
f(1) = (1. + kappa * kappa) * sin(kappa * x(0));
|
||||
if (x.Size() == 3) { f(2) = 0.0; }
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,6 @@ int main(int argc, char *argv[])
|
||||
// 2. Parse command-line options.
|
||||
const char *mesh_file = "../data/star.mesh";
|
||||
int order = 1;
|
||||
bool par_format = false;
|
||||
bool visualization = 1;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
@@ -61,9 +60,6 @@ int main(int argc, char *argv[])
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&par_format, "-pf", "--parallel-format", "-sf",
|
||||
"--serial-format",
|
||||
"Format to use when saving the results for VisIt.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -321,9 +317,6 @@ int main(int argc, char *argv[])
|
||||
VisItDataCollection visit_dc("Example5-Parallel", pmesh);
|
||||
visit_dc.RegisterField("velocity", u);
|
||||
visit_dc.RegisterField("pressure", p);
|
||||
visit_dc.SetFormat(!par_format ?
|
||||
DataCollection::SERIAL_FORMAT :
|
||||
DataCollection::PARALLEL_FORMAT);
|
||||
visit_dc.Save();
|
||||
|
||||
// 16. Send the solution by socket to a GLVis server.
|
||||
|
||||
@@ -15,17 +15,12 @@
|
||||
// ex6 -m ../data/square-disc-surf.mesh -o 2
|
||||
// ex6 -m ../data/amr-quad.mesh
|
||||
//
|
||||
// Device sample runs:
|
||||
// > ex6 -pa -d cuda
|
||||
// > ex6 -pa -d occa-cuda
|
||||
// > ex6 -pa -d raja-omp
|
||||
//
|
||||
// Description: This is a version of Example 1 with a simple adaptive mesh
|
||||
// refinement loop. The problem being solved is again the Laplace
|
||||
// equation -Delta u = 1 with homogeneous Dirichlet boundary
|
||||
// conditions. The problem is solved on a sequence of meshes which
|
||||
// are locally refined in a conforming (triangles, tetrahedrons)
|
||||
// or non-conforming (quadrilaterals, hexahedra) manner according
|
||||
// or non-conforming (quadrilateral, hexahedrons) manner according
|
||||
// to a simple ZZ error estimator.
|
||||
//
|
||||
// The example demonstrates MFEM's capability to work with both
|
||||
@@ -48,19 +43,13 @@ int main(int argc, char *argv[])
|
||||
// 1. Parse command-line options.
|
||||
const char *mesh_file = "../data/star.mesh";
|
||||
int order = 1;
|
||||
bool pa = false;
|
||||
const char *device = "cpu";
|
||||
bool visualization = true;
|
||||
bool visualization = 1;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
|
||||
"--no-partial-assembly", "Enable Partial Assembly.");
|
||||
args.AddOption(&device, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -96,15 +85,10 @@ int main(int argc, char *argv[])
|
||||
H1_FECollection fec(order, dim);
|
||||
FiniteElementSpace fespace(&mesh, &fec);
|
||||
|
||||
// 5. Set device config parameters from the command line options.
|
||||
Device::Configure(device);
|
||||
Device::Print();
|
||||
|
||||
// 6. As in Example 1, we set up bilinear and linear forms corresponding to
|
||||
// 5. As in Example 1, we set up bilinear and linear forms corresponding to
|
||||
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
|
||||
// problem yet, this will be done in the main loop.
|
||||
BilinearForm a(&fespace);
|
||||
if (pa) { a.SetAssemblyLevel(AssemblyLevel::PARTIAL); }
|
||||
LinearForm b(&fespace);
|
||||
|
||||
ConstantCoefficient one(1.0);
|
||||
@@ -114,18 +98,18 @@ int main(int argc, char *argv[])
|
||||
a.AddDomainIntegrator(integ);
|
||||
b.AddDomainIntegrator(new DomainLFIntegrator(one));
|
||||
|
||||
// 7. The solution vector x and the associated finite element grid function
|
||||
// 6. The solution vector x and the associated finite element grid function
|
||||
// will be maintained over the AMR iterations. We initialize it to zero.
|
||||
GridFunction x(&fespace);
|
||||
x = 0.0;
|
||||
|
||||
// 8. All boundary attributes will be used for essential (Dirichlet) BC.
|
||||
// 7. All boundary attributes will be used for essential (Dirichlet) BC.
|
||||
MFEM_VERIFY(mesh.bdr_attributes.Size() > 0,
|
||||
"Boundary attributes required in the mesh.");
|
||||
Array<int> ess_bdr(mesh.bdr_attributes.Max());
|
||||
ess_bdr = 1;
|
||||
|
||||
// 9. Connect to GLVis.
|
||||
// 8. Connect to GLVis.
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock;
|
||||
@@ -134,23 +118,23 @@ int main(int argc, char *argv[])
|
||||
sol_sock.open(vishost, visport);
|
||||
}
|
||||
|
||||
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
|
||||
// that uses the ComputeElementFlux method of the DiffusionIntegrator to
|
||||
// recover a smoothed flux (gradient) that is subtracted from the element
|
||||
// flux to get an error indicator. We need to supply the space for the
|
||||
// smoothed flux: an (H1)^sdim (i.e., vector-valued) space is used here.
|
||||
// 9. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
|
||||
// that uses the ComputeElementFlux method of the DiffusionIntegrator to
|
||||
// recover a smoothed flux (gradient) that is subtracted from the element
|
||||
// flux to get an error indicator. We need to supply the space for the
|
||||
// smoothed flux: an (H1)^sdim (i.e., vector-valued) space is used here.
|
||||
FiniteElementSpace flux_fespace(&mesh, &fec, sdim);
|
||||
ZienkiewiczZhuEstimator estimator(*integ, x, flux_fespace);
|
||||
estimator.SetAnisotropic();
|
||||
|
||||
// 11. A refiner selects and refines elements based on a refinement strategy.
|
||||
// 10. A refiner selects and refines elements based on a refinement strategy.
|
||||
// The strategy here is to refine elements with errors larger than a
|
||||
// fraction of the maximum element error. Other strategies are possible.
|
||||
// The refiner will call the given error estimator.
|
||||
ThresholdRefiner refiner(estimator);
|
||||
refiner.SetTotalErrorFraction(0.7);
|
||||
|
||||
// 12. The main AMR loop. In each iteration we solve the problem on the
|
||||
// 11. The main AMR loop. In each iteration we solve the problem on the
|
||||
// current mesh, visualize the solution, and refine the mesh.
|
||||
const int max_dofs = 50000;
|
||||
for (int it = 0; ; it++)
|
||||
@@ -159,55 +143,44 @@ int main(int argc, char *argv[])
|
||||
cout << "\nAMR iteration " << it << endl;
|
||||
cout << "Number of unknowns: " << cdofs << endl;
|
||||
|
||||
// 13. Assemble the right-hand side.
|
||||
// 12. Assemble the stiffness matrix and the right-hand side.
|
||||
a.Assemble();
|
||||
b.Assemble();
|
||||
|
||||
// 14. Set Dirichlet boundary values in the GridFunction x.
|
||||
// 13. Set Dirichlet boundary values in the GridFunction x.
|
||||
// Determine the list of Dirichlet true DOFs in the linear system.
|
||||
Array<int> ess_tdof_list;
|
||||
x.ProjectBdrCoefficient(zero, ess_bdr);
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
|
||||
// 15. Switch to the device and assemble the stiffness matrix.
|
||||
Device::Enable();
|
||||
a.Assemble();
|
||||
|
||||
// 16. Create the linear system: eliminate boundary conditions, constrain
|
||||
// 14. Create the linear system: eliminate boundary conditions, constrain
|
||||
// hanging nodes and possibly apply other transformations. The system
|
||||
// will be solved for true (unconstrained) DOFs only.
|
||||
OperatorPtr A;
|
||||
SparseMatrix A;
|
||||
Vector B, X;
|
||||
|
||||
const int copy_interior = 1;
|
||||
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
|
||||
|
||||
// 17. Solve the linear system A X = B.
|
||||
if (!pa)
|
||||
{
|
||||
#ifndef MFEM_USE_SUITESPARSE
|
||||
// Use a simple symmetric Gauss-Seidel preconditioner with PCG.
|
||||
GSSmoother M((SparseMatrix&)(*A));
|
||||
PCG(*A, M, B, X, 3, 200, 1e-12, 0.0);
|
||||
// 15. Define a simple symmetric Gauss-Seidel preconditioner and use it to
|
||||
// solve the linear system with PCG.
|
||||
GSSmoother M(A);
|
||||
PCG(A, M, B, X, 3, 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);
|
||||
// 15. If MFEM was compiled with SuiteSparse, use UMFPACK to solve the
|
||||
// the linear system.
|
||||
UMFPackSolver umf_solver;
|
||||
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
|
||||
umf_solver.SetOperator(A);
|
||||
umf_solver.Mult(B, X);
|
||||
#endif
|
||||
}
|
||||
else // No preconditioning for now in partial assembly mode.
|
||||
{
|
||||
CG(*A, B, X, 3, 2000, 1e-12, 0.0);
|
||||
}
|
||||
|
||||
// 18. After solving the linear system, reconstruct the solution as a
|
||||
// 16. After solving the linear system, reconstruct the solution as a
|
||||
// finite element GridFunction. Constrained nodes are interpolated
|
||||
// from true DOFs (it may therefore happen that x.Size() >= X.Size()).
|
||||
Device::Disable();
|
||||
a.RecoverFEMSolution(X, b, x);
|
||||
|
||||
// 19. Send solution by socket to the GLVis server.
|
||||
// 17. Send solution by socket to the GLVis server.
|
||||
if (visualization && sol_sock.good())
|
||||
{
|
||||
sol_sock.precision(8);
|
||||
@@ -220,7 +193,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
// 20. Call the refiner to modify the mesh. The refiner calls the error
|
||||
// 18. Call the refiner to modify the mesh. The refiner calls the error
|
||||
// estimator to obtain element errors, then it selects elements to be
|
||||
// refined and finally it modifies the mesh. The Stop() method can be
|
||||
// used to determine if a stopping criterion was met.
|
||||
@@ -231,7 +204,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
// 21. Update the space to reflect the new state of the mesh. Also,
|
||||
// 19. Update the space to reflect the new state of the mesh. Also,
|
||||
// interpolate the solution x so that it lies in the new space but
|
||||
// represents the same function. This saves solver iterations later
|
||||
// since we'll have a good initial guess of x in the next step.
|
||||
@@ -240,7 +213,7 @@ int main(int argc, char *argv[])
|
||||
fespace.Update();
|
||||
x.Update();
|
||||
|
||||
// 22. Inform also the bilinear and linear forms that the space has
|
||||
// 20. Inform also the bilinear and linear forms that the space has
|
||||
// changed.
|
||||
a.Update();
|
||||
b.Update();
|
||||
|
||||
@@ -15,17 +15,12 @@
|
||||
// mpirun -np 4 ex6p -m ../data/square-disc-surf.mesh -o 2
|
||||
// mpirun -np 4 ex6p -m ../data/amr-quad.mesh
|
||||
//
|
||||
// Device sample runs:
|
||||
// > mpirun -np 4 ex6p -pa -d cuda
|
||||
// > mpirun -np 4 ex6p -pa -d occa-cuda
|
||||
// > mpirun -np 4 ex6p -pa -d raja-omp
|
||||
//
|
||||
// Description: This is a version of Example 1 with a simple adaptive mesh
|
||||
// refinement loop. The problem being solved is again the Laplace
|
||||
// equation -Delta u = 1 with homogeneous Dirichlet boundary
|
||||
// conditions. The problem is solved on a sequence of meshes which
|
||||
// are locally refined in a conforming (triangles, tetrahedrons)
|
||||
// or non-conforming (quadrilaterals, hexahedra) manner according
|
||||
// or non-conforming (quadrilateral, hexahedrons) manner according
|
||||
// to a simple ZZ error estimator.
|
||||
//
|
||||
// The example demonstrates MFEM's capability to work with both
|
||||
@@ -54,8 +49,6 @@ int main(int argc, char *argv[])
|
||||
// 2. Parse command-line options.
|
||||
const char *mesh_file = "../data/star.mesh";
|
||||
int order = 1;
|
||||
bool pa = false;
|
||||
const char *device = "cpu";
|
||||
bool visualization = true;
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
@@ -63,10 +56,6 @@ int main(int argc, char *argv[])
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
|
||||
"--no-partial-assembly", "Enable Partial Assembly.");
|
||||
args.AddOption(&device, "-d", "--device",
|
||||
"Device configuration string, see Device::Configure().");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -117,15 +106,10 @@ int main(int argc, char *argv[])
|
||||
H1_FECollection fec(order, dim);
|
||||
ParFiniteElementSpace fespace(&pmesh, &fec);
|
||||
|
||||
// 7. Set device config parameters from the command line options.
|
||||
Device::Configure(device);
|
||||
if (myid == 0) { Device::Print(); }
|
||||
|
||||
// 8. As in Example 1p, we set up bilinear and linear forms corresponding to
|
||||
// 7. As in Example 1p, we set up bilinear and linear forms corresponding to
|
||||
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
|
||||
// problem yet, this will be done in the main loop.
|
||||
ParBilinearForm a(&fespace);
|
||||
if (pa) { a.SetAssemblyLevel(AssemblyLevel::PARTIAL); }
|
||||
ParLinearForm b(&fespace);
|
||||
|
||||
ConstantCoefficient one(1.0);
|
||||
@@ -134,12 +118,12 @@ int main(int argc, char *argv[])
|
||||
a.AddDomainIntegrator(integ);
|
||||
b.AddDomainIntegrator(new DomainLFIntegrator(one));
|
||||
|
||||
// 9. The solution vector x and the associated finite element grid function
|
||||
// 8. The solution vector x and the associated finite element grid function
|
||||
// will be maintained over the AMR iterations. We initialize it to zero.
|
||||
ParGridFunction x(&fespace);
|
||||
x = 0;
|
||||
|
||||
// 10. Connect to GLVis.
|
||||
// 9. Connect to GLVis.
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
|
||||
@@ -161,7 +145,7 @@ int main(int argc, char *argv[])
|
||||
sout.precision(8);
|
||||
}
|
||||
|
||||
// 11. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
|
||||
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
|
||||
// with L2 projection in the smoothing step to better handle hanging
|
||||
// nodes and parallel partitioning. We need to supply a space for the
|
||||
// discontinuous flux (L2) and a space for the smoothed flux (H(div) is
|
||||
@@ -175,14 +159,14 @@ int main(int argc, char *argv[])
|
||||
// ParFiniteElementSpace smooth_flux_fes(&pmesh, &smooth_flux_fec, dim);
|
||||
L2ZienkiewiczZhuEstimator estimator(*integ, x, flux_fes, smooth_flux_fes);
|
||||
|
||||
// 12. A refiner selects and refines elements based on a refinement strategy.
|
||||
// 11. A refiner selects and refines elements based on a refinement strategy.
|
||||
// The strategy here is to refine elements with errors larger than a
|
||||
// fraction of the maximum element error. Other strategies are possible.
|
||||
// The refiner will call the given error estimator.
|
||||
ThresholdRefiner refiner(estimator);
|
||||
refiner.SetTotalErrorFraction(0.7);
|
||||
|
||||
// 13. The main AMR loop. In each iteration we solve the problem on the
|
||||
// 12. The main AMR loop. In each iteration we solve the problem on the
|
||||
// current mesh, visualize the solution, and refine the mesh.
|
||||
const int max_dofs = 100000;
|
||||
for (int it = 0; ; it++)
|
||||
@@ -194,48 +178,41 @@ int main(int argc, char *argv[])
|
||||
cout << "Number of unknowns: " << global_dofs << endl;
|
||||
}
|
||||
|
||||
// 14. Assemble the right-hand side and determine the list of true
|
||||
// (i.e. parallel conforming) essential boundary dofs.
|
||||
Array<int> ess_tdof_list;
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
// 13. Assemble the stiffness matrix and the right-hand side. Note that
|
||||
// MFEM doesn't care at this point that the mesh is nonconforming
|
||||
// and parallel. The FE space is considered 'cut' along hanging
|
||||
// edges/faces, and also across processor boundaries.
|
||||
a.Assemble();
|
||||
b.Assemble();
|
||||
|
||||
// 15. Switch to the device and assemble the stiffness matrix. Note that
|
||||
// MFEM doesn't care at this point that the mesh is nonconforming and
|
||||
// parallel. The FE space is considered 'cut' along hanging
|
||||
// edges/faces, and also across processor boundaries.
|
||||
Device::Enable();
|
||||
a.Assemble();
|
||||
|
||||
// 16. Create the parallel linear system: eliminate boundary conditions.
|
||||
// 14. Create the parallel linear system: eliminate boundary conditions,
|
||||
// constrain hanging nodes and nodes across processor boundaries.
|
||||
// The system will be solved for true (unconstrained/unique) DOFs only.
|
||||
OperatorPtr A;
|
||||
Vector B, X;
|
||||
Array<int> ess_tdof_list;
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
|
||||
HypreParMatrix A;
|
||||
Vector B, X;
|
||||
const int copy_interior = 1;
|
||||
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
|
||||
|
||||
// 17. Solve the linear system A X = B.
|
||||
// * With full assembly, use the BoomerAMG preconditioner from hypre.
|
||||
// * With partial assembly, use no preconditioner, for now.
|
||||
HypreBoomerAMG *amg = NULL;
|
||||
if (!pa) { amg = new HypreBoomerAMG; amg->SetPrintLevel(0); }
|
||||
CGSolver cg(MPI_COMM_WORLD);
|
||||
cg.SetRelTol(1e-6);
|
||||
cg.SetMaxIter(2000);
|
||||
cg.SetPrintLevel(3); // print the first and the last iterations only
|
||||
if (amg) { cg.SetPreconditioner(*amg); }
|
||||
cg.SetOperator(*A);
|
||||
cg.Mult(B, X);
|
||||
delete amg;
|
||||
// 15. Define and apply a parallel PCG solver for AX=B with the BoomerAMG
|
||||
// preconditioner from hypre.
|
||||
HypreBoomerAMG amg;
|
||||
amg.SetPrintLevel(0);
|
||||
CGSolver pcg(A.GetComm());
|
||||
pcg.SetPreconditioner(amg);
|
||||
pcg.SetOperator(A);
|
||||
pcg.SetRelTol(1e-6);
|
||||
pcg.SetMaxIter(200);
|
||||
pcg.SetPrintLevel(3); // print the first and the last iterations only
|
||||
pcg.Mult(B, X);
|
||||
|
||||
// 18. Switch back to the host and extract the parallel grid function
|
||||
// corresponding to the finite element approximation X. This is the
|
||||
// local solution on each processor.
|
||||
Device::Disable();
|
||||
// 16. Extract the parallel grid function corresponding to the finite element
|
||||
// approximation X. This is the local solution on each processor.
|
||||
a.RecoverFEMSolution(X, b, x);
|
||||
|
||||
// 19. Send the solution by socket to a GLVis server.
|
||||
// 17. Send the solution by socket to a GLVis server.
|
||||
if (visualization)
|
||||
{
|
||||
sout << "parallel " << num_procs << " " << myid << "\n";
|
||||
@@ -251,7 +228,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
// 20. Call the refiner to modify the mesh. The refiner calls the error
|
||||
// 18. Call the refiner to modify the mesh. The refiner calls the error
|
||||
// estimator to obtain element errors, then it selects elements to be
|
||||
// refined and finally it modifies the mesh. The Stop() method can be
|
||||
// used to determine if a stopping criterion was met.
|
||||
@@ -265,7 +242,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
// 21. Update the finite element space (recalculate the number of DOFs,
|
||||
// 19. Update the finite element space (recalculate the number of DOFs,
|
||||
// etc.) and create a grid function update matrix. Apply the matrix
|
||||
// to any GridFunctions over the space. In this case, the update
|
||||
// matrix is an interpolation matrix so the updated GridFunction will
|
||||
@@ -273,7 +250,7 @@ int main(int argc, char *argv[])
|
||||
fespace.Update();
|
||||
x.Update();
|
||||
|
||||
// 22. Load balance the mesh, and update the space and solution. Currently
|
||||
// 20. Load balance the mesh, and update the space and solution. Currently
|
||||
// available only for nonconforming meshes.
|
||||
if (pmesh.Nonconforming())
|
||||
{
|
||||
@@ -285,7 +262,7 @@ int main(int argc, char *argv[])
|
||||
x.Update();
|
||||
}
|
||||
|
||||
// 23. Inform also the bilinear and linear forms that the space has
|
||||
// 21. Inform also the bilinear and linear forms that the space has
|
||||
// changed.
|
||||
a.Update();
|
||||
b.Update();
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
//
|
||||
// Sample runs: ex8 -m ../data/square-disc.mesh
|
||||
// ex8 -m ../data/star.mesh
|
||||
// ex8 -m ../data/star-mixed.mesh
|
||||
// ex8 -m ../data/escher.mesh
|
||||
// ex8 -m ../data/fichera.mesh
|
||||
// ex8 -m ../data/fichera-mixed.mesh
|
||||
// ex8 -m ../data/square-disc-p2.vtk
|
||||
// ex8 -m ../data/square-disc-p3.mesh
|
||||
// ex8 -m ../data/star-surf.mesh -o 2
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
//
|
||||
// Sample runs: mpirun -np 4 ex8p -m ../data/square-disc.mesh
|
||||
// mpirun -np 4 ex8p -m ../data/star.mesh
|
||||
// mpirun -np 4 ex8p -m ../data/star-mixed.mesh
|
||||
// mpirun -np 4 ex8p -m ../data/escher.mesh
|
||||
// mpirun -np 4 ex8p -m ../data/fichera.mesh
|
||||
// mpirun -np 4 ex8p -m ../data/fichera-mixed.mesh
|
||||
// mpirun -np 4 ex8p -m ../data/square-disc-p2.vtk
|
||||
// mpirun -np 4 ex8p -m ../data/square-disc-p3.mesh
|
||||
// mpirun -np 4 ex8p -m ../data/star-surf.mesh -o 2
|
||||
@@ -125,13 +123,9 @@ int main(int argc, char *argv[])
|
||||
test_order++;
|
||||
}
|
||||
if (test_order < trial_order)
|
||||
{
|
||||
if (myid == 0)
|
||||
{
|
||||
cerr << "Warning, test space not enriched enough to handle primal"
|
||||
<< " trial space\n";
|
||||
}
|
||||
}
|
||||
|
||||
FiniteElementCollection *x0_fec, *xhat_fec, *test_fec;
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
// ex9 -m ../data/periodic-hexagon.mesh -p 1 -r 2 -dt 0.005 -tf 9
|
||||
// ex9 -m ../data/amr-quad.mesh -p 1 -r 2 -dt 0.002 -tf 9
|
||||
// ex9 -m ../data/star-q3.mesh -p 1 -r 2 -dt 0.005 -tf 9
|
||||
// ex9 -m ../data/star-mixed.mesh -p 1 -r 2 -dt 0.005 -tf 9
|
||||
// ex9 -m ../data/disc-nurbs.mesh -p 1 -r 3 -dt 0.005 -tf 9
|
||||
// ex9 -m ../data/disc-nurbs.mesh -p 2 -r 3 -dt 0.005 -tf 9
|
||||
// ex9 -m ../data/periodic-square.mesh -p 3 -r 4 -dt 0.0025 -tf 9 -vs 20
|
||||
@@ -132,8 +131,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 2. Read the mesh from the given mesh file. We can handle geometrically
|
||||
// periodic meshes in this code.
|
||||
Mesh mesh(mesh_file, 1, 1);
|
||||
int dim = mesh.Dimension();
|
||||
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
||||
int dim = mesh->Dimension();
|
||||
|
||||
// 3. Define the ODE solver used for time integration. Several explicit
|
||||
// Runge-Kutta methods are available.
|
||||
@@ -156,18 +155,18 @@ int main(int argc, char *argv[])
|
||||
// a (piecewise-polynomial) high-order mesh.
|
||||
for (int lev = 0; lev < ref_levels; lev++)
|
||||
{
|
||||
mesh.UniformRefinement();
|
||||
mesh->UniformRefinement();
|
||||
}
|
||||
if (mesh.NURBSext)
|
||||
if (mesh->NURBSext)
|
||||
{
|
||||
mesh.SetCurvature(max(order, 1));
|
||||
mesh->SetCurvature(max(order, 1));
|
||||
}
|
||||
mesh.GetBoundingBox(bb_min, bb_max, 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.
|
||||
DG_FECollection fec(order, dim);
|
||||
FiniteElementSpace fes(&mesh, &fec);
|
||||
FiniteElementSpace fes(mesh, &fec);
|
||||
|
||||
cout << "Number of unknowns: " << fes.GetVSize() << endl;
|
||||
|
||||
@@ -207,7 +206,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
ofstream omesh("ex9.mesh");
|
||||
omesh.precision(precision);
|
||||
mesh.Print(omesh);
|
||||
mesh->Print(omesh);
|
||||
ofstream osol("ex9-init.gf");
|
||||
osol.precision(precision);
|
||||
u.Save(osol);
|
||||
@@ -221,14 +220,14 @@ int main(int argc, char *argv[])
|
||||
if (binary)
|
||||
{
|
||||
#ifdef MFEM_USE_SIDRE
|
||||
dc = new SidreDataCollection("Example9", &mesh);
|
||||
dc = new SidreDataCollection("Example9", mesh);
|
||||
#else
|
||||
MFEM_ABORT("Must build with MFEM_USE_SIDRE=YES for binary output.");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
dc = new VisItDataCollection("Example9", &mesh);
|
||||
dc = new VisItDataCollection("Example9", mesh);
|
||||
dc->SetPrecision(precision);
|
||||
}
|
||||
dc->RegisterField("solution", &u);
|
||||
@@ -253,7 +252,7 @@ int main(int argc, char *argv[])
|
||||
else
|
||||
{
|
||||
sout.precision(precision);
|
||||
sout << "solution\n" << mesh << u;
|
||||
sout << "solution\n" << *mesh << u;
|
||||
sout << "pause\n";
|
||||
sout << flush;
|
||||
cout << "GLVis visualization paused."
|
||||
@@ -285,7 +284,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (visualization)
|
||||
{
|
||||
sout << "solution\n" << mesh << u << flush;
|
||||
sout << "solution\n" << *mesh << u << flush;
|
||||
}
|
||||
|
||||
if (visit)
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
// mpirun -np 4 ex9p -m ../data/periodic-hexagon.mesh -p 1 -dt 0.005 -tf 9
|
||||
// mpirun -np 4 ex9p -m ../data/amr-quad.mesh -p 1 -rp 1 -dt 0.002 -tf 9
|
||||
// mpirun -np 4 ex9p -m ../data/star-q3.mesh -p 1 -rp 1 -dt 0.004 -tf 9
|
||||
// mpirun -np 4 ex9p -m ../data/star-mixed.mesh -p 1 -rp 1 -dt 0.004 -tf 9
|
||||
// mpirun -np 4 ex9p -m ../data/disc-nurbs.mesh -p 1 -rp 1 -dt 0.005 -tf 9
|
||||
// mpirun -np 4 ex9p -m ../data/disc-nurbs.mesh -p 2 -rp 1 -dt 0.005 -tf 9
|
||||
// mpirun -np 4 ex9p -m ../data/periodic-square.mesh -p 3 -rp 2 -dt 0.0025 -tf 9 -vs 20
|
||||
@@ -165,7 +164,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
|
||||
}
|
||||
delete mesh;
|
||||
MPI_Finalize();
|
||||
return 3;
|
||||
}
|
||||
@@ -272,8 +270,6 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
dc = new VisItDataCollection("Example9-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);
|
||||
|
||||
@@ -14,37 +14,24 @@ MFEM_DIR ?= ..
|
||||
MFEM_BUILD_DIR ?= ..
|
||||
SRC = $(if $(MFEM_DIR:..=),$(MFEM_DIR)/examples/,)
|
||||
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
|
||||
TEST_MK = $(MFEM_DIR)/config/test.mk
|
||||
# Use the MFEM install directory
|
||||
# MFEM_INSTALL_DIR = ../mfem
|
||||
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
|
||||
# SRC = $(if $(MFEM_DIR),$(MFEM_DIR)/examples/,)
|
||||
# MFEM_DIR = ../mfem
|
||||
# CONFIG_MK = $(MFEM_DIR)/config.mk
|
||||
# TEST_MK = $(MFEM_DIR)/test.mk
|
||||
|
||||
MFEM_LIB_FILE = mfem_is_not_built
|
||||
-include $(CONFIG_MK)
|
||||
|
||||
SEQ_EXAMPLES = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex14 ex15 ex16 ex17\
|
||||
ex18 ex19 ex20 ex21 ex22
|
||||
SEQ_EXAMPLES = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex14 ex15 ex16 ex17
|
||||
PAR_EXAMPLES = ex1p ex2p ex3p ex4p ex5p ex6p ex7p ex8p ex9p ex10p ex11p ex12p\
|
||||
ex13p ex14p ex15p ex16p ex17p ex18p ex19p ex20p ex21p ex22p
|
||||
|
||||
ex13p ex14p ex15p ex16p ex17p
|
||||
ifeq ($(MFEM_USE_MPI),NO)
|
||||
EXAMPLES = $(SEQ_EXAMPLES)
|
||||
else
|
||||
EXAMPLES = $(PAR_EXAMPLES) $(SEQ_EXAMPLES)
|
||||
endif
|
||||
SUBDIRS =
|
||||
ifeq ($(MFEM_USE_SUNDIALS),YES)
|
||||
SUBDIRS += sundials
|
||||
endif
|
||||
ifeq ($(MFEM_USE_PETSC),YES)
|
||||
SUBDIRS += petsc
|
||||
endif
|
||||
ifeq ($(MFEM_USE_PUMI),YES)
|
||||
SUBDIRS += pumi
|
||||
endif
|
||||
SUBDIRS_ALL = $(addsuffix /all,$(SUBDIRS))
|
||||
SUBDIRS_TEST = $(addsuffix /test,$(SUBDIRS))
|
||||
SUBDIRS_CLEAN = $(addsuffix /clean,$(SUBDIRS))
|
||||
SUBDIRS_TPRINT = $(addsuffix /test-print,$(SUBDIRS))
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .o .cpp .mk
|
||||
@@ -57,27 +44,13 @@ SUBDIRS_TPRINT = $(addsuffix /test-print,$(SUBDIRS))
|
||||
%: $(SRC)%.cpp $(MFEM_LIB_FILE) $(CONFIG_MK)
|
||||
$(MFEM_CXX) $(MFEM_FLAGS) $< -o $@ $(MFEM_LIBS)
|
||||
|
||||
all: $(EXAMPLES) $(SUBDIRS_ALL)
|
||||
|
||||
.PHONY: $(SUBDIRS_ALL) $(SUBDIRS_TEST) $(SUBDIRS_CLEAN) $(SUBDIRS_TPRINT)
|
||||
$(SUBDIRS_ALL) $(SUBDIRS_TEST) $(SUBDIRS_CLEAN):
|
||||
$(MAKE) -C $(@D) $(@F)
|
||||
$(SUBDIRS_TPRINT):
|
||||
@$(MAKE) -C $(@D) $(@F)
|
||||
|
||||
# Additional dependencies
|
||||
ex18: $(SRC)ex18.hpp
|
||||
ifeq ($(MFEM_USE_MPI),YES)
|
||||
ex18p: $(SRC)ex18.hpp
|
||||
endif
|
||||
all: $(EXAMPLES)
|
||||
|
||||
MFEM_TESTS = EXAMPLES
|
||||
include $(MFEM_TEST_MK)
|
||||
test: $(SUBDIRS_TEST)
|
||||
test-print: $(SUBDIRS_TPRINT)
|
||||
include $(TEST_MK)
|
||||
|
||||
# Testing: Parallel vs. serial runs
|
||||
RUN_MPI = $(MFEM_MPIEXEC) $(MFEM_MPIEXEC_NP) $(MFEM_MPI_NP)
|
||||
RUN_MPI = $(MFEM_MPIEXEC) $(MFEM_MPIEXEC_NP) 4
|
||||
%-test-par: %
|
||||
@$(call mfem-test,$<, $(RUN_MPI), Parallel example)
|
||||
%-test-seq: %
|
||||
@@ -96,12 +69,6 @@ ex15-test-seq: ex15
|
||||
@$(call mfem-test,$<,, Serial example,-e 1)
|
||||
ex15p-test-par: ex15p
|
||||
@$(call mfem-test,$<, $(RUN_MPI), Parallel example,-e 1)
|
||||
# Testing: optional tests
|
||||
ifeq ($(MFEM_USE_STRUMPACK),YES)
|
||||
ex11p-test-strumpack: ex11p
|
||||
@$(call mfem-test,$<, $(RUN_MPI), STRUMPACK example,--strumpack)
|
||||
test-par-YES: ex11p-test-strumpack
|
||||
endif
|
||||
|
||||
# Testing: "test" target and mfem-test* variables are defined in config/test.mk
|
||||
|
||||
@@ -109,7 +76,7 @@ endif
|
||||
$(MFEM_LIB_FILE):
|
||||
$(error The MFEM library is not built)
|
||||
|
||||
clean: clean-build clean-exec $(SUBDIRS_CLEAN)
|
||||
clean: clean-build clean-exec
|
||||
|
||||
clean-build:
|
||||
rm -f *.o *~ $(SEQ_EXAMPLES) $(PAR_EXAMPLES)
|
||||
@@ -118,11 +85,7 @@ clean-build:
|
||||
clean-exec:
|
||||
@rm -f refined.mesh displaced.mesh mesh.* ex5.mesh
|
||||
@rm -rf Example5* Example9* Example15* Example16*
|
||||
@rm -f sphere_refined.* sol.* sol_u.* sol_p.* sol_r.* sol_i.*
|
||||
@rm -f sphere_refined.* sol.* sol_u.* sol_p.*
|
||||
@rm -f ex9.mesh ex9-mesh.* ex9-init.* ex9-final.*
|
||||
@rm -f deformed.* velocity.* elastic_energy.* mode_*
|
||||
@rm -f ex16.mesh ex16-mesh.* ex16-init.* ex16-final.*
|
||||
@rm -f vortex-mesh.* vortex.mesh vortex-?-init.* vortex-?-final.*
|
||||
@rm -f deformation.* pressure.*
|
||||
@rm -f ex20.dat ex20p_?????.dat gnuplot_ex20.inp gnuplot_ex20p.inp
|
||||
@rm -f ex22*.mesh ex22*.sol ex22p_*.*
|
||||
|
||||
@@ -35,7 +35,7 @@ if (MFEM_USE_MPI)
|
||||
endif()
|
||||
|
||||
# Include the source directory where mfem.hpp and mfem-performance.hpp are.
|
||||
include_directories(BEFORE ${PROJECT_BINARY_DIR})
|
||||
include_directories(${PROJECT_BINARY_DIR})
|
||||
|
||||
# Add targets to copy rc_* files from the source directory
|
||||
foreach(RC_FILE ${PETSC_RC_FILES})
|
||||
@@ -49,7 +49,7 @@ add_custom_target(copy_petsc_rc_files DEPENDS ${PETSC_RC_FILES}
|
||||
|
||||
# Add "test_petsc" target, see below.
|
||||
add_custom_target(test_petsc
|
||||
${CMAKE_CTEST_COMMAND} -R petsc USES_TERMINAL)
|
||||
${CMAKE_CTEST_COMMAND} -R petsc -C PETSC USES_TERMINAL)
|
||||
|
||||
# Add one executable per cpp file, adding "petsc_" as prefix. Sets
|
||||
# "copy_petsc_rc_files" as a prerequisite for the given examples. Also, sets
|
||||
@@ -58,47 +58,50 @@ set(PFX petsc_)
|
||||
add_mfem_examples(PETSC_EXAMPLES_SRCS ${PFX} copy_petsc_rc_files test_petsc)
|
||||
|
||||
# Testing.
|
||||
# The PETSc tests can be run separately using the target "test_petsc" which
|
||||
# builds the examples and runs:
|
||||
# ctest -R petsc
|
||||
# We do not want these tests to be run by default, so we add them to their own
|
||||
# configuration - PETSC. To run the tests defined here use the "test_petsc"
|
||||
# target which builds the examples and runs:
|
||||
# ctest -C PETSC -R petsc
|
||||
|
||||
# Command line options for the tests.
|
||||
set(EX1_ARGS_W -m ../../data/amr-quad.mesh --usepetsc)
|
||||
set(EX1_ARGS_P -m ../../data/amr-quad.mesh --usepetsc --petscopts rc_ex1p)
|
||||
set(EX2_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p)
|
||||
set(EX3_ARGS -m ../../data/klein-bottle.mesh -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping)
|
||||
set(EX4_ARGS -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping)
|
||||
set(EX4_HYB_ARGS -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping --hybridization)
|
||||
set(EX5_BDDC_LB_ARGS -m ../../data/star.mesh --usepetsc -o 0 --petscopts rc_ex5p_bddc --nonoverlapping --local-bdr)
|
||||
set(EX5_BDDC_GB_ARGS -m ../../data/star.mesh --usepetsc -o 0 --petscopts rc_ex5p_bddc --nonoverlapping)
|
||||
set(EX5_FSPL_ARGS -m ../../data/beam-tet.mesh --usepetsc -o 0 --petscopts rc_ex5p_fieldsplit)
|
||||
set(EX6_ARGS -m ../../data/amr-quad.mesh --usepetsc)
|
||||
set(EX6_NONOVL_ARGS -m ../../data/amr-quad.mesh --usepetsc --nonoverlapping)
|
||||
set(EX9_E_ARGS -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl -dt 0.1)
|
||||
set(EX9_ES_ARGS -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl --no-step)
|
||||
set(EX9_IS_ARGS -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_impl --implicit -tf 0.5)
|
||||
set(EX10_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p -tf 30 -s 3 -rs 2 -dt 3)
|
||||
set(EX1P_ARGS -m ../../data/amr-quad.mesh --usepetsc --petscopts rc_ex1p)
|
||||
set(EX2P_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p)
|
||||
set(EX3P_ARGS -m ../../data/klein-bottle.mesh
|
||||
-o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping)
|
||||
set(EX4P_ARGS -m ../../data/klein-bottle.mesh
|
||||
-o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping)
|
||||
set(EX5_BDDC_ARGS -m ../../data/star.mesh
|
||||
--usepetsc --petscopts rc_ex5p_bddc --nonoverlapping)
|
||||
set(EX5_FSPL_ARGS -m ../../data/beam-tet.mesh
|
||||
--usepetsc --petscopts rc_ex5p_fieldsplit)
|
||||
set(EX5P_ARGS ${EX5_FSPL_ARGS})
|
||||
set(EX6P_ARGS -m ../../data/amr-quad.mesh --usepetsc)
|
||||
set(EX9P_ARGS -m ../../data/periodic-hexagon.mesh
|
||||
--usepetsc --petscopts rc_ex9p_expl)
|
||||
set(EX10P_ARGS -m ../../data/beam-quad.mesh
|
||||
-tf 30 -s 3 -rs 2 -dt 3 --usepetsc --petscopts rc_ex10p)
|
||||
|
||||
# Add the tests: one test per command-line-variable.
|
||||
foreach(TEST_OPTIONS_VAR
|
||||
EX1_ARGS_W EX1_ARGS_P EX2_ARGS EX3_ARGS EX4_ARGS EX4_HYB_ARGS
|
||||
EX5_BDDC_LB_ARGS EX5_BDDC_GB_ARGS EX5_FSPL_ARGS EX6_ARGS EX6_NONOVL_ARGS
|
||||
EX9_E_ARGS EX9_ES_ARGS EX9_IS_ARGS EX10_ARGS)
|
||||
string(REGEX REPLACE "^(.+)_ARGS" "\\1" TEST_NAME_UC ${TEST_OPTIONS_VAR})
|
||||
string(REGEX REPLACE "^([^_]+)" "\\1P" TEST_NAME_UC ${TEST_NAME_UC})
|
||||
string(TOLOWER ${TEST_NAME_UC} TEST_NAME_FULL)
|
||||
string(REGEX REPLACE "^([^_]+).*" "\\1" TEST_NAME ${TEST_NAME_FULL})
|
||||
set(TEST_NAME_FULL ${PFX}${TEST_NAME_FULL})
|
||||
# Add the tests: one test per source file.
|
||||
foreach(SRC_FILE ${PETSC_EXAMPLES_SRCS})
|
||||
get_filename_component(SRC_FILENAME ${SRC_FILE} NAME)
|
||||
string(REPLACE ".cpp" "" TEST_NAME ${SRC_FILENAME})
|
||||
string(TOUPPER ${TEST_NAME} UP_TEST_NAME)
|
||||
set(TEST_NAME ${PFX}${TEST_NAME})
|
||||
set(TEST_OPTIONS "-no-vis" ${${TEST_OPTIONS_VAR}})
|
||||
# message(STATUS "${TEST_NAME_FULL} --> ${TEST_NAME} ${TEST_OPTIONS}")
|
||||
|
||||
# All PETSC tests are parallel.
|
||||
if (MFEM_USE_MPI)
|
||||
add_test(NAME ${TEST_NAME_FULL}_np=4
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MFEM_MPI_NP}
|
||||
set(THIS_TEST_OPTIONS "-no-vis")
|
||||
list(APPEND THIS_TEST_OPTIONS ${${UP_TEST_NAME}_ARGS})
|
||||
# message(STATUS "Test ${TEST_NAME} options: ${THIS_TEST_OPTIONS}")
|
||||
|
||||
if (NOT (${TEST_NAME} MATCHES ".*p$"))
|
||||
add_test(NAME ${TEST_NAME}_ser
|
||||
COMMAND ${TEST_NAME} ${THIS_TEST_OPTIONS}
|
||||
CONFIGURATIONS PETSC)
|
||||
else()
|
||||
add_test(NAME ${TEST_NAME}_np=4
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 4
|
||||
${MPIEXEC_PREFLAGS}
|
||||
$<TARGET_FILE:${TEST_NAME}> ${TEST_OPTIONS}
|
||||
${MPIEXEC_POSTFLAGS})
|
||||
$<TARGET_FILE:${TEST_NAME}> ${THIS_TEST_OPTIONS}
|
||||
${MPIEXEC_POSTFLAGS}
|
||||
CONFIGURATIONS PETSC)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
//
|
||||
// Sample runs:
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh --petscopts rc_ex10p -s 3 -rs 2 -dt 3
|
||||
// mpirun -np 4 ex10p -m ../../data/beam-quad-amr.mesh --petscopts rc_ex10p -s 3 -rs 2 -dt 3
|
||||
//
|
||||
// Description: This examples solves a time dependent nonlinear elasticity
|
||||
// problem of the form dv/dt = H(x) + S v, dx/dt = v, where H is a
|
||||
@@ -61,7 +60,6 @@ class HyperelasticOperator : public TimeDependentOperator
|
||||
{
|
||||
protected:
|
||||
ParFiniteElementSpace &fespace;
|
||||
Array<int> ess_tdof_list;
|
||||
|
||||
ParBilinearForm M, S;
|
||||
ParNonlinearForm H;
|
||||
@@ -99,10 +97,9 @@ public:
|
||||
This is the only requirement for high-order SDIRK implicit integration.*/
|
||||
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k);
|
||||
|
||||
double ElasticEnergy(const ParGridFunction &x) const;
|
||||
double KineticEnergy(const ParGridFunction &v) const;
|
||||
void GetElasticEnergyDensity(const ParGridFunction &x,
|
||||
ParGridFunction &w) const;
|
||||
double ElasticEnergy(ParGridFunction &x) const;
|
||||
double KineticEnergy(ParGridFunction &v) const;
|
||||
void GetElasticEnergyDensity(ParGridFunction &x, ParGridFunction &w) const;
|
||||
|
||||
virtual ~HyperelasticOperator();
|
||||
};
|
||||
@@ -116,15 +113,14 @@ class ReducedSystemOperator : public Operator
|
||||
private:
|
||||
ParBilinearForm *M, *S;
|
||||
ParNonlinearForm *H;
|
||||
mutable HypreParMatrix *Jacobian;
|
||||
mutable Operator *Jacobian;
|
||||
double dt;
|
||||
const Vector *v, *x;
|
||||
mutable Vector w, z;
|
||||
const Array<int> &ess_tdof_list;
|
||||
|
||||
public:
|
||||
ReducedSystemOperator(ParBilinearForm *M_, ParBilinearForm *S_,
|
||||
ParNonlinearForm *H_, const Array<int> &ess_tdof_list);
|
||||
ParNonlinearForm *H_);
|
||||
|
||||
/// Set current dt, v, x values - needed to compute action and Jacobian.
|
||||
void SetParameters(double dt_, const Vector *v_, const Vector *x_);
|
||||
@@ -144,12 +140,12 @@ public:
|
||||
class ElasticEnergyCoefficient : public Coefficient
|
||||
{
|
||||
private:
|
||||
HyperelasticModel &model;
|
||||
const ParGridFunction &x;
|
||||
DenseMatrix J;
|
||||
HyperelasticModel &model;
|
||||
ParGridFunction &x;
|
||||
DenseMatrix J;
|
||||
|
||||
public:
|
||||
ElasticEnergyCoefficient(HyperelasticModel &m, const ParGridFunction &x_)
|
||||
ElasticEnergyCoefficient(HyperelasticModel &m, ParGridFunction &x_)
|
||||
: model(m), x(x_) { }
|
||||
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip);
|
||||
virtual ~ElasticEnergyCoefficient() { }
|
||||
@@ -239,7 +235,7 @@ int main(int argc, char *argv[])
|
||||
// 2b. We initialize PETSc
|
||||
if (use_petsc)
|
||||
{
|
||||
MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL);
|
||||
PetscInitialize(NULL,NULL,petscrc_file,NULL);
|
||||
}
|
||||
|
||||
// 3. Read the serial mesh from the given mesh file on all processors. We can
|
||||
@@ -315,9 +311,7 @@ int main(int argc, char *argv[])
|
||||
true_offset[2] = 2*true_size;
|
||||
|
||||
BlockVector vx(true_offset);
|
||||
ParGridFunction v_gf, x_gf;
|
||||
v_gf.MakeTRef(&fespace, vx, true_offset[0]);
|
||||
x_gf.MakeTRef(&fespace, vx, true_offset[1]);
|
||||
ParGridFunction v_gf(&fespace), x_gf(&fespace);
|
||||
|
||||
ParGridFunction x_ref(&fespace);
|
||||
pmesh->GetNodes(x_ref);
|
||||
@@ -330,12 +324,11 @@ int main(int argc, char *argv[])
|
||||
// boundary conditions on a beam-like mesh (see description above).
|
||||
VectorFunctionCoefficient velo(dim, InitialVelocity);
|
||||
v_gf.ProjectCoefficient(velo);
|
||||
v_gf.SetTrueVector();
|
||||
VectorFunctionCoefficient deform(dim, InitialDeformation);
|
||||
x_gf.ProjectCoefficient(deform);
|
||||
x_gf.SetTrueVector();
|
||||
|
||||
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
|
||||
v_gf.GetTrueDofs(vx.GetBlock(0));
|
||||
x_gf.GetTrueDofs(vx.GetBlock(1));
|
||||
|
||||
Array<int> ess_bdr(fespace.GetMesh()->bdr_attributes.Max());
|
||||
ess_bdr = 0;
|
||||
@@ -392,7 +385,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (last_step || (ti % vis_steps) == 0)
|
||||
{
|
||||
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
|
||||
v_gf.Distribute(vx.GetBlock(0));
|
||||
x_gf.Distribute(vx.GetBlock(1));
|
||||
|
||||
double ee = oper->ElasticEnergy(x_gf);
|
||||
double ke = oper->KineticEnergy(v_gf);
|
||||
@@ -417,7 +411,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 11. Save the displaced mesh, the velocity and elastic energy.
|
||||
{
|
||||
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
|
||||
GridFunction *nodes = &x_gf;
|
||||
int owns_nodes = 0;
|
||||
pmesh->SwapNodes(nodes, owns_nodes);
|
||||
@@ -446,7 +439,7 @@ int main(int argc, char *argv[])
|
||||
delete oper;
|
||||
|
||||
// We finalize PETSc
|
||||
if (use_petsc) { MFEMFinalizePetsc(); }
|
||||
if (use_petsc) { PetscFinalize(); }
|
||||
|
||||
MPI_Finalize();
|
||||
|
||||
@@ -489,11 +482,9 @@ void visualize(ostream &out, ParMesh *mesh, ParGridFunction *deformed_nodes,
|
||||
|
||||
|
||||
ReducedSystemOperator::ReducedSystemOperator(
|
||||
ParBilinearForm *M_, ParBilinearForm *S_, ParNonlinearForm *H_,
|
||||
const Array<int> &ess_tdof_list_)
|
||||
ParBilinearForm *M_, ParBilinearForm *S_, ParNonlinearForm *H_)
|
||||
: Operator(M_->ParFESpace()->TrueVSize()), M(M_), S(S_), H(H_),
|
||||
Jacobian(NULL), dt(0.0), v(NULL), x(NULL), w(height), z(height),
|
||||
ess_tdof_list(ess_tdof_list_)
|
||||
Jacobian(NULL), dt(0.0), v(NULL), x(NULL), w(height), z(height)
|
||||
{ }
|
||||
|
||||
void ReducedSystemOperator::SetParameters(double dt_, const Vector *v_,
|
||||
@@ -510,7 +501,6 @@ void ReducedSystemOperator::Mult(const Vector &k, Vector &y) const
|
||||
H->Mult(z, y);
|
||||
M->TrueAddMult(k, y);
|
||||
S->TrueAddMult(w, y);
|
||||
y.SetSubVector(ess_tdof_list, 0.0);
|
||||
}
|
||||
|
||||
Operator &ReducedSystemOperator::GetGradient(const Vector &k) const
|
||||
@@ -524,8 +514,6 @@ Operator &ReducedSystemOperator::GetGradient(const Vector &k) const
|
||||
// PETSc's AIJ on the fly
|
||||
Jacobian = M->ParallelAssemble(localJ);
|
||||
delete localJ;
|
||||
HypreParMatrix *Je = Jacobian->EliminateRowsCols(ess_tdof_list);
|
||||
delete Je;
|
||||
return *Jacobian;
|
||||
}
|
||||
|
||||
@@ -550,11 +538,9 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
|
||||
ConstantCoefficient rho0(ref_density);
|
||||
M.AddDomainIntegrator(new VectorMassIntegrator(rho0));
|
||||
M.Assemble(skip_zero_entries);
|
||||
M.EliminateEssentialBC(ess_bdr);
|
||||
M.Finalize(skip_zero_entries);
|
||||
Mmat = M.ParallelAssemble();
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
HypreParMatrix *Me = Mmat->EliminateRowsCols(ess_tdof_list);
|
||||
delete Me;
|
||||
|
||||
M_solver.iterative_mode = false;
|
||||
M_solver.SetRelTol(rel_tol);
|
||||
@@ -567,14 +553,15 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
|
||||
|
||||
model = new NeoHookeanModel(mu, K);
|
||||
H.AddDomainIntegrator(new HyperelasticNLFIntegrator(model));
|
||||
H.SetEssentialTrueDofs(ess_tdof_list);
|
||||
H.SetEssentialBC(ess_bdr);
|
||||
|
||||
ConstantCoefficient visc_coeff(viscosity);
|
||||
S.AddDomainIntegrator(new VectorDiffusionIntegrator(visc_coeff));
|
||||
S.Assemble(skip_zero_entries);
|
||||
S.EliminateEssentialBC(ess_bdr);
|
||||
S.Finalize(skip_zero_entries);
|
||||
|
||||
reduced_oper = new ReducedSystemOperator(&M, &S, &H, ess_tdof_list);
|
||||
reduced_oper = new ReducedSystemOperator(&M, &S, &H);
|
||||
if (!use_petsc)
|
||||
{
|
||||
HypreSmoother *J_hypreSmoother = new HypreSmoother;
|
||||
@@ -626,7 +613,6 @@ void HyperelasticOperator::Mult(const Vector &vx, Vector &dvx_dt) const
|
||||
if (viscosity != 0.0)
|
||||
{
|
||||
S.TrueAddMult(v, z);
|
||||
z.SetSubVector(ess_tdof_list, 0.0);
|
||||
}
|
||||
z.Neg(); // z = -z
|
||||
M_solver.Mult(z, dv_dt);
|
||||
@@ -666,12 +652,12 @@ void HyperelasticOperator::ImplicitSolve(const double dt,
|
||||
add(v, dt, dv_dt, dx_dt);
|
||||
}
|
||||
|
||||
double HyperelasticOperator::ElasticEnergy(const ParGridFunction &x) const
|
||||
double HyperelasticOperator::ElasticEnergy(ParGridFunction &x) const
|
||||
{
|
||||
return H.GetEnergy(x);
|
||||
}
|
||||
|
||||
double HyperelasticOperator::KineticEnergy(const ParGridFunction &v) const
|
||||
double HyperelasticOperator::KineticEnergy(ParGridFunction &v) const
|
||||
{
|
||||
double loc_energy = 0.5*M.InnerProduct(v, v);
|
||||
double energy;
|
||||
@@ -681,7 +667,7 @@ double HyperelasticOperator::KineticEnergy(const ParGridFunction &v) const
|
||||
}
|
||||
|
||||
void HyperelasticOperator::GetElasticEnergyDensity(
|
||||
const ParGridFunction &x, ParGridFunction &w) const
|
||||
ParGridFunction &x, ParGridFunction &w) const
|
||||
{
|
||||
ElasticEnergyCoefficient w_coeff(*model, x);
|
||||
w.ProjectCoefficient(w_coeff);
|
||||
|
||||
@@ -123,7 +123,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// 2b. We initialize PETSc
|
||||
MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL);
|
||||
PetscInitialize(NULL,NULL,petscrc_file,NULL);
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
|
||||
@@ -266,6 +266,7 @@ int main(int argc, char *argv[])
|
||||
if (visualization && petscmonitor)
|
||||
{
|
||||
pcg->SetMonitor(&mymon);
|
||||
pcg->SetPrintLevel(4);
|
||||
pcg->iterative_mode = true;
|
||||
X.Randomize();
|
||||
}
|
||||
@@ -313,7 +314,7 @@ int main(int argc, char *argv[])
|
||||
delete pmesh;
|
||||
|
||||
// We finalize PETSc
|
||||
MFEMFinalizePetsc();
|
||||
PetscFinalize();
|
||||
|
||||
MPI_Finalize();
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// 2b. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
|
||||
@@ -121,9 +121,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
// 4. Select the order of the finite element discretization space. For NURBS
|
||||
// meshes, we increase the order by degree elevation.
|
||||
if (mesh->NURBSext)
|
||||
if (mesh->NURBSext && order > mesh->NURBSext->GetOrder())
|
||||
{
|
||||
mesh->DegreeElevate(order, order);
|
||||
mesh->DegreeElevate(order - mesh->NURBSext->GetOrder());
|
||||
}
|
||||
|
||||
// 5. Refine the serial mesh on all processors to increase the resolution. In
|
||||
@@ -359,7 +359,7 @@ int main(int argc, char *argv[])
|
||||
delete pmesh;
|
||||
|
||||
// We finalize PETSc
|
||||
if (use_petsc) { MFEMFinalizePetsc(); }
|
||||
if (use_petsc) { PetscFinalize(); }
|
||||
|
||||
MPI_Finalize();
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ int main(int argc, char *argv[])
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
// 2b. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
|
||||
kappa = freq * M_PI;
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
@@ -309,7 +309,7 @@ int main(int argc, char *argv[])
|
||||
delete pmesh;
|
||||
|
||||
// We finalize PETSc
|
||||
if (use_petsc) { MFEMFinalizePetsc(); }
|
||||
if (use_petsc) { PetscFinalize(); }
|
||||
|
||||
MPI_Finalize();
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ int main(int argc, char *argv[])
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
// 2b. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
|
||||
kappa = freq * M_PI;
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
@@ -330,7 +330,7 @@ int main(int argc, char *argv[])
|
||||
delete pmesh;
|
||||
|
||||
// We finalize PETSc
|
||||
if (use_petsc) { MFEMFinalizePetsc(); }
|
||||
if (use_petsc) { PetscFinalize(); }
|
||||
|
||||
MPI_Finalize();
|
||||
|
||||
|
||||
@@ -60,11 +60,9 @@ int main(int argc, char *argv[])
|
||||
// 2. Parse command-line options.
|
||||
const char *mesh_file = "../../data/star.mesh";
|
||||
int order = 1;
|
||||
bool par_format = false;
|
||||
bool visualization = 1;
|
||||
bool use_petsc = true;
|
||||
bool use_nonoverlapping = false;
|
||||
bool local_bdr_spec = false;
|
||||
const char *petscrc_file = "";
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
@@ -72,9 +70,6 @@ int main(int argc, char *argv[])
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&par_format, "-pf", "--parallel-format", "-sf",
|
||||
"--serial-format",
|
||||
"Format to use when saving the results for VisIt.");
|
||||
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
||||
"--no-visualization",
|
||||
"Enable or disable GLVis visualization.");
|
||||
@@ -87,9 +82,6 @@ int main(int argc, char *argv[])
|
||||
"-no-nonoverlapping", "--no-nonoverlapping",
|
||||
"Use or not the block diagonal PETSc's matrix format "
|
||||
"for non-overlapping domain decomposition.");
|
||||
args.AddOption(&local_bdr_spec, "-local-bdr", "--local-bdr", "-no-local-bdr",
|
||||
"--no-local-bdr",
|
||||
"Specify boundary dofs in local (Vdofs) ordering.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
@@ -105,7 +97,7 @@ int main(int argc, char *argv[])
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
// 2b. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
|
||||
@@ -218,7 +210,7 @@ int main(int argc, char *argv[])
|
||||
PetscParMatrix *pM = NULL, *pB = NULL, *pBT = NULL;
|
||||
HypreParMatrix *M = NULL, *B = NULL, *BT = NULL;
|
||||
Operator::Type tid =
|
||||
!use_petsc ? Operator::Hypre_ParCSR :
|
||||
!use_petsc ? Operator::HYPRE_PARCSR :
|
||||
(use_nonoverlapping ? Operator::PETSC_MATIS : Operator::PETSC_MATAIJ);
|
||||
OperatorHandle Mh(tid), Bh(tid);
|
||||
|
||||
@@ -310,38 +302,33 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
if (use_nonoverlapping)
|
||||
{
|
||||
PetscBDDCSolverParams opts;
|
||||
|
||||
// For saddle point problems, we need to provide BDDC the list of
|
||||
// boundary dofs either essential or natural.
|
||||
// Since R_space is the only space that may have boundary dofs and it
|
||||
// is ordered first then W_space, we don't need any local offset when
|
||||
// specifying the dofs.
|
||||
Array<int> bdr_tdof_list;
|
||||
bool local = false;
|
||||
if (pmesh->bdr_attributes.Size())
|
||||
{
|
||||
Array<int> bdr(pmesh->bdr_attributes.Max());
|
||||
bdr = 1;
|
||||
|
||||
if (!local_bdr_spec)
|
||||
{
|
||||
// Essential dofs in global ordering
|
||||
R_space->GetEssentialTrueDofs(bdr, bdr_tdof_list);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Alternatively, you can also provide the list of dofs in local
|
||||
// ordering
|
||||
R_space->GetEssentialVDofs(bdr, bdr_tdof_list);
|
||||
bdr_tdof_list.SetSize(R_space->GetVSize()+W_space->GetVSize(),0);
|
||||
}
|
||||
opts.SetNatBdrDofs(&bdr_tdof_list,local_bdr_spec);
|
||||
R_space->GetEssentialTrueDofs(bdr, bdr_tdof_list);
|
||||
local = false;
|
||||
// Alternatively, you can also provide the list of dofs in local
|
||||
// ordering:
|
||||
// R_space->GetEssentialVDofs(bdr, bdr_tdof_list);
|
||||
// bdr_tdof_list.SetSize(R_space->GetVSize()+W_space->GetVSize(),0);
|
||||
// local = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MFEM_WARNING("Missing boundary dofs. This may cause solver failures.");
|
||||
MFEM_ABORT("Need to know the boundary dofs");
|
||||
}
|
||||
|
||||
PetscBDDCSolverParams opts;
|
||||
opts.SetNatBdrDofs(&bdr_tdof_list,local);
|
||||
// See also command line options rc_ex5p_bddc
|
||||
pdarcyPr = new PetscBDDCSolver(MPI_COMM_WORLD,*darcyOp,opts,"prec_");
|
||||
}
|
||||
@@ -491,9 +478,6 @@ int main(int argc, char *argv[])
|
||||
VisItDataCollection visit_dc("Example5-Parallel", pmesh);
|
||||
visit_dc.RegisterField("velocity", u);
|
||||
visit_dc.RegisterField("pressure", p);
|
||||
visit_dc.SetFormat(!par_format ?
|
||||
DataCollection::SERIAL_FORMAT :
|
||||
DataCollection::PARALLEL_FORMAT);
|
||||
visit_dc.Save();
|
||||
|
||||
// 16. Send the solution by socket to a GLVis server.
|
||||
@@ -544,7 +528,7 @@ int main(int argc, char *argv[])
|
||||
delete pmesh;
|
||||
|
||||
// We finalize PETSc
|
||||
if (use_petsc) { MFEMFinalizePetsc(); }
|
||||
if (use_petsc) { PetscFinalize(); }
|
||||
|
||||
MPI_Finalize();
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// equation -Delta u = 1 with homogeneous Dirichlet boundary
|
||||
// conditions. The problem is solved on a sequence of meshes which
|
||||
// are locally refined in a conforming (triangles, tetrahedrons)
|
||||
// or non-conforming (quadrilaterals, hexahedra) manner according
|
||||
// or non-conforming (quadrilateral, hexahedrons) manner according
|
||||
// to a simple ZZ error estimator.
|
||||
//
|
||||
// The example demonstrates MFEM's capability to work with both
|
||||
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
|
||||
args.PrintOptions(cout);
|
||||
}
|
||||
// 2b. We initialize PETSc
|
||||
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
|
||||
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
|
||||
|
||||
// 3. Read the (serial) mesh from the given mesh file on all processors. We
|
||||
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
|
||||
@@ -224,7 +224,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
a.Assemble();
|
||||
b.Assemble();
|
||||
a.SetOperatorType(Operator::Hypre_ParCSR);
|
||||
a.SetOperatorType(Operator::HYPRE_PARCSR);
|
||||
HypreParMatrix A;
|
||||
Vector B, X;
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
@@ -315,7 +315,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
// We finalize PETSc
|
||||
if (use_petsc) { MFEMFinalizePetsc(); }
|
||||
if (use_petsc) { PetscFinalize(); }
|
||||
|
||||
MPI_Finalize();
|
||||
return 0;
|
||||
|
||||
@@ -248,7 +248,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
// When using PETSc, we just create the ODE solver. We use command line
|
||||
// customization to select a specific solver.
|
||||
MFEMInitializePetsc(NULL, NULL, petscrc_file, NULL);
|
||||
PetscInitialize(NULL, NULL, petscrc_file, NULL);
|
||||
ode_solver = pode_solver = new PetscODESolver(MPI_COMM_WORLD);
|
||||
}
|
||||
|
||||
@@ -403,14 +403,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
double t = 0.0;
|
||||
adv->SetTime(t);
|
||||
if (use_petsc)
|
||||
{
|
||||
pode_solver->Init(*adv,PetscODESolver::ODE_SOLVER_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
ode_solver->Init(*adv);
|
||||
}
|
||||
ode_solver->Init(*adv);
|
||||
|
||||
// Explicitly perform time-integration (looping over the time iterations, ti,
|
||||
// with a time-step dt), or use the Run method of the ODE solver class.
|
||||
@@ -431,6 +424,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
cout << "time step: " << ti << ", time: " << t << endl;
|
||||
}
|
||||
|
||||
// 11. Extract the parallel grid function corresponding to the finite
|
||||
// element approximation U (the local solution on each processor).
|
||||
*u = *U;
|
||||
@@ -481,7 +475,7 @@ int main(int argc, char *argv[])
|
||||
delete pmon;
|
||||
|
||||
// We finalize PETSc
|
||||
if (use_petsc) { MFEMFinalizePetsc(); }
|
||||
if (use_petsc) { PetscFinalize(); }
|
||||
|
||||
MPI_Finalize();
|
||||
return 0;
|
||||
|
||||