Compare commits

..
435 changed files with 70330 additions and 25077 deletions
+61
View File
@@ -0,0 +1,61 @@
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an Issue or Pull Request becomes stale
daysUntilStale: 30
# Number of days of inactivity before an Issue or Pull Request with the stale
# label is closed. Set to false to disable. If disabled, issues still need to
# be closed manually, but will remain marked as stale.
daysUntilClose: 7
# Only issues or pull requests with all of these labels are check if stale.
# Defaults to `[]` (disabled)
onlyLabels: []
# Issues or Pull Requests with these labels will never be considered stale. Set
# to `[]` to disable
exemptLabels:
- bug
- WIP
- ready-for-review
- in-review
- in-next
# Set to true to ignore issues in a project (defaults to false)
exemptProjects: false
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: false
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: false
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
:warning: This issue or PR has been automatically marked as stale because it has not
had any activity in the last month. *If no activity occurs in the next week, it will
be automatically closed.* Thank you for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Limit to only `issues` or `pulls`
# only: issues
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
# pulls:
# daysUntilStale: 30
# markComment: >
# This pull request has been automatically marked as stale because it has not had
# recent activity. It will be closed if no further activity occurs. Thank you
# for your contributions.
# issues:
# exemptLabels:
# - confirmed
-31
View File
@@ -1,31 +0,0 @@
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
# For more information, see: https://github.com/actions/stale
name: Mark stale issues and pull requests
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
actions: write
steps:
- uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: ':warning: This issue has been automatically marked as stale because it has not had any activity in the last month. *If no activity occurs in the next week, it will be automatically closed.* Thank you for your contributions.'
stale-pr-message: ':warning: This PR has been automatically marked as stale because it has not had any activity in the last month. *If no activity occurs in the next week, it will be automatically closed.* Thank you for your contributions.'
days-before-stale: 30
days-before-close: 7
stale-issue-label: 'stale'
stale-pr-label: 'stale'
operations-per-run: 500
exempt-issue-labels: "bug,WIP,ready-for-review,in-review,in-next"
exempt-pr-labels: "bug,WIP,ready-for-review,in-review,in-next"
-31
View File
@@ -1,31 +0,0 @@
# Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
name: "Trigger PyMFEM CI"
on:
push:
branches:
- master
jobs:
trigger-pymfem:
runs-on: ubuntu-latest
steps:
- name: Send POST request to trigger PyMFEM CI
run: |
curl -L \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.PYMFEM_CI_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/mfem/pymfem/actions/workflows/build-and-test-dispatch.yml/dispatches \
-d '{"ref":"master", "inputs":{"test_options":"fast"}}'
-14
View File
@@ -15,9 +15,6 @@
CMakeCache.txt
CMakeFiles/
# Clangd server cache
*.cache*
# Backup files
*~
@@ -275,27 +272,16 @@ miniapps/navier/*_output
miniapps/nurbs/nurbs_ex1
miniapps/nurbs/nurbs_ex1p
miniapps/nurbs/nurbs_ex3
miniapps/nurbs/nurbs_ex5
miniapps/nurbs/nurbs_ex11p
miniapps/nurbs/nurbs_ex24
miniapps/nurbs/nurbs_solenoidal
miniapps/nurbs/nurbs_printfunc
miniapps/nurbs/nurbs_patch_ex1
miniapps/nurbs/nurbs_curveint
miniapps/nurbs/refined.mesh
miniapps/nurbs/mesh.*
miniapps/nurbs/sol_?.gf
miniapps/nurbs/sol.*
miniapps/nurbs/mode_*
miniapps/nurbs/Example1*
miniapps/nurbs/Example3*
miniapps/nurbs/Example5*
miniapps/nurbs/Solenoidal*
miniapps/nurbs/ParaView
miniapps/nurbs/sin-fit.mesh
miniapps/nurbs/ex5.mesh
miniapps/nurbs/exsol.mesh
miniapps/nurbs/CurveInt
miniapps/nurbs/nurbs_naca_cmesh
miniapps/nurbs/naca-cmesh.mesh
+5 -5
View File
@@ -22,7 +22,7 @@ include:
# the "needs" keyword and express the DAG of jobs for more efficiency.
# - We use setup and setup_baseline phases to download content outside of mfem
# directory.
# - Allocate/Release is where ruby resource are allocated/released once for all.
# - Allocate/Release is where quartz resource are allocated/released once for all.
# - Build and Test is where we build and MFEM for multiple toolchains.
# - Baseline_checks gathers baseline-type test suites execution
# - Baseline_publish, only available on master, allows to update baseline
@@ -53,7 +53,7 @@ variables:
AUTOTEST_COMMIT: "YES"
# Trigger subpipelines:
ruby-build-and-test:
quartz-build-and-test:
stage: sub-pipelines
variables:
# Explicitly pass down values that we want to be able to set when triggering
@@ -61,10 +61,10 @@ ruby-build-and-test:
AUTOTEST: "${AUTOTEST}"
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
trigger:
include: .gitlab/ruby-build-and-test.yml
include: .gitlab/quartz-build-and-test.yml
strategy: depend
ruby-baseline:
quartz-baseline:
stage: sub-pipelines
variables:
# Explicitly pass down values that we want to be able to set when triggering
@@ -73,7 +73,7 @@ ruby-baseline:
AUTOTEST: "${AUTOTEST}"
AUTOTEST_COMMIT: "${AUTOTEST_COMMIT}"
trigger:
include: .gitlab/ruby-baseline.yml
include: .gitlab/quartz-baseline.yml
strategy: depend
lassen-build-and-test:
+3 -3
View File
@@ -24,7 +24,7 @@ and `test type`.
Machines typically include:
* Ruby: 2nd Gen Intel Xeon (Cascade Lake)
* Quartz: Intel bi-socket x86
* Lassen: Power9 + Nvidia GPU
* Corona: AMD GPU
@@ -76,13 +76,13 @@ with a spack spec of MFEM, within the limits permitted by the MFEM spack
package.
In any build-and-test sub-pipeline a job basically consists in defining the
spack spec to use. Adding a job on ruby for example resumes to:
spack spec to use. Adding a job on quartz for example resumes to:
```yaml
<job_name>:
variables:
SPEC: "<spack_spec>"
extends: .build_and_test_on_ruby
extends: .build_and_test_on_quartz
```
The remaining and non trivial work is to make sure this spec is working. To
+1 -1
View File
@@ -24,7 +24,7 @@ variables:
# TODO: add a clean-up mechanism
BUILD_ROOT: ${USER_CI_TOP_DIR}/${CI_PROJECT_NAME}-${MACHINE_NAME}-pipeline-${CI_PIPELINE_ID}
# On LLNL's ruby, there is only one allocation shared among jobs in order to
# On LLNL's quartz, there is only one allocation shared among jobs in order to
# save time and resource. This allocation has to be uniquely named so that we
# are sure to retrieve it.
ALLOC_NAME: ${CI_PROJECT_NAME}_ci_${CI_PIPELINE_ID}
@@ -9,17 +9,17 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# GitLab pipelines configurations for the Ruby machine at LLNL
# GitLab pipelines configurations for the Quartz machine at LLNL
variables:
MACHINE_NAME: ruby
MACHINE_NAME: quartz
.on_ruby:
.on_quartz:
tags:
- shell
- ruby
- quartz
rules:
# Don't run ruby jobs if...
- if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_RUBY == "OFF"'
# Don't run quartz jobs if...
- if: '$CI_COMMIT_BRANCH =~ /_qnone/ || $ON_QUARTZ == "OFF"'
when: never
# Don't run autotest update if...
- if: '$CI_JOB_NAME =~ /report/ && $AUTOTEST != "YES"'
@@ -40,13 +40,13 @@ variables:
- when: on_success
# Spack helped builds
# Generic ruby build job, extending build script
.build_and_test_on_ruby:
extends: [.on_ruby]
# Generic quartz build job, extending build script
.build_and_test_on_quartz:
extends: [.on_quartz]
stage: build_and_test
script:
# THREADS is used by 'tests/gitlab/build_and_test', run below
- export THREADS=16
- export THREADS=12
- echo ${ALLOC_NAME}
- export JOBID=$(squeue -h --name=${ALLOC_NAME} --format=%A)
- echo ${JOBID}
+1 -1
View File
@@ -18,7 +18,7 @@
setup_baseline:
tags:
- shell
- ruby
- quartz
stage: setup
variables:
GIT_STRATEGY: none
+1 -1
View File
@@ -16,7 +16,7 @@
setup:
tags:
- shell
- ruby
- quartz
stage: setup
variables:
GIT_STRATEGY: none
@@ -19,8 +19,8 @@ stages:
- cleanup
- baseline_publish
baselinecheck_mfem_intel_ruby:
extends: [.on_ruby]
baselinecheck_mfem_intel_quartz:
extends: [.on_quartz]
stage: baseline_check
variables:
# TPLS_DIR is used in .gitlab/scripts/baseline to provide the tpls location
@@ -32,7 +32,7 @@ baselinecheck_mfem_intel_ruby:
- echo ${BUILD_ROOT}
- echo ${TPLS_DIR}
# Used by the tests in MFEM/tests:
- export MFEM_TEST_NP=48
- export MFEM_TEST_NP=32
# The next script uses the following environment variables:
# * BASELINE_TEST, SYS_TYPE, CI_PROJECT_DIR, ARTIFACTS_DIR,
# * BUILD_ROOT, TPLS_DIR, MACHINE_NAME
@@ -44,16 +44,18 @@ baselinecheck_mfem_intel_ruby:
allow_failure: true
cleanup:
extends: .on_ruby
extends: .on_quartz
stage: cleanup
variables:
GIT_STRATEGY: none
script:
- echo "BUILD_ROOT=${BUILD_ROOT}"
- rm -rf "${BUILD_ROOT}" || true
- echo "CI_PROJECT_DIR=${CI_PROJECT_DIR}"
- make -C "${CI_PROJECT_DIR}" distclean
report_baseline:
extends: [.on_ruby]
extends: [.on_quartz]
stage: baseline_report
script:
- echo ${MACHINE_NAME}
@@ -113,8 +115,8 @@ report_baseline:
exit $err
) 9> autotest.lock
baselinepublish_mfem_ruby:
extends: [.on_ruby]
baselinepublish_mfem_quartz:
extends: [.on_quartz]
stage: baseline_publish
rules:
# - if: '$CI_COMMIT_BRANCH == "master" || $REBASELINE == "YES"'
@@ -129,5 +131,5 @@ baselinepublish_mfem_ruby:
include:
- local: .gitlab/configs/common.yml
- local: .gitlab/configs/ruby-config.yml
- local: .gitlab/configs/quartz-config.yml
- local: .gitlab/configs/setup-baseline.yml
@@ -19,54 +19,54 @@ stages:
allocate_resource:
variables:
GIT_STRATEGY: none
extends: .on_ruby
extends: .on_quartz
stage: allocate_resource
script:
- echo ${ALLOC_NAME}
- salloc --exclusive --nodes=1 --reservation=ci --time=60 --no-shell --job-name=${ALLOC_NAME}
timeout: 6h
# GitLab jobs for the Ruby machine at LLNL
# GitLab jobs for the Quartz machine at LLNL
debug_ser_gcc_10:
variables:
SPEC: "%gcc@10.3.1 +debug~mpi"
extends: .build_and_test_on_ruby
extends: .build_and_test_on_quartz
debug_par_gcc_10:
variables:
SPEC: "%gcc@10.3.1 +debug+mpi"
extends: .build_and_test_on_ruby
extends: .build_and_test_on_quartz
opt_ser_gcc_10:
variables:
SPEC: "%gcc@10.3.1 ~mpi"
extends: .build_and_test_on_ruby
extends: .build_and_test_on_quartz
opt_par_gcc_10:
variables:
SPEC: "%gcc@10.3.1"
extends: .build_and_test_on_ruby
extends: .build_and_test_on_quartz
opt_par_gcc_10_sundials:
variables:
SPEC: "%gcc@10.3.1 +sundials"
extends: .build_and_test_on_ruby
extends: .build_and_test_on_quartz
opt_par_gcc_10_petsc:
variables:
SPEC: "%gcc@10.3.1 +petsc ^petsc+mumps~superlu-dist"
extends: .build_and_test_on_ruby
extends: .build_and_test_on_quartz
opt_par_gcc_10_pumi:
variables:
SPEC: "%gcc@10.3.1 +pumi"
extends: .build_and_test_on_ruby
extends: .build_and_test_on_quartz
# Release
release_resource:
variables:
GIT_STRATEGY: none
extends: .on_ruby
extends: .on_quartz
stage: release_resource_and_report
script:
- echo ${ALLOC_NAME}
@@ -78,17 +78,17 @@ release_resource:
report_job_success:
stage: release_resource_and_report
extends:
- .on_ruby
- .on_quartz
- .report_job_success
report_job_failure:
stage: release_resource_and_report
extends:
- .on_ruby
- .on_quartz
- .report_job_failure
include:
- local: .gitlab/configs/common.yml
- local: .gitlab/configs/ruby-config.yml
- local: .gitlab/configs/quartz-config.yml
- local: .gitlab/configs/setup-build-and-test.yml
- local: .gitlab/configs/report-build-and-test.yml
+4 -4
View File
@@ -14,7 +14,7 @@
# locals
glob_err=${BASELINE_TEST}.err
base=${BASELINE_TEST}-${SYS_TYPE}
if [[ "${MACHINE_NAME}" == "ruby" ]]; then
if [[ "${MACHINE_NAME}" == "quartz" ]]; then
base="${BASELINE_TEST}-${MACHINE_NAME}"
fi
base_diff=${base}.diff
@@ -31,8 +31,8 @@ cd tests
mkdir _${BASELINE_TEST} && cd _${BASELINE_TEST}
# run
if [[ "${MACHINE_NAME}" == "ruby" ]]; then
salloc --nodes=1 --exclusive --reservation=ci ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
if [[ "${MACHINE_NAME}" == "quartz" || "${MACHINE_NAME}" == "ruby" ]]; then
salloc --nodes=1 --reservation=ci ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
elif [[ ${MACHINE_NAME} == "corona" ]]; then
salloc --nodes=1 -t 60 -p pbatch ../runtest ../../mfem "${BASELINE_TEST} ${TPLS_DIR}"
elif [[ ${MACHINE_NAME} == "lassen" ]]; then
@@ -41,11 +41,11 @@ else
echo "Unknown machine: MACHINE_NAME=$MACHINE_NAME"
exit 1
fi
status="$?"
# post
mkdir ${artifacts_path}
status=0
if [[ -f ${BASELINE_TEST}.out ]]; then
cp ${BASELINE_TEST}.out ${artifacts_path}
fi
+2 -2
View File
@@ -11,7 +11,7 @@
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# There will be collision between corona and ruby baselines.
# There will be collision between corona and quartz baselines.
# Once the corresponding files have been generated, we can switch to machine
# specific ref.
ARTIFACT_PATH=${CI_PROJECT_DIR}/${ARTIFACTS_DIR}/baseline-${SYS_TYPE}
@@ -21,7 +21,7 @@ PATCH_FILE=${ARTIFACT_PATH}.patch
FULL_FILE=${ARTIFACT_PATH}.out
DIFF_FILE=${ARTIFACT_PATH}.diff
# There will be collision between corona and ruby baselines.
# There will be collision between corona and quartz baselines.
# Once the corresponding files have been generated, we can switch to machine
# specific ref.
SAVED_NAME=baseline-${SYS_TYPE}.saved
-89
View File
@@ -10,87 +10,10 @@
Version 4.7.1 (development)
===========================
- Refactored ALGOIM cut integration rules. The interface is unified with
the interface for moment based cut integration rules.
Discretization improvements
---------------------------
- Added NURBS-based H(div) and H(curl) elements in 2D and 3D. Only on single
patch meshes. Only implemented for serial computations.
- Added support for boundary constraints to the hybridization class.
- Added support for external boundary submeshes with nonconformal mesh adaptation.
Meshing improvements
--------------------
- The ExodusII reader now handles pyramid and wedge element types. Mixed meshes
are also supported.
New and updated examples and miniapps
-------------------------------------
- Added miniapps to demonstrate the H(div) and H(curl) NURBS elements.
- Added an MFEM example for the eikonal equation. This new solver is based on
the proximal Galerkin method introduced by Keith and Surowiec.
- Added a command line option to all miniapps (`-p` or `--send-port`) for
specifying the GLVis server socket port (19916 by default).
GPU computing
-------------
- Added support for GPU-accelerated batched linear algebra (using cuBLAS,
hipBLAS, MAGMA, or native MFEM functionality) through the BatchedLinAlg class.
- A new GPU kernel dispatch mechanism was introduced. Users can instantiate
specialized kernels for specific combinations of (for example) polynomial
degree and number of quadrature points using
`DiffusionIntegrator::AddSpecialization` and
`MassIntegrator::AddSpecialization` (this functionality may be added to more
integrators in the future).
- Calls to slower fallback kernels can be reported to `mfem::err` by setting
the environment variable `MFEM_REPORT_KERNELS` to any value other than `NO`
or by explicitly calling `KernelReporter::Enable`. Users can then add
specializations for these kernels to achieve higher performance.
- Element assembly kernels have been added for low-order refined to
high-order transfer operators. New kernels can be offloaded as device
kernels. Example usage may be found in lor-transfer.cpp under miniapps/tools.
Miscellaneous
-------------
- Added support for SUNDIALS v7. See the section "API changes" for some small
changes related to this new version.
- Refactored the `ARKStepSolver` class (ARKODE interface) to use
`TimeDependentOperator::Mult` only when the associated ODE operator is
expressed in explicit form (i.e., `TimeDependentOperator::isExplicit()`),
otherwise `TimeDependentOperator::ExplicitMult` is used. A check has been
added to `ARKStepSolver` to verify that the associated ODE operator is not in
explicit form when a mass matrix solver is enabled via a call to either the
`UseMFEMMassLinearSolver` or `UseSundialsMassLinearSolver` methods. This is
because enabling a mass matrix solver assumes that F(u,k,t) = M k in the
associated ODE operator.
- Added support for custom interpolation procedure in FindPointsGSLIB.
API changes
-----------
- API change: in class GridFunction, 'fec' was renamed to 'fec_owned'.
- API change: support for SUNDIALS v7:
* the SUNDIALS types `realtype` and `booleantype` are no longer defined by v7
and therefore MFEM now uses the new type names `sunrealtype` and
`sunbooleantype`, respectively, which MFEM defines when using SUNDIALS < v6
where these types were not defined.
* The SUNDIALS macro `SUNLS_SUCCESS` and some other `*_SUCCESS` macros were
removed and replaced by `SUN_SUCCESS` in v7, so to avoid tedious checks for
SUNDIALS versions, MFEM now defines and uses the constant `SUN_SUCCESS` when
using SUNDIALS < v7.
* The constants `SUN_PREC_*`, introduced by SUNDIALS v6 are now introduced by
MFEM when using SUNDIALS < v6 to avoid tedious version checks.
Version 4.7, released on May 7, 2024
====================================
@@ -115,9 +38,6 @@ Meshing improvements
- Added support for internal boundary elements in nonconforming meshes.
- Added ExodusII output capability. The writer can handle first-order (Pyramid5,
Wedge6, Hex8, Tet4) and second-order FE types (Pyramid14, Wedge18, Hex27, Tet10).
- The ReadCubit Genesis mesh importer has been rewritten to improve readability.
Discretization improvements
@@ -177,15 +97,6 @@ New and updated examples and miniapps
- Added two new example codes: 38 and 39/39p described above. Substantially
updated Example 18/18p.
- Added ODE solvers selection routines. This creates a uniformity across examples,
miniapps and other executables in regard to ODE(time-integrator) selection.
- Added new mechanism for retrieving and setting state vectors in ODE solvers.
This is relevant for AB/AM and gen-alpha solvers.
- Added ODEsolver/ODEsolver2 unit tests to verify order of convergence and
read/write functionality.
Miscellaneous
-------------
- Updated the Doxygen documentation style, which now requires Doxygen version
+5 -16
View File
@@ -146,9 +146,7 @@ if (MFEM_USE_CUDA)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${CUDA_FLAGS}")
find_package(CUDAToolkit REQUIRED)
set(CUSPARSE_FOUND TRUE)
set(CUBLAS_FOUND TRUE)
get_target_property(CUSPARSE_LIBRARIES CUDA::cusparse LOCATION)
get_target_property(CUBLAS_LIBRARIES CUDA::cublas LOCATION)
endif()
if (XSDK_ENABLE_C)
@@ -233,7 +231,6 @@ if (MFEM_USE_HIP)
list(INSERT CMAKE_PREFIX_PATH 0 ${ROCM_PATH})
endif()
find_package(HIP REQUIRED)
find_package(HIPBLAS REQUIRED)
find_package(HIPSPARSE REQUIRED)
endif()
@@ -340,10 +337,7 @@ if (MFEM_USE_SUNDIALS)
if (MFEM_USE_HIP)
list(APPEND SUNDIALS_COMPONENTS NVector_Hip)
endif()
# The Core component was added in SUNDIALS v7, so we treat it as optional in
# order to support older versions.
find_package(SUNDIALS REQUIRED ${SUNDIALS_COMPONENTS}
OPTIONAL_COMPONENTS Core)
find_package(SUNDIALS REQUIRED ${SUNDIALS_COMPONENTS})
endif()
# SuperLU_DIST can only be enabled in parallel
@@ -402,10 +396,6 @@ if (MFEM_USE_AMGX)
find_package(AMGX REQUIRED)
endif()
if (MFEM_USE_MAGMA)
find_package(MAGMA REQUIRED)
endif()
if (MFEM_USE_CONDUIT)
find_package(Conduit REQUIRED conduit relay blueprint)
endif()
@@ -567,9 +557,8 @@ find_package(Threads REQUIRED)
set(MFEM_TPLS OPENMP HYPRE LAPACK BLAS SuperLUDist STRUMPACK METIS SuiteSparse
SUNDIALS PETSC SLEPC MUMPS AXOM FMS CONDUIT Ginkgo GNUTLS GSLIB
NETCDF MPFR PUMI HIOP POSIXCLOCKS MFEMBacktrace ZLIB OCCA CEED RAJA UMPIRE
ADIOS2 MKL_CPARDISO MKL_PARDISO AMGX MAGMA CUSPARSE CUBLAS CALIPER CODIPACK
BENCHMARK PARELAG TRIBOL MPI_CXX HIP HIPBLAS HIPSPARSE MOONOLITH BLITZ
ALGOIM ENZYME)
ADIOS2 CUSPARSE MKL_CPARDISO MKL_PARDISO AMGX CALIPER CODIPACK
BENCHMARK PARELAG TRIBOL MPI_CXX HIP HIPSPARSE MOONOLITH BLITZ ALGOIM ENZYME)
# Add all *_FOUND libraries in the variable TPL_LIBRARIES.
set(TPL_LIBRARIES "")
@@ -684,7 +673,7 @@ if (NOT ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}"))
#include \"${PROJECT_SOURCE_DIR}/${Header}\"
")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${PROJECT_BINARY_DIR}/${Header}.tmp"
"${PROJECT_BINARY_DIR}/${Header}"
)
@@ -698,7 +687,7 @@ if (NOT ("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}"))
#include \"mfem/${Header}\"
")
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${PROJECT_BINARY_DIR}/InstallHeaders/${Header}.tmp"
"${PROJECT_BINARY_DIR}/InstallHeaders/${Header}"
)
+4 -24
View File
@@ -273,13 +273,7 @@ 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.
INSTALL - Specify the install program, default = /usr/bin/install
INSTALL_DEF_PERM - Specify the default install permissions. This affects
headers and configuration makefiles, default = 644
INSTALL_BIN_PERM - Specify the install permissions for binaries. This only
affects the shared version of the library, default = 755
INSTALL_DIR_PERM - Specify the install permissions for directories and,
on macOS/BSD, for symlinks as well, default = 755
INSTALL - Specify the install program, e.g /usr/bin/install
MFEM library features/options (GNU make)
----------------------------------------
@@ -394,11 +388,6 @@ MFEM_USE_AMGX = YES/NO
Allows the user to use SparseMatrices and HypreParMatrices to solve linear
systems with the routines from the AmgX library.
MFEM_USE_MAGMA = YES/NO
Enable MFEM functionality based on the MAGMA high-performance linear algebra
library. The MAGMA library provides a BLAS/LAPACK interface, with
implementations that have been optimized for Nvidia and AMD GPUs.
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
@@ -502,14 +491,10 @@ MFEM_USE_CODIPACK = YES/NO
MFEM_USE_ALGOIM = YES/NO
Enable the usage of Algoim - a collection of high-order accurate numerical
methods and C++ algorithms for working with implicitly-defined geometry and
level set methods, see https://algoim.github.io. MFEM provides interface to
Algoim v1. To check out the specific Algoim state use:
https://github.com/algoim/algoim
level set methods. The Algoim library requires the Blitz++ library. The MFEM
provides interface to Algoim v1. Thus, to check out the specific state use:
git checkout 9c9ca0ef094d8ab0390ed36367a1151b459bbe0a
The Algoim library requires the Blitz++ library. To use the latest state of
Blitz++ that has been tested with MFEM, use:
https://github.com/blitzpp/blitz
git checkout f24a250a43dff88c31ad92916da828b7ea9a98b7
https://algoim.github.io
MFEM_USE_ADFORWARD = YES/NO
Enable forward mode for AD packages. This option is valid
@@ -714,11 +699,6 @@ The specific libraries and their options are:
Options: AMGX_OPT, AMGX_LIB.
Versions: AmgX >= 2.1, older versions may work too.
- MAGMA (optional), used with MFEM_USE_MAGMA = YES.
URL: https://icl.utk.edu/magma/
Options: MAGMA_OPT, MAGMA_LIB
Versions: MAGMA >= 2.8.0
- 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).
-1
View File
@@ -37,7 +37,6 @@ set(MFEM_USE_MUMPS @MFEM_USE_MUMPS@)
set(MFEM_USE_STRUMPACK @MFEM_USE_STRUMPACK@)
set(MFEM_USE_GINKGO @MFEM_USE_GINKGO@)
set(MFEM_USE_AMGX @MFEM_USE_AMGX@)
set(MFEM_USE_MAGMA @MFEM_USE_MAGMA@)
set(MFEM_USE_HIOP @MFEM_USE_HIOP@)
set(MFEM_USE_GNUTLS @MFEM_USE_GNUTLS@)
set(MFEM_USE_GSLIB @MFEM_USE_GSLIB@)
-3
View File
@@ -114,9 +114,6 @@
// Enable MFEM functionality based on the AmgX library.
#cmakedefine MFEM_USE_AMGX
// Enable MFEM functionality based on the MAGMA library.
#cmakedefine MFEM_USE_MAGMA
// Enable secure socket streams based on the GNUTLS library.
#cmakedefine MFEM_USE_GNUTLS
-37
View File
@@ -1,37 +0,0 @@
# Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
# at the Lawrence Livermore National Laboratory. All Rights reserved. See files
# LICENSE and NOTICE for details. LLNL-CODE-806117.
#
# This file is part of the MFEM library. For more information and source code
# availability visit https://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the BSD-3 license. We welcome feedback and contributions, see file
# CONTRIBUTING.md for details.
# Defines the following variables:
# - MAGMA_FOUND
# - MAGMA_LIBRARIES
# - MAGMA_INCLUDE_DIRS
include(MfemCmakeUtilities)
mfem_find_package(MAGMA MAGMA MAGMA_DIR "include" "magma.h" "lib" "magma"
"Paths to headers required by MAGMA." "Libraries required by MAGMA.")
if (MAGMA_FOUND AND MFEM_USE_CUDA)
get_target_property(CUSPARSE_LIBRARIES CUDA::cusparse LOCATION)
get_target_property(CUBLAS_LIBRARIES CUDA::cublas LOCATION)
list(APPEND MAGMA_LIBRARIES ${CUSPARSE_LIBRARIES} ${CUBLAS_LIBRARIES})
set(MAGMA_LIBRARIES ${MAGMA_LIBRARIES} CACHE STRING
"MAGMA libraries + dependencies." FORCE)
message(STATUS "Updated MAGMA_LIBRARIES: ${MAGMA_LIBRARIES}")
endif()
if (MAGMA_FOUND AND MFEM_USE_HIP)
find_package(HIPBLAS REQUIRED)
find_package(HIPSPARSE REQUIRED)
list(APPEND MAGMA_LIBRARIES ${HIPBLAS_LIBRARIES} ${HIPSPARSE_LIBRARIES})
set(MAGMA_LIBRARIES ${MAGMA_LIBRARIES} CACHE STRING
"MAGMA libraries + dependencies." FORCE)
message(STATUS "Updated MAGMA_LIBRARIES: ${MAGMA_LIBRARIES}")
endif()
+1 -2
View File
@@ -31,5 +31,4 @@ mfem_find_package(SUNDIALS SUNDIALS SUNDIALS_DIR
ADD_COMPONENT CVODE "include" cvode/cvode.h "lib" sundials_cvode
ADD_COMPONENT CVODES "include" cvodes/cvodes.h "lib" sundials_cvodes
ADD_COMPONENT ARKODE "include" arkode/arkode.h "lib" sundials_arkode
ADD_COMPONENT KINSOL "include" kinsol/kinsol.h "lib" sundials_kinsol
ADD_COMPONENT Core "include" sundials/sundials_core.h "lib" sundials_core)
ADD_COMPONENT KINSOL "include" kinsol/kinsol.h "lib" sundials_kinsol)
@@ -846,14 +846,14 @@ function(mfem_export_mk_files)
MFEM_USE_ZLIB MFEM_USE_LIBUNWIND MFEM_USE_LAPACK MFEM_THREAD_SAFE
MFEM_USE_LEGACY_OPENMP MFEM_USE_OPENMP MFEM_USE_MEMALLOC MFEM_USE_SUNDIALS
MFEM_USE_SUITESPARSE MFEM_USE_SUPERLU MFEM_USE_SUPERLU5 MFEM_USE_MUMPS
MFEM_USE_STRUMPACK MFEM_USE_GINKGO MFEM_USE_AMGX MFEM_USE_MAGMA
MFEM_USE_GNUTLS MFEM_USE_NETCDF MFEM_USE_PETSC MFEM_USE_SLEPC
MFEM_USE_MPFR MFEM_USE_SIDRE MFEM_USE_FMS MFEM_USE_CONDUIT MFEM_USE_PUMI
MFEM_USE_HIOP MFEM_USE_GSLIB MFEM_USE_CUDA MFEM_USE_HIP MFEM_USE_RAJA
MFEM_USE_OCCA MFEM_USE_CEED MFEM_USE_CALIPER MFEM_USE_UMPIRE MFEM_USE_SIMD
MFEM_USE_ADIOS2 MFEM_USE_MKL_CPARDISO MFEM_USE_MKL_PARDISO
MFEM_USE_ADFORWARD MFEM_USE_CODIPACK MFEM_USE_BENCHMARK MFEM_USE_PARELAG
MFEM_USE_TRIBOL MFEM_USE_MOONOLITH MFEM_USE_ALGOIM MFEM_USE_ENZYME)
MFEM_USE_STRUMPACK MFEM_USE_GINKGO MFEM_USE_AMGX MFEM_USE_GNUTLS
MFEM_USE_NETCDF MFEM_USE_PETSC MFEM_USE_SLEPC MFEM_USE_MPFR MFEM_USE_SIDRE
MFEM_USE_FMS MFEM_USE_CONDUIT MFEM_USE_PUMI MFEM_USE_HIOP MFEM_USE_GSLIB
MFEM_USE_CUDA MFEM_USE_HIP MFEM_USE_RAJA MFEM_USE_OCCA MFEM_USE_CEED
MFEM_USE_CALIPER MFEM_USE_UMPIRE MFEM_USE_SIMD MFEM_USE_ADIOS2
MFEM_USE_MKL_CPARDISO MFEM_USE_MKL_PARDISO MFEM_USE_ADFORWARD
MFEM_USE_CODIPACK MFEM_USE_BENCHMARK MFEM_USE_PARELAG MFEM_USE_TRIBOL
MFEM_USE_MOONOLITH MFEM_USE_ALGOIM MFEM_USE_ENZYME)
foreach(var ${CONFIG_MK_BOOL_VARS})
if (${var})
set(${var} YES)
-3
View File
@@ -114,9 +114,6 @@
// Enable MFEM functionality based on the AmgX library.
// #define MFEM_USE_AMGX
// Enable MFEM functionality based on the MAGMA library.
// #define MFEM_USE_MAGMA
// Enable secure socket streams based on the GNUTLS library.
// #define MFEM_USE_GNUTLS
-1
View File
@@ -38,7 +38,6 @@ MFEM_USE_MUMPS = @MFEM_USE_MUMPS@
MFEM_USE_STRUMPACK = @MFEM_USE_STRUMPACK@
MFEM_USE_GINKGO = @MFEM_USE_GINKGO@
MFEM_USE_AMGX = @MFEM_USE_AMGX@
MFEM_USE_MAGMA = @MFEM_USE_MAGMA@
MFEM_USE_GNUTLS = @MFEM_USE_GNUTLS@
MFEM_USE_NETCDF = @MFEM_USE_NETCDF@
MFEM_USE_PETSC = @MFEM_USE_PETSC@
+1 -6
View File
@@ -40,7 +40,6 @@ option(MFEM_USE_MUMPS "Enable MUMPS usage" OFF)
option(MFEM_USE_STRUMPACK "Enable STRUMPACK usage" OFF)
option(MFEM_USE_GINKGO "Enable Ginkgo usage" OFF)
option(MFEM_USE_AMGX "Enable AmgX usage" OFF)
option(MFEM_USE_MAGMA "Enable MAGMA usage" OFF)
option(MFEM_USE_GNUTLS "Enable GNUTLS usage" OFF)
option(MFEM_USE_GSLIB "Enable GSLIB usage" OFF)
option(MFEM_USE_NETCDF "Enable NETCDF usage" OFF)
@@ -184,10 +183,6 @@ set(Ginkgo_DIR "${MFEM_DIR}/../ginkgo" CACHE PATH "Path to the Ginkgo library.")
set(AMGX_DIR "${MFEM_DIR}/../amgx" CACHE PATH "Path to AmgX")
set(MAGMA_DIR "${MFEM_DIR}/../magma" CACHE PATH "Path to MAGMA")
set(MAGMA_REQUIRED_PACKAGES "BLAS" "LAPACK" CACHE STRING
"Additional packages required by MAGMA.")
set(GNUTLS_DIR "" CACHE PATH "Path to the GnuTLS library.")
set(GSLIB_DIR "" CACHE PATH "Path to the GSLIB library.")
@@ -264,7 +259,7 @@ set(PARELAG_LIBRARIES "${PARELAG_DIR}/build/src/libParELAG.a" CACHE STRING
"The ParELAG library.")
set(TRIBOL_DIR "${MFEM_DIR}/../tribol" CACHE PATH "Path to Tribol")
set(Tribol_REQUIRED_PACKAGES "Axom/core/mint/slam/slic" CACHE STRING
set(Tribol_REQUIRED_PACKAGES "Axom/core/mint/slam/slic" CACHE STRING
"Additional packages required by Tribol")
set(BLAS_INCLUDE_DIRS "" CACHE STRING "Path to BLAS headers.")
+3 -22
View File
@@ -95,10 +95,6 @@ else
# Silence unused command line argument warnings when generating dependencies
# with mpicxx and clang
DEP_FLAGS := -Wno-unused-command-line-argument $(DEP_FLAGS)
# Silence "ignoring duplicate libraries" warnings on new (Xcode 15) linker
ifneq (,$(findstring PROJECT:dyld,$(shell ld -v 2>&1)))
LDFLAGS_INTERNAL = -Xlinker -no_warn_duplicate_libraries
endif
endif
# Set CXXFLAGS to overwrite the default selection of DEBUG_FLAGS/OPTIM_FLAGS
@@ -143,7 +139,6 @@ MFEM_USE_MUMPS = NO
MFEM_USE_STRUMPACK = NO
MFEM_USE_GINKGO = NO
MFEM_USE_AMGX = NO
MFEM_USE_MAGMA = NO
MFEM_USE_GNUTLS = NO
MFEM_USE_NETCDF = NO
MFEM_USE_PETSC = NO
@@ -289,13 +284,6 @@ endif
ifeq ($(MFEM_USE_HIP),YES)
SUNDIALS_LIB += -lsundials_nvechip
endif
SUNDIALS_CORE_PAT = $(subst\
@MFEM_DIR@,$(MFEM_DIR),$(SUNDIALS_DIR))/lib*/libsundials_core.*
ifeq ($(MFEM_USE_SUNDIALS),YES)
ifneq ($(wildcard $(SUNDIALS_CORE_PAT)),)
SUNDIALS_LIB += -lsundials_core
endif
endif
# If SUNDIALS was built with KLU:
# MFEM_USE_SUITESPARSE = YES
@@ -402,11 +390,6 @@ AMGX_DIR = @MFEM_DIR@/../amgx
AMGX_OPT = -I$(AMGX_DIR)/include
AMGX_LIB = -L$(AMGX_DIR)/lib -lamgx -lcusparse -lcusolver -lcublas -lnvToolsExt
# MAGMA library configuration
MAGMA_DIR = @MFEM_DIR@/../magma
MAGMA_OPT = -I$(MAGMA_DIR)/include
MAGMA_LIB = -L$(MAGMA_DIR)/lib -l:libmagma.a -lcublas -lcusparse $(LAPACK_LIB)
# GnuTLS library configuration
GNUTLS_OPT =
GNUTLS_LIB = -lgnutls
@@ -514,11 +497,11 @@ GSLIB_LIB = -L$(GSLIB_DIR)/lib -lgs
# CUDA library configuration
CUDA_OPT =
CUDA_LIB = -lcusparse -lcublas
CUDA_LIB = -lcusparse
# HIP library configuration
HIP_OPT =
HIP_LIB = -L$(HIP_DIR)/lib $(XLINKER)-rpath,$(HIP_DIR)/lib -lhipsparse -lhipblas
HIP_LIB = -L$(HIP_DIR)/lib $(XLINKER)-rpath,$(HIP_DIR)/lib -lhipsparse
# OCCA library configuration
OCCA_DIR = @MFEM_DIR@/../occa
@@ -540,10 +523,8 @@ ifdef GOTCHA_DIR
endif
# BLITZ library configuration
# BLITZ_DIR must be the custom installation folder (-DCMAKE_INSTALL_PREFIX).
BLITZ_DIR = @MFEM_DIR@/../blitz/install
BLITZ_DIR = @MFEM_DIR@/../blitz
BLITZ_OPT = -I$(BLITZ_DIR)/include
# On intel machines, use /lib64 instead of /lib.
BLITZ_LIB = $(XLINKER)-rpath,$(BLITZ_DIR)/lib -L$(BLITZ_DIR)/lib -lblitz
# ALGOIM library configuration
+13 -83
View File
@@ -32,7 +32,7 @@ groups_serial=(
'"examples"
"Examples:"
"examples"
"ex{,[1-9]}[0-9].cpp"'
"ex{,1,2,3}[0-9].cpp"'
# "ex1.cpp"'
'"sundials"
"SUNDIALS examples:"
@@ -58,10 +58,6 @@ groups_serial=(
"HiOp examples:"
"examples/hiop"
"ex9.cpp"'
'"moonolith"
"Moonolith examples:"
"examples/moonolith"
"ex1.cpp"'
'"pumi"
"PUMI examples:"
"examples/pumi"
@@ -70,38 +66,25 @@ groups_serial=(
'"meshing"
"Meshing miniapps:"
"miniapps/meshing"
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp mesh-quality.cpp
polar-nc.cpp reflector.cpp shaper.cpp trimmer.cpp twist.cpp
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp
mesh-optimizer.cpp minimal-surface.cpp"'
'"adjoint"
"Adjoint miniapps:"
"miniapps/adjoint"
"cvsRoberts_ASAi_dns.cpp"'
'"autodiff"
"Autodiff miniapps:"
"miniapps/autodiff"
"seq_example.cpp seq_test.cpp"' # 'seq_test.cpp' has no sample runs
'"dpg"
"DPG miniapps:"
"miniapps/dpg"
"{acoustics,convection-diffusion,diffusion,maxwell}.cpp"'
'"gslib"
"GSLIB miniapps:"
"miniapps/gslib"
"field-diff.cpp field-interp.cpp findpts.cpp schwarz_ex1.cpp "'
# todo: miniapps/mtop
'"nurbs"
"NURBS miniapps:"
"miniapps/nurbs"
"nurbs_ex1.cpp"'
# todo: add other nurbs miniapps
# todo: miniapps/solvers (serial)
'"tools"
"Tools miniapps:"
"miniapps/tools"
"convert-dc.cpp display-basis.cpp get-values.cpp load-dc.cpp
lor-transfer.cpp"'
# todo: add other tools miniapps
'"toys"
"Toys miniapps:"
"miniapps/toys"
@@ -117,7 +100,7 @@ groups_parallel=(
'"examples"
"Examples:"
"examples"
"ex{,[1-9]}[0-9]p.cpp"'
"ex{,1,2,3}[0-9]p.cpp"'
# "ex1p.cpp"'
'"sundials"
"SUNDIALS examples:"
@@ -143,10 +126,6 @@ groups_parallel=(
"HiOp examples:"
"examples/hiop"
"ex9p.cpp"'
'"moonolith"
"Moonolith examples:"
"examples/moonolith"
"ex{1,2}p.cpp"'
'"pumi"
"PUMI examples:"
"examples/pumi"
@@ -159,41 +138,24 @@ groups_parallel=(
'"meshing"
"Meshing miniapps:"
"miniapps/meshing"
"pmesh-optimizer.cpp pmesh-fitting.cpp pminimal-surface.cpp
fit-node-position.cpp"'
"pmesh-optimizer.cpp pmesh-fitting.cpp pminimal-surface.cpp"'
'"electromagnetics"
"Electromagnetics miniapps:"
"miniapps/electromagnetics"
"joule.cpp"'
# "{joule,maxwell,tesla,volta}.cpp"' # todo: multiline sample runs
# "{volta,tesla,joule}.cpp"' # todo: multiline sample runs
'"adjoint"
"Adjoint miniapps:"
"miniapps/adjoint"
"adjoint_advection_diffusion.cpp"'
'"autodiff"
"Autodiff miniapps:"
"miniapps/autodiff"
"par_example.cpp"'
'"dpg"
"DPG miniapps:"
"miniapps/dpg"
"p{acoustics,convection-diffusion,diffusion,maxwell}.cpp"'
'"gslib"
"GSLIB miniapps:"
"miniapps/gslib"
"pfindpts.cpp schwarz_ex1p.cpp"'
'"hdiv-linear-solver"
"H(div) linear solver miniapps:"
"miniapps/hdiv-linear-solver"
"grad_div.cpp darcy.cpp"'
# 'miniapps/hooke/hooke.cpp' has no sample runs
# todo: miniapps/mtop
# todo: miniapps/multidomain
'"navier"
"Navier miniapps:"
"miniapps/navier"
"navier_cht.cpp"'
# todo: add other navier miniapps
'"nurbs"
"NURBS miniapps:"
"miniapps/nurbs"
@@ -202,18 +164,14 @@ groups_parallel=(
"Shifted miniapps:"
"miniapps/shifted"
"distance.cpp"'
# todo: add other shifted miniapps
'"solvers"
"Solvers miniapps:"
"miniapps/solvers"
"block-solvers.cpp"'
# todo: add other solvers miniapps
# todo: miniapps/spde
'"tools"
"Tools miniapps:"
"miniapps/tools"
"convert-dc.cpp get-values.cpp load-dc.cpp"'
# todo: add other tools miniapps
"convert-cd.cpp get-values.cpp load-dc.cpp"'
'"convergence"
"Convergence tests:"
"tests/convergence"
@@ -228,7 +186,7 @@ groups_all=(
'"examples"
"Examples:"
"examples"
"ex\"{,[1-9]}[0-9]\"{,p}.cpp"'
"ex\"{,1,2,3}[0-9]\"{,p}.cpp"'
'"sundials"
"SUNDIALS examples:"
"examples/sundials"
@@ -257,14 +215,10 @@ groups_all=(
"HiOp examples:"
"examples/hiop"
"ex9.cpp ex9p.cpp"'
'"moonolith"
"Moonolith examples:"
"examples/moonolith"
"ex1.cpp ex{1,2}p.cpp"'
'"pumi"
"PUMI examples:"
"examples/pumi"
"ex1.cpp ex2.cpp ex1p.cpp ex6p.cpp"'
"ex1.cpp ex1p.cpp ex2.cpp ex6p.cpp"'
'"superlu"
"Superlu examples:"
"examples/superlu"
@@ -272,67 +226,43 @@ groups_all=(
'"meshing"
"Meshing miniapps:"
"miniapps/meshing"
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp mesh-quality.cpp
polar-nc.cpp reflector.cpp shaper.cpp trimmer.cpp twist.cpp
{,p}mesh-optimizer.cpp pmesh-fitting.cpp {,p}minimal-surface.cpp
fit-node-position.cpp"'
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp
{,p}mesh-optimizer.cpp pmesh-fitting.cpp {,p}minimal-surface.cpp"'
'"electromagnetics"
"Electromagnetics miniapps:"
"miniapps/electromagnetics"
"joule.cpp"'
# "{joule,maxwell,tesla,volta}.cpp"' # todo: multiline sample runs
# "{volta,tesla,joule}.cpp"' # todo: multiline sample runs
'"adjoint"
"Adjoint miniapps:"
"miniapps/adjoint"
"cvsRoberts_ASAi_dns.cpp adjoint_advection_diffusion.cpp"'
'"autodiff"
"Autodiff miniapps:"
"miniapps/autodiff"
"seq_example.cpp seq_test.cpp par_example.cpp"'
# 'seq_test.cpp' has no sample runs
'"dpg"
"DPG miniapps:"
"miniapps/dpg"
"{,p}{acoustics,convection-diffusion,diffusion,maxwell}.cpp"'
"adjoint_advection_diffusion.cpp cvsRoberts_ASAi_dns.cpp"'
'"gslib"
"GSLIB miniapps:"
"miniapps/gslib"
"field-diff.cpp field-interp.cpp findpts.cpp schwarz_ex1.cpp pfindpts.cpp
schwarz_ex1p.cpp"'
'"hdiv-linear-solver"
"H(div) linear solver miniapps:"
"miniapps/hdiv-linear-solver"
"grad_div.cpp darcy.cpp"'
# 'miniapps/hooke/hooke.cpp' has no sample runs
# todo: miniapps/mtop
# todo: miniapps/multidomain
'"navier"
"Navier miniapps:"
"miniapps/navier"
"navier_cht.cpp"'
# todo: add other navier miniapps
'"nurbs"
"NURBS miniapps:"
"miniapps/nurbs"
"nurbs_ex1.cpp nurbs_ex1p.cpp nurbs_ex11p.cpp"'
# todo: add other nurbs miniapps
'"shifted"
"Shifted miniapps:"
"miniapps/shifted"
"distance.cpp"'
# todo: add other shifted miniapps
'"solvers"
"Solvers miniapps:"
"miniapps/solvers"
"block-solvers.cpp"'
# todo: add other solvers miniapps
# todo: miniapps/spde
'"tools"
"Tools miniapps:"
"miniapps/tools"
"convert-dc.cpp display-basis.cpp get-values.cpp load-dc.cpp
lor-transfer.cpp"'
# todo: add other tools miniapps
'"toys"
"Toys miniapps:"
"miniapps/toys"
@@ -456,7 +386,7 @@ function help_message()
mfem_config [${mfem_config}]
Set MFEM configuration options
make [${make}], mpiexec [${mpiexec}], mpiexec_np [${mpiexec_np}]
Their values can also be set using the respective uppercase environment
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>
+3 -3
View File
@@ -18,9 +18,9 @@ elements
boundary
4
1 1 0 1
2 1 2 3
3 1 3 0
4 1 1 2
1 1 2 3
1 1 3 0
1 1 1 2
edges
4
+1 -3
View File
@@ -938,7 +938,6 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
@MFEM_SOURCE_DIR@/config \
@MFEM_SOURCE_DIR@/general \
@MFEM_SOURCE_DIR@/linalg \
@MFEM_SOURCE_DIR@/linalg/batched \
@MFEM_SOURCE_DIR@/linalg/simd \
@MFEM_SOURCE_DIR@/mesh \
@MFEM_SOURCE_DIR@/mesh/submesh \
@@ -1050,8 +1049,7 @@ RECURSIVE = NO
EXCLUDE = @MFEM_SOURCE_DIR@/config/_config.hpp \
@MFEM_SOURCE_DIR@/config/get_hypre_version.cpp \
@MFEM_SOURCE_DIR@/general/tinyxml2.h \
@MFEM_SOURCE_DIR@/general/tinyxml2.cpp \
@MFEM_SOURCE_DIR@/linalg/lapack.hpp
@MFEM_SOURCE_DIR@/general/tinyxml2.cpp
# 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
-15
View File
@@ -182,21 +182,6 @@ namespace mfem {
* <a class="el" href="examples_2superlu_2ex1p_8cpp_source.html">1p</a>,
* demonstrating the use of MFEM's \link superlu.hpp SuperLU integration\endlink.
*
* <H4>NURBS Examples</H4>
* - Variants of Examples
* <a class="el" href="nurbs__ex1_8cpp_source.html">1</a>,
* <a class="el" href="nurbs__ex1p_8cpp_source.html">1p</a>,
* <a class="el" href="nurbs__ex3_8cpp_source.html">3</a>,
* <a class="el" href="nurbs__ex5_8cpp_source.html">5</a>,
* <a class="el" href="nurbs__ex11p_8cpp_source.html">11p</a>, and
* <a class="el" href="nurbs__ex24_8cpp_source.html">24</a>,
* demonstrating howto perform NURBS-based Isogeometric Analysis.
* - Variant of Example <a class="el" href="nurbs__patch__ex1_8cpp_source.html">1</a>: demonstrates the use of patch integration
* - <a class="el" href="nurbs__solenoidal_8cpp_source.html">NURBS Divergence-free</a>: solve a solenoidal vector projection with NURBS-based H(div) elements
* - <a class="el" href="nurbs__curveint_8cpp_source.html">NURBS Interpolation</a>: NURBS interpolation of given geometry
* - <a class="el" href="nurbs__naca__cmesh_8cpp_source.html">NURBS NACA Mesher</a>: generate NURBS based mesh around a NACA foil
* - <a class="el" href="nurbs__printfunc_8cpp_source.html">NURBS Printer</a>: print the NURBS-basis
*
* <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
+4 -3
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
MFEM_INSTALL_DIR ?= ../../mfem
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/amgx/,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
+4 -3
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
MFEM_INSTALL_DIR ?= ../../mfem
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/caliper,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
+45 -19
View File
@@ -3,14 +3,14 @@
// Compile with: make ex10
//
// Sample runs:
// ex10 -m ../data/beam-quad.mesh -s 23 -r 2 -o 2 -dt 3
// ex10 -m ../data/beam-tri.mesh -s 23 -r 2 -o 2 -dt 3
// ex10 -m ../data/beam-hex.mesh -s 22 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-tet.mesh -s 22 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-wedge.mesh -s 22 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-quad.mesh -s 4 -r 2 -o 2 -dt 0.03 -vs 20
// ex10 -m ../data/beam-hex.mesh -s 4 -r 1 -o 2 -dt 0.05 -vs 20
// ex10 -m ../data/beam-quad-amr.mesh -s 23 -r 2 -o 2 -dt 3
// ex10 -m ../data/beam-quad.mesh -s 3 -r 2 -o 2 -dt 3
// 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
@@ -87,16 +87,16 @@ public:
real_t visc, real_t mu, real_t K);
/// Compute the right-hand side of the ODE system.
void Mult(const Vector &vx, Vector &dvx_dt) const override;
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
/** Solve the Backward-Euler equation: k = f(x + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
real_t ElasticEnergy(const Vector &x) const;
real_t KineticEnergy(const Vector &v) const;
void GetElasticEnergyDensity(const GridFunction &x, GridFunction &w) const;
~HyperelasticOperator() override;
virtual ~HyperelasticOperator();
};
/** Nonlinear operator of the form:
@@ -120,12 +120,12 @@ public:
void SetParameters(real_t dt_, const Vector *v_, const Vector *x_);
/// Compute y = H(x + dt (v + dt k)) + M k + S (v + dt k).
void Mult(const Vector &k, Vector &y) const override;
virtual void Mult(const Vector &k, Vector &y) const;
/// Compute J = M + dt S + dt^2 grad_H(x + dt (v + dt k)).
Operator &GetGradient(const Vector &k) const override;
virtual Operator &GetGradient(const Vector &k) const;
~ReducedSystemOperator() override;
virtual ~ReducedSystemOperator();
};
@@ -141,8 +141,8 @@ private:
public:
ElasticEnergyCoefficient(HyperelasticModel &m, const GridFunction &x_)
: model(m), x(x_) { }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
~ElasticEnergyCoefficient() override { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual ~ElasticEnergyCoefficient() { }
};
void InitialDeformation(const Vector &x, Vector &y);
@@ -160,7 +160,7 @@ int main(int argc, char *argv[])
const char *mesh_file = "../data/beam-quad.mesh";
int ref_levels = 2;
int order = 2;
int ode_solver_type = 23;
int ode_solver_type = 3;
real_t t_final = 300.0;
real_t dt = 3.0;
real_t visc = 1e-2;
@@ -177,7 +177,11 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
ODESolver::Types.c_str());
"ODE solver: 1 - Backward Euler, 2 - SDIRK2, 3 - SDIRK3,\n\t"
" 11 - Forward Euler, 12 - RK2,\n\t"
" 13 - RK3 SSP, 14 - RK4."
" 22 - Implicit Midpoint Method,\n\t"
" 23 - SDIRK23 (A-stable), 24 - SDIRK34");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -209,7 +213,28 @@ int main(int argc, char *argv[])
// 3. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
ODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit L-stable methods
case 1: ode_solver = new BackwardEulerSolver; break;
case 2: ode_solver = new SDIRK23Solver(2); break;
case 3: ode_solver = new SDIRK33Solver; break;
// Explicit methods
case 11: ode_solver = new ForwardEulerSolver; break;
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;
}
// 4. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
@@ -346,6 +371,7 @@ int main(int argc, char *argv[])
}
// 10. Free the used memory.
delete ode_solver;
delete mesh;
return 0;
+48 -19
View File
@@ -3,14 +3,14 @@
// Compile with: make ex10p
//
// Sample runs:
// mpirun -np 4 ex10p -m ../data/beam-quad.mesh -s 23 -rs 2 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-tri.mesh -s 23 -rs 2 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 22 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-tet.mesh -s 22 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-wedge.mesh -s 22 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-quad.mesh -s 4 -rs 2 -dt 0.03 -vs 20
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 4 -rs 1 -dt 0.05 -vs 20
// mpirun -np 4 ex10p -m ../data/beam-quad-amr.mesh -s 23 -rs 2 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-quad.mesh -s 3 -rs 2 -dt 3
// 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
@@ -89,17 +89,17 @@ public:
real_t visc, real_t mu, real_t K);
/// Compute the right-hand side of the ODE system.
void Mult(const Vector &vx, Vector &dvx_dt) const override;
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
/** Solve the Backward-Euler equation: k = f(x + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
real_t ElasticEnergy(const ParGridFunction &x) const;
real_t KineticEnergy(const ParGridFunction &v) const;
void GetElasticEnergyDensity(const ParGridFunction &x,
ParGridFunction &w) const;
~HyperelasticOperator() override;
virtual ~HyperelasticOperator();
};
/** Nonlinear operator of the form:
@@ -125,12 +125,12 @@ public:
void SetParameters(real_t dt_, const Vector *v_, const Vector *x_);
/// Compute y = H(x + dt (v + dt k)) + M k + S (v + dt k).
void Mult(const Vector &k, Vector &y) const override;
virtual void Mult(const Vector &k, Vector &y) const;
/// Compute J = M + dt S + dt^2 grad_H(x + dt (v + dt k)).
Operator &GetGradient(const Vector &k) const override;
virtual Operator &GetGradient(const Vector &k) const;
~ReducedSystemOperator() override;
virtual ~ReducedSystemOperator();
};
@@ -146,8 +146,8 @@ private:
public:
ElasticEnergyCoefficient(HyperelasticModel &m, const ParGridFunction &x_)
: model(m), x(x_) { }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
~ElasticEnergyCoefficient() override { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual ~ElasticEnergyCoefficient() { }
};
void InitialDeformation(const Vector &x, Vector &y);
@@ -172,7 +172,7 @@ int main(int argc, char *argv[])
int ser_ref_levels = 2;
int par_ref_levels = 0;
int order = 2;
int ode_solver_type = 23;
int ode_solver_type = 3;
real_t t_final = 300.0;
real_t dt = 3.0;
real_t visc = 1e-2;
@@ -192,7 +192,11 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
ODESolver::Types.c_str());
"ODE solver: 1 - Backward Euler, 2 - SDIRK2, 3 - SDIRK3,\n\t"
" 11 - Forward Euler, 12 - RK2,\n\t"
" 13 - RK3 SSP, 14 - RK4."
" 22 - Implicit Midpoint Method,\n\t"
" 23 - SDIRK23 (A-stable), 24 - SDIRK34");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -234,7 +238,31 @@ int main(int argc, char *argv[])
// 4. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
ODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit L-stable methods
case 1: ode_solver = new BackwardEulerSolver; break;
case 2: ode_solver = new SDIRK23Solver(2); break;
case 3: ode_solver = new SDIRK33Solver; break;
// Explicit methods
case 11: ode_solver = new ForwardEulerSolver; break;
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:
if (myid == 0)
{
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
}
delete mesh;
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
@@ -405,6 +433,7 @@ int main(int argc, char *argv[])
}
// 12. Free the used memory.
delete ode_solver;
delete pmesh;
return 0;
+1 -1
View File
@@ -53,7 +53,7 @@ public:
pmesh(pmesh_),
pgf(pgf_) {}
void MonitorSolution(int i, real_t norm, const Vector &x, bool final) override
void MonitorSolution(int i, real_t norm, const Vector &x, bool final)
{
char vishost[] = "localhost";
int visport = 19916;
+33 -12
View File
@@ -5,10 +5,10 @@
// Sample runs: ex16
// ex16 -m ../data/inline-tri.mesh
// ex16 -m ../data/disc-nurbs.mesh -tf 2
// ex16 -s 21 -a 0.0 -k 1.0
// ex16 -s 22 -a 1.0 -k 0.0
// ex16 -s 23 -a 0.5 -k 0.5 -o 4
// ex16 -s 4 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// ex16 -s 1 -a 0.0 -k 1.0
// ex16 -s 2 -a 1.0 -k 0.0
// 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
@@ -76,15 +76,15 @@ public:
ConductionOperator(FiniteElementSpace &f, real_t alpha, real_t kappa,
const Vector &u);
void Mult(const Vector &u, Vector &du_dt) const override;
virtual void Mult(const Vector &u, Vector &du_dt) const;
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
void ImplicitSolve(const real_t dt, const Vector &u, Vector &k) override;
virtual void ImplicitSolve(const real_t dt, const Vector &u, Vector &k);
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
void SetParameters(const Vector &u);
~ConductionOperator() override;
virtual ~ConductionOperator();
};
real_t InitialTemperature(const Vector &x);
@@ -95,13 +95,11 @@ int main(int argc, char *argv[])
const char *mesh_file = "../data/star.mesh";
int ref_levels = 2;
int order = 2;
int ode_solver_type = 23; // SDIRK33Solver
int ode_solver_type = 3;
real_t t_final = 0.5;
real_t dt = 1.0e-2;
real_t alpha = 1.0e-2;
real_t kappa = 0.5;
bool visualization = true;
bool visit = false;
int vis_steps = 5;
@@ -117,7 +115,8 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
ODESolver::Types.c_str());
"ODE solver: 1 - Backward Euler, 2 - SDIRK2, 3 - SDIRK3,\n\t"
"\t 11 - Forward Euler, 12 - RK2, 13 - RK3 SSP, 14 - RK4.");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -150,7 +149,28 @@ int main(int argc, char *argv[])
// 3. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
ODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit L-stable methods
case 1: ode_solver = new BackwardEulerSolver; break;
case 2: ode_solver = new SDIRK23Solver(2); break;
case 3: ode_solver = new SDIRK33Solver; break;
// Explicit methods
case 11: ode_solver = new ForwardEulerSolver; break;
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;
}
// 4. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
@@ -267,6 +287,7 @@ int main(int argc, char *argv[])
}
// 10. Free the used memory.
delete ode_solver;
delete mesh;
return 0;
+33 -12
View File
@@ -5,10 +5,10 @@
// Sample runs: mpirun -np 4 ex16p
// mpirun -np 4 ex16p -m ../data/inline-tri.mesh
// mpirun -np 4 ex16p -m ../data/disc-nurbs.mesh -tf 2
// mpirun -np 4 ex16p -s 21 -a 0.0 -k 1.0
// mpirun -np 4 ex16p -s 22 -a 1.0 -k 0.0
// mpirun -np 8 ex16p -s 23 -a 0.5 -k 0.5 -o 4
// mpirun -np 4 ex16p -s 4 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// mpirun -np 4 ex16p -s 1 -a 0.0 -k 1.0
// mpirun -np 4 ex16p -s 2 -a 1.0 -k 0.0
// 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
@@ -78,15 +78,15 @@ public:
ConductionOperator(ParFiniteElementSpace &f, real_t alpha, real_t kappa,
const Vector &u);
void Mult(const Vector &u, Vector &du_dt) const override;
virtual void Mult(const Vector &u, Vector &du_dt) const;
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
void ImplicitSolve(const real_t dt, const Vector &u, Vector &k) override;
virtual void ImplicitSolve(const real_t dt, const Vector &u, Vector &k);
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
void SetParameters(const Vector &u);
~ConductionOperator() override;
virtual ~ConductionOperator();
};
real_t InitialTemperature(const Vector &x);
@@ -104,13 +104,11 @@ int main(int argc, char *argv[])
int ser_ref_levels = 2;
int par_ref_levels = 1;
int order = 2;
int ode_solver_type = 23; // SDIRK33Solver
int ode_solver_type = 3;
real_t t_final = 0.5;
real_t dt = 1.0e-2;
real_t alpha = 1.0e-2;
real_t kappa = 0.5;
bool visualization = true;
bool visit = false;
int vis_steps = 5;
@@ -129,7 +127,8 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
ODESolver::Types.c_str());
"ODE solver: 1 - Backward Euler, 2 - SDIRK2, 3 - SDIRK3,\n\t"
"\t 11 - Forward Euler, 12 - RK2, 13 - RK3 SSP, 14 - RK4.");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -170,7 +169,28 @@ int main(int argc, char *argv[])
// 4. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
ODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit L-stable methods
case 1: ode_solver = new BackwardEulerSolver; break;
case 2: ode_solver = new SDIRK23Solver(2); break;
case 3: ode_solver = new SDIRK33Solver; break;
// Explicit methods
case 11: ode_solver = new ForwardEulerSolver; break;
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;
}
// 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
@@ -356,6 +376,7 @@ int main(int argc, char *argv[])
}
// 12. Free the used memory.
delete ode_solver;
delete pmesh;
return 0;
+2 -2
View File
@@ -69,7 +69,7 @@ public:
void SetDisplacement(GridFunction &u_) { u = &u_; }
void SetComponent(int i, int j) { si = i; sj = j; }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
};
// Simple GLVis visualization manager.
@@ -89,7 +89,7 @@ public:
void NewWindow();
void CloseConnection();
void PositionWindow();
~VisMan() override;
virtual ~VisMan();
};
// Manipulators for the GLVis visualization manager.
+2 -2
View File
@@ -69,7 +69,7 @@ public:
void SetDisplacement(GridFunction &u_) { u = &u_; }
void SetComponent(int i, int j) { si = i; sj = j; }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
};
// Simple GLVis visualization manager.
@@ -89,7 +89,7 @@ public:
void NewWindow();
void CloseConnection();
void PositionWindow();
~VisMan() override;
virtual ~VisMan();
};
// Manipulators for the GLVis visualization manager.
+17 -2
View File
@@ -90,7 +90,8 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
ODESolver::ExplicitTypes.c_str());
"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.");
@@ -124,7 +125,18 @@ int main(int argc, char *argv[])
// 3. Define the ODE solver used for time integration. Several explicit
// Runge-Kutta methods are available.
unique_ptr<ODESolver> ode_solver = ODESolver::SelectExplicit(ode_solver_type);
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. Define the discontinuous DG finite element space of the given
// polynomial order on the refined mesh.
@@ -292,5 +304,8 @@ int main(int argc, char *argv[])
const real_t error = sol.ComputeLpError(2, u0);
cout << "Solution error: " << error << endl;
// Free the used memory.
delete ode_solver;
return 0;
}
+17 -2
View File
@@ -99,7 +99,8 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
ODESolver::ExplicitTypes.c_str());
"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.");
@@ -147,7 +148,18 @@ int main(int argc, char *argv[])
// 3. Define the ODE solver used for time integration. Several explicit
// Runge-Kutta methods are available.
unique_ptr<ODESolver> ode_solver = ODESolver::SelectExplicit(ode_solver_type);
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. Define the discontinuous DG finite element space of the given
// polynomial order on the refined mesh.
@@ -348,5 +360,8 @@ int main(int argc, char *argv[])
cout << "Solution error: " << error << endl;
}
// Free the used memory.
delete ode_solver;
return 0;
}
+7 -7
View File
@@ -48,7 +48,7 @@ public:
print_level = print_lvl;
}
void MonitorResidual(int it, real_t norm, const Vector &r, bool final) override;
virtual void MonitorResidual(int it, real_t norm, const Vector &r, bool final);
private:
const std::string prefix;
@@ -116,10 +116,10 @@ public:
JacobianPreconditioner(Array<FiniteElementSpace *> &fes,
SparseMatrix &mass, Array<int> &offsets);
void Mult(const Vector &k, Vector &y) const override;
void SetOperator(const Operator &op) override;
virtual void Mult(const Vector &k, Vector &y) const;
virtual void SetOperator(const Operator &op);
~JacobianPreconditioner() override;
virtual ~JacobianPreconditioner();
};
// After spatial discretization, the rubber model can be written as:
@@ -161,13 +161,13 @@ public:
int iter, Coefficient &mu);
// Required to use the native newton solver
Operator &GetGradient(const Vector &xp) const override;
void Mult(const Vector &k, Vector &y) const override;
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;
~RubberOperator() override;
virtual ~RubberOperator();
};
// Visualization driver
+7 -7
View File
@@ -62,7 +62,7 @@ public:
#endif
}
void MonitorResidual(int it, real_t norm, const Vector &r, bool final) override;
virtual void MonitorResidual(int it, real_t norm, const Vector &r, bool final);
private:
const std::string prefix;
@@ -130,10 +130,10 @@ public:
JacobianPreconditioner(Array<ParFiniteElementSpace *> &fes,
Operator &mass, Array<int> &offsets);
void Mult(const Vector &k, Vector &y) const override;
void SetOperator(const Operator &op) override;
virtual void Mult(const Vector &k, Vector &y) const;
virtual void SetOperator(const Operator &op);
~JacobianPreconditioner() override;
virtual ~JacobianPreconditioner();
};
// After spatial discretization, the rubber model can be written as:
@@ -175,13 +175,13 @@ public:
int iter, Coefficient &mu);
// Required to use the native newton solver
Operator &GetGradient(const Vector &xp) const override;
void Mult(const Vector &k, Vector &y) const override;
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;
~RubberOperator() override;
virtual ~RubberOperator();
};
// Visualization driver
+2 -2
View File
@@ -79,14 +79,14 @@ class GradT : public Operator
{
public:
GradT() : Operator(1) {}
void Mult(const Vector &x, Vector &y) const override { y.Set(1.0/m_, x); }
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 override;
void Mult(const Vector &x, Vector &y) const;
};
int main(int argc, char *argv[])
+2 -2
View File
@@ -84,14 +84,14 @@ class GradT : public Operator
{
public:
GradT() : Operator(1) {}
void Mult(const Vector &x, Vector &y) const override { y.Set(1.0/m_, x); }
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 override;
void Mult(const Vector &x, Vector &y) const;
};
int main(int argc, char *argv[])
+54 -23
View File
@@ -44,7 +44,7 @@ protected:
BilinearForm *M;
BilinearForm *K;
SparseMatrix Mmat, Kmat;
SparseMatrix Mmat, Kmat, Kmat0;
SparseMatrix *T; // T = M + dt K
real_t current_dt;
@@ -61,20 +61,20 @@ public:
WaveOperator(FiniteElementSpace &f, Array<int> &ess_bdr, real_t speed);
using SecondOrderTimeDependentOperator::Mult;
void Mult(const Vector &u, const Vector &du_dt,
Vector &d2udt2) const override;
virtual void Mult(const Vector &u, const Vector &du_dt,
Vector &d2udt2) const;
/** Solve the Backward-Euler equation:
d2udt2 = f(u + fac0*d2udt2,dudt + fac1*d2udt2, t),
for the unknown d2udt2. */
using SecondOrderTimeDependentOperator::ImplicitSolve;
void ImplicitSolve(const real_t fac0, const real_t fac1,
const Vector &u, const Vector &dudt, Vector &d2udt2) override;
virtual void ImplicitSolve(const real_t fac0, const real_t fac1,
const Vector &u, const Vector &dudt, Vector &d2udt2);
///
void SetParameters(const Vector &u);
~WaveOperator() override;
virtual ~WaveOperator();
};
@@ -83,24 +83,25 @@ WaveOperator::WaveOperator(FiniteElementSpace &f,
: SecondOrderTimeDependentOperator(f.GetTrueVSize(), (real_t) 0.0),
fespace(f), M(NULL), K(NULL), T(NULL), current_dt(0.0), z(height)
{
// Assemble Laplace matrix
const real_t rel_tol = 1e-8;
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
c2 = new ConstantCoefficient(speed*speed);
K = new BilinearForm(&fespace);
K->AddDomainIntegrator(new DiffusionIntegrator(*c2));
K->Assemble();
// Assemble Mass matrix
Array<int> dummy;
K->FormSystemMatrix(dummy, Kmat0);
K->FormSystemMatrix(ess_tdof_list, Kmat);
M = new BilinearForm(&fespace);
M->AddDomainIntegrator(new MassIntegrator());
M->Assemble();
// Apply Bcs
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
K->FormSystemMatrix(ess_tdof_list, Kmat);
M->FormSystemMatrix(ess_tdof_list, Mmat);
// Configure preconditioner
const real_t rel_tol = 1e-8;
M_solver.iterative_mode = false;
M_solver.SetRelTol(rel_tol);
M_solver.SetAbsTol(0.0);
@@ -109,13 +110,14 @@ WaveOperator::WaveOperator(FiniteElementSpace &f,
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(Mmat);
// Configure solver
T_solver.iterative_mode = false;
T_solver.SetRelTol(rel_tol);
T_solver.SetAbsTol(0.0);
T_solver.SetMaxIter(100);
T_solver.SetPrintLevel(0);
T_solver.SetPreconditioner(T_prec);
T = NULL;
}
void WaveOperator::Mult(const Vector &u, const Vector &du_dt,
@@ -124,11 +126,9 @@ void WaveOperator::Mult(const Vector &u, const Vector &du_dt,
// Compute:
// d2udt2 = M^{-1}*-K(u)
// for d2udt2
K->FullMult(u, z);
Kmat.Mult(u, z);
z.Neg(); // z = -z
z.SetSubVector(ess_tdof_list, 0.0);
M_solver.Mult(z, d2udt2);
d2udt2.SetSubVector(ess_tdof_list, 0.0);
}
void WaveOperator::ImplicitSolve(const real_t fac0, const real_t fac1,
@@ -142,11 +142,14 @@ void WaveOperator::ImplicitSolve(const real_t fac0, const real_t fac1,
T = Add(1.0, Mmat, fac0, Kmat);
T_solver.SetOperator(*T);
}
K->FullMult(u, z);
Kmat0.Mult(u, z);
z.Neg();
z.SetSubVector(ess_tdof_list, 0.0);
for (int i = 0; i < ess_tdof_list.Size(); i++)
{
z[ess_tdof_list[i]] = 0.0;
}
T_solver.Mult(z, d2udt2);
d2udt2.SetSubVector(ess_tdof_list, 0.0);
}
void WaveOperator::SetParameters(const Vector &u)
@@ -201,7 +204,9 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
SecondOrderODESolver::Types.c_str());
"ODE solver: [0--10] - GeneralizedAlpha(0.1 * s),\n\t"
"\t 11 - Average Acceleration, 12 - Linear Acceleration\n"
"\t 13 - CentralDifference, 14 - FoxGoodwin");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -236,7 +241,32 @@ int main(int argc, char *argv[])
// 3. Define the ODE solver used for time integration. Several second order
// time integrators are available.
SecondOrderODESolver *ode_solver= SecondOrderODESolver::Select(ode_solver_type);
SecondOrderODESolver *ode_solver;
switch (ode_solver_type)
{
// Implicit methods
case 0: ode_solver = new GeneralizedAlpha2Solver(0.0); break;
case 1: ode_solver = new GeneralizedAlpha2Solver(0.1); break;
case 2: ode_solver = new GeneralizedAlpha2Solver(0.2); break;
case 3: ode_solver = new GeneralizedAlpha2Solver(0.3); break;
case 4: ode_solver = new GeneralizedAlpha2Solver(0.4); break;
case 5: ode_solver = new GeneralizedAlpha2Solver(0.5); break;
case 6: ode_solver = new GeneralizedAlpha2Solver(0.6); break;
case 7: ode_solver = new GeneralizedAlpha2Solver(0.7); break;
case 8: ode_solver = new GeneralizedAlpha2Solver(0.8); break;
case 9: ode_solver = new GeneralizedAlpha2Solver(0.9); break;
case 10: ode_solver = new GeneralizedAlpha2Solver(1.0); break;
case 11: ode_solver = new AverageAccelerationSolver(); break;
case 12: ode_solver = new LinearAccelerationSolver(); break;
case 13: ode_solver = new CentralDifferenceSolver(); break;
case 14: ode_solver = new FoxGoodwinSolver(); break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
delete mesh;
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
@@ -284,6 +314,7 @@ int main(int argc, char *argv[])
ess_bdr = 0;
}
}
WaveOperator oper(fespace, ess_bdr, speed);
u_gf.SetFromTrueDofs(u);
+2 -2
View File
@@ -103,8 +103,8 @@ public:
using VectorCoefficient::Eval;
void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip)
{
real_t x[3];
Vector transip(x, 3);
+2 -2
View File
@@ -102,8 +102,8 @@ public:
using VectorCoefficient::Eval;
void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip)
{
real_t x[3];
Vector transip(x, 3);
+1 -1
View File
@@ -58,7 +58,7 @@ public:
}
}
~DiffusionMultigrid() override
virtual ~DiffusionMultigrid()
{
delete amg;
}
+3 -3
View File
@@ -53,7 +53,7 @@ public:
real_t min_val_=-36)
: u(&u_), obstacle(&obst_), min_val(min_val_) { }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
};
class ExponentialGridFunctionCoefficient : public Coefficient
@@ -69,7 +69,7 @@ public:
real_t min_val_=0.0, real_t max_val_=1e6)
: u(&u_), obstacle(&obst_), min_val(min_val_), max_val(max_val_) { }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
};
int main(int argc, char *argv[])
@@ -258,7 +258,7 @@ int main(int argc, char *argv[])
MixedBilinearForm a10(&H1fes,&L2fes);
a10.AddDomainIntegrator(new MixedScalarMassIntegrator());
a10.Assemble();
a10.EliminateTrialEssentialBC(ess_bdr, x.GetBlock(0), rhs.GetBlock(1));
a10.EliminateTrialDofs(ess_bdr, x.GetBlock(0), rhs.GetBlock(1));
a10.Finalize();
SparseMatrix &A10 = a10.SpMat();
+2 -2
View File
@@ -53,7 +53,7 @@ public:
real_t min_val_=-36)
: u(&u_), obstacle(&obst_), min_val(min_val_) { }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
};
class ExponentialGridFunctionCoefficient : public Coefficient
@@ -69,7 +69,7 @@ public:
real_t min_val_=0.0, real_t max_val_=1e6)
: u(&u_), obstacle(&obst_), min_val(min_val_), max_val(max_val_) { }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
};
int main(int argc, char *argv[])
+8 -8
View File
@@ -52,8 +52,8 @@ public:
fun(fun_) {}
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
return fun(GridFunctionCoefficient::Eval(T, ip));
}
@@ -83,8 +83,8 @@ public:
OtherGridF_cf(OtherGridF),
fun(fun_) {}
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
const real_t value1 = fun(GridFunctionCoefficient::Eval(T, ip));
const real_t value2 = fun(OtherGridF_cf.Eval(T, ip));
@@ -108,7 +108,7 @@ public:
: rho_filter(rho_filter_), min_val(min_val_), max_val(max_val_),
exponent(exponent_) { }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
{
real_t val = rho_filter->GetValue(T, ip);
real_t coeff = min_val + pow(val,exponent)*(max_val-min_val);
@@ -142,7 +142,7 @@ public:
MFEM_ASSERT(rho_filter, "density field is not set");
}
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
{
real_t L = lambda->Eval(T, ip);
real_t M = mu->Eval(T, ip);
@@ -176,8 +176,8 @@ public:
using VectorCoefficient::Eval;
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
Vector xx; xx.SetSize(T.GetDimension());
T.Transform(ip,xx);
+90 -124
View File
@@ -3,18 +3,18 @@
// Compile with: make ex38
//
// Sample runs:
// (since all sample runs require LAPACK or ALGOIM, the * symbol is used to
// exclude them from the automatically generated internal MFEM tests).
// (since all sample runs require LAPACK, the * symbol is used to exclude them
// from the automatically generated internal MFEM tests).
// * ex38
// * ex38 -i volumetric1d
// * ex38 -i surface2d
// * ex38 -i surface2d -o 4 -r 5 -m 1
// * ex38 -i surface2d -o 4 -r 5
// * ex38 -i volumetric2d
// * ex38 -i volumetric2d -o 4 -r 5 -m 1
// * ex38 -i volumetric2d -o 4 -r 5
// * ex38 -i surface3d
// * ex38 -i surface3d -o 3 -r 4 -m 1
// * ex38 -i surface3d -o 4 -r 5
// * ex38 -i volumetric3d
// * ex38 -i volumetric3d -o 3 -r 4 -m 1
// * ex38 -i volumetric3d -o 4 -r 5
//
// Description: This example code demonstrates the use of MFEM to integrate
// functions over implicit interfaces and subdomains bounded by
@@ -71,7 +71,7 @@ real_t integrand(const Vector& X)
switch (itype)
{
case IntegrationType::Volumetric1D:
return pow(X(0), 2.);
return 1.;
case IntegrationType::Surface2D:
return 3. * pow(X(0), 2.) - pow(X(1), 2.);
case IntegrationType::Volumetric2D:
@@ -91,7 +91,7 @@ real_t Surface()
switch (itype)
{
case IntegrationType::Volumetric1D:
return .3025;
return 1.;
case IntegrationType::Surface2D:
return 2. * M_PI;
case IntegrationType::Volumetric2D:
@@ -111,7 +111,7 @@ real_t Volume()
switch (itype)
{
case IntegrationType::Volumetric1D:
return pow(.55, 3.) / 3.;
return .55;
case IntegrationType::Surface2D:
return NAN;
case IntegrationType::Volumetric2D:
@@ -125,6 +125,7 @@ real_t Volume()
}
}
#ifdef MFEM_USE_LAPACK
/**
@brief Class for surface IntegrationRule
@@ -134,14 +135,11 @@ real_t Volume()
class SIntegrationRule : public IntegrationRule
{
protected:
/// method 0 is moments-based, 1 is Algoim.
int method, ir_order, ls_order;
Coefficient &level_set;
/// Space Dimension of the IntegrationRule
/// @brief Space Dimension of the IntegrationRule
int dim;
/// Column-wise matrix of the quadtrature weights
/// @brief Column-wise matrix of the quadtrature weights
DenseMatrix Weights;
/// Column-wise matrix of the transformation weights of the normal
/// @brief Column-wise matrix of the transformation weights of the normal
DenseMatrix SurfaceWeights;
public:
@@ -155,21 +153,15 @@ public:
@param [in] lsOrder Polynomial degree for approx of level-set function
@param [in] mesh Pointer to the mesh that is used
*/
SIntegrationRule(int method_, int Order,
Coefficient& LvlSet, int lsOrder, Mesh* mesh)
: method(method_), ir_order(Order), ls_order(lsOrder),
level_set(LvlSet), dim(mesh->Dimension())
SIntegrationRule(int Order, Coefficient& LvlSet, int lsOrder, Mesh* mesh)
{
// Nothing gets pre-computed for Algoim.
if (method == 1) { return; }
#ifdef MFEM_USE_LAPACK
MomentFittingIntRules mf_ir(ir_order, level_set, ls_order);
dim = mesh->Dimension();
IsoparametricTransformation Tr;
MomentFittingIntRules MFIRs(Order, LvlSet, lsOrder);
mesh->GetElementTransformation(0, &Tr);
IntegrationRule ir;
mf_ir.GetSurfaceIntegrationRule(Tr, ir);
MFIRs.GetSurfaceIntegrationRule(Tr, ir);
if (dim >1)
{
Weights.SetSize(ir.GetNPoints(), mesh->GetNE());
@@ -180,7 +172,7 @@ public:
}
SurfaceWeights.SetSize(ir.GetNPoints(), mesh->GetNE());
Vector w;
mf_ir.GetSurfaceWeights(Tr, ir, w);
MFIRs.GetSurfaceWeights(Tr, ir, w);
SurfaceWeights.SetCol(0, w);
SetSize(ir.GetNPoints());
@@ -206,8 +198,8 @@ public:
for (int elem = 1; elem < mesh->GetNE(); elem++)
{
mesh->GetElementTransformation(elem, &Tr);
mf_ir.GetSurfaceIntegrationRule(Tr, ir);
mf_ir.GetSurfaceWeights(Tr, ir, w);
MFIRs.GetSurfaceIntegrationRule(Tr, ir);
MFIRs.GetSurfaceWeights(Tr, ir, w);
SurfaceWeights.SetCol(elem, w);
for (int ip = 0; ip < GetNPoints(); ip++)
@@ -223,48 +215,48 @@ public:
}
}
}
#else
MFEM_ABORT("Moment-fitting requires MFEM to be built with LAPACK!");
#endif
}
/**
@brief Set the weights for the given element and multiply them with the
transformation of the interface
*/
void SetElementAndSurfaceWeight(ElementTransformation &Tr)
void SetElementinclSurfaceWeight(int Element)
{
if (method == 1)
{
#ifdef MFEM_USE_ALGOIM
AlgoimIntegrationRules a_ir(ir_order, level_set, ls_order);
a_ir.GetSurfaceIntegrationRule(Tr, *this);
Vector w;
a_ir.GetSurfaceWeights(Tr, *this, w);
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntPoint(ip).weight *= w(ip);
}
return;
#else
MFEM_ABORT("MFEM is not built with Algoim support!");
#endif
}
if (dim == 1)
{
IntPoint(0).x = Weights(0, Tr.ElementNo);
IntPoint(0).weight = Weights(1, Tr.ElementNo);
IntegrationPoint &intp = IntPoint(0);
intp.x = Weights(0, Element);
intp.weight = Weights(1, Element);
cout << intp.x << " " << Element << endl;
}
else
{
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntPoint(ip).weight = Weights(ip, Tr.ElementNo) *
SurfaceWeights(ip, Tr.ElementNo);
IntegrationPoint &intp = IntPoint(ip);
intp.weight = Weights(ip, Element) * SurfaceWeights(ip, Element);
}
}
}
/// @brief Set the weights for the given element
void SetElement(int Element)
{
if (dim == 1)
{
IntegrationPoint &intp = IntPoint(0);
intp.x = Weights(0, Element);
intp.weight = Weights(1, Element);
}
else
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntegrationPoint &intp = IntPoint(ip);
intp.weight = Weights(ip, Element);
}
}
/// @brief Destructor of SIntegrationRule
~SIntegrationRule() {}
};
/**
@@ -276,12 +268,9 @@ public:
class CIntegrationRule : public IntegrationRule
{
protected:
/// method 0 is moments-based, 1 is Algoim.
int method, ir_order, ls_order;
Coefficient &level_set;
/// Space Dimension of the IntegrationRule
/// @brief Space Dimension of the IntegrationRule
int dim;
/// Column-wise matrix of the quadtrature positions and weights.
/// @brief Column-wise matrix of the quadtrature weights
DenseMatrix Weights;
public:
@@ -295,21 +284,15 @@ public:
@param [in] lsOrder Polynomial degree for approx of level-set function
@param [in] mesh Pointer to the mesh that is used
*/
CIntegrationRule(int method_, int Order,
Coefficient &LvlSet, int lsOrder, Mesh *mesh)
: method(method_), ir_order(Order), ls_order(lsOrder),
level_set(LvlSet), dim(mesh->Dimension())
CIntegrationRule(int Order, Coefficient& LvlSet, int lsOrder, Mesh* mesh)
{
// Nothing gets pre-computed for Algoim.
if (method == 1) { return; }
#ifdef MFEM_USE_LAPACK
MomentFittingIntRules mf_ir(ir_order, level_set, ls_order);
dim = mesh->Dimension();
IsoparametricTransformation Tr;
MomentFittingIntRules MFIRs(Order, LvlSet, lsOrder);
mesh->GetElementTransformation(0, &Tr);
IntegrationRule ir;
mf_ir.GetVolumeIntegrationRule(Tr, ir);
MFIRs.GetVolumeIntegrationRule(Tr, ir);
if (dim > 1)
{
Weights.SetSize(ir.GetNPoints(), mesh->GetNE());
@@ -341,9 +324,9 @@ public:
for (int elem = 1; elem < mesh->GetNE(); elem++)
{
mesh->GetElementTransformation(elem, &Tr);
mf_ir.GetVolumeIntegrationRule(Tr, ir);
MFIRs.GetVolumeIntegrationRule(Tr, ir);
for (int ip = 0; ip < ir.GetNPoints(); ip++)
for (int ip = 0; ip < GetNPoints(); ip++)
{
if (dim > 1)
{
@@ -356,39 +339,29 @@ public:
}
}
}
#else
MFEM_ABORT("Moment-fitting requires MFEM to be built with LAPACK!");
#endif
}
/// @brief Set the weights for the given element
void SetElement(ElementTransformation &Tr)
void SetElement(int Element)
{
if (method == 1)
{
#ifdef MFEM_USE_ALGOIM
AlgoimIntegrationRules a_ir(ir_order, level_set, ls_order);
a_ir.GetVolumeIntegrationRule(Tr, *this);
return;
#else
MFEM_ABORT("MFEM is not built with Algoim support!");
#endif
}
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntegrationPoint &intp = IntPoint(ip);
if (dim == 1)
if (dim == 1)
for (int ip = 0; ip < GetNPoints(); ip++)
{
intp.x = Weights(2 * ip, Tr.ElementNo);
intp.weight = Weights(2 * ip + 1, Tr.ElementNo);
IntegrationPoint &intp = IntPoint(ip);
intp.x = Weights(2 * ip, Element);
intp.weight = Weights(2 * ip + 1, Element);
}
else
for (int ip = 0; ip < GetNPoints(); ip++)
{
IntegrationPoint &intp = IntPoint(ip);
intp.weight = Weights(ip, Element);
}
else { intp.weight = Weights(ip, Tr.ElementNo); }
}
}
/// @brief Destructor of CIntegrationRule
~CIntegrationRule() {}
};
/**
@brief Class for surface linearform integrator
@@ -435,9 +408,9 @@ public:
@param [in] Tr transformation of finite element
@param [out] elvect vector containing the
*/
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override
{
int dof = el.GetDof();
shape.SetSize(dof);
@@ -445,7 +418,7 @@ public:
elvect = 0.;
// Update the surface integration rule for the current element
SIntRule->SetElementAndSurfaceWeight(Tr);
SIntRule->SetElementinclSurfaceWeight(Tr.ElementNo);
for (int ip = 0; ip < SIntRule->GetNPoints(); ip++)
{
@@ -455,8 +428,6 @@ public:
add(elvect, SIntRule->IntPoint(ip).weight * val, shape, elvect);
}
}
using LinearFormIntegrator::AssembleRHSElementVect;
};
/**
@@ -505,9 +476,9 @@ public:
@param [in] Tr transformation of finite element
@param [out] elvect vector containing the
*/
void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override
virtual void AssembleRHSElementVect(const FiniteElement &el,
ElementTransformation &Tr,
Vector &elvect) override
{
int dof = el.GetDof();
shape.SetSize(dof);
@@ -515,7 +486,7 @@ public:
elvect = 0.;
// Update the subdomain integration rule
CIntRule->SetElement(Tr);
CIntRule->SetElement(Tr.ElementNo);
for (int ip = 0; ip < CIntRule->GetNPoints(); ip++)
{
@@ -526,17 +497,18 @@ public:
add(elvect, CIntRule->IntPoint(ip).weight * val, shape, elvect);
}
}
using LinearFormIntegrator::AssembleRHSElementVect;
};
#endif // MFEM_USE_LAPACK
int main(int argc, char *argv[])
{
#if defined(MFEM_USE_LAPACK) || defined(MFEM_USE_ALGOIM)
#ifndef MFEM_USE_LAPACK
cout << "MFEM must be built with LAPACK for this example." << endl;
return MFEM_SKIP_RETURN_VALUE;
#else
// 1. Parse he command-line options.
int ref_levels = 3;
int order = 2;
int method = 0;
const char *inttype = "surface2d";
bool visualization = true;
itype = IntegrationType::Surface2D;
@@ -544,8 +516,6 @@ int main(int argc, char *argv[])
OptionsParser args(argc, argv);
args.AddOption(&order, "-o", "--order", "Order of quadrature rule");
args.AddOption(&ref_levels, "-r", "--refine", "Number of meh refinements");
args.AddOption(&method, "-m", "--method",
"Cut integration method: 0 for moments-based, 1 for Algoim.");
args.AddOption(&inttype, "-i", "--integrationtype",
"IntegrationType to demonstrate");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
@@ -580,7 +550,7 @@ int main(int argc, char *argv[])
}
// 2. Construct and refine the mesh.
Mesh *mesh = nullptr;
Mesh *mesh;
if (itype == IntegrationType::Volumetric1D)
{
mesh = new Mesh("../data/inline-segment.mesh");
@@ -628,14 +598,13 @@ int main(int argc, char *argv[])
// 5. Define the necessary Integration rules on element 0.
IsoparametricTransformation Tr;
mesh->GetElementTransformation(0, &Tr);
SIntegrationRule* sir = new SIntegrationRule(method, order,
levelset, 2, mesh);
SIntegrationRule* sir = new SIntegrationRule(order, levelset, 2, mesh);
CIntegrationRule* cir = NULL;
if (itype == IntegrationType::Volumetric1D
|| itype == IntegrationType::Volumetric2D
|| itype == IntegrationType::Volumetric3D)
{
cir = new CIntegrationRule(method, order, levelset, 2, mesh);
cir = new CIntegrationRule(order, levelset, 2, mesh);
}
// 6. Define and assemble the linear forms on the finite element space.
@@ -678,11 +647,11 @@ int main(int argc, char *argv[])
cout << "Number of div free basis functions: " << nbasis << endl;
cout << "Number of quadrature points: " << ir.GetNPoints() << endl;
}
cout << scientific << setprecision(10);
cout << scientific << setprecision(2);
cout << "============================================" << endl;
cout << "Computed value of surface integral: " << surface.Sum() << endl;
cout << "True value of surface integral: " << Surface() << endl;
cout << "Absolute Error (Surface): ";
cout << "Absolute Error (Surface): ";
cout << abs(surface.Sum() - Surface()) << endl;
cout << "Relative Error (Surface): ";
cout << abs(surface.Sum() - Surface()) / Surface() << endl;
@@ -693,7 +662,7 @@ int main(int argc, char *argv[])
cout << "--------------------------------------------" << endl;
cout << "Computed value of volume integral: " << volume.Sum() << endl;
cout << "True value of volume integral: " << Volume() << endl;
cout << "Absolute Error (Volume): ";
cout << "Absolute Error (Volume): ";
cout << abs(volume.Sum() - Volume()) << endl;
cout << "Relative Error (Volume): ";
cout << abs(volume.Sum() - Volume()) / Volume() << endl;
@@ -722,8 +691,5 @@ int main(int argc, char *argv[])
delete fespace;
delete mesh;
return EXIT_SUCCESS;
#else
cout << "MFEM must be built with LAPACK or ALGOIM for this example." << endl;
return MFEM_SKIP_RETURN_VALUE;
#endif // MFEM_USE_LAPACK
#endif //MFEM_USE_LAPACK
}
+4 -6
View File
@@ -67,10 +67,8 @@ public:
ZCoefficient(int vdim, GridFunction &psi_, real_t alpha_ = 1.0)
: VectorCoefficient(vdim), psi(&psi_), alpha(alpha_) { }
using VectorCoefficient::Eval;
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void SetAlpha(real_t alpha_) { alpha = alpha_; }
};
@@ -84,8 +82,8 @@ public:
DZCoefficient(int height, GridFunction &psi_, real_t alpha_ = 1.0)
: MatrixCoefficient(height), psi(&psi_), alpha(alpha_) { }
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void SetAlpha(real_t alpha_) { alpha = alpha_; }
};
+4 -6
View File
@@ -67,10 +67,8 @@ public:
ZCoefficient(int vdim, ParGridFunction &psi_, real_t alpha_ = 1.0)
: VectorCoefficient(vdim), psi(&psi_), alpha(alpha_) { }
using VectorCoefficient::Eval;
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void SetAlpha(real_t alpha_) { alpha = alpha_; }
};
@@ -84,8 +82,8 @@ public:
DZCoefficient(int height, ParGridFunction &psi_, real_t alpha_ = 1.0)
: MatrixCoefficient(height), psi(&psi_), alpha(alpha_) { }
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
void SetAlpha(real_t alpha_) { alpha = alpha_; }
};
+1 -1
View File
@@ -157,7 +157,7 @@ int main(int argc, char *argv[])
MixedBilinearForm *B0 = new MixedBilinearForm(x0_space,test_space);
B0->AddDomainIntegrator(new DiffusionIntegrator(one));
B0->Assemble();
B0->EliminateTrialEssentialBC(ess_bdr, x.GetBlock(x0_var), F);
B0->EliminateTrialDofs(ess_bdr, x.GetBlock(x0_var), F);
B0->Finalize();
MixedBilinearForm *Bhat = new MixedBilinearForm(xhat_space,test_space);
+35 -8
View File
@@ -9,7 +9,7 @@
// ex9 -m ../data/periodic-square.mesh -p 1 -r 2 -dt 0.005 -tf 9
// 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/amr-quad.mesh -p 1 -r 2 -dt 0.02 -s 23 -tf 9
// ex9 -m ../data/amr-quad.mesh -p 1 -r 2 -dt 0.02 -s 13 -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
@@ -104,12 +104,12 @@ public:
}
}
void SetOperator(const Operator &op) override
void SetOperator(const Operator &op)
{
linear_solver.SetOperator(op);
}
void Mult(const Vector &x, Vector &y) const override
virtual void Mult(const Vector &x, Vector &y) const
{
linear_solver.Mult(x, y);
}
@@ -134,10 +134,10 @@ private:
public:
FE_Evolution(BilinearForm &M_, BilinearForm &K_, const Vector &b_);
void Mult(const Vector &x, Vector &y) const override;
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
~FE_Evolution() override;
virtual ~FE_Evolution();
};
@@ -182,7 +182,12 @@ int main(int argc, char *argv[])
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
ODESolver::Types.c_str());
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6,\n\t"
" 11 - Backward Euler,\n\t"
" 12 - SDIRK23 (L-stable), 13 - SDIRK33,\n\t"
" 22 - Implicit Midpoint Method,\n\t"
" 23 - SDIRK23 (A-stable), 24 - SDIRK34");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -219,7 +224,28 @@ int main(int argc, char *argv[])
// 3. Define the ODE solver used for time integration. Several explicit
// Runge-Kutta methods are available.
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
ODESolver *ode_solver = NULL;
switch (ode_solver_type)
{
// Explicit methods
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;
// Implicit (L-stable) methods
case 11: ode_solver = new BackwardEulerSolver; break;
case 12: ode_solver = new SDIRK23Solver(2); break;
case 13: ode_solver = new SDIRK33Solver; 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';
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
@@ -414,6 +440,7 @@ int main(int argc, char *argv[])
}
// 10. Free the used memory.
delete ode_solver;
delete pd;
delete dc;
+42 -12
View File
@@ -9,7 +9,7 @@
// mpirun -np 4 ex9p -m ../data/periodic-square.mesh -p 1 -dt 0.005 -tf 9
// 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/amr-quad.mesh -p 1 -rp 1 -dt 0.02 -s 23 -tf 9
// mpirun -np 4 ex9p -m ../data/amr-quad.mesh -p 1 -rp 1 -dt 0.02 -s 13 -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
@@ -92,7 +92,7 @@ private:
public:
AIR_prec(int blocksize_) : AIR_solver(NULL), blocksize(blocksize_) { }
void SetOperator(const Operator &op) override
void SetOperator(const Operator &op)
{
width = op.Width();
height = op.Height();
@@ -110,7 +110,7 @@ public:
AIR_solver->SetMaxLevels(50);
}
void Mult(const Vector &x, Vector &y) const override
virtual void Mult(const Vector &x, Vector &y) const
{
// Scale the rhs by block inverse and solve system
HypreParVector z_s;
@@ -119,7 +119,7 @@ public:
AIR_solver->Mult(z_s, y);
}
~AIR_prec() override
~AIR_prec()
{
delete AIR_solver;
}
@@ -185,17 +185,17 @@ public:
}
}
void SetOperator(const Operator &op) override
void SetOperator(const Operator &op)
{
linear_solver.SetOperator(op);
}
void Mult(const Vector &x, Vector &y) const override
virtual void Mult(const Vector &x, Vector &y) const
{
linear_solver.Mult(x, y);
}
~DG_Solver() override
~DG_Solver()
{
delete prec;
delete A;
@@ -223,10 +223,10 @@ public:
FE_Evolution(ParBilinearForm &M_, ParBilinearForm &K_, const Vector &b_,
PrecType prec_type);
void Mult(const Vector &x, Vector &y) const override;
void ImplicitSolve(const real_t dt, const Vector &x, Vector &k) override;
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
~FE_Evolution() override;
virtual ~FE_Evolution();
};
@@ -285,7 +285,12 @@ int main(int argc, char *argv[])
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
ODESolver::Types.c_str());
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6,\n\t"
" 11 - Backward Euler,\n\t"
" 12 - SDIRK23 (L-stable), 13 - SDIRK33,\n\t"
" 22 - Implicit Midpoint Method,\n\t"
" 23 - SDIRK23 (A-stable), 24 - SDIRK34");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -333,7 +338,31 @@ int main(int argc, char *argv[])
// 4. Define the ODE solver used for time integration. Several explicit
// Runge-Kutta methods are available.
unique_ptr<ODESolver> ode_solver = ODESolver::Select(ode_solver_type);
ODESolver *ode_solver = NULL;
switch (ode_solver_type)
{
// Explicit methods
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;
// Implicit (L-stable) methods
case 11: ode_solver = new BackwardEulerSolver; break;
case 12: ode_solver = new SDIRK23Solver(2); break;
case 13: ode_solver = new SDIRK33Solver; 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:
if (Mpi::Root())
{
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
}
delete mesh;
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
@@ -613,6 +642,7 @@ int main(int argc, char *argv[])
delete m;
delete fes;
delete pmesh;
delete ode_solver;
delete pd;
#ifdef MFEM_USE_ADIOS2
if (adios2)
+4 -3
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
MFEM_INSTALL_DIR ?= ../../mfem
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/ginkgo/,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
-1
View File
@@ -96,7 +96,6 @@ public:
{
Vector w_glob(width);
pfes.Dof_TrueDof_Matrix()->MultTranspose(w, w_glob);
w_glob.HostReadWrite(); // read+write -> can use w_glob(i) (non-const)
for (int i = 0; i < width; i++) { grad(0, i) = w_glob(i); }
}
+4 -3
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
MFEM_INSTALL_DIR ?= ../../mfem
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/hiop/,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
+4 -3
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ..
MFEM_BUILD_DIR ?= ..
MFEM_INSTALL_DIR ?= ../mfem
SRC = $(if $(MFEM_DIR:..=),$(MFEM_DIR)/examples/,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
+4 -3
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
MFEM_INSTALL_DIR ?= ../../mfem
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/moonolith/,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
+1 -9
View File
@@ -206,7 +206,6 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool petsc_use_jfnk = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -244,8 +243,6 @@ int main(int argc, char *argv[])
args.AddOption(&petsc_use_jfnk, "-jfnk", "--jfnk", "-no-jfnk",
"--no-jfnk",
"Use JFNK with user-defined preconditioner factory.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -260,12 +257,7 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
// 2b. We initialize PETSc
if (use_petsc)
{
MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL);
+1 -9
View File
@@ -67,7 +67,6 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool use_nonoverlapping = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -96,8 +95,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(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -112,12 +109,7 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
// 3. Read the (serial) mesh from the given mesh file on all processors. We
+2 -11
View File
@@ -61,7 +61,6 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool use_nonoverlapping = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -88,8 +87,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(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -103,15 +100,9 @@ int main(int argc, char *argv[])
{
args.PrintOptions(cout);
}
kappa = freq * M_PI;
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
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
+2 -11
View File
@@ -58,7 +58,6 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool use_nonoverlapping = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -89,8 +88,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(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -104,15 +101,9 @@ int main(int argc, char *argv[])
{
args.PrintOptions(cout);
}
kappa = freq * M_PI;
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
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
+7 -28
View File
@@ -59,8 +59,6 @@ int main(int argc, char *argv[])
// 2. Parse command-line options.
const char *mesh_file = "../../data/star.mesh";
int ser_ref_levels = -1;
int par_ref_levels = 2;
int order = 1;
bool par_format = false;
bool visualization = 1;
@@ -68,22 +66,15 @@ int main(int argc, char *argv[])
bool use_nonoverlapping = false;
bool local_bdr_spec = false;
const char *petscrc_file = "";
const char *device_config = "cpu";
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(&par_format, "-pf", "--parallel-format", "-sf",
"--serial-format",
"Format to use when saving the results for VisIt.");
args.AddOption(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
@@ -112,13 +103,7 @@ int main(int argc, char *argv[])
{
args.PrintOptions(cout);
}
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
// 3. Read the (serial) mesh from the given mesh file on all processors. We
@@ -132,11 +117,9 @@ int main(int argc, char *argv[])
// 'ref_levels' to be the largest number that gives a final mesh with no
// more than 10,000 elements.
{
if (ser_ref_levels < 0)
{
ser_ref_levels = (int)floor(log(10000./mesh->GetNE())/log(2.)/dim);
}
for (int l = 0; l < ser_ref_levels; l++)
int ref_levels =
(int)floor(log(10000./mesh->GetNE())/log(2.)/dim);
for (int l = 0; l < ref_levels; l++)
{
mesh->UniformRefinement();
}
@@ -148,6 +131,7 @@ int main(int argc, char *argv[])
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();
@@ -203,26 +187,21 @@ int main(int argc, char *argv[])
// 9. Define the parallel grid function and parallel linear forms, solution
// vector and rhs.
MemoryType mt = device.GetMemoryType();
BlockVector x(block_offsets, mt), rhs(block_offsets, mt);
BlockVector trueX(block_trueOffsets, mt), trueRhs(block_trueOffsets, mt);
BlockVector x(block_offsets), rhs(block_offsets);
BlockVector trueX(block_trueOffsets), trueRhs(block_trueOffsets);
ParLinearForm *fform(new ParLinearForm);
fform->Update(R_space, rhs.GetBlock(0), 0);
fform->AddDomainIntegrator(new VectorFEDomainLFIntegrator(fcoeff));
fform->AddBoundaryIntegrator(new VectorFEBoundaryFluxLFIntegrator(fnatcoeff));
fform->Assemble();
fform->SyncAliasMemory(rhs);
fform->ParallelAssemble(trueRhs.GetBlock(0));
trueRhs.GetBlock(0).SyncAliasMemory(trueRhs);
ParLinearForm *gform(new ParLinearForm);
gform->Update(W_space, rhs.GetBlock(1), 0);
gform->AddDomainIntegrator(new DomainLFIntegrator(gcoeff));
gform->Assemble();
gform->SyncAliasMemory(rhs);
gform->ParallelAssemble(trueRhs.GetBlock(1));
trueRhs.GetBlock(1).SyncAliasMemory(trueRhs);
// 10. Assemble the finite element matrices for the Darcy operator
//
+1 -10
View File
@@ -53,7 +53,6 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool use_nonoverlapping = false;
const char *device_config = "cpu";
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -74,8 +73,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(&device_config, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.Parse();
if (!args.Good())
{
@@ -89,13 +86,7 @@ int main(int argc, char *argv[])
{
args.PrintOptions(cout);
}
// 2b. Enable hardware devices such as GPUs, and programming models such as
// CUDA, OCCA, RAJA and OpenMP based on command line options.
Device device(device_config);
if (myid == 0) { device.Print(); }
// 2c. We initialize PETSc
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
// 3. Read the (serial) mesh from the given mesh file on all processors. We
+4 -3
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
MFEM_INSTALL_DIR ?= ../../mfem
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/petsc/,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
+1
View File
@@ -66,6 +66,7 @@ int main(int argc, char *argv[])
{
// 1. Initialize MPI (required by PUMI) and HYPRE.
Mpi::Init(argc, argv);
int num_procs = Mpi::WorldSize();
int myid = Mpi::WorldRank();
Hypre::Init();
+2
View File
@@ -80,6 +80,8 @@ int main(int argc, char *argv[])
{
// 1. Initialize MPI (required by PUMI) and HYPRE.
Mpi::Init(argc, argv);
int num_proc = Mpi::WorldSize();
int myId = Mpi::WorldRank();
Hypre::Init();
// 2. Parse command-line options.
+4 -3
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
MFEM_INSTALL_DIR ?= ../../mfem
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/pumi/,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
+3 -16
View File
@@ -31,21 +31,11 @@ include_directories(BEFORE ${PROJECT_BINARY_DIR})
add_custom_target(test_sundials
${CMAKE_CTEST_COMMAND} -R sundials USES_TERMINAL)
# Add one executable per cpp file, adding "sundials_" as prefix so the CMake
# target is unique from those in the non-SUNDIALS examples. Also sets
# "test_sundials" as a target that depends on the given SUNDIALS examples.
# Add one executable per cpp file, adding "sundials_" as prefix. Sets
# "test_sundials" as a target that depends on the given examples.
set(PFX sundials_)
add_mfem_examples(SUNDIALS_EXAMPLES_SRCS ${PFX} "" test_sundials)
# Remove "sundials_" prefix from exectuable name for consistency with GNU build
# system.
foreach(SRC_FILE ${SUNDIALS_EXAMPLES_SRCS})
get_filename_component(SRC_FILENAME ${SRC_FILE} NAME)
string(REPLACE ".cpp" "" TARGET_NAME "${PFX}${SRC_FILENAME}")
string(REPLACE ${PFX} "" EXE_NAME ${TARGET_NAME})
set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME ${EXE_NAME})
endforeach()
# Testing.
# The SUNDIALS tests can be run separately using the target "test_sundials"
# which builds the examples and runs:
@@ -61,10 +51,7 @@ if (MFEM_ENABLE_TESTING)
set(EX10_COMMON_OPTS -m ../../data/beam-quad.mesh -o 2 -s 5 -dt 0.15 -tf 6 -vs 10)
set(EX10_TEST_OPTS ${EX10_COMMON_OPTS} -r 2)
set(EX10P_TEST_OPTS ${EX10_COMMON_OPTS} -rp 1)
# Example 16: test ARKODE with implicit time stepping using mass form
set(EX16_COMMON_OPTS -s 15)
set(EX16_TEST_OPTS ${EX16_COMMON_OPTS})
set(EX16P_TEST_OPTS ${EX16_COMMON_OPTS})
# Example 16: use the default options
# Add the tests: one test per source file.
foreach(SRC_FILE ${SUNDIALS_EXAMPLES_SRCS})
+50 -112
View File
@@ -1,17 +1,15 @@
// MFEM Example 10
// SUNDIALS Modification
//
// Compile with:
// make ex10 (GNU make)
// make sundials_ex10 (CMake)
// Compile with: make ex10
//
// Sample runs:
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 12 -dt 0.15 -vs 10
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 16 -dt 0.3 -vs 5
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 12 -dt 0.2 -vs 5
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 2 -dt 3 -nls 1
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 2 -dt 3 -nls 2
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 2 -dt 3 -nls 4
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 2 -dt 3 -nls kinsol
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 2 -dt 3 -nls kinsol
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 2 -dt 3 -nls kinsol
// ex10 -m ../../data/beam-quad.mesh -r 2 -o 2 -s 14 -dt 0.15 -vs 10
// ex10 -m ../../data/beam-tri.mesh -r 2 -o 2 -s 17 -dt 0.01 -vs 30
// ex10 -m ../../data/beam-hex.mesh -r 1 -o 2 -s 14 -dt 0.15 -vs 10
@@ -99,11 +97,16 @@ protected:
double saved_gamma; // saved gamma value from implicit setup
public:
/// Solver type to use in the ImplicitSolve() method, used by SDIRK methods.
enum NonlinearSolverType
{
NEWTON = 0, ///< Use MFEM's plain NewtonSolver
KINSOL = 1 ///< Use SUNDIALS' KINSOL (through MFEM's class KINSolver)
};
HyperelasticOperator(FiniteElementSpace &f, Array<int> &ess_bdr,
double visc, double mu, double K,
int kinsol_nls_type = -1, double kinsol_damping = 0.0,
int kinsol_aa_n = 0);
NonlinearSolverType nls_type);
/// Compute the right-hand side of the ODE system.
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
@@ -221,10 +224,8 @@ int main(int argc, char *argv[])
double mu = 0.25;
double K = 5.0;
bool visualization = true;
int nonlinear_solver_type = 0;
const char *nls = "newton";
int vis_steps = 1;
double kinsol_damping = 0.0;
int kinsol_aa_n = -1;
// Relative and absolute tolerances for CVODE and ARKODE.
const double reltol = 1e-1, abstol = 1e-1;
@@ -261,18 +262,9 @@ int main(int argc, char *argv[])
"15 - ARKODE implicit, approximate Jacobian,\n\t"
"16 - ARKODE implicit, specified Jacobian,\n\t"
"17 - ARKODE explicit, 4th order.");
args.AddOption(&nonlinear_solver_type, "-nls", "--nonlinear-solver",
"Nonlinear system solver:\n\t"
"0 - MFEM Newton method,\n\t"
"1 - KINSOL Newton method,\n\t"
"2 - KINSOL Newton method with globalization,\n\t"
"3 - KINSOL fixed-point method (with or without AA),\n\t"
"4 - KINSOL Picard method (with or without AA).");
args.AddOption(&kinsol_damping, "-damp", "--kinsol-damping",
"Picard or Fixed-Point damping parameter (only valid with KINSOL): "
"0 < d <= 1.0");
args.AddOption(&kinsol_aa_n, "-aan", "--anderson-subspace",
"Anderson Acceleration subspace size (only valid with KINSOL)");
args.AddOption(&nls, "-nls", "--nonlinear-solver",
"Nonlinear systems solver: "
"\"newton\" (plain Newton) or \"kinsol\" (KINSOL).");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -303,32 +295,22 @@ int main(int argc, char *argv[])
return 1;
}
// check for valid nonlinear solver options
if (nonlinear_solver_type < 0 || nonlinear_solver_type > 4)
{
cout << "Unknown nonlinear solver type: " << nonlinear_solver_type << "\n";
return 1;
}
if (kinsol_damping > 0.0 &&
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
{
cout << "Only KINSOL fixed-point and Picard methods can use damping\n";
return 1;
}
if (kinsol_aa_n > 0 &&
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
{
cout << "Only KINSOL fixed-point and Picard methods can use AA\n";
return 1;
}
// 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
// 3. Setup the nonlinear solver
map<string,HyperelasticOperator::NonlinearSolverType> nls_map;
nls_map["newton"] = HyperelasticOperator::NEWTON;
nls_map["kinsol"] = HyperelasticOperator::KINSOL;
if (nls_map.find(nls) == nls_map.end())
{
cout << "Unknown type of nonlinear solver: " << nls << endl;
return 4;
}
// 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++)
@@ -336,7 +318,7 @@ int main(int argc, char *argv[])
mesh->UniformRefinement();
}
// 4. Define the vector finite element spaces representing the mesh
// 5. Define the vector finite element spaces representing the mesh
// deformation x, the velocity v, and the initial configuration, x_ref.
// Define also the elastic energy density, w, which is in a discontinuous
// higher-order space. Since x and v are integrated in time as a system,
@@ -364,7 +346,7 @@ int main(int argc, char *argv[])
FiniteElementSpace w_fespace(mesh, &w_fec);
GridFunction w(&w_fespace);
// 5. Set the initial conditions for v and x, and the boundary conditions on
// 6. Set the initial conditions for v and x, and the boundary conditions on
// a beam-like mesh (see description above).
VectorFunctionCoefficient velo(dim, InitialVelocity);
v.ProjectCoefficient(velo);
@@ -377,34 +359,9 @@ int main(int argc, char *argv[])
ess_bdr = 0;
ess_bdr[0] = 1; // boundary attribute 1 (index 0) is fixed
// 6. Initialize the hyperelastic operator, the GLVis visualization and print
// 7. Initialize the hyperelastic operator, the GLVis visualization and print
// the initial energies.
std::unique_ptr<HyperelasticOperator> oper;
if (nonlinear_solver_type == 0)
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr, visc, mu,
K);
else
{
switch (nonlinear_solver_type)
{
case 1:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_NONE);
break;
case 2:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_LINESEARCH);
break;
case 3:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_FP, kinsol_damping, kinsol_aa_n);
break;
case 4:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_PICARD, kinsol_damping, kinsol_aa_n);
break;
}
}
HyperelasticOperator oper(fespace, ess_bdr, visc, mu, K, nls_map[nls]);
socketstream vis_v, vis_w;
if (visualization)
@@ -418,23 +375,23 @@ int main(int argc, char *argv[])
vis_w.open(vishost, visport);
if (vis_w)
{
oper->GetElasticEnergyDensity(x, w);
oper.GetElasticEnergyDensity(x, w);
vis_w.precision(8);
visualize(vis_w, mesh, &x, &w, "Elastic energy density", true);
}
}
double ee0 = oper->ElasticEnergy(x.GetTrueVector());
double ke0 = oper->KineticEnergy(v.GetTrueVector());
double ee0 = oper.ElasticEnergy(x.GetTrueVector());
double ke0 = oper.KineticEnergy(v.GetTrueVector());
cout << "initial elastic energy (EE) = " << ee0 << endl;
cout << "initial kinetic energy (KE) = " << ke0 << endl;
cout << "initial total energy (TE) = " << (ee0 + ke0) << endl;
// 7. Define the ODE solver used for time integration. Several implicit
// 8. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
double t = 0.0;
oper->SetTime(t);
oper.SetTime(t);
ODESolver *ode_solver = NULL;
CVODESolver *cvode = NULL;
@@ -458,7 +415,7 @@ int main(int argc, char *argv[])
case 11:
case 12:
cvode = new CVODESolver(CV_BDF);
cvode->Init(*oper);
cvode->Init(oper);
cvode->SetSStolerances(reltol, abstol);
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
cvode->SetMaxStep(dt);
@@ -471,7 +428,7 @@ int main(int argc, char *argv[])
case 13:
case 14:
cvode = new CVODESolver(CV_ADAMS);
cvode->Init(*oper);
cvode->Init(oper);
cvode->SetSStolerances(reltol, abstol);
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
cvode->SetMaxStep(dt);
@@ -484,13 +441,9 @@ int main(int argc, char *argv[])
case 15:
case 16:
arkode = new ARKStepSolver(ARKStepSolver::IMPLICIT);
arkode->Init(*oper);
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
#if MFEM_SUNDIALS_VERSION < 70100
ARKStepSetNonlinConvCoef(arkode->GetMem(), arkode_eps_nonlin);
#else
ARKodeSetNonlinConvCoef(arkode->GetMem(), arkode_eps_nonlin);
#endif
arkode->SetMaxStep(dt);
if (ode_solver_type == 15)
{
@@ -500,16 +453,16 @@ int main(int argc, char *argv[])
// ARKStep Explicit methods
case 17:
arkode = new ARKStepSolver(ARKStepSolver::EXPLICIT);
arkode->Init(*oper);
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
ode_solver = arkode; break;
}
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
if (ode_solver_type < 11) { ode_solver->Init(*oper); }
if (ode_solver_type < 11) { ode_solver->Init(oper); }
// 8. Perform time-integration (looping over the time iterations, ti, with a
// 9. Perform time-integration (looping over the time iterations, ti, with a
// time-step dt).
bool last_step = false;
for (int ti = 1; !last_step; ti++)
@@ -522,8 +475,8 @@ 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.GetTrueVector());
double ke = oper.KineticEnergy(v.GetTrueVector());
cout << "step " << ti << ", t = " << t << ", EE = " << ee << ", KE = "
<< ke << ", ΔTE = " << (ee+ke)-(ee0+ke0) << endl;
@@ -537,14 +490,14 @@ int main(int argc, char *argv[])
visualize(vis_v, mesh, &x, &v);
if (vis_w)
{
oper->GetElasticEnergyDensity(x, w);
oper.GetElasticEnergyDensity(x, w);
visualize(vis_w, mesh, &x, &w);
}
}
}
}
// 9. Save the displaced mesh, the velocity and elastic energy.
// 10. Save the displaced mesh, the velocity and elastic energy.
{
v.SetFromTrueVector(); x.SetFromTrueVector();
GridFunction *nodes = &x;
@@ -559,11 +512,11 @@ int main(int argc, char *argv[])
v.Save(velo_ofs);
ofstream ee_ofs("elastic_energy.sol");
ee_ofs.precision(8);
oper->GetElasticEnergyDensity(x, w);
oper.GetElasticEnergyDensity(x, w);
w.Save(ee_ofs);
}
// 10. Free the used memory.
// 11. Free the used memory.
delete ode_solver;
delete mesh;
@@ -647,9 +600,7 @@ ReducedSystemOperator::~ReducedSystemOperator()
HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
Array<int> &ess_bdr, double visc,
double mu, double K,
int kinsol_nls_type,
double kinsol_damping,
int kinsol_aa_n)
NonlinearSolverType nls_type)
: TimeDependentOperator(2*f.GetTrueVSize(), 0.0), fespace(f),
M(&fespace), S(&fespace), H(&fespace),
viscosity(visc), z(height/2),
@@ -700,28 +651,15 @@ HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
J_prec = NULL;
#endif
if (kinsol_nls_type > 0)
if (nls_type == KINSOL)
{
KINSolver *kinsolver = new KINSolver(kinsol_nls_type, true);
if (kinsol_nls_type != KIN_PICARD)
{
kinsolver->SetJFNK(true);
kinsolver->SetLSMaxIter(100);
}
if (kinsol_aa_n > 0)
{
kinsolver->EnableAndersonAcc(kinsol_aa_n);
}
KINSolver *kinsolver = new KINSolver(KIN_NONE, true);
newton_solver = kinsolver;
newton_solver->SetOperator(*reduced_oper);
newton_solver->SetMaxIter(200);
newton_solver->SetRelTol(rel_tol);
newton_solver->SetPrintLevel(0);
kinsolver->SetMaxSetupCalls(4);
if (kinsol_damping > 0.0)
{
kinsolver->SetDamping(kinsol_damping);
}
}
else
{
+60 -130
View File
@@ -1,17 +1,15 @@
// MFEM Example 10 - Parallel Version
// SUNDIALS Modification
//
// Compile with:
// make ex10p (GNU make)
// make sundials_ex10p (CMake)
// Compile with: make ex10p
//
// Sample runs:
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 12 -dt 0.15 -vs 10
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 16 -dt 0.25 -vs 10
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rp 0 -o 2 -s 12 -dt 0.15 -vs 10
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 2 -dt 3 -nls 1
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 2 -dt 3 -nls 2
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rs 1 -o 2 -s 2 -dt 3 -nls 4
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 2 -dt 3 -nls kinsol
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 2 -dt 3 -nls kinsol
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rs 1 -o 2 -s 2 -dt 3 -nls kinsol
// mpirun -np 4 ex10p -m ../../data/beam-quad.mesh -rp 1 -o 2 -s 14 -dt 0.15 -vs 10
// mpirun -np 4 ex10p -m ../../data/beam-tri.mesh -rp 1 -o 2 -s 17 -dt 5e-3 -vs 60
// mpirun -np 4 ex10p -m ../../data/beam-hex.mesh -rp 0 -o 2 -s 14 -dt 0.15 -vs 10
@@ -101,11 +99,16 @@ protected:
double saved_gamma; // saved gamma value from implicit setup
public:
/// Solver type to use in the ImplicitSolve() method, used by SDIRK methods.
enum NonlinearSolverType
{
NEWTON = 0, ///< Use MFEM's plain NewtonSolver
KINSOL = 1 ///< Use SUNDIALS' KINSOL (through MFEM's class KINSolver)
};
HyperelasticOperator(ParFiniteElementSpace &f, Array<int> &ess_bdr,
double visc, double mu, double K,
int kinsol_nls_type = -1, double kinsol_damping = 0.0,
int kinsol_aa_n = 0);
NonlinearSolverType nls_type);
/// Compute the right-hand side of the ODE system.
virtual void Mult(const Vector &vx, Vector &dvx_dt) const;
@@ -230,10 +233,8 @@ int main(int argc, char *argv[])
double mu = 0.25;
double K = 5.0;
bool visualization = true;
int nonlinear_solver_type = 0;
const char *nls = "newton";
int vis_steps = 1;
double kinsol_damping = 0.0;
int kinsol_aa_n = -1;
// Relative and absolute tolerances for CVODE and ARKODE.
const double reltol = 1e-1, abstol = 1e-1;
@@ -272,18 +273,9 @@ int main(int argc, char *argv[])
"15 - ARKODE implicit, approximate Jacobian,\n\t"
"16 - ARKODE implicit, specified Jacobian,\n\t"
"17 - ARKODE explicit, 4th order.");
args.AddOption(&nonlinear_solver_type, "-nls", "--nonlinear-solver",
"Nonlinear system solver:\n\t"
"0 - MFEM Newton method,\n\t"
"1 - KINSOL Newton method,\n\t"
"2 - KINSOL Newton method with globalization,\n\t"
"3 - KINSOL fixed-point method (with or without AA),\n\t"
"4 - KINSOL Picard method (with or without AA).");
args.AddOption(&kinsol_damping, "-damp", "--kinsol-damping",
"Picard or Fixed-Point damping parameter (only valid with KINSOL): "
"0 < d <= 1.0");
args.AddOption(&kinsol_aa_n, "-aan", "--anderson-subspace",
"Anderson Acceleration subspace size (only valid with KINSOL)");
args.AddOption(&nls, "-nls", "--nonlinear-solver",
"Nonlinear systems solver: "
"\"newton\" (plain Newton) or \"kinsol\" (KINSOL).");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -323,42 +315,27 @@ int main(int argc, char *argv[])
return 1;
}
// check for valid nonlinear solver options
if (nonlinear_solver_type < 0 || nonlinear_solver_type > 4)
{
if (myid == 0)
{
cout << "Unknown nonlinear solver type: " << nonlinear_solver_type
<< "\n";
}
return 1;
}
if (kinsol_damping > 0.0 &&
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
{
if (myid == 0)
{
cout << "Only KINSOL fixed-point and Picard methods can use damping\n";
}
return 1;
}
if (kinsol_aa_n > 0 &&
!(nonlinear_solver_type == 3 || nonlinear_solver_type == 4))
{
if (myid == 0)
{
cout << "Only KINSOL fixed-point and Picard methods can use AA\n";
}
return 1;
}
// 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
// 4. Nonlinear solver
map<string,HyperelasticOperator::NonlinearSolverType> nls_map;
nls_map["newton"] = HyperelasticOperator::NEWTON;
nls_map["kinsol"] = HyperelasticOperator::KINSOL;
if (nls_map.find(nls) == nls_map.end())
{
if (myid == 0)
{
cout << "Unknown type of nonlinear solver: " << nls << endl;
}
delete mesh;
return 4;
}
// 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++)
@@ -366,7 +343,7 @@ int main(int argc, char *argv[])
mesh->UniformRefinement();
}
// 5. Define a parallel mesh by a partitioning of the serial mesh. Refine
// 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 = new ParMesh(MPI_COMM_WORLD, *mesh);
@@ -376,7 +353,7 @@ int main(int argc, char *argv[])
pmesh->UniformRefinement();
}
// 6. Define the parallel vector finite element spaces representing the mesh
// 7. Define the parallel vector finite element spaces representing the mesh
// deformation x_gf, the velocity v_gf, and the initial configuration,
// x_ref. Define also the elastic energy density, w_gf, which is in a
// discontinuous higher-order space. Since x and v are integrated in time
@@ -408,7 +385,7 @@ int main(int argc, char *argv[])
ParFiniteElementSpace w_fespace(pmesh, &w_fec);
ParGridFunction w_gf(&w_fespace);
// 7. Set the initial conditions for v_gf, x_gf and vx, and define the
// 8. Set the initial conditions for v_gf, x_gf and vx, and define the
// boundary conditions on a beam-like mesh (see description above).
VectorFunctionCoefficient velo(dim, InitialVelocity);
v_gf.ProjectCoefficient(velo);
@@ -423,38 +400,9 @@ int main(int argc, char *argv[])
ess_bdr = 0;
ess_bdr[0] = 1; // boundary attribute 1 (index 0) is fixed
// 8. Initialize the hyperelastic operator, the GLVis visualization and print
// 9. Initialize the hyperelastic operator, the GLVis visualization and print
// the initial energies.
std::unique_ptr<HyperelasticOperator> oper;
if (nonlinear_solver_type == 0)
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr, visc, mu,
K);
else
{
switch (nonlinear_solver_type)
{
case 1:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_NONE);
break;
case 2:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_LINESEARCH);
break;
case 3:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_FP, kinsol_damping, kinsol_aa_n);
break;
case 4:
oper = std::make_unique<HyperelasticOperator>(fespace, ess_bdr,
visc, mu, K, KIN_PICARD, kinsol_damping, kinsol_aa_n);
break;
default:
cout << "Unknown type of nonlinear solver: "
<< nonlinear_solver_type << endl;
return 4;
}
}
HyperelasticOperator oper(fespace, ess_bdr, visc, mu, K, nls_map[nls]);
socketstream vis_v, vis_w;
if (visualization)
@@ -470,14 +418,14 @@ int main(int argc, char *argv[])
vis_w.open(vishost, visport);
if (vis_w)
{
oper->GetElasticEnergyDensity(x_gf, w_gf);
oper.GetElasticEnergyDensity(x_gf, w_gf);
vis_w.precision(8);
visualize(vis_w, pmesh, &x_gf, &w_gf, "Elastic energy density", true);
}
}
double ee0 = oper->ElasticEnergy(x_gf);
double ke0 = oper->KineticEnergy(v_gf);
double ee0 = oper.ElasticEnergy(x_gf);
double ke0 = oper.KineticEnergy(v_gf);
if (myid == 0)
{
cout << "initial elastic energy (EE) = " << ee0 << endl;
@@ -485,11 +433,11 @@ int main(int argc, char *argv[])
cout << "initial total energy (TE) = " << (ee0 + ke0) << endl;
}
// 9. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
// 10. Define the ODE solver used for time integration. Several implicit
// singly diagonal implicit Runge-Kutta (SDIRK) methods, as well as
// explicit Runge-Kutta methods are available.
double t = 0.0;
oper->SetTime(t);
oper.SetTime(t);
ODESolver *ode_solver = NULL;
CVODESolver *cvode = NULL;
@@ -513,7 +461,7 @@ int main(int argc, char *argv[])
case 11:
case 12:
cvode = new CVODESolver(MPI_COMM_WORLD, CV_BDF);
cvode->Init(*oper);
cvode->Init(oper);
cvode->SetSStolerances(reltol, abstol);
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
cvode->SetMaxStep(dt);
@@ -526,7 +474,7 @@ int main(int argc, char *argv[])
case 13:
case 14:
cvode = new CVODESolver(MPI_COMM_WORLD, CV_ADAMS);
cvode->Init(*oper);
cvode->Init(oper);
cvode->SetSStolerances(reltol, abstol);
CVodeSetEpsLin(cvode->GetMem(), cvode_eps_lin);
cvode->SetMaxStep(dt);
@@ -539,13 +487,9 @@ int main(int argc, char *argv[])
case 15:
case 16:
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::IMPLICIT);
arkode->Init(*oper);
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
#if MFEM_SUNDIALS_VERSION < 70100
ARKStepSetNonlinConvCoef(arkode->GetMem(), arkode_eps_nonlin);
#else
ARKodeSetNonlinConvCoef(arkode->GetMem(), arkode_eps_nonlin);
#endif
arkode->SetMaxStep(dt);
if (ode_solver_type == 15)
{
@@ -555,16 +499,16 @@ int main(int argc, char *argv[])
// ARKStep Explicit methods
case 17:
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::EXPLICIT);
arkode->Init(*oper);
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
ode_solver = arkode; break;
}
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
if (ode_solver_type < 11) { ode_solver->Init(*oper); }
if (ode_solver_type < 11) { ode_solver->Init(oper); }
// 10. Perform time-integration
// 11. Perform time-integration
// (looping over the time iterations, ti, with a time-step dt).
bool last_step = false;
for (int ti = 1; !last_step; ti++)
@@ -579,8 +523,8 @@ int main(int argc, char *argv[])
{
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
double ee = oper->ElasticEnergy(x_gf);
double ke = oper->KineticEnergy(v_gf);
double ee = oper.ElasticEnergy(x_gf);
double ke = oper.KineticEnergy(v_gf);
if (myid == 0)
{
@@ -596,14 +540,14 @@ int main(int argc, char *argv[])
visualize(vis_v, pmesh, &x_gf, &v_gf);
if (vis_w)
{
oper->GetElasticEnergyDensity(x_gf, w_gf);
oper.GetElasticEnergyDensity(x_gf, w_gf);
visualize(vis_w, pmesh, &x_gf, &w_gf);
}
}
}
}
// 11. Save the displaced mesh, the velocity and elastic energy.
// 12. Save the displaced mesh, the velocity and elastic energy.
{
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
GridFunction *nodes = &x_gf;
@@ -624,11 +568,11 @@ int main(int argc, char *argv[])
v_gf.Save(velo_ofs);
ofstream ee_ofs(ee_name.str().c_str());
ee_ofs.precision(8);
oper->GetElasticEnergyDensity(x_gf, w_gf);
oper.GetElasticEnergyDensity(x_gf, w_gf);
w_gf.Save(ee_ofs);
}
// 12. Free the used memory.
// 13. Free the used memory.
delete ode_solver;
delete pmesh;
@@ -718,10 +662,7 @@ ReducedSystemOperator::~ReducedSystemOperator()
HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
Array<int> &ess_bdr, double visc,
double mu, double K,
int kinsol_nls_type,
double kinsol_damping,
int kinsol_aa_n)
NonlinearSolverType nls_type)
: TimeDependentOperator(2*f.TrueVSize(), 0.0), fespace(f),
M(&fespace), S(&fespace), H(&fespace),
viscosity(visc), M_solver(f.GetComm()), z(height/2),
@@ -773,28 +714,17 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
J_minres->SetPreconditioner(*J_prec);
J_solver = J_minres;
if (kinsol_nls_type > 0)
if (nls_type == KINSOL)
{
KINSolver *kinsolver = new KINSolver(f.GetComm(), kinsol_nls_type, true);
if (kinsol_nls_type != KIN_PICARD)
{
kinsolver->SetJFNK(true);
kinsolver->SetLSMaxIter(100);
}
if (kinsol_aa_n > 0)
{
kinsolver->EnableAndersonAcc(kinsol_aa_n);
}
KINSolver *kinsolver = new KINSolver(f.GetComm(), KIN_LINESEARCH, true);
kinsolver->SetJFNK(true);
kinsolver->SetLSMaxIter(100);
newton_solver = kinsolver;
newton_solver->SetOperator(*reduced_oper);
newton_solver->SetMaxIter(200);
newton_solver->SetRelTol(rel_tol);
newton_solver->SetPrintLevel(0);
newton_solver->SetPrintLevel(1);
kinsolver->SetMaxSetupCalls(4);
if (kinsol_damping > 0.0)
{
kinsolver->SetDamping(kinsol_damping);
}
}
else
{
+164 -257
View File
@@ -1,21 +1,15 @@
// MFEM Example 16
// SUNDIALS Modification
//
// Compile with:
// make ex16 (GNU make)
// make sundials_ex16 (CMake)
// Compile with: make ex16
//
// Sample runs: ex16
// ex16 -m ../../data/inline-tri.mesh
// ex16 -m ../../data/disc-nurbs.mesh -tf 2
// ex16 -s 12 -a 0.0 -k 1.0
// ex16 -s 15 -a 0.0 -k 1.0
// ex16 -s 8 -a 1.0 -k 0.0 -dt 1e-4 -tf 5e-2 -vs 25
// ex16 -s 11 -a 1.0 -k 0.0 -dt 1e-4 -tf 5e-2 -vs 25
// ex16 -s 9 -a 0.5 -k 0.5 -o 4 -dt 1e-4 -tf 2e-2 -vs 25
// ex16 -s 12 -a 0.5 -k 0.5 -o 4 -dt 1e-4 -tf 2e-2 -vs 25
// ex16 -s 10 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// ex16 -s 13 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// ex16 -m ../../data/fichera-q2.mesh
// ex16 -m ../../data/escher.mesh
// ex16 -m ../../data/beam-tet.mesh -tf 10 -dt 0.1
@@ -43,102 +37,75 @@
using namespace std;
using namespace mfem;
/** After spatial discretization, the conduction model is expressed as
/** After spatial discretization, the conduction model can be written as:
*
* M du/dt = - K(u) u
* du/dt = M^{-1}(-Ku)
*
* where u is the vector representing the temperature, M is the mass matrix,
* and K(u) is the diffusion operator with diffusivity depending on u:
* and K is the diffusion operator with diffusivity depending on u:
* (\kappa + \alpha u).
*
* Class ConductionOperatorOperator represents the above ODE operator in the
* general form F(u, k, t) = G(u, t) where
*
* 1. F(u, du/dt, t) = du/dt (ODE is expressed in EXPLICIT form)
* G(u, t) = - inv(M) K(u) u
* 2. F(u, du/dt, t) = M du/dt (ODE is expressed in IMPLICIT form)
* G(u, t) = - K(u) u
* Class ConductionOperator represents the right-hand side of the above ODE.
*/
class ConductionOperator : public TimeDependentOperator
{
protected:
FiniteElementSpace &fespace;
Array<int> ess_tdof_list; // this list remains empty for pure Neumann b.c.
BilinearForm M;
SparseMatrix Mmat;
BilinearForm *M;
BilinearForm *K;
const real_t alpha, kappa;
std::unique_ptr<BilinearForm> K;
SparseMatrix Kmat;
std::unique_ptr<SparseMatrix> T; // T = M + gam K(u)
SparseMatrix Mmat, Kmat;
SparseMatrix *T; // T = M + dt K
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
DSmoother M_prec; // Preconditioner for the mass matrix M
CGSolver T_solver; // Implicit solver for T = M + gam K(u)
CGSolver T_solver; // Implicit solver for T = M + dt K
DSmoother T_prec; // Preconditioner for the implicit solver
double alpha, kappa;
mutable Vector z; // auxiliary vector
public:
ConductionOperator(FiniteElementSpace &f, double alpha, double kappa,
const Vector &u);
ConductionOperator(FiniteElementSpace &f, const real_t alpha,
const real_t kappa, const Vector &u,
const Type &ode_expression_type);
virtual void Mult(const Vector &u, Vector &du_dt) const;
// Compute K(u_n) for use as an approximation in - K(u) u
void SetConductionTensor(const Vector &u);
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
virtual void ImplicitSolve(const double dt, const Vector &u, Vector &k);
/** Compute G(u, t) as defined in the IMPLICIT expression form of the ODE
operator, i.e., @a v = - K(u_n) @a u. Note that K(u_n) is an
approximation to K(u). */
void ExplicitMult(const Vector &u, Vector &v) const override;
/// Custom Jacobian system solver for the SUNDIALS time integrators.
/** For the ODE system represented by ConductionOperator
/** Solve for k in F(u, k, t) = G(u, t) for either EXPLICIT or IMPLICIT
expression forms of the ODE operator, i.e., @a k = - inv(M) K(u_n) @a u.
Note that K(u_n) is an approximation to K(u). */
void Mult(const Vector &u, Vector &k) const override;
M du/dt = -K(u),
/** Solve for k in F(u + gam*k, k, t) = G(u + gam*k, t) for either EXPLICIT
or IMPLICIT expression forms of the ODE operator, i.e.,
[ M + @a gam K(u_n) ] @a k = - K(u_n) @a u . Note that K(u_n) is an
approximation to K(u). */
void ImplicitSolve(const real_t gam, const Vector &u, Vector &k) override;
this class facilitates the solution of linear systems of the form
/** Setup to solve for dk in [dF/dk + gam*dF/du - gam*dG/du] dk = G - F for
either EXPLICIT or IMPLICIT expression forms of the ODE operator, i.e.,
[M - @a gam Jf(u)] dk = G - F, where Jf(u) is an approximation of the
Jacobian of -K(u) u. The approximation chosen here is Jf(u) = -K(u_n). */
int SUNImplicitSetup(const Vector &u, const Vector &fu, int jok, int *jcur,
real_t gam) override;
(M + γK) y = M b,
/** Solve for @a dk in the system in SUNImplicitSetup to the given tolerance,
with the residual @a r providing either
1. @a r = G - F = inv(M) f(u) - k (EXPLICIT expression form)
1. @a r = G - F = f(u) - M k (IMPLICIT expression form)
*/
int SUNImplicitSolve(const Vector &r, Vector &dk, real_t tol) override;
for given b, u (not used), and γ = GetTimeStep(). */
int SUNMassSetup() override;
/** Setup the system (M + dt K) x = M b. This method is used by the implicit
SUNDIALS solvers. */
virtual int SUNImplicitSetup(const Vector &x, const Vector &fx,
int jok, int *jcur, double gamma);
int SUNMassSolve(const Vector &b, Vector &x, real_t tol) override;
/** Solve the system (M + dt K) x = M b. This method is used by the implicit
SUNDIALS solvers. */
virtual int SUNImplicitSolve(const Vector &b, Vector &x, double tol);
int SUNMassMult(const Vector &x, Vector &v) override;
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
void SetParameters(const Vector &u);
virtual ~ConductionOperator();
};
real_t InitialTemperature(const Vector &x)
{
if (x.Norml2() < 0.5)
{
return 2.0;
}
else
{
return 1.0;
}
}
double InitialTemperature(const Vector &x);
int main(int argc, char *argv[])
{
@@ -150,16 +117,16 @@ int main(int argc, char *argv[])
int ref_levels = 2;
int order = 2;
int ode_solver_type = 9; // CVODE implicit BDF
real_t t_final = 0.5;
real_t dt = 1.0e-2;
real_t alpha = 1.0e-2;
real_t kappa = 0.5;
double t_final = 0.5;
double dt = 1.0e-2;
double alpha = 1.0e-2;
double kappa = 0.5;
bool visualization = true;
bool visit = false;
int vis_steps = 5;
// Relative and absolute tolerances for CVODE and ARKODE.
const real_t reltol = 1e-4, abstol = 1e-4;
const double reltol = 1e-4, abstol = 1e-4;
int precision = 8;
cout.precision(precision);
@@ -184,10 +151,7 @@ int main(int argc, char *argv[])
"9 - CVODE (implicit BDF),\n\t"
"10 - ARKODE (default explicit),\n\t"
"11 - ARKODE (explicit Fehlberg-6-4-5),\n\t"
"12 - ARKODE (default implicit),\n\t"
"13 - ARKODE (default explicit with MFEM mass solve),\n\t"
"14 - ARKODE (explicit Fehlberg-6-4-5 with MFEM mass solve),\n\t"
"15 - ARKODE (default implicit with MFEM mass solve).");
"12 - ARKODE (default impicit).");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -210,13 +174,16 @@ int main(int argc, char *argv[])
args.PrintUsage(cout);
return 1;
}
if (ode_solver_type < 1 || ode_solver_type > 12)
{
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
return 3;
}
args.PrintOptions(cout);
bool use_mass_solver = ode_solver_type >= 13;
// 2. Read the mesh from the given mesh file. We can handle triangular,
// quadrilateral, tetrahedral and hexahedral meshes with the same code.
std::unique_ptr<Mesh> mesh(new Mesh(mesh_file, 1, 1));
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
@@ -230,7 +197,7 @@ int main(int argc, char *argv[])
// 4. Define the vector finite element space representing the current and the
// initial temperature, u_ref.
H1_FECollection fe_coll(order, dim);
FiniteElementSpace fespace(mesh.get(), &fe_coll);
FiniteElementSpace fespace(mesh, &fe_coll);
int fe_size = fespace.GetTrueVSize();
cout << "Number of temperature unknowns: " << fe_size << endl;
@@ -244,17 +211,8 @@ int main(int argc, char *argv[])
Vector u;
u_gf.GetTrueDofs(u);
// 6. Initialize the conduction ODE operator and the visualization.
ConductionOperator::Type ode_expression_type;
if (use_mass_solver)
{
ode_expression_type = ConductionOperator::Type::IMPLICIT;
}
else
{
ode_expression_type = ConductionOperator::Type::EXPLICIT;
}
ConductionOperator oper(fespace, alpha, kappa, u, ode_expression_type);
// 6. Initialize the conduction operator and the visualization.
ConductionOperator oper(fespace, alpha, kappa, u);
u_gf.SetFromTrueDofs(u);
{
@@ -266,7 +224,7 @@ int main(int argc, char *argv[])
u_gf.Save(osol);
}
VisItDataCollection visit_dc("Example16", mesh.get());
VisItDataCollection visit_dc("Example16", mesh);
visit_dc.RegisterField("temperature", &u_gf);
if (visit)
{
@@ -300,75 +258,52 @@ int main(int argc, char *argv[])
}
// 7. Define the ODE solver used for time integration.
real_t t = 0.0;
std::unique_ptr<ODESolver> ode_solver;
double t = 0.0;
ODESolver *ode_solver = NULL;
CVODESolver *cvode = NULL;
ARKStepSolver *arkode = NULL;
switch (ode_solver_type)
{
// MFEM explicit methods
case 1: ode_solver = std::make_unique<ForwardEulerSolver>(); break;
case 2: ode_solver = std::make_unique<RK2Solver>(0.5); break; // midpoint method
case 3: ode_solver = std::make_unique<RK3SSPSolver>(); break;
case 4: ode_solver = std::make_unique<RK4Solver>(); break;
case 1: ode_solver = new ForwardEulerSolver; break;
case 2: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 3: ode_solver = new RK3SSPSolver; break;
case 4: ode_solver = new RK4Solver; break;
// MFEM implicit L-stable methods
case 5: ode_solver = std::make_unique<BackwardEulerSolver>(); break;
case 6: ode_solver = std::make_unique<SDIRK23Solver>(2); break;
case 7: ode_solver = std::make_unique<SDIRK33Solver>(); break;
case 5: ode_solver = new BackwardEulerSolver; break;
case 6: ode_solver = new SDIRK23Solver(2); break;
case 7: ode_solver = new SDIRK33Solver; break;
// CVODE
case 8:
case 9:
{
int cvode_solver_type;
if (ode_solver_type == 8)
{
cvode_solver_type = CV_ADAMS;
}
else
{
cvode_solver_type = CV_BDF;
}
std::unique_ptr<CVODESolver> cvode(new CVODESolver(cvode_solver_type));
cvode = new CVODESolver(CV_ADAMS);
cvode->Init(oper);
cvode->SetSStolerances(reltol, abstol);
cvode->SetMaxStep(dt);
ode_solver = std::move(cvode);
break;
}
ode_solver = cvode; break;
case 9:
cvode = new CVODESolver(CV_BDF);
cvode->Init(oper);
cvode->SetSStolerances(reltol, abstol);
cvode->SetMaxStep(dt);
ode_solver = cvode; break;
// ARKODE
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
{
ARKStepSolver::Type arkode_solver_type;
if (ode_solver_type == 12 || ode_solver_type == 15)
{
arkode_solver_type = ARKStepSolver::IMPLICIT;
}
else
{
arkode_solver_type = ARKStepSolver::EXPLICIT;
}
std::unique_ptr<ARKStepSolver> arkode(
new ARKStepSolver(arkode_solver_type));
arkode = new ARKStepSolver(ARKStepSolver::EXPLICIT);
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
if (ode_solver_type == 11 || ode_solver_type == 14)
if (ode_solver_type == 11)
{
arkode->SetERKTableNum(ARKODE_FEHLBERG_13_7_8);
}
if (use_mass_solver)
{
arkode->UseMFEMMassLinearSolver(SUNFALSE);
}
ode_solver = std::move(arkode);
break;
}
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
return 3;
ode_solver = arkode; break;
case 12:
arkode = new ARKStepSolver(ARKStepSolver::IMPLICIT);
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
ode_solver = arkode; break;
}
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
@@ -376,14 +311,8 @@ int main(int argc, char *argv[])
// Since we want to update the diffusion coefficient after every time step,
// we need to use the "one-step" mode of the SUNDIALS solvers.
if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
{
cvode->SetStepMode(CV_ONE_STEP);
}
else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
{
arkode->SetStepMode(ARK_ONE_STEP);
}
if (cvode) { cvode->SetStepMode(CV_ONE_STEP); }
if (arkode) { arkode->SetStepMode(ARK_ONE_STEP); }
// 8. Perform time-integration (looping over the time iterations, ti, with a
// time-step dt).
@@ -394,7 +323,7 @@ int main(int argc, char *argv[])
bool last_step = false;
for (int ti = 1; !last_step; ti++)
{
real_t dt_real = min(dt, t_final - t);
double dt_real = min(dt, t_final - t);
// Note that since we are using the "one-step" mode of the SUNDIALS
// solvers, they will, generally, step over the final time and will not
@@ -408,14 +337,8 @@ int main(int argc, char *argv[])
if (last_step || (ti % vis_steps) == 0)
{
cout << "step " << ti << ", t = " << t << endl;
if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
{
cvode->PrintInfo();
}
else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
{
arkode->PrintInfo();
}
if (cvode) { cvode->PrintInfo(); }
if (arkode) { arkode->PrintInfo(); }
u_gf.SetFromTrueDofs(u);
if (visualization)
@@ -430,153 +353,137 @@ int main(int argc, char *argv[])
visit_dc.Save();
}
}
oper.SetConductionTensor(u);
oper.SetParameters(u);
}
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 ex16.mesh -g ex16-final.gf".
u_gf.Save("ex16-final.gf", precision);
{
ofstream osol("ex16-final.gf");
osol.precision(precision);
u_gf.Save(osol);
}
// 10. Free the used memory.
delete ode_solver;
delete mesh;
return 0;
}
ConductionOperator::ConductionOperator(FiniteElementSpace &fes,
const real_t alpha, const real_t kappa,
const Vector &u,
const Type &ode_expression_type)
: TimeDependentOperator(fes.GetTrueVSize(), 0.0, ode_expression_type),
fespace(fes), M(&fespace), alpha(alpha), kappa(kappa), z(height)
ConductionOperator::ConductionOperator(FiniteElementSpace &f, double al,
double kap, const Vector &u)
: TimeDependentOperator(f.GetTrueVSize(), 0.0), fespace(f), M(NULL), K(NULL),
T(NULL), z(height)
{
// specify a relative tolerance for all solves with MFEM integrators
const real_t rel_tol = 1e-8;
const double rel_tol = 1e-8;
M.AddDomainIntegrator(new MassIntegrator());
M.Assemble();
M.FormSystemMatrix(ess_tdof_list, Mmat);
M = new BilinearForm(&fespace);
M->AddDomainIntegrator(new MassIntegrator());
M->Assemble();
M->FormSystemMatrix(ess_tdof_list, Mmat);
M_solver.iterative_mode = false;
M_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
M_solver.SetRelTol(rel_tol);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(50);
M_solver.SetPrintLevel(0);
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(Mmat);
alpha = al;
kappa = kap;
T_solver.iterative_mode = false;
T_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
T_solver.SetRelTol(rel_tol);
T_solver.SetAbsTol(0.0);
T_solver.SetMaxIter(100);
T_solver.SetPrintLevel(0);
T_solver.SetPreconditioner(T_prec);
SetConductionTensor(u);
SetParameters(u);
}
void ConductionOperator::SetConductionTensor(const Vector &u)
void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
{
// Compute:
// du_dt = M^{-1}*-K(u)
// for du_dt
Kmat.Mult(u, z);
z.Neg(); // z = -z
M_solver.Mult(z, du_dt);
}
void ConductionOperator::ImplicitSolve(const double dt,
const Vector &u, Vector &du_dt)
{
// Solve the equation:
// du_dt = M^{-1}*[-K(u + dt*du_dt)]
// for du_dt
if (T) { delete T; }
T = Add(1.0, Mmat, dt, Kmat);
T_solver.SetOperator(*T);
Kmat.Mult(u, z);
z.Neg();
T_solver.Mult(z, du_dt);
}
void ConductionOperator::SetParameters(const Vector &u)
{
// Compute K(u_n).
GridFunction u_alpha_gf(&fespace);
u_alpha_gf.SetFromTrueDofs(u);
for (int i = 0; i < u_alpha_gf.Size(); i++)
{
u_alpha_gf(i) = kappa + alpha*u_alpha_gf(i);
}
delete K;
K = new BilinearForm(&fespace);
GridFunctionCoefficient u_coeff(&u_alpha_gf);
K = std::make_unique<BilinearForm>(&fespace);
K->AddDomainIntegrator(new DiffusionIntegrator(u_coeff));
K->Assemble();
K->FormSystemMatrix(ess_tdof_list, Kmat);
}
void ConductionOperator::ExplicitMult(const Vector &u, Vector &v) const
int ConductionOperator::SUNImplicitSetup(const Vector &x,
const Vector &fx, int jok, int *jcur,
double gamma)
{
// Compute - K(u_n) u.
Kmat.Mult(u, v);
v.Neg();
}
void ConductionOperator::Mult(const Vector &u, Vector &k) const
{
// Compute - inv(M) K(u_n) u.
ExplicitMult(u, z);
M_solver.Mult(z, k);
}
void ConductionOperator::ImplicitSolve(const real_t gam, const Vector &u,
Vector &k)
{
// Solve for k in M k = - K(u_n) [u + gam*k].
ExplicitMult(u, z);
T = std::unique_ptr<SparseMatrix>(Add(1.0, Mmat, gam, Kmat));
// Setup the ODE Jacobian T = M + gamma K.
if (T) { delete T; }
T = Add(1.0, Mmat, gamma, Kmat);
T_solver.SetOperator(*T);
T_solver.Mult(z, k);
*jcur = 1;
return (0);
}
int ConductionOperator::SUNImplicitSetup(const Vector &u, const Vector &fu,
int jok, int *jcur, real_t gam)
int ConductionOperator::SUNImplicitSolve(const Vector &b, Vector &x, double tol)
{
// Compute T = M + gamma K(u_n).
T = std::unique_ptr<SparseMatrix>(Add(1.0, Mmat, gam, Kmat));
T_solver.SetOperator(*T);
*jcur = SUNTRUE; // this should eventually only be set true if K(u) is used
return SUN_SUCCESS;
// Solve the system A x = z => (M - gamma K) x = M b.
Mmat.Mult(b, z);
T_solver.Mult(z, x);
return (0);
}
int ConductionOperator::SUNImplicitSolve(const Vector &r, Vector &dk,
real_t tol)
ConductionOperator::~ConductionOperator()
{
// Solve the system [M + gamma K(u_n)] dk = - K(u_n) u - M k.
// What value r is providing depends on the ODE expression form:
// EXPLICIT form: r = -inv(M) K(u_n) u - k
// IMPLICIT form: r = -K(u_n) u - M k
T_solver.SetRelTol(tol);
if (isExplicit())
delete T;
delete M;
delete K;
}
double InitialTemperature(const Vector &x)
{
if (x.Norml2() < 0.5)
{
Mmat.Mult(r, z);
T_solver.Mult(z, dk);
return 2.0;
}
else
{
T_solver.Mult(r, dk);
}
if (T_solver.GetConverged())
{
return SUN_SUCCESS;
}
else
{
return SUNLS_CONV_FAIL;
return 1.0;
}
}
int ConductionOperator::SUNMassSetup()
{
// Do nothing b/c mass solver was setup in constructor.
return SUN_SUCCESS;
}
int ConductionOperator::SUNMassSolve(const Vector &b, Vector &x, real_t tol)
{
// Solve the system M x = b.
M_solver.SetRelTol(tol);
M_solver.Mult(b, x);
if (M_solver.GetConverged())
{
return SUN_SUCCESS;
}
else
{
return SUNLS_CONV_FAIL;
}
}
int ConductionOperator::SUNMassMult(const Vector &x, Vector &v)
{
// Compute M x.
Mmat.Mult(x, v);
return SUN_SUCCESS;
}
+189 -286
View File
@@ -1,22 +1,16 @@
// MFEM Example 16 - Parallel Version
// SUNDIALS Modification
//
// Compile with:
// make ex16p (GNU make)
// make sundials_ex16p (CMake)
// Compile with: make ex16p
//
// Sample runs:
// mpirun -np 4 ex16p
// mpirun -np 4 ex16p -m ../../data/inline-tri.mesh
// mpirun -np 4 ex16p -m ../../data/disc-nurbs.mesh -tf 2
// mpirun -np 4 ex16p -s 12 -a 0.0 -k 1.0
// mpirun -np 4 ex16p -s 15 -a 0.0 -k 1.0
// mpirun -np 4 ex16p -s 8 -a 1.0 -k 0.0 -dt 4e-6 -tf 2e-2 -vs 50
// mpirun -np 4 ex16p -s 11 -a 1.0 -k 0.0 -dt 4e-6 -tf 2e-2 -vs 50
// mpirun -np 8 ex16p -s 9 -a 0.5 -k 0.5 -o 4 -dt 8e-6 -tf 2e-2 -vs 50
// mpirun -np 8 ex16p -s 12 -a 0.5 -k 0.5 -o 4 -dt 8e-6 -tf 2e-2 -vs 50
// mpirun -np 4 ex16p -s 10 -dt 2.0e-4 -tf 4.0e-2
// mpirun -np 4 ex16p -s 13 -dt 2.0e-4 -tf 4.0e-2
// mpirun -np 16 ex16p -m ../../data/fichera-q2.mesh
// mpirun -np 16 ex16p -m ../../data/escher-p2.mesh
// mpirun -np 8 ex16p -m ../../data/beam-tet.mesh -tf 10 -dt 0.1
@@ -44,102 +38,66 @@
using namespace std;
using namespace mfem;
/** After spatial discretization, the conduction model is expressed as
/** After spatial discretization, the conduction model can be written as:
*
* M du/dt = - K(u) u
* du/dt = M^{-1}(-Ku)
*
* where u is the vector representing the temperature, M is the mass matrix,
* and K(u) is the diffusion operator with diffusivity depending on u:
* and K is the diffusion operator with diffusivity depending on u:
* (\kappa + \alpha u).
*
* Class ConductionOperatorOperator represents the above ODE operator in the
* general form F(u, k, t) = G(u, t) where either
*
* 1. F(u, du/dt, t) = du/dt (ODE is expressed in EXPLICIT form)
* G(u, t) = - inv(M) K(u) u
* 2. F(u, du/dt, t) = M du/dt (ODE is expressed in IMPLICIT form)
* G(u, t) = - K(u) u
* Class ConductionOperator represents the right-hand side of the above ODE.
*/
class ConductionOperator : public TimeDependentOperator
{
protected:
ParFiniteElementSpace &fespace;
Array<int> ess_tdof_list; // this list remains empty for pure Neumann b.c.
ParBilinearForm M;
ParBilinearForm *M;
ParBilinearForm *K;
HypreParMatrix Mmat;
const real_t alpha, kappa;
std::unique_ptr<BilinearForm> K;
HypreParMatrix Kmat;
HypreParMatrix *T; // T = M + dt K
double current_dt;
std::unique_ptr<HypreParMatrix> T; // T = M + gam K(u)
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
HypreSmoother M_prec; // Preconditioner for the mass matrix M
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
HypreSmoother M_prec; // Preconditioner for the mass matrix M
CGSolver T_solver; // Implicit solver for T = M + dt K
HypreSmoother T_prec; // Preconditioner for the implicit solver
CGSolver T_solver; // Implicit solver for T = M + gam K(u)
HypreSmoother T_prec; // Preconditioner for the implicit solver
double alpha, kappa;
mutable Vector z; // auxiliary vector
public:
ConductionOperator(ParFiniteElementSpace &f, double alpha, double kappa,
const Vector &u);
ConductionOperator(ParFiniteElementSpace &f, const real_t alpha,
const real_t kappa, const Vector &u,
const Type &ode_expression_type);
virtual void Mult(const Vector &u, Vector &du_dt) const;
// Compute K(u_n) for use as an approximation in - K(u) u
void SetConductionTensor(const Vector &u);
/** Solve the Backward-Euler equation: k = f(u + dt*k, t), for the unknown k.
This is the only requirement for high-order SDIRK implicit integration.*/
virtual void ImplicitSolve(const double dt, const Vector &u, Vector &k);
/** Compute G(u, t) as defined in the IMPLICIT expression form of the ODE
operator, i.e., @a v = - K(u_n) @a u. Note that K(u_n) is an
approximation to K(u). */
void ExplicitMult(const Vector &u, Vector &v) const override;
/** Setup the system (M + dt K) x = M b. This method is used by the implicit
SUNDIALS solvers. */
virtual int SUNImplicitSetup(const Vector &x, const Vector &fx,
int jok, int *jcur, double gamma);
/** Solve for k in F(u, k, t) = G(u, t) for either EXPLICIT or IMPLICIT
expression forms of the ODE operator, i.e., @a k = - inv(M) K(u_n) @a u.
Note that K(u_n) is an approximation to K(u). */
void Mult(const Vector &u, Vector &k) const override;
/** Solve the system (M + dt K) x = M b. This method is used by the implicit
SUNDIALS solvers. */
virtual int SUNImplicitSolve(const Vector &b, Vector &x, double tol);
/** Solve for k in F(u + gam*k, k, t) = G(u + gam*k, t) for either EXPLICIT
or IMPLICIT expression forms of the ODE operator, i.e.,
[ M + @a gam K(u_n) ] @a k = - K(u_n) @a u . Note that K(u_n) is an
approximation to K(u). */
void ImplicitSolve(const real_t gam, const Vector &u, Vector &k) override;
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
void SetParameters(const Vector &u);
/** Setup to solve for dk in [dF/dk + gam*dF/du - gam*dG/du] dk = G - F for
either EXPLICIT or IMPLICIT expression forms of the ODE operator, i.e.,
[M - @a gam Jf(u)] dk = G - F, where Jf(u) is an approximation of the
Jacobian of -K(u) u. The approximation chosen here is Jf(u) = -K(u_n). */
int SUNImplicitSetup(const Vector &u, const Vector &fu, int jok, int *jcur,
real_t gam) override;
/** Solve for @a dk in the system in SUNImplicitSetup to the given tolerance,
with the residual @a r providing either
1. @a r = G - F = inv(M) f(u) - k (EXPLICIT expression form)
1. @a r = G - F = f(u) - M k (IMPLICIT expression form)
*/
int SUNImplicitSolve(const Vector &r, Vector &dk, real_t tol) override;
int SUNMassSetup() override;
int SUNMassSolve(const Vector &b, Vector &x, real_t tol) override;
int SUNMassMult(const Vector &x, Vector &v) override;
virtual ~ConductionOperator();
};
real_t InitialTemperature(const Vector &x)
{
if (x.Norml2() < 0.5)
{
return 2.0;
}
else
{
return 1.0;
}
}
double InitialTemperature(const Vector &x);
int main(int argc, char *argv[])
{
@@ -156,16 +114,16 @@ int main(int argc, char *argv[])
int par_ref_levels = 1;
int order = 2;
int ode_solver_type = 9; // CVODE implicit BDF
real_t t_final = 0.5;
real_t dt = 1.0e-2;
real_t alpha = 1.0e-2;
real_t kappa = 0.5;
double t_final = 0.5;
double dt = 1.0e-2;
double alpha = 1.0e-2;
double kappa = 0.5;
bool visualization = true;
bool visit = false;
int vis_steps = 5;
// Relative and absolute tolerances for CVODE and ARKODE.
const real_t reltol = 1e-4, abstol = 1e-4;
const double reltol = 1e-4, abstol = 1e-4;
int precision = 8;
cout.precision(precision);
@@ -192,10 +150,7 @@ int main(int argc, char *argv[])
"9 - CVODE (implicit BDF),\n\t"
"10 - ARKODE (default explicit),\n\t"
"11 - ARKODE (explicit Fehlberg-6-4-5),\n\t"
"12 - ARKODE (default implicit),\n\t"
"13 - ARKODE (default explicit with MFEM mass solve),\n\t"
"14 - ARKODE (explicit Fehlberg-6-4-5 with MFEM mass solve),\n\t"
"15 - ARKODE (default implicit with MFEM mass solve).");
"12 - ARKODE (default impicit).");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
@@ -219,33 +174,40 @@ int main(int argc, char *argv[])
return 1;
}
if (Mpi::Root())
if (myid == 0)
{
args.PrintOptions(cout);
}
bool use_mass_solver = ode_solver_type >= 13;
// check for valid ODE solver option
if (ode_solver_type < 1 || ode_solver_type > 12)
{
if (myid == 0)
{
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
}
return 1;
}
// 3. Define a parallel mesh by a partitioning of a serial mesh. Read the
// serial mesh from the given mesh file on all processors. We can
// 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.
std::unique_ptr<ParMesh> pmesh;
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++)
{
std::unique_ptr<Mesh> mesh(new Mesh(mesh_file, 1, 1));
// 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. Refine this mesh further in parallel to increase the resolution.
// Once the parallel mesh is defined, the serial mesh can be deleted.
pmesh = std::make_unique<ParMesh>(MPI_COMM_WORLD, *mesh);
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();
@@ -253,9 +215,8 @@ int main(int argc, char *argv[])
// 6. Define the vector finite element space representing the current and the
// initial temperature, u_ref.
int dim = pmesh->Dimension();
H1_FECollection fe_coll(order, dim);
ParFiniteElementSpace fespace(pmesh.get(), &fe_coll);
ParFiniteElementSpace fespace(pmesh, &fe_coll);
int fe_size = fespace.GlobalTrueVSize();
if (myid == 0)
@@ -272,17 +233,8 @@ int main(int argc, char *argv[])
Vector u;
u_gf.GetTrueDofs(u);
// 8. Initialize the conduction ODE operator and the visualization.
ConductionOperator::Type ode_expression_type;
if (use_mass_solver)
{
ode_expression_type = ConductionOperator::Type::IMPLICIT;
}
else
{
ode_expression_type = ConductionOperator::Type::EXPLICIT;
}
ConductionOperator oper(fespace, alpha, kappa, u, ode_expression_type);
// 8. Initialize the conduction operator and the VisIt visualization.
ConductionOperator oper(fespace, alpha, kappa, u);
u_gf.SetFromTrueDofs(u);
{
@@ -297,7 +249,7 @@ int main(int argc, char *argv[])
u_gf.Save(osol);
}
VisItDataCollection visit_dc("Example16-Parallel", pmesh.get());
VisItDataCollection visit_dc("Example16-Parallel", pmesh);
visit_dc.RegisterField("temperature", &u_gf);
if (visit)
{
@@ -341,76 +293,52 @@ int main(int argc, char *argv[])
}
// 9. Define the ODE solver used for time integration.
real_t t = 0.0;
std::unique_ptr<ODESolver> ode_solver;
double t = 0.0;
ODESolver *ode_solver = NULL;
CVODESolver *cvode = NULL;
ARKStepSolver *arkode = NULL;
switch (ode_solver_type)
{
// MFEM explicit methods
case 1: ode_solver = std::make_unique<ForwardEulerSolver>(); break;
case 2: ode_solver = std::make_unique<RK2Solver>(0.5); break; // midpoint method
case 3: ode_solver = std::make_unique<RK3SSPSolver>(); break;
case 4: ode_solver = std::make_unique<RK4Solver>(); break;
case 1: ode_solver = new ForwardEulerSolver; break;
case 2: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 3: ode_solver = new RK3SSPSolver; break;
case 4: ode_solver = new RK4Solver; break;
// MFEM implicit L-stable methods
case 5: ode_solver = std::make_unique<BackwardEulerSolver>(); break;
case 6: ode_solver = std::make_unique<SDIRK23Solver>(2); break;
case 7: ode_solver = std::make_unique<SDIRK33Solver>(); break;
case 5: ode_solver = new BackwardEulerSolver; break;
case 6: ode_solver = new SDIRK23Solver(2); break;
case 7: ode_solver = new SDIRK33Solver; break;
// CVODE
case 8:
case 9:
{
int cvode_solver_type;
if (ode_solver_type == 8)
{
cvode_solver_type = CV_ADAMS;
}
else
{
cvode_solver_type = CV_BDF;
}
std::unique_ptr<CVODESolver> cvode(
new CVODESolver(MPI_COMM_WORLD, cvode_solver_type));
cvode = new CVODESolver(MPI_COMM_WORLD, CV_ADAMS);
cvode->Init(oper);
cvode->SetSStolerances(reltol, abstol);
cvode->SetMaxStep(dt);
ode_solver = std::move(cvode);
break;
}
ode_solver = cvode; break;
case 9:
cvode = new CVODESolver(MPI_COMM_WORLD, CV_BDF);
cvode->Init(oper);
cvode->SetSStolerances(reltol, abstol);
cvode->SetMaxStep(dt);
ode_solver = cvode; break;
// ARKODE
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
{
ARKStepSolver::Type arkode_solver_type;
if (ode_solver_type == 12 || ode_solver_type == 15)
{
arkode_solver_type = ARKStepSolver::IMPLICIT;
}
else
{
arkode_solver_type = ARKStepSolver::EXPLICIT;
}
std::unique_ptr<ARKStepSolver> arkode(
new ARKStepSolver(MPI_COMM_WORLD, arkode_solver_type));
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::EXPLICIT);
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
if (ode_solver_type == 11 || ode_solver_type == 14)
if (ode_solver_type == 11)
{
arkode->SetERKTableNum(ARKODE_FEHLBERG_13_7_8);
}
if (use_mass_solver)
{
arkode->UseMFEMMassLinearSolver(SUNFALSE);
}
ode_solver = std::move(arkode);
break;
}
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
return 3;
ode_solver = arkode; break;
case 12:
arkode = new ARKStepSolver(MPI_COMM_WORLD, ARKStepSolver::IMPLICIT);
arkode->Init(oper);
arkode->SetSStolerances(reltol, abstol);
arkode->SetMaxStep(dt);
ode_solver = arkode; break;
}
// Initialize MFEM integrators, SUNDIALS integrators are initialized above
@@ -418,18 +346,12 @@ int main(int argc, char *argv[])
// Since we want to update the diffusion coefficient after every time step,
// we need to use the "one-step" mode of the SUNDIALS solvers.
if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
{
cvode->SetStepMode(CV_ONE_STEP);
}
else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
{
arkode->SetStepMode(ARK_ONE_STEP);
}
if (cvode) { cvode->SetStepMode(CV_ONE_STEP); }
if (arkode) { arkode->SetStepMode(ARK_ONE_STEP); }
// 10. Perform time-integration (looping over the time iterations, ti, with a
// time-step dt).
if (Mpi::Root())
if (myid == 0)
{
cout << "Integrating the ODE ..." << endl;
}
@@ -439,7 +361,7 @@ int main(int argc, char *argv[])
bool last_step = false;
for (int ti = 1; !last_step; ti++)
{
real_t dt_real = min(dt, t_final - t);
double dt_real = min(dt, t_final - t);
// Note that since we are using the "one-step" mode of the SUNDIALS
// solvers, they will, generally, step over the final time and will not
@@ -455,14 +377,8 @@ int main(int argc, char *argv[])
if (myid == 0)
{
cout << "step " << ti << ", t = " << t << endl;
if (CVODESolver* cvode = dynamic_cast<CVODESolver*>(ode_solver.get()))
{
cvode->PrintInfo();
}
else if (ARKStepSolver* arkode = dynamic_cast<ARKStepSolver*>(ode_solver.get()))
{
arkode->PrintInfo();
}
if (cvode) { cvode->PrintInfo(); }
if (arkode) { arkode->PrintInfo(); }
}
u_gf.SetFromTrueDofs(u);
@@ -479,38 +395,46 @@ int main(int argc, char *argv[])
visit_dc.Save();
}
}
oper.SetConductionTensor(u);
oper.SetParameters(u);
}
tic_toc.Stop();
if (Mpi::Root())
if (myid == 0)
{
cout << "Done, " << tic_toc.RealTime() << "s." << endl;
}
// 11. Save the final solution in parallel. This output can be viewed later
// using GLVis: "glvis -np <np> -m ex16-mesh -g ex16-final".
u_gf.Save("ex16-final", precision);
{
ostringstream sol_name;
sol_name << "ex16-final." << setfill('0') << setw(6) << myid;
ofstream osol(sol_name.str().c_str());
osol.precision(precision);
u_gf.Save(osol);
}
// 12. Free the used memory.
delete ode_solver;
delete pmesh;
return 0;
}
ConductionOperator::ConductionOperator(ParFiniteElementSpace &fes,
const real_t alpha, const real_t kappa,
const Vector &u,
const Type &ode_expression_type)
: TimeDependentOperator(fes.GetTrueVSize(), 0.0, ode_expression_type),
fespace(fes), M(&fespace), alpha(alpha), kappa(kappa),
M_solver(fes.GetComm()), T_solver(fes.GetComm()), z(height)
ConductionOperator::ConductionOperator(ParFiniteElementSpace &f, double al,
double kap, const Vector &u)
: TimeDependentOperator(f.GetTrueVSize(), 0.0), fespace(f), M(NULL), K(NULL),
T(NULL),
M_solver(f.GetComm()), T_solver(f.GetComm()), z(height)
{
// specify a relative tolerance for all solves with MFEM integrators
const real_t rel_tol = 1e-8;
const double rel_tol = 1e-8;
M.AddDomainIntegrator(new MassIntegrator());
M.Assemble(0); // keep zeros to keep sparsity pattern of M and K the same
M.FormSystemMatrix(ess_tdof_list, Mmat);
M = new ParBilinearForm(&fespace);
M->AddDomainIntegrator(new MassIntegrator());
M->Assemble(0); // keep sparsity pattern of M and K the same
M->FormSystemMatrix(ess_tdof_list, Mmat);
M_solver.iterative_mode = false;
M_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
M_solver.SetRelTol(rel_tol);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(100);
M_solver.SetPrintLevel(0);
@@ -518,118 +442,97 @@ ConductionOperator::ConductionOperator(ParFiniteElementSpace &fes,
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(Mmat);
alpha = al;
kappa = kap;
T_solver.iterative_mode = false;
T_solver.SetRelTol(rel_tol); // will be overwritten with SUNDIALS integrators
T_solver.SetRelTol(rel_tol);
T_solver.SetAbsTol(0.0);
T_solver.SetMaxIter(100);
T_solver.SetPrintLevel(0);
T_solver.SetPreconditioner(T_prec);
SetConductionTensor(u);
SetParameters(u);
}
void ConductionOperator::SetConductionTensor(const Vector &u)
void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
{
// Compute:
// du_dt = M^{-1}*-K(u)
// for du_dt
Kmat.Mult(u, z);
z.Neg(); // z = -z
M_solver.Mult(z, du_dt);
}
void ConductionOperator::ImplicitSolve(const double dt,
const Vector &u, Vector &du_dt)
{
// Solve the equation:
// du_dt = M^{-1}*[-K(u + dt*du_dt)]
// for du_dt
if (T) { delete T; }
T = Add(1.0, Mmat, dt, Kmat);
T_solver.SetOperator(*T);
Kmat.Mult(u, z);
z.Neg();
T_solver.Mult(z, du_dt);
}
int ConductionOperator::SUNImplicitSetup(const Vector &x,
const Vector &fx, int jok, int *jcur,
double gamma)
{
// Setup the ODE Jacobian T = M + gamma K.
if (T) { delete T; }
T = Add(1.0, Mmat, gamma, Kmat);
T_solver.SetOperator(*T);
*jcur = 1;
return (0);
}
int ConductionOperator::SUNImplicitSolve(const Vector &b, Vector &x, double tol)
{
// Solve the system A x = z => (M - gamma K) x = M b.
Mmat.Mult(b, z);
T_solver.Mult(z, x);
return (0);
}
void ConductionOperator::SetParameters(const Vector &u)
{
// Compute K(u_n).
ParGridFunction u_alpha_gf(&fespace);
u_alpha_gf.SetFromTrueDofs(u);
for (int i = 0; i < u_alpha_gf.Size(); i++)
{
u_alpha_gf(i) = kappa + alpha*u_alpha_gf(i);
}
delete K;
K = new ParBilinearForm(&fespace);
GridFunctionCoefficient u_coeff(&u_alpha_gf);
K = std::make_unique<ParBilinearForm>(&fespace);
K->AddDomainIntegrator(new DiffusionIntegrator(u_coeff));
K->Assemble(0); // keep zeros to keep sparsity pattern of M and K the same
K->Assemble(0); // keep sparsity pattern of M and K the same
K->FormSystemMatrix(ess_tdof_list, Kmat);
}
void ConductionOperator::ExplicitMult(const Vector &u, Vector &v) const
ConductionOperator::~ConductionOperator()
{
// Compute - K(u_n) u.
Kmat.Mult(u, v);
v.Neg();
delete T;
delete M;
delete K;
}
void ConductionOperator::Mult(const Vector &u, Vector &k) const
double InitialTemperature(const Vector &x)
{
// Compute - inv(M) K(u_n) u.
ExplicitMult(u, z);
M_solver.Mult(z, k);
}
void ConductionOperator::ImplicitSolve(const real_t gam, const Vector &u,
Vector &k)
{
// Solve for k in M k = - K(u_n) [u + gam*k].
ExplicitMult(u, z);
T = std::unique_ptr<HypreParMatrix>(Add(1.0, Mmat, gam, Kmat));
T_solver.SetOperator(*T);
T_solver.Mult(z, k);
}
int ConductionOperator::SUNImplicitSetup(const Vector &u, const Vector &fu,
int jok, int *jcur, real_t gam)
{
// Compute T = M + gamma K(u_n).
T = std::unique_ptr<HypreParMatrix>(Add(1.0, Mmat, gam, Kmat));
T_solver.SetOperator(*T);
*jcur = SUNTRUE; // this should eventually only be set true if K(u) is used
return SUN_SUCCESS;
}
int ConductionOperator::SUNImplicitSolve(const Vector &r, Vector &dk,
real_t tol)
{
// Solve the system [M + gamma K(u_n)] dk = - K(u_n) u - M k.
// What value r is providing depends on the ODE expression form:
// EXPLICIT form: r = -inv(M) K(u_n) u - k
// IMPLICIT form: r = -K(u_n) u - M k
T_solver.SetRelTol(tol);
if (isExplicit())
if (x.Norml2() < 0.5)
{
Mmat.Mult(r, z);
T_solver.Mult(z, dk);
return 2.0;
}
else
{
T_solver.Mult(r, dk);
}
if (T_solver.GetConverged())
{
return SUN_SUCCESS;
}
else
{
return SUNLS_CONV_FAIL;
return 1.0;
}
}
int ConductionOperator::SUNMassSetup()
{
// Do nothing b/c mass solver was setup in constructor.
return SUN_SUCCESS;
}
int ConductionOperator::SUNMassSolve(const Vector &b, Vector &x, real_t tol)
{
// Solve the system M x = b.
M_solver.SetRelTol(tol);
M_solver.Mult(b, x);
if (M_solver.GetConverged())
{
return SUN_SUCCESS;
}
else
{
return SUNLS_CONV_FAIL;
}
}
int ConductionOperator::SUNMassMult(const Vector &x, Vector &v)
{
// Compute M x.
Mmat.Mult(x, v);
return SUN_SUCCESS;
}
+1 -3
View File
@@ -1,9 +1,7 @@
// MFEM Example 9
// SUNDIALS Modification
//
// Compile with:
// make ex9 (GNU make)
// make sundials_ex9 (CMake)
// Compile with: make ex9
//
// Sample runs:
// ex9 -m ../../data/periodic-segment.mesh -p 0 -r 2 -s 7 -dt 0.005
+1 -3
View File
@@ -1,9 +1,7 @@
// MFEM Example 9 - Parallel Version
// SUNDIALS Modification
//
// Compile with:
// make ex9p (GNU make)
// make sundials_ex9p (CMake)
// Compile with: make ex9p
//
// Sample runs:
// mpirun -np 4 ex9p -m ../../data/periodic-segment.mesh -p 1 -rp 1 -s 7 -dt 0.0025
+4 -9
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
MFEM_INSTALL_DIR ?= ../../mfem
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/sundials/,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
@@ -99,12 +100,6 @@ ex10-test-seq: ex10
@$(call mfem-test,$<,, $(SERIAL_NAME),$(EX10_ARGS))
ex10p-test-par: ex10p
@$(call mfem-test,$<, $(RUN_MPI), $(PARALLEL_NAME),$(EX10P_ARGS))
# Example 16: test ARKODE with implicit time stepping using mass form
EX16_COMMON_ARGS := -s 15
ex16-test-seq: ex16
@$(call mfem-test,$<,, $(SERIAL_NAME),$(EX16_COMMON_ARGS))
ex16p-test-par: ex16p
@$(call mfem-test,$<, $(RUN_MPI), $(PARALLEL_NAME),$(EX16_COMMON_ARGS))
# Testing: "test" target and mfem-test* variables are defined in config/test.mk
+4 -3
View File
@@ -12,10 +12,11 @@
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
MFEM_INSTALL_DIR ?= ../../mfem
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/superlu/,)
CONFIG_MK = $(or $(wildcard $(MFEM_BUILD_DIR)/config/config.mk),\
$(wildcard $(MFEM_INSTALL_DIR)/share/mfem/config.mk))
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
+3 -4
View File
@@ -101,7 +101,6 @@ set(SRCS
lor/lor_ads.cpp
lor/lor_ams.cpp
lor/lor_batched.cpp
mdgridfunc.hpp
multigrid.cpp
nonlinearform.cpp
nonlinearform_ext.cpp
@@ -113,6 +112,8 @@ set(SRCS
qinterp/eval_by_vdim.cpp
qinterp/grad_by_nodes.cpp
qinterp/grad_by_vdim.cpp
qinterp/grad_phys_by_nodes.cpp
qinterp/grad_phys_by_vdim.cpp
qspace.cpp
quadinterpolator.cpp
quadinterpolator_face.cpp
@@ -191,9 +192,6 @@ set(HDRS
hybridization.hpp
intrules.hpp
intrules_cut.hpp
kernel_dispatch.hpp
kernel_reporter.hpp
kernels.hpp
ceed/interface/basis.hpp
ceed/interface/integrator.hpp
ceed/interface/interface.hpp
@@ -225,6 +223,7 @@ set(HDRS
nonlinearform_ext.hpp
nonlininteg.hpp
qfunction.hpp
qinterp/dispatch.hpp
qinterp/eval.hpp
qinterp/grad.hpp
qspace.hpp
+66 -470
View File
@@ -280,7 +280,7 @@ void BilinearForm::AddBdrFaceIntegrator(BilinearFormIntegrator *bfi,
boundary_face_integs_marker.Append(&bdr_marker);
}
void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat)
{
if (element_matrices)
{
@@ -289,10 +289,9 @@ void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
return;
}
const FiniteElement &fe = *fes->GetFE(i);
if (domain_integs.Size())
{
const FiniteElement &fe = *fes->GetFE(i);
ElementTransformation *eltrans = fes->GetElementTransformation(i);
domain_integs[0]->AssembleElementMatrix(fe, *eltrans, elmat);
for (int k = 1; k < domain_integs.Size(); k++)
@@ -303,18 +302,17 @@ void BilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
}
else
{
const int ndof = fe.GetDof() * fes->GetVDim();
elmat.SetSize(ndof);
fes->GetElementVDofs(i, vdofs);
elmat.SetSize(vdofs.Size());
elmat = 0.0;
}
}
void BilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
void BilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat)
{
const FiniteElement &be = *fes->GetBE(i);
if (boundary_integs.Size())
{
const FiniteElement &be = *fes->GetBE(i);
ElementTransformation *eltrans = fes->GetBdrElementTransformation(i);
boundary_integs[0]->AssembleElementMatrix(be, *eltrans, elmat);
for (int k = 1; k < boundary_integs.Size(); k++)
@@ -325,81 +323,8 @@ void BilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
}
else
{
const int ndof = be.GetDof() * fes->GetVDim();
elmat.SetSize(ndof);
elmat = 0.0;
}
}
void BilinearForm::ComputeFaceMatrix(int i, DenseMatrix &elmat) const
{
FaceElementTransformations *tr;
Mesh *mesh = fes -> GetMesh();
tr = mesh -> GetFaceElementTransformations (i);
const FiniteElement *fe1, *fe2;
fe1 = fes->GetFE(tr->Elem1No);
if (tr->Elem2No >= 0)
{
fe2 = fes->GetFE(tr->Elem2No);
}
else
{
// The fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
fe2 = fe1;
}
if (interior_face_integs.Size())
{
interior_face_integs[0] -> AssembleFaceMatrix (*fe1, *fe2, *tr, elmat);
for (int k = 1; k < interior_face_integs.Size(); k++)
{
interior_face_integs[k] -> AssembleFaceMatrix (*fe1, *fe2, *tr, elemmat);
elmat += elemmat;
}
}
else
{
int ndof = fe1->GetDof() * fes->GetVDim();
if (tr->Elem2No >= 0)
{
ndof += fe2->GetDof() * fes->GetVDim();
}
elmat.SetSize(ndof);
elmat = 0.0;
}
}
void BilinearForm::ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const
{
FaceElementTransformations *tr;
Mesh *mesh = fes -> GetMesh();
tr = mesh -> GetBdrFaceTransformations (i);
const FiniteElement *fe1, *fe2;
fe1 = fes -> GetFE (tr -> Elem1No);
// The fe2 object is really a dummy and not used on the boundaries,
// but we can't dereference a NULL pointer, and we don't want to
// actually make a fake element.
fe2 = fe1;
if (boundary_face_integs.Size())
{
boundary_face_integs[0] -> AssembleFaceMatrix (*fe1, *fe2, *tr, elmat);
for (int k = 1; k < boundary_face_integs.Size(); k++)
{
boundary_face_integs[k] -> AssembleFaceMatrix (*fe1, *fe2, *tr, elemmat);
elmat += elemmat;
}
}
else
{
int ndof = fe1->GetDof() * fes->GetVDim();
elmat.SetSize(ndof);
fes->GetBdrElementVDofs(i, vdofs);
elmat.SetSize(vdofs.Size());
elmat = 0.0;
}
}
@@ -1431,50 +1356,32 @@ void MixedBilinearForm::GetBlocks(Array2D<SparseMatrix *> &blocks) const
mat->GetBlocks(blocks);
}
void MixedBilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi)
void MixedBilinearForm::AddDomainIntegrator (BilinearFormIntegrator * bfi)
{
domain_integs.Append(bfi);
domain_integs.Append (bfi);
domain_integs_marker.Append(NULL); // NULL marker means apply everywhere
}
void MixedBilinearForm::AddDomainIntegrator(BilinearFormIntegrator *bfi,
Array<int> &elem_marker)
void MixedBilinearForm::AddDomainIntegrator (BilinearFormIntegrator * bfi,
Array<int> &elem_marker)
{
domain_integs.Append(bfi);
domain_integs.Append (bfi);
domain_integs_marker.Append(&elem_marker);
}
void MixedBilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator *bfi)
void MixedBilinearForm::AddBoundaryIntegrator (BilinearFormIntegrator * bfi)
{
boundary_integs.Append(bfi);
boundary_integs.Append (bfi);
boundary_integs_marker.Append(NULL); // NULL marker means apply everywhere
}
void MixedBilinearForm::AddBoundaryIntegrator(BilinearFormIntegrator *bfi,
Array<int> &bdr_marker)
void MixedBilinearForm::AddBoundaryIntegrator (BilinearFormIntegrator * bfi,
Array<int> &bdr_marker)
{
boundary_integs.Append(bfi);
boundary_integs.Append (bfi);
boundary_integs_marker.Append(&bdr_marker);
}
void MixedBilinearForm::AddInteriorFaceIntegrator(BilinearFormIntegrator *bfi)
{
interior_face_integs.Append(bfi);
}
void MixedBilinearForm::AddBdrFaceIntegrator(BilinearFormIntegrator *bfi)
{
boundary_face_integs.Append(bfi);
boundary_face_integs_marker.Append(NULL); // NULL marker means apply everywhere
}
void MixedBilinearForm::AddBdrFaceIntegrator(BilinearFormIntegrator *bfi,
Array<int> &bdr_marker)
{
boundary_face_integs.Append(bfi);
boundary_face_integs_marker.Append(&bdr_marker);
}
void MixedBilinearForm::AddTraceFaceIntegrator (BilinearFormIntegrator * bfi)
{
trace_face_integs.Append (bfi);
@@ -1607,108 +1514,6 @@ void MixedBilinearForm::Assemble(int skip_zeros)
}
}
if (interior_face_integs.Size())
{
FaceElementTransformations *ftr;
Array<int> trial_vdofs2, test_vdofs2;
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
int nfaces = mesh->GetNumFaces();
for (int i = 0; i < nfaces; i++)
{
ftr = mesh->GetInteriorFaceTransformations(i);
if (ftr != NULL)
{
trial_fes->GetElementVDofs(ftr->Elem1No, trial_vdofs);
test_fes->GetElementVDofs(ftr->Elem1No, test_vdofs);
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
if (ftr->Elem2No >= 0)
{
trial_fes->GetElementVDofs(ftr->Elem2No, trial_vdofs2);
test_fes->GetElementVDofs(ftr->Elem2No, test_vdofs2);
trial_vdofs.Append(trial_vdofs2);
test_vdofs.Append(test_vdofs2);
trial_fe2 = trial_fes->GetFE(ftr->Elem2No);
test_fe2 = test_fes->GetFE(ftr->Elem2No);
}
else
{
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
trial_fe2 = trial_fe1;
test_fe2 = test_fe1;
}
for (int k = 0; k < interior_face_integs.Size(); k++)
{
interior_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elemmat);
mat->AddSubMatrix(test_vdofs, trial_vdofs, elemmat, skip_zeros);
}
}
}
}
if (boundary_face_integs.Size())
{
FaceElementTransformations *ftr;
Array<int> tr_vdofs2, te_vdofs2;
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
// Which boundary attributes need to be processed?
Array<int> bdr_attr_marker(mesh->bdr_attributes.Size() ?
mesh->bdr_attributes.Max() : 0);
bdr_attr_marker = 0;
for (int k = 0; k < boundary_face_integs.Size(); k++)
{
if (boundary_face_integs_marker[k] == NULL)
{
bdr_attr_marker = 1;
break;
}
Array<int> &bdr_marker = *boundary_face_integs_marker[k];
MFEM_ASSERT(bdr_marker.Size() == bdr_attr_marker.Size(),
"invalid boundary marker for boundary face integrator #"
<< k << ", counting from zero");
for (int i = 0; i < bdr_attr_marker.Size(); i++)
{
bdr_attr_marker[i] |= bdr_marker[i];
}
}
for (int i = 0; i < trial_fes -> GetNBE(); i++)
{
const int bdr_attr = mesh->GetBdrAttribute(i);
if (bdr_attr_marker[bdr_attr-1] == 0) { continue; }
ftr = mesh -> GetBdrFaceTransformations (i);
if (ftr != NULL)
{
trial_fes->GetElementVDofs(ftr->Elem1No, trial_vdofs);
test_fes->GetElementVDofs(ftr->Elem1No, test_vdofs);
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
trial_fe2 = trial_fe1;
test_fe2 = test_fe1;
for (int k = 0; k < boundary_face_integs.Size(); k++)
{
if (boundary_face_integs_marker[k] &&
(*boundary_face_integs_marker[k])[bdr_attr-1] == 0) { continue; }
boundary_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elemmat);
mat->AddSubMatrix(test_vdofs, trial_vdofs, elemmat, skip_zeros);
}
}
}
}
if (trace_face_integs.Size())
{
FaceElementTransformations *ftr;
@@ -1887,13 +1692,12 @@ void MixedBilinearForm::ConformingAssemble()
}
void MixedBilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
void MixedBilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat)
{
const FiniteElement &trial_fe = *trial_fes->GetFE(i);
const FiniteElement &test_fe = *test_fes->GetFE(i);
if (domain_integs.Size())
{
const FiniteElement &trial_fe = *trial_fes->GetFE(i);
const FiniteElement &test_fe = *test_fes->GetFE(i);
ElementTransformation *eltrans = test_fes->GetElementTransformation(i);
domain_integs[0]->AssembleElementMatrix2(trial_fe, test_fe, *eltrans,
elmat);
@@ -1906,21 +1710,19 @@ void MixedBilinearForm::ComputeElementMatrix(int i, DenseMatrix &elmat) const
}
else
{
const int tr_dofs = trial_fe.GetDof() * trial_fes->GetVDim();
const int te_dofs = test_fe.GetDof() * test_fes->GetVDim();
elmat.SetSize(te_dofs, tr_dofs);
trial_fes->GetElementVDofs(i, trial_vdofs);
test_fes->GetElementVDofs(i, test_vdofs);
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
elmat = 0.0;
}
}
void MixedBilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
void MixedBilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat)
{
const FiniteElement &trial_be = *trial_fes->GetBE(i);
const FiniteElement &test_be = *test_fes->GetBE(i);
if (boundary_integs.Size())
{
const FiniteElement &trial_be = *trial_fes->GetBE(i);
const FiniteElement &test_be = *test_fes->GetBE(i);
ElementTransformation *eltrans = test_fes->GetBdrElementTransformation(i);
boundary_integs[0]->AssembleElementMatrix2(trial_be, test_be, *eltrans,
elmat);
@@ -1933,191 +1735,9 @@ void MixedBilinearForm::ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const
}
else
{
const int tr_dofs = trial_be.GetDof() * trial_fes->GetVDim();
const int te_dofs = test_be.GetDof() * test_fes->GetVDim();
elmat.SetSize(te_dofs, tr_dofs);
elmat = 0.0;
}
}
void MixedBilinearForm::ComputeFaceMatrix(int i, DenseMatrix &elmat) const
{
FaceElementTransformations *ftr;
Mesh *mesh = test_fes -> GetMesh();
ftr = mesh->GetFaceElementTransformations(i);
MFEM_ASSERT(ftr, "No associated face transformations.");
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
if (ftr->Elem2No >= 0)
{
trial_fe2 = trial_fes->GetFE(ftr->Elem2No);
test_fe2 = test_fes->GetFE(ftr->Elem2No);
}
else
{
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
trial_fe2 = trial_fe1;
test_fe2 = test_fe1;
}
if (interior_face_integs.Size())
{
interior_face_integs[0]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elmat);
for (int k = 1; k < interior_face_integs.Size(); k++)
{
interior_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elemmat);
elmat += elemmat;
}
}
else
{
int tr_dofs = trial_fe1->GetDof() * trial_fes->GetVDim();
int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
if (ftr->Elem2No >= 0)
{
tr_dofs += trial_fe2->GetDof() * trial_fes->GetVDim();
te_dofs += test_fe2->GetDof() * test_fes->GetVDim();
}
elmat.SetSize(te_dofs, tr_dofs);
elmat = 0.0;
}
}
void MixedBilinearForm::ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const
{
FaceElementTransformations *ftr;
Mesh *mesh = test_fes -> GetMesh();
ftr = mesh->GetBdrFaceTransformations(i);
MFEM_ASSERT(ftr, "No associated boundary face.");
const FiniteElement *trial_fe1, *trial_fe2, *test_fe1, *test_fe2;
trial_fe1 = trial_fes->GetFE(ftr->Elem1No);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
trial_fe2 = trial_fe1;
test_fe2 = test_fe1;
if (boundary_face_integs.Size())
{
boundary_face_integs[0]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elmat);
for (int k = 1; k < boundary_face_integs.Size(); k++)
{
boundary_face_integs[k]->AssembleFaceMatrix(*trial_fe1, *test_fe1, *trial_fe2,
*test_fe2,
*ftr, elemmat);
elmat += elemmat;
}
}
else
{
const int tr_dofs = trial_fe1->GetDof() * trial_fes->GetVDim();
const int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
elmat.SetSize(te_dofs, tr_dofs);
elmat = 0.0;
}
}
void MixedBilinearForm::ComputeTraceFaceMatrix(int i, DenseMatrix &elmat) const
{
FaceElementTransformations *ftr;
Mesh *mesh = test_fes -> GetMesh();
ftr = mesh->GetFaceElementTransformations(i);
MFEM_ASSERT(ftr, "No associated face transformation.");
const FiniteElement *trial_face_fe, *test_fe1, *test_fe2;
trial_face_fe = trial_fes->GetFaceElement(i);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
if (ftr->Elem2No >= 0)
{
test_fe2 = test_fes->GetFE(ftr->Elem2No);
}
else
{
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
test_fe2 = test_fe1;
}
if (trace_face_integs.Size())
{
trace_face_integs[0]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
*ftr, elmat);
for (int k = 1; k < trace_face_integs.Size(); k++)
{
trace_face_integs[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1, *test_fe2,
*ftr, elemmat);
elmat += elemmat;
}
}
else
{
const int tr_face_dofs = trial_face_fe->GetDof() * trial_fes->GetVDim();
int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
if (ftr->Elem2No >= 0)
{
te_dofs += test_fe2->GetDof() * test_fes->GetVDim();
}
elmat.SetSize(te_dofs, tr_face_dofs);
elmat = 0.0;
}
}
void MixedBilinearForm::ComputeBdrTraceFaceMatrix(int i,
DenseMatrix &elmat) const
{
FaceElementTransformations *ftr;
Mesh *mesh = test_fes -> GetMesh();
ftr = mesh->GetBdrFaceTransformations(i);
MFEM_ASSERT(ftr, "No associated boundary face.");
const FiniteElement *trial_face_fe, *test_fe1, *test_fe2;
int iface = mesh->GetBdrElementFaceIndex(i);
trial_face_fe = trial_fes->GetFaceElement(iface);
test_fe1 = test_fes->GetFE(ftr->Elem1No);
// The test_fe2 object is really a dummy and not used on the
// boundaries, but we can't dereference a NULL pointer, and we don't
// want to actually make a fake element.
test_fe2 = test_fe1;
if (boundary_trace_face_integs.Size())
{
boundary_trace_face_integs[0]->AssembleFaceMatrix(*trial_face_fe, *test_fe1,
*test_fe2,
*ftr, elmat);
for (int k = 1; k < boundary_trace_face_integs.Size(); k++)
{
boundary_trace_face_integs[k]->AssembleFaceMatrix(*trial_face_fe, *test_fe1,
*test_fe2,
*ftr, elemmat);
elmat += elemmat;
}
}
else
{
const int tr_face_dofs = trial_face_fe->GetDof() * trial_fes->GetVDim();
int te_dofs = test_fe1->GetDof() * test_fes->GetVDim();
elmat.SetSize(te_dofs, tr_face_dofs);
trial_fes->GetBdrElementVDofs(i, trial_vdofs);
test_fes->GetBdrElementVDofs(i, test_vdofs);
elmat.SetSize(test_vdofs.Size(), trial_vdofs.Size());
elmat = 0.0;
}
}
@@ -2160,59 +1780,36 @@ void MixedBilinearForm::AssembleBdrElementMatrix(
mat->AddSubMatrix(test_vdofs_, trial_vdofs_, elmat, skip_zeros);
}
void MixedBilinearForm::EliminateTrialEssentialBC(
void MixedBilinearForm::EliminateTrialDofs (
const Array<int> &bdr_attr_is_ess, const Vector &sol, Vector &rhs )
{
Array<int> trial_ess_dofs;
trial_fes->GetEssentialVDofs(bdr_attr_is_ess, trial_ess_dofs);
mat->EliminateCols(trial_ess_dofs, &sol, &rhs);
int i, j, k;
Array<int> tr_vdofs, cols_marker (trial_fes -> GetVSize());
cols_marker = 0;
for (i = 0; i < trial_fes -> GetNBE(); i++)
if (bdr_attr_is_ess[trial_fes -> GetBdrAttribute (i)-1])
{
trial_fes -> GetBdrElementVDofs (i, tr_vdofs);
for (j = 0; j < tr_vdofs.Size(); j++)
{
if ( (k = tr_vdofs[j]) < 0 )
{
k = -1-k;
}
cols_marker[k] = 1;
}
}
mat -> EliminateCols (cols_marker, &sol, &rhs);
}
void MixedBilinearForm::EliminateTrialEssentialBC(const Array<int>
&bdr_attr_is_ess)
{
Array<int> trial_ess_dofs;
trial_fes->GetEssentialVDofs(bdr_attr_is_ess, trial_ess_dofs);
mat->EliminateCols(trial_ess_dofs);
}
void MixedBilinearForm::EliminateTrialVDofs(const Array<int> &trial_vdofs_,
const Vector &sol, Vector &rhs)
{
Array<int> trial_vdofs_marker;
FiniteElementSpace::ListToMarker(trial_vdofs_, mat->Width(),
trial_vdofs_marker);
mat->EliminateCols(trial_vdofs_marker, &sol, &rhs);
}
void MixedBilinearForm::EliminateTrialVDofs(const Array<int> &trial_vdofs_)
{
if (mat_e == NULL)
{
mat_e = new SparseMatrix(mat->Height(), mat->Width());
}
Array<int> trial_vdofs_marker;
FiniteElementSpace::ListToMarker(trial_vdofs_, mat->Width(),
trial_vdofs_marker);
mat->EliminateCols(trial_vdofs_marker, *mat_e);
mat_e->Finalize();
}
void MixedBilinearForm::EliminateTrialVDofsInRHS(const Array<int> &trial_vdofs_,
const Vector &x, Vector &b)
{
mat_e->AddMult(x, b, -1.);
}
void MixedBilinearForm::EliminateEssentialBCFromTrialDofs(
void MixedBilinearForm::EliminateEssentialBCFromTrialDofs (
const Array<int> &marked_vdofs, const Vector &sol, Vector &rhs)
{
mat->EliminateCols(marked_vdofs, &sol, &rhs);
mat -> EliminateCols (marked_vdofs, &sol, &rhs);
}
void MixedBilinearForm::EliminateTestEssentialBC(const Array<int>
&bdr_attr_is_ess)
void MixedBilinearForm::EliminateTestDofs (const Array<int> &bdr_attr_is_ess)
{
int i, j, k;
Array<int> te_vdofs;
@@ -2232,14 +1829,6 @@ void MixedBilinearForm::EliminateTestEssentialBC(const Array<int>
}
}
void MixedBilinearForm::EliminateTestVDofs(const Array<int> &test_vdofs_)
{
for (int i=0; i<test_vdofs_.Size(); ++i)
{
mat->EliminateRow(test_vdofs_[i]);
}
}
void MixedBilinearForm::FormRectangularSystemMatrix(
const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
@@ -2276,9 +1865,20 @@ void MixedBilinearForm::FormRectangularSystemMatrix(
mat = m;
}
EliminateTrialVDofs(trial_tdof_list);
EliminateTestVDofs(test_tdof_list);
Array<int> ess_trial_tdof_marker, ess_test_tdof_marker;
FiniteElementSpace::ListToMarker(trial_tdof_list, trial_fes->GetTrueVSize(),
ess_trial_tdof_marker);
FiniteElementSpace::ListToMarker(test_tdof_list, test_fes->GetTrueVSize(),
ess_test_tdof_marker);
mat_e = new SparseMatrix(mat->Height(), mat->Width());
mat->EliminateCols(ess_trial_tdof_marker, *mat_e);
for (int i=0; i<test_tdof_list.Size(); ++i)
{
mat->EliminateRow(test_tdof_list[i]);
}
mat_e->Finalize();
A.Reset(mat, false);
}
@@ -2307,7 +1907,7 @@ void MixedBilinearForm::FormRectangularLinearSystem(
A); // Set A = mat_e
}
// Eliminate essential BCs with B -= Ab xb
EliminateTrialVDofsInRHS(trial_tdof_list, X, B);
mat_e->AddMult(X, B, -1.0);
B.SetSubVector(test_tdof_list, 0.0);
}
@@ -2333,10 +1933,6 @@ MixedBilinearForm::~MixedBilinearForm()
for (i = 0; i < domain_integs.Size(); i++) { delete domain_integs[i]; }
for (i = 0; i < boundary_integs.Size(); i++)
{ delete boundary_integs[i]; }
for (i = 0; i < interior_face_integs.Size(); i++)
{ delete interior_face_integs[i]; }
for (i = 0; i < boundary_face_integs.Size(); i++)
{ delete boundary_face_integs[i]; }
for (i = 0; i < trace_face_integs.Size(); i++)
{ delete trace_face_integs[i]; }
for (i = 0; i < boundary_trace_face_integs.Size(); i++)
+53 -164
View File
@@ -119,8 +119,8 @@ protected:
Array<BilinearFormIntegrator*> boundary_face_integs;
Array<Array<int>*> boundary_face_integs_marker; ///< Entries are not owned.
mutable DenseMatrix elemmat;
mutable Array<int> vdofs;
DenseMatrix elemmat;
Array<int> vdofs;
DenseTensor *element_matrices; ///< Owned.
@@ -294,13 +294,13 @@ public:
const real_t &operator()(int i, int j) { return (*mat)(i,j); }
/// Returns a reference to: $ M_{ij} $
real_t &Elem(int i, int j) override;
virtual real_t &Elem(int i, int j);
/// Returns constant reference to: $ M_{ij} $
const real_t &Elem(int i, int j) const override;
virtual const real_t &Elem(int i, int j) const;
/// Matrix vector multiplication: $ y = M x $
void Mult(const Vector &x, Vector &y) const override;
virtual void Mult(const Vector &x, Vector &y) const;
/** @brief Matrix vector multiplication with the original uneliminated
matrix. The original matrix is $ M + M_e $ so we have:
@@ -309,7 +309,7 @@ public:
{ mat->Mult(x, y); mat_e->AddMult(x, y); }
/// Add the matrix vector multiple to a vector: $ y += a M x $
void AddMult(const Vector &x, Vector &y, const real_t a = 1.0) const override
virtual void AddMult(const Vector &x, Vector &y, const real_t a = 1.0) const
{ mat -> AddMult (x, y, a); }
/** @brief Add the original uneliminated matrix vector multiple to a vector.
@@ -319,8 +319,8 @@ public:
{ mat->AddMult(x, y); mat_e->AddMult(x, y); }
/// Add the matrix transpose vector multiplication: $ y += a M^T x $
void AddMultTranspose(const Vector & x, Vector & y,
const real_t a = 1.0) const override
virtual void AddMultTranspose(const Vector & x, Vector & y,
const real_t a = 1.0) const
{ mat->AddMultTranspose(x, y, a); }
/** @brief Add the original uneliminated matrix transpose vector
@@ -330,7 +330,7 @@ public:
{ mat->AddMultTranspose(x, y); mat_e->AddMultTranspose(x, y); }
/// Matrix transpose vector multiplication: $ y = M^T x $
void MultTranspose(const Vector & x, Vector & y) const override;
virtual void MultTranspose(const Vector & x, Vector & y) const;
/// Compute $ y^T M x $
real_t InnerProduct(const Vector &x, const Vector &y) const
@@ -338,13 +338,13 @@ public:
/** @brief Returns a pointer to (approximation) of the matrix inverse:
$ M^{-1} $ (currently returns NULL) */
MatrixInverse *Inverse() const override;
virtual MatrixInverse *Inverse() const;
/** @brief Finalizes the matrix initialization if the ::AssemblyLevel is
AssemblyLevel::LEGACY.
The matrix that gets finalized is different if you are using static
condensation or hybridization.*/
void Finalize(int skip_zeros = 1) override;
virtual void Finalize(int skip_zeros = 1);
/** @brief Returns a const reference to the sparse matrix: $ M $
*
@@ -458,18 +458,18 @@ public:
conforming prolongation, and |.| denotes the entry-wise absolute value.
In general, this is just an approximation of the exact diagonal for this
case. */
void AssembleDiagonal(Vector &diag) const override;
virtual void AssembleDiagonal(Vector &diag) const;
/// Get the finite element space prolongation operator.
const Operator *GetProlongation() const override
virtual const Operator *GetProlongation() const
{ return fes->GetConformingProlongation(); }
/// Get the finite element space restriction operator
const Operator *GetRestriction() const override
virtual const Operator *GetRestriction() const
{ return fes->GetConformingRestriction(); }
/// Get the output finite element space prolongation matrix
const Operator *GetOutputProlongation() const override
virtual const Operator *GetOutputProlongation() const
{ return GetProlongation(); }
/** @brief Returns the output fe space restriction matrix, transposed
@@ -477,11 +477,11 @@ public:
Logically, this is the transpose of GetOutputRestriction, but in
practice it is convenient to have it in transposed form for
construction of RAP operators in matrix-free methods. */
const Operator *GetOutputRestrictionTranspose() const override
virtual const Operator *GetOutputRestrictionTranspose() const
{ return fes->GetRestrictionTransposeOperator(); }
/// Get the output finite element space restriction matrix
const Operator *GetOutputRestriction() const override
virtual const Operator *GetOutputRestriction() const
{ return GetRestriction(); }
/// Compute serial RAP operator and store it in @a A as a SparseMatrix.
@@ -566,8 +566,7 @@ public:
FormLinearSystem() method to recover the solution as a GridFunction-size
vector in @a x. Use the same arguments as in the FormLinearSystem() call.
*/
void RecoverFEMSolution(const Vector &X, const Vector &b,
Vector &x) override;
virtual void RecoverFEMSolution(const Vector &X, const Vector &b, Vector &x);
/// Compute and store internally all element matrices.
void ComputeElementMatrices();
@@ -581,18 +580,10 @@ public:
or the one stored internally by a prior call of ComputeElementMatrices()
is returned when available.
*/
void ComputeElementMatrix(int i, DenseMatrix &elmat) const;
void ComputeElementMatrix(int i, DenseMatrix &elmat);
/// Compute the boundary element matrix of the given boundary element
/** @note The boundary attribute markers of the integrators are ignored. */
void ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const;
/// Compute the face matrix of the given face element
void ComputeFaceMatrix(int i, DenseMatrix &elmat) const;
/// Compute the boundary face matrix of the given boundary element
/** @note The boundary attribute markers of the integrators are ignored. */
void ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const;
void ComputeBdrElementMatrix(int i, DenseMatrix &elmat);
/// Assemble the given element matrix
/** The element matrix @a elmat is assembled for the element @a i, i.e.
@@ -772,14 +763,6 @@ protected:
/// Entries are not owned.
Array<Array<int>*> boundary_integs_marker;
/// Interior face integrators.
Array<BilinearFormIntegrator*> interior_face_integs;
/// Boundary face integrators.
Array<BilinearFormIntegrator*> boundary_face_integs;
/// Entries are not owned.
Array<Array<int>*> boundary_face_integs_marker;
/// Trace face (skeleton) integrators.
Array<BilinearFormIntegrator*> trace_face_integs;
@@ -788,8 +771,8 @@ protected:
/// Entries are not owned.
Array<Array<int>*> boundary_trace_face_integs_marker;
mutable DenseMatrix elemmat;
mutable Array<int> trial_vdofs, test_vdofs;
DenseMatrix elemmat;
Array<int> trial_vdofs, test_vdofs;
private:
/// Copy construction is not supported; body is undefined.
@@ -820,32 +803,32 @@ public:
MixedBilinearForm *mbf);
/// Returns a reference to: $ M_{ij} $
real_t &Elem(int i, int j) override;
virtual real_t &Elem(int i, int j);
/// Returns a reference to: $ M_{ij} $
const real_t &Elem(int i, int j) const override;
virtual const real_t &Elem(int i, int j) const;
/// Matrix multiplication: $ y = M x $
void Mult(const Vector & x, Vector & y) const override;
virtual void Mult(const Vector & x, Vector & y) const;
/// Add the matrix vector multiple to a vector: $ y += a M x $
void AddMult(const Vector & x, Vector & y,
const real_t a = 1.0) const override;
virtual void AddMult(const Vector & x, Vector & y,
const real_t a = 1.0) const;
/// Matrix transpose vector multiplication: $ y = M^T x $
void MultTranspose(const Vector & x, Vector & y) const override;
virtual void MultTranspose(const Vector & x, Vector & y) const;
/// Add the matrix transpose vector multiplication: $ y += a M^T x $
void AddMultTranspose(const Vector & x, Vector & y,
const real_t a = 1.0) const override;
virtual void AddMultTranspose(const Vector & x, Vector & y,
const real_t a = 1.0) const;
/** @brief Returns a pointer to (approximation) of the matrix inverse:
$ M^{-1} $ (currently unimplemented and returns NULL)*/
MatrixInverse *Inverse() const override;
virtual MatrixInverse *Inverse() const;
/** @brief Finalizes the matrix initialization if the ::AssemblyLevel is
AssemblyLevel::LEGACY.*/
void Finalize(int skip_zeros = 1) override;
virtual void Finalize(int skip_zeros = 1);
/** @brief Extract the associated matrix as SparseMatrix blocks. The number
of block rows and columns is given by the vector dimensions (vdim) of the
@@ -856,37 +839,15 @@ public:
/** This will segfault if the usual sparse mat is not defined
like when static condensation is being used or AllocMat() has
not yet been called. */
const SparseMatrix &SpMat() const
{
MFEM_VERIFY(mat, "mat is NULL and can't be dereferenced");
return *mat;
}
const SparseMatrix &SpMat() const { return *mat; }
/// Returns a reference to the sparse matrix: $ M $
SparseMatrix &SpMat()
{
MFEM_VERIFY(mat, "mat is NULL and can't be dereferenced");
return *mat;
}
SparseMatrix &SpMat() { return *mat; }
/** @brief Nullifies the internal matrix $ M $ and returns a pointer
to it. Used for transferring ownership. */
SparseMatrix *LoseMat() { SparseMatrix *tmp = mat; mat = NULL; return tmp; }
/// Returns a const reference to the sparse matrix of eliminated b.c.: $ M_e $
const SparseMatrix &SpMatElim() const
{
MFEM_VERIFY(mat_e, "mat_e is NULL and can't be dereferenced");
return *mat_e;
}
/// Returns a reference to the sparse matrix of eliminated b.c.: $ M_e $
SparseMatrix &SpMatElim()
{
MFEM_VERIFY(mat_e, "mat_e is NULL and can't be dereferenced");
return *mat_e;
}
/// Adds a domain integrator. Assumes ownership of @a bfi.
void AddDomainIntegrator(BilinearFormIntegrator *bfi);
@@ -901,16 +862,6 @@ public:
void AddBoundaryIntegrator(BilinearFormIntegrator * bfi,
Array<int> &bdr_marker);
/// Adds an interior face integrator. Assumes ownership of @a bfi.
void AddInteriorFaceIntegrator(BilinearFormIntegrator *bfi);
/// Adds a boundary face integrator. Assumes ownership of @a bfi.
void AddBdrFaceIntegrator(BilinearFormIntegrator *bfi);
/// Adds a boundary face integrator. Assumes ownership of @a bfi.
void AddBdrFaceIntegrator(BilinearFormIntegrator *bfi,
Array<int> &bdr_marker);
/** @brief Add a trace face integrator. Assumes ownership of @a bfi.
This type of integrator assembles terms over all faces of the mesh using
@@ -941,16 +892,6 @@ public:
corresponding pointer (to Array<int>) will be NULL. */
Array<Array<int>*> *GetBBFI_Marker() { return &boundary_integs_marker; }
/// Access all integrators added with AddInteriorFaceIntegrator().
Array<BilinearFormIntegrator*> *GetFBFI() { return &interior_face_integs; }
/// Access all integrators added with AddBdrFaceIntegrator().
Array<BilinearFormIntegrator*> *GetBFBFI() { return &boundary_face_integs; }
/** @brief Access all boundary markers added with AddBdrFaceIntegrator().
If no marker was specified when the integrator was added, the
corresponding pointer (to Array<int>) will be NULL. */
Array<Array<int>*> *GetBFBFI_Marker() { return &boundary_face_integs_marker; }
/// Access all integrators added with AddTraceFaceIntegrator().
Array<BilinearFormIntegrator*> *GetTFBFI() { return &trace_face_integs; }
@@ -979,19 +920,19 @@ public:
void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const;
/// Get the input finite element space prolongation matrix
const Operator *GetProlongation() const override
virtual const Operator *GetProlongation() const
{ return trial_fes->GetProlongationMatrix(); }
/// Get the input finite element space restriction matrix
const Operator *GetRestriction() const override
virtual const Operator *GetRestriction() const
{ return trial_fes->GetRestrictionMatrix(); }
/// Get the test finite element space prolongation matrix
const Operator *GetOutputProlongation() const override
virtual const Operator *GetOutputProlongation() const
{ return test_fes->GetProlongationMatrix(); }
/// Get the test finite element space restriction matrix
const Operator *GetOutputRestriction() const override
virtual const Operator *GetOutputRestriction() const
{ return test_fes->GetRestrictionMatrix(); }
/** @brief For partially conforming trial and/or test FE spaces, complete the
@@ -1003,25 +944,10 @@ public:
void ConformingAssemble();
/// Compute the element matrix of the given element
void ComputeElementMatrix(int i, DenseMatrix &elmat) const;
void ComputeElementMatrix(int i, DenseMatrix &elmat);
/// Compute the boundary element matrix of the given boundary element
/** @note The boundary attribute markers of the integrators are ignored. */
void ComputeBdrElementMatrix(int i, DenseMatrix &elmat) const;
/// Compute the trace face matrix of the given face element
void ComputeTraceFaceMatrix(int i, DenseMatrix &elmat) const;
/// Compute the boundary trace face matrix of the given boundary element
/** @note The boundary attribute markers of the integrators are ignored. */
void ComputeBdrTraceFaceMatrix(int i, DenseMatrix &elmat) const;
/// Compute the face matrix of the given face element
void ComputeFaceMatrix(int i, DenseMatrix &elmat) const;
/// Compute the boundary face matrix of the given boundary element
/** @note The boundary attribute markers of the integrators are ignored. */
void ComputeBdrFaceMatrix(int i, DenseMatrix &elmat) const;
void ComputeBdrElementMatrix(int i, DenseMatrix &elmat);
/// Assemble the given element matrix
/** The element matrix @a elmat is assembled for the element @a i, i.e.
@@ -1063,61 +989,24 @@ public:
Array<int> &test_vdofs,
int skip_zeros = 1);
/// Eliminate essential boundary trial DOFs from the system.
/// Eliminate essential boundary DOFs from the columns of the system.
/** The array @a bdr_attr_is_ess marks boundary attributes that constitute
the essential part of the boundary. */
void EliminateTrialEssentialBC(const Array<int> &bdr_attr_is_ess,
const Vector &sol, Vector &rhs);
the essential part of the boundary. All entries in the columns will be
set to 0.0 through elimination.*/
void EliminateTrialDofs(const Array<int> &bdr_attr_is_ess,
const Vector &sol, Vector &rhs);
/// Eliminate essential boundary trial DOFs from the system matrix.
/** The array @a bdr_attr_is_ess marks boundary attributes that constitute
the essential part of the boundary. */
void EliminateTrialEssentialBC(const Array<int> &bdr_attr_is_ess);
/// (DEPRECATED) Eliminate essential boundary trial DOFs from the system.
/** @see EliminateTrialEssentialBC() */
MFEM_DEPRECATED void EliminateTrialDofs(const Array<int> &bdr_attr_is_ess,
const Vector &sol, Vector &rhs)
{ EliminateTrialEssentialBC(bdr_attr_is_ess, sol, rhs); }
/// Eliminate the given trial @a vdofs. NOTE: here, @a vdofs is a list of DOFs.
/** In this case the eliminations are applied to the internal $ M $
and @a rhs without storing the elimination matrix $ M_e $. */
void EliminateTrialVDofs(const Array<int> &vdofs, const Vector &sol,
Vector &rhs);
/// Eliminate the given trial @a vdofs, storing the eliminated part internally in $ M_e $.
/** This method works in conjunction with EliminateTrialVDofsInRHS() and allows
elimination of boundary conditions in multiple right-hand sides. In this
method, @a vdofs is a list of DOFs. */
void EliminateTrialVDofs(const Array<int> &vdofs);
/** @brief Use the stored eliminated part of the matrix (see
EliminateTrialVDofs(const Array<int> &)) to modify the r.h.s.
@a b; @a vdofs is a list of DOFs (non-directional, i.e. >= 0). */
void EliminateTrialVDofsInRHS(const Array<int> &vdofs, const Vector &x,
Vector &b);
/** @brief Similar to
EliminateTrialVDofs(const Array<int> &, const Vector &, Vector &)
but here @a ess_dofs is a marker (boolean) array on all vector-dofs
(@a ess_dofs[i] < 0 is true). */
/// Eliminate the list of DOFs from the columns of the system.
/** @a marked_vdofs is the of colunm numbers that will be eliminated. All
entries in the columns will be set to 0.0 through elimination.*/
void EliminateEssentialBCFromTrialDofs(const Array<int> &marked_vdofs,
const Vector &sol, Vector &rhs);
/// Eliminate essential boundary test DOFs from the system matrix.
/// Eliminate essential boundary DOFs from the rows of the system.
/** The array @a bdr_attr_is_ess marks boundary attributes that constitute
the essential part of the boundary. */
void EliminateTestEssentialBC(const Array<int> &bdr_attr_is_ess);
/// (DEPRECATED) Eliminate essential boundary test DOFs from the system.
/** @see EliminateTestEssentialBC() */
MFEM_DEPRECATED virtual void EliminateTestDofs(const Array<int>
&bdr_attr_is_ess)
{ EliminateTestEssentialBC(bdr_attr_is_ess); }
/// Eliminate the given test @a vdofs. NOTE: here, @a vdofs is a list of DOFs.
void EliminateTestVDofs(const Array<int> &vdofs);
the essential part of the boundary. All entries in the rows will be
set to 0.0 through elimination.*/
virtual void EliminateTestDofs(const Array<int> &bdr_attr_is_ess);
/** @brief Return in @a A that is column-constrained.
@@ -1273,7 +1162,7 @@ public:
/** @brief Get the output finite element space restriction matrix in
transposed form. */
const Operator *GetOutputRestrictionTranspose() const override
virtual const Operator *GetOutputRestrictionTranspose() const
{ return test_fes->GetRestrictionTransposeOperator(); }
};
+45 -50
View File
@@ -37,19 +37,19 @@ protected:
public:
BilinearFormExtension(BilinearForm *form);
MemoryClass GetMemoryClass() const override
virtual MemoryClass GetMemoryClass() const
{ return Device::GetDeviceMemoryClass(); }
/// Get the finite element space prolongation matrix
const Operator *GetProlongation() const override;
virtual const Operator *GetProlongation() const;
/// Get the finite element space restriction matrix
const Operator *GetRestriction() const override;
virtual const Operator *GetRestriction() const;
/// Assemble at the level given for the BilinearFormExtension subclass
virtual void Assemble() = 0;
void AssembleDiagonal(Vector &diag) const override
virtual void AssembleDiagonal(Vector &diag) const
{
MFEM_ABORT("AssembleDiagonal not implemented for this assembly level!");
}
@@ -83,17 +83,16 @@ protected:
public:
PABilinearFormExtension(BilinearForm*);
void Assemble() override;
void AssembleDiagonal(Vector &diag) const override;
void FormSystemMatrix(const Array<int> &ess_tdof_list,
OperatorHandle &A) override;
void Assemble();
void AssembleDiagonal(Vector &diag) const;
void FormSystemMatrix(const Array<int> &ess_tdof_list, OperatorHandle &A);
void FormLinearSystem(const Array<int> &ess_tdof_list,
Vector &x, Vector &b,
OperatorHandle &A, Vector &X, Vector &B,
int copy_interior = 0) override;
void Mult(const Vector &x, Vector &y) const override;
void MultTranspose(const Vector &x, Vector &y) const override;
void Update() override;
int copy_interior = 0);
void Mult(const Vector &x, Vector &y) const;
void MultTranspose(const Vector &x, Vector &y) const;
void Update();
protected:
void SetupRestrictionOperators(const L2FaceValues m);
@@ -151,9 +150,9 @@ protected:
public:
EABilinearFormExtension(BilinearForm *form);
void Assemble() override;
void Mult(const Vector &x, Vector &y) const override;
void MultTranspose(const Vector &x, Vector &y) const override;
void Assemble();
void Mult(const Vector &x, Vector &y) const;
void MultTranspose(const Vector &x, Vector &y) const;
};
/// Data and methods for fully-assembled bilinear forms
@@ -166,19 +165,18 @@ private:
public:
FABilinearFormExtension(BilinearForm *form);
void Assemble() override;
void Assemble();
void RAP(OperatorHandle &A);
/** @note Always does `DIAG_ONE` policy to be consistent with
`Operator::FormConstrainedSystemOperator`. */
void EliminateBC(const Array<int> &ess_dofs, OperatorHandle &A);
void FormSystemMatrix(const Array<int> &ess_tdof_list,
OperatorHandle &A) override;
void FormSystemMatrix(const Array<int> &ess_tdof_list, OperatorHandle &A);
void FormLinearSystem(const Array<int> &ess_tdof_list,
Vector &x, Vector &b,
OperatorHandle &A, Vector &X, Vector &B,
int copy_interior = 0) override;
void Mult(const Vector &x, Vector &y) const override;
void MultTranspose(const Vector &x, Vector &y) const override;
int copy_interior = 0);
void Mult(const Vector &x, Vector &y) const;
void MultTranspose(const Vector &x, Vector &y) const;
/** DGMult and DGMultTranspose use the extended L-vector to perform the
computation. */
@@ -201,17 +199,16 @@ protected:
public:
MFBilinearFormExtension(BilinearForm *form);
void Assemble() override;
void AssembleDiagonal(Vector &diag) const override;
void FormSystemMatrix(const Array<int> &ess_tdof_list,
OperatorHandle &A) override;
void Assemble();
void AssembleDiagonal(Vector &diag) const;
void FormSystemMatrix(const Array<int> &ess_tdof_list, OperatorHandle &A);
void FormLinearSystem(const Array<int> &ess_tdof_list,
Vector &x, Vector &b,
OperatorHandle &A, Vector &X, Vector &B,
int copy_interior = 0) override;
void Mult(const Vector &x, Vector &y) const override;
void MultTranspose(const Vector &x, Vector &y) const override;
void Update() override;
int copy_interior = 0);
void Mult(const Vector &x, Vector &y) const;
void MultTranspose(const Vector &x, Vector &y) const;
void Update();
};
/// Class extending the MixedBilinearForm class to support different AssemblyLevels.
@@ -228,20 +225,20 @@ protected:
public:
MixedBilinearFormExtension(MixedBilinearForm *form);
MemoryClass GetMemoryClass() const override
virtual MemoryClass GetMemoryClass() const
{ return Device::GetMemoryClass(); }
/// Get the finite element space prolongation matrix
const Operator *GetProlongation() const override;
virtual const Operator *GetProlongation() const;
/// Get the finite element space restriction matrix
const Operator *GetRestriction() const override;
virtual const Operator *GetRestriction() const;
/// Get the output finite element space restriction matrix
const Operator *GetOutputProlongation() const override;
virtual const Operator *GetOutputProlongation() const;
/// Get the output finite element space restriction matrix
const Operator *GetOutputRestriction() const override;
virtual const Operator *GetOutputRestriction() const;
virtual void Assemble() = 0;
virtual void FormRectangularSystemOperator(const Array<int> &trial_tdof_list,
@@ -276,7 +273,7 @@ public:
PAMixedBilinearFormExtension(MixedBilinearForm *form);
/// Partial assembly of all internal integrators
void Assemble() override;
void Assemble();
/**
@brief Setup OperatorHandle A to contain constrained linear operator
@@ -286,7 +283,7 @@ public:
*/
void FormRectangularSystemOperator(const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
OperatorHandle &A) override;
OperatorHandle &A);
/**
Setup OperatorHandle A to contain constrained linear operator and
eliminate columns corresponding to essential dofs from system,
@@ -295,21 +292,20 @@ public:
void FormRectangularLinearSystem(const Array<int> &trial_tdof_list,
const Array<int> &test_tdof_list,
Vector &x, Vector &b,
OperatorHandle &A, Vector &X, Vector &B) override;
OperatorHandle &A, Vector &X, Vector &B);
/// y = A*x
void Mult(const Vector &x, Vector &y) const override;
void Mult(const Vector &x, Vector &y) const;
/// y += c*A*x
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const override;
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const;
/// y = A^T*x
void MultTranspose(const Vector &x, Vector &y) const override;
void MultTranspose(const Vector &x, Vector &y) const;
/// y += c*A^T*x
void AddMultTranspose(const Vector &x, Vector &y,
const real_t c=1.0) const override;
void AddMultTranspose(const Vector &x, Vector &y, const real_t c=1.0) const;
/// Assemble the diagonal of ADA^T for a diagonal vector D.
void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const override;
void AssembleDiagonal_ADAt(const Vector &D, Vector &diag) const;
/// Update internals for when a new MixedBilinearForm is given to this class
void Update() override;
void Update();
};
@@ -326,17 +322,16 @@ public:
PADiscreteLinearOperatorExtension(DiscreteLinearOperator *linop);
/// Partial assembly of all internal integrators
void Assemble() override;
void Assemble();
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const override;
void AddMult(const Vector &x, Vector &y, const real_t c=1.0) const;
void AddMultTranspose(const Vector &x, Vector &y,
const real_t c=1.0) const override;
void AddMultTranspose(const Vector &x, Vector &y, const real_t c=1.0) const;
void FormRectangularSystemOperator(const Array<int>&, const Array<int>&,
OperatorHandle& A) override;
OperatorHandle& A);
const Operator * GetOutputRestrictionTranspose() const override;
const Operator * GetOutputRestrictionTranspose() const;
private:
Vector test_multiplicity;
+45 -285
View File
@@ -170,16 +170,6 @@ void BilinearFormIntegrator::AssembleFaceMatrix(
" is not implemented for this class.");
}
void BilinearFormIntegrator::AssembleFaceMatrix(
const FiniteElement &trial_fe1, const FiniteElement &test_fe1,
const FiniteElement &trial_fe2, const FiniteElement &test_fe2,
FaceElementTransformations &Trans,
DenseMatrix &elmat)
{
MFEM_ABORT("AssembleFaceMatrix (mixed form) is not implemented for this"
" Integrator class.");
}
void BilinearFormIntegrator::AssembleFaceMatrix(
const FiniteElement &trial_face_fe, const FiniteElement &test_fe1,
const FiniteElement &test_fe2, FaceElementTransformations &Trans,
@@ -233,38 +223,28 @@ void TransposeIntegrator::SetIntRule(const IntegrationRule *ir)
bfi->SetIntRule(ir);
}
void TransposeIntegrator::AssembleElementMatrix(
void TransposeIntegrator::AssembleElementMatrix (
const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
{
bfi->AssembleElementMatrix(el, Trans, bfi_elmat);
bfi -> AssembleElementMatrix (el, Trans, bfi_elmat);
// elmat = bfi_elmat^t
elmat.Transpose (bfi_elmat);
}
void TransposeIntegrator::AssembleElementMatrix2(
void TransposeIntegrator::AssembleElementMatrix2 (
const FiniteElement &trial_fe, const FiniteElement &test_fe,
ElementTransformation &Trans, DenseMatrix &elmat)
{
bfi->AssembleElementMatrix2(test_fe, trial_fe, Trans, bfi_elmat);
bfi -> AssembleElementMatrix2 (test_fe, trial_fe, Trans, bfi_elmat);
// elmat = bfi_elmat^t
elmat.Transpose (bfi_elmat);
}
void TransposeIntegrator::AssembleFaceMatrix(
void TransposeIntegrator::AssembleFaceMatrix (
const FiniteElement &el1, const FiniteElement &el2,
FaceElementTransformations &Trans, DenseMatrix &elmat)
{
bfi->AssembleFaceMatrix(el1, el2, Trans, bfi_elmat);
// elmat = bfi_elmat^t
elmat.Transpose (bfi_elmat);
}
void TransposeIntegrator::AssembleFaceMatrix(
const FiniteElement &tr_el1, const FiniteElement &te_el1,
const FiniteElement &tr_el2, const FiniteElement &te_el2,
FaceElementTransformations &Trans, DenseMatrix &elmat)
{
bfi->AssembleFaceMatrix(te_el1, tr_el1, te_el2, tr_el2, Trans, bfi_elmat);
bfi -> AssembleFaceMatrix (el1, el2, Trans, bfi_elmat);
// elmat = bfi_elmat^t
elmat.Transpose (bfi_elmat);
}
@@ -1242,8 +1222,7 @@ real_t DiffusionIntegrator::ComputeFluxEnergy
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
Trans.SetIntPoint(&ip);
fluxelem.CalcPhysShape(Trans, shape);
fluxelem.CalcShape(ip, shape);
pointflux = 0.0;
for (int k = 0; k < spaceDim; k++)
@@ -1254,6 +1233,7 @@ real_t DiffusionIntegrator::ComputeFluxEnergy
}
}
Trans.SetIntPoint(&ip);
real_t w = Trans.Weight() * ip.weight;
if (MQ)
@@ -1430,7 +1410,9 @@ void BoundaryMassIntegrator::AssembleFaceMatrix(
// Set the integration point in the face and the neighboring element
Trans.SetAllIntPoints(&ip);
el1.CalcPhysShape(*Trans.Elem1, shape);
// Access the neighboring element's integration point
const IntegrationPoint &eip = Trans.GetElement1IntPoint();
el1.CalcShape(eip, shape);
w = Trans.Weight() * ip.weight;
if (Q)
@@ -1600,9 +1582,9 @@ void VectorMassIntegrator::AssembleElementMatrix
for (int s = 0; s < ir->GetNPoints(); s++)
{
const IntegrationPoint &ip = ir->IntPoint(s);
Trans.SetIntPoint (&ip);
el.CalcPhysShape(Trans, shape);
el.CalcShape(ip, shape);
Trans.SetIntPoint (&ip);
norm = ip.weight * Trans.Weight();
MultVVt(shape, partelmat);
@@ -1684,10 +1666,10 @@ void VectorMassIntegrator::AssembleElementMatrix2(
for (int s = 0; s < ir->GetNPoints(); s++)
{
const IntegrationPoint &ip = ir->IntPoint(s);
Trans.SetIntPoint(&ip);
trial_fe.CalcPhysShape(Trans, shape);
test_fe.CalcPhysShape(Trans, te_shape);
trial_fe.CalcShape(ip, shape);
test_fe.CalcShape(ip, te_shape);
Trans.SetIntPoint(&ip);
norm = ip.weight * Trans.Weight();
MultVWt(te_shape, shape, partelmat);
@@ -1915,12 +1897,12 @@ void VectorFECurlIntegrator::AssembleElementMatrix2(
if ( trial_fe.GetMapType() == mfem::FiniteElement::H_CURL )
{
trial_fe.CalcCurlShape(ip, curlshapeTrial_dFT);
test_fe.CalcPhysShape(Trans, shapeTest);
test_fe.CalcShape(ip, shapeTest);
}
else
{
test_fe.CalcCurlShape(ip, curlshapeTrial_dFT);
trial_fe.CalcPhysShape(Trans, shapeTest);
trial_fe.CalcShape(ip, shapeTest);
}
}
@@ -1943,89 +1925,6 @@ void VectorFECurlIntegrator::AssembleElementMatrix2(
}
}
void VectorFEBoundaryFluxIntegrator::AssembleElementMatrix(
const FiniteElement &el, ElementTransformation &Tr,
DenseMatrix &elmat)
{
int nd = el.GetDof();
real_t w;
#ifdef MFEM_THREAD_SAFE
Vector shape;
#endif
elmat.SetSize(nd);
shape.SetSize(nd);
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
int intorder = 2*el.GetOrder() + Tr.OrderW(); // <----------
ir = &IntRules.Get(el.GetGeomType(), intorder);
}
elmat = 0.0;
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
el.CalcShape(ip, shape);
Tr.SetIntPoint (&ip);
w = ip.weight / Tr.Weight();
if (Q)
{
w *= Q->Eval(Tr, ip);
}
AddMult_a_VVt(w, shape, elmat);
}
}
void VectorFEBoundaryFluxIntegrator::AssembleElementMatrix2(
const FiniteElement &trial_fe,
const FiniteElement &test_fe,
ElementTransformation &Tr,
DenseMatrix &elmat)
{
int tr_nd = trial_fe.GetDof();
int te_nd = test_fe.GetDof();
real_t w;
#ifdef MFEM_THREAD_SAFE
Vector shape, te_shape;
#endif
elmat.SetSize(te_nd, tr_nd);
shape.SetSize(tr_nd);
te_shape.SetSize(te_nd);
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
int order = trial_fe.GetOrder() + test_fe.GetOrder() + Tr.OrderW();
ir = &IntRules.Get(trial_fe.GetGeomType(), order);
}
elmat = 0.0;
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
trial_fe.CalcShape(ip, shape);
test_fe.CalcShape(ip, te_shape);
Tr.SetIntPoint (&ip);
w = ip.weight / Tr.Weight();
if (Q)
{
w *= Q->Eval(Tr, ip);
}
te_shape *= w;
AddMultVWt(te_shape, shape, elmat);
}
}
void DerivativeIntegrator::AssembleElementMatrix2 (
const FiniteElement &trial_fe,
const FiniteElement &test_fe,
@@ -2082,7 +1981,7 @@ void DerivativeIntegrator::AssembleElementMatrix2 (
det = Trans.Weight();
Mult (dshape, invdfdx, dshapedxt);
test_fe.CalcPhysShape(Trans, shape);
test_fe.CalcShape(ip, shape);
for (l = 0; l < trial_nd; l++)
{
@@ -2667,7 +2566,7 @@ void VectorFEMassIntegrator::AssembleElementMatrix2(
Trans.SetIntPoint (&ip);
trial_fe.CalcVShape(Trans, trial_vshape);
test_fe.CalcPhysShape(Trans, shape);
test_fe.CalcShape(ip, shape);
w = ip.weight * Trans.Weight();
if (DQ)
@@ -2827,11 +2726,11 @@ void VectorDivergenceIntegrator::AssembleElementMatrix2(
for (int i = 0; i < ir -> GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
Trans.SetIntPoint (&ip);
trial_fe.CalcDShape (ip, dshape);
test_fe.CalcPhysShape (Trans, shape);
test_fe.CalcShape (ip, shape);
Trans.SetIntPoint (&ip);
CalcAdjugate(Trans.Jacobian(), Jadj);
Mult (dshape, Jadj, gshape);
@@ -3332,11 +3231,11 @@ real_t ElasticityIntegrator::ComputeFluxEnergy(const FiniteElement &fluxelem,
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
Trans.SetIntPoint(&ip);
fluxelem.CalcPhysShape(Trans, shape);
fluxelem.CalcShape(ip, shape);
flux_mat.MultTranspose(shape, pointstress);
Trans.SetIntPoint(&ip);
real_t w = Trans.Weight() * ip.weight;
M = mu->Eval(Trans, ip);
@@ -3443,7 +3342,7 @@ void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &el1,
const IntegrationPoint &eip1 = Trans.GetElement1IntPoint();
const IntegrationPoint &eip2 = Trans.GetElement2IntPoint();
el1.CalcPhysShape(*Trans.Elem1, shape1);
el1.CalcShape(eip1, shape1);
u->Eval(vu, *Trans.Elem1, eip1);
@@ -3490,7 +3389,7 @@ void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &el1,
if (ndof2)
{
el2.CalcPhysShape(*Trans.Elem2, shape2);
el2.CalcShape(eip2, shape2);
if (w != 0.0)
for (int i = 0; i < ndof2; i++)
@@ -3518,150 +3417,6 @@ void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &el1,
}
}
void DGTraceIntegrator::AssembleFaceMatrix(const FiniteElement &trial_fe1,
const FiniteElement &test_fe1,
const FiniteElement &trial_fe2,
const FiniteElement &test_fe2,
FaceElementTransformations &Trans,
DenseMatrix &elmat)
{
int tr_ndof1, te_ndof1, tr_ndof2, te_ndof2;
real_t un, a, b, w;
dim = test_fe1.GetDim();
tr_ndof1 = trial_fe1.GetDof();
te_ndof1 = test_fe1.GetDof();
Vector vu(dim), nor(dim);
if (Trans.Elem2No >= 0)
{
tr_ndof2 = trial_fe2.GetDof();
te_ndof2 = test_fe2.GetDof();
}
else
{
tr_ndof2 = 0;
te_ndof2 = 0;
}
tr_shape1.SetSize(tr_ndof1);
te_shape1.SetSize(te_ndof1);
tr_shape2.SetSize(tr_ndof2);
te_shape2.SetSize(te_ndof2);
elmat.SetSize(te_ndof1 + te_ndof2, tr_ndof1 + tr_ndof2);
elmat = 0.0;
const IntegrationRule *ir = IntRule;
if (ir == NULL)
{
int order;
// Assuming order(u)==order(mesh)
if (Trans.Elem2No >= 0)
order = (min(Trans.Elem1->OrderW(), Trans.Elem2->OrderW()) +
max(trial_fe1.GetOrder(), trial_fe2.GetOrder()) +
max(test_fe1.GetOrder(), test_fe2.GetOrder()));
else
{
order = Trans.Elem1->OrderW() + trial_fe1.GetOrder() + test_fe1.GetOrder();
}
if (trial_fe1.Space() == FunctionSpace::Pk)
{
order++;
}
ir = &IntRules.Get(Trans.FaceGeom, order);
}
for (int p = 0; p < ir->GetNPoints(); p++)
{
const IntegrationPoint &ip = ir->IntPoint(p);
IntegrationPoint eip1, eip2;
Trans.Loc1.Transform(ip, eip1);
Trans.Elem1->SetIntPoint(&eip1);
if (tr_ndof2 && te_ndof2)
{
Trans.Loc2.Transform(ip, eip2);
Trans.Elem2->SetIntPoint(&eip2);
}
trial_fe1.CalcPhysShape(*Trans.Elem1, tr_shape1);
test_fe1.CalcPhysShape(*Trans.Elem1, te_shape1);
Trans.Face->SetIntPoint(&ip);
u->Eval(vu, *Trans.Elem1, eip1);
if (dim == 1)
{
nor(0) = 2*eip1.x - 1.0;
}
else
{
CalcOrtho(Trans.Face->Jacobian(), nor);
}
un = vu * nor;
a = 0.5 * alpha * un;
b = beta * fabs(un);
// note: if |alpha/2|==|beta| then |a|==|b|, i.e. (a==b) or (a==-b)
// and therefore two blocks in the element matrix contribution
// (from the current quadrature point) are 0
if (rho)
{
real_t rho_p;
if (un >= 0.0 && tr_ndof2 && te_ndof2)
{
Trans.Elem2->SetIntPoint(&eip2);
rho_p = rho->Eval(*Trans.Elem2, eip2);
}
else
{
rho_p = rho->Eval(*Trans.Elem1, eip1);
}
a *= rho_p;
b *= rho_p;
}
w = ip.weight * (a+b);
if (w != 0.0)
{
for (int i = 0; i < te_ndof1; i++)
for (int j = 0; j < tr_ndof1; j++)
{
elmat(i, j) += w * te_shape1(i) * tr_shape1(j);
}
}
if (tr_ndof2 && te_ndof2)
{
trial_fe2.CalcPhysShape(*Trans.Elem2, tr_shape2);
test_fe2.CalcPhysShape(*Trans.Elem2, te_shape2);
if (w != 0.0)
for (int i = 0; i < te_ndof2; i++)
for (int j = 0; j < tr_ndof1; j++)
{
elmat(te_ndof1+i, j) -= w * te_shape2(i) * tr_shape1(j);
}
w = ip.weight * (b-a);
if (w != 0.0)
{
for (int i = 0; i < te_ndof2; i++)
for (int j = 0; j < tr_ndof2; j++)
{
elmat(te_ndof1+i, tr_ndof1+j) += w * te_shape2(i) * tr_shape2(j);
}
for (int i = 0; i < te_ndof1; i++)
for (int j = 0; j < tr_ndof2; j++)
{
elmat(i, tr_ndof1+j) -= w * te_shape1(i) * tr_shape2(j);
}
}
}
}
}
const IntegrationRule &DGTraceIntegrator::GetRule(
Geometry::Type geom, int order, FaceElementTransformations &T)
@@ -4184,14 +3939,19 @@ void TraceJumpIntegrator::AssembleFaceMatrix(
// Set the integration point in the face and the neighboring elements
Trans.SetAllIntPoints(&ip);
// Access the neighboring elements' integration points
// Note: eip2 will only contain valid data if Elem2 exists
const IntegrationPoint &eip1 = Trans.GetElement1IntPoint();
const IntegrationPoint &eip2 = Trans.GetElement2IntPoint();
// Trace finite element shape function
trial_face_fe.CalcShape(ip, face_shape);
// Side 1 finite element shape function
test_fe1.CalcPhysShape(*Trans.Elem1, shape1);
test_fe1.CalcShape(eip1, shape1);
if (ndof2)
{
// Side 2 finite element shape function
test_fe2.CalcPhysShape(*Trans.Elem2, shape2);
test_fe2.CalcShape(eip2, shape2);
}
w = ip.weight;
if (trial_face_fe.GetMapType() == FiniteElement::VALUE)
@@ -4554,8 +4314,8 @@ struct ShapeCoefficient : public VectorCoefficient
: VectorCoefficient(fe_.GetDof()), Q(q), fe(fe_) { }
using VectorCoefficient::Eval;
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
V.SetSize(vdim);
fe.CalcPhysShape(T, V);
@@ -4597,8 +4357,8 @@ ScalarVectorProductInterpolator::AssembleElementMatrix2(
VShapeCoefficient(Coefficient &q, const FiniteElement &fe_, int sdim)
: MatrixCoefficient(fe_.GetDof(), sdim), Q(q), fe(fe_) { }
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip)
{
M.SetSize(height, width);
fe.CalcPhysVShape(T, M);
@@ -4634,8 +4394,8 @@ VectorScalarProductInterpolator::AssembleElementMatrix2(
: MatrixCoefficient(fe_.GetDof(), vq.GetVDim()), VQ(vq), fe(fe_),
vc(width), shape(height) { }
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip)
{
M.SetSize(height, width);
VQ.Eval(vc, T, ip);
@@ -4674,8 +4434,8 @@ ScalarCrossProductInterpolator::AssembleElementMatrix2(
vshape(vdim, vq.GetVDim()), vc(vq.GetVDim()) { }
using VectorCoefficient::Eval;
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
V.SetSize(vdim);
VQ.Eval(vc, T, ip);
@@ -4718,8 +4478,8 @@ VectorCrossProductInterpolator::AssembleElementMatrix2(
MFEM_ASSERT(width == 3, "");
}
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip)
{
M.SetSize(height, width);
VQ.Eval(vc, T, ip);
@@ -4767,8 +4527,8 @@ struct VDotVShapeCoefficient : public VectorCoefficient
vshape(vdim, vq.GetVDim()), vc(vq.GetVDim()) { }
using VectorCoefficient::Eval;
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{
V.SetSize(vdim);
VQ.Eval(vc, T, ip);
+474 -591
View File
File diff suppressed because it is too large Load Diff
+156 -174
View File
@@ -90,12 +90,12 @@ public:
explicit ConstantCoefficient(real_t c = 1.0) { constant=c; }
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{ return (constant); }
/// Fill the QuadratureFunction @a qf with the constant value.
void Project(QuadratureFunction &qf) override;
void Project(QuadratureFunction &qf);
};
/** @brief A piecewise constant coefficient with the constants keyed
@@ -130,8 +130,8 @@ public:
int GetNConst() { return constants.Size(); }
/// Evaluate the coefficient.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/** @brief A piecewise coefficient with the pieces keyed off the element
@@ -195,7 +195,7 @@ public:
{ InitMap(attr, coefs); }
/// Set the time for time dependent coefficients
void SetTime(real_t t) override;
virtual void SetTime(real_t t);
/// Replace a set of coefficients
void UpdateCoefficients(const Array<int> & attr,
@@ -211,8 +211,8 @@ public:
{ pieces.erase(attr); }
/// Evaluate the coefficient.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// A general function coefficient
@@ -254,8 +254,8 @@ public:
}
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// A common base class for returning individual components of the domain's
@@ -271,8 +271,8 @@ protected:
public:
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Scalar coefficient which returns the x-component of the evaluation point
@@ -307,8 +307,8 @@ public:
CylindricalRadialCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Scalar coefficient which returns the angular position or azimuth (often
@@ -323,8 +323,8 @@ public:
CylindricalAzimuthalCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Scalar coefficient which returns the height or altitude of
@@ -342,8 +342,8 @@ public:
SphericalRadialCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Scalar coefficient which returns the azimuthal angle (often denoted by phi)
@@ -357,8 +357,8 @@ public:
SphericalAzimuthalCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Scalar coefficient which returns the polar angle (often denoted by theta)
@@ -372,8 +372,8 @@ public:
SphericalPolarCoefficient() : transip(3) {}
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
class GridFunction;
@@ -399,15 +399,15 @@ public:
const GridFunction * GetGridFunction() const { return GridF; }
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
/// @brief Fill the QuadratureFunction @a qf by evaluating the coefficient at
/// the quadrature points.
///
/// This function uses the efficient QuadratureFunction::ProjectGridFunction
/// to fill the QuadratureFunction.
void Project(QuadratureFunction &qf) override;
virtual void Project(QuadratureFunction &qf);
};
@@ -433,10 +433,10 @@ public:
: Q1(q1), Q2(q2), Transform2(std::move(F)) { Transform1 = 0; }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
};
/** @brief Delta function coefficient optionally multiplied by a weight
@@ -488,7 +488,7 @@ public:
}
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Set the center location of the delta function.
void SetDeltaCenter(const Vector& center);
@@ -534,7 +534,7 @@ public:
virtual real_t EvalDelta(ElementTransformation &T, const IntegrationPoint &ip);
/** @brief A DeltaFunction cannot be evaluated. Calling this method will
cause an MFEM error, terminating the application. */
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
{ mfem_error("DeltaCoefficient::Eval"); return 0.; }
virtual ~DeltaCoefficient() { delete weight; }
};
@@ -555,10 +555,10 @@ public:
{ c = &c_; attr.Copy(active_attr); }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
{ return active_attr[T.Attribute-1] ? c->Eval(T, ip, GetTime()) : 0.0; }
};
@@ -628,8 +628,8 @@ public:
using VectorCoefficient::Eval;
/// Evaluate the vector coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override { V = vec; }
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) { V = vec; }
/// Return a reference to the constant vector in this class.
const Vector& GetVec() const { return vec; }
@@ -698,7 +698,7 @@ public:
: VectorCoefficient(vd) { InitMap(attr, coefs); }
/// Set the time for time dependent coefficients
void SetTime(real_t t) override;
virtual void SetTime(real_t t);
/// Replace a set of coefficients
void UpdateCoefficients(const Array<int> & attr,
@@ -713,8 +713,8 @@ public:
{ pieces.erase(attr); }
/// Evaluate the coefficient.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
using VectorCoefficient::Eval;
};
@@ -728,8 +728,8 @@ public:
using VectorCoefficient::Eval;
/// Evaluate the vector coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
virtual ~PositionVectorCoefficient() { }
};
@@ -765,8 +765,8 @@ public:
using VectorCoefficient::Eval;
/// Evaluate the vector coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
virtual ~VectorFunctionCoefficient() { }
};
@@ -787,7 +787,7 @@ public:
explicit VectorArrayCoefficient(int dim);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Returns i'th coefficient.
Coefficient* GetCoeff(int i) { return Coeff[i]; }
@@ -798,12 +798,6 @@ public:
/// Sets coefficient in the vector.
void Set(int i, Coefficient *c, bool own=true);
/// Set ownership of the i'th coefficient
void SetOwnership(int i, bool own) { ownCoeff[i] = own; }
/// Get ownership of the i'th coefficient
bool GetOwnership(int i) const { return ownCoeff[i]; }
/// Evaluates i'th component of the vector of coefficients and returns the
/// value.
real_t Eval(int i, ElementTransformation &T, const IntegrationPoint &ip)
@@ -812,8 +806,8 @@ public:
using VectorCoefficient::Eval;
/** @brief Evaluate the coefficient. Each element of vector V comes from the
associated array of scalar coefficients. */
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
/// Destroys vector coefficient.
virtual ~VectorArrayCoefficient();
@@ -842,21 +836,21 @@ public:
const GridFunction * GetGridFunction() const { return GridFunc; }
/// Evaluate the vector coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
/** @brief Evaluate the vector coefficients at all of the locations in the
integration rule and write the vectors into the columns of matrix @a
M. */
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir);
/// @brief Fill the QuadratureFunction @a qf by evaluating the coefficient at
/// the quadrature points.
///
/// This function uses the efficient QuadratureFunction::ProjectGridFunction
/// to fill the QuadratureFunction.
void Project(QuadratureFunction &qf) override;
virtual void Project(QuadratureFunction &qf);
virtual ~VectorGridFunctionCoefficient() { }
};
@@ -880,14 +874,14 @@ public:
const GridFunction * GetGridFunction() const { return GridFunc; }
/// Evaluate the gradient vector coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
/** @brief Evaluate the gradient vector coefficient at all of the locations
in the integration rule and write the vectors into columns of matrix @a
M. */
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir);
virtual ~GradientGridFunctionCoefficient() { }
};
@@ -911,8 +905,8 @@ public:
using VectorCoefficient::Eval;
/// Evaluate the vector curl coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
virtual ~CurlGridFunctionCoefficient() { }
};
@@ -935,8 +929,8 @@ public:
const GridFunction * GetGridFunction() const { return GridFunc; }
/// Evaluate the scalar divergence coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
virtual ~DivergenceGridFunctionCoefficient() { }
};
@@ -979,7 +973,7 @@ public:
: VectorCoefficient(dir_.Size()), dir(dir_), d(x,y,z,s) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Replace the associated DeltaCoefficient with a new DeltaCoefficient.
/** The new DeltaCoefficient cannot have a specified weight Coefficient, i.e.
@@ -1004,8 +998,8 @@ public:
using VectorCoefficient::Eval;
/** @brief A VectorDeltaFunction cannot be evaluated. Calling this method
will cause an MFEM error, terminating the application. */
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
{ mfem_error("VectorDeltaCoefficient::Eval"); }
virtual ~VectorDeltaCoefficient() { }
};
@@ -1027,17 +1021,17 @@ public:
{ c = &vc; attr.Copy(active_attr); }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Evaluate the vector coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
/** @brief Evaluate the vector coefficient at all of the locations in the
integration rule and write the vectors into the columns of matrix @a
M. */
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationRule &ir);
};
typedef VectorCoefficient DiagonalMatrixCoefficient;
@@ -1119,8 +1113,8 @@ public:
: MatrixCoefficient(m.Height(), m.Width()), mat(m) { }
using MatrixCoefficient::Eval;
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override { M = mat; }
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) { M = mat; }
/// Return a reference to the constant matrix.
const DenseMatrix& GetMatrix() { return mat; }
};
@@ -1213,7 +1207,7 @@ public:
: MatrixCoefficient(h, w, symm) { InitMap(attr, coefs); }
/// Set the time for time dependent coefficients
void SetTime(real_t t) override;
virtual void SetTime(real_t t);
/// Replace a set of coefficients
void UpdateCoefficients(const Array<int> & attr,
@@ -1228,8 +1222,8 @@ public:
{ pieces.erase(attr); }
/// Evaluate the coefficient.
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
};
/** @brief A matrix coefficient with an optional scalar coefficient multiplier
@@ -1286,16 +1280,16 @@ public:
{ }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
/// (DEPRECATED) Evaluate the symmetric matrix coefficient at @a ip.
/** @deprecated Use Eval() instead. */
void EvalSymmetric(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void EvalSymmetric(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip);
virtual ~MatrixFunctionCoefficient() { }
};
@@ -1316,7 +1310,7 @@ public:
explicit MatrixArrayCoefficient (int dim);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Get the coefficient located at (i,j) in the matrix.
Coefficient* GetCoeff (int i, int j) { return Coeff[i*width+j]; }
@@ -1326,12 +1320,6 @@ public:
can be overridden with the @a own parameter. */
void Set(int i, int j, Coefficient * c, bool own=true);
/// Set ownership of the coefficient at (i,j) in the matrix
void SetOwnership(int i, int j, bool own) { ownCoeff[i*width+j] = own; }
/// Get ownership of the coefficient at (i,j) in the matrix
bool GetOwnership(int i, int j) const { return ownCoeff[i*width+j]; }
using MatrixCoefficient::Eval;
/// Evaluate coefficient located at (i,j) in the matrix using integration
@@ -1340,8 +1328,8 @@ public:
{ return Coeff[i*width+j] ? Coeff[i*width+j] -> Eval(T, ip, GetTime()) : 0.0; }
/// Evaluate the matrix coefficient @a ip.
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
virtual ~MatrixArrayCoefficient();
};
@@ -1372,12 +1360,6 @@ public:
can be overridden with the @a own parameter. */
void Set(int i, VectorCoefficient * c, bool own=true);
/// Set ownership of the i'th coefficient
void SetOwnership(int i, bool own) { ownCoeff[i] = own; }
/// Get ownership of the i'th coefficient
bool GetOwnership(int i) const { return ownCoeff[i]; }
using MatrixCoefficient::Eval;
/// Evaluate coefficient located at the i-th row of the matrix using integration
@@ -1410,11 +1392,11 @@ public:
{ c = &mc; attr.Copy(active_attr); }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Coefficients based on sums, products, or other functions of coefficients.
@@ -1443,7 +1425,7 @@ public:
: aConst(0.0), a(&A), b(&B), alpha(alpha_), beta(beta_) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the first term in the linear combination as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -1471,8 +1453,8 @@ public:
real_t GetBeta() const { return beta; }
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
return alpha * ((a == NULL ) ? aConst : a->Eval(T, ip) )
+ beta * b->Eval(T, ip);
@@ -1520,8 +1502,8 @@ public:
@note When this method is called, the caller must make sure that the
IntegrationPoint associated with @a T is the same as @a ip. This can be
achieved by calling T.SetIntPoint(&ip). */
void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
/// @deprecated Return a reference to the internal matrix used when evaluating this coefficient as a DenseMatrix.
@@ -1543,8 +1525,8 @@ public:
: SymmetricMatrixCoefficient(m.Height()), mat(m) { }
using SymmetricMatrixCoefficient::Eval;
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseSymmetricMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override { M = mat; }
virtual void Eval(DenseSymmetricMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) { M = mat; }
/// Return a reference to the constant matrix.
const DenseSymmetricMatrix& GetMatrix() { return mat; }
@@ -1594,12 +1576,12 @@ public:
{ }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
using SymmetricMatrixCoefficient::Eval;
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseSymmetricMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseSymmetricMatrix &K, ElementTransformation &T,
const IntegrationPoint &ip);
virtual ~SymmetricMatrixFunctionCoefficient() { }
};
@@ -1624,7 +1606,7 @@ public:
: aConst(0.0), a(&A), b(&B) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the first term in the product as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -1642,8 +1624,8 @@ public:
Coefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{ return ((a == NULL ) ? aConst : a->Eval(T, ip) ) * b->Eval(T, ip); }
};
@@ -1672,7 +1654,7 @@ public:
: aConst(0.0), bConst(B), a(&A), b(NULL) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the numerator in the ratio as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -1695,8 +1677,8 @@ public:
Coefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{
real_t den = (b == NULL ) ? bConst : b->Eval(T, ip);
MFEM_ASSERT(den != 0.0, "Division by zero in RatioCoefficient");
@@ -1718,7 +1700,7 @@ public:
: a(&A), p(p_) { }
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the base coefficient
void SetACoef(Coefficient &A) { a = &A; }
@@ -1731,8 +1713,8 @@ public:
real_t GetExponent() const { return p; }
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
{ return pow(a->Eval(T, ip), p); }
};
@@ -1751,7 +1733,7 @@ public:
InnerProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the first vector in the inner product
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -1764,8 +1746,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Scalar coefficient defined as a cross product of two vectors in the xy-plane.
@@ -1783,7 +1765,7 @@ public:
VectorRotProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the first vector in the product
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -1796,8 +1778,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Scalar coefficient defined as the determinant of a matrix coefficient
@@ -1813,7 +1795,7 @@ public:
DeterminantCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -1821,8 +1803,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the determinant coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Scalar coefficient defined as the trace of a matrix coefficient
@@ -1838,7 +1820,7 @@ public:
TraceCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -1846,8 +1828,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the trace coefficient at @a ip.
real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Vector coefficient defined as the linear combination of two vectors
@@ -1884,7 +1866,7 @@ public:
Coefficient &alpha_, Coefficient &beta_);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the first vector coefficient
void SetACoef(VectorCoefficient &A_) { ACoef = &A_; }
@@ -1927,8 +1909,8 @@ public:
real_t GetBeta() const { return beta; }
/// Evaluate the coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
using VectorCoefficient::Eval;
};
@@ -1948,7 +1930,7 @@ public:
ScalarVectorProductCoefficient(Coefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the scalar factor as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -1966,8 +1948,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
using VectorCoefficient::Eval;
};
@@ -1989,7 +1971,7 @@ public:
NormalizedVectorCoefficient(VectorCoefficient &A, real_t tol = 1e-6);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the vector coefficient
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -1997,8 +1979,8 @@ public:
VectorCoefficient * GetACoef() const { return a; }
/// Evaluate the coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
using VectorCoefficient::Eval;
};
@@ -2017,7 +1999,7 @@ public:
VectorCrossProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the first term in the product
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -2030,8 +2012,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
using VectorCoefficient::Eval;
};
@@ -2051,7 +2033,7 @@ public:
MatrixVectorProductCoefficient(MatrixCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2064,8 +2046,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the vector coefficient at @a ip.
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
using VectorCoefficient::Eval;
};
@@ -2084,8 +2066,8 @@ public:
: MatrixCoefficient(d, d), dim(d) { }
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Matrix coefficient defined as the linear combination of two matrices
@@ -2106,7 +2088,7 @@ public:
real_t alpha_ = 1.0, real_t beta_ = 1.0);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the first matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2129,8 +2111,8 @@ public:
real_t GetBeta() const { return beta; }
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Matrix coefficient defined as the product of two matrices
@@ -2158,8 +2140,8 @@ public:
MatrixCoefficient * GetBCoef() const { return b; }
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
};
/** @brief Matrix coefficient defined as a product of a scalar coefficient and a
@@ -2179,7 +2161,7 @@ public:
ScalarMatrixProductCoefficient(Coefficient &A, MatrixCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the scalar factor as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -2197,8 +2179,8 @@ public:
MatrixCoefficient * GetBCoef() const { return b; }
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Matrix coefficient defined as the transpose of a matrix coefficient
@@ -2212,7 +2194,7 @@ public:
TransposeMatrixCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2220,8 +2202,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Matrix coefficient defined as the inverse of a matrix coefficient.
@@ -2235,7 +2217,7 @@ public:
InverseMatrixCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2243,8 +2225,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Matrix coefficient defined as the exponential of a matrix coefficient.
@@ -2258,7 +2240,7 @@ public:
ExponentialMatrixCoefficient(MatrixCoefficient &A);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the matrix coefficient
void SetACoef(MatrixCoefficient &A) { a = &A; }
@@ -2266,8 +2248,8 @@ public:
MatrixCoefficient * GetACoef() const { return a; }
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
};
/// Matrix coefficient defined as the outer product of two vector coefficients.
@@ -2285,7 +2267,7 @@ public:
OuterProductCoefficient(VectorCoefficient &A, VectorCoefficient &B);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the first vector in the outer product
void SetACoef(VectorCoefficient &A) { a = &A; }
@@ -2298,8 +2280,8 @@ public:
VectorCoefficient * GetBCoef() const { return b; }
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
};
/** @brief Matrix coefficient defined as -a k x k x, for a vector k and scalar a
@@ -2323,7 +2305,7 @@ public:
CrossCrossCoefficient(Coefficient &A, VectorCoefficient &K);
/// Set the time for internally stored coefficients
void SetTime(real_t t) override;
void SetTime(real_t t);
/// Reset the scalar factor as a constant
void SetAConst(real_t A) { a = NULL; aConst = A; }
@@ -2341,8 +2323,8 @@ public:
VectorCoefficient * GetKCoef() const { return k; }
/// Evaluate the matrix coefficient at @a ip.
void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(DenseMatrix &M, ElementTransformation &T,
const IntegrationPoint &ip);
};
///@}
@@ -2367,10 +2349,10 @@ public:
const QuadratureFunction& GetQuadFunction() const { return QuadF; }
using VectorCoefficient::Eval;
void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip) override;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip);
void Project(QuadratureFunction &qf) override;
virtual void Project(QuadratureFunction &qf);
virtual ~VectorQuadratureFunctionCoefficient() { }
};
@@ -2389,9 +2371,9 @@ public:
const QuadratureFunction& GetQuadFunction() const { return QuadF; }
real_t Eval(ElementTransformation &T, const IntegrationPoint &ip) override;
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
void Project(QuadratureFunction &qf) override;
virtual void Project(QuadratureFunction &qf);
virtual ~QuadratureFunctionCoefficient() { }
};
+1 -1
View File
@@ -1245,7 +1245,7 @@ ParSesquilinearForm::FormLinearSystem(const Array<int> &ess_tdof_list,
hypre_ParCSRMatrix *Aih = *Ah;
Ah->HypreReadWrite();
const int *d_ess_tdof_list =
ess_tdof_list.GetMemory().Read(GetHypreForallMemoryClass(), n);
ess_tdof_list.GetMemory().Read(GetHypreMemoryClass(), n);
HYPRE_Int *d_diag_i = Aih->diag->i;
real_t *d_diag_data = Aih->diag->data;
mfem::hypre_forall(n, [=] MFEM_HOST_DEVICE (int k)
+2 -5
View File
@@ -943,7 +943,6 @@ void ParaViewDataCollection::Save()
pvtu_out << "<PDataArray type=\"" << GetDataTypeString()
<< "\" Name=\"" << field_it.first
<< "\" NumberOfComponents=\"" << vec_dim << "\" "
<< VTKComponentLabels(vec_dim) << " "
<< "format=\"" << GetDataFormatString() << "\" />\n";
}
pvtu_out << "</PPointData>\n";
@@ -978,7 +977,6 @@ void ParaViewDataCollection::Save()
pvtu_out << "<PDataArray type=\"" << GetDataTypeString()
<< "\" Name=\"" << q_field_name
<< "\" NumberOfComponents=\"" << vec_dim << "\" "
<< VTKComponentLabels(vec_dim) << " "
<< "format=\"" << GetDataFormatString() << "\" />\n";
pvtu_out << "</PPointData>\n";
WritePVTUFooter(pvtu_out, q_field_name);
@@ -1071,9 +1069,8 @@ void ParaViewDataCollection::SaveGFieldVTU(std::ostream &os, int ref_,
int vec_dim = it->second->VectorDim();
os << "<DataArray type=\"" << GetDataTypeString()
<< "\" Name=\"" << it->first
<< "\" NumberOfComponents=\"" << vec_dim << "\" "
<< VTKComponentLabels(vec_dim) << " "
<< "format=\"" << GetDataFormatString() << "\" >" << '\n';
<< "\" NumberOfComponents=\"" << vec_dim << "\""
<< " format=\"" << GetDataFormatString() << "\" >" << '\n';
if (vec_dim == 1)
{
// scalar data
+11 -11
View File
@@ -454,28 +454,28 @@ public:
#endif
/// Set/change the mesh associated with the collection
void SetMesh(Mesh *new_mesh) override;
virtual void SetMesh(Mesh *new_mesh) override;
#ifdef MFEM_USE_MPI
/// Set/change the mesh associated with the collection.
void SetMesh(MPI_Comm comm, Mesh *new_mesh) override;
virtual void SetMesh(MPI_Comm comm, Mesh *new_mesh) override;
#endif
/// Add a grid function to the collection and update the root file
void RegisterField(const std::string& field_name,
GridFunction *gf) override;
virtual void RegisterField(const std::string& field_name,
GridFunction *gf) override;
/// Add a quadrature function to the collection and update the root file.
/** Visualization of quadrature function is not supported in VisIt(3.12).
A patch has been sent to VisIt developers in June 2020. */
void RegisterQField(const std::string& q_field_name,
QuadratureFunction *qf) override;
virtual void RegisterQField(const std::string& q_field_name,
QuadratureFunction *qf) override;
/// Set the number of digits used for both the cycle and the MPI rank
/// @note VisIt seems to require 6 pad digits for the MPI rank. Therefore,
/// this function uses this default value. This behavior can be overridden
/// by calling SetPadDigitsCycle() and SetPadDigitsRank() instead.
void SetPadDigits(int digits) override
virtual void SetPadDigits(int digits) override
{ pad_digits_cycle=digits; pad_digits_rank=6; }
/// Set VisIt parameter: default levels of detail for the MultiresControl
@@ -489,13 +489,13 @@ public:
void DeleteAll();
/// Save the collection and a VisIt root file
void Save() override;
virtual void Save() override;
/// Save a VisIt root file for the collection
void SaveRootFile();
/// Load the collection based on its VisIt data (described in its root file)
void Load(int cycle_ = 0) override;
virtual void Load(int cycle_ = 0) override;
/// We will delete the mesh and fields if we own them
virtual ~VisItDataCollection() {}
@@ -546,7 +546,7 @@ public:
/// Save the collection - the directory name is constructed based on the
/// cycle value
void Save() override;
virtual void Save() override;
/// Set the data format for the ParaView output files. Possible options are
/// VTKFormat::ASCII, VTKFormat::BINARY, and VTKFormat::BINARY32.
@@ -590,7 +590,7 @@ public:
void UseRestartMode(bool restart_mode_);
/// Load the collection - not implemented in the ParaView writer
void Load(int cycle_ = 0) override;
virtual void Load(int cycle_ = 0) override;
};
}
+16 -31
View File
@@ -52,15 +52,6 @@ protected:
const DenseMatrix &EvalTransAdjugateJ();
const DenseMatrix &EvalInverseJ();
/// @name Tolerance used for point comparisons
///@{
#ifdef MFEM_USE_DOUBLE
static constexpr real_t tol_0 = 1e-15;
#elif defined(MFEM_USE_SINGLE)
static constexpr real_t tol_0 = 1e-7;
#endif
///@}
public:
/** This enumeration declares the values stored in
@@ -185,7 +176,7 @@ public:
returned. This method is not 100 percent reliable for non-linear
transformations. */
virtual int TransformBack(const Vector &pt, IntegrationPoint &ip,
const real_t phys_tol = tol_0) = 0;
const real_t phys_tol = 1e-15) = 0;
virtual ~ElementTransformation() { }
};
@@ -290,15 +281,9 @@ public:
rel_qpts_order(-1),
solver_type(NewtonElementProject),
max_iter(16),
#ifdef MFEM_USE_DOUBLE
ref_tol(1e-15),
phys_rtol(1e-15),
ip_tol(1e-8),
#elif defined(MFEM_USE_SINGLE)
ref_tol(1e-7),
phys_rtol(1e-7),
ip_tol(1e-4),
#endif
print_level(-1)
{ }
@@ -385,10 +370,10 @@ private:
/** @brief Evaluate the Jacobian of the transformation at the IntPoint and
store it in dFdx. */
const DenseMatrix &EvalJacobian() override;
virtual const DenseMatrix &EvalJacobian();
// Evaluate the Hessian of the transformation at the IntPoint and store it
// in d2Fdx2.
const DenseMatrix &EvalHessian() override;
virtual const DenseMatrix &EvalHessian();
public:
IsoparametricTransformation() : FElem(NULL) {}
@@ -430,32 +415,32 @@ public:
/** @brief Transform integration point from reference coordinates to
physical coordinates and store them in the vector. */
void Transform(const IntegrationPoint &, Vector &) override;
virtual void Transform(const IntegrationPoint &, Vector &);
/** @brief Transform all the integration points from the integration rule
from reference coordinates to physical
coordinates and store them as column vectors in the matrix. */
void Transform(const IntegrationRule &, DenseMatrix &) override;
virtual void Transform(const IntegrationRule &, DenseMatrix &);
/** @brief Transform all the integration points from the column vectors
of @a matrix from reference coordinates to physical
coordinates and store them as column vectors in @a result. */
void Transform(const DenseMatrix &matrix, DenseMatrix &result) override;
virtual void Transform(const DenseMatrix &matrix, DenseMatrix &result);
/// Return the order of the current element we are using for the transformation.
int Order() const override { return FElem->GetOrder(); }
virtual int Order() const { return FElem->GetOrder(); }
/// Return the order of the elements of the Jacobian of the transformation.
int OrderJ() const override;
virtual int OrderJ() const;
/** @brief Return the order of the determinant of the Jacobian (weight)
of the transformation. */
int OrderW() const override;
virtual int OrderW() const;
/// Return the order of $ adj(J)^T \nabla fi $
int OrderGrad(const FiniteElement *fe) const override;
virtual int OrderGrad(const FiniteElement *fe) const;
int GetSpaceDim() const override { return PointMat.Height(); }
virtual int GetSpaceDim() const { return PointMat.Height(); }
/** @brief Transform a point @a pt from physical space to a point @a ip in
reference space and optionally can set a solver tolerance using @a phys_tol. */
@@ -463,8 +448,8 @@ public:
point in physical space. If the inversion fails a non-zero value is
returned. This method is not 100 percent reliable for non-linear
transformations. */
int TransformBack (const Vector & v, IntegrationPoint & ip,
const real_t phys_rel_tol = tol_0) override
virtual int TransformBack(const Vector & v, IntegrationPoint & ip,
const real_t phys_rel_tol = 1e-15)
{
InverseElementTransformation inv_tr(this);
inv_tr.SetPhysicalRelTol(phys_rel_tol);
@@ -604,9 +589,9 @@ public:
has been configured. */
const IntegrationPoint &GetElement2IntPoint() { return eip2; }
void Transform(const IntegrationPoint &, Vector &) override;
void Transform(const IntegrationRule &, DenseMatrix &) override;
void Transform(const DenseMatrix &matrix, DenseMatrix &result) override;
virtual void Transform(const IntegrationPoint &, Vector &);
virtual void Transform(const IntegrationRule &, DenseMatrix &);
virtual void Transform(const DenseMatrix &matrix, DenseMatrix &result);
ElementTransformation & GetElement1Transformation();
ElementTransformation & GetElement2Transformation();
+13 -13
View File
@@ -172,10 +172,10 @@ public:
void SetFluxAveraging(int fa) { flux_averaging = fa; }
/// Return the total error from the last error estimate.
real_t GetTotalError() const override { return total_error; }
virtual real_t GetTotalError() const override { return total_error; }
/// Get a Vector with all element errors.
const Vector &GetLocalErrors() override
virtual const Vector &GetLocalErrors() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return error_estimates;
@@ -184,14 +184,14 @@ public:
/** @brief Get an Array<int> with anisotropic flags for all mesh elements.
Return an empty array when anisotropic estimates are not available or
enabled. */
const Array<int> &GetAnisotropicFlags() override
virtual const Array<int> &GetAnisotropicFlags() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return aniso_flags;
}
/// Reset the error estimator.
void Reset() override { current_sequence = -1; }
virtual void Reset() override { current_sequence = -1; }
/** @brief Destroy a ZienkiewiczZhuEstimator object. Destroys, if owned, the
FiniteElementSpace, flux_space. */
@@ -298,17 +298,17 @@ public:
}
/// Return the total error from the last error estimate.
real_t GetTotalError() const override { return total_error; }
virtual real_t GetTotalError() const override { return total_error; }
/// Get a Vector with all element errors.
const Vector &GetLocalErrors() override
virtual const Vector &GetLocalErrors() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return error_estimates;
}
/// Reset the error estimator.
void Reset() override { current_sequence = -1; }
virtual void Reset() override { current_sequence = -1; }
virtual ~LSZienkiewiczZhuEstimator() { }
};
@@ -411,17 +411,17 @@ public:
void SetLocalErrorNormP(int p) { local_norm_p = p; }
/// Return the total error from the last error estimate.
real_t GetTotalError() const override { return total_error; }
virtual real_t GetTotalError() const override { return total_error; }
/// Get a Vector with all element errors.
const Vector &GetLocalErrors() override
virtual const Vector &GetLocalErrors() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return error_estimates;
}
/// Reset the error estimator.
void Reset() override { current_sequence = -1; }
virtual void Reset() override { current_sequence = -1; }
/** @brief Destroy a L2ZienkiewiczZhuEstimator object. Destroys, if owned,
the FiniteElementSpace, flux_space. */
@@ -505,10 +505,10 @@ public:
void SetCoef(VectorCoefficient &A) { vcoef = &A; }
/// Reset the error estimator.
void Reset() override { current_sequence = -1; }
virtual void Reset() override { current_sequence = -1; }
/// Get a Vector with all element errors.
const Vector &GetLocalErrors() override
virtual const Vector &GetLocalErrors() override
{
if (MeshIsModified()) { ComputeEstimates(); }
return error_estimates;
@@ -661,7 +661,7 @@ public:
/// Reset the error estimator.
void Reset() override { current_sequence = -1; };
real_t GetTotalError() const override { return total_error; }
virtual real_t GetTotalError() const override { return total_error; }
/** @brief Change the method to compute hₑ on a per-element basis.
@param compute_element_coefficient_
+25 -26
View File
@@ -394,32 +394,7 @@ public:
/// Get a const reference to the nodes of the element
const IntegrationRule & GetNodes() const { return Nodes; }
/** @brief Evaluate the Hessians of all shape functions of a scalar finite
element in reference space at the given point @a ip. */
/** Each row of the result DenseMatrix @a Hessian contains upper triangular
part of the Hessian of one shape function.
The order in 2D is {u_xx, u_xy, u_yy}.
The size (#dof x (#dim (#dim+1)/2) of @a Hessian must be set in advance.*/
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const;
/** @brief Evaluate the Hessian of all shape functions of a scalar finite
element in physical space at the given point @a ip. */
/** The size (#dof, #dim*(#dim+1)/2) of @a Hessian must be set in advance. */
void CalcPhysHessian(ElementTransformation &Trans,
DenseMatrix& Hessian) const;
/** @brief Evaluate the Laplacian of all shape functions of a scalar finite
element in physical space at the given point @a ip. */
/** The size (#dof) of @a Laplacian must be set in advance. */
void CalcPhysLaplacian(ElementTransformation &Trans,
Vector& Laplacian) const;
/** @brief Evaluate the Laplacian of all shape functions of a scalar finite
element in physical space at the given point @a ip. */
/** The size (#dof) of @a Laplacian must be set in advance. */
void CalcPhysLinLaplacian(ElementTransformation &Trans,
Vector& Laplacian) const;
// virtual functions for finite elements on vector spaces
/** @brief Evaluate the values of all shape functions of a *vector* finite
element in reference space at the given point @a ip. */
@@ -479,6 +454,30 @@ public:
*/
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const;
/** @brief Evaluate the Hessians of all shape functions of a scalar finite
element in reference space at the given point @a ip. */
/** Each row of the result DenseMatrix @a Hessian contains upper triangular
part of the Hessian of one shape function.
The order in 2D is {u_xx, u_xy, u_yy}.
The size (#dof x (#dim (#dim+1)/2) of @a Hessian must be set in advance.*/
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const;
/** @brief Evaluate the Hessian of all shape functions of a scalar finite
element in reference space at the given point @a ip. */
/** The size (#dof, #dim*(#dim+1)/2) of @a Hessian must be set in advance. */
virtual void CalcPhysHessian(ElementTransformation &Trans,
DenseMatrix& Hessian) const;
/** @brief Evaluate the Laplacian of all shape functions of a scalar finite
element in reference space at the given point @a ip. */
/** The size (#dof) of @a Laplacian must be set in advance. */
virtual void CalcPhysLaplacian(ElementTransformation &Trans,
Vector& Laplacian) const;
virtual void CalcPhysLinLaplacian(ElementTransformation &Trans,
Vector& Laplacian) const;
/** @brief Return the local interpolation matrix @a I (Dof x Dof) where the
fine element is the image of the base geometry under the given
transformation. */
+324 -324
View File
File diff suppressed because it is too large Load Diff
+31 -31
View File
@@ -28,12 +28,12 @@ private:
public:
/// Construct the H1_SegmentElement of order @a p and BasisType @a btype
H1_SegmentElement(const int p, const int btype = BasisType::GaussLobatto);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
};
@@ -49,12 +49,12 @@ public:
/// Construct the H1_QuadrilateralElement of order @a p and BasisType @a btype
H1_QuadrilateralElement(const int p,
const int btype = BasisType::GaussLobatto);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
};
@@ -70,12 +70,12 @@ private:
public:
/// Construct the H1_HexahedronElement of order @a p and BasisType @a btype
H1_HexahedronElement(const int p, const int btype = BasisType::GaussLobatto);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &Hessian) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
};
@@ -93,11 +93,11 @@ private:
public:
/// Construct the H1_TriangleElement of order @a p and BasisType @a btype
H1_TriangleElement(const int p, const int btype = BasisType::GaussLobatto);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &ddshape) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &ddshape) const;
};
@@ -117,11 +117,11 @@ public:
/// Construct the H1_TetrahedronElement of order @a p and BasisType @a btype
H1_TetrahedronElement(const int p,
const int btype = BasisType::GaussLobatto);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &ddshape) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void CalcHessian(const IntegrationPoint &ip,
DenseMatrix &ddshape) const;
};
@@ -143,9 +143,9 @@ public:
/// Construct the H1_WedgeElement of order @a p and BasisType @a btype
H1_WedgeElement(const int p,
const int btype = BasisType::GaussLobatto);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
};
} // namespace mfem
+49 -49
View File
@@ -28,13 +28,13 @@ private:
public:
/// Construct the L2_SegmentElement of order @a p and BasisType @a btype
L2_SegmentElement(const int p, const int btype = BasisType::GaussLegendre);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ ScalarLocalL2Restriction(Trans, R, *this); }
};
@@ -52,25 +52,25 @@ public:
/// Construct the L2_QuadrilateralElement of order @a p and BasisType @a btype
L2_QuadrilateralElement(const int p,
const int btype = BasisType::GaussLegendre);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_2D(fe, Trans, curl); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ ScalarLocalL2Restriction(Trans, R, *this); }
using FiniteElement::Project;
void ProjectDiv(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &div) const override;
void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void ProjectDiv(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &div) const;
virtual void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const;
};
@@ -86,21 +86,21 @@ public:
/// Construct the L2_HexahedronElement of order @a p and BasisType @a btype
L2_HexahedronElement(const int p,
const int btype = BasisType::GaussLegendre);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ ScalarLocalL2Restriction(Trans, R, *this); }
using FiniteElement::Project;
void ProjectDiv(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &div) const override;
void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void ProjectDiv(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &div) const;
virtual void Project(Coefficient &coeff,
ElementTransformation &Trans, Vector &dofs) const;
};
@@ -118,17 +118,17 @@ public:
/// Construct the L2_TriangleElement of order @a p and BasisType @a btype
L2_TriangleElement(const int p,
const int btype = BasisType::GaussLegendre);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_2D(fe, Trans, curl); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ ScalarLocalL2Restriction(Trans, R, *this); }
};
@@ -149,13 +149,13 @@ public:
/// Construct the L2_TetrahedronElement of order @a p and BasisType @a btype
L2_TetrahedronElement(const int p,
const int btype = BasisType::GaussLegendre);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
void ProjectDelta(int vertex, Vector &dofs) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
virtual void ProjectDelta(int vertex, Vector &dofs) const;
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ ScalarLocalL2Restriction(Trans, R, *this); }
};
@@ -178,9 +178,9 @@ public:
/// Construct the L2_WedgeElement of order @a p and BasisType @a btype
L2_WedgeElement(const int p,
const int btype = BasisType::GaussLegendre);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override;
void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const override;
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const;
virtual void CalcDShape(const IntegrationPoint &ip,
DenseMatrix &dshape) const;
};
} // namespace mfem
+235 -242
View File
@@ -36,63 +36,62 @@ public:
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{ CalcVShape_ND(Trans, shape); }
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
else { Project_ND(tk, dof2tk, vc, Trans, dofs); }
}
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
protected:
void ProjectIntegrated(VectorCoefficient &vc,
@@ -119,47 +118,46 @@ public:
ND_QuadrilateralElement(const int p,
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{ CalcVShape_ND(Trans, shape); }
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{
if (obasis1d.IsIntegratedType()) { ProjectIntegrated(vc, Trans, dofs); }
else { Project_ND(tk, dof2tk, vc, Trans, dofs); }
}
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
void GetFaceMap(const int face_id, Array<int> &face_map) const override;
virtual void GetFaceMap(const int face_id, Array<int> &face_map) const;
protected:
void ProjectIntegrated(VectorCoefficient &vc,
@@ -186,48 +184,47 @@ class ND_TetrahedronElement : public VectorFiniteElement
public:
/// Construct the ND_TetrahedronElement of order @a p
ND_TetrahedronElement(const int p);
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{ CalcVShape_ND(Trans, shape); }
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
const StatelessDofTransformation *GetDofTransformation() const override
virtual const StatelessDofTransformation *GetDofTransformation() const
{ return &doftrans; }
using FiniteElement::Project;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
};
@@ -250,43 +247,42 @@ class ND_TriangleElement : public VectorFiniteElement
public:
/// Construct the ND_TriangleElement of order @a p
ND_TriangleElement(const int p);
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{ CalcVShape_ND(Trans, shape); }
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
const StatelessDofTransformation *GetDofTransformation() const override
virtual const StatelessDofTransformation *GetDofTransformation() const
{ return &doftrans; }
using FiniteElement::Project;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
};
@@ -302,40 +298,39 @@ public:
/** @brief Construct the ND_SegmentElement of order @a p and open
BasisType @a ob_type */
ND_SegmentElement(const int p, const int ob_type = BasisType::GaussLegendre);
void CalcShape(const IntegrationPoint &ip, Vector &shape) const override
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
{ obasis1d.Eval(ip.x, shape); }
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{ CalcVShape_ND(Trans, shape); }
// void CalcCurlShape(const IntegrationPoint &ip,
// virtual void CalcCurlShape(const IntegrationPoint &ip,
// DenseMatrix &curl_shape) const;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
};
@@ -363,54 +358,53 @@ public:
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{ CalcVShape_ND(Trans, shape); }
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
const StatelessDofTransformation *GetDofTransformation() const override
virtual const StatelessDofTransformation *GetDofTransformation() const
{ return &doftrans; }
using FiniteElement::Project;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ Project_ND(tk, dof2tk, fe, Trans, I); }
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
};
@@ -429,11 +423,11 @@ public:
using FiniteElement::CalcVShape;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
};
/// Arbitrary order, three component, Nedelec elements in 1D on a segment
@@ -461,57 +455,56 @@ public:
using FiniteElement::CalcVShape;
using FiniteElement::CalcPhysCurlShape;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void CalcPhysCurlShape(ElementTransformation &Trans,
DenseMatrix &curl_shape) const override;
virtual void CalcPhysCurlShape(ElementTransformation &Trans,
DenseMatrix &curl_shape) const;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(*this, tk, dof2tk, Trans, I); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ LocalRestriction_ND(tk, dof2tk, Trans, R); }
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation_ND(CheckVectorFE(fe), tk, dof2tk, Trans, I); }
using FiniteElement::Project;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const override
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans,
Vector &dofs) const
{ Project_ND(tk, dof2tk, vc, Trans, dofs); }
void ProjectMatrixCoefficient(MatrixCoefficient &mc,
ElementTransformation &T,
Vector &dofs) const override
virtual void ProjectMatrixCoefficient(
MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
{ ProjectMatrixCoefficient_ND(tk, dof2tk, mc, T, dofs); }
void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override;
virtual void Project(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const;
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const
{ ProjectGrad_ND(tk, dof2tk, fe, Trans, grad); }
void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const override
virtual void ProjectCurl(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &curl) const
{ ProjectCurl_ND(tk, dof2tk, fe, Trans, curl); }
};
@@ -542,32 +535,32 @@ public:
const int cb_type = BasisType::GaussLobatto,
const int ob_type = BasisType::GaussLegendre);
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation(*this, Trans, I); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const
{ MFEM_ABORT("method is not overloaded"); }
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
using FiniteElement::Project;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
};
class ND_R2D_FiniteElement : public VectorFiniteElement
@@ -587,35 +580,35 @@ public:
using FiniteElement::CalcVShape;
using FiniteElement::CalcPhysCurlShape;
void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const override;
virtual void CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const;
void CalcPhysCurlShape(ElementTransformation &Trans,
DenseMatrix &curl_shape) const override;
virtual void CalcPhysCurlShape(ElementTransformation &Trans,
DenseMatrix &curl_shape) const;
void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetLocalInterpolation(ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation(*this, Trans, I); }
void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const override;
virtual void GetLocalRestriction(ElementTransformation &Trans,
DenseMatrix &R) const;
void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const override
virtual void GetTransferMatrix(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &I) const
{ LocalInterpolation(CheckVectorFE(fe), Trans, I); }
using FiniteElement::Project;
void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const override;
virtual void Project(VectorCoefficient &vc,
ElementTransformation &Trans, Vector &dofs) const;
void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const override;
virtual void Project(const FiniteElement &fe, ElementTransformation &Trans,
DenseMatrix &I) const;
void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const override;
virtual void ProjectGrad(const FiniteElement &fe,
ElementTransformation &Trans,
DenseMatrix &grad) const;
};
/// Arbitrary order Nedelec 3D elements in 2D on a triangle
@@ -642,10 +635,10 @@ public:
using ND_R2D_FiniteElement::CalcVShape;
using ND_R2D_FiniteElement::CalcPhysCurlShape;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
};
@@ -671,10 +664,10 @@ public:
using ND_R2D_FiniteElement::CalcVShape;
using ND_R2D_FiniteElement::CalcPhysCurlShape;
void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const override;
void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const override;
virtual void CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const;
virtual void CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const;
};
+1 -614
View File
@@ -398,621 +398,8 @@ void NURBS3DFiniteElement::CalcHessian (const IntegrationPoint &ip,
hessian(o,5) = hessian(o,5)*sum
- 2*du(o,1)*sum*dsum[1]
+ u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[5]);
}
}
void NURBS_HDiv2DFiniteElement::SetOrder() const
{
orders[0] = kv[0]->GetOrder();
orders[1] = kv[1]->GetOrder();
if (kv1[0]) { delete kv1[0]; }
if (kv1[1]) { delete kv1[1]; }
kv1[0] = kv[0]->DegreeElevate(1);
kv1[1] = kv[1]->DegreeElevate(1);
shape_x.SetSize(orders[0]+1);
shape_y.SetSize(orders[1]+1);
dshape_x.SetSize(orders[0]+1);
dshape_y.SetSize(orders[1]+1);
d2shape_x.SetSize(orders[0]+1);
d2shape_y.SetSize(orders[1]+1);
shape1_x.SetSize(orders[0]+2);
shape1_y.SetSize(orders[1]+2);
dshape1_x.SetSize(orders[0]+2);
dshape1_y.SetSize(orders[1]+2);
d2shape1_x.SetSize(orders[0]+2);
d2shape1_y.SetSize(orders[1]+2);
order = max(orders[0]+1, orders[1]+1);
dof = (orders[0] + 2)*(orders[1] + 1)
+ (orders[1] + 1)*(orders[1] + 2);
u.SetSize(dof);
du.SetSize(dof);
weights.SetSize(dof);
}
void NURBS_HDiv2DFiniteElement::CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const
{
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
int o = 0;
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy = shape_y(j);
for (int i = 0; i <= orders[0]+1; i++, o++)
{
shape(o,0) = shape1_x(i)*sy;
shape(o,1) = 0.0;
}
}
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t sy1 = shape1_y(j);
for (int i = 0; i <= orders[0]; i++, o++)
{
shape(o,0) = 0.0;
shape(o,1) = shape_x(i)*sy1;
}
}
}
void NURBS_HDiv2DFiniteElement::CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{
CalcVShape(Trans.GetIntPoint(), shape);
const DenseMatrix & J = Trans.Jacobian();
MFEM_ASSERT(J.Width() == 2 && J.Height() == 2,
"NURBS_HDiv2DFiniteElement cannot be embedded in "
"3 dimensional spaces");
for (int i=0; i<dof; i++)
{
real_t sx = shape(i, 0);
real_t sy = shape(i, 1);
shape(i, 0) = sx * J(0, 0) + sy * J(0, 1);
shape(i, 1) = sx * J(1, 0) + sy * J(1, 1);
}
shape *= (1.0 / Trans.Weight());
}
void NURBS_HDiv2DFiniteElement::CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const
{
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
kv1[0]->CalcDShape(dshape1_x, ijk[0], ip.x);
kv1[1]->CalcDShape(dshape1_y, ijk[1], ip.y);
int o = 0;
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy = shape_y(j);
for (int i = 0; i <= orders[0]+1; i++, o++)
{
divshape(o) = dshape1_x(i)*sy;
}
}
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t dsy1 = dshape1_y(j);
for (int i = 0; i <= orders[0]; i++, o++)
{
divshape(o) = shape_x(i)*dsy1;
}
}
}
NURBS_HDiv2DFiniteElement::~NURBS_HDiv2DFiniteElement()
{
if (kv1[0]) { delete kv1[0]; }
if (kv1[1]) { delete kv1[1]; }
}
void NURBS_HDiv3DFiniteElement::SetOrder() const
{
orders[0] = kv[0]->GetOrder();
orders[1] = kv[1]->GetOrder();
orders[2] = kv[2]->GetOrder();
if (kv1[0]) { delete kv1[0]; }
if (kv1[1]) { delete kv1[1]; }
if (kv1[2]) { delete kv1[2]; }
kv1[0] = kv[0]->DegreeElevate(1);
kv1[1] = kv[1]->DegreeElevate(1);
kv1[2] = kv[2]->DegreeElevate(1);
shape_x.SetSize(orders[0]+1);
shape_y.SetSize(orders[1]+1);
shape_z.SetSize(orders[2]+1);
dshape_x.SetSize(orders[0]+1);
dshape_y.SetSize(orders[1]+1);
dshape_z.SetSize(orders[2]+1);
d2shape_x.SetSize(orders[0]+1);
d2shape_y.SetSize(orders[1]+1);
d2shape_z.SetSize(orders[2]+1);
shape1_x.SetSize(orders[0]+2);
shape1_y.SetSize(orders[1]+2);
shape1_z.SetSize(orders[2]+2);
dshape1_x.SetSize(orders[0]+2);
dshape1_y.SetSize(orders[1]+2);
dshape1_z.SetSize(orders[2]+2);
d2shape1_x.SetSize(orders[0]+2);
d2shape1_y.SetSize(orders[1]+2);
d2shape1_z.SetSize(orders[2]+2);
order = max(orders[0]+1, max( orders[1]+1, orders[2]+1));
dof = (orders[0] + 2)*(orders[1] + 1)*(orders[2] + 1) +
(orders[0] + 1)*(orders[1] + 2)*(orders[2] + 1) +
(orders[0] + 1)*(orders[1] + 1)*(orders[2] + 2);
u.SetSize(dof);
du.SetSize(dof);
weights.SetSize(dof);
}
void NURBS_HDiv3DFiniteElement::CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const
{
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
kv[2]->CalcShape(shape_z, ijk[2], ip.z);
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
kv1[2]->CalcShape(shape1_z, ijk[2], ip.z);
shape = 0.0;
int o = 0;
for (int k = 0; k <= orders[2]; k++)
{
const real_t sz = shape_z(k);
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy_sz = shape_y(j)*sz;
for (int i = 0; i <= orders[0]+1; i++, o++)
{
shape(o,0) = shape1_x(i)*sy_sz;
}
}
}
for (int k = 0; k <= orders[2]; k++)
{
const real_t sz = shape_z(k);
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t sy1_sz = shape1_y(j)*sz;
for (int i = 0; i <= orders[0]; i++, o++)
{
shape(o,1) = shape_x(i)*sy1_sz;
}
}
}
for (int k = 0; k <= orders[2]+1; k++)
{
const real_t sz1 = shape1_z(k);
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy_sz1 = shape_y(j)*sz1;
for (int i = 0; i <= orders[0]; i++, o++)
{
shape(o,2) = shape_x(i)*sy_sz1;
}
}
}
}
void NURBS_HDiv3DFiniteElement::CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{
CalcVShape(Trans.GetIntPoint(), shape);
const DenseMatrix & J = Trans.Jacobian();
MFEM_ASSERT(J.Width() == 3 && J.Height() == 3,
"RT_R2D_FiniteElement cannot be embedded in "
"3 dimensional spaces");
for (int i=0; i<dof; i++)
{
real_t sx = shape(i, 0);
real_t sy = shape(i, 1);
real_t sz = shape(i, 2);
shape(i, 0) = sx * J(0, 0) + sy * J(0, 1) + sz * J(0, 2);
shape(i, 1) = sx * J(1, 0) + sy * J(1, 1) + sz * J(1, 2);
shape(i, 2) = sx * J(2, 0) + sy * J(2, 1) + sz * J(2, 2);
}
shape *= (1.0 / Trans.Weight());
}
void NURBS_HDiv3DFiniteElement::CalcDivShape(const IntegrationPoint &ip,
Vector &divshape) const
{
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
kv1[0]->CalcDShape(dshape1_x, ijk[0], ip.x);
kv1[1]->CalcDShape(dshape1_y, ijk[1], ip.y);
kv1[2]->CalcDShape(dshape1_z, ijk[2], ip.z);
int o = 0;
for (int k = 0; k <= orders[2]; k++)
{
const real_t sz = shape_z(k);
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy_sz = shape_y(j)*sz;
for (int i = 0; i <= orders[0]+1; i++, o++)
{
divshape(o) = dshape1_x(i)*sy_sz;
}
}
}
for (int k = 0; k <= orders[2]; k++)
{
const real_t sz = shape_z(k);
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t dy1_sz = dshape1_y(j)*sz;
for (int i = 0; i <= orders[0]; i++, o++)
{
divshape(o) = shape_x(i)*dy1_sz;
}
}
}
for (int k = 0; k <= orders[2]+1; k++)
{
const real_t dz1 = dshape1_z(k);
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy_dz1 = shape_y(j)*dz1;
for (int i = 0; i <= orders[0]; i++, o++)
{
divshape(o) = shape_x(i)*sy_dz1;
}
}
}
}
NURBS_HDiv3DFiniteElement::~NURBS_HDiv3DFiniteElement()
{
if (kv1[0]) { delete kv1[0]; }
if (kv1[1]) { delete kv1[1]; }
if (kv1[2]) { delete kv1[2]; }
}
void NURBS_HCurl2DFiniteElement::SetOrder() const
{
orders[0] = kv[0]->GetOrder();
orders[1] = kv[1]->GetOrder();
if (kv1[0]) { delete kv1[0]; }
if (kv1[1]) { delete kv1[1]; }
kv1[0] = kv[0]->DegreeElevate(1);
kv1[1] = kv[1]->DegreeElevate(1);
shape_x.SetSize(orders[0]+1);
shape_y.SetSize(orders[1]+1);
dshape_x.SetSize(orders[0]+1);
dshape_y.SetSize(orders[1]+1);
d2shape_x.SetSize(orders[0]+1);
d2shape_y.SetSize(orders[1]+1);
shape1_x.SetSize(orders[0]+2);
shape1_y.SetSize(orders[1]+2);
dshape1_x.SetSize(orders[0]+2);
dshape1_y.SetSize(orders[1]+2);
d2shape1_x.SetSize(orders[0]+2);
d2shape1_y.SetSize(orders[1]+2);
order = max(orders[0]+1, orders[1]+1);
dof = (orders[0] + 1)*(orders[1] + 2)
+ (orders[1] + 2)*(orders[1] + 1);
u.SetSize(dof);
du.SetSize(dof);
weights.SetSize(dof);
}
void NURBS_HCurl2DFiniteElement::CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const
{
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
int o = 0;
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t sy1 = shape1_y(j);
for (int i = 0; i <= orders[0]; i++, o++)
{
shape(o,0) = shape_x(i)*sy1;
shape(o,1) = 0.0;
}
}
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy = shape_y(j);
for (int i = 0; i <= orders[0]+1; i++, o++)
{
shape(o,0) = 0.0;
shape(o,1) = shape1_x(i)*sy;
}
}
}
void NURBS_HCurl2DFiniteElement::CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{
CalcVShape(Trans.GetIntPoint(), shape);
const DenseMatrix & JI = Trans.InverseJacobian();
MFEM_ASSERT(JI.Width() == 2 && JI.Height() == 2,
"NURBS_HCurl2DFiniteElement cannot be embedded in "
"3 dimensional spaces");
for (int i=0; i<dof; i++)
{
real_t sx = shape(i, 0);
real_t sy = shape(i, 1);
shape(i, 0) = sx * JI(0, 0) + sy * JI(1, 0);
shape(i, 1) = sx * JI(0, 1) + sy * JI(1, 1);
}
}
void NURBS_HCurl2DFiniteElement::CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const
{
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
kv1[0]->CalcDShape(dshape1_x, ijk[0], ip.x);
kv1[1]->CalcDShape(dshape1_y, ijk[1], ip.y);
int o = 0;
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t dsy1 = dshape1_y(j);
for (int i = 0; i <= orders[0]; i++, o++)
{
curl_shape(o,0) = -shape_x(i)*dsy1;
}
}
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy = shape_y(j);
for (int i = 0; i <= orders[0]+1; i++, o++)
{
curl_shape(o,0) = dshape1_x(i)*sy;
}
}
}
NURBS_HCurl2DFiniteElement::~NURBS_HCurl2DFiniteElement()
{
if (kv1[0]) { delete kv1[0]; }
if (kv1[1]) { delete kv1[1]; }
}
void NURBS_HCurl3DFiniteElement::SetOrder() const
{
orders[0] = kv[0]->GetOrder();
orders[1] = kv[1]->GetOrder();
orders[2] = kv[2]->GetOrder();
if (kv1[0]) { delete kv1[0]; }
if (kv1[1]) { delete kv1[1]; }
if (kv1[2]) { delete kv1[2]; }
kv1[0] = kv[0]->DegreeElevate(1);
kv1[1] = kv[1]->DegreeElevate(1);
kv1[2] = kv[2]->DegreeElevate(1);
shape_x.SetSize(orders[0]+1);
shape_y.SetSize(orders[1]+1);
shape_z.SetSize(orders[2]+1);
dshape_x.SetSize(orders[0]+1);
dshape_y.SetSize(orders[1]+1);
dshape_z.SetSize(orders[2]+1);
d2shape_x.SetSize(orders[0]+1);
d2shape_y.SetSize(orders[1]+1);
d2shape_z.SetSize(orders[2]+1);
shape1_x.SetSize(orders[0]+2);
shape1_y.SetSize(orders[1]+2);
shape1_z.SetSize(orders[2]+2);
dshape1_x.SetSize(orders[0]+2);
dshape1_y.SetSize(orders[1]+2);
dshape1_z.SetSize(orders[2]+2);
d2shape1_x.SetSize(orders[0]+2);
d2shape1_y.SetSize(orders[1]+2);
d2shape1_z.SetSize(orders[2]+2);
order = max(orders[0]+1, max( orders[1]+1, orders[2]+1));
dof = (orders[0] + 1)*(orders[1] + 2)*(orders[2] + 2) +
(orders[0] + 2)*(orders[1] + 1)*(orders[2] + 2) +
(orders[0] + 2)*(orders[1] + 2)*(orders[2] + 1);
u.SetSize(dof);
du.SetSize(dof);
weights.SetSize(dof);
}
void NURBS_HCurl3DFiniteElement::CalcVShape(const IntegrationPoint &ip,
DenseMatrix &shape) const
{
kv[0]->CalcShape(shape_x, ijk[0], ip.x);
kv[1]->CalcShape(shape_y, ijk[1], ip.y);
kv[2]->CalcShape(shape_z, ijk[2], ip.z);
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
kv1[2]->CalcShape(shape1_z, ijk[2], ip.z);
shape = 0.0;
int o = 0;
for (int k = 0; k <= orders[2]+1; k++)
{
const real_t sz1 = shape1_z(k);
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t sy1_sz1 = shape1_y(j)*sz1;
for (int i = 0; i <= orders[0]; i++, o++)
{
shape(o,0) = shape_x(i)*sy1_sz1;
}
}
}
for (int k = 0; k <= orders[2]+1; k++)
{
const real_t sz1 = shape1_z(k);
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy_sz1 = shape_y(j)*sz1;
for (int i = 0; i <= orders[0]+1; i++, o++)
{
shape(o,1) = shape1_x(i)*sy_sz1;
}
}
}
for (int k = 0; k <= orders[2]; k++)
{
const real_t sz = shape_z(k);
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t sy1_sz = shape1_y(j)*sz;
for (int i = 0; i <= orders[0]+1; i++, o++)
{
shape(o,2) = shape1_x(i)*sy1_sz;
}
}
}
}
void NURBS_HCurl3DFiniteElement::CalcVShape(ElementTransformation &Trans,
DenseMatrix &shape) const
{
CalcVShape(Trans.GetIntPoint(), shape);
const DenseMatrix & JI = Trans.InverseJacobian();
MFEM_ASSERT(JI.Width() == 3 && JI.Height() == 3,
"NURBS_HCurl3DFiniteElement must be in a"
"3 dimensional spaces");
for (int i=0; i<dof; i++)
{
real_t sx = shape(i, 0);
real_t sy = shape(i, 1);
real_t sz = shape(i, 2);
shape(i, 0) = sx * JI(0, 0) + sy * JI(1, 0) + sz * JI(2, 0);
shape(i, 1) = sx * JI(0, 1) + sy * JI(1, 1) + sz * JI(2, 1);
shape(i, 2) = sx * JI(0, 2) + sy * JI(1, 2) + sz * JI(2, 2);
}
}
void NURBS_HCurl3DFiniteElement::CalcCurlShape(const IntegrationPoint &ip,
DenseMatrix &curl_shape) const
{
kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
kv1[0]->CalcShape(shape1_x, ijk[0], ip.x);
kv1[1]->CalcShape(shape1_y, ijk[1], ip.y);
kv1[2]->CalcShape(shape1_z, ijk[2], ip.z);
kv1[0]->CalcDShape(dshape1_x, ijk[0], ip.x);
kv1[1]->CalcDShape(dshape1_y, ijk[1], ip.y);
kv1[2]->CalcDShape(dshape1_z, ijk[2], ip.z);
int o = 0;
for (int k = 0; k <= orders[2]+1; k++)
{
const real_t sz1 = shape1_z(k), dsz1 = dshape1_z(k);
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t sy1_dsz1 = shape1_y(j)*dsz1,
dsy1_sz1 = dshape1_y(j)*sz1;
for (int i = 0; i <= orders[0]; i++, o++)
{
curl_shape(o,0) = 0.0;
curl_shape(o,1) = shape_x(i)*sy1_dsz1;
curl_shape(o,2) = -shape_x(i)*dsy1_sz1;
}
}
}
for (int k = 0; k <= orders[2]+1; k++)
{
const real_t sz1 = shape1_z(k), dsz1 = dshape1_z(k);
for (int j = 0; j <= orders[1]; j++)
{
const real_t sy_dsz1 = shape_y(j)*dsz1,
sy_sz1 = shape_y(j)*sz1;
for (int i = 0; i <= orders[0]+1; i++, o++)
{
curl_shape(o,0) = -shape1_x(i)*sy_dsz1;
curl_shape(o,1) = 0.0;
curl_shape(o,2) = dshape1_x(i)*sy_sz1;
}
}
}
for (int k = 0; k <= orders[2]; k++)
{
const real_t sz = shape_z(k);
for (int j = 0; j <= orders[1]+1; j++)
{
const real_t sy1_sz = shape1_y(j)*sz,
dsy1_sz = dshape1_y(j)*sz;
for (int i = 0; i <= orders[0]+1; i++, o++)
{
curl_shape(o,0) = shape1_x(i)*dsy1_sz;
curl_shape(o,1) = -dshape1_x(i)*sy1_sz;
curl_shape(o,2) = 0.0;
}
}
}
}
NURBS_HCurl3DFiniteElement::~NURBS_HCurl3DFiniteElement()
{
if (kv1[0]) { delete kv1[0]; }
if (kv1[1]) { delete kv1[1]; }
if (kv1[2]) { delete kv1[2]; }
}
}

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