Compare commits

..
15 Commits
Author SHA1 Message Date
Joseph Signorelli 86ba47cbb9 style 2024-03-17 18:20:51 -05:00
Joseph Signorelli 04ea231d3b Backward compatibility for SymmetricMatrixCoefficient 2024-03-17 18:20:22 -05:00
Joseph Signorelli 0aaa0b4353 Prevent overloaded-virtual warning 2024-03-17 17:53:32 -05:00
Joseph Signorelli fd8b529c11 sundials + petsc examples changes propagated through 2024-03-17 17:45:48 -05:00
Joseph Signorelli 94b5f2dad8 style 2024-03-14 18:18:32 -05:00
Joseph Signorelli 6de569ce93 Backward compatibility for codes w/ custom coeffs 2024-03-14 18:17:41 -05:00
Joseph Signorelli 13d4976b3e Merge branch 'master' into constcoeff-dev 2024-03-14 15:33:13 -05:00
Joseph Signorelli 596923be2c Propogate changes through miniapps 2024-03-05 17:03:12 -06:00
Joseph Signorelli 8d612acd5e Propogate changes through examples 2024-03-05 16:42:05 -06:00
Joseph Signorelli 094542ac8b Propogate changes through fem + mesh
- Make const and add `mutable` to appropriate member vars
2024-03-05 16:41:28 -06:00
Joseph Signorelli 841a546bfa Make VectorSumCoefficient member variables mutable to ensure backward compatibility
Not clean but there may be situations where one calls GetAlpha, GetBeta, GetA, or GetB specifically after an Eval call to get those variables at a given point (when ACoeff,BCoeff, AlphaCoeff, BetaCoeff exist).

An alternative option is to use separate auxiliary variables for coefficient evaluations instead.
2024-03-05 16:23:46 -06:00
Joseph Signorelli af29df2b4d *Make access to internal coefficients + member function const-ness consistent
**This may be a breaking change for existing codes. Ex:

```
const SumCoefficient* coeff = ....;
Coefficient* a_coeff = coeff->GetACoef(); // Cannot do this anymore unless a_coeff is also const
```

GetACoef was previously declared const, so it makes more sense to not allow non-const calls to ACoef when this is called.
2024-03-05 16:18:07 -06:00
Joseph Signorelli 88d43f0b97 Add SetTime for VectorFunctionCoefficient 2024-03-05 16:03:00 -06:00
Joseph Signorelli 316572693a Remove any calls setting internal coefficient times' in Eval
These internal coefficients' times' should already have been set in SetTime for each given class, so it is not necessary
2024-03-05 16:00:46 -06:00
Joseph Signorelli f8335862ac Appropriate member functions of coefficients made const
- Eval, Project, + more specific ones
2024-03-05 15:49:58 -06:00
565 changed files with 16187 additions and 22561 deletions
+1 -1
View File
@@ -65,7 +65,7 @@ jobs:
- name: GHCR Login
if: (github.event_name != 'pull_request')
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
-6
View File
@@ -27,12 +27,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Temporary workaround for sanitizer crashes
# See https://github.com/actions/runner-images/issues/9491
# The issue should be fixed in the next runner image for Ubuntu 22.04,
# see https://github.com/actions/runner-images/pull/9513
run: sudo sysctl vm.mmap_rnd_bits=28
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.12.1
with:
+4 -4
View File
@@ -91,6 +91,10 @@ examples/ex16.mesh
examples/ex16-mesh.*
examples/ex16-init.*
examples/ex16-final.*
examples/vortex-mesh.*
examples/vortex.mesh
examples/vortex-?-init.*
examples/vortex-?-final.*
examples/deformation.*
examples/pressure.*
examples/ex20.dat
@@ -116,8 +120,6 @@ examples/cond_mesh.*
examples/port_mesh.*
examples/port_mode.*
examples/euler-*
examples/amgx/ex1
examples/amgx/ex1p
examples/amgx/.logamgx
@@ -352,8 +354,6 @@ miniapps/parelag/MultilevelHcurlHdivSolver
miniapps/parelag/*.mesh
miniapps/multidomain/multidomain
miniapps/multidomain/multidomain_nd
miniapps/multidomain/multidomain_rt
miniapps/hooke/hooke
miniapps/dpg/diffusion
+1 -1
View File
@@ -87,7 +87,7 @@ report_baseline:
# We create an autotest-email.html file, because that's how we signal
# that there was an error / diff (temporary).
if [[ -f ${rundir}/${BASELINE_TEST}.err ]] || \
[[ -f ${rundir}/${BASELINE_TEST}-${MACHINE_NAME}.diff ]]; then
[[ -f ${rundir}/${BASELINE_TEST}-${SYS_TYPE}.diff ]]; then
cp ${rundir}/pipeline.txt ${rundir}/autotest-email.html
fi
msg="GitLab CI log for ${BASELINE_TEST} on ${MACHINE_NAME} ($(date +%Y-%m-%d))"
-3
View File
@@ -14,9 +14,6 @@
# locals
glob_err=${BASELINE_TEST}.err
base=${BASELINE_TEST}-${SYS_TYPE}
if [[ "${MACHINE_NAME}" == "quartz" ]]; then
base="${BASELINE_TEST}-${MACHINE_NAME}"
fi
base_diff=${base}.diff
base_patch=${base}.patch
base_out=${base}.out
-20
View File
@@ -28,13 +28,6 @@ Discretization improvements
IntegrationRules through a moment-fitting approach. The cut is specified by
the zero level set of a Coefficient. See fem/intrules_cut.hpp and Example 38.
- Added a new nonlinear integrator, `HyperbolicFormIntegrator`. This implements
both element-wise weak divergence and face-wise numerical flux for a general
system of hyperbolic conservation laws. To use this integrator for a specific
flux function, users can define a derived class of `FluxFunction`. Currently,
advection, Burgers', shallow-water, Euler equations (see, Example 18) are
available.
GPU support
----------------------------
- Added support for full assembly on simplices.
@@ -54,10 +47,6 @@ New and updated examples and miniapps
Miscellaneous
-------------
- Added support for single and double precision, with corresponding hypre build.
Generalized the floating point type from `double` to `real_t`. For more
details see https://github.com/orgs/mfem/discussions/4207.
- The ReadCubit Genesis mesh importer has been rewritten to improve readability.
- Updated the Doxygen documentation style, which now requires Doxygen version
@@ -67,15 +56,6 @@ Miscellaneous
IntegrationRules IntRules, RefinedIntRules, GeometryRefiner
GlobGeometryRefiner, and FiniteElement::dof2quad_array.
- PETSc integration now generally requires PETSc version 3.21 or later, though
depending on the functionality older versions may still work.
- RAJA backend will use seq_exec for serial loop execution when RAJA
v2023.06.00 and beyond is detected as loop_exec is deprecated.
- Adding named attribute sets and basic supporting methods to the Mesh class as
a convenient means of referring to sets of domain or boundary attribute
numbers. Also adding related serial and parallel examples which illustrate.
Version 4.6, released on September 27, 2023
===========================================
-13
View File
@@ -183,19 +183,6 @@ endif()
# Process configuration options
#-------------------------------------------------------------------------------
# MFEM_PRECISION -> MFEM_USE_SINGLE, MFEM_USE_DOUBLE
if (MFEM_PRECISION MATCHES "^(double|Double|DOUBLE)$")
set(MFEM_USE_SINGLE OFF)
set(MFEM_USE_DOUBLE ON)
elseif (MFEM_PRECISION MATCHES "^(single|Single|SINGLE)$")
set(MFEM_USE_SINGLE ON)
set(MFEM_USE_DOUBLE OFF)
else()
message(FATAL_ERROR " *** Invalid floating-point precision: "
"MFEM_PRECISION = ${MFEM_PRECISION}")
endif()
message(STATUS "Floating-point precision: MFEM_PRECISION = ${MFEM_PRECISION}")
# MFEM_DEBUG
if (CMAKE_BUILD_TYPE MATCHES "Debug|debug|DEBUG")
set(MFEM_DEBUG ON)
-2
View File
@@ -362,8 +362,6 @@ Before you can start, you need a GitHub account, here are a few suggestions:
conflicted files in the commit message.
- All significant new features and changes should be documented in CHANGELOG.
- New examples and miniapps should have documentation on the MFEM webpage.
- The general floating-point type `real_t` should be used, rather than
`float` or `double`, except in special cases where only one is possible.
### Pull Requests
+6 -15
View File
@@ -284,15 +284,6 @@ MFEM_USE_METIS = YES/NO
option in the library will be Cartesian partitioning with box meshes, and
thus most of the parallel examples and miniapps will fail.
MFEM_PRECISION = double/Double/DOUBLE/single/Single/SINGLE
Use single (float type) or double floating-point precision. In the
configuration header 'config/_config.hpp' this option is represented by
defining exactly one of the macros: MFEM_USE_DOUBLE, or MFEM_USE_SINGLE.
In the exported config files 'config.mk' and 'MFEMConfig.cmake', the option
is represented by the variables MFEM_USE_DOUBLE and MFEM_USE_SINGLE defined
as YES/NO (make) or ON/OFF (cmake). For more details see
https://github.com/orgs/mfem/discussions/4207
MFEM_DEBUG = YES/NO
Choose debug/optimized build. The debug build enables a number of messages
and consistency checks that may simplify bug-hunting.
@@ -701,10 +692,9 @@ The specific libraries and their options are:
Options: NETCDF_OPT, NETCDF_LIB.
Versions: NetCDF >= 4.4.0.
- PETSc (optional), used when MFEM_USE_PETSC = YES. Version 3.21 or higher of
the PETSC dev branch is required, though depending on the functionality older
versions may work too. The MFEM and PETSc builds can share common libraries,
e.g., hypre and SUNDIALS. Here's an example configuration, assuming
- PETSc (optional), used when MFEM_USE_PETSC = YES. Version 3.8 or higher of
the PETSC dev branch is required. The MFEM and PETSc builds can share common
libraries, e.g., hypre and SUNDIALS. Here's an example configuration, assuming
PETSc has been cloned on the same level as mfem and hypre:
./configure --download-fblaslapack=yes --download-scalapack=yes \
--download-mumps=yes --download-suitesparse=yes \
@@ -714,7 +704,9 @@ The specific libraries and their options are:
CFLAGS to allow proper parsing of the hipsparse header under C.
URL: https://www.mcs.anl.gov/petsc
Options: PETSC_OPT, PETSC_LIB.
Versions: PETSc >= 3.21.0, older versions may work too.
Versions: PETSc >= 3.8.0 (PETSc build without CUDA/HIP)
PETSc >= 3.15.0 (PETSc built with CUDA)
PETSc >= 3.19.0 (PETSc built with HIP, older versions may work too)
- SLEPc (optional), used when MFEM_USE_SLEPC = YES. SLEPc depends on PETSc and
uses some of the PETSc options when compiled.
@@ -967,7 +959,6 @@ The following options are equivalent to the GNU make options with the same name:
MFEM_USE_MPI
MFEM_USE_METIS - Set to ${MFEM_USE_MPI}, can be overwritten.
MFEM_PRECISION
MFEM_USE_LIBUNWIND
MFEM_USE_LAPACK
MFEM_THREAD_SAFE
-2
View File
@@ -18,8 +18,6 @@ set(MFEM_GIT_STRING "@MFEM_GIT_STRING@")
set(MFEM_USE_MPI @MFEM_USE_MPI@)
set(MFEM_USE_METIS @MFEM_USE_METIS@)
set(MFEM_USE_METIS_5 @MFEM_USE_METIS_5@)
set(MFEM_USE_DOUBLE @MFEM_USE_DOUBLE@)
set(MFEM_USE_SINGLE @MFEM_USE_SINGLE@)
set(MFEM_DEBUG @MFEM_DEBUG@)
set(MFEM_USE_EXCEPTIONS @MFEM_USE_EXCEPTIONS@)
set(MFEM_USE_ZLIB @MFEM_USE_ZLIB@)
-6
View File
@@ -46,12 +46,6 @@
// Requires an MPI compiler, and the libraries HYPRE and METIS.
#cmakedefine MFEM_USE_MPI
// Use double-precision floating point type
#cmakedefine MFEM_USE_DOUBLE
// Use single-precision floating point type
#cmakedefine MFEM_USE_SINGLE
// Enable debug checks in MFEM.
#cmakedefine MFEM_DEBUG
+1 -3
View File
@@ -79,9 +79,7 @@ if (HYPRE_FOUND AND HYPRE_USING_CUDA)
find_package(CUDAToolkit REQUIRED)
get_target_property(CUSPARSE_LIBRARIES CUDA::cusparse LOCATION)
get_target_property(CURAND_LIBRARIES CUDA::curand LOCATION)
get_target_property(CUBLAS_LIBRARIES CUDA::cublas LOCATION)
list(APPEND HYPRE_LIBRARIES ${CUSPARSE_LIBRARIES} ${CURAND_LIBRARIES}
${CUBLAS_LIBRARIES})
list(APPEND HYPRE_LIBRARIES ${CUSPARSE_LIBRARIES} ${CURAND_LIBRARIES})
set(HYPRE_LIBRARIES ${HYPRE_LIBRARIES} CACHE STRING
"HYPRE libraries + dependencies." FORCE)
message(STATUS "Updated HYPRE_LIBRARIES: ${HYPRE_LIBRARIES}")
+11 -12
View File
@@ -842,18 +842,17 @@ function(mfem_export_mk_files)
# Convert Boolean vars to YES/NO without writing the values to cache
set(CONFIG_MK_BOOL_VARS MFEM_USE_MPI MFEM_USE_METIS MFEM_USE_METIS_5
MFEM_USE_SINGLE MFEM_USE_DOUBLE MFEM_DEBUG MFEM_USE_EXCEPTIONS
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_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_MOONOLITH
MFEM_USE_ALGOIM MFEM_USE_ENZYME)
MFEM_DEBUG MFEM_USE_EXCEPTIONS 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_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_ADFORWARD MFEM_USE_CODIPACK MFEM_USE_BENCHMARK MFEM_USE_PARELAG
MFEM_USE_MOONOLITH MFEM_USE_ALGOIM MFEM_USE_ENZYME)
foreach(var ${CONFIG_MK_BOOL_VARS})
if (${var})
set(${var} YES)
-56
View File
@@ -23,62 +23,6 @@
#include "_config.hpp"
#endif
namespace mfem
{
#if (defined(MFEM_USE_CUDA) && defined(__CUDACC__)) || \
(defined(MFEM_USE_HIP) && defined(__HIPCC__))
#define MFEM_HOST_DEVICE __host__ __device__
#else
#define MFEM_HOST_DEVICE
#endif
// MFEM precision configuration
#if defined MFEM_USE_SINGLE && defined MFEM_USE_DOUBLE
#error "DOUBLE and SINGLE precision cannot both be specified"
#endif
#ifdef MFEM_USE_SINGLE
typedef float real_t;
#elif defined MFEM_USE_DOUBLE
typedef double real_t;
#else
#error "Either DOUBLE or SINGLE precision must be specified"
#endif
MFEM_HOST_DEVICE
constexpr real_t operator""_r(long double v)
{
return static_cast<real_t>(v);
}
MFEM_HOST_DEVICE
constexpr real_t operator""_r(unsigned long long v)
{
return static_cast<real_t>(v);
}
} // namespace mfem
// Return value for main function in examples that should be skipped by testing
// in some case. This return value prevents failures in testing.
#define MFEM_SKIP_RETURN_VALUE 242
// Request a global object to be instantiated for each thread in its TLS.
#define MFEM_THREAD_LOCAL thread_local
// MFEM_DEPRECATED macro to mark obsolete functions and methods
// see https://stackoverflow.com/questions/295120/c-mark-as-deprecated
#if defined(__GNUC__) || defined(__clang__)
#define MFEM_DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
#define MFEM_DEPRECATED __declspec(deprecated)
#else
#pragma message("WARNING: You need to implement MFEM_DEPRECATED for this compiler")
#define MFEM_DEPRECATED
#endif
// Common configuration macros
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__)
-6
View File
@@ -46,12 +46,6 @@
// Requires an MPI compiler, and the libraries HYPRE and METIS.
// #define MFEM_USE_MPI
// Use double-precision floating point type
// #define MFEM_USE_DOUBLE
// Use single-precision floating point type
// #define MFEM_USE_SINGLE
// Enable debug checks in MFEM.
// #define MFEM_DEBUG
-2
View File
@@ -18,8 +18,6 @@ MFEM_GIT_STRING = @MFEM_GIT_STRING@
MFEM_USE_MPI = @MFEM_USE_MPI@
MFEM_USE_METIS = @MFEM_USE_METIS@
MFEM_USE_METIS_5 = @MFEM_USE_METIS_5@
MFEM_USE_DOUBLE = @MFEM_USE_DOUBLE@
MFEM_USE_SINGLE = @MFEM_USE_SINGLE@
MFEM_DEBUG = @MFEM_DEBUG@
MFEM_USE_EXCEPTIONS = @MFEM_USE_EXCEPTIONS@
MFEM_USE_ZLIB = @MFEM_USE_ZLIB@
-2
View File
@@ -22,8 +22,6 @@ endif()
option(BUILD_SHARED_LIBS "Enable shared library build of MFEM" OFF)
option(MFEM_USE_MPI "Enable MPI parallel build" OFF)
option(MFEM_USE_METIS "Enable METIS usage" ${MFEM_USE_MPI})
set(MFEM_PRECISION "double" CACHE STRING
"Floating-point precision to use: single, or double")
option(MFEM_USE_EXCEPTIONS "Enable the use of exceptions" OFF)
option(MFEM_USE_ZLIB "Enable zlib for compressed data streams." OFF)
option(MFEM_USE_LIBUNWIND "Enable backtrace for errors." OFF)
+1 -7
View File
@@ -120,7 +120,6 @@ MFEM_MPI_NP = 4
MFEM_USE_MPI = NO
MFEM_USE_METIS = $(MFEM_USE_MPI)
MFEM_USE_METIS_5 = NO
MFEM_PRECISION = double
MFEM_DEBUG = NO
MFEM_USE_EXCEPTIONS = NO
MFEM_USE_ZLIB = NO
@@ -318,13 +317,8 @@ MPI_FORTRAN_LIB = -lmpifort
# MUMPS library configuration
MUMPS_DIR = @MFEM_DIR@/../MUMPS_5.5.0
MUMPS_OPT = -I$(MUMPS_DIR)/include
MUMPS_LIB = $(XLINKER)-rpath,$(MUMPS_DIR)/lib -L$(MUMPS_DIR)/lib \
MUMPS_LIB = $(XLINKER)-rpath,$(MUMPS_DIR)/lib -L$(MUMPS_DIR)/lib -ldmumps\
-lmumps_common -lpord $(SCALAPACK_LIB) $(LAPACK_LIB) $(MPI_FORTRAN_LIB)
ifeq ($(MFEM_USE_SINGLE),YES)
MUMPS_LIB += -lsmumps
else
MUMPS_LIB += -ldmumps
endif
# STRUMPACK library configuration
STRUMPACK_DIR = @MFEM_DIR@/../STRUMPACK-build
-4
View File
@@ -9,11 +9,7 @@
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
#ifdef MFEM_USE_SINGLE
#include "smumps_c.h"
#else
#include "dmumps_c.h"
#endif
#include <string>
#include <iostream>
#include <algorithm>
-118
View File
@@ -1,118 +0,0 @@
SetFactory("OpenCASCADE");
order = 1;
R = 1;
r = 0.2;
Point(1) = {0,0,0};
Point(2) = {r/Sqrt(2),r/Sqrt(2),0};
Point(3) = {-r/Sqrt(2),r/Sqrt(2),0};
Point(4) = {-r/Sqrt(2),-r/Sqrt(2),0};
Point(5) = {r/Sqrt(2),-r/Sqrt(2),0};
Point(6) = {R,0,0};
Point(7) = {R/Sqrt(2),R/Sqrt(2),0};
Point(8) = {0,R,0};
Point(9) = {-R/Sqrt(2),R/Sqrt(2),0};
Point(10) = {-R,0,0};
Point(11) = {-R/Sqrt(2),-R/Sqrt(2),0};
Point(12) = {0,-R,0};
Point(13) = {R/Sqrt(2),-R/Sqrt(2),0};
Line(1) = {1,2};
Line(2) = {1,3};
Line(3) = {1,4};
Line(4) = {1,5};
Line(5) = {1,6};
Line(6) = {1,8};
Line(7) = {1,10};
Line(8) = {1,12};
Line(9) = {2,6};
Line(10) = {2,8};
Line(11) = {3,8};
Line(12) = {3,10};
Line(13) = {4,10};
Line(14) = {4,12};
Line(15) = {5,12};
Line(16) = {5,6};
Line(17) = {6,7};
Line(18) = {7,8};
Line(19) = {8,9};
Line(20) = {9,10};
Line(21) = {10,11};
Line(22) = {11,12};
Line(23) = {12,13};
Line(24) = {13,6};
Transfinite Curve{1:24} = 2;
Physical Curve("ENE") = {17};
Physical Curve("NNE") = {18};
Physical Curve("NNW") = {19};
Physical Curve("WNW") = {20};
Physical Curve("WSW") = {21};
Physical Curve("SSW") = {22};
Physical Curve("SSE") = {23};
Physical Curve("ESE") = {24};
Curve Loop(1) = {9,17,18,-10};
Curve Loop(2) = {11,19,20,-12};
Curve Loop(3) = {13,21,22,-14};
Curve Loop(4) = {15,23,24,-16};
Plane Surface(1) = {1};
Plane Surface(2) = {2};
Plane Surface(3) = {3};
Plane Surface(4) = {4};
Transfinite Surface{1} = {2,6,7,8};
Transfinite Surface{2} = {3,8,9,10};
Transfinite Surface{3} = {4,10,11,12};
Transfinite Surface{4} = {5,12,13,6};
Recombine Surface{1:4};
Physical Surface("Base") = {1,2,3,4};
Curve Loop(5) = {1,10,-6};
Plane Surface(5) = {5};
Physical Surface("N Even") = {5};
Curve Loop(6) = {6,-11,-2};
Plane Surface(6) = {6};
Physical Surface("N Odd") = {6};
Curve Loop(7) = {2,12,-7};
Plane Surface(7) = {7};
Physical Surface("W Even") = {7};
Curve Loop(8) = {7,-13,-3};
Plane Surface(8) = {8};
Physical Surface("W Odd") = {8};
Curve Loop(9) = {3,14,-8};
Plane Surface(9) = {9};
Physical Surface("S Even") = {9};
Curve Loop(10) = {8,-15,-4};
Plane Surface(10) = {10};
Physical Surface("S Odd") = {10};
Curve Loop(11) = {4,16,-5};
Plane Surface(11) = {11};
Physical Surface("E Even") = {11};
Curve Loop(12) = {5,-9,-1};
Plane Surface(12) = {12};
Physical Surface("E Odd") = {12};
// Generate 2D mesh
Mesh 2;
SetOrder order;
Mesh.MshFileVersion = 2.2;
Save "compass.msh";
-95
View File
@@ -1,95 +0,0 @@
MFEM mesh v1.3
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
2
elements
12
10 2 7 0 1
11 2 0 7 2
12 2 9 0 2
13 2 0 9 3
14 2 11 0 3
15 2 0 11 4
16 2 5 0 4
17 2 0 5 1
9 3 1 5 6 7
9 3 2 7 8 9
9 3 3 9 10 11
9 3 4 11 12 5
attribute_sets
16
"Base" 1 9
"E Even" 1 16
"E Odd" 1 17
"East" 2 16 17
"N Even" 1 10
"N Odd" 1 11
"North" 2 10 11
"Rose" 8 10 11 12 13 14 15 16 17
"Rose Even" 4 10 12 14 16
"Rose Odd" 4 11 13 15 17
"S Even" 1 14
"S Odd" 1 15
"South" 2 14 15
"W Even" 1 12
"W Odd" 1 13
"West" 2 12 13
boundary
8
1 1 5 6
2 1 6 7
3 1 7 8
4 1 8 9
5 1 9 10
6 1 10 11
7 1 11 12
8 1 12 5
bdr_attribute_sets
13
"Boundary" 8 1 2 3 4 5 6 7 8
"ENE" 1 1
"ESE" 1 8
"Eastern Boundary" 2 1 8
"NNE" 1 2
"NNW" 1 3
"Northern Boundary" 2 2 3
"SSE" 1 7
"SSW" 1 6
"Southern Boundary" 2 6 7
"WNW" 1 4
"WSW" 1 5
"Western Boundary" 2 4 5
vertices
13
2
0 0
0.14142136 0.14142136
-0.14142136 0.14142136
-0.14142136 -0.14142136
0.14142136 -0.14142136
1 0
0.70710678 0.70710678
0 1
-0.70710678 0.70710678
-1 0
-0.70710678 -0.70710678
0 -1
0.70710678 -0.70710678
mfem_mesh_end
-62
View File
@@ -1,62 +0,0 @@
$MeshFormat
2.2 0 8
$EndMeshFormat
$PhysicalNames
17
1 1 "ENE"
1 2 "NNE"
1 3 "NNW"
1 4 "WNW"
1 5 "WSW"
1 6 "SSW"
1 7 "SSE"
1 8 "ESE"
2 9 "Base"
2 10 "N Even"
2 11 "N Odd"
2 12 "W Even"
2 13 "W Odd"
2 14 "S Even"
2 15 "S Odd"
2 16 "E Even"
2 17 "E Odd"
$EndPhysicalNames
$Nodes
13
1 0 0 0
2 0.1414213562373095 0.1414213562373095 0
3 -0.1414213562373095 0.1414213562373095 0
4 -0.1414213562373095 -0.1414213562373095 0
5 0.1414213562373095 -0.1414213562373095 0
6 1 0 0
7 0.7071067811865475 0.7071067811865475 0
8 0 1 0
9 -0.7071067811865475 0.7071067811865475 0
10 -1 0 0
11 -0.7071067811865475 -0.7071067811865475 0
12 0 -1 0
13 0.7071067811865475 -0.7071067811865475 0
$EndNodes
$Elements
20
1 1 2 1 17 6 7
2 1 2 2 18 7 8
3 1 2 3 19 8 9
4 1 2 4 20 9 10
5 1 2 5 21 10 11
6 1 2 6 22 11 12
7 1 2 7 23 12 13
8 1 2 8 24 13 6
9 2 2 10 5 1 2 8
10 2 2 11 6 1 8 3
11 2 2 12 7 1 3 10
12 2 2 13 8 1 10 4
13 2 2 14 9 1 4 12
14 2 2 15 10 1 12 5
15 2 2 16 11 1 5 6
16 2 2 17 12 1 6 2
17 3 2 9 1 2 6 7 8
18 3 2 9 2 3 8 9 10
19 3 2 9 3 4 10 11 12
20 3 2 9 4 5 12 13 6
$EndElements
+7 -21
View File
@@ -43,11 +43,14 @@ list(APPEND ALL_EXE_SRCS
ex34.cpp
ex36.cpp
ex37.cpp
ex38.cpp
ex39.cpp
ex40.cpp
)
if(MFEM_USE_LAPACK)
list(APPEND ALL_EXE_SRCS
ex38.cpp
)
endif()
if (MFEM_USE_MPI)
list(APPEND ALL_EXE_SRCS
ex0p.cpp
@@ -87,21 +90,7 @@ if (MFEM_USE_MPI)
ex35p.cpp
ex36p.cpp
ex37p.cpp
ex39p.cpp
ex40p.cpp
)
endif()
# Examples that return MFEM_SKIP_RETURN_VALUE in some cases:
set(SKIP_TESTS)
if (HYPRE_USING_CUDA OR HYPRE_USING_HIP)
list(APPEND SKIP_TESTS ex19p.cpp ex28p.cpp)
endif()
if (MFEM_USE_SINGLE)
list(APPEND SKIP_TESTS ex33.cpp ex33p.cpp)
endif()
if (NOT MFEM_USE_LAPACK)
list(APPEND SKIP_TESTS ex38.cpp)
)
endif()
# Include the source directory where mfem.hpp and mfem-performance.hpp are.
@@ -113,9 +102,6 @@ add_mfem_examples(ALL_EXE_SRCS)
# Add a test for each example
if (MFEM_ENABLE_TESTING)
foreach(SRC_FILE ${ALL_EXE_SRCS})
if (SRC_FILE IN_LIST SKIP_TESTS)
continue()
endif()
get_filename_component(SRC_FILENAME ${SRC_FILE} NAME)
string(REPLACE ".cpp" "" TEST_NAME ${SRC_FILENAME})
+33 -43
View File
@@ -62,7 +62,7 @@ protected:
BilinearForm M, S;
NonlinearForm H;
real_t viscosity;
double viscosity;
HyperelasticModel *model;
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
@@ -84,16 +84,16 @@ protected:
public:
HyperelasticOperator(FiniteElementSpace &f, Array<int> &ess_bdr,
real_t visc, real_t mu, real_t K);
double visc, double mu, double K);
/// Compute the right-hand side of the ODE system.
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.*/
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k);
real_t ElasticEnergy(const Vector &x) const;
real_t KineticEnergy(const Vector &v) const;
double ElasticEnergy(const Vector &x) const;
double KineticEnergy(const Vector &v) const;
void GetElasticEnergyDensity(const GridFunction &x, GridFunction &w) const;
virtual ~HyperelasticOperator();
@@ -109,7 +109,7 @@ private:
BilinearForm *M, *S;
NonlinearForm *H;
mutable SparseMatrix *Jacobian;
real_t dt;
double dt;
const Vector *v, *x;
mutable Vector w, z;
@@ -117,7 +117,7 @@ public:
ReducedSystemOperator(BilinearForm *M_, BilinearForm *S_, NonlinearForm *H_);
/// Set current dt, v, x values - needed to compute action and Jacobian.
void SetParameters(real_t dt_, const Vector *v_, const Vector *x_);
void SetParameters(double dt_, const Vector *v_, const Vector *x_);
/// Compute y = H(x + dt (v + dt k)) + M k + S (v + dt k).
virtual void Mult(const Vector &k, Vector &y) const;
@@ -136,12 +136,12 @@ class ElasticEnergyCoefficient : public Coefficient
private:
HyperelasticModel &model;
const GridFunction &x;
DenseMatrix J;
mutable DenseMatrix J;
public:
ElasticEnergyCoefficient(HyperelasticModel &m, const GridFunction &x_)
: model(m), x(x_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const;
virtual ~ElasticEnergyCoefficient() { }
};
@@ -161,11 +161,11 @@ int main(int argc, char *argv[])
int ref_levels = 2;
int order = 2;
int ode_solver_type = 3;
real_t t_final = 300.0;
real_t dt = 3.0;
real_t visc = 1e-2;
real_t mu = 0.25;
real_t K = 5.0;
double t_final = 300.0;
double dt = 3.0;
double visc = 1e-2;
double mu = 0.25;
double K = 5.0;
bool visualization = true;
int vis_steps = 1;
@@ -309,13 +309,13 @@ int main(int argc, char *argv[])
<< " Press space (in the GLVis window) to resume it.\n";
}
real_t ee0 = oper.ElasticEnergy(x.GetTrueVector());
real_t 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;
real_t t = 0.0;
double t = 0.0;
oper.SetTime(t);
ode_solver->Init(oper);
@@ -324,7 +324,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);
ode_solver->Step(vx, t, dt_real);
@@ -332,8 +332,8 @@ int main(int argc, char *argv[])
if (last_step || (ti % vis_steps) == 0)
{
real_t ee = oper.ElasticEnergy(x.GetTrueVector());
real_t 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;
@@ -419,7 +419,7 @@ ReducedSystemOperator::ReducedSystemOperator(
dt(0.0), v(NULL), x(NULL), w(height), z(height)
{ }
void ReducedSystemOperator::SetParameters(real_t dt_, const Vector *v_,
void ReducedSystemOperator::SetParameters(double dt_, const Vector *v_,
const Vector *x_)
{
dt = dt_; v = v_; x = x_;
@@ -453,26 +453,16 @@ ReducedSystemOperator::~ReducedSystemOperator()
HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
Array<int> &ess_bdr, real_t visc,
real_t mu, real_t K)
: TimeDependentOperator(2*f.GetTrueVSize(), (real_t) 0.0), fespace(f),
Array<int> &ess_bdr, double visc,
double mu, double K)
: TimeDependentOperator(2*f.GetTrueVSize(), 0.0), fespace(f),
M(&fespace), S(&fespace), H(&fespace),
viscosity(visc), z(height/2)
{
#if defined(MFEM_USE_DOUBLE)
const real_t rel_tol = 1e-8;
const real_t newton_abs_tol = 0.0;
#elif defined(MFEM_USE_SINGLE)
const real_t rel_tol = 1e-3;
const real_t newton_abs_tol = 1e-4;
#else
#error "Only single and double precision are supported!"
const real_t rel_tol = real_t(1);
const real_t newton_abs_tol = real_t(0);
#endif
const double rel_tol = 1e-8;
const int skip_zero_entries = 0;
const real_t ref_density = 1.0; // density in the reference configuration
const double ref_density = 1.0; // density in the reference configuration
ConstantCoefficient rho0(ref_density);
M.AddDomainIntegrator(new VectorMassIntegrator(rho0));
M.Assemble(skip_zero_entries);
@@ -519,7 +509,7 @@ HyperelasticOperator::HyperelasticOperator(FiniteElementSpace &f,
newton_solver.SetOperator(*reduced_oper);
newton_solver.SetPrintLevel(1); // print Newton iterations
newton_solver.SetRelTol(rel_tol);
newton_solver.SetAbsTol(newton_abs_tol);
newton_solver.SetAbsTol(0.0);
newton_solver.SetMaxIter(10);
}
@@ -543,7 +533,7 @@ void HyperelasticOperator::Mult(const Vector &vx, Vector &dvx_dt) const
dx_dt = v;
}
void HyperelasticOperator::ImplicitSolve(const real_t dt,
void HyperelasticOperator::ImplicitSolve(const double dt,
const Vector &vx, Vector &dvx_dt)
{
int sc = height/2;
@@ -565,12 +555,12 @@ void HyperelasticOperator::ImplicitSolve(const real_t dt,
add(v, dt, dv_dt, dx_dt);
}
real_t HyperelasticOperator::ElasticEnergy(const Vector &x) const
double HyperelasticOperator::ElasticEnergy(const Vector &x) const
{
return H.GetEnergy(x);
}
real_t HyperelasticOperator::KineticEnergy(const Vector &v) const
double HyperelasticOperator::KineticEnergy(const Vector &v) const
{
return 0.5*M.InnerProduct(v, v);
}
@@ -591,8 +581,8 @@ HyperelasticOperator::~HyperelasticOperator()
}
real_t ElasticEnergyCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
double ElasticEnergyCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
model.SetTransformation(T);
x.GetVectorGradient(T, J);
@@ -611,7 +601,7 @@ void InitialDeformation(const Vector &x, Vector &y)
void InitialVelocity(const Vector &x, Vector &v)
{
const int dim = x.Size();
const real_t s = 0.1/64.;
const double s = 0.1/64.;
v = 0.0;
v(dim-1) = s*x(0)*x(0)*(8.0-x(0));
+37 -47
View File
@@ -63,7 +63,7 @@ protected:
ParBilinearForm M, S;
ParNonlinearForm H;
real_t viscosity;
double viscosity;
HyperelasticModel *model;
HypreParMatrix *Mmat; // Mass matrix from ParallelAssemble()
@@ -86,16 +86,16 @@ protected:
public:
HyperelasticOperator(ParFiniteElementSpace &f, Array<int> &ess_bdr,
real_t visc, real_t mu, real_t K);
double visc, double mu, double K);
/// Compute the right-hand side of the ODE system.
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.*/
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k);
real_t ElasticEnergy(const ParGridFunction &x) const;
real_t KineticEnergy(const ParGridFunction &v) const;
double ElasticEnergy(const ParGridFunction &x) const;
double KineticEnergy(const ParGridFunction &v) const;
void GetElasticEnergyDensity(const ParGridFunction &x,
ParGridFunction &w) const;
@@ -112,7 +112,7 @@ private:
ParBilinearForm *M, *S;
ParNonlinearForm *H;
mutable HypreParMatrix *Jacobian;
real_t dt;
double dt;
const Vector *v, *x;
mutable Vector w, z;
const Array<int> &ess_tdof_list;
@@ -122,7 +122,7 @@ public:
ParNonlinearForm *H_, const Array<int> &ess_tdof_list);
/// Set current dt, v, x values - needed to compute action and Jacobian.
void SetParameters(real_t dt_, const Vector *v_, const Vector *x_);
void SetParameters(double dt_, const Vector *v_, const Vector *x_);
/// Compute y = H(x + dt (v + dt k)) + M k + S (v + dt k).
virtual void Mult(const Vector &k, Vector &y) const;
@@ -141,12 +141,12 @@ class ElasticEnergyCoefficient : public Coefficient
private:
HyperelasticModel &model;
const ParGridFunction &x;
DenseMatrix J;
mutable DenseMatrix J;
public:
ElasticEnergyCoefficient(HyperelasticModel &m, const ParGridFunction &x_)
: model(m), x(x_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const;
virtual ~ElasticEnergyCoefficient() { }
};
@@ -173,11 +173,11 @@ int main(int argc, char *argv[])
int par_ref_levels = 0;
int order = 2;
int ode_solver_type = 3;
real_t t_final = 300.0;
real_t dt = 3.0;
real_t visc = 1e-2;
real_t mu = 0.25;
real_t K = 5.0;
double t_final = 300.0;
double dt = 3.0;
double visc = 1e-2;
double mu = 0.25;
double K = 5.0;
bool adaptive_lin_rtol = true;
bool visualization = true;
int vis_steps = 1;
@@ -358,8 +358,8 @@ int main(int argc, char *argv[])
}
}
real_t ee0 = oper.ElasticEnergy(x_gf);
real_t 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;
@@ -367,7 +367,7 @@ int main(int argc, char *argv[])
cout << "initial total energy (TE) = " << (ee0 + ke0) << endl;
}
real_t t = 0.0;
double t = 0.0;
oper.SetTime(t);
ode_solver->Init(oper);
@@ -376,7 +376,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);
ode_solver->Step(vx, t, dt_real);
@@ -386,8 +386,8 @@ int main(int argc, char *argv[])
{
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
real_t ee = oper.ElasticEnergy(x_gf);
real_t ke = oper.KineticEnergy(v_gf);
double ee = oper.ElasticEnergy(x_gf);
double ke = oper.KineticEnergy(v_gf);
if (myid == 0)
{
@@ -485,7 +485,7 @@ ReducedSystemOperator::ReducedSystemOperator(
ess_tdof_list(ess_tdof_list_)
{ }
void ReducedSystemOperator::SetParameters(real_t dt_, const Vector *v_,
void ReducedSystemOperator::SetParameters(double dt_, const Vector *v_,
const Vector *x_)
{
dt = dt_; v = v_; x = x_;
@@ -523,27 +523,17 @@ ReducedSystemOperator::~ReducedSystemOperator()
HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
Array<int> &ess_bdr, real_t visc,
real_t mu, real_t K)
: TimeDependentOperator(2*f.TrueVSize(), (real_t) 0.0), fespace(f),
Array<int> &ess_bdr, double visc,
double mu, double K)
: TimeDependentOperator(2*f.TrueVSize(), 0.0), fespace(f),
M(&fespace), S(&fespace), H(&fespace),
viscosity(visc), M_solver(f.GetComm()), newton_solver(f.GetComm()),
z(height/2)
{
#if defined(MFEM_USE_DOUBLE)
const real_t rel_tol = 1e-8;
const real_t newton_abs_tol = 0.0;
#elif defined(MFEM_USE_SINGLE)
const real_t rel_tol = 1e-3;
const real_t newton_abs_tol = 1e-4;
#else
#error "Only single and double precision are supported!"
const real_t rel_tol = real_t(1);
const real_t newton_abs_tol = real_t(0);
#endif
const double rel_tol = 1e-8;
const int skip_zero_entries = 0;
const real_t ref_density = 1.0; // density in the reference configuration
const double ref_density = 1.0; // density in the reference configuration
ConstantCoefficient rho0(ref_density);
M.AddDomainIntegrator(new VectorMassIntegrator(rho0));
M.Assemble(skip_zero_entries);
@@ -591,7 +581,7 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
newton_solver.SetOperator(*reduced_oper);
newton_solver.SetPrintLevel(1); // print Newton iterations
newton_solver.SetRelTol(rel_tol);
newton_solver.SetAbsTol(newton_abs_tol);
newton_solver.SetAbsTol(0.0);
newton_solver.SetAdaptiveLinRtol(2, 0.5, 0.9);
newton_solver.SetMaxIter(10);
}
@@ -617,7 +607,7 @@ void HyperelasticOperator::Mult(const Vector &vx, Vector &dvx_dt) const
dx_dt = v;
}
void HyperelasticOperator::ImplicitSolve(const real_t dt,
void HyperelasticOperator::ImplicitSolve(const double dt,
const Vector &vx, Vector &dvx_dt)
{
int sc = height/2;
@@ -639,17 +629,17 @@ void HyperelasticOperator::ImplicitSolve(const real_t dt,
add(v, dt, dv_dt, dx_dt);
}
real_t HyperelasticOperator::ElasticEnergy(const ParGridFunction &x) const
double HyperelasticOperator::ElasticEnergy(const ParGridFunction &x) const
{
return H.GetEnergy(x);
}
real_t HyperelasticOperator::KineticEnergy(const ParGridFunction &v) const
double HyperelasticOperator::KineticEnergy(const ParGridFunction &v) const
{
real_t loc_energy = 0.5*M.InnerProduct(v, v);
real_t energy;
MPI_Allreduce(&loc_energy, &energy, 1, MPITypeMap<real_t>::mpi_type,
MPI_SUM, fespace.GetComm());
double loc_energy = 0.5*M.InnerProduct(v, v);
double energy;
MPI_Allreduce(&loc_energy, &energy, 1, MPI_DOUBLE, MPI_SUM,
fespace.GetComm());
return energy;
}
@@ -670,8 +660,8 @@ HyperelasticOperator::~HyperelasticOperator()
}
real_t ElasticEnergyCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
double ElasticEnergyCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
model.SetTransformation(T);
x.GetVectorGradient(T, J);
@@ -690,7 +680,7 @@ void InitialDeformation(const Vector &x, Vector &y)
void InitialVelocity(const Vector &x, Vector &v)
{
const int dim = x.Size();
const real_t s = 0.1/64.;
const double s = 0.1/64.;
v = 0.0;
v(dim-1) = s*x(0)*x(0)*(8.0-x(0));
+2 -2
View File
@@ -211,7 +211,7 @@ int main(int argc, char *argv[])
m->AddDomainIntegrator(new MassIntegrator(one));
m->Assemble();
// shift the eigenvalue corresponding to eliminated dofs to a large value
m->EliminateEssentialBCDiag(ess_bdr, numeric_limits<real_t>::min());
m->EliminateEssentialBCDiag(ess_bdr, numeric_limits<double>::min());
m->Finalize();
HypreParMatrix *A = a->ParallelAssemble();
@@ -300,7 +300,7 @@ int main(int argc, char *argv[])
// 9. Compute the eigenmodes and extract the array of eigenvalues. Define a
// parallel grid function to represent each of the eigenmodes returned by
// the solver.
Array<real_t> eigenvalues;
Array<double> eigenvalues;
lobpcg->Solve();
lobpcg->GetEigenvalues(eigenvalues);
ParGridFunction x(fespace);
+2 -2
View File
@@ -206,7 +206,7 @@ int main(int argc, char *argv[])
m->AddDomainIntegrator(new VectorMassIntegrator());
m->Assemble();
// shift the eigenvalue corresponding to eliminated dofs to a large value
m->EliminateEssentialBCDiag(ess_bdr, numeric_limits<real_t>::min());
m->EliminateEssentialBCDiag(ess_bdr, numeric_limits<double>::min());
m->Finalize();
if (myid == 0)
{
@@ -247,7 +247,7 @@ int main(int argc, char *argv[])
// 10. Compute the eigenmodes and extract the array of eigenvalues. Define a
// parallel grid function to represent each of the eigenmodes returned by
// the solver.
Array<real_t> eigenvalues;
Array<double> eigenvalues;
lobpcg->Solve();
lobpcg->GetEigenvalues(eigenvalues);
ParGridFunction x(fespace);
+2 -2
View File
@@ -170,7 +170,7 @@ int main(int argc, char *argv[])
m->AddDomainIntegrator(new VectorFEMassIntegrator(one));
m->Assemble();
// shift the eigenvalue corresponding to eliminated dofs to a large value
m->EliminateEssentialBCDiag(ess_bdr, numeric_limits<real_t>::min());
m->EliminateEssentialBCDiag(ess_bdr, numeric_limits<double>::min());
m->Finalize();
HypreParMatrix *A = a->ParallelAssemble();
@@ -198,7 +198,7 @@ int main(int argc, char *argv[])
// 10. Compute the eigenmodes and extract the array of eigenvalues. Define a
// parallel grid function to represent each of the eigenmodes returned by
// the solver.
Array<real_t> eigenvalues;
Array<double> eigenvalues;
ame->Solve();
ame->GetEigenvalues(eigenvalues);
ParGridFunction x(fespace);
+3 -3
View File
@@ -43,9 +43,9 @@ int main(int argc, char *argv[])
const char *mesh_file = "../data/star.mesh";
int ref_levels = -1;
int order = 1;
real_t sigma = -1.0;
real_t kappa = -1.0;
real_t eta = 0.0;
double sigma = -1.0;
double kappa = -1.0;
double eta = 0.0;
bool visualization = 1;
OptionsParser args(argc, argv);
+4 -4
View File
@@ -44,7 +44,7 @@ public:
pmesh(m),
pgf(f) {}
void MonitorSolution(int i, real_t norm, const Vector &x, bool final)
void MonitorSolution(int i, double norm, const Vector &x, bool final)
{
char vishost[] = "localhost";
int visport = 19916;
@@ -81,9 +81,9 @@ int main(int argc, char *argv[])
int ser_ref_levels = -1;
int par_ref_levels = 2;
int order = 1;
real_t sigma = -1.0;
real_t kappa = -1.0;
real_t eta = 0.0;
double sigma = -1.0;
double kappa = -1.0;
double eta = 0.0;
bool visualization = 1;
OptionsParser args(argc, argv);
+30 -30
View File
@@ -63,8 +63,8 @@ int problem;
int nfeatures;
// Prescribed time-dependent boundary and right-hand side functions.
real_t bdr_func(const Vector &pt, real_t t);
real_t rhs_func(const Vector &pt, real_t t);
double bdr_func(const Vector &pt, double t);
double rhs_func(const Vector &pt, double t);
// Update the finite element space, interpolate the solution and perform
// parallel load balancing.
@@ -79,9 +79,9 @@ int main(int argc, char *argv[])
nfeatures = 1;
const char *mesh_file = "../data/star-hilbert.mesh";
int order = 2;
real_t t_final = 1.0;
real_t max_elem_error = 5.0e-3;
real_t hysteresis = 0.15; // derefinement safety coefficient
double t_final = 1.0;
double max_elem_error = 5.0e-3;
double hysteresis = 0.15; // derefinement safety coefficient
int ref_levels = 0;
int nc_limit = 3; // maximum level of hanging nodes
bool visualization = true;
@@ -247,7 +247,7 @@ int main(int argc, char *argv[])
// refine the mesh as many times as necessary. Then we derefine any
// elements which have very small errors.
x = 0.0;
for (real_t time = 0.0; time < t_final + 1e-10; time += 0.01)
for (double time = 0.0; time < t_final + 1e-10; time += 0.01)
{
cout << "\nTime " << time << "\n\nRefinement:" << endl;
@@ -366,47 +366,47 @@ void UpdateProblem(Mesh &mesh, FiniteElementSpace &fespace,
}
const real_t alpha = 0.02;
const double alpha = 0.02;
// Spherical front with a Gaussian cross section and radius t
real_t front(real_t x, real_t y, real_t z, real_t t, int)
double front(double x, double y, double z, double t, int)
{
real_t r = sqrt(x*x + y*y + z*z);
double r = sqrt(x*x + y*y + z*z);
return exp(-0.5*pow((r - t)/alpha, 2));
}
real_t front_laplace(real_t x, real_t y, real_t z, real_t t, int dim)
double front_laplace(double x, double y, double z, double t, int dim)
{
real_t x2 = x*x, y2 = y*y, z2 = z*z, t2 = t*t;
real_t r = sqrt(x2 + y2 + z2);
real_t a2 = alpha*alpha, a4 = a2*a2;
double x2 = x*x, y2 = y*y, z2 = z*z, t2 = t*t;
double r = sqrt(x2 + y2 + z2);
double a2 = alpha*alpha, a4 = a2*a2;
return -exp(-0.5*pow((r - t)/alpha, 2)) / a4 *
(-2*t*(x2 + y2 + z2 - (dim-1)*a2/2)/r + x2 + y2 + z2 + t2 - dim*a2);
}
// Smooth spherical step function with radius t
real_t ball(real_t x, real_t y, real_t z, real_t t, int)
double ball(double x, double y, double z, double t, int)
{
real_t r = sqrt(x*x + y*y + z*z);
double r = sqrt(x*x + y*y + z*z);
return -atan(2*(r - t)/alpha);
}
real_t ball_laplace(real_t x, real_t y, real_t z, real_t t, int dim)
double ball_laplace(double x, double y, double z, double t, int dim)
{
real_t x2 = x*x, y2 = y*y, z2 = z*z, t2 = 4*t*t;
real_t r = sqrt(x2 + y2 + z2);
real_t a2 = alpha*alpha;
real_t den = pow(-a2 - 4*(x2 + y2 + z2 - 2*r*t) - t2, 2.0);
double x2 = x*x, y2 = y*y, z2 = z*z, t2 = 4*t*t;
double r = sqrt(x2 + y2 + z2);
double a2 = alpha*alpha;
double den = pow(-a2 - 4*(x2 + y2 + z2 - 2*r*t) - t2, 2.0);
return (dim == 2) ? 2*alpha*(a2 + t2 - 4*x2 - 4*y2)/r/den
/* */ : 4*alpha*(a2 + t2 - 4*r*t)/r/den;
}
// Composes several features into one function
template<typename F0, typename F1>
real_t composite_func(const Vector &pt, real_t t, F0 f0, F1 f1)
double composite_func(const Vector &pt, double t, F0 f0, F1 f1)
{
int dim = pt.Size();
real_t x = pt(0), y = pt(1), z = 0.0;
double x = pt(0), y = pt(1), z = 0.0;
if (dim == 3) { z = pt(2); }
if (problem == 0)
@@ -417,11 +417,11 @@ real_t composite_func(const Vector &pt, real_t t, F0 f0, F1 f1)
}
else
{
real_t sum = 0.0;
double sum = 0.0;
for (int i = 0; i < nfeatures; i++)
{
real_t x0 = 0.5*cos(2*M_PI * i / nfeatures);
real_t y0 = 0.5*sin(2*M_PI * i / nfeatures);
double x0 = 0.5*cos(2*M_PI * i / nfeatures);
double y0 = 0.5*sin(2*M_PI * i / nfeatures);
sum += f0(x - x0, y - y0, z, t, dim);
}
return sum;
@@ -429,11 +429,11 @@ real_t composite_func(const Vector &pt, real_t t, F0 f0, F1 f1)
}
else
{
real_t sum = 0.0;
double sum = 0.0;
for (int i = 0; i < nfeatures; i++)
{
real_t x0 = 0.5*cos(2*M_PI * i / nfeatures + M_PI*t);
real_t y0 = 0.5*sin(2*M_PI * i / nfeatures + M_PI*t);
double x0 = 0.5*cos(2*M_PI * i / nfeatures + M_PI*t);
double y0 = 0.5*sin(2*M_PI * i / nfeatures + M_PI*t);
sum += f1(x - x0, y - y0, z, 0.25, dim);
}
return sum;
@@ -441,13 +441,13 @@ real_t composite_func(const Vector &pt, real_t t, F0 f0, F1 f1)
}
// Exact solution, used for the Dirichlet BC.
real_t bdr_func(const Vector &pt, real_t t)
double bdr_func(const Vector &pt, double t)
{
return composite_func(pt, t, front, ball);
}
// Laplace of the exact solution, used for the right hand side.
real_t rhs_func(const Vector &pt, real_t t)
double rhs_func(const Vector &pt, double t)
{
return composite_func(pt, t, front_laplace, ball_laplace);
}
+30 -30
View File
@@ -68,8 +68,8 @@ int problem;
int nfeatures;
// Prescribed time-dependent boundary and right-hand side functions.
real_t bdr_func(const Vector &pt, real_t t);
real_t rhs_func(const Vector &pt, real_t t);
double bdr_func(const Vector &pt, double t);
double rhs_func(const Vector &pt, double t);
// Update the finite element space, interpolate the solution and perform
// parallel load balancing.
@@ -91,9 +91,9 @@ int main(int argc, char *argv[])
nfeatures = 1;
const char *mesh_file = "../data/star-hilbert.mesh";
int order = 2;
real_t t_final = 1.0;
real_t max_elem_error = 1.0e-4;
real_t hysteresis = 0.25; // derefinement safety coefficient
double t_final = 1.0;
double max_elem_error = 1.0e-4;
double hysteresis = 0.25; // derefinement safety coefficient
int ref_levels = 0;
int nc_limit = 3; // maximum level of hanging nodes
bool visualization = true;
@@ -282,7 +282,7 @@ int main(int argc, char *argv[])
// solve the problem on the current mesh, visualize the solution and
// refine the mesh as many times as necessary. Then we derefine any
// elements which have very small errors.
for (real_t time = 0.0; time < t_final + 1e-10; time += 0.01)
for (double time = 0.0; time < t_final + 1e-10; time += 0.01)
{
if (myid == 0)
{
@@ -427,47 +427,47 @@ void UpdateAndRebalance(ParMesh &pmesh, ParFiniteElementSpace &fespace,
}
const real_t alpha = 0.02;
const double alpha = 0.02;
// Spherical front with a Gaussian cross section and radius t
real_t front(real_t x, real_t y, real_t z, real_t t, int)
double front(double x, double y, double z, double t, int)
{
real_t r = sqrt(x*x + y*y + z*z);
double r = sqrt(x*x + y*y + z*z);
return exp(-0.5*pow((r - t)/alpha, 2));
}
real_t front_laplace(real_t x, real_t y, real_t z, real_t t, int dim)
double front_laplace(double x, double y, double z, double t, int dim)
{
real_t x2 = x*x, y2 = y*y, z2 = z*z, t2 = t*t;
real_t r = sqrt(x2 + y2 + z2);
real_t a2 = alpha*alpha, a4 = a2*a2;
double x2 = x*x, y2 = y*y, z2 = z*z, t2 = t*t;
double r = sqrt(x2 + y2 + z2);
double a2 = alpha*alpha, a4 = a2*a2;
return -exp(-0.5*pow((r - t)/alpha, 2)) / a4 *
(-2*t*(x2 + y2 + z2 - (dim-1)*a2/2)/r + x2 + y2 + z2 + t2 - dim*a2);
}
// Smooth spherical step function with radius t
real_t ball(real_t x, real_t y, real_t z, real_t t, int)
double ball(double x, double y, double z, double t, int)
{
real_t r = sqrt(x*x + y*y + z*z);
double r = sqrt(x*x + y*y + z*z);
return -atan(2*(r - t)/alpha);
}
real_t ball_laplace(real_t x, real_t y, real_t z, real_t t, int dim)
double ball_laplace(double x, double y, double z, double t, int dim)
{
real_t x2 = x*x, y2 = y*y, z2 = z*z, t2 = 4*t*t;
real_t r = sqrt(x2 + y2 + z2);
real_t a2 = alpha*alpha;
real_t den = pow(-a2 - 4*(x2 + y2 + z2 - 2*r*t) - t2, 2.0);
double x2 = x*x, y2 = y*y, z2 = z*z, t2 = 4*t*t;
double r = sqrt(x2 + y2 + z2);
double a2 = alpha*alpha;
double den = pow(-a2 - 4*(x2 + y2 + z2 - 2*r*t) - t2, 2.0);
return (dim == 2) ? 2*alpha*(a2 + t2 - 4*x2 - 4*y2)/r/den
/* */ : 4*alpha*(a2 + t2 - 4*r*t)/r/den;
}
// Composes several features into one function
template<typename F0, typename F1>
real_t composite_func(const Vector &pt, real_t t, F0 f0, F1 f1)
double composite_func(const Vector &pt, double t, F0 f0, F1 f1)
{
int dim = pt.Size();
real_t x = pt(0), y = pt(1), z = 0.0;
double x = pt(0), y = pt(1), z = 0.0;
if (dim == 3) { z = pt(2); }
if (problem == 0)
@@ -478,11 +478,11 @@ real_t composite_func(const Vector &pt, real_t t, F0 f0, F1 f1)
}
else
{
real_t sum = 0.0;
double sum = 0.0;
for (int i = 0; i < nfeatures; i++)
{
real_t x0 = 0.5*cos(2*M_PI * i / nfeatures);
real_t y0 = 0.5*sin(2*M_PI * i / nfeatures);
double x0 = 0.5*cos(2*M_PI * i / nfeatures);
double y0 = 0.5*sin(2*M_PI * i / nfeatures);
sum += f0(x - x0, y - y0, z, t, dim);
}
return sum;
@@ -490,11 +490,11 @@ real_t composite_func(const Vector &pt, real_t t, F0 f0, F1 f1)
}
else
{
real_t sum = 0.0;
double sum = 0.0;
for (int i = 0; i < nfeatures; i++)
{
real_t x0 = 0.5*cos(2*M_PI * i / nfeatures + M_PI*t);
real_t y0 = 0.5*sin(2*M_PI * i / nfeatures + M_PI*t);
double x0 = 0.5*cos(2*M_PI * i / nfeatures + M_PI*t);
double y0 = 0.5*sin(2*M_PI * i / nfeatures + M_PI*t);
sum += f1(x - x0, y - y0, z, 0.25, dim);
}
return sum;
@@ -502,13 +502,13 @@ real_t composite_func(const Vector &pt, real_t t, F0 f0, F1 f1)
}
// Exact solution, used for the Dirichlet BC.
real_t bdr_func(const Vector &pt, real_t t)
double bdr_func(const Vector &pt, double t)
{
return composite_func(pt, t, front, ball);
}
// Laplace of the exact solution, used for the right hand side.
real_t rhs_func(const Vector &pt, real_t t)
double rhs_func(const Vector &pt, double t)
{
return composite_func(pt, t, front_laplace, ball_laplace);
}
+17 -17
View File
@@ -60,7 +60,7 @@ protected:
SparseMatrix Mmat, Kmat;
SparseMatrix *T; // T = M + dt K
real_t current_dt;
double current_dt;
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
DSmoother M_prec; // Preconditioner for the mass matrix M
@@ -68,18 +68,18 @@ protected:
CGSolver T_solver; // Implicit solver for T = M + dt K
DSmoother T_prec; // Preconditioner for the implicit solver
real_t alpha, kappa;
double alpha, kappa;
mutable Vector z; // auxiliary vector
public:
ConductionOperator(FiniteElementSpace &f, real_t alpha, real_t kappa,
ConductionOperator(FiniteElementSpace &f, double alpha, double kappa,
const Vector &u);
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.*/
virtual void ImplicitSolve(const real_t dt, const Vector &u, Vector &k);
virtual void ImplicitSolve(const double dt, const Vector &u, Vector &k);
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
void SetParameters(const Vector &u);
@@ -87,7 +87,7 @@ public:
virtual ~ConductionOperator();
};
real_t InitialTemperature(const Vector &x);
double InitialTemperature(const Vector &x);
int main(int argc, char *argv[])
{
@@ -96,10 +96,10 @@ int main(int argc, char *argv[])
int ref_levels = 2;
int order = 2;
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;
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;
@@ -246,7 +246,7 @@ int main(int argc, char *argv[])
// 8. Perform time-integration (looping over the time iterations, ti, with a
// time-step dt).
ode_solver->Init(oper);
real_t t = 0.0;
double t = 0.0;
bool last_step = false;
for (int ti = 1; !last_step; ti++)
@@ -293,12 +293,12 @@ int main(int argc, char *argv[])
return 0;
}
ConductionOperator::ConductionOperator(FiniteElementSpace &f, real_t al,
real_t kap, const Vector &u)
: TimeDependentOperator(f.GetTrueVSize(), (real_t) 0.0), fespace(f),
M(NULL), K(NULL), T(NULL), current_dt(0.0), 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), current_dt(0.0), z(height)
{
const real_t rel_tol = 1e-8;
const double rel_tol = 1e-8;
M = new BilinearForm(&fespace);
M->AddDomainIntegrator(new MassIntegrator());
@@ -336,7 +336,7 @@ void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
M_solver.Mult(z, du_dt);
}
void ConductionOperator::ImplicitSolve(const real_t dt,
void ConductionOperator::ImplicitSolve(const double dt,
const Vector &u, Vector &du_dt)
{
// Solve the equation:
@@ -382,7 +382,7 @@ ConductionOperator::~ConductionOperator()
delete K;
}
real_t InitialTemperature(const Vector &x)
double InitialTemperature(const Vector &x)
{
if (x.Norml2() < 0.5)
{
+17 -17
View File
@@ -62,7 +62,7 @@ protected:
HypreParMatrix Mmat;
HypreParMatrix Kmat;
HypreParMatrix *T; // T = M + dt K
real_t current_dt;
double current_dt;
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
HypreSmoother M_prec; // Preconditioner for the mass matrix M
@@ -70,18 +70,18 @@ protected:
CGSolver T_solver; // Implicit solver for T = M + dt K
HypreSmoother T_prec; // Preconditioner for the implicit solver
real_t alpha, kappa;
double alpha, kappa;
mutable Vector z; // auxiliary vector
public:
ConductionOperator(ParFiniteElementSpace &f, real_t alpha, real_t kappa,
ConductionOperator(ParFiniteElementSpace &f, double alpha, double kappa,
const Vector &u);
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.*/
virtual void ImplicitSolve(const real_t dt, const Vector &u, Vector &k);
virtual void ImplicitSolve(const double dt, const Vector &u, Vector &k);
/// Update the diffusion BilinearForm K using the given true-dof vector `u`.
void SetParameters(const Vector &u);
@@ -89,7 +89,7 @@ public:
virtual ~ConductionOperator();
};
real_t InitialTemperature(const Vector &x);
double InitialTemperature(const Vector &x);
int main(int argc, char *argv[])
{
@@ -105,10 +105,10 @@ int main(int argc, char *argv[])
int par_ref_levels = 1;
int order = 2;
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;
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;
@@ -313,7 +313,7 @@ int main(int argc, char *argv[])
// 10. Perform time-integration (looping over the time iterations, ti, with a
// time-step dt).
ode_solver->Init(oper);
real_t t = 0.0;
double t = 0.0;
bool last_step = false;
for (int ti = 1; !last_step; ti++)
@@ -382,13 +382,13 @@ int main(int argc, char *argv[])
return 0;
}
ConductionOperator::ConductionOperator(ParFiniteElementSpace &f, real_t al,
real_t kap, const Vector &u)
: TimeDependentOperator(f.GetTrueVSize(), (real_t) 0.0), fespace(f),
M(NULL), K(NULL), T(NULL), current_dt(0.0),
ConductionOperator::ConductionOperator(ParFiniteElementSpace &f, double al,
double kap, const Vector &u)
: TimeDependentOperator(f.GetTrueVSize(), 0.0), fespace(f), M(NULL), K(NULL),
T(NULL), current_dt(0.0),
M_solver(f.GetComm()), T_solver(f.GetComm()), z(height)
{
const real_t rel_tol = 1e-8;
const double rel_tol = 1e-8;
M = new ParBilinearForm(&fespace);
M->AddDomainIntegrator(new MassIntegrator());
@@ -427,7 +427,7 @@ void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
M_solver.Mult(z, du_dt);
}
void ConductionOperator::ImplicitSolve(const real_t dt,
void ConductionOperator::ImplicitSolve(const double dt,
const Vector &u, Vector &du_dt)
{
// Solve the equation:
@@ -473,7 +473,7 @@ ConductionOperator::~ConductionOperator()
delete K;
}
real_t InitialTemperature(const Vector &x)
double InitialTemperature(const Vector &x)
{
if (x.Norml2() < 0.5)
{
+10 -10
View File
@@ -60,7 +60,7 @@ protected:
GridFunction *u; // displacement
int si, sj; // component of the stress to evaluate, 0 <= si,sj < dim
DenseMatrix grad; // auxiliary matrix, used in Eval
mutable DenseMatrix grad; // auxiliary matrix, used in Eval
public:
StressCoefficient(Coefficient &lambda_, Coefficient &mu_)
@@ -69,7 +69,7 @@ public:
void SetDisplacement(GridFunction &u_) { u = &u_; }
void SetComponent(int i, int j) { si = i; sj = j; }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const;
};
// Simple GLVis visualization manager.
@@ -104,8 +104,8 @@ int main(int argc, char *argv[])
const char *mesh_file = "../data/beam-tri.mesh";
int ref_levels = -1;
int order = 1;
real_t alpha = -1.0;
real_t kappa = -1.0;
double alpha = -1.0;
double kappa = -1.0;
bool visualization = 1;
OptionsParser args(argc, argv);
@@ -245,7 +245,7 @@ int main(int argc, char *argv[])
// solve the system Ax=b with PCG for the symmetric formulation, or GMRES
// for the non-symmetric.
GSSmoother M(A);
const real_t rtol = 1e-6;
const double rtol = 1e-6;
if (alpha == -1.0)
{
PCG(A, M, B, X, 3, 5000, rtol*rtol, 0.0);
@@ -337,17 +337,17 @@ void InitDisplacement(const Vector &x, Vector &u)
}
real_t StressCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
double StressCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
MFEM_ASSERT(u != NULL, "displacement field is not set");
real_t L = lambda.Eval(T, ip);
real_t M = mu.Eval(T, ip);
double L = lambda.Eval(T, ip);
double M = mu.Eval(T, ip);
u->GetVectorGradient(T, grad);
if (si == sj)
{
real_t div_u = grad.Trace();
double div_u = grad.Trace();
return L*div_u + 2*M*grad(si,si);
}
else
+10 -10
View File
@@ -60,7 +60,7 @@ protected:
GridFunction *u; // displacement
int si, sj; // component of the stress to evaluate, 0 <= si,sj < dim
DenseMatrix grad; // auxiliary matrix, used in Eval
mutable DenseMatrix grad; // auxiliary matrix, used in Eval
public:
StressCoefficient(Coefficient &lambda_, Coefficient &mu_)
@@ -69,7 +69,7 @@ public:
void SetDisplacement(GridFunction &u_) { u = &u_; }
void SetComponent(int i, int j) { si = i; sj = j; }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const;
};
// Simple GLVis visualization manager.
@@ -108,8 +108,8 @@ int main(int argc, char *argv[])
int ser_ref_levels = -1;
int par_ref_levels = 1;
int order = 1;
real_t alpha = -1.0;
real_t kappa = -1.0;
double alpha = -1.0;
double kappa = -1.0;
bool amg_elast = false;
bool visualization = 1;
@@ -268,7 +268,7 @@ int main(int argc, char *argv[])
// 11. Define a simple symmetric Gauss-Seidel preconditioner and use it to
// solve the system Ax=b with PCG for the symmetric formulation, or GMRES
// for the non-symmetric.
const real_t rtol = 1e-6;
const double rtol = 1e-6;
HypreBoomerAMG amg(A);
if (amg_elast)
{
@@ -376,17 +376,17 @@ void InitDisplacement(const Vector &x, Vector &u)
}
real_t StressCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
double StressCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
MFEM_ASSERT(u != NULL, "displacement field is not set");
real_t L = lambda.Eval(T, ip);
real_t M = mu.Eval(T, ip);
double L = lambda.Eval(T, ip);
double M = mu.Eval(T, ip);
u->GetVectorGradient(T, grad);
if (si == sj)
{
real_t div_u = grad.Trace();
double div_u = grad.Trace();
return L*div_u + 2*M*grad(si,si);
}
else
+123 -125
View File
@@ -7,19 +7,13 @@
// ex18 -p 1 -r 2 -o 1 -s 3
// ex18 -p 1 -r 1 -o 3 -s 4
// ex18 -p 1 -r 0 -o 5 -s 6
// ex18 -p 2 -r 1 -o 1 -s 3 -mf
// ex18 -p 2 -r 0 -o 3 -s 3 -mf
// ex18 -p 2 -r 1 -o 1 -s 3
// ex18 -p 2 -r 0 -o 3 -s 3
//
// Description: This example code solves the compressible Euler system of
// equations, a model nonlinear hyperbolic PDE, with a
// discontinuous Galerkin (DG) formulation.
//
// (u_t, v)_T - (F(u), ∇ v)_T + <F̂(u,n), [[v]]>_F = 0
//
// where (⋅,⋅)_T is volume integration, and <⋅,⋅>_F is face
// integration, F is the Euler flux function, and F̂ is the
// numerical flux.
//
// Specifically, it solves for an exact solution of the equations
// whereby a vortex is transported by a uniform flow. Since all
// boundaries are periodic here, the method's accuracy can be
@@ -33,47 +27,49 @@
// method. An additional factor can be tuned by passing the --cfl
// (or -c shorter) flag.
//
// The example demonstrates usage of DGHyperbolicConservationLaws
// that wraps NonlinearFormIntegrators containing element and face
// integration schemes. In this case the system also involves an
// external approximate Riemann solver for the DG interface flux.
// By default, weak-divergence is pre-assembled in element-wise
// manner, which corresponds to (I_h(F(u_h)), ∇ v). This yields
// better performance and similar accuracy for the included test
// problems. This can be turned off and use nonlinear assembly
// similar to matrix-free assembly when -mf flag is provided.
// It also demonstrates how to use GLVis for in-situ visualization
// of vector grid function and how to set top-view.
// The example demonstrates user-defined bilinear and nonlinear
// form integrators for systems of equations that are defined with
// block vectors, and how these are used with an operator for
// explicit time integrators. In this case the system also
// involves an external approximate Riemann solver for the DG
// interface flux. It also demonstrates how to use GLVis for
// in-situ visualization of vector grid functions.
//
// We recommend viewing examples 9, 14 and 17 before viewing this
// example.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include <sstream>
#include <iostream>
// Classes FE_Evolution, RiemannSolver, and FaceIntegrator
// shared between the serial and parallel version of the example.
#include "ex18.hpp"
using namespace std;
using namespace mfem;
// Choice for the problem setup. See InitialCondition in ex18.hpp.
int problem;
// Equation constant parameters.
const int num_equation = 4;
const double specific_heat_ratio = 1.4;
const double gas_constant = 1.0;
// Maximum characteristic speed (updated by integrators)
double max_char_speed;
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
int problem = 1;
const real_t specific_heat_ratio = 1.4;
const real_t gas_constant = 1.0;
string mesh_file = "";
int IntOrderOffset = 1;
problem = 1;
const char *mesh_file = "../data/periodic-square.mesh";
int ref_levels = 1;
int order = 3;
int ode_solver_type = 4;
real_t t_final = 2.0;
real_t dt = -0.01;
real_t cfl = 0.3;
double t_final = 2.0;
double dt = -0.01;
double cfl = 0.3;
bool visualization = true;
bool preassembleWeakDiv = true;
int vis_steps = 50;
int precision = 8;
@@ -81,10 +77,9 @@ int main(int argc, char *argv[])
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use. If not provided, then a periodic square"
" mesh will be used.");
"Mesh file to use.");
args.AddOption(&problem, "-p", "--problem",
"Problem setup to use. See EulerInitialCondition().");
"Problem setup to use. See options in velocity_function().");
args.AddOption(&ref_levels, "-r", "--refine",
"Number of times to refine the mesh uniformly.");
args.AddOption(&order, "-o", "--order",
@@ -92,7 +87,8 @@ int main(int argc, char *argv[])
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
args.AddOption(&t_final, "-tf", "--t-final", "Final time; start time is 0.");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
"Time step. Positive number skips CFL timestep calculation.");
args.AddOption(&cfl, "-c", "--cfl-number",
@@ -100,28 +96,23 @@ int main(int argc, char *argv[])
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&preassembleWeakDiv, "-ea", "--element-assembly-divergence",
"-mf", "--matrix-free-divergence",
"Weak divergence assembly level\n"
" ea - Element assembly with interpolated F\n"
" mf - Nonlinear assembly in matrix-free manner");
args.AddOption(&vis_steps, "-vs", "--visualization-steps",
"Visualize every n-th timestep.");
args.ParseCheck();
// 2. Read the mesh from the given mesh file. When the user does not provide
// mesh file, use the default mesh file for the problem.
Mesh mesh = mesh_file.empty() ? EulerMesh(problem) : Mesh(mesh_file);
const int dim = mesh.Dimension();
const int num_equations = dim + 2;
// 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++)
args.Parse();
if (!args.Good())
{
mesh.UniformRefinement();
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
// 2. Read the mesh from the given mesh file. This example requires a 2D
// periodic mesh, such as ../data/periodic-square.mesh.
Mesh mesh(mesh_file, 1, 1);
const int dim = mesh.Dimension();
MFEM_ASSERT(dim == 2, "Need a two-dimensional mesh for the problem definition");
// 3. Define the ODE solver used for time integration. Several explicit
// Runge-Kutta methods are available.
@@ -138,7 +129,15 @@ int main(int argc, char *argv[])
return 3;
}
// 4. Define the discontinuous DG finite element space of the given
// 4. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
// command-line parameter.
for (int lev = 0; lev < ref_levels; lev++)
{
mesh.UniformRefinement();
}
// 5. Define the discontinuous DG finite element space of the given
// polynomial order on the refined mesh.
DG_FECollection fec(order, dim);
// Finite element space for a scalar (thermodynamic quantity)
@@ -146,74 +145,81 @@ int main(int argc, char *argv[])
// Finite element space for a mesh-dim vector quantity (momentum)
FiniteElementSpace dfes(&mesh, &fec, dim, Ordering::byNODES);
// Finite element space for all variables together (total thermodynamic state)
FiniteElementSpace vfes(&mesh, &fec, num_equations, Ordering::byNODES);
FiniteElementSpace vfes(&mesh, &fec, num_equation, Ordering::byNODES);
// This example depends on this ordering of the space.
MFEM_ASSERT(fes.GetOrdering() == Ordering::byNODES, "");
cout << "Number of unknowns: " << vfes.GetVSize() << endl;
// 5. Define the initial conditions, save the corresponding mesh and grid
// functions to files. These can be opened with GLVis using:
// "glvis -m euler-mesh.mesh -g euler-1-init.gf" (for x-momentum).
// 6. Define the initial conditions, save the corresponding mesh and grid
// functions to a file. This can be opened with GLVis with the -gc option.
// The solution u has components {density, x-momentum, y-momentum, energy}.
// These are stored contiguously in the BlockVector u_block.
Array<int> offsets(num_equation + 1);
for (int k = 0; k <= num_equation; k++) { offsets[k] = k * vfes.GetNDofs(); }
BlockVector u_block(offsets);
// Momentum grid function on dfes for visualization.
GridFunction mom(&dfes, u_block.GetData() + offsets[1]);
// Initialize the state.
VectorFunctionCoefficient u0 = EulerInitialCondition(problem,
specific_heat_ratio,
gas_constant);
GridFunction sol(&vfes);
VectorFunctionCoefficient u0(num_equation, InitialCondition);
GridFunction sol(&vfes, u_block.GetData());
sol.ProjectCoefficient(u0);
GridFunction mom(&dfes, sol.GetData() + fes.GetNDofs());
// Output the initial solution.
{
ostringstream mesh_name;
mesh_name << "euler-mesh.mesh";
ofstream mesh_ofs(mesh_name.str().c_str());
ofstream mesh_ofs("vortex.mesh");
mesh_ofs.precision(precision);
mesh_ofs << mesh;
for (int k = 0; k < num_equations; k++)
for (int k = 0; k < num_equation; k++)
{
GridFunction uk(&fes, sol.GetData() + k * fes.GetNDofs());
GridFunction uk(&fes, u_block.GetBlock(k));
ostringstream sol_name;
sol_name << "euler-" << k << "-init.gf";
sol_name << "vortex-" << k << "-init.gf";
ofstream sol_ofs(sol_name.str().c_str());
sol_ofs.precision(precision);
sol_ofs << uk;
}
}
// 6. Set up the nonlinear form with euler flux and numerical flux
EulerFlux flux(dim, specific_heat_ratio);
RusanovFlux numericalFlux(flux);
DGHyperbolicConservationLaws euler(
vfes, std::unique_ptr<HyperbolicFormIntegrator>(
new HyperbolicFormIntegrator(numericalFlux, IntOrderOffset)),
preassembleWeakDiv);
// 7. Set up the nonlinear form corresponding to the DG discretization of the
// flux divergence, and assemble the corresponding mass matrix.
MixedBilinearForm Aflux(&dfes, &fes);
Aflux.AddDomainIntegrator(new TransposeIntegrator(new GradientIntegrator()));
Aflux.Assemble();
// 7. Visualize momentum with its magnitude
NonlinearForm A(&vfes);
RiemannSolver rsolver;
A.AddInteriorFaceIntegrator(new FaceIntegrator(rsolver, dim));
// 8. Define the time-dependent evolution operator describing the ODE
// right-hand side, and perform time-integration (looping over the time
// iterations, ti, with a time-step dt).
FE_Evolution euler(vfes, A, Aflux.SpMat());
// Visualize the density
socketstream sout;
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
int visport = 19916;
sout.open(vishost, visport);
if (!sout)
{
cout << "Unable to connect to GLVis server at "
<< vishost << ':' << visport << endl;
visualization = false;
cout << "Unable to connect to GLVis server at " << vishost << ':'
<< visport << endl;
cout << "GLVis visualization disabled.\n";
}
else
{
sout.precision(precision);
// Plot magnitude of vector-valued momentum
sout << "solution\n" << mesh << mom;
sout << "window_title 'momentum, t = 0'\n";
sout << "view 0 0\n"; // view from top
sout << "keys jlm\n"; // turn off perspective and light, show mesh
sout << "pause\n";
sout << flush;
cout << "GLVis visualization paused."
@@ -221,57 +227,54 @@ int main(int argc, char *argv[])
}
}
// 8. Time integration
// When dt is not specified, use CFL condition.
// Compute h_min and initial maximum characteristic speed
real_t hmin = infinity();
// Determine the minimum element size.
double hmin = 0.0;
if (cfl > 0)
{
for (int i = 0; i < mesh.GetNE(); i++)
hmin = mesh.GetElementSize(0, 1);
for (int i = 1; i < mesh.GetNE(); i++)
{
hmin = min(mesh.GetElementSize(i, 1), hmin);
}
// Find a safe dt, using a temporary vector. Calling Mult() computes the
// maximum char speed at all quadrature points on all faces (and all
// elements with -mf).
Vector z(sol.Size());
euler.Mult(sol, z);
real_t max_char_speed = euler.GetMaxCharSpeed();
dt = cfl * hmin / max_char_speed / (2 * order + 1);
}
// Start the timer.
tic_toc.Clear();
tic_toc.Start();
// Init time integration
real_t t = 0.0;
double t = 0.0;
euler.SetTime(t);
ode_solver->Init(euler);
if (cfl > 0)
{
// Find a safe dt, using a temporary vector. Calling Mult() computes the
// maximum char speed at all quadrature points on all faces.
Vector z(A.Width());
max_char_speed = 0.;
A.Mult(sol, z);
dt = cfl * hmin / max_char_speed / (2*order+1);
}
// Integrate in time.
bool done = false;
for (int ti = 0; !done;)
for (int ti = 0; !done; )
{
real_t dt_real = min(dt, t_final - t);
double dt_real = min(dt, t_final - t);
ode_solver->Step(sol, t, dt_real);
if (cfl > 0) // update time step size with CFL
if (cfl > 0)
{
real_t max_char_speed = euler.GetMaxCharSpeed();
dt = cfl * hmin / max_char_speed / (2 * order + 1);
dt = cfl * hmin / max_char_speed / (2*order+1);
}
ti++;
done = (t >= t_final - 1e-8 * dt);
done = (t >= t_final - 1e-8*dt);
if (done || ti % vis_steps == 0)
{
cout << "time step: " << ti << ", time: " << t << endl;
if (visualization)
{
sout << "window_title 'momentum, t = " << t << "'\n";
sout << "solution\n" << mesh << mom << flush;
}
}
@@ -281,28 +284,23 @@ int main(int argc, char *argv[])
cout << " done, " << tic_toc.RealTime() << "s." << endl;
// 9. Save the final solution. This output can be viewed later using GLVis:
// "glvis -m euler-mesh-final.mesh -g euler-1-final.gf" (for x-momentum).
// "glvis -m vortex.mesh -g vortex-1-final.gf".
for (int k = 0; k < num_equation; k++)
{
ostringstream mesh_name;
mesh_name << "euler-mesh-final.mesh";
ofstream mesh_ofs(mesh_name.str().c_str());
mesh_ofs.precision(precision);
mesh_ofs << mesh;
for (int k = 0; k < num_equations; k++)
{
GridFunction uk(&fes, sol.GetData() + k * fes.GetNDofs());
ostringstream sol_name;
sol_name << "euler-" << k << "-final.gf";
ofstream sol_ofs(sol_name.str().c_str());
sol_ofs.precision(precision);
sol_ofs << uk;
}
GridFunction uk(&fes, u_block.GetBlock(k));
ostringstream sol_name;
sol_name << "vortex-" << k << "-final.gf";
ofstream sol_ofs(sol_name.str().c_str());
sol_ofs.precision(precision);
sol_ofs << uk;
}
// 10. Compute the L2 solution error summed for all components.
const real_t error = sol.ComputeLpError(2, u0);
cout << "Solution error: " << error << endl;
if (t_final == 2.0)
{
const double error = sol.ComputeLpError(2, u0);
cout << "Solution error: " << error << endl;
}
// Free the used memory.
delete ode_solver;
+444 -321
View File
@@ -1,367 +1,490 @@
// MFEM Example 18 - Serial/Parallel Shared Code
// (Implementation of Time-dependent DG Operator)
//
// This code provide example problems for the Euler equations and implements
// the time-dependent DG operator given by the equation:
//
// (u_t, v)_T - (F(u), ∇ v)_T + <F̂(u, n), [[v]]>_F = 0.
//
// This operator is designed for explicit time stepping methods. Specifically,
// the function DGHyperbolicConservationLaws::Mult implements the following
// transformation:
//
// u ↦ M⁻¹(-DF(u) + NF(u))
//
// where M is the mass matrix, DF is the weak divergence of flux, and NF is the
// interface flux. The inverse of the mass matrix is computed element-wise by
// leveraging the block-diagonal structure of the DG mass matrix. Additionally,
// the flux-related terms are computed using the HyperbolicFormIntegrator.
//
// The maximum characteristic speed is determined for each time step. For more
// details, refer to the documentation of DGHyperbolicConservationLaws::Mult.
//
#include <functional>
#include "mfem.hpp"
namespace mfem
{
using namespace std;
using namespace mfem;
/// @brief Time dependent DG operator for hyperbolic conservation laws
class DGHyperbolicConservationLaws : public TimeDependentOperator
// Problem definition
extern int problem;
// Maximum characteristic speed (updated by integrators)
extern double max_char_speed;
extern const int num_equation;
extern const double specific_heat_ratio;
extern const double gas_constant;
// Time-dependent operator for the right-hand side of the ODE representing the
// DG weak form.
class FE_Evolution : public TimeDependentOperator
{
private:
const int num_equations; // the number of equations
const int dim;
FiniteElementSpace &vfes; // vector finite element space
// Element integration form. Should contain ComputeFlux
std::unique_ptr<HyperbolicFormIntegrator> formIntegrator;
// Base Nonlinear Form
std::unique_ptr<NonlinearForm> nonlinearForm;
// element-wise inverse mass matrix
std::vector<DenseMatrix> invmass; // local scalar inverse mass.
std::vector<DenseMatrix> weakdiv; // local weakdivergence. Trial space is ByDim.
// global maximum characteristic speed. Updated by form integrators
mutable real_t max_char_speed;
// auxiliary variable used in Mult
FiniteElementSpace &vfes;
Operator &A;
SparseMatrix &Aflux;
DenseTensor Me_inv;
mutable Vector state;
mutable DenseMatrix f;
mutable DenseTensor flux;
mutable Vector z;
// Compute element-wise inverse mass matrix
void ComputeInvMass();
// Compute element-wise weak-divergence matrix
void ComputeWeakDivergence();
void GetFlux(const DenseMatrix &state_, DenseTensor &flux_) const;
public:
/**
* @brief Construct a new DGHyperbolicConservationLaws object
*
* @param vfes_ vector finite element space. Only tested for DG [Pₚ]ⁿ
* @param formIntegrator_ integrator (F(u,x), grad v)
* @param preassembleWeakDivergence preassemble weak divergence for faster
* assembly
*/
DGHyperbolicConservationLaws(
FiniteElementSpace &vfes_,
std::unique_ptr<HyperbolicFormIntegrator> formIntegrator_,
bool preassembleWeakDivergence=true);
/**
* @brief Apply nonlinear form to obtain M⁻¹(DIVF + JUMP HAT(F))
*
* @param x current solution vector
* @param y resulting dual vector to be used in an EXPLICIT solver
*/
void Mult(const Vector &x, Vector &y) const override;
// get global maximum characteristic speed to be used in CFL condition
// where max_char_speed is updated during Mult.
real_t GetMaxCharSpeed() { return max_char_speed; }
void Update();
FE_Evolution(FiniteElementSpace &vfes_,
Operator &A_, SparseMatrix &Aflux_);
virtual void Mult(const Vector &x, Vector &y) const;
virtual ~FE_Evolution() { }
};
//////////////////////////////////////////////////////////////////
/// HYPERBOLIC CONSERVATION LAWS IMPLEMENTATION ///
//////////////////////////////////////////////////////////////////
// Implements a simple Rusanov flux
class RiemannSolver
{
private:
Vector flux1;
Vector flux2;
// Implementation of class DGHyperbolicConservationLaws
DGHyperbolicConservationLaws::DGHyperbolicConservationLaws(
FiniteElementSpace &vfes_,
std::unique_ptr<HyperbolicFormIntegrator> formIntegrator_,
bool preassembleWeakDivergence)
: TimeDependentOperator(vfes_.GetTrueVSize()),
num_equations(formIntegrator_->num_equations),
dim(vfes_.GetMesh()->SpaceDimension()),
public:
RiemannSolver();
double Eval(const Vector &state1, const Vector &state2,
const Vector &nor, Vector &flux);
};
// Interior face term: <F.n(u),[w]>
class FaceIntegrator : public NonlinearFormIntegrator
{
private:
RiemannSolver rsolver;
Vector shape1;
Vector shape2;
Vector funval1;
Vector funval2;
Vector nor;
Vector fluxN;
public:
FaceIntegrator(RiemannSolver &rsolver_, const int dim);
virtual void AssembleFaceVector(const FiniteElement &el1,
const FiniteElement &el2,
FaceElementTransformations &Tr,
const Vector &elfun, Vector &elvect);
};
// Implementation of class FE_Evolution
FE_Evolution::FE_Evolution(FiniteElementSpace &vfes_,
Operator &A_, SparseMatrix &Aflux_)
: TimeDependentOperator(A_.Height()),
dim(vfes_.GetFE(0)->GetDim()),
vfes(vfes_),
formIntegrator(std::move(formIntegrator_)),
z(vfes_.GetTrueVSize())
A(A_),
Aflux(Aflux_),
Me_inv(vfes.GetFE(0)->GetDof(), vfes.GetFE(0)->GetDof(), vfes.GetNE()),
state(num_equation),
f(num_equation, dim),
flux(vfes.GetNDofs(), dim, num_equation),
z(A.Height())
{
// Standard local assembly and inversion for energy mass matrices.
ComputeInvMass();
#ifndef MFEM_USE_MPI
nonlinearForm.reset(new NonlinearForm(&vfes));
#else
ParFiniteElementSpace *pvfes = dynamic_cast<ParFiniteElementSpace *>(&vfes);
if (pvfes)
const int dof = vfes.GetFE(0)->GetDof();
DenseMatrix Me(dof);
DenseMatrixInverse inv(&Me);
MassIntegrator mi;
for (int i = 0; i < vfes.GetNE(); i++)
{
nonlinearForm.reset(new ParNonlinearForm(pvfes));
}
else
{
nonlinearForm.reset(new NonlinearForm(&vfes));
}
#endif
if (preassembleWeakDivergence)
{
ComputeWeakDivergence();
}
else
{
nonlinearForm->AddDomainIntegrator(formIntegrator.get());
}
nonlinearForm->AddInteriorFaceIntegrator(formIntegrator.get());
nonlinearForm->UseExternalIntegrators();
}
void DGHyperbolicConservationLaws::ComputeInvMass()
{
InverseIntegrator inv_mass(new MassIntegrator());
invmass.resize(vfes.GetNE());
for (int i=0; i<vfes.GetNE(); i++)
{
int dof = vfes.GetFE(i)->GetDof();
invmass[i].SetSize(dof);
inv_mass.AssembleElementMatrix(*vfes.GetFE(i),
*vfes.GetElementTransformation(i),
invmass[i]);
mi.AssembleElementMatrix(*vfes.GetFE(i), *vfes.GetElementTransformation(i), Me);
inv.Factor();
inv.GetInverseMatrix(Me_inv(i));
}
}
void DGHyperbolicConservationLaws::ComputeWeakDivergence()
{
TransposeIntegrator weak_div(new GradientIntegrator());
DenseMatrix weakdiv_bynodes;
weakdiv.resize(vfes.GetNE());
for (int i=0; i<vfes.GetNE(); i++)
{
int dof = vfes.GetFE(i)->GetDof();
weakdiv_bynodes.SetSize(dof, dof*dim);
weak_div.AssembleElementMatrix2(*vfes.GetFE(i), *vfes.GetFE(i),
*vfes.GetElementTransformation(i),
weakdiv_bynodes);
weakdiv[i].SetSize(dof, dof*dim);
// Reorder so that trial space is ByDim.
// This makes applying weak divergence to flux value simpler.
for (int j=0; j<dof; j++)
{
for (int d=0; d<dim; d++)
{
weakdiv[i].SetCol(j*dim + d, weakdiv_bynodes.GetColumn(d*dof + j));
}
}
}
}
void DGHyperbolicConservationLaws::Mult(const Vector &x, Vector &y) const
void FE_Evolution::Mult(const Vector &x, Vector &y) const
{
// 0. Reset wavespeed computation before operator application.
formIntegrator->ResetMaxCharSpeed();
// 1. Apply Nonlinear form to obtain an axiliary result
// z = - <F̂(u_h,n), [[v]]>_e
// If weak-divergencee is not preassembled, we also have weak-divergence
// z = - <F̂(u_h,n), [[v]]>_e + (F(u_h), ∇v)
nonlinearForm->Mult(x, z);
if (!weakdiv.empty()) // if weak divergence is pre-assembled
max_char_speed = 0.;
// 1. Create the vector z with the face terms -<F.n(u), [w]>.
A.Mult(x, z);
// 2. Add the element terms.
// i. computing the flux approximately as a grid function by interpolating
// at the solution nodes.
// ii. multiplying this grid function by a (constant) mixed bilinear form for
// each of the num_equation, computing (F(u), grad(w)) for each equation.
DenseMatrix xmat(x.GetData(), vfes.GetNDofs(), num_equation);
GetFlux(xmat, flux);
for (int k = 0; k < num_equation; k++)
{
// Apply weak divergence to F(u_h), and inverse mass to z_loc + weakdiv_loc
Vector current_state; // view of current state at a node
DenseMatrix current_flux; // flux of current state
DenseMatrix flux; // element flux value. Whose column is ordered by dim.
DenseMatrix current_xmat; // view of current states in an element, dof x num_eq
DenseMatrix current_zmat; // view of element auxiliary result, dof x num_eq
DenseMatrix current_ymat; // view of element result, dof x num_eq
const FluxFunction &fluxFunction = formIntegrator->GetFluxFunction();
Array<int> vdofs;
Vector xval, zval;
for (int i=0; i<vfes.GetNE(); i++)
{
ElementTransformation* Tr = vfes.GetElementTransformation(i);
int dof = vfes.GetFE(i)->GetDof();
vfes.GetElementVDofs(i, vdofs);
x.GetSubVector(vdofs, xval);
current_xmat.UseExternalData(xval.GetData(), dof, num_equations);
flux.SetSize(num_equations, dim*dof);
for (int j=0; j<dof; j++) // compute flux for all nodes in the element
{
current_xmat.GetRow(j, current_state);
current_flux.UseExternalData(flux.GetData() + num_equations*dim*j,
num_equations, dof);
fluxFunction.ComputeFlux(current_state, *Tr, current_flux);
}
// Compute weak-divergence and add it to auxiliary result, z
// Recalling that weakdiv is reordered by dim, we can apply
// weak-divergence to the transpose of flux.
z.GetSubVector(vdofs, zval);
current_zmat.UseExternalData(zval.GetData(), dof, num_equations);
mfem::AddMult_a_ABt(1.0, weakdiv[i], flux, current_zmat);
// Apply inverse mass to auxiliary result to obtain the final result
current_ymat.SetSize(dof, num_equations);
mfem::Mult(invmass[i], current_zmat, current_ymat);
y.SetSubVector(vdofs, current_ymat.GetData());
}
Vector fk(flux(k).GetData(), dim * vfes.GetNDofs());
Vector zk(z.GetData() + k * vfes.GetNDofs(), vfes.GetNDofs());
Aflux.AddMult(fk, zk);
}
// 3. Multiply element-wise by the inverse mass matrices.
Vector zval;
Array<int> vdofs;
const int dof = vfes.GetFE(0)->GetDof();
DenseMatrix zmat, ymat(dof, num_equation);
for (int i = 0; i < vfes.GetNE(); i++)
{
// Return the vdofs ordered byNODES
vfes.GetElementVDofs(i, vdofs);
z.GetSubVector(vdofs, zval);
zmat.UseExternalData(zval.GetData(), dof, num_equation);
mfem::Mult(Me_inv(i), zmat, ymat);
y.SetSubVector(vdofs, ymat.GetData());
}
}
// Physicality check (at end)
bool StateIsPhysical(const Vector &state, const int dim);
// Pressure (EOS) computation
inline double ComputePressure(const Vector &state, int dim)
{
const double den = state(0);
const Vector den_vel(state.GetData() + 1, dim);
const double den_energy = state(1 + dim);
double den_vel2 = 0;
for (int d = 0; d < dim; d++) { den_vel2 += den_vel(d) * den_vel(d); }
den_vel2 /= den;
return (specific_heat_ratio - 1.0) * (den_energy - 0.5 * den_vel2);
}
// Compute the vector flux F(u)
void ComputeFlux(const Vector &state, int dim, DenseMatrix &flux)
{
const double den = state(0);
const Vector den_vel(state.GetData() + 1, dim);
const double den_energy = state(1 + dim);
MFEM_ASSERT(StateIsPhysical(state, dim), "");
const double pres = ComputePressure(state, dim);
for (int d = 0; d < dim; d++)
{
flux(0, d) = den_vel(d);
for (int i = 0; i < dim; i++)
{
flux(1+i, d) = den_vel(i) * den_vel(d) / den;
}
flux(1+d, d) += pres;
}
const double H = (den_energy + pres) / den;
for (int d = 0; d < dim; d++)
{
flux(1+dim, d) = den_vel(d) * H;
}
}
// Compute the scalar F(u).n
void ComputeFluxDotN(const Vector &state, const Vector &nor,
Vector &fluxN)
{
// NOTE: nor in general is not a unit normal
const int dim = nor.Size();
const double den = state(0);
const Vector den_vel(state.GetData() + 1, dim);
const double den_energy = state(1 + dim);
MFEM_ASSERT(StateIsPhysical(state, dim), "");
const double pres = ComputePressure(state, dim);
double den_velN = 0;
for (int d = 0; d < dim; d++) { den_velN += den_vel(d) * nor(d); }
fluxN(0) = den_velN;
for (int d = 0; d < dim; d++)
{
fluxN(1+d) = den_velN * den_vel(d) / den + pres * nor(d);
}
const double H = (den_energy + pres) / den;
fluxN(1 + dim) = den_velN * H;
}
// Compute the maximum characteristic speed.
inline double ComputeMaxCharSpeed(const Vector &state, const int dim)
{
const double den = state(0);
const Vector den_vel(state.GetData() + 1, dim);
double den_vel2 = 0;
for (int d = 0; d < dim; d++) { den_vel2 += den_vel(d) * den_vel(d); }
den_vel2 /= den;
const double pres = ComputePressure(state, dim);
const double sound = sqrt(specific_heat_ratio * pres / den);
const double vel = sqrt(den_vel2 / den);
return vel + sound;
}
// Compute the flux at solution nodes.
void FE_Evolution::GetFlux(const DenseMatrix &x_, DenseTensor &flux_) const
{
const int flux_dof = flux_.SizeI();
const int flux_dim = flux_.SizeJ();
for (int i = 0; i < flux_dof; i++)
{
for (int k = 0; k < num_equation; k++) { state(k) = x_(i, k); }
ComputeFlux(state, flux_dim, f);
for (int d = 0; d < flux_dim; d++)
{
for (int k = 0; k < num_equation; k++)
{
flux_(i, d, k) = f(k, d);
}
}
// Update max char speed
const double mcs = ComputeMaxCharSpeed(state, flux_dim);
if (mcs > max_char_speed) { max_char_speed = mcs; }
}
}
// Implementation of class RiemannSolver
RiemannSolver::RiemannSolver() :
flux1(num_equation),
flux2(num_equation) { }
double RiemannSolver::Eval(const Vector &state1, const Vector &state2,
const Vector &nor, Vector &flux)
{
// NOTE: nor in general is not a unit normal
const int dim = nor.Size();
MFEM_ASSERT(StateIsPhysical(state1, dim), "");
MFEM_ASSERT(StateIsPhysical(state2, dim), "");
const double maxE1 = ComputeMaxCharSpeed(state1, dim);
const double maxE2 = ComputeMaxCharSpeed(state2, dim);
const double maxE = max(maxE1, maxE2);
ComputeFluxDotN(state1, nor, flux1);
ComputeFluxDotN(state2, nor, flux2);
double normag = 0;
for (int i = 0; i < dim; i++)
{
normag += nor(i) * nor(i);
}
normag = sqrt(normag);
for (int i = 0; i < num_equation; i++)
{
flux(i) = 0.5 * (flux1(i) + flux2(i))
- 0.5 * maxE * (state2(i) - state1(i)) * normag;
}
return maxE;
}
// Implementation of class FaceIntegrator
FaceIntegrator::FaceIntegrator(RiemannSolver &rsolver_, const int dim) :
rsolver(rsolver_),
funval1(num_equation),
funval2(num_equation),
nor(dim),
fluxN(num_equation) { }
void FaceIntegrator::AssembleFaceVector(const FiniteElement &el1,
const FiniteElement &el2,
FaceElementTransformations &Tr,
const Vector &elfun, Vector &elvect)
{
// Compute the term <F.n(u),[w]> on the interior faces.
const int dof1 = el1.GetDof();
const int dof2 = el2.GetDof();
shape1.SetSize(dof1);
shape2.SetSize(dof2);
elvect.SetSize((dof1 + dof2) * num_equation);
elvect = 0.0;
DenseMatrix elfun1_mat(elfun.GetData(), dof1, num_equation);
DenseMatrix elfun2_mat(elfun.GetData() + dof1 * num_equation, dof2,
num_equation);
DenseMatrix elvect1_mat(elvect.GetData(), dof1, num_equation);
DenseMatrix elvect2_mat(elvect.GetData() + dof1 * num_equation, dof2,
num_equation);
// Integration order calculation from DGTraceIntegrator
int intorder;
if (Tr.Elem2No >= 0)
intorder = (min(Tr.Elem1->OrderW(), Tr.Elem2->OrderW()) +
2*max(el1.GetOrder(), el2.GetOrder()));
else
{
// Apply block inverse mass
Vector zval; // z_loc, dof*num_eq
intorder = Tr.Elem1->OrderW() + 2*el1.GetOrder();
}
if (el1.Space() == FunctionSpace::Pk)
{
intorder++;
}
const IntegrationRule *ir = &IntRules.Get(Tr.GetGeometryType(), intorder);
DenseMatrix current_zmat; // view of element auxiliary result, dof x num_eq
DenseMatrix current_ymat; // view of element result, dof x num_eq
Array<int> vdofs;
for (int i=0; i<vfes.GetNE(); i++)
for (int i = 0; i < ir->GetNPoints(); i++)
{
const IntegrationPoint &ip = ir->IntPoint(i);
Tr.SetAllIntPoints(&ip); // set face and element int. points
// Calculate basis functions on both elements at the face
el1.CalcShape(Tr.GetElement1IntPoint(), shape1);
el2.CalcShape(Tr.GetElement2IntPoint(), shape2);
// Interpolate elfun at the point
elfun1_mat.MultTranspose(shape1, funval1);
elfun2_mat.MultTranspose(shape2, funval2);
// Get the normal vector and the flux on the face
CalcOrtho(Tr.Jacobian(), nor);
const double mcs = rsolver.Eval(funval1, funval2, nor, fluxN);
// Update max char speed
if (mcs > max_char_speed) { max_char_speed = mcs; }
fluxN *= ip.weight;
for (int k = 0; k < num_equation; k++)
{
int dof = vfes.GetFE(i)->GetDof();
vfes.GetElementVDofs(i, vdofs);
z.GetSubVector(vdofs, zval);
current_zmat.UseExternalData(zval.GetData(), dof, num_equations);
current_ymat.SetSize(dof, num_equations);
mfem::Mult(invmass[i], current_zmat, current_ymat);
y.SetSubVector(vdofs, current_ymat.GetData());
for (int s = 0; s < dof1; s++)
{
elvect1_mat(s, k) -= fluxN(k) * shape1(s);
}
for (int s = 0; s < dof2; s++)
{
elvect2_mat(s, k) += fluxN(k) * shape2(s);
}
}
}
max_char_speed = formIntegrator->GetMaxCharSpeed();
}
void DGHyperbolicConservationLaws::Update()
// Check that the state is physical - enabled in debug mode
bool StateIsPhysical(const Vector &state, const int dim)
{
nonlinearForm->Update();
height = nonlinearForm->Height();
width = height;
z.SetSize(height);
const double den = state(0);
const Vector den_vel(state.GetData() + 1, dim);
const double den_energy = state(1 + dim);
ComputeInvMass();
if (!weakdiv.empty()) {ComputeWeakDivergence();}
}
std::function<void(const Vector&, Vector&)> GetMovingVortexInit(
const real_t radius, const real_t Minf, const real_t beta,
const real_t gas_constant, const real_t specific_heat_ratio)
{
return [specific_heat_ratio,
gas_constant, Minf, radius, beta](const Vector &x, Vector &y)
if (den < 0)
{
MFEM_ASSERT(x.Size() == 2, "");
const real_t xc = 0.0, yc = 0.0;
// Nice units
const real_t vel_inf = 1.;
const real_t den_inf = 1.;
// Derive remainder of background state from this and Minf
const real_t pres_inf = (den_inf / specific_heat_ratio) *
(vel_inf / Minf) * (vel_inf / Minf);
const real_t temp_inf = pres_inf / (den_inf * gas_constant);
real_t r2rad = 0.0;
r2rad += (x(0) - xc) * (x(0) - xc);
r2rad += (x(1) - yc) * (x(1) - yc);
r2rad /= (radius * radius);
const real_t shrinv1 = 1.0 / (specific_heat_ratio - 1.);
const real_t velX =
vel_inf * (1 - beta * (x(1) - yc) / radius * std::exp(-0.5 * r2rad));
const real_t velY =
vel_inf * beta * (x(0) - xc) / radius * std::exp(-0.5 * r2rad);
const real_t vel2 = velX * velX + velY * velY;
const real_t specific_heat =
gas_constant * specific_heat_ratio * shrinv1;
const real_t temp = temp_inf - 0.5 * (vel_inf * beta) *
(vel_inf * beta) / specific_heat *
std::exp(-r2rad);
const real_t den = den_inf * std::pow(temp / temp_inf, shrinv1);
const real_t pres = den * gas_constant * temp;
const real_t energy = shrinv1 * pres / den + 0.5 * vel2;
y(0) = den;
y(1) = den * velX;
y(2) = den * velY;
y(3) = den * energy;
};
}
Mesh EulerMesh(const int problem)
{
switch (problem)
{
case 1:
case 2:
case 3:
return Mesh("../data/periodic-square.mesh");
break;
case 4:
return Mesh("../data/periodic-segment.mesh");
break;
default:
MFEM_ABORT("Problem Undefined");
cout << "Negative density: ";
for (int i = 0; i < state.Size(); i++)
{
cout << state(i) << " ";
}
cout << endl;
return false;
}
if (den_energy <= 0)
{
cout << "Negative energy: ";
for (int i = 0; i < state.Size(); i++)
{
cout << state(i) << " ";
}
cout << endl;
return false;
}
double den_vel2 = 0;
for (int i = 0; i < dim; i++) { den_vel2 += den_vel(i) * den_vel(i); }
den_vel2 /= den;
const double pres = (specific_heat_ratio - 1.0) * (den_energy - 0.5 * den_vel2);
if (pres <= 0)
{
cout << "Negative pressure: " << pres << ", state: ";
for (int i = 0; i < state.Size(); i++)
{
cout << state(i) << " ";
}
cout << endl;
return false;
}
return true;
}
// Initial condition
VectorFunctionCoefficient EulerInitialCondition(const int problem,
const real_t specific_heat_ratio,
const real_t gas_constant)
void InitialCondition(const Vector &x, Vector &y)
{
switch (problem)
MFEM_ASSERT(x.Size() == 2, "");
double radius = 0, Minf = 0, beta = 0;
if (problem == 1)
{
case 1: // fast moving vortex
return VectorFunctionCoefficient(
4, GetMovingVortexInit(0.2, 0.5, 1. / 5., gas_constant,
specific_heat_ratio));
case 2: // slow moving vortex
return VectorFunctionCoefficient(
4, GetMovingVortexInit(0.2, 0.05, 1. / 50., gas_constant,
specific_heat_ratio));
case 3: // moving sine wave
return VectorFunctionCoefficient(4, [](const Vector &x, Vector &y)
{
MFEM_ASSERT(x.Size() == 2, "");
const real_t density = 1.0 + 0.2 * std::sin(M_PI*(x(0) + x(1)));
const real_t velocity_x = 0.7;
const real_t velocity_y = 0.3;
const real_t pressure = 1.0;
const real_t energy =
pressure / (1.4 - 1.0) +
density * 0.5 * (velocity_x * velocity_x + velocity_y * velocity_y);
y(0) = density;
y(1) = density * velocity_x;
y(2) = density * velocity_y;
y(3) = energy;
});
case 4:
return VectorFunctionCoefficient(3, [](const Vector &x, Vector &y)
{
MFEM_ASSERT(x.Size() == 1, "");
const real_t density = 1.0 + 0.2 * std::sin(M_PI * 2 * x(0));
const real_t velocity_x = 1.0;
const real_t pressure = 1.0;
const real_t energy =
pressure / (1.4 - 1.0) + density * 0.5 * (velocity_x * velocity_x);
y(0) = density;
y(1) = density * velocity_x;
y(2) = energy;
});
default:
MFEM_ABORT("Problem Undefined");
// "Fast vortex"
radius = 0.2;
Minf = 0.5;
beta = 1. / 5.;
}
else if (problem == 2)
{
// "Slow vortex"
radius = 0.2;
Minf = 0.05;
beta = 1. / 50.;
}
else
{
mfem_error("Cannot recognize problem."
"Options are: 1 - fast vortex, 2 - slow vortex");
}
}
} // namespace mfem
const double xc = 0.0, yc = 0.0;
// Nice units
const double vel_inf = 1.;
const double den_inf = 1.;
// Derive remainder of background state from this and Minf
const double pres_inf = (den_inf / specific_heat_ratio) * (vel_inf / Minf) *
(vel_inf / Minf);
const double temp_inf = pres_inf / (den_inf * gas_constant);
double r2rad = 0.0;
r2rad += (x(0) - xc) * (x(0) - xc);
r2rad += (x(1) - yc) * (x(1) - yc);
r2rad /= (radius * radius);
const double shrinv1 = 1.0 / (specific_heat_ratio - 1.);
const double velX = vel_inf * (1 - beta * (x(1) - yc) / radius * exp(
-0.5 * r2rad));
const double velY = vel_inf * beta * (x(0) - xc) / radius * exp(-0.5 * r2rad);
const double vel2 = velX * velX + velY * velY;
const double specific_heat = gas_constant * specific_heat_ratio * shrinv1;
const double temp = temp_inf - 0.5 * (vel_inf * beta) *
(vel_inf * beta) / specific_heat * exp(-r2rad);
const double den = den_inf * pow(temp/temp_inf, shrinv1);
const double pres = den * gas_constant * temp;
const double energy = shrinv1 * pres / den + 0.5 * vel2;
y(0) = den;
y(1) = den * velX;
y(2) = den * velY;
y(3) = den * energy;
}
+181 -168
View File
@@ -1,24 +1,18 @@
// MFEM Example 18 - Parallel Version
// MFEM Example 18 - Parallel Version
//
// Compile with: make ex18p
// Compile with: make ex18
//
// Sample runs:
//
// mpirun -np 4 ex18p -p 1 -rs 2 -rp 1 -o 1 -s 3
// mpirun -np 4 ex18p -p 1 -rs 1 -rp 1 -o 3 -s 4
// mpirun -np 4 ex18p -p 1 -rs 1 -rp 1 -o 5 -s 6
// mpirun -np 4 ex18p -p 2 -rs 1 -rp 1 -o 1 -s 3 -mf
// mpirun -np 4 ex18p -p 2 -rs 1 -rp 1 -o 3 -s 3 -mf
// mpirun -np 4 ex18p -p 2 -rs 1 -rp 1 -o 1 -s 3
// mpirun -np 4 ex18p -p 2 -rs 1 -rp 1 -o 3 -s 3
//
// Description: This example code solves the compressible Euler system of
// equations, a model nonlinear hyperbolic PDE, with a
// discontinuous Galerkin (DG) formulation in parallel.
//
// (u_t, v)_T - (F(u), ∇ v)_T + <F̂(u,n), [[v]]>_F = 0
//
// where (⋅,⋅)_T is volume integration, and <⋅,⋅>_F is face
// integration, F is the Euler flux function, and F̂ is the
// numerical flux.
// discontinuous Galerkin (DG) formulation.
//
// Specifically, it solves for an exact solution of the equations
// whereby a vortex is transported by a uniform flow. Since all
@@ -33,54 +27,54 @@
// method. An additional factor can be tuned by passing the --cfl
// (or -c shorter) flag.
//
// The example demonstrates usage of DGHyperbolicConservationLaws
// that wraps NonlinearFormIntegrators containing element and face
// integration schemes. In this case the system also involves an
// external approximate Riemann solver for the DG interface flux.
// By default, weak-divergence is pre-assembled in element-wise
// manner, which corresponds to (I_h(F(u_h)), ∇ v). This yields
// better performance and similar accuracy for the included test
// problems. This can be turned off and use nonlinear assembly
// similar to matrix-free assembly when -mf flag is provided.
// It also demonstrates how to use GLVis for in-situ visualization
// of vector grid function and how to set top-view.
// The example demonstrates user-defined bilinear and nonlinear
// form integrators for systems of equations that are defined with
// block vectors, and how these are used with an operator for
// explicit time integrators. In this case the system also
// involves an external approximate Riemann solver for the DG
// interface flux. It also demonstrates how to use GLVis for
// in-situ visualization of vector grid functions.
//
// We recommend viewing examples 9, 14 and 17 before viewing this
// example.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include <sstream>
#include <iostream>
// Classes FE_Evolution, RiemannSolver, and FaceIntegrator
// shared between the serial and parallel version of the example.
#include "ex18.hpp"
using namespace std;
using namespace mfem;
// Choice for the problem setup. See InitialCondition in ex18.hpp.
int problem;
// Equation constant parameters.
const int num_equation = 4;
const double specific_heat_ratio = 1.4;
const double gas_constant = 1.0;
// Maximum characteristic speed (updated by integrators)
double max_char_speed;
int main(int argc, char *argv[])
{
// 0. Parallel setup
// 1. Initialize MPI and HYPRE.
Mpi::Init(argc, argv);
const int numProcs = Mpi::WorldSize();
const int myRank = Mpi::WorldRank();
Hypre::Init();
// 1. Parse command-line options.
int problem = 1;
const real_t specific_heat_ratio = 1.4;
const real_t gas_constant = 1.0;
string mesh_file = "";
int IntOrderOffset = 1;
// 2. Parse command-line options.
problem = 1;
const char *mesh_file = "../data/periodic-square.mesh";
int ser_ref_levels = 0;
int par_ref_levels = 1;
int order = 3;
int ode_solver_type = 4;
real_t t_final = 2.0;
real_t dt = -0.01;
real_t cfl = 0.3;
double t_final = 2.0;
double dt = -0.01;
double cfl = 0.3;
bool visualization = true;
bool preassembleWeakDiv = true;
int vis_steps = 50;
int precision = 8;
@@ -88,20 +82,22 @@ int main(int argc, char *argv[])
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use. If not provided, then a periodic square"
" mesh will be used.");
"Mesh file to use.");
args.AddOption(&problem, "-p", "--problem",
"Problem setup to use. See EulerInitialCondition().");
args.AddOption(&ser_ref_levels, "-rs", "--serial-refine",
"Number of times to refine the serial mesh uniformly.");
args.AddOption(&par_ref_levels, "-rp", "--parallel-refine",
"Number of times to refine the parallel mesh uniformly.");
"Problem setup to use. See options in velocity_function().");
args.AddOption(&ser_ref_levels, "-rs", "--refine-serial",
"Number of times to refine the mesh uniformly before parallel"
" partitioning, -1 for auto.");
args.AddOption(&par_ref_levels, "-rp", "--refine-parallel",
"Number of times to refine the mesh uniformly after parallel"
" partitioning.");
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
args.AddOption(&t_final, "-tf", "--t-final", "Final time; start time is 0.");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
"Time step. Positive number skips CFL timestep calculation.");
args.AddOption(&cfl, "-c", "--cfl-number",
@@ -109,44 +105,25 @@ int main(int argc, char *argv[])
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&preassembleWeakDiv, "-ea", "--element-assembly-divergence",
"-mf", "--matrix-free-divergence",
"Weak divergence assembly level\n"
" ea - Element assembly with interpolated F\n"
" mf - Nonlinear assembly in matrix-free manner");
args.AddOption(&vis_steps, "-vs", "--visualization-steps",
"Visualize every n-th timestep.");
args.ParseCheck();
// 2. Read the mesh from the given mesh file. When the user does not provide
// mesh file, use the default mesh file for the problem.
Mesh mesh = mesh_file.empty() ? EulerMesh(problem) : Mesh(mesh_file);
args.Parse();
if (!args.Good())
{
if (Mpi::Root()) { args.PrintUsage(cout); }
return 1;
}
if (Mpi::Root()) { args.PrintOptions(cout); }
// 3. Read the mesh from the given mesh file. This example requires a 2D
// periodic mesh, such as ../data/periodic-square.mesh.
Mesh mesh(mesh_file, 1, 1);
const int dim = mesh.Dimension();
const int num_equations = dim + 2;
// Refine the mesh 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();
}
MFEM_ASSERT(dim == 2, "Need a two-dimensional mesh for the problem definition");
// 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 = ParMesh(MPI_COMM_WORLD, mesh);
mesh.Clear();
// Refine the mesh to increase the resolution. In this example we do
// 'par_ref_levels' of uniform refinement, where 'par_ref_levels' is a
// command-line parameter.
for (int lev = 0; lev < par_ref_levels; lev++)
{
pmesh.UniformRefinement();
}
// 3. Define the ODE solver used for time integration. Several explicit
// 4. Define the ODE solver used for time integration. Several explicit
// Runge-Kutta methods are available.
ODESolver *ode_solver = NULL;
switch (ode_solver_type)
@@ -157,11 +134,32 @@ int main(int argc, char *argv[])
case 4: ode_solver = new RK4Solver; break;
case 6: ode_solver = new RK6Solver; break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
if (Mpi::Root())
{
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
}
return 3;
}
// 4. Define the discontinuous DG finite element space of the given
// 5. Refine the mesh in serial to increase the resolution. In this example
// we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
// a command-line parameter.
for (int lev = 0; lev < ser_ref_levels; lev++)
{
mesh.UniformRefinement();
}
// 6. Define a parallel mesh by a partitioning of the serial mesh. Refine
// this mesh further in parallel to increase the resolution. Once the
// parallel mesh is defined, the serial mesh can be deleted.
ParMesh pmesh(MPI_COMM_WORLD, mesh);
mesh.Clear();
for (int lev = 0; lev < par_ref_levels; lev++)
{
pmesh.UniformRefinement();
}
// 7. Define the discontinuous DG finite element space of the given
// polynomial order on the refined mesh.
DG_FECollection fec(order, dim);
// Finite element space for a scalar (thermodynamic quantity)
@@ -169,7 +167,7 @@ int main(int argc, char *argv[])
// Finite element space for a mesh-dim vector quantity (momentum)
ParFiniteElementSpace dfes(&pmesh, &fec, dim, Ordering::byNODES);
// Finite element space for all variables together (total thermodynamic state)
ParFiniteElementSpace vfes(&pmesh, &fec, num_equations, Ordering::byNODES);
ParFiniteElementSpace vfes(&pmesh, &fec, num_equation, Ordering::byNODES);
// This example depends on this ordering of the space.
MFEM_ASSERT(fes.GetOrdering() == Ordering::byNODES, "");
@@ -180,72 +178,87 @@ int main(int argc, char *argv[])
cout << "Number of unknowns: " << glob_size << endl;
}
// 5. Define the initial conditions, save the corresponding mesh and grid
// functions to files. These can be opened with GLVis using:
// "glvis -np 4 -m euler-mesh -g euler-1-init" (for x-momentum).
// 8. Define the initial conditions, save the corresponding mesh and grid
// functions to a file. This can be opened with GLVis with the -gc option.
// The solution u has components {density, x-momentum, y-momentum, energy}.
// These are stored contiguously in the BlockVector u_block.
Array<int> offsets(num_equation + 1);
for (int k = 0; k <= num_equation; k++) { offsets[k] = k * vfes.GetNDofs(); }
BlockVector u_block(offsets);
// Momentum grid function on dfes for visualization.
ParGridFunction mom(&dfes, u_block.GetData() + offsets[1]);
// Initialize the state.
VectorFunctionCoefficient u0 = EulerInitialCondition(problem,
specific_heat_ratio,
gas_constant);
ParGridFunction sol(&vfes);
VectorFunctionCoefficient u0(num_equation, InitialCondition);
ParGridFunction sol(&vfes, u_block.GetData());
sol.ProjectCoefficient(u0);
ParGridFunction mom(&dfes, sol.GetData() + fes.GetNDofs());
// Output the initial solution.
{
ostringstream mesh_name;
mesh_name << "euler-mesh." << setfill('0') << setw(6) << Mpi::WorldRank();
mesh_name << "vortex-mesh." << setfill('0')
<< setw(6) << Mpi::WorldRank();
ofstream mesh_ofs(mesh_name.str().c_str());
mesh_ofs.precision(precision);
mesh_ofs << pmesh;
for (int k = 0; k < num_equations; k++)
for (int k = 0; k < num_equation; k++)
{
ParGridFunction uk(&fes, sol.GetData() + k * fes.GetNDofs());
ParGridFunction uk(&fes, u_block.GetBlock(k));
ostringstream sol_name;
sol_name << "euler-" << k << "-init." << setfill('0') << setw(6)
<< Mpi::WorldRank();
sol_name << "vortex-" << k << "-init."
<< setfill('0') << setw(6) << Mpi::WorldRank();
ofstream sol_ofs(sol_name.str().c_str());
sol_ofs.precision(precision);
sol_ofs << uk;
}
}
// 6. Set up the nonlinear form with euler flux and numerical flux
EulerFlux flux(dim, specific_heat_ratio);
RusanovFlux numericalFlux(flux);
DGHyperbolicConservationLaws euler(
vfes, std::unique_ptr<HyperbolicFormIntegrator>(
new HyperbolicFormIntegrator(numericalFlux, IntOrderOffset)),
preassembleWeakDiv);
// 9. Set up the nonlinear form corresponding to the DG discretization of the
// flux divergence, and assemble the corresponding mass matrix.
MixedBilinearForm Aflux(&dfes, &fes);
Aflux.AddDomainIntegrator(new TransposeIntegrator(new GradientIntegrator()));
Aflux.Assemble();
// 7. Visualize momentum with its magnitude
ParNonlinearForm A(&vfes);
RiemannSolver rsolver;
A.AddInteriorFaceIntegrator(new FaceIntegrator(rsolver, dim));
// 10. Define the time-dependent evolution operator describing the ODE
// right-hand side, and perform time-integration (looping over the time
// iterations, ti, with a time-step dt).
FE_Evolution euler(vfes, A, Aflux.SpMat());
// Visualize the density
socketstream sout;
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
int visport = 19916;
MPI_Barrier(pmesh.GetComm());
sout.open(vishost, visport);
if (!sout)
{
if (Mpi::Root())
{
cout << "Unable to connect to GLVis server at "
<< vishost << ':' << visport << endl;
}
visualization = false;
if (Mpi::Root())
{
cout << "Unable to connect to GLVis server at " << vishost << ':'
<< visport << endl;
cout << "GLVis visualization disabled.\n";
}
}
else
{
sout << "parallel " << Mpi::WorldSize()
<< " " << Mpi::WorldRank() << "\n";
sout.precision(precision);
// Plot magnitude of vector-valued momentum
sout << "parallel " << numProcs << " " << myRank << "\n";
sout << "solution\n" << pmesh << mom;
sout << "window_title 'momentum, t = 0'\n";
sout << "view 0 0\n"; // view from top
sout << "keys jlm\n"; // turn off perspective and light, show mesh
sout << "pause\n";
sout << flush;
if (Mpi::Root())
@@ -253,63 +266,68 @@ int main(int argc, char *argv[])
cout << "GLVis visualization paused."
<< " Press space (in the GLVis window) to resume it.\n";
}
MPI_Barrier(pmesh.GetComm());
}
}
// 8. Time integration
// When dt is not specified, use CFL condition.
// Compute h_min and initial maximum characteristic speed
real_t hmin = infinity();
// Determine the minimum element size.
double hmin;
if (cfl > 0)
{
for (int i = 0; i < pmesh.GetNE(); i++)
double my_hmin = pmesh.GetElementSize(0, 1);
for (int i = 1; i < pmesh.GetNE(); i++)
{
hmin = min(pmesh.GetElementSize(i, 1), hmin);
my_hmin = min(pmesh.GetElementSize(i, 1), my_hmin);
}
MPI_Allreduce(MPI_IN_PLACE, &hmin, 1, MPITypeMap<real_t>::mpi_type, MPI_MIN,
pmesh.GetComm());
// Find a safe dt, using a temporary vector. Calling Mult() computes the
// maximum char speed at all quadrature points on all faces (and all
// elements with -mf).
Vector z(sol.Size());
euler.Mult(sol, z);
real_t max_char_speed = euler.GetMaxCharSpeed();
MPI_Allreduce(MPI_IN_PLACE, &max_char_speed, 1, MPITypeMap<real_t>::mpi_type,
MPI_MAX,
pmesh.GetComm());
dt = cfl * hmin / max_char_speed / (2 * order + 1);
// Reduce to find the global minimum element size
MPI_Allreduce(&my_hmin, &hmin, 1, MPI_DOUBLE, MPI_MIN, pmesh.GetComm());
}
// Start the timer.
tic_toc.Clear();
tic_toc.Start();
// Init time integration
real_t t = 0.0;
double t = 0.0;
euler.SetTime(t);
ode_solver->Init(euler);
if (cfl > 0)
{
// Find a safe dt, using a temporary vector. Calling Mult() computes the
// maximum char speed at all quadrature points on all faces.
max_char_speed = 0.;
Vector z(sol.Size());
A.Mult(sol, z);
// Reduce to find the global maximum wave speed
{
double all_max_char_speed;
MPI_Allreduce(&max_char_speed, &all_max_char_speed,
1, MPI_DOUBLE, MPI_MAX, pmesh.GetComm());
max_char_speed = all_max_char_speed;
}
dt = cfl * hmin / max_char_speed / (2*order+1);
}
// Integrate in time.
bool done = false;
for (int ti = 0; !done;)
for (int ti = 0; !done; )
{
real_t dt_real = min(dt, t_final - t);
double dt_real = min(dt, t_final - t);
ode_solver->Step(sol, t, dt_real);
if (cfl > 0) // update time step size with CFL
if (cfl > 0)
{
real_t max_char_speed = euler.GetMaxCharSpeed();
MPI_Allreduce(MPI_IN_PLACE, &max_char_speed, 1, MPITypeMap<real_t>::mpi_type,
MPI_MAX,
pmesh.GetComm());
dt = cfl * hmin / max_char_speed / (2 * order + 1);
// Reduce to find the global maximum wave speed
{
double all_max_char_speed;
MPI_Allreduce(&max_char_speed, &all_max_char_speed,
1, MPI_DOUBLE, MPI_MAX, pmesh.GetComm());
max_char_speed = all_max_char_speed;
}
dt = cfl * hmin / max_char_speed / (2*order+1);
}
ti++;
done = (t >= t_final - 1e-8 * dt);
done = (t >= t_final - 1e-8*dt);
if (done || ti % vis_steps == 0)
{
if (Mpi::Root())
@@ -318,8 +336,9 @@ int main(int argc, char *argv[])
}
if (visualization)
{
sout << "window_title 'momentum, t = " << t << "'\n";
sout << "parallel " << numProcs << " " << myRank << "\n";
MPI_Barrier(pmesh.GetComm());
sout << "parallel " << Mpi::WorldSize()
<< " " << Mpi::WorldRank() << "\n";
sout << "solution\n" << pmesh << mom << flush;
}
}
@@ -331,33 +350,27 @@ int main(int argc, char *argv[])
cout << " done, " << tic_toc.RealTime() << "s." << endl;
}
// 9. Save the final solution. This output can be viewed later using GLVis:
// "glvis -np 4 -m euler-mesh-final -g euler-1-final" (for x-momentum).
// 11. Save the final solution. This output can be viewed later using GLVis:
// "glvis -np 4 -m vortex-mesh -g vortex-1-final".
for (int k = 0; k < num_equation; k++)
{
ostringstream mesh_name;
mesh_name << "euler-mesh-final." << setfill('0') << setw(6)
<< Mpi::WorldRank();
ofstream mesh_ofs(mesh_name.str().c_str());
mesh_ofs.precision(precision);
mesh_ofs << pmesh;
for (int k = 0; k < num_equations; k++)
{
ParGridFunction uk(&fes, sol.GetData() + k * fes.GetNDofs());
ostringstream sol_name;
sol_name << "euler-" << k << "-final." << setfill('0') << setw(6)
<< Mpi::WorldRank();
ofstream sol_ofs(sol_name.str().c_str());
sol_ofs.precision(precision);
sol_ofs << uk;
}
ParGridFunction uk(&fes, u_block.GetBlock(k));
ostringstream sol_name;
sol_name << "vortex-" << k << "-final."
<< setfill('0') << setw(6) << Mpi::WorldRank();
ofstream sol_ofs(sol_name.str().c_str());
sol_ofs.precision(precision);
sol_ofs << uk;
}
// 10. Compute the L2 solution error summed for all components.
const real_t error = sol.ComputeLpError(2, u0);
if (Mpi::Root())
// 12. Compute the L2 solution error summed for all components.
if (t_final == 2.0)
{
cout << "Solution error: " << error << endl;
const double error = sol.ComputeLpError(2, u0);
if (Mpi::Root())
{
cout << "Solution error: " << error << endl;
}
}
// Free the used memory.
+10 -10
View File
@@ -48,15 +48,15 @@ public:
print_level = print_lvl;
}
virtual void MonitorResidual(int it, real_t norm, const Vector &r, bool final);
virtual void MonitorResidual(int it, double norm, const Vector &r, bool final);
private:
const std::string prefix;
int print_level;
mutable real_t norm0;
mutable double norm0;
};
void GeneralResidualMonitor::MonitorResidual(int it, real_t norm,
void GeneralResidualMonitor::MonitorResidual(int it, double norm,
const Vector &r, bool final)
{
if (print_level == 1 || (print_level == 3 && (final || it == 0)))
@@ -103,7 +103,7 @@ protected:
BlockOperator *jacobian;
// Scaling factor for the pressure mass matrix in the block preconditioner
real_t gamma;
double gamma;
// Objects for the block preconditioner application
SparseMatrix *pressure_mass;
@@ -157,7 +157,7 @@ protected:
public:
RubberOperator(Array<FiniteElementSpace *> &fes, Array<Array<int> *>&ess_bdr,
Array<int> &block_trueOffsets, real_t rel_tol, real_t abs_tol,
Array<int> &block_trueOffsets, double rel_tol, double abs_tol,
int iter, Coefficient &mu);
// Required to use the native newton solver
@@ -187,10 +187,10 @@ int main(int argc, char *argv[])
int ref_levels = 0;
int order = 2;
bool visualization = true;
real_t newton_rel_tol = 1e-4;
real_t newton_abs_tol = 1e-6;
double newton_rel_tol = 1e-4;
double newton_abs_tol = 1e-6;
int newton_iter = 500;
real_t mu = 1.0;
double mu = 1.0;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -449,8 +449,8 @@ JacobianPreconditioner::~JacobianPreconditioner()
RubberOperator::RubberOperator(Array<FiniteElementSpace *> &fes,
Array<Array<int> *> &ess_bdr,
Array<int> &offsets,
real_t rel_tol,
real_t abs_tol,
double rel_tol,
double abs_tol,
int iter,
Coefficient &c_mu)
: Operator(fes[0]->GetTrueVSize() + fes[1]->GetTrueVSize()),
+11 -11
View File
@@ -62,15 +62,15 @@ public:
#endif
}
virtual void MonitorResidual(int it, real_t norm, const Vector &r, bool final);
virtual void MonitorResidual(int it, double norm, const Vector &r, bool final);
private:
const std::string prefix;
int print_level;
mutable real_t norm0;
mutable double norm0;
};
void GeneralResidualMonitor::MonitorResidual(int it, real_t norm,
void GeneralResidualMonitor::MonitorResidual(int it, double norm,
const Vector &r, bool final)
{
if (print_level == 1 || (print_level == 3 && (final || it == 0)))
@@ -117,7 +117,7 @@ protected:
BlockOperator *jacobian;
// Scaling factor for the pressure mass matrix in the block preconditioner
real_t gamma;
double gamma;
// Objects for the block preconditioner application
Operator *pressure_mass;
@@ -171,7 +171,7 @@ protected:
public:
RubberOperator(Array<ParFiniteElementSpace *> &fes, Array<Array<int> *>&ess_bdr,
Array<int> &block_trueOffsets, real_t rel_tol, real_t abs_tol,
Array<int> &block_trueOffsets, double rel_tol, double abs_tol,
int iter, Coefficient &mu);
// Required to use the native newton solver
@@ -200,7 +200,7 @@ int main(int argc, char *argv[])
#ifdef HYPRE_USING_GPU
cout << "\nAs of mfem-4.3 and hypre-2.22.0 (July 2021) this example\n"
<< "is NOT supported with the GPU version of hypre.\n\n";
return MFEM_SKIP_RETURN_VALUE;
return 242;
#endif
// 1. Initialize MPI and HYPRE.
@@ -214,10 +214,10 @@ int main(int argc, char *argv[])
int par_ref_levels = 0;
int order = 2;
bool visualization = true;
real_t newton_rel_tol = 1e-4;
real_t newton_abs_tol = 1e-6;
double newton_rel_tol = 1e-4;
double newton_abs_tol = 1e-6;
int newton_iter = 500;
real_t mu = 1.0;
double mu = 1.0;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -524,8 +524,8 @@ JacobianPreconditioner::~JacobianPreconditioner()
RubberOperator::RubberOperator(Array<ParFiniteElementSpace *> &fes,
Array<Array<int> *> &ess_bdr,
Array<int> &trueOffsets,
real_t rel_tol,
real_t abs_tol,
double rel_tol,
double abs_tol,
int iter,
Coefficient &c_mu)
: Operator(fes[0]->TrueVSize() + fes[1]->TrueVSize()),
+10 -10
View File
@@ -69,11 +69,11 @@ using namespace mfem;
// Constants used in the Hamiltonian
static int prob_ = 0;
static real_t m_ = 1.0;
static real_t k_ = 1.0;
static double m_ = 1.0;
static double k_ = 1.0;
// Hamiltonian functional, see below for implementation
real_t hamiltonian(real_t q, real_t p, real_t t);
double hamiltonian(double q, double p, double t);
class GradT : public Operator
{
@@ -94,7 +94,7 @@ int main(int argc, char *argv[])
// 1. Parse command-line options.
int order = 1;
int nsteps = 100;
real_t dt = 0.1;
double dt = 0.1;
bool visualization = true;
bool gnuplot = false;
@@ -136,7 +136,7 @@ int main(int argc, char *argv[])
siaSolver.Init(P,F);
// 3. Set the initial conditions
real_t t = 0.0;
double t = 0.0;
Vector q(1), p(1);
Vector e(nsteps+1);
q(0) = 0.0;
@@ -160,7 +160,7 @@ int main(int argc, char *argv[])
Vector x1(3); x1 = 0.0;
// 6. Perform time-stepping
real_t e_mean = 0.0;
double e_mean = 0.0;
for (int i = 0; i < nsteps; i++)
{
@@ -210,13 +210,13 @@ int main(int argc, char *argv[])
// 7. Compute and display mean and standard deviation of the energy
e_mean /= (nsteps + 1);
real_t e_var = 0.0;
double e_var = 0.0;
for (int i=0; i<=nsteps; i++)
{
e_var += pow(e[i] - e_mean, 2);
}
e_var /= (nsteps + 1);
real_t e_sd = sqrt(e_var);
double e_sd = sqrt(e_var);
cout << endl << "Mean and standard deviation of the energy" << endl;
cout << e_mean << "\t" << e_sd << endl;
@@ -256,9 +256,9 @@ int main(int argc, char *argv[])
}
}
real_t hamiltonian(real_t q, real_t p, real_t t)
double hamiltonian(double q, double p, double t)
{
real_t h = 1.0 - 0.5 / m_ + 0.5 * p * p / m_;
double h = 1.0 - 0.5 / m_ + 0.5 * p * p / m_;
switch (prob_)
{
case 1:
+15 -16
View File
@@ -74,11 +74,11 @@ using namespace mfem;
// Constants used in the Hamiltonian
static int prob_ = 0;
static real_t m_ = 1.0;
static real_t k_ = 1.0;
static double m_ = 1.0;
static double k_ = 1.0;
// Hamiltonian functional, see below for implementation
real_t hamiltonian(real_t q, real_t p, real_t t);
double hamiltonian(double q, double p, double t);
class GradT : public Operator
{
@@ -106,7 +106,7 @@ int main(int argc, char *argv[])
// 2. Parse command-line options.
int order = 1;
int nsteps = 100;
real_t dt = 0.1;
double dt = 0.1;
bool visualization = true;
bool gnuplot = false;
@@ -154,11 +154,11 @@ int main(int argc, char *argv[])
siaSolver.Init(P,F);
// 4. Set the initial conditions
real_t t = 0.0;
double t = 0.0;
Vector q(1), p(1);
Vector e(nsteps+1);
q(0) = sin(2.0*M_PI*(real_t)myid/num_procs);
p(0) = cos(2.0*M_PI*(real_t)myid/num_procs);
q(0) = sin(2.0*M_PI*(double)myid/num_procs);
p(0) = cos(2.0*M_PI*(double)myid/num_procs);
// 5. Prepare GnuPlot output file if needed
ostringstream oss;
@@ -181,7 +181,7 @@ int main(int argc, char *argv[])
Vector x1(3); x1 = 0.0;
// 7. Perform time-stepping
real_t e_mean = 0.0;
double e_mean = 0.0;
for (int i = 0; i < nsteps; i++)
{
@@ -238,21 +238,20 @@ int main(int argc, char *argv[])
// 8. Compute and display mean and standard deviation of the energy
e_mean /= (nsteps + 1);
real_t e_var = 0.0;
double e_var = 0.0;
for (int i = 0; i <= nsteps; i++)
{
e_var += pow(e[i] - e_mean, 2);
}
e_var /= (nsteps + 1);
real_t e_sd = sqrt(e_var);
double e_sd = sqrt(e_var);
real_t e_loc_stats[2];
real_t *e_stats = (myid == 0) ? new real_t[2 * num_procs] : (real_t*)NULL;
double e_loc_stats[2];
double *e_stats = (myid == 0) ? new double[2 * num_procs] : (double*)NULL;
e_loc_stats[0] = e_mean;
e_loc_stats[1] = e_sd;
MPI_Gather(e_loc_stats, 2, MPITypeMap<real_t>::mpi_type, e_stats, 2,
MPITypeMap<real_t>::mpi_type, 0, comm);
MPI_Gather(e_loc_stats, 2, MPI_DOUBLE, e_stats, 2, MPI_DOUBLE, 0, comm);
if (myid == 0)
{
@@ -325,9 +324,9 @@ int main(int argc, char *argv[])
}
}
real_t hamiltonian(real_t q, real_t p, real_t t)
double hamiltonian(double q, double p, double t)
{
real_t h = 1.0 - 0.5 / m_ + 0.5 * p * p / m_;
double h = 1.0 - 0.5 / m_ + 0.5 * p * p / m_;
switch (prob_)
{
case 1:
+18 -18
View File
@@ -57,13 +57,13 @@
using namespace std;
using namespace mfem;
static real_t mu_ = 1.0;
static real_t epsilon_ = 1.0;
static real_t sigma_ = 20.0;
static real_t omega_ = 10.0;
static double mu_ = 1.0;
static double epsilon_ = 1.0;
static double sigma_ = 20.0;
static double omega_ = 10.0;
real_t u0_real_exact(const Vector &);
real_t u0_imag_exact(const Vector &);
double u0_real_exact(const Vector &);
double u0_imag_exact(const Vector &);
void u1_real_exact(const Vector &, Vector &);
void u1_imag_exact(const Vector &, Vector &);
@@ -80,8 +80,8 @@ int main(int argc, char *argv[])
int ref_levels = 0;
int order = 1;
int prob = 0;
real_t freq = -1.0;
real_t a_coef = 0.0;
double freq = -1.0;
double a_coef = 0.0;
bool visualization = 1;
bool herm_conv = true;
bool exact_sol = true;
@@ -412,7 +412,7 @@ int main(int argc, char *argv[])
break; // This should be unreachable
}
}
real_t s = (prob != 1) ? 1.0 : -1.0;
double s = (prob != 1) ? 1.0 : -1.0;
pc_i = new ScaledOperator(pc_r,
(conv == ComplexOperator::HERMITIAN) ?
s:-s);
@@ -436,8 +436,8 @@ int main(int argc, char *argv[])
if (exact_sol)
{
real_t err_r = -1.0;
real_t err_i = -1.0;
double err_r = -1.0;
double err_i = -1.0;
switch (prob)
{
@@ -524,7 +524,7 @@ int main(int argc, char *argv[])
int i = 0;
while (sol_sock)
{
real_t t = (real_t)(i % num_frames) / num_frames;
double t = (double)(i % num_frames) / num_frames;
ostringstream oss;
oss << "Harmonic Solution (t = " << t << " T)";
@@ -555,21 +555,21 @@ bool check_for_inline_mesh(const char * mesh_file)
return s0 == "inline-";
}
complex<real_t> u0_exact(const Vector &x)
complex<double> u0_exact(const Vector &x)
{
int dim = x.Size();
complex<real_t> i(0.0, 1.0);
complex<real_t> alpha = (epsilon_ * omega_ - i * sigma_);
complex<real_t> kappa = std::sqrt(mu_ * omega_* alpha);
complex<double> i(0.0, 1.0);
complex<double> alpha = (epsilon_ * omega_ - i * sigma_);
complex<double> kappa = std::sqrt(mu_ * omega_* alpha);
return std::exp(-i * kappa * x[dim - 1]);
}
real_t u0_real_exact(const Vector &x)
double u0_real_exact(const Vector &x)
{
return u0_exact(x).real();
}
real_t u0_imag_exact(const Vector &x)
double u0_imag_exact(const Vector &x)
{
return u0_exact(x).imag();
}
+17 -17
View File
@@ -57,13 +57,13 @@
using namespace std;
using namespace mfem;
static real_t mu_ = 1.0;
static real_t epsilon_ = 1.0;
static real_t sigma_ = 20.0;
static real_t omega_ = 10.0;
static double mu_ = 1.0;
static double epsilon_ = 1.0;
static double sigma_ = 20.0;
static double omega_ = 10.0;
real_t u0_real_exact(const Vector &);
real_t u0_imag_exact(const Vector &);
double u0_real_exact(const Vector &);
double u0_imag_exact(const Vector &);
void u1_real_exact(const Vector &, Vector &);
void u1_imag_exact(const Vector &, Vector &);
@@ -87,8 +87,8 @@ int main(int argc, char *argv[])
int par_ref_levels = 1;
int order = 1;
int prob = 0;
real_t freq = -1.0;
real_t a_coef = 0.0;
double freq = -1.0;
double a_coef = 0.0;
bool visualization = 1;
bool herm_conv = true;
bool exact_sol = true;
@@ -475,8 +475,8 @@ int main(int argc, char *argv[])
if (exact_sol)
{
real_t err_r = -1.0;
real_t err_i = -1.0;
double err_r = -1.0;
double err_i = -1.0;
switch (prob)
{
@@ -576,7 +576,7 @@ int main(int argc, char *argv[])
int i = 0;
while (sol_sock)
{
real_t t = (real_t)(i % num_frames) / num_frames;
double t = (double)(i % num_frames) / num_frames;
ostringstream oss;
oss << "Harmonic Solution (t = " << t << " T)";
@@ -608,21 +608,21 @@ bool check_for_inline_mesh(const char * mesh_file)
return s0 == "inline-";
}
complex<real_t> u0_exact(const Vector &x)
complex<double> u0_exact(const Vector &x)
{
int dim = x.Size();
complex<real_t> i(0.0, 1.0);
complex<real_t> alpha = (epsilon_ * omega_ - i * sigma_);
complex<real_t> kappa = std::sqrt(mu_ * omega_* alpha);
complex<double> i(0.0, 1.0);
complex<double> alpha = (epsilon_ * omega_ - i * sigma_);
complex<double> kappa = std::sqrt(mu_ * omega_* alpha);
return std::exp(-i * kappa * x[dim - 1]);
}
real_t u0_real_exact(const Vector &x)
double u0_real_exact(const Vector &x)
{
return u0_exact(x).real();
}
real_t u0_imag_exact(const Vector &x)
double u0_imag_exact(const Vector &x)
{
return u0_exact(x).imag();
}
+15 -14
View File
@@ -46,7 +46,7 @@ protected:
SparseMatrix Mmat, Kmat, Kmat0;
SparseMatrix *T; // T = M + dt K
real_t current_dt;
double current_dt;
CGSolver M_solver; // Krylov solver for inverting the mass matrix M
DSmoother M_prec; // Preconditioner for the mass matrix M
@@ -58,7 +58,7 @@ protected:
mutable Vector z; // auxiliary vector
public:
WaveOperator(FiniteElementSpace &f, Array<int> &ess_bdr, real_t speed);
WaveOperator(FiniteElementSpace &f, Array<int> &ess_bdr,double speed);
using SecondOrderTimeDependentOperator::Mult;
virtual void Mult(const Vector &u, const Vector &du_dt,
@@ -68,7 +68,7 @@ public:
d2udt2 = f(u + fac0*d2udt2,dudt + fac1*d2udt2, t),
for the unknown d2udt2. */
using SecondOrderTimeDependentOperator::ImplicitSolve;
virtual void ImplicitSolve(const real_t fac0, const real_t fac1,
virtual void ImplicitSolve(const double fac0, const double fac1,
const Vector &u, const Vector &dudt, Vector &d2udt2);
///
@@ -79,11 +79,12 @@ public:
WaveOperator::WaveOperator(FiniteElementSpace &f,
Array<int> &ess_bdr, real_t speed)
: SecondOrderTimeDependentOperator(f.GetTrueVSize(), (real_t) 0.0),
fespace(f), M(NULL), K(NULL), T(NULL), current_dt(0.0), z(height)
Array<int> &ess_bdr, double speed)
: SecondOrderTimeDependentOperator(f.GetTrueVSize(), 0.0), fespace(f), M(NULL),
K(NULL),
T(NULL), current_dt(0.0), z(height)
{
const real_t rel_tol = 1e-8;
const double rel_tol = 1e-8;
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
@@ -131,7 +132,7 @@ void WaveOperator::Mult(const Vector &u, const Vector &du_dt,
M_solver.Mult(z, d2udt2);
}
void WaveOperator::ImplicitSolve(const real_t fac0, const real_t fac1,
void WaveOperator::ImplicitSolve(const double fac0, const double fac1,
const Vector &u, const Vector &dudt, Vector &d2udt2)
{
// Solve the equation:
@@ -166,12 +167,12 @@ WaveOperator::~WaveOperator()
delete c2;
}
real_t InitialSolution(const Vector &x)
double InitialSolution(const Vector &x)
{
return exp(-x.Norml2()*x.Norml2()*30);
}
real_t InitialRate(const Vector &x)
double InitialRate(const Vector &x)
{
return 0.0;
}
@@ -185,9 +186,9 @@ int main(int argc, char *argv[])
int ref_levels = 2;
int order = 2;
int ode_solver_type = 10;
real_t t_final = 0.5;
real_t dt = 1.0e-2;
real_t speed = 1.0;
double t_final = 0.5;
double dt = 1.0e-2;
double speed = 1.0;
bool visualization = true;
bool visit = true;
bool dirichlet = true;
@@ -365,7 +366,7 @@ int main(int argc, char *argv[])
// 8. Perform time-integration (looping over the time iterations, ti, with a
// time-step dt).
ode_solver->Init(oper);
real_t t = 0.0;
double t = 0.0;
bool last_step = false;
for (int ti = 1; !last_step; ti++)
+14 -14
View File
@@ -44,14 +44,14 @@
using namespace std;
using namespace mfem;
real_t p_exact(const Vector &x);
double p_exact(const Vector &x);
void gradp_exact(const Vector &, Vector &);
real_t div_gradp_exact(const Vector &x);
double div_gradp_exact(const Vector &x);
void v_exact(const Vector &x, Vector &v);
void curlv_exact(const Vector &x, Vector &cv);
int dim;
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int main(int argc, char *argv[])
{
@@ -304,9 +304,9 @@ int main(int argc, char *argv[])
// 12. Compute and print the L_2 norm of the error.
if (prob == 0)
{
real_t errSol = x.ComputeL2Error(gradp_coef);
real_t errInterp = discreteInterpolant.ComputeL2Error(gradp_coef);
real_t errProj = exact_proj.ComputeL2Error(gradp_coef);
double errSol = x.ComputeL2Error(gradp_coef);
double errInterp = discreteInterpolant.ComputeL2Error(gradp_coef);
double errProj = exact_proj.ComputeL2Error(gradp_coef);
cout << "\n Solution of (E_h,v) = (grad p_h,v) for E_h and v in H(curl): "
"|| E_h - grad p ||_{L_2} = " << errSol << '\n' << endl;
@@ -317,9 +317,9 @@ int main(int argc, char *argv[])
}
else if (prob == 1)
{
real_t errSol = x.ComputeL2Error(curlv_coef);
real_t errInterp = discreteInterpolant.ComputeL2Error(curlv_coef);
real_t errProj = exact_proj.ComputeL2Error(curlv_coef);
double errSol = x.ComputeL2Error(curlv_coef);
double errInterp = discreteInterpolant.ComputeL2Error(curlv_coef);
double errProj = exact_proj.ComputeL2Error(curlv_coef);
cout << "\n Solution of (E_h,w) = (curl v_h,w) for E_h and w in H(div): "
"|| E_h - curl v ||_{L_2} = " << errSol << '\n' << endl;
@@ -337,9 +337,9 @@ int main(int argc, char *argv[])
irs[i] = &(IntRules.Get(i, order_quad));
}
real_t errSol = x.ComputeL2Error(divgradp_coef, irs);
real_t errInterp = discreteInterpolant.ComputeL2Error(divgradp_coef, irs);
real_t errProj = exact_proj.ComputeL2Error(divgradp_coef, irs);
double errSol = x.ComputeL2Error(divgradp_coef, irs);
double errInterp = discreteInterpolant.ComputeL2Error(divgradp_coef, irs);
double errProj = exact_proj.ComputeL2Error(divgradp_coef, irs);
cout << "\n Solution of (f_h,q) = (div v_h,q) for f_h and q in L_2: "
"|| f_h - div v ||_{L_2} = " << errSol << '\n' << endl;
@@ -376,7 +376,7 @@ int main(int argc, char *argv[])
return 0;
}
real_t p_exact(const Vector &x)
double p_exact(const Vector &x)
{
if (dim == 3)
{
@@ -406,7 +406,7 @@ void gradp_exact(const Vector &x, Vector &f)
}
}
real_t div_gradp_exact(const Vector &x)
double div_gradp_exact(const Vector &x)
{
if (dim == 3)
{
+14 -14
View File
@@ -44,14 +44,14 @@
using namespace std;
using namespace mfem;
real_t p_exact(const Vector &x);
double p_exact(const Vector &x);
void gradp_exact(const Vector &, Vector &);
real_t div_gradp_exact(const Vector &x);
double div_gradp_exact(const Vector &x);
void v_exact(const Vector &x, Vector &v);
void curlv_exact(const Vector &x, Vector &cv);
int dim;
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int main(int argc, char *argv[])
{
@@ -352,9 +352,9 @@ int main(int argc, char *argv[])
// 14. Compute and print the L_2 norm of the error.
if (prob == 0)
{
real_t errSol = x.ComputeL2Error(gradp_coef);
real_t errInterp = discreteInterpolant.ComputeL2Error(gradp_coef);
real_t errProj = exact_proj.ComputeL2Error(gradp_coef);
double errSol = x.ComputeL2Error(gradp_coef);
double errInterp = discreteInterpolant.ComputeL2Error(gradp_coef);
double errProj = exact_proj.ComputeL2Error(gradp_coef);
if (myid == 0)
{
@@ -368,9 +368,9 @@ int main(int argc, char *argv[])
}
else if (prob == 1)
{
real_t errSol = x.ComputeL2Error(curlv_coef);
real_t errInterp = discreteInterpolant.ComputeL2Error(curlv_coef);
real_t errProj = exact_proj.ComputeL2Error(curlv_coef);
double errSol = x.ComputeL2Error(curlv_coef);
double errInterp = discreteInterpolant.ComputeL2Error(curlv_coef);
double errProj = exact_proj.ComputeL2Error(curlv_coef);
if (myid == 0)
{
@@ -391,9 +391,9 @@ int main(int argc, char *argv[])
irs[i] = &(IntRules.Get(i, order_quad));
}
real_t errSol = x.ComputeL2Error(divgradp_coef, irs);
real_t errInterp = discreteInterpolant.ComputeL2Error(divgradp_coef, irs);
real_t errProj = exact_proj.ComputeL2Error(divgradp_coef, irs);
double errSol = x.ComputeL2Error(divgradp_coef, irs);
double errInterp = discreteInterpolant.ComputeL2Error(divgradp_coef, irs);
double errProj = exact_proj.ComputeL2Error(divgradp_coef, irs);
if (myid == 0)
{
@@ -441,7 +441,7 @@ int main(int argc, char *argv[])
return 0;
}
real_t p_exact(const Vector &x)
double p_exact(const Vector &x)
{
if (dim == 3)
{
@@ -471,7 +471,7 @@ void gradp_exact(const Vector &x, Vector &f)
}
}
real_t div_gradp_exact(const Vector &x)
double div_gradp_exact(const Vector &x)
{
if (dim == 3)
{
+117 -121
View File
@@ -53,13 +53,13 @@ private:
int dim;
// Length of the PML Region in each direction
Array2D<real_t> length;
Array2D<double> length;
// Computational Domain Boundary
Array2D<real_t> comp_dom_bdr;
Array2D<double> comp_dom_bdr;
// Domain Boundary
Array2D<real_t> dom_bdr;
Array2D<double> dom_bdr;
// Integer Array identifying elements in the PML
// 0: in the PML, 1: not in the PML
@@ -70,13 +70,13 @@ private:
public:
// Constructor
PML(Mesh *mesh_,Array2D<real_t> length_);
PML(Mesh *mesh_,Array2D<double> length_);
// Return Computational Domain Boundary
Array2D<real_t> GetCompDomainBdr() {return comp_dom_bdr;}
Array2D<double> GetCompDomainBdr() {return comp_dom_bdr;}
// Return Domain Boundary
Array2D<real_t> GetDomainBdr() {return dom_bdr;}
Array2D<double> GetDomainBdr() {return dom_bdr;}
// Return Markers list for elements
Array<int> * GetMarkedPMLElements() {return &elems;}
@@ -85,7 +85,7 @@ public:
void SetAttributes(Mesh *mesh_);
// PML complex stretching function
void StretchFunction(const Vector &x, vector<complex<real_t>> &dxs);
void StretchFunction(const Vector &x, vector<complex<double>> &dxs);
};
// Class for returning the PML coefficients of the bilinear form
@@ -104,9 +104,9 @@ public:
using VectorCoefficient::Eval;
virtual void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip)
const IntegrationPoint &ip) const
{
real_t x[3];
double x[3];
Vector transip(x, 3);
T.Transform(ip, transip);
K.SetSize(vdim);
@@ -114,7 +114,7 @@ public:
}
};
void maxwell_solution(const Vector &x, vector<complex<real_t>> &Eval);
void maxwell_solution(const Vector &x, vector<complex<double>> &Eval);
void E_bdr_data_Re(const Vector &x, Vector &E);
void E_bdr_data_Im(const Vector &x, Vector &E);
@@ -134,17 +134,15 @@ void detJ_inv_JT_J_Re(const Vector &x, PML * pml, Vector &D);
void detJ_inv_JT_J_Im(const Vector &x, PML * pml, Vector &D);
void detJ_inv_JT_J_abs(const Vector &x, PML * pml, Vector &D);
Array2D<real_t> comp_domain_bdr;
Array2D<real_t> domain_bdr;
Array2D<double> comp_domain_bdr;
Array2D<double> domain_bdr;
real_t mu = 1.0;
real_t epsilon = 1.0;
real_t omega;
double mu = 1.0;
double epsilon = 1.0;
double omega;
int dim;
bool exact_known = false;
template <typename T> T pow2(const T &x) { return x*x; }
enum prob_type
{
beam, // Wave propagating in a beam-like domain
@@ -162,7 +160,7 @@ int main(int argc, char *argv[])
int order = 1;
int ref_levels = 3;
int iprob = 4;
real_t freq = 5.0;
double freq = 5.0;
bool herm_conv = true;
bool umf_solver = false;
bool visualization = 1;
@@ -243,10 +241,10 @@ int main(int argc, char *argv[])
dim = mesh->Dimension();
// Angular frequency
omega = real_t(2.0 * M_PI) * freq;
omega = 2.0 * M_PI * freq;
// Setup PML length
Array2D<real_t> length(dim, 2); length = 0.0;
Array2D<double> length(dim, 2); length = 0.0;
// 4. Setup the Cartesian PML region.
switch (prob)
@@ -314,15 +312,14 @@ int main(int argc, char *argv[])
switch (prob)
{
case lshape:
if (center[0] == 1_r || center[0] == 0.5_r ||
center[1] == 0.5_r)
if (center[0] == 1.0 || center[0] == 0.5 || center[1] == 0.5)
{
ess_bdr[k - 1] = 1;
}
break;
case fichera:
if (center[0] == -1_r || center[0] == 0_r ||
center[1] == 0_r || center[2] == 0_r)
if (center[0] == -1.0 || center[0] == 0.0 ||
center[1] == 0.0 || center[2] == 0.0)
{
ess_bdr[k - 1] = 1;
}
@@ -381,8 +378,8 @@ int main(int argc, char *argv[])
}
}
ConstantCoefficient muinv(1_r / mu);
ConstantCoefficient omeg(-pow2(omega) * epsilon);
ConstantCoefficient muinv(1.0/mu);
ConstantCoefficient omeg(-pow(omega, 2) * epsilon);
RestrictedCoefficient restr_muinv(muinv,attr);
RestrictedCoefficient restr_omeg(omeg,attr);
@@ -442,7 +439,7 @@ int main(int argc, char *argv[])
// + omega^2 * epsilon (abs(det(J) * (J^T J)^-1) * E, F)
if (pa || !umf_solver)
{
ConstantCoefficient absomeg(pow2(omega) * epsilon);
ConstantCoefficient absomeg(pow(omega, 2) * epsilon);
RestrictedCoefficient restr_absomeg(absomeg,attr);
BilinearForm prec(fespace);
@@ -473,7 +470,7 @@ int main(int argc, char *argv[])
std::unique_ptr<Operator> pc_r;
std::unique_ptr<Operator> pc_i;
real_t s = (conv == ComplexOperator::HERMITIAN) ? -1_r : 1_r;
double s = (conv == ComplexOperator::HERMITIAN) ? -1.0 : 1.0;
if (pa)
{
// Jacobi Smoother
@@ -522,14 +519,14 @@ int main(int argc, char *argv[])
irs[i] = &(IntRules.Get(i, order_quad));
}
real_t L2Error_Re = x.real().ComputeL2Error(E_ex_Re, irs,
double L2Error_Re = x.real().ComputeL2Error(E_ex_Re, irs,
pml->GetMarkedPMLElements());
real_t L2Error_Im = x.imag().ComputeL2Error(E_ex_Im, irs,
double L2Error_Im = x.imag().ComputeL2Error(E_ex_Im, irs,
pml->GetMarkedPMLElements());
ComplexGridFunction x_gf0(fespace);
x_gf0 = 0.0;
real_t norm_E_Re, norm_E_Im;
double norm_E_Re, norm_E_Im;
norm_E_Re = x_gf0.real().ComputeL2Error(E_ex_Re, irs,
pml->GetMarkedPMLElements());
norm_E_Im = x_gf0.imag().ComputeL2Error(E_ex_Im, irs,
@@ -596,12 +593,12 @@ int main(int argc, char *argv[])
int i = 0;
while (sol_sock)
{
real_t t = (real_t)(i % num_frames) / num_frames;
double t = (double)(i % num_frames) / num_frames;
ostringstream oss;
oss << "Harmonic Solution (t = " << t << " T)";
add(cos(real_t(2.0 * M_PI) * t), x.real(),
sin(real_t(2.0 * M_PI) * t), x.imag(), x_t);
add(cos(2.0 * M_PI * t), x.real(),
sin(2.0 * M_PI * t), x.imag(), x_t);
sol_sock << "solution\n"
<< *mesh << x_t
<< "window_title '" << oss.str() << "'" << flush;
@@ -620,20 +617,20 @@ int main(int argc, char *argv[])
void source(const Vector &x, Vector &f)
{
Vector center(dim);
real_t r = 0.0;
double r = 0.0;
for (int i = 0; i < dim; ++i)
{
center(i) = 0.5_r * (comp_domain_bdr(i, 0) + comp_domain_bdr(i, 1));
r += pow2(x[i] - center[i]);
center(i) = 0.5 * (comp_domain_bdr(i, 0) + comp_domain_bdr(i, 1));
r += pow(x[i] - center[i], 2.);
}
real_t n = 5_r * omega * sqrt(epsilon * mu) / real_t(M_PI);
real_t coeff = pow2(n) / real_t(M_PI);
real_t alpha = -pow2(n) * r;
double n = 5.0 * omega * sqrt(epsilon * mu) / M_PI;
double coeff = pow(n, 2) / M_PI;
double alpha = -pow(n, 2) * r;
f = 0.0;
f[0] = coeff * exp(alpha);
}
void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
void maxwell_solution(const Vector &x, vector<complex<double>> &E)
{
// Initialize
for (int i = 0; i < dim; ++i)
@@ -641,8 +638,8 @@ void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
E[i] = 0.0;
}
constexpr complex<real_t> zi = complex<real_t>(0., 1.);
real_t k = omega * sqrt(epsilon * mu);
complex<double> zi = complex<double>(0., 1.);
double k = omega * sqrt(epsilon * mu);
switch (prob)
{
case disc:
@@ -657,58 +654,58 @@ void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
if (dim == 2)
{
real_t x0 = x(0) + shift(0);
real_t x1 = x(1) + shift(1);
real_t r = sqrt(x0 * x0 + x1 * x1);
real_t beta = k * r;
double x0 = x(0) + shift(0);
double x1 = x(1) + shift(1);
double r = sqrt(x0 * x0 + x1 * x1);
double beta = k * r;
// Bessel functions
complex<real_t> Ho, Ho_r, Ho_rr;
Ho = real_t(jn(0, beta)) + zi * real_t(yn(0, beta));
Ho_r = -k * (real_t(jn(1, beta)) + zi * real_t(yn(1, beta)));
Ho_rr = -k * k * (1_r / beta *
(real_t(jn(1, beta)) + zi * real_t(yn(1, beta))) -
(real_t(jn(2, beta)) + zi * real_t(yn(2, beta))));
complex<double> Ho, Ho_r, Ho_rr;
Ho = jn(0, beta) + zi * yn(0, beta);
Ho_r = -k * (jn(1, beta) + zi * yn(1, beta));
Ho_rr = -k * k * (1.0 / beta *
(jn(1, beta) + zi * yn(1, beta)) -
(jn(2, beta) + zi * yn(2, beta)));
// First derivatives
real_t r_x = x0 / r;
real_t r_y = x1 / r;
real_t r_xy = -(r_x / r) * r_y;
real_t r_xx = (1_r / r) * (1_r - r_x * r_x);
double r_x = x0 / r;
double r_y = x1 / r;
double r_xy = -(r_x / r) * r_y;
double r_xx = (1.0 / r) * (1.0 - r_x * r_x);
complex<real_t> val, val_xx, val_xy;
val = real_t(0.25) * zi * Ho;
val_xx = real_t(0.25) * zi * (r_xx * Ho_r + r_x * r_x * Ho_rr);
val_xy = real_t(0.25) * zi * (r_xy * Ho_r + r_x * r_y * Ho_rr);
complex<double> val, val_xx, val_xy;
val = 0.25 * zi * Ho;
val_xx = 0.25 * zi * (r_xx * Ho_r + r_x * r_x * Ho_rr);
val_xy = 0.25 * zi * (r_xy * Ho_r + r_x * r_y * Ho_rr);
E[0] = zi / k * (k * k * val + val_xx);
E[1] = zi / k * val_xy;
}
else if (dim == 3)
{
real_t x0 = x(0) + shift(0);
real_t x1 = x(1) + shift(1);
real_t x2 = x(2) + shift(2);
real_t r = sqrt(x0 * x0 + x1 * x1 + x2 * x2);
double x0 = x(0) + shift(0);
double x1 = x(1) + shift(1);
double x2 = x(2) + shift(2);
double r = sqrt(x0 * x0 + x1 * x1 + x2 * x2);
real_t r_x = x0 / r;
real_t r_y = x1 / r;
real_t r_z = x2 / r;
real_t r_xx = (1_r / r) * (1_r - r_x * r_x);
real_t r_yx = -(r_y / r) * r_x;
real_t r_zx = -(r_z / r) * r_x;
double r_x = x0 / r;
double r_y = x1 / r;
double r_z = x2 / r;
double r_xx = (1.0 / r) * (1.0 - r_x * r_x);
double r_yx = -(r_y / r) * r_x;
double r_zx = -(r_z / r) * r_x;
complex<real_t> val, val_r, val_rr;
complex<double> val, val_r, val_rr;
val = exp(zi * k * r) / r;
val_r = val / r * (zi * k * r - 1_r);
val_r = val / r * (zi * k * r - 1.0);
val_rr = val / (r * r) * (-k * k * r * r
- real_t(2) * zi * k * r + real_t(2));
- 2.0 * zi * k * r + 2.0);
complex<real_t> val_xx, val_yx, val_zx;
complex<double> val_xx, val_yx, val_zx;
val_xx = val_rr * r_x * r_x + val_r * r_xx;
val_yx = val_rr * r_x * r_y + val_r * r_yx;
val_zx = val_rr * r_x * r_z + val_r * r_zx;
complex<real_t> alpha = zi * k / real_t(4) / (real_t) M_PI / k / k;
complex<double> alpha = zi * k / 4.0 / M_PI / k / k;
E[0] = alpha * (k * k * val + val_xx);
E[1] = alpha * val_yx;
E[2] = alpha * val_zx;
@@ -720,13 +717,12 @@ void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
// T_10 mode
if (dim == 3)
{
real_t k10 = sqrt(k * k - real_t(M_PI * M_PI));
E[1] = -zi * k / (real_t) M_PI *
sin((real_t) M_PI*x(2))*exp(zi * k10 * x(0));
double k10 = sqrt(k * k - M_PI * M_PI);
E[1] = -zi * k / M_PI * sin(M_PI*x(2))*exp(zi * k10 * x(0));
}
else if (dim == 2)
{
E[1] = -zi * k / (real_t) M_PI * exp(zi * k * x(0));
E[1] = -zi * k / M_PI * exp(zi * k * x(0));
}
break;
}
@@ -737,7 +733,7 @@ void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
void E_exact_Re(const Vector &x, Vector &E)
{
vector<complex<real_t>> Eval(E.Size());
vector<complex<double>> Eval(E.Size());
maxwell_solution(x, Eval);
for (int i = 0; i < dim; ++i)
{
@@ -747,7 +743,7 @@ void E_exact_Re(const Vector &x, Vector &E)
void E_exact_Im(const Vector &x, Vector &E)
{
vector<complex<real_t>> Eval(E.Size());
vector<complex<double>> Eval(E.Size());
maxwell_solution(x, Eval);
for (int i = 0; i < dim; ++i)
{
@@ -763,8 +759,8 @@ void E_bdr_data_Re(const Vector &x, Vector &E)
for (int i = 0; i < dim; ++i)
{
// check if in PML
if (x(i) - comp_domain_bdr(i, 0) < 0_r ||
x(i) - comp_domain_bdr(i, 1) > 0_r)
if (x(i) - comp_domain_bdr(i, 0) < 0.0 ||
x(i) - comp_domain_bdr(i, 1) > 0.0)
{
in_pml = true;
break;
@@ -772,7 +768,7 @@ void E_bdr_data_Re(const Vector &x, Vector &E)
}
if (!in_pml)
{
vector<complex<real_t>> Eval(E.Size());
vector<complex<double>> Eval(E.Size());
maxwell_solution(x, Eval);
for (int i = 0; i < dim; ++i)
{
@@ -790,8 +786,8 @@ void E_bdr_data_Im(const Vector &x, Vector &E)
for (int i = 0; i < dim; ++i)
{
// check if in PML
if (x(i) - comp_domain_bdr(i, 0) < 0_r ||
x(i) - comp_domain_bdr(i, 1) > 0_r)
if (x(i) - comp_domain_bdr(i, 0) < 0.0 ||
x(i) - comp_domain_bdr(i, 1) > 0.0)
{
in_pml = true;
break;
@@ -799,7 +795,7 @@ void E_bdr_data_Im(const Vector &x, Vector &E)
}
if (!in_pml)
{
vector<complex<real_t>> Eval(E.Size());
vector<complex<double>> Eval(E.Size());
maxwell_solution(x, Eval);
for (int i = 0; i < dim; ++i)
{
@@ -810,8 +806,8 @@ void E_bdr_data_Im(const Vector &x, Vector &E)
void detJ_JT_J_inv_Re(const Vector &x, PML * pml, Vector &D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det(1.0, 0.0);
vector<complex<double>> dxs(dim);
complex<double> det(1.0, 0.0);
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -821,14 +817,14 @@ void detJ_JT_J_inv_Re(const Vector &x, PML * pml, Vector &D)
for (int i = 0; i < dim; ++i)
{
D(i) = (det / pow2(dxs[i])).real();
D(i) = (det / pow(dxs[i], 2)).real();
}
}
void detJ_JT_J_inv_Im(const Vector &x, PML * pml, Vector &D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det = 1.0;
vector<complex<double>> dxs(dim);
complex<double> det = 1.0;
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -838,14 +834,14 @@ void detJ_JT_J_inv_Im(const Vector &x, PML * pml, Vector &D)
for (int i = 0; i < dim; ++i)
{
D(i) = (det / pow2(dxs[i])).imag();
D(i) = (det / pow(dxs[i], 2)).imag();
}
}
void detJ_JT_J_inv_abs(const Vector &x, PML * pml, Vector &D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det = 1.0;
vector<complex<double>> dxs(dim);
complex<double> det = 1.0;
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -855,14 +851,14 @@ void detJ_JT_J_inv_abs(const Vector &x, PML * pml, Vector &D)
for (int i = 0; i < dim; ++i)
{
D(i) = abs(det / pow2(dxs[i]));
D(i) = abs(det / pow(dxs[i], 2));
}
}
void detJ_inv_JT_J_Re(const Vector &x, PML * pml, Vector &D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det(1.0, 0.0);
vector<complex<double>> dxs(dim);
complex<double> det(1.0, 0.0);
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -873,21 +869,21 @@ void detJ_inv_JT_J_Re(const Vector &x, PML * pml, Vector &D)
// in the 2D case the coefficient is scalar 1/det(J)
if (dim == 2)
{
D = (1_r / det).real();
D = (1.0 / det).real();
}
else
{
for (int i = 0; i < dim; ++i)
{
D(i) = (pow2(dxs[i]) / det).real();
D(i) = (pow(dxs[i], 2) / det).real();
}
}
}
void detJ_inv_JT_J_Im(const Vector &x, PML * pml, Vector &D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det = 1.0;
vector<complex<double>> dxs(dim);
complex<double> det = 1.0;
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -897,21 +893,21 @@ void detJ_inv_JT_J_Im(const Vector &x, PML * pml, Vector &D)
if (dim == 2)
{
D = (1_r / det).imag();
D = (1.0 / det).imag();
}
else
{
for (int i = 0; i < dim; ++i)
{
D(i) = (pow2(dxs[i]) / det).imag();
D(i) = (pow(dxs[i], 2) / det).imag();
}
}
}
void detJ_inv_JT_J_abs(const Vector &x, PML * pml, Vector &D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det = 1.0;
vector<complex<double>> dxs(dim);
complex<double> det = 1.0;
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -921,18 +917,18 @@ void detJ_inv_JT_J_abs(const Vector &x, PML * pml, Vector &D)
if (dim == 2)
{
D = abs(1_r / det);
D = abs(1.0 / det);
}
else
{
for (int i = 0; i < dim; ++i)
{
D(i) = abs(pow2(dxs[i]) / det);
D(i) = abs(pow(dxs[i], 2) / det);
}
}
}
PML::PML(Mesh *mesh_, Array2D<real_t> length_)
PML::PML(Mesh *mesh_, Array2D<double> length_)
: mesh(mesh_), length(length_)
{
dim = mesh->Dimension();
@@ -983,7 +979,7 @@ void PML::SetAttributes(Mesh *mesh_)
for (int iv = 0; iv < nrvert; ++iv)
{
int vert_idx = vertices[iv];
real_t *coords = mesh_->GetVertex(vert_idx);
double *coords = mesh_->GetVertex(vert_idx);
for (int comp = 0; comp < dim; ++comp)
{
if (coords[comp] > comp_dom_bdr(comp, 1) ||
@@ -1004,14 +1000,14 @@ void PML::SetAttributes(Mesh *mesh_)
}
void PML::StretchFunction(const Vector &x,
vector<complex<real_t>> &dxs)
vector<complex<double>> &dxs)
{
constexpr complex<real_t> zi = complex<real_t>(0., 1.);
complex<double> zi = complex<double>(0., 1.);
real_t n = 2.0;
real_t c = 5.0;
real_t coeff;
real_t k = omega * sqrt(epsilon * mu);
double n = 2.0;
double c = 5.0;
double coeff;
double k = omega * sqrt(epsilon * mu);
// Stretch in each direction independently
for (int i = 0; i < dim; ++i)
@@ -1020,14 +1016,14 @@ void PML::StretchFunction(const Vector &x,
if (x(i) >= comp_domain_bdr(i, 1))
{
coeff = n * c / k / pow(length(i, 1), n);
dxs[i] = 1_r + zi * coeff *
abs(pow(x(i) - comp_domain_bdr(i, 1), n - 1_r));
dxs[i] = 1.0 + zi * coeff *
abs(pow(x(i) - comp_domain_bdr(i, 1), n - 1.0));
}
if (x(i) <= comp_domain_bdr(i, 0))
{
coeff = n * c / k / pow(length(i, 0), n);
dxs[i] = 1_r + zi * coeff *
abs(pow(x(i) - comp_domain_bdr(i, 0), n - 1_r));
dxs[i] = 1.0 + zi * coeff *
abs(pow(x(i) - comp_domain_bdr(i, 0), n - 1.0));
}
}
}
+116 -121
View File
@@ -52,13 +52,13 @@ private:
int dim;
// Length of the PML Region in each direction
Array2D<real_t> length;
Array2D<double> length;
// Computational Domain Boundary
Array2D<real_t> comp_dom_bdr;
Array2D<double> comp_dom_bdr;
// Domain Boundary
Array2D<real_t> dom_bdr;
Array2D<double> dom_bdr;
// Integer Array identifying elements in the PML
// 0: in the PML, 1: not in the PML
@@ -69,13 +69,13 @@ private:
public:
// Constructor
PML(Mesh *mesh_,Array2D<real_t> length_);
PML(Mesh *mesh_,Array2D<double> length_);
// Return Computational Domain Boundary
Array2D<real_t> GetCompDomainBdr() {return comp_dom_bdr;}
Array2D<double> GetCompDomainBdr() {return comp_dom_bdr;}
// Return Domain Boundary
Array2D<real_t> GetDomainBdr() {return dom_bdr;}
Array2D<double> GetDomainBdr() {return dom_bdr;}
// Return Markers list for elements
Array<int> * GetMarkedPMLElements() {return &elems;}
@@ -84,7 +84,7 @@ public:
void SetAttributes(ParMesh *pmesh);
// PML complex stretching function
void StretchFunction(const Vector &x, vector<complex<real_t>> &dxs);
void StretchFunction(const Vector &x, vector<complex<double>> &dxs);
};
// Class for returning the PML coefficients of the bilinear form
@@ -103,9 +103,9 @@ public:
using VectorCoefficient::Eval;
virtual void Eval(Vector &K, ElementTransformation &T,
const IntegrationPoint &ip)
const IntegrationPoint &ip) const
{
real_t x[3];
double x[3];
Vector transip(x, 3);
T.Transform(ip, transip);
K.SetSize(vdim);
@@ -113,7 +113,7 @@ public:
}
};
void maxwell_solution(const Vector &x, vector<complex<real_t>> &Eval);
void maxwell_solution(const Vector &x, vector<complex<double>> &Eval);
void E_bdr_data_Re(const Vector &x, Vector &E);
void E_bdr_data_Im(const Vector &x, Vector &E);
@@ -133,17 +133,15 @@ void detJ_inv_JT_J_Re(const Vector &x, PML * pml, Vector & D);
void detJ_inv_JT_J_Im(const Vector &x, PML * pml, Vector & D);
void detJ_inv_JT_J_abs(const Vector &x, PML * pml, Vector & D);
Array2D<real_t> comp_domain_bdr;
Array2D<real_t> domain_bdr;
Array2D<double> comp_domain_bdr;
Array2D<double> domain_bdr;
real_t mu = 1.0;
real_t epsilon = 1.0;
real_t omega;
double mu = 1.0;
double epsilon = 1.0;
double omega;
int dim;
bool exact_known = false;
template <typename T> T pow2(const T &x) { return x*x; }
enum prob_type
{
beam, // Wave propagating in a beam-like domain
@@ -168,7 +166,7 @@ int main(int argc, char *argv[])
int ref_levels = 1;
int par_ref_levels = 2;
int iprob = 4;
real_t freq = 5.0;
double freq = 5.0;
bool herm_conv = true;
bool slu_solver = false;
bool mumps_solver = false;
@@ -277,10 +275,10 @@ int main(int argc, char *argv[])
dim = mesh->Dimension();
// Angular frequency
omega = real_t(2.0 * M_PI) * freq;
omega = 2.0 * M_PI * freq;
// Setup PML length
Array2D<real_t> length(dim, 2); length = 0.0;
Array2D<double> length(dim, 2); length = 0.0;
// 5. Setup the Cartesian PML region.
switch (prob)
@@ -359,15 +357,14 @@ int main(int argc, char *argv[])
switch (prob)
{
case lshape:
if (center[0] == 1_r || center[0] == 0.5_r ||
center[1] == 0.5_r)
if (center[0] == 1.0 || center[0] == 0.5 || center[1] == 0.5)
{
ess_bdr[k - 1] = 1;
}
break;
case fichera:
if (center[0] == -1_r || center[0] == 0_r ||
center[1] == 0_r || center[2] == 0_r)
if (center[0] == -1.0 || center[0] == 0.0 ||
center[1] == 0.0 || center[2] == 0.0)
{
ess_bdr[k - 1] = 1;
}
@@ -426,8 +423,8 @@ int main(int argc, char *argv[])
}
}
ConstantCoefficient muinv(1_r / mu);
ConstantCoefficient omeg(-pow2(omega) * epsilon);
ConstantCoefficient muinv(1.0/mu);
ConstantCoefficient omeg(-pow(omega, 2) * epsilon);
RestrictedCoefficient restr_muinv(muinv,attr);
RestrictedCoefficient restr_omeg(omeg,attr);
@@ -523,7 +520,7 @@ int main(int argc, char *argv[])
// + omega^2 * epsilon (abs(det(J) * (J^T J)^-1) * E, F)
if (pa || (!slu_solver && !mumps_solver && !strumpack_solver))
{
ConstantCoefficient absomeg(pow2(omega) * epsilon);
ConstantCoefficient absomeg(pow(omega, 2) * epsilon);
RestrictedCoefficient restr_absomeg(absomeg,attr);
ParBilinearForm prec(fespace);
@@ -554,7 +551,7 @@ int main(int argc, char *argv[])
std::unique_ptr<Operator> pc_r;
std::unique_ptr<Operator> pc_i;
int s = (conv == ComplexOperator::HERMITIAN) ? -1 : 1;
int s = (conv == ComplexOperator::HERMITIAN) ? -1.0 : 1.0;
if (pa)
{
// Jacobi Smoother
@@ -602,14 +599,14 @@ int main(int argc, char *argv[])
irs[i] = &(IntRules.Get(i, order_quad));
}
real_t L2Error_Re = x.real().ComputeL2Error(E_ex_Re, irs,
double L2Error_Re = x.real().ComputeL2Error(E_ex_Re, irs,
pml->GetMarkedPMLElements());
real_t L2Error_Im = x.imag().ComputeL2Error(E_ex_Im, irs,
double L2Error_Im = x.imag().ComputeL2Error(E_ex_Im, irs,
pml->GetMarkedPMLElements());
ParComplexGridFunction x_gf0(fespace);
x_gf0 = 0.0;
real_t norm_E_Re, norm_E_Im;
double norm_E_Re, norm_E_Im;
norm_E_Re = x_gf0.real().ComputeL2Error(E_ex_Re, irs,
pml->GetMarkedPMLElements());
norm_E_Im = x_gf0.imag().ComputeL2Error(E_ex_Im, irs,
@@ -697,12 +694,11 @@ int main(int argc, char *argv[])
int i = 0;
while (sol_sock)
{
real_t t = (real_t)(i % num_frames) / num_frames;
double t = (double)(i % num_frames) / num_frames;
ostringstream oss;
oss << "Harmonic Solution (t = " << t << " T)";
add(cos(real_t(2.0*M_PI)*t), x.real(),
sin(real_t(2.0*M_PI)*t), x.imag(), x_t);
add(cos(2.0*M_PI*t), x.real(), sin(2.0*M_PI*t), x.imag(), x_t);
sol_sock << "parallel " << num_procs << " " << myid << "\n";
sol_sock << "solution\n" << *pmesh << x_t
<< "window_title '" << oss.str() << "'" << flush;
@@ -722,20 +718,20 @@ int main(int argc, char *argv[])
void source(const Vector &x, Vector &f)
{
Vector center(dim);
real_t r = 0.0;
double r = 0.0;
for (int i = 0; i < dim; ++i)
{
center(i) = real_t(0.5) * (comp_domain_bdr(i, 0) + comp_domain_bdr(i, 1));
r += pow2(x[i] - center[i]);
center(i) = 0.5 * (comp_domain_bdr(i, 0) + comp_domain_bdr(i, 1));
r += pow(x[i] - center[i], 2.);
}
real_t n = real_t(5) * omega * sqrt(epsilon * mu) / real_t(M_PI);
real_t coeff = pow2(n) / real_t(M_PI);
real_t alpha = -pow2(n) * r;
double n = 5.0 * omega * sqrt(epsilon * mu) / M_PI;
double coeff = pow(n, 2) / M_PI;
double alpha = -pow(n, 2) * r;
f = 0.0;
f[0] = coeff * exp(alpha);
}
void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
void maxwell_solution(const Vector &x, vector<complex<double>> &E)
{
// Initialize
for (int i = 0; i < dim; ++i)
@@ -743,8 +739,8 @@ void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
E[i] = 0.0;
}
constexpr complex<real_t> zi = complex<real_t>(0., 1.);
real_t k = omega * sqrt(epsilon * mu);
complex<double> zi = complex<double>(0., 1.);
double k = omega * sqrt(epsilon * mu);
switch (prob)
{
case disc:
@@ -759,58 +755,58 @@ void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
if (dim == 2)
{
real_t x0 = x(0) + shift(0);
real_t x1 = x(1) + shift(1);
real_t r = sqrt(x0 * x0 + x1 * x1);
real_t beta = k * r;
double x0 = x(0) + shift(0);
double x1 = x(1) + shift(1);
double r = sqrt(x0 * x0 + x1 * x1);
double beta = k * r;
// Bessel functions
complex<real_t> Ho, Ho_r, Ho_rr;
Ho = real_t(jn(0, beta)) + zi * real_t(yn(0, beta));
Ho_r = -k * (real_t(jn(1, beta)) + zi * real_t(yn(1, beta)));
Ho_rr = -k * k * (1_r / beta *
(real_t(jn(1, beta)) + zi * real_t(yn(1, beta))) -
(real_t(jn(2, beta)) + zi * real_t(yn(2, beta))));
complex<double> Ho, Ho_r, Ho_rr;
Ho = jn(0, beta) + zi * yn(0, beta);
Ho_r = -k * (jn(1, beta) + zi * yn(1, beta));
Ho_rr = -k * k * (1.0 / beta *
(jn(1, beta) + zi * yn(1, beta)) -
(jn(2, beta) + zi * yn(2, beta)));
// First derivatives
real_t r_x = x0 / r;
real_t r_y = x1 / r;
real_t r_xy = -(r_x / r) * r_y;
real_t r_xx = (1_r / r) * (1_r - r_x * r_x);
double r_x = x0 / r;
double r_y = x1 / r;
double r_xy = -(r_x / r) * r_y;
double r_xx = (1.0 / r) * (1.0 - r_x * r_x);
complex<real_t> val, val_xx, val_xy;
val = real_t(0.25) * zi * Ho;
val_xx = real_t(0.25) * zi * (r_xx * Ho_r + r_x * r_x * Ho_rr);
val_xy = real_t(0.25) * zi * (r_xy * Ho_r + r_x * r_y * Ho_rr);
complex<double> val, val_xx, val_xy;
val = 0.25 * zi * Ho;
val_xx = 0.25 * zi * (r_xx * Ho_r + r_x * r_x * Ho_rr);
val_xy = 0.25 * zi * (r_xy * Ho_r + r_x * r_y * Ho_rr);
E[0] = zi / k * (k * k * val + val_xx);
E[1] = zi / k * val_xy;
}
else if (dim == 3)
{
real_t x0 = x(0) + shift(0);
real_t x1 = x(1) + shift(1);
real_t x2 = x(2) + shift(2);
real_t r = sqrt(x0 * x0 + x1 * x1 + x2 * x2);
double x0 = x(0) + shift(0);
double x1 = x(1) + shift(1);
double x2 = x(2) + shift(2);
double r = sqrt(x0 * x0 + x1 * x1 + x2 * x2);
real_t r_x = x0 / r;
real_t r_y = x1 / r;
real_t r_z = x2 / r;
real_t r_xx = (1_r / r) * (1_r - r_x * r_x);
real_t r_yx = -(r_y / r) * r_x;
real_t r_zx = -(r_z / r) * r_x;
double r_x = x0 / r;
double r_y = x1 / r;
double r_z = x2 / r;
double r_xx = (1.0 / r) * (1.0 - r_x * r_x);
double r_yx = -(r_y / r) * r_x;
double r_zx = -(r_z / r) * r_x;
complex<real_t> val, val_r, val_rr;
complex<double> val, val_r, val_rr;
val = exp(zi * k * r) / r;
val_r = val / r * (zi * k * r - 1_r);
val_r = val / r * (zi * k * r - 1.0);
val_rr = val / (r * r) * (-k * k * r * r
- real_t(2) * zi * k * r + real_t(2));
- 2.0 * zi * k * r + 2.0);
complex<real_t> val_xx, val_yx, val_zx;
complex<double> val_xx, val_yx, val_zx;
val_xx = val_rr * r_x * r_x + val_r * r_xx;
val_yx = val_rr * r_x * r_y + val_r * r_yx;
val_zx = val_rr * r_x * r_z + val_r * r_zx;
complex<real_t> alpha = zi * k / real_t(4) / (real_t) M_PI / k / k;
complex<double> alpha = zi * k / 4.0 / M_PI / k / k;
E[0] = alpha * (k * k * val + val_xx);
E[1] = alpha * val_yx;
E[2] = alpha * val_zx;
@@ -822,13 +818,12 @@ void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
// T_10 mode
if (dim == 3)
{
real_t k10 = sqrt(k * k - real_t(M_PI * M_PI));
E[1] = -zi * k / (real_t) M_PI *
sin((real_t) M_PI*x(2))*exp(zi * k10 * x(0));
double k10 = sqrt(k * k - M_PI * M_PI);
E[1] = -zi * k / M_PI * sin(M_PI*x(2))*exp(zi * k10 * x(0));
}
else if (dim == 2)
{
E[1] = -zi * k / (real_t) M_PI * exp(zi * k * x(0));
E[1] = -zi * k / M_PI * exp(zi * k * x(0));
}
break;
}
@@ -839,7 +834,7 @@ void maxwell_solution(const Vector &x, vector<complex<real_t>> &E)
void E_exact_Re(const Vector &x, Vector &E)
{
vector<complex<real_t>> Eval(E.Size());
vector<complex<double>> Eval(E.Size());
maxwell_solution(x, Eval);
for (int i = 0; i < dim; ++i)
{
@@ -849,7 +844,7 @@ void E_exact_Re(const Vector &x, Vector &E)
void E_exact_Im(const Vector &x, Vector &E)
{
vector<complex<real_t>> Eval(E.Size());
vector<complex<double>> Eval(E.Size());
maxwell_solution(x, Eval);
for (int i = 0; i < dim; ++i)
{
@@ -865,8 +860,8 @@ void E_bdr_data_Re(const Vector &x, Vector &E)
for (int i = 0; i < dim; ++i)
{
// check if in PML
if (x(i) - comp_domain_bdr(i, 0) < 0_r ||
x(i) - comp_domain_bdr(i, 1) > 0_r)
if (x(i) - comp_domain_bdr(i, 0) < 0.0 ||
x(i) - comp_domain_bdr(i, 1) > 0.0)
{
in_pml = true;
break;
@@ -874,7 +869,7 @@ void E_bdr_data_Re(const Vector &x, Vector &E)
}
if (!in_pml)
{
vector<complex<real_t>> Eval(E.Size());
vector<complex<double>> Eval(E.Size());
maxwell_solution(x, Eval);
for (int i = 0; i < dim; ++i)
{
@@ -892,8 +887,8 @@ void E_bdr_data_Im(const Vector &x, Vector &E)
for (int i = 0; i < dim; ++i)
{
// check if in PML
if (x(i) - comp_domain_bdr(i, 0) < 0_r ||
x(i) - comp_domain_bdr(i, 1) > 0_r)
if (x(i) - comp_domain_bdr(i, 0) < 0.0 ||
x(i) - comp_domain_bdr(i, 1) > 0.0)
{
in_pml = true;
break;
@@ -901,7 +896,7 @@ void E_bdr_data_Im(const Vector &x, Vector &E)
}
if (!in_pml)
{
vector<complex<real_t>> Eval(E.Size());
vector<complex<double>> Eval(E.Size());
maxwell_solution(x, Eval);
for (int i = 0; i < dim; ++i)
{
@@ -912,8 +907,8 @@ void E_bdr_data_Im(const Vector &x, Vector &E)
void detJ_JT_J_inv_Re(const Vector &x, PML * pml, Vector & D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det(1.0, 0.0);
vector<complex<double>> dxs(dim);
complex<double> det(1.0, 0.0);
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -923,14 +918,14 @@ void detJ_JT_J_inv_Re(const Vector &x, PML * pml, Vector & D)
for (int i = 0; i < dim; ++i)
{
D(i) = (det / pow2(dxs[i])).real();
D(i) = (det / pow(dxs[i], 2)).real();
}
}
void detJ_JT_J_inv_Im(const Vector &x, PML * pml, Vector & D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det = 1.0;
vector<complex<double>> dxs(dim);
complex<double> det = 1.0;
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -940,14 +935,14 @@ void detJ_JT_J_inv_Im(const Vector &x, PML * pml, Vector & D)
for (int i = 0; i < dim; ++i)
{
D(i) = (det / pow2(dxs[i])).imag();
D(i) = (det / pow(dxs[i], 2)).imag();
}
}
void detJ_JT_J_inv_abs(const Vector &x, PML * pml, Vector & D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det = 1.0;
vector<complex<double>> dxs(dim);
complex<double> det = 1.0;
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -957,14 +952,14 @@ void detJ_JT_J_inv_abs(const Vector &x, PML * pml, Vector & D)
for (int i = 0; i < dim; ++i)
{
D(i) = abs(det / pow2(dxs[i]));
D(i) = abs(det / pow(dxs[i], 2));
}
}
void detJ_inv_JT_J_Re(const Vector &x, PML * pml, Vector & D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det(1.0, 0.0);
vector<complex<double>> dxs(dim);
complex<double> det(1.0, 0.0);
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -975,21 +970,21 @@ void detJ_inv_JT_J_Re(const Vector &x, PML * pml, Vector & D)
// in the 2D case the coefficient is scalar 1/det(J)
if (dim == 2)
{
D = (1_r / det).real();
D = (1.0 / det).real();
}
else
{
for (int i = 0; i < dim; ++i)
{
D(i) = (pow2(dxs[i]) / det).real();
D(i) = (pow(dxs[i], 2) / det).real();
}
}
}
void detJ_inv_JT_J_Im(const Vector &x, PML * pml, Vector & D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det = 1.0;
vector<complex<double>> dxs(dim);
complex<double> det = 1.0;
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -999,21 +994,21 @@ void detJ_inv_JT_J_Im(const Vector &x, PML * pml, Vector & D)
if (dim == 2)
{
D = (1_r / det).imag();
D = (1.0 / det).imag();
}
else
{
for (int i = 0; i < dim; ++i)
{
D(i) = (pow2(dxs[i]) / det).imag();
D(i) = (pow(dxs[i], 2) / det).imag();
}
}
}
void detJ_inv_JT_J_abs(const Vector &x, PML * pml, Vector & D)
{
vector<complex<real_t>> dxs(dim);
complex<real_t> det = 1.0;
vector<complex<double>> dxs(dim);
complex<double> det = 1.0;
pml->StretchFunction(x, dxs);
for (int i = 0; i < dim; ++i)
@@ -1023,18 +1018,18 @@ void detJ_inv_JT_J_abs(const Vector &x, PML * pml, Vector & D)
if (dim == 2)
{
D = abs(1_r / det);
D = abs(1.0 / det);
}
else
{
for (int i = 0; i < dim; ++i)
{
D(i) = abs(pow2(dxs[i]) / det);
D(i) = abs(pow(dxs[i], 2) / det);
}
}
}
PML::PML(Mesh *mesh_, Array2D<real_t> length_)
PML::PML(Mesh *mesh_, Array2D<double> length_)
: mesh(mesh_), length(length_)
{
dim = mesh->Dimension();
@@ -1086,7 +1081,7 @@ void PML::SetAttributes(ParMesh *pmesh)
for (int iv = 0; iv < nrvert; ++iv)
{
int vert_idx = vertices[iv];
real_t *coords = pmesh->GetVertex(vert_idx);
double *coords = pmesh->GetVertex(vert_idx);
for (int comp = 0; comp < dim; ++comp)
{
if (coords[comp] > comp_dom_bdr(comp, 1) ||
@@ -1107,14 +1102,14 @@ void PML::SetAttributes(ParMesh *pmesh)
}
void PML::StretchFunction(const Vector &x,
vector<complex<real_t>> &dxs)
vector<complex<double>> &dxs)
{
constexpr complex<real_t> zi = complex<real_t>(0., 1.);
complex<double> zi = complex<double>(0., 1.);
real_t n = 2.0;
real_t c = 5.0;
real_t coeff;
real_t k = omega * sqrt(epsilon * mu);
double n = 2.0;
double c = 5.0;
double coeff;
double k = omega * sqrt(epsilon * mu);
// Stretch in each direction independently
for (int i = 0; i < dim; ++i)
@@ -1123,14 +1118,14 @@ void PML::StretchFunction(const Vector &x,
if (x(i) >= comp_domain_bdr(i, 1))
{
coeff = n * c / k / pow(length(i, 1), n);
dxs[i] = 1_r + zi * coeff *
abs(pow(x(i) - comp_domain_bdr(i, 1), n - 1_r));
dxs[i] = 1.0 + zi * coeff *
abs(pow(x(i) - comp_domain_bdr(i, 1), n - 1.0));
}
if (x(i) <= comp_domain_bdr(i, 0))
{
coeff = n * c / k / pow(length(i, 0), n);
dxs[i] = 1_r + zi * coeff *
abs(pow(x(i) - comp_domain_bdr(i, 0), n - 1_r));
dxs[i] = 1.0 + zi * coeff *
abs(pow(x(i) - comp_domain_bdr(i, 0), n - 1.0));
}
}
}
+32 -32
View File
@@ -63,7 +63,7 @@
using namespace std;
using namespace mfem;
static real_t a_ = 0.2;
static double a_ = 0.2;
// Normal to hole with boundary attribute 4
void n4Vec(const Vector &x, Vector &n) { n = x; n[0] -= 0.5; n /= -n.Norml2(); }
@@ -73,25 +73,25 @@ Mesh * GenerateSerialMesh(int ref);
// Compute the average value of alpha*n.Grad(sol) + beta*sol over the boundary
// attributes marked in bdr_marker. Also computes the L2 norm of
// alpha*n.Grad(sol) + beta*sol - gamma over the same boundary.
real_t IntegrateBC(const GridFunction &sol, const Array<int> &bdr_marker,
real_t alpha, real_t beta, real_t gamma,
real_t &error);
double IntegrateBC(const GridFunction &sol, const Array<int> &bdr_marker,
double alpha, double beta, double gamma,
double &error);
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
int ser_ref_levels = 2;
int order = 1;
real_t sigma = -1.0;
real_t kappa = -1.0;
double sigma = -1.0;
double kappa = -1.0;
bool h1 = true;
bool visualization = true;
real_t mat_val = 1.0;
real_t dbc_val = 0.0;
real_t nbc_val = 1.0;
real_t rbc_a_val = 1.0; // du/dn + a * u = b
real_t rbc_b_val = 1.0;
double mat_val = 1.0;
double dbc_val = 0.0;
double nbc_val = 1.0;
double rbc_a_val = 1.0; // du/dn + a * u = b
double rbc_b_val = 1.0;
OptionsParser args(argc, argv);
args.AddOption(&h1, "-h1", "--continuous", "-dg", "--discontinuous",
@@ -302,7 +302,7 @@ int main(int argc, char *argv[])
{
// Integrate the solution on the Dirichlet boundary and compare to the
// expected value.
real_t error, avg = IntegrateBC(u, dbc_bdr, 0.0, 1.0, dbc_val, error);
double error, avg = IntegrateBC(u, dbc_bdr, 0.0, 1.0, dbc_val, error);
bool hom_dbc = (dbc_val == 0.0);
error /= hom_dbc ? 1.0 : fabs(dbc_val);
@@ -314,7 +314,7 @@ int main(int argc, char *argv[])
{
// Integrate n.Grad(u) on the inhomogeneous Neumann boundary and compare
// to the expected value.
real_t error, avg = IntegrateBC(u, nbc_bdr, 1.0, 0.0, nbc_val, error);
double error, avg = IntegrateBC(u, nbc_bdr, 1.0, 0.0, nbc_val, error);
bool hom_nbc = (nbc_val == 0.0);
error /= hom_nbc ? 1.0 : fabs(nbc_val);
@@ -330,7 +330,7 @@ int main(int argc, char *argv[])
nbc0_bdr = 0;
nbc0_bdr[3] = 1;
real_t error, avg = IntegrateBC(u, nbc0_bdr, 1.0, 0.0, 0.0, error);
double error, avg = IntegrateBC(u, nbc0_bdr, 1.0, 0.0, 0.0, error);
bool hom_nbc = true;
mfem::out << "Average of n.Grad(u) on Gamma_nbc0:\t"
@@ -341,8 +341,8 @@ int main(int argc, char *argv[])
{
// Integrate n.Grad(u) + a * u on the Robin boundary and compare to the
// expected value.
real_t error;
real_t avg = IntegrateBC(u, rbc_bdr, 1.0, rbc_a_val, rbc_b_val, error);
double error;
double avg = IntegrateBC(u, rbc_bdr, 1.0, rbc_a_val, rbc_b_val, error);
bool hom_rbc = (rbc_b_val == 0.0);
error /= hom_rbc ? 1.0 : fabs(rbc_b_val);
@@ -383,22 +383,22 @@ int main(int argc, char *argv[])
return 0;
}
void quad_trans(real_t u, real_t v, real_t &x, real_t &y, bool log = false)
void quad_trans(double u, double v, double &x, double &y, bool log = false)
{
real_t a = a_; // Radius of disc
double a = a_; // Radius of disc
real_t d = 4.0 * a * (M_SQRT2 - 2.0 * a) * (1.0 - 2.0 * v);
double d = 4.0 * a * (M_SQRT2 - 2.0 * a) * (1.0 - 2.0 * v);
real_t v0 = (1.0 + M_SQRT2) * (M_SQRT2 * a - 2.0 * v) *
double v0 = (1.0 + M_SQRT2) * (M_SQRT2 * a - 2.0 * v) *
((4.0 - 3 * M_SQRT2) * a +
(8.0 * (M_SQRT2 - 1.0) * a - 2.0) * v) / d;
real_t r = 2.0 * ((M_SQRT2 - 1.0) * a * a * (1.0 - 4.0 *v) +
double r = 2.0 * ((M_SQRT2 - 1.0) * a * a * (1.0 - 4.0 *v) +
2.0 * (1.0 + M_SQRT2 *
(1.0 + 2.0 * (2.0 * a - M_SQRT2 - 1.0) * a)) * v * v
) / d;
real_t t = asin(v / r) * u / v;
double t = asin(v / r) * u / v;
if (log)
{
mfem::out << "u, v, r, v0, t "
@@ -411,7 +411,7 @@ void quad_trans(real_t u, real_t v, real_t &x, real_t &y, bool log = false)
void trans(const Vector &u, Vector &x)
{
real_t tol = 1e-4;
double tol = 1e-4;
if (u[1] > 0.5 - tol || u[1] < -0.5 + tol)
{
@@ -542,8 +542,8 @@ Mesh * GenerateSerialMesh(int ref)
vi[0] = o + 3; vi[1] = o + 4; mesh->AddBdrSegment(vi, 3 + i);
}
real_t d[2];
real_t a = a_ / M_SQRT2;
double d[2];
double a = a_ / M_SQRT2;
d[0] = -1.0; d[1] = -0.5; mesh->AddVertex(d);
d[0] = -1.0; d[1] = 0.0; mesh->AddVertex(d);
@@ -636,12 +636,12 @@ Mesh * GenerateSerialMesh(int ref)
return mesh;
}
real_t IntegrateBC(const GridFunction &x, const Array<int> &bdr,
real_t alpha, real_t beta, real_t gamma,
real_t &error)
double IntegrateBC(const GridFunction &x, const Array<int> &bdr,
double alpha, double beta, double gamma,
double &error)
{
real_t nrm = 0.0;
real_t avg = 0.0;
double nrm = 0.0;
double avg = 0.0;
error = 0.0;
const bool a_is_zero = alpha == 0.0;
@@ -683,8 +683,8 @@ real_t IntegrateBC(const GridFunction &x, const Array<int> &bdr,
IntegrationPoint eip;
FTr->Loc1.Transform(ip, eip);
FTr->Face->SetIntPoint(&ip);
real_t face_weight = FTr->Face->Weight();
real_t val = 0.0;
double face_weight = FTr->Face->Weight();
double val = 0.0;
if (!a_is_zero)
{
FTr->Elem1->SetIntPoint(&eip);
+37 -38
View File
@@ -63,7 +63,7 @@
using namespace std;
using namespace mfem;
static real_t a_ = 0.2;
static double a_ = 0.2;
// Normal to hole with boundary attribute 4
void n4Vec(const Vector &x, Vector &n) { n = x; n[0] -= 0.5; n /= -n.Norml2(); }
@@ -73,9 +73,9 @@ Mesh * GenerateSerialMesh(int ref);
// Compute the average value of alpha*n.Grad(sol) + beta*sol over the boundary
// attributes marked in bdr_marker. Also computes the L2 norm of
// alpha*n.Grad(sol) + beta*sol - gamma over the same boundary.
real_t IntegrateBC(const ParGridFunction &sol, const Array<int> &bdr_marker,
real_t alpha, real_t beta, real_t gamma,
real_t &error);
double IntegrateBC(const ParGridFunction &sol, const Array<int> &bdr_marker,
double alpha, double beta, double gamma,
double &error);
int main(int argc, char *argv[])
{
@@ -88,16 +88,16 @@ int main(int argc, char *argv[])
int ser_ref_levels = 2;
int par_ref_levels = 1;
int order = 1;
real_t sigma = -1.0;
real_t kappa = -1.0;
double sigma = -1.0;
double kappa = -1.0;
bool h1 = true;
bool visualization = true;
real_t mat_val = 1.0;
real_t dbc_val = 0.0;
real_t nbc_val = 1.0;
real_t rbc_a_val = 1.0; // du/dn + a * u = b
real_t rbc_b_val = 1.0;
double mat_val = 1.0;
double dbc_val = 0.0;
double nbc_val = 1.0;
double rbc_a_val = 1.0; // du/dn + a * u = b
double rbc_b_val = 1.0;
OptionsParser args(argc, argv);
args.AddOption(&h1, "-h1", "--continuous", "-dg", "--discontinuous",
@@ -322,7 +322,7 @@ int main(int argc, char *argv[])
{
// Integrate the solution on the Dirichlet boundary and compare to the
// expected value.
real_t error, avg = IntegrateBC(u, dbc_bdr, 0.0, 1.0, dbc_val, error);
double error, avg = IntegrateBC(u, dbc_bdr, 0.0, 1.0, dbc_val, error);
bool hom_dbc = (dbc_val == 0.0);
error /= hom_dbc ? 1.0 : fabs(dbc_val);
@@ -334,7 +334,7 @@ int main(int argc, char *argv[])
{
// Integrate n.Grad(u) on the inhomogeneous Neumann boundary and compare
// to the expected value.
real_t error, avg = IntegrateBC(u, nbc_bdr, 1.0, 0.0, nbc_val, error);
double error, avg = IntegrateBC(u, nbc_bdr, 1.0, 0.0, nbc_val, error);
bool hom_nbc = (nbc_val == 0.0);
error /= hom_nbc ? 1.0 : fabs(nbc_val);
@@ -350,7 +350,7 @@ int main(int argc, char *argv[])
nbc0_bdr = 0;
nbc0_bdr[3] = 1;
real_t error, avg = IntegrateBC(u, nbc0_bdr, 1.0, 0.0, 0.0, error);
double error, avg = IntegrateBC(u, nbc0_bdr, 1.0, 0.0, 0.0, error);
bool hom_nbc = true;
mfem::out << "Average of n.Grad(u) on Gamma_nbc0:\t"
@@ -361,7 +361,7 @@ int main(int argc, char *argv[])
{
// Integrate n.Grad(u) + a * u on the Robin boundary and compare to the
// expected value.
real_t error, avg = IntegrateBC(u, rbc_bdr, 1.0, rbc_a_val, rbc_b_val,
double error, avg = IntegrateBC(u, rbc_bdr, 1.0, rbc_a_val, rbc_b_val,
error);
bool hom_rbc = (rbc_b_val == 0.0);
@@ -409,22 +409,22 @@ int main(int argc, char *argv[])
return 0;
}
void quad_trans(real_t u, real_t v, real_t &x, real_t &y, bool log = false)
void quad_trans(double u, double v, double &x, double &y, bool log = false)
{
real_t a = a_; // Radius of disc
double a = a_; // Radius of disc
real_t d = 4.0 * a * (M_SQRT2 - 2.0 * a) * (1.0 - 2.0 * v);
double d = 4.0 * a * (M_SQRT2 - 2.0 * a) * (1.0 - 2.0 * v);
real_t v0 = (1.0 + M_SQRT2) * (M_SQRT2 * a - 2.0 * v) *
double v0 = (1.0 + M_SQRT2) * (M_SQRT2 * a - 2.0 * v) *
((4.0 - 3 * M_SQRT2) * a +
(8.0 * (M_SQRT2 - 1.0) * a - 2.0) * v) / d;
real_t r = 2.0 * ((M_SQRT2 - 1.0) * a * a * (1.0 - 4.0 *v) +
double r = 2.0 * ((M_SQRT2 - 1.0) * a * a * (1.0 - 4.0 *v) +
2.0 * (1.0 + M_SQRT2 *
(1.0 + 2.0 * (2.0 * a - M_SQRT2 - 1.0) * a)) * v * v
) / d;
real_t t = asin(v / r) * u / v;
double t = asin(v / r) * u / v;
if (log)
{
mfem::out << "u, v, r, v0, t "
@@ -437,7 +437,7 @@ void quad_trans(real_t u, real_t v, real_t &x, real_t &y, bool log = false)
void trans(const Vector &u, Vector &x)
{
real_t tol = 1e-4;
double tol = 1e-4;
if (u[1] > 0.5 - tol || u[1] < -0.5 + tol)
{
@@ -568,8 +568,8 @@ Mesh * GenerateSerialMesh(int ref)
vi[0] = o + 3; vi[1] = o + 4; mesh->AddBdrSegment(vi, 3 + i);
}
real_t d[2];
real_t a = a_ / M_SQRT2;
double d[2];
double a = a_ / M_SQRT2;
d[0] = -1.0; d[1] = -0.5; mesh->AddVertex(d);
d[0] = -1.0; d[1] = 0.0; mesh->AddVertex(d);
@@ -662,14 +662,14 @@ Mesh * GenerateSerialMesh(int ref)
return mesh;
}
real_t IntegrateBC(const ParGridFunction &x, const Array<int> &bdr,
real_t alpha, real_t beta, real_t gamma,
real_t &glb_err)
double IntegrateBC(const ParGridFunction &x, const Array<int> &bdr,
double alpha, double beta, double gamma,
double &glb_err)
{
real_t loc_vals[3];
real_t &nrm = loc_vals[0];
real_t &avg = loc_vals[1];
real_t &error = loc_vals[2];
double loc_vals[3];
double &nrm = loc_vals[0];
double &avg = loc_vals[1];
double &error = loc_vals[2];
nrm = 0.0;
avg = 0.0;
@@ -714,8 +714,8 @@ real_t IntegrateBC(const ParGridFunction &x, const Array<int> &bdr,
IntegrationPoint eip;
FTr->Loc1.Transform(ip, eip);
FTr->Face->SetIntPoint(&ip);
real_t face_weight = FTr->Face->Weight();
real_t val = 0.0;
double face_weight = FTr->Face->Weight();
double val = 0.0;
if (!a_is_zero)
{
FTr->Elem1->SetIntPoint(&eip);
@@ -741,12 +741,11 @@ real_t IntegrateBC(const ParGridFunction &x, const Array<int> &bdr,
}
}
real_t glb_vals[3];
MPI_Allreduce(loc_vals, glb_vals, 3, MPITypeMap<real_t>::mpi_type,
MPI_SUM, fes.GetComm());
double glb_vals[3];
MPI_Allreduce(loc_vals, glb_vals, 3, MPI_DOUBLE, MPI_SUM, fes.GetComm());
real_t glb_nrm = glb_vals[0];
real_t glb_avg = glb_vals[1];
double glb_nrm = glb_vals[0];
double glb_avg = glb_vals[1];
glb_err = glb_vals[2];
// Normalize by the length of the boundary
+3 -3
View File
@@ -35,7 +35,7 @@ using namespace mfem;
// Return a mesh with a single element with vertices (0, 0), (1, 0), (1, 1),
// (offset, 1) to demonstrate boundary conditions on a surface that is not
// axis-aligned.
Mesh * build_trapezoid_mesh(real_t offset)
Mesh * build_trapezoid_mesh(double offset)
{
MFEM_VERIFY(offset < 0.9, "offset is too large!");
@@ -45,7 +45,7 @@ Mesh * build_trapezoid_mesh(real_t offset)
Mesh * mesh = new Mesh(dimension, nvt, 1, nbe);
// vertices
real_t vc[dimension];
double vc[dimension];
vc[0] = 0.0; vc[1] = 0.0;
mesh->AddVertex(vc);
vc[0] = 1.0; vc[1] = 0.0;
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
// 1. Parse command-line options.
int order = 1;
bool visualization = 1;
real_t offset = 0.3;
double offset = 0.3;
bool visit = false;
OptionsParser args(argc, argv);
+5 -5
View File
@@ -38,7 +38,7 @@ using namespace mfem;
// Return a mesh with a single element with vertices (0, 0), (1, 0), (1, 1),
// (offset, 1) to demonstrate boundary conditions on a surface that is not
// axis-aligned.
Mesh * build_trapezoid_mesh(real_t offset)
Mesh * build_trapezoid_mesh(double offset)
{
MFEM_VERIFY(offset < 0.9, "offset is too large!");
@@ -48,7 +48,7 @@ Mesh * build_trapezoid_mesh(real_t offset)
Mesh * mesh = new Mesh(dimension, nvt, 1, nbe);
// vertices
real_t vc[dimension];
double vc[dimension];
vc[0] = 0.0; vc[1] = 0.0;
mesh->AddVertex(vc);
vc[0] = 1.0; vc[1] = 0.0;
@@ -84,7 +84,7 @@ int main(int argc, char *argv[])
#ifdef HYPRE_USING_GPU
cout << "\nAs of mfem-4.3 and hypre-2.22.0 (July 2021) this example\n"
<< "is NOT supported with the GPU version of hypre.\n\n";
return MFEM_SKIP_RETURN_VALUE;
return 242;
#endif
// 1. Initialize MPI and HYPRE.
@@ -97,9 +97,9 @@ int main(int argc, char *argv[])
int order = 1;
bool visualization = 1;
bool reorder_space = false;
real_t offset = 0.3;
double offset = 0.3;
bool visit = false;
real_t penalty = 0.0;
double penalty = 0.0;
OptionsParser args(argc, argv);
args.AddOption(&order, "-o", "--order",
+6 -6
View File
@@ -34,7 +34,7 @@ void trans(const Vector &x, Vector &r);
void sigmaFunc(const Vector &x, DenseMatrix &s);
real_t uExact(const Vector &x)
double uExact(const Vector &x)
{
return (0.25 * (2.0 + x[0]) - x[2]) * (x[2] + 0.25 * (2.0 + x[0]));
}
@@ -167,7 +167,7 @@ int main(int argc, char *argv[])
// 13. Compute error in the solution and its flux
FunctionCoefficient uCoef(uExact);
real_t error = x.ComputeL2Error(uCoef);
double error = x.ComputeL2Error(uCoef);
cout << "|u - u_h|_2 = " << error << endl;
@@ -176,7 +176,7 @@ int main(int argc, char *argv[])
x.ComputeFlux(*integ, flux); flux *= -1.0;
VectorFunctionCoefficient fluxCoef(3, fluxExact);
real_t flux_err = flux.ComputeL2Error(fluxCoef);
double flux_err = flux.ComputeL2Error(fluxCoef);
cout << "|f - f_h|_2 = " << flux_err << endl;
@@ -304,8 +304,8 @@ void trans(const Vector &x, Vector &r)
{
r.SetSize(3);
real_t tol = 1e-6;
real_t theta = 0.0;
double tol = 1e-6;
double theta = 0.0;
if (fabs(x[1] + 1.0) < tol)
{
theta = 0.25 * M_PI * (x[0] - 2.0);
@@ -337,7 +337,7 @@ void trans(const Vector &x, Vector &r)
void sigmaFunc(const Vector &x, DenseMatrix &s)
{
s.SetSize(3);
real_t a = 17.0 - 2.0 * x[0] * (1.0 + x[0]);
double a = 17.0 - 2.0 * x[0] * (1.0 + x[0]);
s(0,0) = 0.5 + x[0] * x[0] * (8.0 / a - 0.5);
s(0,1) = x[0] * x[1] * (8.0 / a - 0.5);
s(0,2) = 0.0;
+6 -6
View File
@@ -34,7 +34,7 @@ void trans(const Vector &x, Vector &r);
void sigmaFunc(const Vector &x, DenseMatrix &s);
real_t uExact(const Vector &x)
double uExact(const Vector &x)
{
return (0.25 * (2.0 + x[0]) - x[2]) * (x[2] + 0.25 * (2.0 + x[0]));
}
@@ -201,7 +201,7 @@ int main(int argc, char *argv[])
// 15. Compute error in the solution and its flux
FunctionCoefficient uCoef(uExact);
real_t error = x.ComputeL2Error(uCoef);
double error = x.ComputeL2Error(uCoef);
if (myid == 0) { cout << "|u - u_h|_2 = " << error << endl; }
@@ -210,7 +210,7 @@ int main(int argc, char *argv[])
x.ComputeFlux(*integ, flux); flux *= -1.0;
VectorFunctionCoefficient fluxCoef(3, fluxExact);
real_t flux_err = flux.ComputeL2Error(fluxCoef);
double flux_err = flux.ComputeL2Error(fluxCoef);
if (myid == 0) { cout << "|f - f_h|_2 = " << flux_err << endl; }
@@ -349,8 +349,8 @@ void trans(const Vector &x, Vector &r)
{
r.SetSize(3);
real_t tol = 1e-6;
real_t theta = 0.0;
double tol = 1e-6;
double theta = 0.0;
if (fabs(x[1] + 1.0) < tol)
{
theta = 0.25 * M_PI * (x[0] - 2.0);
@@ -382,7 +382,7 @@ void trans(const Vector &x, Vector &r)
void sigmaFunc(const Vector &x, DenseMatrix &s)
{
s.SetSize(3);
real_t a = 17.0 - 2.0 * x[0] * (1.0 + x[0]);
double a = 17.0 - 2.0 * x[0] * (1.0 + x[0]);
s(0,0) = 0.5 + x[0] * x[0] * (8.0 / a - 0.5);
s(0,1) = x[0] * x[1] * (8.0 / a - 0.5);
s(0,2) = 0.0;
+1 -1
View File
@@ -53,7 +53,7 @@ using namespace mfem;
// Exact solution, E, and r.h.s., f. See below for implementation.
void E_exact(const Vector &, Vector &);
void f_exact(const Vector &, Vector &);
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int dim;
int main(int argc, char *argv[])
+14 -14
View File
@@ -42,9 +42,9 @@ using namespace std;
using namespace mfem;
// Piecewise-affine function which is sometimes mesh-conforming
real_t affine_function(const Vector &p)
double affine_function(const Vector &p)
{
real_t x = p(0), y = p(1);
double x = p(0), y = p(1);
if (x < 0.0)
{
return 1.0 + x + y;
@@ -56,7 +56,7 @@ real_t affine_function(const Vector &p)
}
// Piecewise-constant function which is never mesh-conforming
real_t jump_function(const Vector &p)
double jump_function(const Vector &p)
{
if (p.Normlp(2.0) > 0.4 && p.Normlp(2.0) < 0.6)
{
@@ -70,17 +70,17 @@ real_t jump_function(const Vector &p)
// Singular function derived from the Laplacian of the "steep wavefront" problem
// in [2].
real_t singular_function(const Vector &p)
double singular_function(const Vector &p)
{
real_t x = p(0), y = p(1);
real_t alpha = 1000.0;
real_t xc = 0.75, yc = 0.5;
real_t r0 = 0.7;
real_t r = sqrt(pow(x - xc,2.0) + pow(y - yc,2.0));
real_t num = - ( alpha - pow(alpha,3) * (pow(r,2) - pow(r0,2)) );
real_t denom = pow(r * ( pow(alpha,2) * pow(r0,2) + pow(alpha,2) * pow(r,2) \
double x = p(0), y = p(1);
double alpha = 1000.0;
double xc = 0.75, yc = 0.5;
double r0 = 0.7;
double r = sqrt(pow(x - xc,2.0) + pow(y - yc,2.0));
double num = - ( alpha - pow(alpha,3) * (pow(r,2) - pow(r0,2)) );
double denom = pow(r * ( pow(alpha,2) * pow(r0,2) + pow(alpha,2) * pow(r,2) \
- 2 * pow(alpha,2) * r0 * r + 1.0 ),2);
denom = std::max(denom, (real_t) 1.0e-8);
denom = max(denom,1e-8);
return num / denom;
}
@@ -91,9 +91,9 @@ int main(int argc, char *argv[])
int order = 1;
int nc_limit = 1;
int max_elems = 100*1000;
real_t double_max_elems = real_t(max_elems);
double double_max_elems = double(max_elems);
bool visualization = true;
real_t osc_threshold = 1e-3;
double osc_threshold = 1e-3;
int enriched_order = 5;
OptionsParser args(argc, argv);
+15 -15
View File
@@ -42,9 +42,9 @@ using namespace std;
using namespace mfem;
// Piecewise-affine function which is sometimes mesh-conforming
real_t affine_function(const Vector &p)
double affine_function(const Vector &p)
{
real_t x = p(0), y = p(1);
double x = p(0), y = p(1);
if (x < 0.0)
{
return 1.0 + x + y;
@@ -56,7 +56,7 @@ real_t affine_function(const Vector &p)
}
// Piecewise-constant function which is never mesh-conforming
real_t jump_function(const Vector &p)
double jump_function(const Vector &p)
{
if (p.Normlp(2.0) > 0.4 && p.Normlp(2.0) < 0.6)
{
@@ -70,17 +70,17 @@ real_t jump_function(const Vector &p)
// Singular function derived from the Laplacian of the "steep wavefront" problem
// in [2].
real_t singular_function(const Vector &p)
double singular_function(const Vector &p)
{
real_t x = p(0), y = p(1);
real_t alpha = 1000.0;
real_t xc = 0.75, yc = 0.5;
real_t r0 = 0.7;
real_t r = sqrt(pow(x - xc,2.0) + pow(y - yc,2.0));
real_t num = - ( alpha - pow(alpha,3) * (pow(r,2) - pow(r0,2)) );
real_t denom = pow(r * ( pow(alpha,2) * pow(r0,2) + pow(alpha,2) * pow(r,2) \
double x = p(0), y = p(1);
double alpha = 1000.0;
double xc = 0.75, yc = 0.5;
double r0 = 0.7;
double r = sqrt(pow(x - xc,2.0) + pow(y - yc,2.0));
double num = - ( alpha - pow(alpha,3) * (pow(r,2) - pow(r0,2)) );
double denom = pow(r * ( pow(alpha,2) * pow(r0,2) + pow(alpha,2) * pow(r,2) \
- 2 * pow(alpha,2) * r0 * r + 1.0 ),2);
denom = std::max(denom, (real_t) 1.0e-8);
denom = max(denom,1e-8);
return num / denom;
}
@@ -97,10 +97,10 @@ int main(int argc, char *argv[])
int order = 1;
int nc_limit = 1;
int max_elems = 1e5;
real_t double_max_elems = real_t(max_elems);
double double_max_elems = double(max_elems);
bool visualization = true;
bool nc_simplices = true;
real_t osc_threshold = 1e-3;
double osc_threshold = 1e-3;
int enriched_order = 5;
OptionsParser args(argc, argv);
@@ -199,7 +199,7 @@ int main(int argc, char *argv[])
coeffrefiner.PreprocessMesh(pmesh);
int globalNE = pmesh.GetGlobalNE();
real_t osc = coeffrefiner.GetOsc();
double osc = coeffrefiner.GetOsc();
if (myid == 0)
{
mfem::out << "\n";
+28 -28
View File
@@ -39,7 +39,7 @@ using namespace mfem;
void E_exact(const Vector &, Vector &);
void CurlE_exact(const Vector &, Vector &);
void f_exact(const Vector &, Vector &);
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int dim;
int main(int argc, char *argv[])
@@ -177,7 +177,7 @@ int main(int argc, char *argv[])
// 13. Compute and print the H(Curl) norm of the error.
{
real_t error = sol.ComputeHCurlError(&E, &CurlE);
double error = sol.ComputeHCurlError(&E, &CurlE);
cout << "\n|| E_h - E ||_{H(Curl)} = " << error << '\n' << endl;
}
@@ -376,8 +376,8 @@ void CurlE_exact(const Vector &x, Vector &dE)
{
if (dim == 1)
{
real_t c4 = cos(kappa * x(0) + 0.4 * M_PI);
real_t c9 = cos(kappa * x(0) + 0.9 * M_PI);
double c4 = cos(kappa * x(0) + 0.4 * M_PI);
double c9 = cos(kappa * x(0) + 0.9 * M_PI);
dE(0) = 0.0;
dE(1) = -1.3 * c9;
@@ -386,9 +386,9 @@ void CurlE_exact(const Vector &x, Vector &dE)
}
else if (dim == 2)
{
real_t c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
dE(0) = 1.3 * c9;
dE(1) = -1.3 * c9;
@@ -397,13 +397,13 @@ void CurlE_exact(const Vector &x, Vector &dE)
}
else
{
real_t s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
real_t sk = sin(kappa * x(2));
real_t ck = cos(kappa * x(2));
double s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double sk = sin(kappa * x(2));
double ck = cos(kappa * x(2));
dE(0) = 1.2 * s4 * sk + 1.3 * M_SQRT1_2 * c9 * ck;
dE(1) = -1.1 * s0 * sk - 1.3 * M_SQRT1_2 * c9 * ck;
@@ -416,9 +416,9 @@ void f_exact(const Vector &x, Vector &f)
{
if (dim == 1)
{
real_t s0 = sin(kappa * x(0) + 0.0 * M_PI);
real_t s4 = sin(kappa * x(0) + 0.4 * M_PI);
real_t s9 = sin(kappa * x(0) + 0.9 * M_PI);
double s0 = sin(kappa * x(0) + 0.0 * M_PI);
double s4 = sin(kappa * x(0) + 0.4 * M_PI);
double s9 = sin(kappa * x(0) + 0.9 * M_PI);
f(0) = 2.2 * s0 + 1.2 * M_SQRT1_2 * s4;
f(1) = 1.2 * (2.0 + kappa * kappa) * s4 +
@@ -427,9 +427,9 @@ void f_exact(const Vector &x, Vector &f)
}
else if (dim == 2)
{
real_t s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t s9 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double s9 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
f(0) = 0.55 * (4.0 + kappa * kappa) * s0 +
0.6 * (M_SQRT2 - kappa * kappa) * s4;
@@ -440,14 +440,14 @@ void f_exact(const Vector &x, Vector &f)
}
else
{
real_t s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t s9 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
real_t c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
real_t sk = sin(kappa * x(2));
real_t ck = cos(kappa * x(2));
double s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double s9 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double sk = sin(kappa * x(2));
double ck = cos(kappa * x(2));
f(0) = 0.55 * (4.0 + 3.0 * kappa * kappa) * s0 * ck +
0.6 * (M_SQRT2 - kappa * kappa) * s4 * ck -
+28 -28
View File
@@ -39,7 +39,7 @@ using namespace mfem;
void E_exact(const Vector &, Vector &);
void CurlE_exact(const Vector &, Vector &);
void f_exact(const Vector &, Vector &);
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int dim;
int main(int argc, char *argv[])
@@ -224,7 +224,7 @@ int main(int argc, char *argv[])
// 14. Compute and print the H(Curl) norm of the error.
{
real_t error = sol.ComputeHCurlError(&E, &CurlE);
double error = sol.ComputeHCurlError(&E, &CurlE);
if (Mpi::Root())
{
cout << "\n|| E_h - E ||_{H(Curl)} = " << error << '\n' << endl;
@@ -442,8 +442,8 @@ void CurlE_exact(const Vector &x, Vector &dE)
{
if (dim == 1)
{
real_t c4 = cos(kappa * x(0) + 0.4 * M_PI);
real_t c9 = cos(kappa * x(0) + 0.9 * M_PI);
double c4 = cos(kappa * x(0) + 0.4 * M_PI);
double c9 = cos(kappa * x(0) + 0.9 * M_PI);
dE(0) = 0.0;
dE(1) = -1.3 * c9;
@@ -452,9 +452,9 @@ void CurlE_exact(const Vector &x, Vector &dE)
}
else if (dim == 2)
{
real_t c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
dE(0) = 1.3 * c9;
dE(1) = -1.3 * c9;
@@ -463,13 +463,13 @@ void CurlE_exact(const Vector &x, Vector &dE)
}
else
{
real_t s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
real_t sk = sin(kappa * x(2));
real_t ck = cos(kappa * x(2));
double s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double sk = sin(kappa * x(2));
double ck = cos(kappa * x(2));
dE(0) = 1.2 * s4 * sk + 1.3 * M_SQRT1_2 * c9 * ck;
dE(1) = -1.1 * s0 * sk - 1.3 * M_SQRT1_2 * c9 * ck;
@@ -482,9 +482,9 @@ void f_exact(const Vector &x, Vector &f)
{
if (dim == 1)
{
real_t s0 = sin(kappa * x(0) + 0.0 * M_PI);
real_t s4 = sin(kappa * x(0) + 0.4 * M_PI);
real_t s9 = sin(kappa * x(0) + 0.9 * M_PI);
double s0 = sin(kappa * x(0) + 0.0 * M_PI);
double s4 = sin(kappa * x(0) + 0.4 * M_PI);
double s9 = sin(kappa * x(0) + 0.9 * M_PI);
f(0) = 2.2 * s0 + 1.2 * M_SQRT1_2 * s4;
f(1) = 1.2 * (2.0 + kappa * kappa) * s4 +
@@ -493,9 +493,9 @@ void f_exact(const Vector &x, Vector &f)
}
else if (dim == 2)
{
real_t s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t s9 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double s9 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
f(0) = 0.55 * (4.0 + kappa * kappa) * s0 +
0.6 * (M_SQRT2 - kappa * kappa) * s4;
@@ -506,14 +506,14 @@ void f_exact(const Vector &x, Vector &f)
}
else
{
real_t s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
real_t s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
real_t s9 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
real_t c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
real_t sk = sin(kappa * x(2));
real_t ck = cos(kappa * x(2));
double s0 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double c0 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.0 * M_PI);
double s4 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double c4 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.4 * M_PI);
double s9 = sin(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double c9 = cos(kappa * M_SQRT1_2 * (x(0) + x(1)) + 0.9 * M_PI);
double sk = sin(kappa * x(2));
double ck = cos(kappa * x(2));
f(0) = 0.55 * (4.0 + 3.0 * kappa * kappa) * s0 * ck +
0.6 * (M_SQRT2 - kappa * kappa) * s4 * ck -
+18 -18
View File
@@ -35,8 +35,8 @@
using namespace std;
using namespace mfem;
real_t GetVectorMax(int vdim, const ParGridFunction &x);
real_t GetScalarMax(const ParGridFunction &x);
double GetVectorMax(int vdim, const ParGridFunction &x);
double GetScalarMax(const ParGridFunction &x);
int main(int argc, char *argv[])
{
@@ -140,7 +140,7 @@ int main(int argc, char *argv[])
// extract the corresponding parallel matrices A and M.
HypreParMatrix *A = NULL;
HypreParMatrix *M = NULL;
real_t shift = 0.0;
double shift = 0.0;
{
DenseMatrix epsilonMat(3);
epsilonMat(0,0) = 2.0; epsilonMat(1,1) = 2.0; epsilonMat(2,2) = 2.0;
@@ -178,7 +178,7 @@ int main(int argc, char *argv[])
m.AddDomainIntegrator(new VectorFEMassIntegrator(epsilon));
m.Assemble();
// shift the eigenvalue corresponding to eliminated dofs to a large value
m.EliminateEssentialBCDiag(ess_bdr, numeric_limits<real_t>::min());
m.EliminateEssentialBCDiag(ess_bdr, numeric_limits<double>::min());
m.Finalize();
A = a.ParallelAssemble();
@@ -204,7 +204,7 @@ int main(int argc, char *argv[])
// 9. Compute the eigenmodes and extract the array of eigenvalues. Define
// parallel grid functions to represent each of the eigenmodes returned by
// the solver and their derivatives.
Array<real_t> eigenvalues;
Array<double> eigenvalues;
ame->Solve();
ame->GetEigenvalues(eigenvalues);
ParGridFunction x(&fespace_nd);
@@ -308,10 +308,10 @@ int main(int argc, char *argv[])
yComp.ProjectCoefficient(yCoef);
zComp.ProjectCoefficient(zCoef);
real_t max_x = GetScalarMax(xComp);
real_t max_y = GetScalarMax(yComp);
real_t max_z = GetScalarMax(zComp);
real_t max_r = std::max(max_x, std::max(max_y, max_z));
double max_x = GetScalarMax(xComp);
double max_y = GetScalarMax(yComp);
double max_z = GetScalarMax(zComp);
double max_r = std::max(max_x, std::max(max_y, max_z));
ostringstream x_cmd;
x_cmd << " window_title 'Eigenmode " << i+1 << '/' << nev
@@ -368,7 +368,7 @@ int main(int argc, char *argv[])
dyComp.ProjectCoefficient(dyCoef);
dzComp.ProjectCoefficient(dzCoef);
real_t min_d = max_r / (bbMax[0] - bbMin[0]);
double min_d = max_r / (bbMax[0] - bbMin[0]);
max_y = GetScalarMax(dyComp);
max_z = GetScalarMax(dzComp);
@@ -480,9 +480,9 @@ int main(int argc, char *argv[])
xyComp.ProjectCoefficient(xyCoef);
zComp.ProjectCoefficient(zCoef);
real_t max_v = GetVectorMax(2, xyComp);
real_t max_s = GetScalarMax(zComp);
real_t max_r = std::max(max_v, max_s);
double max_v = GetVectorMax(2, xyComp);
double max_s = GetScalarMax(zComp);
double max_r = std::max(max_v, max_s);
ostringstream xy_cmd;
xy_cmd << " window_title 'Eigenmode " << i+1 << '/' << nev
@@ -523,7 +523,7 @@ int main(int argc, char *argv[])
dxyComp.ProjectCoefficient(dxyCoef);
dzComp.ProjectCoefficient(dzCoef);
real_t min_d = max_r / std::min(bbMax[0] - bbMin[0],
double min_d = max_r / std::min(bbMax[0] - bbMin[0],
bbMax[1] - bbMin[1]);
max_v = GetVectorMax(2, dxyComp);
@@ -649,17 +649,17 @@ int main(int argc, char *argv[])
return 0;
}
real_t GetVectorMax(int vdim, const ParGridFunction &x)
double GetVectorMax(int vdim, const ParGridFunction &x)
{
Vector zeroVec(vdim); zeroVec = 0.0;
VectorConstantCoefficient zero(zeroVec);
real_t nrm = x.ComputeMaxError(zero);
double nrm = x.ComputeMaxError(zero);
return nrm;
}
real_t GetScalarMax(const ParGridFunction &x)
double GetScalarMax(const ParGridFunction &x)
{
ConstantCoefficient zero(0.0);
real_t nrm = x.ComputeMaxError(zero);
double nrm = x.ComputeMaxError(zero);
return nrm;
}
+7 -12
View File
@@ -86,16 +86,11 @@ using namespace mfem;
int main(int argc, char *argv[])
{
#ifdef MFEM_USE_SINGLE
cout << "This example is not supported in single precision.\n\n";
return MFEM_SKIP_RETURN_VALUE;
#endif
// 1. Parse command-line options.
const char *mesh_file = "../data/star.mesh";
int order = 1;
int num_refs = 3;
real_t alpha = 0.5;
double alpha = 0.5;
bool visualization = true;
bool verification = false;
@@ -123,13 +118,13 @@ int main(int argc, char *argv[])
}
args.PrintOptions(cout);
Array<real_t> coeffs, poles;
Array<double> coeffs, poles;
int progress_steps = 1;
// 2. Compute the rational expansion coefficients that define the
// integer-order PDEs.
const int power_of_laplace = (int)floor(alpha);
real_t exponent_to_approximate = alpha - power_of_laplace;
double exponent_to_approximate = alpha - power_of_laplace;
bool integer_order = false;
// Check if alpha is an integer or not.
if (abs(exponent_to_approximate) > 1e-12)
@@ -140,7 +135,7 @@ int main(int argc, char *argv[])
ComputePartialFractionApproximation(exponent_to_approximate, coeffs,
poles);
// If the example is built without LAPACK, the exponent_to_approximate
// If the example is build without LAPACK, the exponent_to_approximate
// might be modified by the function call above.
alpha = exponent_to_approximate + power_of_laplace;
}
@@ -178,7 +173,7 @@ int main(int argc, char *argv[])
// 7. Define diffusion coefficient, load, and solution GridFunction.
auto func = [&alpha](const Vector &x)
{
real_t val = 1.0;
double val = 1.0;
for (int i=0; i<x.Size(); i++)
{
val *= sin(M_PI*x(i));
@@ -369,7 +364,7 @@ int main(int argc, char *argv[])
{
auto solution = [] (const Vector &x)
{
real_t val = 1.0;
double val = 1.0;
for (int i=0; i<x.Size(); i++)
{
val *= sin(M_PI*x(i));
@@ -377,7 +372,7 @@ int main(int argc, char *argv[])
return val;
};
FunctionCoefficient sol(solution);
real_t l2_error = u.ComputeL2Error(sol);
double l2_error = u.ComputeL2Error(sol);
string analytic_solution,expected_mesh;
switch (dim)
+28 -28
View File
@@ -50,8 +50,8 @@ using namespace mfem;
See pg. A1501 of Nakatsukasa et al. [1]. */
void RationalApproximation_AAA(const Vector &val, const Vector &pt,
Array<real_t> &z, Array<real_t> &f, Vector &w,
real_t tol, int max_order)
Array<double> &z, Array<double> &f, Vector &w,
double tol, int max_order)
{
// number of sample points
@@ -67,11 +67,11 @@ void RationalApproximation_AAA(const Vector &val, const Vector &pt,
DenseMatrix C, Ctemp, A, Am;
// auxiliary arrays and vectors
Vector f_vec;
Array<real_t> c_i;
Array<double> c_i;
// mean of the value vector
Vector R(val.Size());
real_t mean_val = val.Sum()/size;
double mean_val = val.Sum()/size;
for (int i = 0; i<R.Size(); i++) { R(i) = mean_val; }
@@ -79,10 +79,10 @@ void RationalApproximation_AAA(const Vector &val, const Vector &pt,
{
// select next support point
int idx = 0;
real_t tmp_max = 0;
double tmp_max = 0;
for (int j = 0; j < size; j++)
{
real_t tmp = abs(val(j)-R(j));
double tmp = abs(val(j)-R(j));
if (tmp > tmp_max)
{
tmp_max = tmp;
@@ -98,7 +98,7 @@ void RationalApproximation_AAA(const Vector &val, const Vector &pt,
J.DeleteFirst(idx);
// next column in Cauchy matrix
Array<real_t> C_tmp(size);
Array<double> C_tmp(size);
for (int j = 0; j < size; j++)
{
C_tmp[j] = 1.0/(pt(j)-pt(idx));
@@ -173,7 +173,7 @@ void RationalApproximation_AAA(const Vector &val, const Vector &pt,
See pg. A1501 of Nakatsukasa et al. [1]. */
void ComputePolesAndZeros(const Vector &z, const Vector &f, const Vector &w,
Array<real_t> & poles, Array<real_t> & zeros, real_t &scale)
Array<double> & poles, Array<double> & zeros, double &scale)
{
// Initialization
poles.SetSize(0);
@@ -242,8 +242,8 @@ void ComputePolesAndZeros(const Vector &z, const Vector &f, const Vector &w,
@param[in] zeros Array of zeros
@param[in] scale Scaling constant
@param[out] coeffs Coefficients c_i */
void PartialFractionExpansion(real_t scale, Array<real_t> & poles,
Array<real_t> & zeros, Array<real_t> & coeffs)
void PartialFractionExpansion(double scale, Array<double> & poles,
Array<double> & zeros, Array<double> & coeffs)
{
int psize = poles.Size();
int zsize = zeros.Size();
@@ -259,13 +259,13 @@ void PartialFractionExpansion(real_t scale, Array<real_t> & poles,
for (int i=0; i<psize; i++)
{
real_t tmp_numer=1.0;
double tmp_numer=1.0;
for (int j=0; j<zsize; j++)
{
tmp_numer *= poles[i]-zeros[j];
}
real_t tmp_denom=1.0;
double tmp_denom=1.0;
for (int k=0; k<psize; k++)
{
if (k != i) { tmp_denom *= poles[i]-poles[k]; }
@@ -292,10 +292,10 @@ void PartialFractionExpansion(real_t scale, Array<real_t> & poles,
@a alpha != 0.99, then @a alpha = 0.5 is used by default.
See pg. A1501 of Nakatsukasa et al. [1]. */
void ComputePartialFractionApproximation(real_t & alpha,
Array<real_t> & coeffs, Array<real_t> & poles,
real_t lmax = 1000.,
real_t tol=1e-10, int npoints = 1000,
void ComputePartialFractionApproximation(double & alpha,
Array<double> & coeffs, Array<double> & poles,
double lmax = 1000.,
double tol=1e-10, int npoints = 1000,
int max_order = 100)
{
MFEM_VERIFY(alpha < 1., "alpha must be less than 1");
@@ -320,26 +320,26 @@ void ComputePartialFractionApproximation(real_t & alpha,
<< "\nThe default is alpha = 0.5.\n" << string(80, '=') << "\n"
<< endl;
}
const real_t eps = std::numeric_limits<real_t>::epsilon();
const double eps = std::numeric_limits<double>::epsilon();
if (abs(alpha - 0.33) < eps)
{
coeffs = Array<real_t> ({1.821898e+03, 9.101221e+01, 2.650611e+01,
coeffs = Array<double> ({1.821898e+03, 9.101221e+01, 2.650611e+01,
1.174937e+01, 6.140444e+00, 3.441713e+00,
1.985735e+00, 1.162634e+00, 6.891560e-01,
4.111574e-01, 2.298736e-01});
poles = Array<real_t> ({-4.155583e+04, -2.956285e+03, -8.331715e+02,
poles = Array<double> ({-4.155583e+04, -2.956285e+03, -8.331715e+02,
-3.139332e+02, -1.303448e+02, -5.563385e+01,
-2.356255e+01, -9.595516e+00, -3.552160e+00,
-1.032136e+00, -1.241480e-01});
}
else if (abs(alpha - 0.99) < eps)
{
coeffs = Array<real_t>({2.919591e-02, 1.419750e-02, 1.065798e-02,
coeffs = Array<double>({2.919591e-02, 1.419750e-02, 1.065798e-02,
9.395094e-03, 8.915329e-03, 8.822991e-03,
9.058247e-03, 9.814521e-03, 1.180396e-02,
1.834554e-02, 9.840482e-01});
poles = Array<real_t> ({-1.069683e+04, -1.769370e+03, -5.718374e+02,
poles = Array<double> ({-1.069683e+04, -1.769370e+03, -5.718374e+02,
-2.242095e+02, -9.419132e+01, -4.031012e+01,
-1.701525e+01, -6.810088e+00, -2.382810e+00,
-5.700059e-01, -1.384324e-03});
@@ -350,11 +350,11 @@ void ComputePartialFractionApproximation(real_t & alpha,
{
alpha = 0.5;
}
coeffs = Array<real_t>({2.290262e+02, 2.641819e+01, 1.005566e+01,
coeffs = Array<double>({2.290262e+02, 2.641819e+01, 1.005566e+01,
5.390411e+00, 3.340725e+00, 2.211205e+00,
1.508883e+00, 1.049474e+00, 7.462709e-01,
5.482686e-01, 4.232510e-01, 3.578967e-01});
poles = Array<real_t>({-3.168211e+04, -3.236077e+03, -9.868287e+02,
poles = Array<double>({-3.168211e+04, -3.236077e+03, -9.868287e+02,
-3.945597e+02, -1.738889e+02, -7.925178e+01,
-3.624992e+01, -1.629196e+01, -6.982956e+00,
-2.679984e+00, -7.782607e-01, -7.649166e-02});
@@ -372,15 +372,15 @@ void ComputePartialFractionApproximation(real_t & alpha,
Vector x(npoints);
Vector val(npoints);
real_t dx = lmax / (real_t)(npoints-1);
double dx = lmax / (double)(npoints-1);
for (int i = 0; i<npoints; i++)
{
x(i) = dx * (real_t)i;
x(i) = dx * (double)i;
val(i) = pow(x(i),1.-alpha);
}
// Apply triple-A algorithm to f(x) = x^{1-a}
Array<real_t> z, f;
Array<double> z, f;
Vector w;
RationalApproximation_AAA(val,x,z,f,w,tol,max_order);
@@ -389,8 +389,8 @@ void ComputePartialFractionApproximation(real_t & alpha,
vecf.SetDataAndSize(f.GetData(), f.Size());
// Compute poles and zeros for RA of f(x) = x^{1-a}
real_t scale;
Array<real_t> zeros;
double scale;
Array<double> zeros;
ComputePolesAndZeros(vecz, vecf, w, poles, zeros, scale);
// Remove the zero at x=0, thus, delivering a RA for f(x) = x^{-a}
+6 -11
View File
@@ -86,11 +86,6 @@ using namespace mfem;
int main(int argc, char *argv[])
{
#ifdef MFEM_USE_SINGLE
cout << "This example is not supported in single precision.\n\n";
return MFEM_SKIP_RETURN_VALUE;
#endif
// 0. Initialize MPI.
Mpi::Init(argc, argv);
int num_procs = Mpi::WorldSize();
@@ -101,7 +96,7 @@ int main(int argc, char *argv[])
const char *mesh_file = "../data/star.mesh";
int order = 1;
int num_refs = 3;
real_t alpha = 0.5;
double alpha = 0.5;
bool visualization = true;
bool verification = false;
@@ -132,13 +127,13 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
Array<real_t> coeffs, poles;
Array<double> coeffs, poles;
int progress_steps = 1;
// 2. Compute the rational expansion coefficients that define the
// integer-order PDEs.
const int power_of_laplace = floor(alpha);
real_t exponent_to_approximate = alpha - power_of_laplace;
double exponent_to_approximate = alpha - power_of_laplace;
bool integer_order = false;
// Check if alpha is an integer or not.
if (abs(exponent_to_approximate) > 1e-12)
@@ -198,7 +193,7 @@ int main(int argc, char *argv[])
// 7. Define diffusion coefficient, load, and solution GridFunction.
auto func = [&alpha](const Vector &x)
{
real_t val = 1.0;
double val = 1.0;
for (int i=0; i<x.Size(); i++)
{
val *= sin(M_PI*x(i));
@@ -403,7 +398,7 @@ int main(int argc, char *argv[])
{
auto solution = [] (const Vector &x)
{
real_t val = 1.0;
double val = 1.0;
for (int i=0; i<x.Size(); i++)
{
val *= sin(M_PI*x(i));
@@ -411,7 +406,7 @@ int main(int argc, char *argv[])
return val;
};
FunctionCoefficient sol(solution);
real_t l2_error = u.ComputeL2Error(sol);
double l2_error = u.ComputeL2Error(sol);
if (Mpi::Root())
{
+3 -7
View File
@@ -52,7 +52,6 @@ static bool pa_ = false;
static bool algebraic_ceed_ = false;
void ComputeCurrentDensityOnSubMesh(int order,
bool visualization,
const Array<int> &phi0_attr,
const Array<int> &phi1_attr,
const Array<int> &jn_zero_attr,
@@ -70,7 +69,7 @@ int main(int argc, char *argv[])
Array<int> jn_zero_attr;
int ref_levels = 1;
int order = 1;
real_t delta_const = 1e-6;
double delta_const = 1e-6;
bool mixed = true;
bool static_cond = false;
const char *device_config = "cpu";
@@ -237,8 +236,8 @@ int main(int argc, char *argv[])
FiniteElementSpace fes_cond_rt(&mesh_cond, &fec_cond_rt);
GridFunction j_cond(&fes_cond_rt);
ComputeCurrentDensityOnSubMesh(order, visualization,
phi0_attr, phi1_attr, jn_zero_attr, j_cond);
ComputeCurrentDensityOnSubMesh(order, phi0_attr, phi1_attr, jn_zero_attr,
j_cond);
// 6a. Save the SubMesh and associated current density in parallel. This
// output can be viewed later using GLVis:
@@ -256,7 +255,6 @@ int main(int argc, char *argv[])
cond_ofs.precision(8);
j_cond.Save(cond_ofs);
}
// 6b. Send the current density, computed on the SubMesh, to a GLVis server.
if (visualization)
{
@@ -452,7 +450,6 @@ int main(int argc, char *argv[])
}
void ComputeCurrentDensityOnSubMesh(int order,
bool visualization,
const Array<int> &phi0_attr,
const Array<int> &phi1_attr,
const Array<int> &jn_zero_attr,
@@ -570,7 +567,6 @@ void ComputeCurrentDensityOnSubMesh(int order,
a_h1.RecoverFEMSolution(X, b_h1, phi_h1);
}
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
+3 -8
View File
@@ -49,7 +49,6 @@ using namespace std;
using namespace mfem;
void ComputeCurrentDensityOnSubMesh(int order,
bool visualization,
const Array<int> &phi0_attr,
const Array<int> &phi1_attr,
const Array<int> &jn_zero_attr,
@@ -74,7 +73,7 @@ int main(int argc, char *argv[])
int ser_ref_levels = 1;
int par_ref_levels = 1;
int order = 1;
real_t delta_const = 1e-6;
double delta_const = 1e-6;
bool mixed = true;
bool static_cond = false;
bool pa = false;
@@ -271,8 +270,8 @@ int main(int argc, char *argv[])
ParFiniteElementSpace fes_cond_rt(&pmesh_cond, &fec_cond_rt);
ParGridFunction j_cond(&fes_cond_rt);
ComputeCurrentDensityOnSubMesh(order, visualization,
phi0_attr, phi1_attr, jn_zero_attr, j_cond);
ComputeCurrentDensityOnSubMesh(order, phi0_attr, phi1_attr, jn_zero_attr,
j_cond);
// 7a. Save the SubMesh and associated current density in parallel. This
// output can be viewed later using GLVis:
@@ -290,7 +289,6 @@ int main(int argc, char *argv[])
cond_ofs.precision(8);
j_cond.Save(cond_ofs);
}
// 7b. Send the current density, computed on the SubMesh, to a GLVis server.
if (visualization)
{
@@ -500,7 +498,6 @@ int main(int argc, char *argv[])
}
void ComputeCurrentDensityOnSubMesh(int order,
bool visualization,
const Array<int> &phi0_attr,
const Array<int> &phi1_attr,
const Array<int> &jn_zero_attr,
@@ -589,8 +586,6 @@ void ComputeCurrentDensityOnSubMesh(int order,
cg.Mult(B, X);
a_h1.RecoverFEMSolution(X, b_h1, phi_h1);
}
if (visualization)
{
int num_procs = fes_cond_h1.GetNRanks();
char vishost[] = "localhost";
+9 -9
View File
@@ -55,9 +55,9 @@
using namespace std;
using namespace mfem;
static real_t mu_ = 1.0;
static real_t epsilon_ = 1.0;
static real_t sigma_ = 2.0;
static double mu_ = 1.0;
static double epsilon_ = 1.0;
static double sigma_ = 2.0;
void SetPortBC(int prob, int dim, int mode, ParGridFunction &port_bc);
@@ -77,9 +77,9 @@ int main(int argc, char *argv[])
Array<int> port_bc_attr;
int prob = 0;
int mode = 1;
real_t freq = -1.0;
real_t omega = 2.0 * M_PI;
real_t a_coef = 0.0;
double freq = -1.0;
double omega = 2.0 * M_PI;
double a_coef = 0.0;
bool herm_conv = true;
bool slu_solver = false;
bool visualization = 1;
@@ -587,7 +587,7 @@ int main(int argc, char *argv[])
int i = 0;
while (sol_sock)
{
real_t t = (real_t)(i % num_frames) / num_frames;
double t = (double)(i % num_frames) / num_frames;
ostringstream oss;
oss << "Harmonic Solution (t = " << t << " T)";
@@ -637,7 +637,7 @@ void ScalarWaveGuide(int mode, ParGridFunction &x)
m.AddDomainIntegrator(new MassIntegrator);
m.Assemble();
// shift the eigenvalue corresponding to eliminated dofs to a large value
m.EliminateEssentialBCDiag(ess_bdr, numeric_limits<real_t>::min());
m.EliminateEssentialBCDiag(ess_bdr, numeric_limits<double>::min());
m.Finalize();
HypreParMatrix *A = a.ParallelAssemble();
@@ -694,7 +694,7 @@ void VectorWaveGuide(int mode, ParGridFunction &x)
m.AddDomainIntegrator(new VectorFEMassIntegrator);
m.Assemble();
// shift the eigenvalue corresponding to eliminated dofs to a large value
m.EliminateEssentialBCDiag(ess_bdr, numeric_limits<real_t>::min());
m.EliminateEssentialBCDiag(ess_bdr, numeric_limits<double>::min());
m.Finalize();
HypreParMatrix *A = a.ParallelAssemble();
+47 -47
View File
@@ -37,8 +37,8 @@
using namespace std;
using namespace mfem;
real_t spherical_obstacle(const Vector &pt);
real_t exact_solution_obstacle(const Vector &pt);
double spherical_obstacle(const Vector &pt);
double exact_solution_obstacle(const Vector &pt);
void exact_solution_gradient_obstacle(const Vector &pt, Vector &grad);
class LogarithmGridFunctionCoefficient : public Coefficient
@@ -46,14 +46,14 @@ class LogarithmGridFunctionCoefficient : public Coefficient
protected:
GridFunction *u; // grid function
Coefficient *obstacle;
real_t min_val;
double min_val;
public:
LogarithmGridFunctionCoefficient(GridFunction &u_, Coefficient &obst_,
real_t min_val_=-36)
double min_val_=-36)
: u(&u_), obstacle(&obst_), min_val(min_val_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const;
};
class ExponentialGridFunctionCoefficient : public Coefficient
@@ -61,15 +61,15 @@ class ExponentialGridFunctionCoefficient : public Coefficient
protected:
GridFunction *u;
Coefficient *obstacle;
real_t min_val;
real_t max_val;
double min_val;
double max_val;
public:
ExponentialGridFunctionCoefficient(GridFunction &u_, Coefficient &obst_,
real_t min_val_=0.0, real_t max_val_=1e6)
double min_val_=0.0, double max_val_=1e6)
: u(&u_), obstacle(&obst_), min_val(min_val_), max_val(max_val_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const;
};
int main(int argc, char *argv[])
@@ -78,8 +78,8 @@ int main(int argc, char *argv[])
int order = 1;
int max_it = 10;
int ref_levels = 3;
real_t alpha = 1.0;
real_t tol = 1e-5;
double alpha = 1.0;
double tol = 1e-5;
bool visualization = true;
OptionsParser args(argc, argv);
@@ -124,7 +124,7 @@ int main(int argc, char *argv[])
// 3C. Rescale the domain to a unit circle (radius = 1).
GridFunction *nodes = mesh.GetNodes();
real_t scale = 2*sqrt(2);
double scale = 2*sqrt(2);
*nodes /= scale;
// 4. Define the necessary finite element spaces on the mesh.
@@ -159,8 +159,8 @@ int main(int argc, char *argv[])
// 6. Define an initial guess for the solution.
auto IC_func = [](const Vector &x)
{
real_t r0 = 1.0;
real_t rr = 0.0;
double r0 = 1.0;
double rr = 0.0;
for (int i=0; i<x.Size(); i++)
{
rr += x(i)*x(i);
@@ -211,7 +211,7 @@ int main(int argc, char *argv[])
// 10. Iterate
int k;
int total_iterations = 0;
real_t increment_u = 0.1;
double increment_u = 0.1;
for (k = 0; k < max_it; k++)
{
GridFunction u_tmp(&H1fes);
@@ -300,10 +300,10 @@ int main(int argc, char *argv[])
delta_psi_gf.MakeRef(&L2fes, x.GetBlock(1), 0);
u_tmp -= u_gf;
real_t Newton_update_size = u_tmp.ComputeL2Error(zero);
double Newton_update_size = u_tmp.ComputeL2Error(zero);
u_tmp = u_gf;
real_t gamma = 1.0;
double gamma = 1.0;
delta_psi_gf *= gamma;
psi_gf += delta_psi_gf;
@@ -337,7 +337,7 @@ int main(int argc, char *argv[])
break;
}
real_t H1_error = u_gf.ComputeH1Error(&exact_coef,&exact_grad_coef);
double H1_error = u_gf.ComputeH1Error(&exact_coef,&exact_grad_coef);
mfem::out << "H1-error (|| u - uₕᵏ||) = " << H1_error << endl;
}
@@ -362,13 +362,13 @@ int main(int argc, char *argv[])
}
{
real_t L2_error = u_gf.ComputeL2Error(exact_coef);
real_t H1_error = u_gf.ComputeH1Error(&exact_coef,&exact_grad_coef);
double L2_error = u_gf.ComputeL2Error(exact_coef);
double H1_error = u_gf.ComputeH1Error(&exact_coef,&exact_grad_coef);
ExponentialGridFunctionCoefficient u_alt_cf(psi_gf,obstacle);
GridFunction u_alt_gf(&L2fes);
u_alt_gf.ProjectCoefficient(u_alt_cf);
real_t L2_error_alt = u_alt_gf.ComputeL2Error(exact_coef);
double L2_error_alt = u_alt_gf.ComputeL2Error(exact_coef);
mfem::out << "\n Final L2-error (|| u - uₕ||) = " << L2_error <<
endl;
@@ -380,35 +380,35 @@ int main(int argc, char *argv[])
return 0;
}
real_t LogarithmGridFunctionCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
double LogarithmGridFunctionCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
MFEM_ASSERT(u != NULL, "grid function is not set");
real_t val = u->GetValue(T, ip) - obstacle->Eval(T, ip);
double val = u->GetValue(T, ip) - obstacle->Eval(T, ip);
return max(min_val, log(val));
}
real_t ExponentialGridFunctionCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
double ExponentialGridFunctionCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
MFEM_ASSERT(u != NULL, "grid function is not set");
real_t val = u->GetValue(T, ip);
double val = u->GetValue(T, ip);
return min(max_val, max(min_val, exp(val) + obstacle->Eval(T, ip)));
}
real_t spherical_obstacle(const Vector &pt)
double spherical_obstacle(const Vector &pt)
{
real_t x = pt(0), y = pt(1);
real_t r = sqrt(x*x + y*y);
real_t r0 = 0.5;
real_t beta = 0.9;
double x = pt(0), y = pt(1);
double r = sqrt(x*x + y*y);
double r0 = 0.5;
double beta = 0.9;
real_t b = r0*beta;
real_t tmp = sqrt(r0*r0 - b*b);
real_t B = tmp + b*b/tmp;
real_t C = -b/tmp;
double b = r0*beta;
double tmp = sqrt(r0*r0 - b*b);
double B = tmp + b*b/tmp;
double C = -b/tmp;
if (r > b)
{
@@ -420,13 +420,13 @@ real_t spherical_obstacle(const Vector &pt)
}
}
real_t exact_solution_obstacle(const Vector &pt)
double exact_solution_obstacle(const Vector &pt)
{
real_t x = pt(0), y = pt(1);
real_t r = sqrt(x*x + y*y);
real_t r0 = 0.5;
real_t a = 0.348982574111686;
real_t A = -0.340129705945858;
double x = pt(0), y = pt(1);
double r = sqrt(x*x + y*y);
double r0 = 0.5;
double a = 0.348982574111686;
double A = -0.340129705945858;
if (r > a)
{
@@ -440,11 +440,11 @@ real_t exact_solution_obstacle(const Vector &pt)
void exact_solution_gradient_obstacle(const Vector &pt, Vector &grad)
{
real_t x = pt(0), y = pt(1);
real_t r = sqrt(x*x + y*y);
real_t r0 = 0.5;
real_t a = 0.348982574111686;
real_t A = -0.340129705945858;
double x = pt(0), y = pt(1);
double r = sqrt(x*x + y*y);
double r0 = 0.5;
double a = 0.348982574111686;
double A = -0.340129705945858;
if (r > a)
{
+47 -47
View File
@@ -37,8 +37,8 @@
using namespace std;
using namespace mfem;
real_t spherical_obstacle(const Vector &pt);
real_t exact_solution_obstacle(const Vector &pt);
double spherical_obstacle(const Vector &pt);
double exact_solution_obstacle(const Vector &pt);
void exact_solution_gradient_obstacle(const Vector &pt, Vector &grad);
class LogarithmGridFunctionCoefficient : public Coefficient
@@ -46,14 +46,14 @@ class LogarithmGridFunctionCoefficient : public Coefficient
protected:
GridFunction *u; // grid function
Coefficient *obstacle;
real_t min_val;
double min_val;
public:
LogarithmGridFunctionCoefficient(GridFunction &u_, Coefficient &obst_,
real_t min_val_=-36)
double min_val_=-36)
: u(&u_), obstacle(&obst_), min_val(min_val_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const;
};
class ExponentialGridFunctionCoefficient : public Coefficient
@@ -61,15 +61,15 @@ class ExponentialGridFunctionCoefficient : public Coefficient
protected:
GridFunction *u;
Coefficient *obstacle;
real_t min_val;
real_t max_val;
double min_val;
double max_val;
public:
ExponentialGridFunctionCoefficient(GridFunction &u_, Coefficient &obst_,
real_t min_val_=0.0, real_t max_val_=1e6)
double min_val_=0.0, double max_val_=1e6)
: u(&u_), obstacle(&obst_), min_val(min_val_), max_val(max_val_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const;
};
int main(int argc, char *argv[])
@@ -84,8 +84,8 @@ int main(int argc, char *argv[])
int order = 1;
int max_it = 10;
int ref_levels = 3;
real_t alpha = 1.0;
real_t tol = 1e-5;
double alpha = 1.0;
double tol = 1e-5;
bool visualization = true;
OptionsParser args(argc, argv);
@@ -136,7 +136,7 @@ int main(int argc, char *argv[])
// 3C. Rescale the domain to a unit circle (radius = 1).
GridFunction *nodes = mesh.GetNodes();
real_t scale = 2*sqrt(2);
double scale = 2*sqrt(2);
*nodes /= scale;
ParMesh pmesh(MPI_COMM_WORLD, mesh);
@@ -192,8 +192,8 @@ int main(int argc, char *argv[])
// 6. Define an initial guess for the solution.
auto IC_func = [](const Vector &x)
{
real_t r0 = 1.0;
real_t rr = 0.0;
double r0 = 1.0;
double rr = 0.0;
for (int i=0; i<x.Size(); i++)
{
rr += x(i)*x(i);
@@ -243,7 +243,7 @@ int main(int argc, char *argv[])
// 10. Iterate
int k;
int total_iterations = 0;
real_t increment_u = 0.1;
double increment_u = 0.1;
for (k = 0; k < max_it; k++)
{
ParGridFunction u_tmp(&H1fes);
@@ -346,10 +346,10 @@ int main(int argc, char *argv[])
delta_psi_gf.SetFromTrueDofs(tx.GetBlock(1));
u_tmp -= u_gf;
real_t Newton_update_size = u_tmp.ComputeL2Error(zero);
double Newton_update_size = u_tmp.ComputeL2Error(zero);
u_tmp = u_gf;
real_t gamma = 1.0;
double gamma = 1.0;
delta_psi_gf *= gamma;
psi_gf += delta_psi_gf;
@@ -391,7 +391,7 @@ int main(int argc, char *argv[])
break;
}
real_t H1_error = u_gf.ComputeH1Error(&exact_coef,&exact_grad_coef);
double H1_error = u_gf.ComputeH1Error(&exact_coef,&exact_grad_coef);
if (myid == 0)
{
mfem::out << "H1-error (|| u - uₕᵏ||) = " << H1_error << endl;
@@ -423,13 +423,13 @@ int main(int argc, char *argv[])
}
{
real_t L2_error = u_gf.ComputeL2Error(exact_coef);
real_t H1_error = u_gf.ComputeH1Error(&exact_coef,&exact_grad_coef);
double L2_error = u_gf.ComputeL2Error(exact_coef);
double H1_error = u_gf.ComputeH1Error(&exact_coef,&exact_grad_coef);
ExponentialGridFunctionCoefficient u_alt_cf(psi_gf,obstacle);
ParGridFunction u_alt_gf(&L2fes);
u_alt_gf.ProjectCoefficient(u_alt_cf);
real_t L2_error_alt = u_alt_gf.ComputeL2Error(exact_coef);
double L2_error_alt = u_alt_gf.ComputeL2Error(exact_coef);
if (myid == 0)
{
@@ -444,35 +444,35 @@ int main(int argc, char *argv[])
return 0;
}
real_t LogarithmGridFunctionCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
double LogarithmGridFunctionCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
MFEM_ASSERT(u != NULL, "grid function is not set");
real_t val = u->GetValue(T, ip) - obstacle->Eval(T, ip);
double val = u->GetValue(T, ip) - obstacle->Eval(T, ip);
return max(min_val, log(val));
}
real_t ExponentialGridFunctionCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
double ExponentialGridFunctionCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
MFEM_ASSERT(u != NULL, "grid function is not set");
real_t val = u->GetValue(T, ip);
double val = u->GetValue(T, ip);
return min(max_val, max(min_val, exp(val) + obstacle->Eval(T, ip)));
}
real_t spherical_obstacle(const Vector &pt)
double spherical_obstacle(const Vector &pt)
{
real_t x = pt(0), y = pt(1);
real_t r = sqrt(x*x + y*y);
real_t r0 = 0.5;
real_t beta = 0.9;
double x = pt(0), y = pt(1);
double r = sqrt(x*x + y*y);
double r0 = 0.5;
double beta = 0.9;
real_t b = r0*beta;
real_t tmp = sqrt(r0*r0 - b*b);
real_t B = tmp + b*b/tmp;
real_t C = -b/tmp;
double b = r0*beta;
double tmp = sqrt(r0*r0 - b*b);
double B = tmp + b*b/tmp;
double C = -b/tmp;
if (r > b)
{
@@ -484,13 +484,13 @@ real_t spherical_obstacle(const Vector &pt)
}
}
real_t exact_solution_obstacle(const Vector &pt)
double exact_solution_obstacle(const Vector &pt)
{
real_t x = pt(0), y = pt(1);
real_t r = sqrt(x*x + y*y);
real_t r0 = 0.5;
real_t a = 0.348982574111686;
real_t A = -0.340129705945858;
double x = pt(0), y = pt(1);
double r = sqrt(x*x + y*y);
double r0 = 0.5;
double a = 0.348982574111686;
double A = -0.340129705945858;
if (r > a)
{
@@ -504,11 +504,11 @@ real_t exact_solution_obstacle(const Vector &pt)
void exact_solution_gradient_obstacle(const Vector &pt, Vector &grad)
{
real_t x = pt(0), y = pt(1);
real_t r = sqrt(x*x + y*y);
real_t r0 = 0.5;
real_t a = 0.348982574111686;
real_t A = -0.340129705945858;
double x = pt(0), y = pt(1);
double r = sqrt(x*x + y*y);
double r0 = 0.5;
double a = 0.348982574111686;
double A = -0.340129705945858;
if (r > a)
{
+24 -24
View File
@@ -67,9 +67,9 @@ using namespace mfem;
* @param target_volume θ vol(Ω)
* @param tol Newton iteration tolerance
* @param max_its Newton maximum iteration number
* @return real_t Final volume, sigmoid(ψ)
* @return double Final volume, sigmoid(ψ)
*/
real_t proj(GridFunction &psi, real_t target_volume, real_t tol=1e-12,
double proj(GridFunction &psi, double target_volume, double tol=1e-12,
int max_its=10)
{
MappedGridFunctionCoefficient sigmoid_psi(&psi, sigmoid);
@@ -84,12 +84,12 @@ real_t proj(GridFunction &psi, real_t target_volume, real_t tol=1e-12,
for (int k=0; k<max_its; k++) // Newton iteration
{
int_sigmoid_psi.Assemble(); // Recompute f(c) with updated ψ
const real_t f = int_sigmoid_psi.Sum() - target_volume;
const double f = int_sigmoid_psi.Sum() - target_volume;
int_der_sigmoid_psi.Assemble(); // Recompute df(c) with updated ψ
const real_t df = int_der_sigmoid_psi.Sum();
const double df = int_der_sigmoid_psi.Sum();
const real_t dc = -f/df;
const double dc = -f/df;
psi += dc;
if (abs(dc) < tol) { done = true; break; }
}
@@ -179,15 +179,15 @@ int main(int argc, char *argv[])
// 1. Parse command-line options.
int ref_levels = 5;
int order = 2;
real_t alpha = 1.0;
real_t epsilon = 0.01;
real_t vol_fraction = 0.5;
double alpha = 1.0;
double epsilon = 0.01;
double vol_fraction = 0.5;
int max_it = 1e3;
real_t itol = 1e-1;
real_t ntol = 1e-4;
real_t rho_min = 1e-6;
real_t lambda = 1.0;
real_t mu = 1.0;
double itol = 1e-1;
double ntol = 1e-4;
double rho_min = 1e-6;
double lambda = 1.0;
double mu = 1.0;
bool glvis_visualization = true;
bool paraview_output = false;
@@ -239,8 +239,8 @@ int main(int argc, char *argv[])
Array<int> vertices;
be->GetVertices(vertices);
real_t * coords1 = mesh.GetVertex(vertices[0]);
real_t * coords2 = mesh.GetVertex(vertices[1]);
double * coords1 = mesh.GetVertex(vertices[0]);
double * coords2 = mesh.GetVertex(vertices[1]);
Vector center(2);
center(0) = 0.5*(coords1[0] + coords2[0]);
@@ -312,7 +312,7 @@ int main(int argc, char *argv[])
ElasticitySolver->SetupFEM();
Vector center(2); center(0) = 2.9; center(1) = 0.5;
Vector force(2); force(0) = 0.0; force(1) = -1.0;
real_t r = 0.05;
double r = 0.05;
VolumeForceCoefficient vforce_cf(r,center,force);
ElasticitySolver->SetRHSCoefficient(&vforce_cf);
ElasticitySolver->SetEssentialBoundary(ess_bdr);
@@ -353,8 +353,8 @@ int main(int argc, char *argv[])
LinearForm vol_form(&control_fes);
vol_form.AddDomainIntegrator(new DomainLFIntegrator(one));
vol_form.Assemble();
real_t domain_volume = vol_form(onegf);
const real_t target_volume = domain_volume * vol_fraction;
double domain_volume = vol_form(onegf);
const double target_volume = domain_volume * vol_fraction;
// 10. Connect to GLVis. Prepare for VisIt output.
char vishost[] = "localhost";
@@ -385,7 +385,7 @@ int main(int argc, char *argv[])
// 11. Iterate:
for (int k = 1; k <= max_it; k++)
{
if (k > 1) { alpha *= ((real_t) k) / ((real_t) k-1); }
if (k > 1) { alpha *= ((double) k) / ((double) k-1); }
mfem::out << "\nStep = " << k << std::endl;
@@ -422,14 +422,14 @@ int main(int argc, char *argv[])
// Step 5 - Update design variable ψ ← proj(ψ - αG)
psi.Add(-alpha, grad);
const real_t material_volume = proj(psi, target_volume);
const double material_volume = proj(psi, target_volume);
// Compute ||ρ - ρ_old|| in control fes.
real_t norm_increment = zerogf.ComputeL1Error(succ_diff_rho);
real_t norm_reduced_gradient = norm_increment/alpha;
double norm_increment = zerogf.ComputeL1Error(succ_diff_rho);
double norm_reduced_gradient = norm_increment/alpha;
psi_old = psi;
real_t compliance = (*(ElasticitySolver->GetLinearForm()))(u);
double compliance = (*(ElasticitySolver->GetLinearForm()))(u);
mfem::out << "norm of the reduced gradient = " << norm_reduced_gradient <<
std::endl;
mfem::out << "norm of the increment = " << norm_increment << endl;
@@ -449,7 +449,7 @@ int main(int argc, char *argv[])
{
rho_gf.ProjectCoefficient(rho);
paraview_dc.SetCycle(k);
paraview_dc.SetTime((real_t)k);
paraview_dc.SetTime((double)k);
paraview_dc.Save();
}
+44 -44
View File
@@ -9,15 +9,15 @@ namespace mfem
{
/// @brief Inverse sigmoid function
real_t inv_sigmoid(real_t x)
double inv_sigmoid(double x)
{
real_t tol = 1e-12;
x = std::min(std::max(tol,x), real_t(1.0)-tol);
double tol = 1e-12;
x = std::min(std::max(tol,x),1.0-tol);
return std::log(x/(1.0-x));
}
/// @brief Sigmoid function
real_t sigmoid(real_t x)
double sigmoid(double x)
{
if (x >= 0)
{
@@ -30,9 +30,9 @@ real_t sigmoid(real_t x)
}
/// @brief Derivative of sigmoid function
real_t der_sigmoid(real_t x)
double der_sigmoid(double x)
{
real_t tmp = sigmoid(-x);
double tmp = sigmoid(-x);
return tmp - std::pow(tmp,2);
}
@@ -40,24 +40,24 @@ real_t der_sigmoid(real_t x)
class MappedGridFunctionCoefficient : public GridFunctionCoefficient
{
protected:
std::function<real_t(const real_t)> fun; // f:R → R
std::function<double(const double)> fun; // f:R → R
public:
MappedGridFunctionCoefficient()
:GridFunctionCoefficient(),
fun([](real_t x) {return x;}) {}
fun([](double x) {return x;}) {}
MappedGridFunctionCoefficient(const GridFunction *gf,
std::function<real_t(const real_t)> fun_,
std::function<double(const double)> fun_,
int comp=1)
:GridFunctionCoefficient(gf, comp),
fun(fun_) {}
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
virtual double Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
return fun(GridFunctionCoefficient::Eval(T, ip));
}
void SetFunction(std::function<real_t(const real_t)> fun_) { fun = fun_; }
void SetFunction(std::function<double(const double)> fun_) { fun = fun_; }
};
@@ -67,30 +67,30 @@ class DiffMappedGridFunctionCoefficient : public GridFunctionCoefficient
protected:
const GridFunction *OtherGridF;
GridFunctionCoefficient OtherGridF_cf;
std::function<real_t(const real_t)> fun; // f:R → R
std::function<double(const double)> fun; // f:R → R
public:
DiffMappedGridFunctionCoefficient()
:GridFunctionCoefficient(),
OtherGridF(nullptr),
OtherGridF_cf(),
fun([](real_t x) {return x;}) {}
fun([](double x) {return x;}) {}
DiffMappedGridFunctionCoefficient(const GridFunction *gf,
const GridFunction *other_gf,
std::function<real_t(const real_t)> fun_,
std::function<double(const double)> fun_,
int comp=1)
:GridFunctionCoefficient(gf, comp),
OtherGridF(other_gf),
OtherGridF_cf(OtherGridF),
fun(fun_) {}
virtual real_t Eval(ElementTransformation &T,
const IntegrationPoint &ip)
virtual double Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
const real_t value1 = fun(GridFunctionCoefficient::Eval(T, ip));
const real_t value2 = fun(OtherGridF_cf.Eval(T, ip));
const double value1 = fun(GridFunctionCoefficient::Eval(T, ip));
const double value2 = fun(OtherGridF_cf.Eval(T, ip));
return value1 - value2;
}
void SetFunction(std::function<real_t(const real_t)> fun_) { fun = fun_; }
void SetFunction(std::function<double(const double)> fun_) { fun = fun_; }
};
/// @brief Solid isotropic material penalization (SIMP) coefficient
@@ -98,20 +98,20 @@ class SIMPInterpolationCoefficient : public Coefficient
{
protected:
GridFunction *rho_filter;
real_t min_val;
real_t max_val;
real_t exponent;
double min_val;
double max_val;
double exponent;
public:
SIMPInterpolationCoefficient(GridFunction *rho_filter_, real_t min_val_= 1e-6,
real_t max_val_ = 1.0, real_t exponent_ = 3)
SIMPInterpolationCoefficient(GridFunction *rho_filter_, double min_val_= 1e-6,
double max_val_ = 1.0, double exponent_ = 3)
: rho_filter(rho_filter_), min_val(min_val_), max_val(max_val_),
exponent(exponent_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const
{
real_t val = rho_filter->GetValue(T, ip);
real_t coeff = min_val + pow(val,exponent)*(max_val-min_val);
double val = rho_filter->GetValue(T, ip);
double coeff = min_val + pow(val,exponent)*(max_val-min_val);
return coeff;
}
};
@@ -125,14 +125,14 @@ protected:
Coefficient * mu=nullptr;
GridFunction *u = nullptr; // displacement
GridFunction *rho_filter = nullptr; // filter density
DenseMatrix grad; // auxiliary matrix, used in Eval
real_t exponent;
real_t rho_min;
mutable DenseMatrix grad; // auxiliary matrix, used in Eval
double exponent;
double rho_min;
public:
StrainEnergyDensityCoefficient(Coefficient *lambda_, Coefficient *mu_,
GridFunction * u_, GridFunction * rho_filter_, real_t rho_min_=1e-6,
real_t exponent_ = 3.0)
GridFunction * u_, GridFunction * rho_filter_, double rho_min_=1e-6,
double exponent_ = 3.0)
: lambda(lambda_), mu(mu_), u(u_), rho_filter(rho_filter_),
exponent(exponent_), rho_min(rho_min_)
{
@@ -142,13 +142,13 @@ public:
MFEM_ASSERT(rho_filter, "density field is not set");
}
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip)
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const
{
real_t L = lambda->Eval(T, ip);
real_t M = mu->Eval(T, ip);
double L = lambda->Eval(T, ip);
double M = mu->Eval(T, ip);
u->GetVectorGradient(T, grad);
real_t div_u = grad.Trace();
real_t density = L*div_u*div_u;
double div_u = grad.Trace();
double density = L*div_u*div_u;
int dim = T.GetSpaceDim();
for (int i=0; i<dim; i++)
{
@@ -157,7 +157,7 @@ public:
density += M*grad(i,j)*(grad(i,j)+grad(j,i));
}
}
real_t val = rho_filter->GetValue(T,ip);
double val = rho_filter->GetValue(T,ip);
return -exponent * pow(val, exponent-1.0) * (1-rho_min) * density;
}
@@ -167,17 +167,17 @@ public:
class VolumeForceCoefficient : public VectorCoefficient
{
private:
real_t r;
double r;
Vector center;
Vector force;
public:
VolumeForceCoefficient(real_t r_,Vector & center_, Vector & force_) :
VolumeForceCoefficient(double r_,Vector & center_, Vector & force_) :
VectorCoefficient(center_.Size()), r(r_), center(center_), force(force_) { }
using VectorCoefficient::Eval;
virtual void Eval(Vector &V, ElementTransformation &T,
const IntegrationPoint &ip)
const IntegrationPoint &ip) const
{
Vector xx; xx.SetSize(T.GetDimension());
T.Transform(ip,xx);
@@ -186,7 +186,7 @@ public:
xx[i]=xx[i]-center[i];
}
real_t cr=xx.Norml2();
double cr=xx.Norml2();
V.SetSize(T.GetDimension());
if (cr <= r)
{
@@ -198,7 +198,7 @@ public:
}
}
void Set(real_t r_,Vector & center_, Vector & force_)
void Set(double r_,Vector & center_, Vector & force_)
{
r=r_;
center = center_;
+30 -33
View File
@@ -66,9 +66,9 @@ using namespace mfem;
* @param target_volume θ vol(Ω)
* @param tol Newton iteration tolerance
* @param max_its Newton maximum iteration number
* @return real_t Final volume, sigmoid(ψ)
* @return double Final volume, sigmoid(ψ)
*/
real_t proj(ParGridFunction &psi, real_t target_volume, real_t tol=1e-12,
double proj(ParGridFunction &psi, double target_volume, double tol=1e-12,
int max_its=10)
{
MappedGridFunctionCoefficient sigmoid_psi(&psi, sigmoid);
@@ -83,17 +83,15 @@ real_t proj(ParGridFunction &psi, real_t target_volume, real_t tol=1e-12,
for (int k=0; k<max_its; k++) // Newton iteration
{
int_sigmoid_psi.Assemble(); // Recompute f(c) with updated ψ
real_t f = int_sigmoid_psi.Sum();
MPI_Allreduce(MPI_IN_PLACE, &f, 1, MPITypeMap<real_t>::mpi_type,
MPI_SUM, MPI_COMM_WORLD);
double f = int_sigmoid_psi.Sum();
MPI_Allreduce(MPI_IN_PLACE, &f, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
f -= target_volume;
int_der_sigmoid_psi.Assemble(); // Recompute df(c) with updated ψ
real_t df = int_der_sigmoid_psi.Sum();
MPI_Allreduce(MPI_IN_PLACE, &df, 1, MPITypeMap<real_t>::mpi_type,
MPI_SUM, MPI_COMM_WORLD);
double df = int_der_sigmoid_psi.Sum();
MPI_Allreduce(MPI_IN_PLACE, &df, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
const real_t dc = -f/df;
const double dc = -f/df;
psi += dc;
if (abs(dc) < tol) { done = true; break; }
}
@@ -103,9 +101,9 @@ real_t proj(ParGridFunction &psi, real_t target_volume, real_t tol=1e-12,
"Result may not be accurate.");
}
int_sigmoid_psi.Assemble();
real_t material_volume = int_sigmoid_psi.Sum();
MPI_Allreduce(MPI_IN_PLACE, &material_volume, 1,
MPITypeMap<real_t>::mpi_type, MPI_SUM, MPI_COMM_WORLD);
double material_volume = int_sigmoid_psi.Sum();
MPI_Allreduce(MPI_IN_PLACE, &material_volume, 1, MPI_DOUBLE, MPI_SUM,
MPI_COMM_WORLD);
return material_volume;
}
@@ -192,15 +190,15 @@ int main(int argc, char *argv[])
// 1. Parse command-line options.
int ref_levels = 5;
int order = 2;
real_t alpha = 1.0;
real_t epsilon = 0.01;
real_t vol_fraction = 0.5;
double alpha = 1.0;
double epsilon = 0.01;
double vol_fraction = 0.5;
int max_it = 1e3;
real_t itol = 1e-1;
real_t ntol = 1e-4;
real_t rho_min = 1e-6;
real_t lambda = 1.0;
real_t mu = 1.0;
double itol = 1e-1;
double ntol = 1e-4;
double rho_min = 1e-6;
double lambda = 1.0;
double mu = 1.0;
bool glvis_visualization = true;
bool paraview_output = false;
@@ -260,8 +258,8 @@ int main(int argc, char *argv[])
Array<int> vertices;
be->GetVertices(vertices);
real_t * coords1 = mesh.GetVertex(vertices[0]);
real_t * coords2 = mesh.GetVertex(vertices[1]);
double * coords1 = mesh.GetVertex(vertices[0]);
double * coords2 = mesh.GetVertex(vertices[1]);
Vector center(2);
center(0) = 0.5*(coords1[0] + coords2[0]);
@@ -339,7 +337,7 @@ int main(int argc, char *argv[])
ElasticitySolver->SetupFEM();
Vector center(2); center(0) = 2.9; center(1) = 0.5;
Vector force(2); force(0) = 0.0; force(1) = -1.0;
real_t r = 0.05;
double r = 0.05;
VolumeForceCoefficient vforce_cf(r,center,force);
ElasticitySolver->SetRHSCoefficient(&vforce_cf);
ElasticitySolver->SetEssentialBoundary(ess_bdr);
@@ -380,8 +378,8 @@ int main(int argc, char *argv[])
ParLinearForm vol_form(&control_fes);
vol_form.AddDomainIntegrator(new DomainLFIntegrator(one));
vol_form.Assemble();
real_t domain_volume = vol_form(onegf);
const real_t target_volume = domain_volume * vol_fraction;
double domain_volume = vol_form(onegf);
const double target_volume = domain_volume * vol_fraction;
// 10. Connect to GLVis. Prepare for VisIt output.
char vishost[] = "localhost";
@@ -412,7 +410,7 @@ int main(int argc, char *argv[])
// 11. Iterate:
for (int k = 1; k <= max_it; k++)
{
if (k > 1) { alpha *= ((real_t) k) / ((real_t) k-1); }
if (k > 1) { alpha *= ((double) k) / ((double) k-1); }
if (myid == 0)
{
@@ -452,16 +450,15 @@ int main(int argc, char *argv[])
// Step 5 - Update design variable ψ ← proj(ψ - αG)
psi.Add(-alpha, grad);
const real_t material_volume = proj(psi, target_volume);
const double material_volume = proj(psi, target_volume);
// Compute ||ρ - ρ_old|| in control fes.
real_t norm_increment = zerogf.ComputeL1Error(succ_diff_rho);
real_t norm_reduced_gradient = norm_increment/alpha;
double norm_increment = zerogf.ComputeL1Error(succ_diff_rho);
double norm_reduced_gradient = norm_increment/alpha;
psi_old = psi;
real_t compliance = (*(ElasticitySolver->GetLinearForm()))(u);
MPI_Allreduce(MPI_IN_PLACE, &compliance, 1, MPITypeMap<real_t>::mpi_type,
MPI_SUM, MPI_COMM_WORLD);
double compliance = (*(ElasticitySolver->GetLinearForm()))(u);
MPI_Allreduce(MPI_IN_PLACE,&compliance,1,MPI_DOUBLE,MPI_SUM,MPI_COMM_WORLD);
if (myid == 0)
{
mfem::out << "norm of the reduced gradient = " << norm_reduced_gradient << endl;
@@ -483,7 +480,7 @@ int main(int argc, char *argv[])
{
rho_gf.ProjectCoefficient(rho);
paraview_dc.SetCycle(k);
paraview_dc.SetTime((real_t)k);
paraview_dc.SetTime((double)k);
paraview_dc.Save();
}
+12 -12
View File
@@ -46,7 +46,7 @@ enum class IntegrationType { Volumetric1D, Surface2D, Volumetric2D,
IntegrationType itype;
/// @brief Level-set function defining the implicit interface
real_t lvlset(const Vector& X)
double lvlset(const Vector& X)
{
switch (itype)
{
@@ -66,7 +66,7 @@ real_t lvlset(const Vector& X)
}
/// @brief Function that should be integrated
real_t integrand(const Vector& X)
double integrand(const Vector& X)
{
switch (itype)
{
@@ -86,7 +86,7 @@ real_t integrand(const Vector& X)
}
/// @brief Analytic surface integral
real_t Surface()
double Surface()
{
switch (itype)
{
@@ -106,7 +106,7 @@ real_t Surface()
}
/// @brief Analytic volume integral over subdomain with positive level-set
real_t Volume()
double Volume()
{
switch (itype)
{
@@ -424,7 +424,7 @@ public:
for (int ip = 0; ip < SIntRule->GetNPoints(); ip++)
{
Tr.SetIntPoint((&(SIntRule->IntPoint(ip))));
real_t val = Tr.Weight() * Q.Eval(Tr, SIntRule->IntPoint(ip));
double val = Tr.Weight() * Q.Eval(Tr, SIntRule->IntPoint(ip));
el.CalcShape(SIntRule->IntPoint(ip), shape);
add(elvect, SIntRule->IntPoint(ip).weight * val, shape, elvect);
}
@@ -492,7 +492,7 @@ public:
for (int ip = 0; ip < CIntRule->GetNPoints(); ip++)
{
Tr.SetIntPoint((&(CIntRule->IntPoint(ip))));
real_t val = Tr.Weight()
double val = Tr.Weight()
* Q.Eval(Tr, CIntRule->IntPoint(ip));
el.CalcPhysShape(Tr, shape);
add(elvect, CIntRule->IntPoint(ip).weight * val, shape, elvect);
@@ -504,8 +504,8 @@ public:
int main(int argc, char *argv[])
{
#ifndef MFEM_USE_LAPACK
cout << "MFEM must be built with LAPACK for this example." << endl;
return MFEM_SKIP_RETURN_VALUE;
cout << "MFEM must be build with LAPACK for this example." << endl;
return EXIT_FAILURE;
#else
// 1. Parse he command-line options.
int ref_levels = 3;
@@ -636,11 +636,11 @@ int main(int argc, char *argv[])
cout << "Mesh size dx: ";
if (itype != IntegrationType::Volumetric1D)
{
cout << 3.2 / pow(2., (real_t)ref_levels) << endl;
cout << 3.2 / pow(2., (double)ref_levels) << endl;
}
else
{
cout << .25 / pow(2., (real_t)ref_levels) << endl;
cout << .25 / pow(2., (double)ref_levels) << endl;
}
if (itype == IntegrationType::Surface2D
|| itype == IntegrationType::Volumetric2D)
@@ -652,7 +652,7 @@ int main(int argc, char *argv[])
cout << "============================================" << endl;
cout << "Computed value of surface integral: " << surface.Sum() << endl;
cout << "True value of surface integral: " << Surface() << endl;
cout << "Absolute Error (Surface): ";
cout << "Absolut Error (Surface): ";
cout << abs(surface.Sum() - Surface()) << endl;
cout << "Relative Error (Surface): ";
cout << abs(surface.Sum() - Surface()) / Surface() << endl;
@@ -663,7 +663,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 << "Absolut Error (Volume): ";
cout << abs(volume.Sum() - Volume()) << endl;
cout << "Relative Error (Volume): ";
cout << abs(volume.Sum() - Volume()) / Volume() << endl;
-285
View File
@@ -1,285 +0,0 @@
// MFEM Example 39
//
// Compile with: make ex39
//
// Sample runs: ex39
// ex39 -ess "Southern Boundary"
// ex39 -src Base
//
// Description: This example code demonstrates the use of named attribute
// sets in MFEM to specify material regions, boundary regions,
// or source regions by name rather than attribute numbers. It
// also demonstrates how new named attribute sets may be created
// from arbitrary groupings of attribute numbers and used as a
// convenient shorthand to refer to those groupings in other
// portions of the application or through the command line.
//
// The particular problem being solved here is nearly the same
// as that in example 1 i.e. a simple finite element
// discretization of the Laplace problem -Delta u = 1 with
// homogeneous Dirichlet boundary conditions and, in this case,
// an inhomogeneous diffusion coefficient. The diffusion
// coefficient is given a small default value throughout the
// domain which is increased by two separate amounts in two named
// regions.
//
// This example makes use of a specific input mesh, "compass.msh",
// containing named domain and boundary regions generated by Gmsh
// and stored in their "msh" format (version 2.2). This file
// defines eight boundary regions corresponding to eight compass
// headings; "ENE", "NNE", "NNW", "WSW", "SSW", "SSE", and "ESE".
// It also defines nine domain regions; "Base", "N Even", "N Odd",
// "W Even", "W Odd", "S Even", "S Odd", "E Even", and "E Odd".
// These regions split the four compass pointers into two halves
// each and also label the remaining elements as "Base". Starting
// with these named regions we test the construction of named
// sets as well as reading and writing these named groupings from
// and to mesh files.
//
// The example highlights the use of named attribute sets for
// both subdomains and boundaries in different contexts as well
// as basic methods to create named sets from existing attributes.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
const char *mesh_file = "../data/compass.msh";
int order = 1;
string source_name = "Rose Even";
string ess_name = "Boundary";
bool visualization = true;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree) or -1 for"
" isoparametric space.");
args.AddOption(&source_name,"-src","--source-attr-name",
"Name of attribute set containing source.");
args.AddOption(&ess_name,"-ess","--ess-attr-name",
"Name of attribute set containing essential BC.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.ParseCheck();
// 2. Read the mesh from the given mesh file. We can handle triangular,
// quadrilateral, tetrahedral, hexahedral, surface and volume meshes with
// the same code.
Mesh mesh(mesh_file, 1, 1);
int dim = mesh.Dimension();
// 3. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement. We choose 'ref_levels' to be the
// largest number that gives a final mesh with no more than 50,000
// elements.
{
int ref_levels =
(int)floor(log(50000./mesh.GetNE())/log(2.)/dim);
for (int l = 0; l < ref_levels; l++)
{
mesh.UniformRefinement();
}
}
// 4a. Display attribute set names contained in the initial mesh
AttributeSets &attr_sets = mesh.attribute_sets;
AttributeSets &bdr_attr_sets = mesh.bdr_attribute_sets;
{
std::set<string> names = attr_sets.GetAttributeSetNames();
cout << "Element Attribute Set Names: ";
for (auto const &set_name : names)
{
cout << " \"" << set_name << "\"";
}
cout << endl;
std::set<string> bdr_names = bdr_attr_sets.GetAttributeSetNames();
cout << "Boundary Attribute Set Names: ";
for (auto const &bdr_set_name : bdr_names)
{
cout << " \"" << bdr_set_name << "\"";
}
cout << endl;
}
// 4b. Define new regions based on existing attribute sets
{
Array<int> & Na = attr_sets.GetAttributeSet("N Even");
Array<int> & Nb = attr_sets.GetAttributeSet("N Odd");
Array<int> & Sa = attr_sets.GetAttributeSet("S Even");
Array<int> & Sb = attr_sets.GetAttributeSet("S Odd");
Array<int> & Ea = attr_sets.GetAttributeSet("E Even");
Array<int> & Eb = attr_sets.GetAttributeSet("E Odd");
Array<int> & Wa = attr_sets.GetAttributeSet("W Even");
Array<int> & Wb = attr_sets.GetAttributeSet("W Odd");
// Create a new set spanning the North point
attr_sets.SetAttributeSet("North", Na);
attr_sets.AddToAttributeSet("North", Nb);
// Create a new set spanning the South point
attr_sets.SetAttributeSet("South", Sa);
attr_sets.AddToAttributeSet("South", Sb);
// Create a new set spanning the East point
attr_sets.SetAttributeSet("East", Ea);
attr_sets.AddToAttributeSet("East", Eb);
// Create a new set spanning the West point
attr_sets.SetAttributeSet("West", Wa);
attr_sets.AddToAttributeSet("West", Wb);
// Create a new set consisting of the "a" sides of the compass rose
attr_sets.SetAttributeSet("Rose Even", Na);
attr_sets.AddToAttributeSet("Rose Even", Sa);
attr_sets.AddToAttributeSet("Rose Even", Ea);
attr_sets.AddToAttributeSet("Rose Even", Wa);
// Create a new set consisting of the "b" sides of the compass rose
attr_sets.SetAttributeSet("Rose Odd", Nb);
attr_sets.AddToAttributeSet("Rose Odd", Sb);
attr_sets.AddToAttributeSet("Rose Odd", Eb);
attr_sets.AddToAttributeSet("Rose Odd", Wb);
// Create a new set consisting of the full compass rose
Array<int> & Ra = attr_sets.GetAttributeSet("Rose Even");
Array<int> & Rb = attr_sets.GetAttributeSet("Rose Odd");
attr_sets.SetAttributeSet("Rose", Ra);
attr_sets.AddToAttributeSet("Rose", Rb);
}
// 4c. Define new boundary regions based on existing boundary attribute sets
{
Array<int> & NNE = bdr_attr_sets.GetAttributeSet("NNE");
Array<int> & NNW = bdr_attr_sets.GetAttributeSet("NNW");
Array<int> & ENE = bdr_attr_sets.GetAttributeSet("ENE");
Array<int> & ESE = bdr_attr_sets.GetAttributeSet("ESE");
Array<int> & SSE = bdr_attr_sets.GetAttributeSet("SSE");
Array<int> & SSW = bdr_attr_sets.GetAttributeSet("SSW");
Array<int> & WNW = bdr_attr_sets.GetAttributeSet("WNW");
Array<int> & WSW = bdr_attr_sets.GetAttributeSet("WSW");
bdr_attr_sets.SetAttributeSet("Northern Boundary", NNE);
bdr_attr_sets.AddToAttributeSet("Northern Boundary", NNW);
bdr_attr_sets.SetAttributeSet("Southern Boundary", SSE);
bdr_attr_sets.AddToAttributeSet("Southern Boundary", SSW);
bdr_attr_sets.SetAttributeSet("Eastern Boundary", ENE);
bdr_attr_sets.AddToAttributeSet("Eastern Boundary", ESE);
bdr_attr_sets.SetAttributeSet("Western Boundary", WNW);
bdr_attr_sets.AddToAttributeSet("Western Boundary", WSW);
bdr_attr_sets.SetAttributeSet("Boundary",
bdr_attr_sets.GetAttributeSet
("Northern Boundary"));
bdr_attr_sets.AddToAttributeSet("Boundary",
bdr_attr_sets.GetAttributeSet
("Southern Boundary"));
bdr_attr_sets.AddToAttributeSet("Boundary",
bdr_attr_sets.GetAttributeSet
("Eastern Boundary"));
bdr_attr_sets.AddToAttributeSet("Boundary",
bdr_attr_sets.GetAttributeSet
("Western Boundary"));
}
// 5. Define a finite element space on the mesh. Here we use continuous
// Lagrange finite elements of the specified order.
H1_FECollection fec(order, mesh.Dimension());
FiniteElementSpace fespace(&mesh, &fec);
cout << "Number of finite element unknowns: "
<< fespace.GetTrueVSize() << endl;
// 6. Determine the list of true (i.e. conforming) essential boundary dofs.
// In this example, the boundary conditions are defined by marking all
// the boundary regions corresponding to the boundary attributes
// contained in the set named "ess_name" as essential (Dirichlet) and
// converting them to a list of true dofs.
Array<int> ess_tdof_list;
if (bdr_attr_sets.AttributeSetExists(ess_name))
{
Array<int> ess_bdr_marker = bdr_attr_sets.GetAttributeSetMarker(ess_name);
fespace.GetEssentialTrueDofs(ess_bdr_marker, ess_tdof_list);
}
// 7. Set up the linear form b(.) which corresponds to the right-hand side of
// the FEM linear system, which in this case is (1_s,phi_i) where phi_i
// are the basis functions in fespace and 1_s is an indicator function
// equal to 1 on the region defined by the named set "source_name" and
// zero elsewhere.
Array<int> source_marker = attr_sets.GetAttributeSetMarker(source_name);
LinearForm b(&fespace);
ConstantCoefficient one(1.0);
b.AddDomainIntegrator(new DomainLFIntegrator(one), source_marker);
b.Assemble();
// 8. Define the solution vector x as a finite element grid function
// corresponding to fespace. Initialize x with initial guess of zero,
// which satisfies the boundary conditions.
GridFunction x(&fespace);
x = 0.0;
// 9. Set up the bilinear form a(.,.) on the finite element space
// corresponding to the Laplacian operator -Delta, by adding the
// Diffusion domain integrator.
BilinearForm a(&fespace);
ConstantCoefficient defaultCoef(1.0e-6);
ConstantCoefficient baseCoef(1.0);
ConstantCoefficient roseCoef(2.0);
Array<int> base_marker = attr_sets.GetAttributeSetMarker("Base");
Array<int> rose_marker = attr_sets.GetAttributeSetMarker("Rose Even");
// Impose a very small diffusion coefficient across the entire mesh
a.AddDomainIntegrator(new DiffusionIntegrator(defaultCoef));
// Impose an additional, stronger diffusion coefficient in select regions
a.AddDomainIntegrator(new DiffusionIntegrator(baseCoef), base_marker);
a.AddDomainIntegrator(new DiffusionIntegrator(roseCoef), rose_marker);
// 10. Assemble the bilinear form and the corresponding linear system,
// applying any necessary transformations.
a.Assemble();
SparseMatrix A;
Vector B, X;
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B);
cout << "Size of linear system: " << A.Height() << endl;
// 11. Solve the system using PCG with symmetric Gauss-Seidel preconditioner.
GSSmoother M(A);
PCG(A, M, B, X, 1, 800, 1e-12, 0.0);
// 12. Recover the solution as a finite element grid function.
a.RecoverFEMSolution(X, b, x);
// 13. Save the refined mesh and the solution. This output can be viewed
// later using GLVis: "glvis -m refined.mesh -g sol.gf".
mesh.Save("refined.mesh");
x.Save("sol.gf");
// 14. Send the solution by socket to a GLVis server.
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock(vishost, visport);
sol_sock.precision(8);
sol_sock << "solution\n" << mesh << x << "keys Rjmm" << flush;
}
return 0;
}
-314
View File
@@ -1,314 +0,0 @@
// MFEM Example 39 - Parallel Version
//
// Compile with: make ex39p
//
// Sample runs: mpirun -np 4 ex39p
// mpirun -np 4 ex39p -ess "Southern Boundary"
// mpirun -np 4 ex39p -src Base
//
// Description: This example code demonstrates the use of named attribute
// sets in MFEM to specify material regions, boundary regions,
// or source regions by name rather than attribute numbers. It
// also demonstrates how new named attribute sets may be created
// from arbitrary groupings of attribute numbers and used as a
// convenient shorthand to refer to those groupings in other
// portions of the application or through the command line.
//
// The particular problem being solved here is nearly the same
// as that in example 1 i.e. a simple finite element
// discretization of the Laplace problem -Delta u = 1 with
// homogeneous Dirichlet boundary conditions and, in this case,
// an inhomogeneous diffusion coefficient. The diffusion
// coefficient is given a small default value throughout the
// domain which is increased by two separate amounts in two named
// regions.
//
// This example makes use of a specific input mesh, "compass.msh",
// containing named domain and boundary regions generated by Gmsh
// and stored in their "msh" format (version 2.2). This file
// defines eight boundary regions corresponding to eight compass
// headings; "ENE", "NNE", "NNW", "WSW", "SSW", "SSE", and "ESE".
// It also defines nine domain regions; "Base", "N Even", "N Odd",
// "W Even", "W Odd", "S Even", "S Odd", "E Even", and "E Odd".
// These regions split the four compass pointers into two halves
// each and also label the remaining elements as "Base". Starting
// with these named regions we test the construction of named
// sets as well as reading and writing these named groupings from
// and to mesh files.
//
// The example highlights the use of named attribute sets for
// both subdomains and boundaries in different contexts as well
// as basic methods to create named sets from existing attributes.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
int main(int argc, char *argv[])
{
// 1. Initialize MPI and HYPRE.
Mpi::Init();
Hypre::Init();
// 2. Parse command-line options.
const char *mesh_file = "../data/compass.msh";
int order = 1;
string source_name = "Rose Even";
string ess_name = "Boundary";
bool visualization = true;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree) or -1 for"
" isoparametric space.");
args.AddOption(&source_name,"-src","--source-attr-name",
"Name of attribute set containing source.");
args.AddOption(&ess_name,"-ess","--ess-attr-name",
"Name of attribute set containing essential BC.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.ParseCheck();
// 3. Read the serial mesh from the given mesh file.
Mesh mesh(mesh_file, 1, 1);
int dim = mesh.Dimension();
// 4. Refine the serial mesh on all processors to increase the resolution. In
// this example we do 'ref_levels' of uniform refinement. We choose
// 'ref_levels' to be the largest number that gives a final mesh with no
// more than 10,000 elements.
{
int ref_levels =
(int)floor(log(10000./mesh.GetNE())/log(2.)/dim);
for (int l = 0; l < ref_levels; l++)
{
mesh.UniformRefinement();
}
}
// 5. Define a parallel mesh by a partitioning of the serial mesh. Refine
// this mesh further in parallel to increase the resolution. Once the
// parallel mesh is defined, the serial mesh can be deleted.
ParMesh pmesh(MPI_COMM_WORLD, mesh);
mesh.Clear();
{
int par_ref_levels = 2;
for (int l = 0; l < par_ref_levels; l++)
{
pmesh.UniformRefinement();
}
}
// 6a. Display attribute set names contained in the initial mesh
AttributeSets &attr_sets = pmesh.attribute_sets;
AttributeSets &bdr_attr_sets = pmesh.bdr_attribute_sets;
if (Mpi::Root())
{
std::set<string> names = attr_sets.GetAttributeSetNames();
cout << "Element Attribute Set Names: ";
for (auto const &set_name : names)
{
cout << " \"" << set_name << "\"";
}
cout << endl;
std::set<string> bdr_names = bdr_attr_sets.GetAttributeSetNames();
cout << "Boundary Attribute Set Names: ";
for (auto const &bdr_set_name : bdr_names)
{
cout << " \"" << bdr_set_name << "\"";
}
cout << endl;
}
// 6b. Define new regions based on existing attribute sets
{
Array<int> & Na = attr_sets.GetAttributeSet("N Even");
Array<int> & Nb = attr_sets.GetAttributeSet("N Odd");
Array<int> & Sa = attr_sets.GetAttributeSet("S Even");
Array<int> & Sb = attr_sets.GetAttributeSet("S Odd");
Array<int> & Ea = attr_sets.GetAttributeSet("E Even");
Array<int> & Eb = attr_sets.GetAttributeSet("E Odd");
Array<int> & Wa = attr_sets.GetAttributeSet("W Even");
Array<int> & Wb = attr_sets.GetAttributeSet("W Odd");
// Create a new set spanning the North point
attr_sets.SetAttributeSet("North", Na);
attr_sets.AddToAttributeSet("North", Nb);
// Create a new set spanning the South point
attr_sets.SetAttributeSet("South", Sa);
attr_sets.AddToAttributeSet("South", Sb);
// Create a new set spanning the East point
attr_sets.SetAttributeSet("East", Ea);
attr_sets.AddToAttributeSet("East", Eb);
// Create a new set spanning the West point
attr_sets.SetAttributeSet("West", Wa);
attr_sets.AddToAttributeSet("West", Wb);
// Create a new set consisting of the "a" sides of the compass rose
attr_sets.SetAttributeSet("Rose Even", Na);
attr_sets.AddToAttributeSet("Rose Even", Sa);
attr_sets.AddToAttributeSet("Rose Even", Ea);
attr_sets.AddToAttributeSet("Rose Even", Wa);
// Create a new set consisting of the "b" sides of the compass rose
attr_sets.SetAttributeSet("Rose Odd", Nb);
attr_sets.AddToAttributeSet("Rose Odd", Sb);
attr_sets.AddToAttributeSet("Rose Odd", Eb);
attr_sets.AddToAttributeSet("Rose Odd", Wb);
// Create a new set consisting of the full compass rose
Array<int> & Ra = attr_sets.GetAttributeSet("Rose Even");
Array<int> & Rb = attr_sets.GetAttributeSet("Rose Odd");
attr_sets.SetAttributeSet("Rose", Ra);
attr_sets.AddToAttributeSet("Rose", Rb);
}
// 6c. Define new boundary regions based on existing boundary attribute sets
{
Array<int> & NNE = bdr_attr_sets.GetAttributeSet("NNE");
Array<int> & NNW = bdr_attr_sets.GetAttributeSet("NNW");
Array<int> & ENE = bdr_attr_sets.GetAttributeSet("ENE");
Array<int> & ESE = bdr_attr_sets.GetAttributeSet("ESE");
Array<int> & SSE = bdr_attr_sets.GetAttributeSet("SSE");
Array<int> & SSW = bdr_attr_sets.GetAttributeSet("SSW");
Array<int> & WNW = bdr_attr_sets.GetAttributeSet("WNW");
Array<int> & WSW = bdr_attr_sets.GetAttributeSet("WSW");
bdr_attr_sets.SetAttributeSet("Northern Boundary", NNE);
bdr_attr_sets.AddToAttributeSet("Northern Boundary", NNW);
bdr_attr_sets.SetAttributeSet("Southern Boundary", SSE);
bdr_attr_sets.AddToAttributeSet("Southern Boundary", SSW);
bdr_attr_sets.SetAttributeSet("Eastern Boundary", ENE);
bdr_attr_sets.AddToAttributeSet("Eastern Boundary", ESE);
bdr_attr_sets.SetAttributeSet("Western Boundary", WNW);
bdr_attr_sets.AddToAttributeSet("Western Boundary", WSW);
bdr_attr_sets.SetAttributeSet("Boundary",
bdr_attr_sets.GetAttributeSet
("Northern Boundary"));
bdr_attr_sets.AddToAttributeSet("Boundary",
bdr_attr_sets.GetAttributeSet
("Southern Boundary"));
bdr_attr_sets.AddToAttributeSet("Boundary",
bdr_attr_sets.GetAttributeSet
("Eastern Boundary"));
bdr_attr_sets.AddToAttributeSet("Boundary",
bdr_attr_sets.GetAttributeSet
("Western Boundary"));
}
// 7. Define a parallel finite element space on the parallel mesh. Here we
// use continuous Lagrange finite elements of the specified order. If
// order < 1, we instead use an isoparametric/isogeometric space.
H1_FECollection fec(order, dim);
ParFiniteElementSpace fespace(&pmesh, &fec);
HYPRE_BigInt size = fespace.GlobalTrueVSize();
if (Mpi::Root())
{
cout << "Number of finite element unknowns: " << size << endl;
}
// 8. Determine the list of true (i.e. parallel conforming) essential
// boundary dofs. In this example, the boundary conditions are defined
// by marking all the boundary regions corresponding to the boundary
// attributes contained in the set named "ess_name" as essential
// (Dirichlet) and converting them to a list of true dofs.
Array<int> ess_tdof_list;
if (bdr_attr_sets.AttributeSetExists(ess_name))
{
Array<int> ess_bdr_marker = bdr_attr_sets.GetAttributeSetMarker(ess_name);
fespace.GetEssentialTrueDofs(ess_bdr_marker, ess_tdof_list);
}
// 9. Set up the parallel linear form b(.) which corresponds to the
// right-hand side of the FEM linear system, which in this case is
// (1_s,phi_i) where phi_i are the basis functions in fespace and 1_s
// is an indicator function equal to 1 on the region defined by the
// named set "source_name" and zero elsewhere.
Array<int> source_marker = attr_sets.GetAttributeSetMarker(source_name);
ParLinearForm b(&fespace);
ConstantCoefficient one(1.0);
b.AddDomainIntegrator(new DomainLFIntegrator(one), source_marker);
b.Assemble();
// 10. Define the solution vector x as a parallel finite element grid
// function corresponding to fespace. Initialize x with initial guess of
// zero, which satisfies the boundary conditions.
ParGridFunction x(&fespace);
x = 0.0;
// 11. Set up the parallel bilinear form a(.,.) on the finite element space
// corresponding to the Laplacian operator -Delta, by adding the
// Diffusion domain integrator.
ParBilinearForm a(&fespace);
ConstantCoefficient defaultCoef(1.0e-6);
ConstantCoefficient baseCoef(1.0);
ConstantCoefficient roseCoef(2.0);
Array<int> base_marker = attr_sets.GetAttributeSetMarker("Base");
Array<int> rose_marker = attr_sets.GetAttributeSetMarker("Rose Even");
// Impose a very small diffusion coefficient across the entire mesh
a.AddDomainIntegrator(new DiffusionIntegrator(defaultCoef));
// Impose an additional, stronger diffusion coefficient in select regions
a.AddDomainIntegrator(new DiffusionIntegrator(baseCoef), base_marker);
a.AddDomainIntegrator(new DiffusionIntegrator(roseCoef), rose_marker);
// 12. Assemble the parallel bilinear form and the corresponding linear
// system, applying any necessary transformations.
a.Assemble();
HypreParMatrix A;
Vector B, X;
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B);
// 13. Solve the system using PCG with hypre's BoomerAMG preconditioner.
HypreBoomerAMG M(A);
CGSolver cg(MPI_COMM_WORLD);
cg.SetRelTol(1e-12);
cg.SetMaxIter(2000);
cg.SetPrintLevel(1);
cg.SetPreconditioner(M);
cg.SetOperator(A);
cg.Mult(B, X);
// 14. Recover the parallel grid function corresponding to X. This is the
// local finite element solution on each processor.
a.RecoverFEMSolution(X, b, x);
// 15. Save the refined mesh and the solution in parallel. This output can
// be viewed later using GLVis: "glvis -np <np> -m mesh -g sol".
pmesh.Save("mesh");
x.Save("sol");
// 16. Send the solution by socket to a GLVis server.
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
int num_procs = Mpi::WorldSize();
int myid = Mpi::WorldRank();
socketstream sol_sock(vishost, visport);
sol_sock << "parallel " << num_procs << " " << myid << "\n";
sol_sock.precision(8);
sol_sock << "solution\n" << pmesh << x << "keys Rjmm" << flush;
}
return 0;
}
+2 -2
View File
@@ -55,7 +55,7 @@ using namespace mfem;
// Exact solution, E, and r.h.s., f. See below for implementation.
void E_exact(const Vector &, Vector &);
void f_exact(const Vector &, Vector &);
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int dim;
int main(int argc, char *argv[])
@@ -263,7 +263,7 @@ int main(int argc, char *argv[])
// 15. Compute and print the L^2 norm of the error.
{
real_t error = x.ComputeL2Error(E);
double error = x.ComputeL2Error(E);
if (myid == 0)
{
cout << "\n|| E_h - E ||_{L^2} = " << error << '\n' << endl;
+8 -8
View File
@@ -54,7 +54,7 @@ using namespace mfem;
// Exact solution, F, and r.h.s., f. See below for implementation.
void F_exact(const Vector &, Vector &);
void f_exact(const Vector &, Vector &);
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int main(int argc, char *argv[])
{
@@ -269,9 +269,9 @@ void F_exact(const Vector &p, Vector &F)
{
int dim = p.Size();
real_t x = p(0);
real_t y = p(1);
// real_t z = (dim == 3) ? p(2) : 0.0; // Uncomment if F is changed to depend on z
double x = p(0);
double y = p(1);
// double z = (dim == 3) ? p(2) : 0.0; // Uncomment if F is changed to depend on z
F(0) = cos(kappa*x)*sin(kappa*y);
F(1) = cos(kappa*y)*sin(kappa*x);
@@ -286,11 +286,11 @@ void f_exact(const Vector &p, Vector &f)
{
int dim = p.Size();
real_t x = p(0);
real_t y = p(1);
// real_t z = (dim == 3) ? p(2) : 0.0; // Uncomment if f is changed to depend on z
double x = p(0);
double y = p(1);
// double z = (dim == 3) ? p(2) : 0.0; // Uncomment if f is changed to depend on z
real_t temp = 1 + 2*kappa*kappa;
double temp = 1 + 2*kappa*kappa;
f(0) = temp*cos(kappa*x)*sin(kappa*y);
f(1) = temp*cos(kappa*y)*sin(kappa*x);
-411
View File
@@ -1,411 +0,0 @@
// MFEM Example 40
//
// Compile with: make ex40
//
// Sample runs: ex40 -o 2
// ex40 -o 2 -r 4
//
// Description: This example code demonstrates to how to use MFEM to solve
// the MongeAmpère equation
//
// det(∇²u) = f in Ω, u = 0 on ∂Ω.
//
// This example highlights the ExponentialMatrixCoefficient
// class, which is used in Newton's method to solve the
// variational formulation
//
// Find M ∈ H₀(div,Ω)ⁿ and u ∈ H₀¹(Ω) such that
// (exp(M), N) + (∇u, ∇⋅N) = 0 ∀ N ∈ H₀(div,Ω)ⁿ
// (tr(M), v) = (ln f, v) ∀ v ∈ H₀¹(Ω)
//
// where n is the spatial dimension of the domain Ω.
//
//
// The linearized subproblem is
//
// Find δM ∈ H₀(div,Ω)ⁿ and u ∈ H₀¹(Ω) such that
// (exp(M) δM, N) + (∇u, ∇⋅N) = -(exp(M), N) ∀ N ∈ H₀(div,Ω)ⁿ
// (tr(δM), v) = (ln f - tr(M), v) ∀ v ∈ H₀¹(Ω)
//
//
// (exp(M) δM, N) ::: VectorFEMassIntegrator
// (∇u, ∇⋅N) ::: MixedGradDivIntegrator
// (tr(δM), v) ::: MixedDotProductIntegrator
// (exp(M), N) ::: VectorFEDomainLFIntegrator
// (ln f - tr(M), v) ::: DomainLFIntegrator
//
//
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
real_t exact_solution(const Vector &pt);
void exact_solution_gradient(const Vector &pt, Vector &grad);
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
const char *mesh_file = "../data/disc-nurbs.mesh";
// const char *mesh_file = "../data/star.mesh";
int order = 2;
int max_it = 10;
int ref_levels = 1;
real_t tol = 1e-5;
bool visualization = true;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&ref_levels, "-r", "--refs",
"Number of h-refinements.");
args.AddOption(&max_it, "-mi", "--max-it",
"Maximum number of iterations");
args.AddOption(&tol, "-tol", "--tol",
"Stopping criteria based on the difference between"
"successive solution updates");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
// 2. Read the mesh from the mesh file.
Mesh mesh(mesh_file, 1, 1);
int dim = mesh.Dimension();
if (dim != 2)
{
MFEM_ABORT("Example 40 currently only supports 2D problems")
}
// 3. Postprocess the mesh.
// 3A. Refine the mesh to increase the resolution.
for (int l = 0; l < ref_levels; l++)
{
mesh.UniformRefinement();
}
// 3B. Interpolate the geometry after refinement to control geometry error.
// NOTE: Minimum second-order interpolation is used to improve the accuracy.
int curvature_order = max(order,2);
mesh.SetCurvature(curvature_order);
// 4. Define the necessary finite element spaces on the mesh.
H1_FECollection H1fec(order, dim);
FiniteElementSpace H1fes(&mesh, &H1fec);
RT_FECollection RTfec(order-1, dim);
FiniteElementSpace RTfes(&mesh, &RTfec);
cout << "Number of H¹ degrees of freedom: "
<< H1fes.GetTrueVSize() << endl;
cout << "Number of H(div) degrees of freedom: "
<< RTfes.GetTrueVSize() * dim << endl;
Array<int> offsets(4);
offsets[0] = 0;
offsets[1] = RTfes.GetVSize();
offsets[2] = RTfes.GetVSize();
offsets[3] = H1fes.GetVSize();
offsets.PartialSum();
BlockVector x(offsets), rhs(offsets);
x = 0.0; rhs = 0.0;
// 5. Determine the list of true (i.e., conforming) essential boundary dofs.
Array<int> ess_bdr;
if (mesh.bdr_attributes.Size())
{
ess_bdr.SetSize(mesh.bdr_attributes.Max());
ess_bdr = 1;
}
// 6. Define constants to be used later.
ConstantCoefficient one(1.0);
ConstantCoefficient neg_one(-1.0);
ConstantCoefficient zero(0.0);
Vector V1(2), V2(2);
V1(0) = 1.0; V1(1) = 0.0;
V2(0) = 0.0; V2(1) = 1.0;
VectorConstantCoefficient onezero(V1);
VectorConstantCoefficient zeroone(V2);
ScalarVectorProductCoefficient neg_onezero(-1.0, onezero);
ScalarVectorProductCoefficient neg_zeroone(-1.0, zeroone);
// 7. Define the solution vectors as finite element grid functions
// corresponding to the fespaces.
GridFunction delta_M1_gf, delta_M2_gf, delta_u_gf;
delta_M1_gf.MakeRef(&RTfes,x,offsets[0]);
delta_M2_gf.MakeRef(&RTfes,x,offsets[1]);
delta_u_gf.MakeRef(&H1fes,x,offsets[2]);
GridFunction M1_gf(&RTfes);
GridFunction M2_gf(&RTfes);
GridFunction u_gf(&H1fes);
// 8. Define the function coefficients for the solution and use them to
// initialize the initial guess
FunctionCoefficient exact_coef(exact_solution);
VectorFunctionCoefficient exact_grad_coef(dim,exact_solution_gradient);
ConstantCoefficient ln_rhs_coef(0.0);
u_gf.ProjectCoefficient(exact_coef);
// u_gf.ProjectCoefficient(zero);
M1_gf = 0.0;
M2_gf = 0.0;
delta_M1_gf = 0.0;
delta_M2_gf = 0.0;
delta_u_gf = 0.0;
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock;
if (visualization)
{
sol_sock.open(vishost,visport);
sol_sock.precision(8);
}
// 10. Iterate
int k;
for (k = 0; k < max_it; k++)
{
mfem::out << "\nITERATION " << k+1 << endl;
LinearForm b0,b1,b2;
b0.Update(&RTfes,rhs.GetBlock(0),0);
b1.Update(&RTfes,rhs.GetBlock(1),0);
b2.Update(&H1fes,rhs.GetBlock(2),0);
VectorGridFunctionCoefficient M1(&M1_gf);
VectorGridFunctionCoefficient M2(&M2_gf);
MatrixArrayVectorCoefficient M(dim);
M.Set(0, &M1, false);
M.Set(1, &M2, false);
ExponentialMatrixCoefficient exp_M(M);
MatrixVectorProductCoefficient exp_M1(exp_M, onezero);
MatrixVectorProductCoefficient exp_M2(exp_M, zeroone);
InnerProductCoefficient exp_M11(exp_M1, onezero);
InnerProductCoefficient exp_M12(exp_M1, zeroone);
InnerProductCoefficient exp_M21(exp_M2, onezero);
InnerProductCoefficient exp_M22(exp_M2, zeroone);
GradientGridFunctionCoefficient grad_u(&u_gf);
InnerProductCoefficient neg_dudx(neg_onezero, grad_u);
ScalarVectorProductCoefficient neg_exp_M1(-1.0, exp_M1);
b0.AddDomainIntegrator(new VectorFEDomainLFDivIntegrator(neg_dudx));
b0.AddDomainIntegrator(new VectorFEDomainLFIntegrator(neg_exp_M1));
b0.Assemble();
InnerProductCoefficient neg_dudy(neg_zeroone, grad_u);
b1.AddDomainIntegrator(new VectorFEDomainLFDivIntegrator(neg_dudy));
ScalarVectorProductCoefficient neg_exp_M2(-1.0, exp_M2);
b1.AddDomainIntegrator(new VectorFEDomainLFIntegrator(neg_exp_M2));
b1.Assemble();
InnerProductCoefficient M11(M1, onezero);
InnerProductCoefficient M22(M2, zeroone);
SumCoefficient trace_M(M11, M22);
SumCoefficient rhs2(ln_rhs_coef, trace_M, 1.0, -1.0);
b2.AddDomainIntegrator(new DomainLFIntegrator(rhs2));
b2.Assemble();
cout << "b0.Norml2() = " << b0.Norml2() << endl;
cout << "b1.Norml2() = " << b1.Norml2() << endl;
cout << "b2.Norml2() = " << b2.Norml2() << endl;
BilinearForm a00(&RTfes);
a00.AddDomainIntegrator(new VectorFEMassIntegrator());
// a00.AddDomainIntegrator(new VectorFEMassIntegrator(exp_M11));
a00.Assemble();
a00.EliminateEssentialBC(ess_bdr,x.GetBlock(0),rhs.GetBlock(0),mfem::Operator::DIAG_ONE);
a00.Finalize();
SparseMatrix &A00 = a00.SpMat();
BilinearForm a01(&RTfes);
a01.AddDomainIntegrator(new VectorFEMassIntegrator(zero));
// a01.AddDomainIntegrator(new VectorFEMassIntegrator(exp_M12));
a01.Assemble();
a01.EliminateEssentialBC(ess_bdr,mfem::Operator::DIAG_ZERO);
a01.Finalize();
SparseMatrix &A01 = a01.SpMat();
MixedBilinearForm a02(&H1fes,&RTfes);
a02.AddDomainIntegrator(new MixedGradDivIntegrator(neg_onezero));
a02.Assemble(false);
a02.EliminateTrialDofs(ess_bdr,x.GetBlock(2),rhs.GetBlock(0));
a02.EliminateTestDofs(ess_bdr);
a02.Finalize();
SparseMatrix &A02 = a02.SpMat();
BilinearForm a10(&RTfes);
a10.AddDomainIntegrator(new VectorFEMassIntegrator(zero));
// a10.AddDomainIntegrator(new VectorFEMassIntegrator(exp_M21));
a10.Assemble();
a10.EliminateEssentialBC(ess_bdr,mfem::Operator::DIAG_ZERO);
a10.Finalize();
SparseMatrix &A10 = a10.SpMat();
BilinearForm a11(&RTfes);
a11.AddDomainIntegrator(new VectorFEMassIntegrator());
// a11.AddDomainIntegrator(new VectorFEMassIntegrator(exp_M22));
a11.Assemble();
a11.EliminateEssentialBC(ess_bdr,x.GetBlock(1),rhs.GetBlock(1),mfem::Operator::DIAG_ONE);
a11.Finalize();
SparseMatrix &A11 = a11.SpMat();
MixedBilinearForm a12(&H1fes,&RTfes);
a12.AddDomainIntegrator(new MixedGradDivIntegrator(neg_zeroone));
a12.Assemble(false);
a12.EliminateTrialDofs(ess_bdr,x.GetBlock(2),rhs.GetBlock(1));
a12.EliminateTestDofs(ess_bdr);
a12.Finalize();
SparseMatrix &A12 = a12.SpMat();
MixedBilinearForm a20(&RTfes,&H1fes);
a20.AddDomainIntegrator(new MixedDotProductIntegrator(onezero));
a20.Assemble();
a20.EliminateTrialDofs(ess_bdr,x.GetBlock(0),rhs.GetBlock(2));
a20.EliminateTestDofs(ess_bdr);
a20.Finalize();
SparseMatrix &A20 = a20.SpMat();
MixedBilinearForm a21(&RTfes,&H1fes);
a21.AddDomainIntegrator(new MixedDotProductIntegrator(zeroone));
a21.Assemble();
a21.EliminateTrialDofs(ess_bdr,x.GetBlock(1),rhs.GetBlock(2));
a21.EliminateTestDofs(ess_bdr);
a21.Finalize();
SparseMatrix &A21 = a21.SpMat();
BilinearForm a22(&H1fes);
// a22.AddDomainIntegrator(new MassIntegrator(neg_one));
a22.AddDomainIntegrator(new MassIntegrator(zero));
a22.Assemble(false);
a22.EliminateEssentialBC(ess_bdr,x.GetBlock(2),rhs.GetBlock(2),mfem::Operator::DIAG_ONE);
a22.Finalize();
SparseMatrix &A22 = a22.SpMat();
cout << "b0.Norml2() = " << b0.Norml2() << endl;
cout << "b1.Norml2() = " << b1.Norml2() << endl;
cout << "b2.Norml2() = " << b2.Norml2() << endl;
// BlockOperator A(offsets);
// A.SetBlock(0,0,&A00);
// A.SetBlock(0,1,&A01);
// A.SetBlock(0,2,&A02);
// A.SetBlock(1,0,&A10);
// A.SetBlock(1,1,&A11);
// A.SetBlock(1,2,&A12);
// A.SetBlock(2,0,&A20);
// A.SetBlock(2,1,&A21);
// A.SetBlock(2,2,&A22);
// BlockDiagonalPreconditioner prec(offsets);
// prec.SetDiagonalBlock(0,new GSSmoother(A00));
// prec.SetDiagonalBlock(1,new GSSmoother(A11));
// prec.SetDiagonalBlock(1,new GSSmoother(A22));
// prec.owns_blocks = 1;
// GMRES(A,prec,rhs,x,1,10000,500,1e-12,0.0);
BlockMatrix A(offsets);
A.SetBlock(0,0,&A00);
A.SetBlock(0,1,&A01);
A.SetBlock(0,2,&A02);
A.SetBlock(1,0,&A10);
A.SetBlock(1,1,&A11);
A.SetBlock(1,2,&A12);
A.SetBlock(2,0,&A20);
A.SetBlock(2,1,&A21);
A.SetBlock(2,2,&A22);
SparseMatrix * A_mono = A.CreateMonolithic();
UMFPackSolver umf(*A_mono);
umf.Mult(rhs,x);
delta_M1_gf.MakeRef(&RTfes, x.GetBlock(0), 0);
delta_M2_gf.MakeRef(&RTfes, x.GetBlock(1), 0);
delta_u_gf.MakeRef(&H1fes, x.GetBlock(2), 0);
real_t Newton_update_size = delta_u_gf.ComputeL2Error(zero);
real_t gamma = 0.3;
delta_M1_gf *= gamma;
delta_M2_gf *= gamma;
delta_u_gf *= gamma;
M1_gf += delta_M1_gf;
M2_gf += delta_M2_gf;
u_gf += delta_u_gf;
if (visualization)
{
// sol_sock << "solution\n" << mesh << delta_M1_gf << "window_title 'Discrete solution'"
sol_sock << "solution\n" << mesh << u_gf << "window_title 'Discrete solution'"
<< flush;
mfem::out << "Increment (|| uₕ - uₕ_prvs||) = " << Newton_update_size <<
endl;
}
// if (Newton_update_size < tol || k == max_it-1)
// {
// break;
// }
real_t H1_error = u_gf.ComputeH1Error(&exact_coef,&exact_grad_coef);
real_t L2_error = u_gf.ComputeL2Error(exact_coef);
mfem::out << "L2-error (|| u - uₕᵏ||) = " << L2_error << endl;
// mfem::out << "H1-error (|| u - uₕᵏ||) = " << H1_error << endl;
cin.get();
}
mfem::out << "\n Total iterations: " << k+1
<< "\n Total dofs: " << RTfes.GetTrueVSize() * 2 + H1fes.GetTrueVSize()
<< endl;
// 11. Exact solution.
// if (visualization)
// {
// socketstream err_sock(vishost, visport);
// err_sock.precision(8);
// GridFunction error_gf(&H1fes);
// error_gf.ProjectCoefficient(exact_coef);
// error_gf -= u_gf;
// err_sock << "solution\n" << mesh << error_gf << "window_title 'Error'" <<
// flush;
// }
return 0;
}
real_t exact_solution(const Vector &pt)
{
real_t x = pt(0), y = pt(1);
return (x*x + y*y) / 2.0 - 4.0;
}
void exact_solution_gradient(const Vector &pt, Vector &grad)
{
real_t x = pt(0), y = pt(1);
grad(0) = x;
grad(1) = y;
}
+9 -9
View File
@@ -54,7 +54,7 @@ using namespace mfem;
// Exact solution, F, and r.h.s., f. See below for implementation.
void F_exact(const Vector &, Vector &);
void f_exact(const Vector &, Vector &);
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int main(int argc, char *argv[])
{
@@ -255,7 +255,7 @@ int main(int argc, char *argv[])
// 15. Compute and print the L^2 norm of the error.
{
real_t error = x.ComputeL2Error(F);
double error = x.ComputeL2Error(F);
if (myid == 0)
{
cout << "\n|| F_h - F ||_{L^2} = " << error << '\n' << endl;
@@ -311,9 +311,9 @@ void F_exact(const Vector &p, Vector &F)
{
int dim = p.Size();
real_t x = p(0);
real_t y = p(1);
// real_t z = (dim == 3) ? p(2) : 0.0; // Uncomment if F is changed to depend on z
double x = p(0);
double y = p(1);
// double z = (dim == 3) ? p(2) : 0.0; // Uncomment if F is changed to depend on z
F(0) = cos(kappa*x)*sin(kappa*y);
F(1) = cos(kappa*y)*sin(kappa*x);
@@ -328,11 +328,11 @@ void f_exact(const Vector &p, Vector &f)
{
int dim = p.Size();
real_t x = p(0);
real_t y = p(1);
// real_t z = (dim == 3) ? p(2) : 0.0; // Uncomment if f is changed to depend on z
double x = p(0);
double y = p(1);
// double z = (dim == 3) ? p(2) : 0.0; // Uncomment if f is changed to depend on z
real_t temp = 1 + 2*kappa*kappa;
double temp = 1 + 2*kappa*kappa;
f(0) = temp*cos(kappa*x)*sin(kappa*y);
f(1) = temp*cos(kappa*y)*sin(kappa*x);
+18 -18
View File
@@ -45,10 +45,10 @@ using namespace mfem;
// Define the analytical solution and forcing terms / boundary conditions
void uFun_ex(const Vector & x, Vector & u);
real_t pFun_ex(const Vector & x);
double pFun_ex(const Vector & x);
void fFun(const Vector & x, Vector & f);
real_t gFun(const Vector & x);
real_t f_natural(const Vector & x);
double gFun(const Vector & x);
double f_natural(const Vector & x);
int main(int argc, char *argv[])
{
@@ -270,8 +270,8 @@ int main(int argc, char *argv[])
// 11. Solve the linear system with MINRES.
// Check the norm of the unpreconditioned residual.
int maxIter(1000);
real_t rtol(1.e-6);
real_t atol(1.e-10);
double rtol(1.e-6);
double atol(1.e-10);
chrono.Clear();
chrono.Start();
@@ -313,10 +313,10 @@ int main(int argc, char *argv[])
irs[i] = &(IntRules.Get(i, order_quad));
}
real_t err_u = u.ComputeL2Error(ucoeff, irs);
real_t norm_u = ComputeLpNorm(2., ucoeff, *mesh, irs);
real_t err_p = p.ComputeL2Error(pcoeff, irs);
real_t norm_p = ComputeLpNorm(2., pcoeff, *mesh, irs);
double err_u = u.ComputeL2Error(ucoeff, irs);
double norm_u = ComputeLpNorm(2., ucoeff, *mesh, irs);
double err_p = p.ComputeL2Error(pcoeff, irs);
double norm_p = ComputeLpNorm(2., pcoeff, *mesh, irs);
std::cout << "|| u_h - u_ex || / || u_ex || = " << err_u / norm_u << "\n";
std::cout << "|| p_h - p_ex || / || p_ex || = " << err_p / norm_p << "\n";
@@ -391,9 +391,9 @@ int main(int argc, char *argv[])
void uFun_ex(const Vector & x, Vector & u)
{
real_t xi(x(0));
real_t yi(x(1));
real_t zi(0.0);
double xi(x(0));
double yi(x(1));
double zi(0.0);
if (x.Size() == 3)
{
zi = x(2);
@@ -409,11 +409,11 @@ void uFun_ex(const Vector & x, Vector & u)
}
// Change if needed
real_t pFun_ex(const Vector & x)
double pFun_ex(const Vector & x)
{
real_t xi(x(0));
real_t yi(x(1));
real_t zi(0.0);
double xi(x(0));
double yi(x(1));
double zi(0.0);
if (x.Size() == 3)
{
@@ -428,7 +428,7 @@ void fFun(const Vector & x, Vector & f)
f = 0.0;
}
real_t gFun(const Vector & x)
double gFun(const Vector & x)
{
if (x.Size() == 3)
{
@@ -440,7 +440,7 @@ real_t gFun(const Vector & x)
}
}
real_t f_natural(const Vector & x)
double f_natural(const Vector & x)
{
return (-pFun_ex(x));
}
+18 -18
View File
@@ -46,10 +46,10 @@ using namespace mfem;
// Define the analytical solution and forcing terms / boundary conditions
void uFun_ex(const Vector & x, Vector & u);
real_t pFun_ex(const Vector & x);
double pFun_ex(const Vector & x);
void fFun(const Vector & x, Vector & f);
real_t gFun(const Vector & x);
real_t f_natural(const Vector & x);
double gFun(const Vector & x);
double f_natural(const Vector & x);
int main(int argc, char *argv[])
{
@@ -326,8 +326,8 @@ int main(int argc, char *argv[])
// 13. Solve the linear system with MINRES.
// Check the norm of the unpreconditioned residual.
int maxIter(pa ? 1000 : 500);
real_t rtol(1.e-6);
real_t atol(1.e-10);
double rtol(1.e-6);
double atol(1.e-10);
chrono.Clear();
chrono.Start();
@@ -371,10 +371,10 @@ int main(int argc, char *argv[])
irs[i] = &(IntRules.Get(i, order_quad));
}
real_t err_u = u->ComputeL2Error(ucoeff, irs);
real_t norm_u = ComputeGlobalLpNorm(2, ucoeff, *pmesh, irs);
real_t err_p = p->ComputeL2Error(pcoeff, irs);
real_t norm_p = ComputeGlobalLpNorm(2, pcoeff, *pmesh, irs);
double err_u = u->ComputeL2Error(ucoeff, irs);
double norm_u = ComputeGlobalLpNorm(2, ucoeff, *pmesh, irs);
double err_p = p->ComputeL2Error(pcoeff, irs);
double norm_p = ComputeGlobalLpNorm(2, pcoeff, *pmesh, irs);
if (verbose)
{
@@ -493,9 +493,9 @@ int main(int argc, char *argv[])
void uFun_ex(const Vector & x, Vector & u)
{
real_t xi(x(0));
real_t yi(x(1));
real_t zi(0.0);
double xi(x(0));
double yi(x(1));
double zi(0.0);
if (x.Size() == 3)
{
zi = x(2);
@@ -511,11 +511,11 @@ void uFun_ex(const Vector & x, Vector & u)
}
// Change if needed
real_t pFun_ex(const Vector & x)
double pFun_ex(const Vector & x)
{
real_t xi(x(0));
real_t yi(x(1));
real_t zi(0.0);
double xi(x(0));
double yi(x(1));
double zi(0.0);
if (x.Size() == 3)
{
@@ -530,7 +530,7 @@ void fFun(const Vector & x, Vector & f)
f = 0.0;
}
real_t gFun(const Vector & x)
double gFun(const Vector & x)
{
if (x.Size() == 3)
{
@@ -542,7 +542,7 @@ real_t gFun(const Vector & x)
}
}
real_t f_natural(const Vector & x)
double f_natural(const Vector & x)
{
return (-pFun_ex(x));
}
+8 -8
View File
@@ -28,8 +28,8 @@ using namespace std;
using namespace mfem;
// Exact solution and r.h.s., see below for implementation.
real_t analytic_solution(const Vector &x);
real_t analytic_rhs(const Vector &x);
double analytic_solution(const Vector &x);
double analytic_rhs(const Vector &x);
void SnapNodes(Mesh &mesh);
int main(int argc, char *argv[])
@@ -81,7 +81,7 @@ int main(int argc, char *argv[])
if (elem_type == 0) // inscribed octahedron
{
const real_t tri_v[6][3] =
const double tri_v[6][3] =
{
{ 1, 0, 0}, { 0, 1, 0}, {-1, 0, 0},
{ 0, -1, 0}, { 0, 0, 1}, { 0, 0, -1}
@@ -105,7 +105,7 @@ int main(int argc, char *argv[])
}
else // inscribed cube
{
const real_t quad_v[8][3] =
const double quad_v[8][3] =
{
{-1, -1, -1}, {+1, -1, -1}, {+1, +1, -1}, {-1, +1, -1},
{-1, -1, +1}, {+1, -1, +1}, {+1, +1, +1}, {-1, +1, +1}
@@ -249,15 +249,15 @@ int main(int argc, char *argv[])
return 0;
}
real_t analytic_solution(const Vector &x)
double analytic_solution(const Vector &x)
{
real_t l2 = x(0)*x(0) + x(1)*x(1) + x(2)*x(2);
double l2 = x(0)*x(0) + x(1)*x(1) + x(2)*x(2);
return x(0)*x(1)/l2;
}
real_t analytic_rhs(const Vector &x)
double analytic_rhs(const Vector &x)
{
real_t l2 = x(0)*x(0) + x(1)*x(1) + x(2)*x(2);
double l2 = x(0)*x(0) + x(1)*x(1) + x(2)*x(2);
return 7*x(0)*x(1)/l2;
}
+9 -9
View File
@@ -28,8 +28,8 @@ using namespace std;
using namespace mfem;
// Exact solution and r.h.s., see below for implementation.
real_t analytic_solution(const Vector &x);
real_t analytic_rhs(const Vector &x);
double analytic_solution(const Vector &x);
double analytic_rhs(const Vector &x);
void SnapNodes(Mesh &mesh);
int main(int argc, char *argv[])
@@ -101,7 +101,7 @@ int main(int argc, char *argv[])
if (elem_type == 0) // inscribed octahedron
{
const real_t tri_v[6][3] =
const double tri_v[6][3] =
{
{ 1, 0, 0}, { 0, 1, 0}, {-1, 0, 0},
{ 0, -1, 0}, { 0, 0, 1}, { 0, 0, -1}
@@ -125,7 +125,7 @@ int main(int argc, char *argv[])
}
else // inscribed cube
{
const real_t quad_v[8][3] =
const double quad_v[8][3] =
{
{-1, -1, -1}, {+1, -1, -1}, {+1, +1, -1}, {-1, +1, -1},
{-1, -1, +1}, {+1, -1, +1}, {+1, +1, +1}, {-1, +1, +1}
@@ -281,7 +281,7 @@ int main(int argc, char *argv[])
delete b;
// 12. Compute and print the L^2 norm of the error.
real_t error = x.ComputeL2Error(sol_coef);
double error = x.ComputeL2Error(sol_coef);
if (myid == 0)
{
cout << "\nL2 norm of error: " << error << endl;
@@ -323,15 +323,15 @@ int main(int argc, char *argv[])
return 0;
}
real_t analytic_solution(const Vector &x)
double analytic_solution(const Vector &x)
{
real_t l2 = x(0)*x(0) + x(1)*x(1) + x(2)*x(2);
double l2 = x(0)*x(0) + x(1)*x(1) + x(2)*x(2);
return x(0)*x(1)/l2;
}
real_t analytic_rhs(const Vector &x)
double analytic_rhs(const Vector &x)
{
real_t l2 = x(0)*x(0) + x(1)*x(1) + x(2)*x(2);
double l2 = x(0)*x(0) + x(1)*x(1) + x(2)*x(2);
return 7*x(0)*x(1)/l2;
}
+2 -2
View File
@@ -206,7 +206,7 @@ int main(int argc, char *argv[])
SparseMatrix * Shat = RAP(matBhat, matSinv, matBhat);
#ifndef MFEM_USE_SUITESPARSE
const real_t prec_rtol = 1e-3;
const double prec_rtol = 1e-3;
const int prec_maxit = 200;
CGSolver *S0inv = new CGSolver;
S0inv->SetOperator(matS0);
@@ -240,7 +240,7 @@ int main(int argc, char *argv[])
Vector LSres(s_test);
B.Mult(x, LSres);
LSres -= F;
real_t res = sqrt(matSinv.InnerProduct(LSres, LSres));
double res = sqrt(matSinv.InnerProduct(LSres, LSres));
cout << "\n|| B0*x0 + Bhat*xhat - F ||_{S^-1} = " << res << endl;
}
+1 -1
View File
@@ -283,7 +283,7 @@ int main(int argc, char *argv[])
B.Mult(x, LSres);
LSres -= *trueF;
matSinv->Mult(LSres, tmp);
real_t res = sqrt(InnerProduct(LSres, tmp));
double res = sqrt(InnerProduct(LSres, tmp));
if (myid == 0)
{
cout << "\n|| B0*x0 + Bhat*xhat - F ||_{S^-1} = " << res << endl;
+25 -25
View File
@@ -58,10 +58,10 @@ int problem;
void velocity_function(const Vector &x, Vector &v);
// Initial condition
real_t u0_function(const Vector &x);
double u0_function(const Vector &x);
// Inflow boundary condition
real_t inflow_function(const Vector &x);
double inflow_function(const Vector &x);
// Mesh bounding box
Vector bb_min, bb_max;
@@ -72,7 +72,7 @@ private:
SparseMatrix &M, &K, A;
GMRESSolver linear_solver;
BlockILU prec;
real_t dt;
double dt;
public:
DG_Solver(SparseMatrix &M_, SparseMatrix &K_, const FiniteElementSpace &fes)
: M(M_),
@@ -89,7 +89,7 @@ public:
linear_solver.SetPreconditioner(prec);
}
void SetTimeStep(real_t dt_)
void SetTimeStep(double dt_)
{
if (dt_ != dt)
{
@@ -135,7 +135,7 @@ public:
FE_Evolution(BilinearForm &M_, BilinearForm &K_, const Vector &b_);
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k);
virtual ~FE_Evolution();
};
@@ -153,8 +153,8 @@ int main(int argc, char *argv[])
bool fa = false;
const char *device_config = "cpu";
int ode_solver_type = 4;
real_t t_final = 10.0;
real_t dt = 0.01;
double t_final = 10.0;
double dt = 0.01;
bool visualization = true;
bool visit = false;
bool paraview = false;
@@ -293,7 +293,7 @@ int main(int argc, char *argv[])
k.SetAssemblyLevel(AssemblyLevel::FULL);
}
m.AddDomainIntegrator(new MassIntegrator);
constexpr real_t alpha = -1.0;
constexpr double alpha = -1.0;
k.AddDomainIntegrator(new ConvectionIntegrator(velocity, alpha));
k.AddInteriorFaceIntegrator(
new NonconservativeDGTraceIntegrator(velocity, alpha));
@@ -393,14 +393,14 @@ int main(int argc, char *argv[])
// iterations, ti, with a time-step dt).
FE_Evolution adv(m, k, b);
real_t t = 0.0;
double t = 0.0;
adv.SetTime(t);
ode_solver->Init(adv);
bool done = false;
for (int ti = 0; !done; )
{
real_t dt_real = min(dt, t_final - t);
double dt_real = min(dt, t_final - t);
ode_solver->Step(u, t, dt_real);
ti++;
@@ -482,7 +482,7 @@ void FE_Evolution::Mult(const Vector &x, Vector &y) const
M_solver.Mult(z, y);
}
void FE_Evolution::ImplicitSolve(const real_t dt, const Vector &x, Vector &k)
void FE_Evolution::ImplicitSolve(const double dt, const Vector &x, Vector &k)
{
MFEM_VERIFY(dg_solver != NULL,
"Implicit time integration is not supported with partial assembly");
@@ -507,7 +507,7 @@ void velocity_function(const Vector &x, Vector &v)
Vector X(dim);
for (int i = 0; i < dim; i++)
{
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
@@ -529,7 +529,7 @@ void velocity_function(const Vector &x, Vector &v)
case 2:
{
// Clockwise rotation in 2D around the origin
const real_t w = M_PI/2;
const double w = M_PI/2;
switch (dim)
{
case 1: v(0) = 1.0; break;
@@ -541,8 +541,8 @@ void velocity_function(const Vector &x, Vector &v)
case 3:
{
// Clockwise twisting rotation in 2D around the origin
const real_t w = M_PI/2;
real_t d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
const double w = M_PI/2;
double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
d = d*d;
switch (dim)
{
@@ -556,7 +556,7 @@ void velocity_function(const Vector &x, Vector &v)
}
// Initial condition
real_t u0_function(const Vector &x)
double u0_function(const Vector &x)
{
int dim = x.Size();
@@ -564,7 +564,7 @@ real_t u0_function(const Vector &x)
Vector X(dim);
for (int i = 0; i < dim; i++)
{
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
@@ -580,28 +580,28 @@ real_t u0_function(const Vector &x)
case 2:
case 3:
{
real_t rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
if (dim == 3)
{
const real_t s = (1. + 0.25*cos(2*M_PI*X(2)));
const double s = (1. + 0.25*cos(2*M_PI*X(2)));
rx *= s;
ry *= s;
}
return ( std::erfc(w*(X(0)-cx-rx))*std::erfc(-w*(X(0)-cx+rx)) *
std::erfc(w*(X(1)-cy-ry))*std::erfc(-w*(X(1)-cy+ry)) )/16;
return ( erfc(w*(X(0)-cx-rx))*erfc(-w*(X(0)-cx+rx)) *
erfc(w*(X(1)-cy-ry))*erfc(-w*(X(1)-cy+ry)) )/16;
}
}
}
case 2:
{
real_t x_ = X(0), y_ = X(1), rho, phi;
rho = std::hypot(x_, y_);
double x_ = X(0), y_ = X(1), rho, phi;
rho = hypot(x_, y_);
phi = atan2(y_, x_);
return pow(sin(M_PI*rho),2)*sin(3*phi);
}
case 3:
{
const real_t f = M_PI;
const double f = M_PI;
return sin(f*X(0))*sin(f*X(1));
}
}
@@ -609,7 +609,7 @@ real_t u0_function(const Vector &x)
}
// Inflow boundary condition (zero for the problems considered in this example)
real_t inflow_function(const Vector &x)
double inflow_function(const Vector &x)
{
switch (problem)
{
+25 -25
View File
@@ -59,10 +59,10 @@ int problem;
void velocity_function(const Vector &x, Vector &v);
// Initial condition
real_t u0_function(const Vector &x);
double u0_function(const Vector &x);
// Inflow boundary condition
real_t inflow_function(const Vector &x);
double inflow_function(const Vector &x);
// Mesh bounding box
Vector bb_min, bb_max;
@@ -135,7 +135,7 @@ private:
HypreParMatrix *A;
GMRESSolver linear_solver;
Solver *prec;
real_t dt;
double dt;
public:
DG_Solver(HypreParMatrix &M_, HypreParMatrix &K_, const FiniteElementSpace &fes,
PrecType prec_type)
@@ -169,7 +169,7 @@ public:
M.GetDiag(M_diag);
}
void SetTimeStep(real_t dt_)
void SetTimeStep(double dt_)
{
if (dt_ != dt)
{
@@ -224,7 +224,7 @@ public:
PrecType prec_type);
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k);
virtual ~FE_Evolution();
};
@@ -249,8 +249,8 @@ int main(int argc, char *argv[])
bool fa = false;
const char *device_config = "cpu";
int ode_solver_type = 4;
real_t t_final = 10.0;
real_t dt = 0.01;
double t_final = 10.0;
double dt = 0.01;
bool visualization = true;
bool visit = false;
bool paraview = false;
@@ -425,7 +425,7 @@ int main(int argc, char *argv[])
}
m->AddDomainIntegrator(new MassIntegrator);
constexpr real_t alpha = -1.0;
constexpr double alpha = -1.0;
k->AddDomainIntegrator(new ConvectionIntegrator(velocity, alpha));
k->AddInteriorFaceIntegrator(
new NonconservativeDGTraceIntegrator(velocity, alpha));
@@ -566,14 +566,14 @@ int main(int argc, char *argv[])
// iterations, ti, with a time-step dt).
FE_Evolution adv(*m, *k, *B, prec_type);
real_t t = 0.0;
double t = 0.0;
adv.SetTime(t);
ode_solver->Init(adv);
bool done = false;
for (int ti = 0; !done; )
{
real_t dt_real = min(dt, t_final - t);
double dt_real = min(dt, t_final - t);
ode_solver->Step(*U, t, dt_real);
ti++;
@@ -704,7 +704,7 @@ FE_Evolution::FE_Evolution(ParBilinearForm &M_, ParBilinearForm &K_,
// u_t = M^{-1}(Ku + b),
// by solving associated linear system
// (M - dt*K) d = K*u + b
void FE_Evolution::ImplicitSolve(const real_t dt, const Vector &x, Vector &k)
void FE_Evolution::ImplicitSolve(const double dt, const Vector &x, Vector &k)
{
K->Mult(x, z);
z += b;
@@ -736,7 +736,7 @@ void velocity_function(const Vector &x, Vector &v)
Vector X(dim);
for (int i = 0; i < dim; i++)
{
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
@@ -758,7 +758,7 @@ void velocity_function(const Vector &x, Vector &v)
case 2:
{
// Clockwise rotation in 2D around the origin
const real_t w = M_PI/2;
const double w = M_PI/2;
switch (dim)
{
case 1: v(0) = 1.0; break;
@@ -770,8 +770,8 @@ void velocity_function(const Vector &x, Vector &v)
case 3:
{
// Clockwise twisting rotation in 2D around the origin
const real_t w = M_PI/2;
real_t d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
const double w = M_PI/2;
double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
d = d*d;
switch (dim)
{
@@ -785,7 +785,7 @@ void velocity_function(const Vector &x, Vector &v)
}
// Initial condition
real_t u0_function(const Vector &x)
double u0_function(const Vector &x)
{
int dim = x.Size();
@@ -793,7 +793,7 @@ real_t u0_function(const Vector &x)
Vector X(dim);
for (int i = 0; i < dim; i++)
{
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
@@ -809,28 +809,28 @@ real_t u0_function(const Vector &x)
case 2:
case 3:
{
real_t rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
if (dim == 3)
{
const real_t s = (1. + 0.25*cos(2*M_PI*X(2)));
const double s = (1. + 0.25*cos(2*M_PI*X(2)));
rx *= s;
ry *= s;
}
return ( std::erfc(w*(X(0)-cx-rx))*std::erfc(-w*(X(0)-cx+rx)) *
std::erfc(w*(X(1)-cy-ry))*std::erfc(-w*(X(1)-cy+ry)) )/16;
return ( erfc(w*(X(0)-cx-rx))*erfc(-w*(X(0)-cx+rx)) *
erfc(w*(X(1)-cy-ry))*erfc(-w*(X(1)-cy+ry)) )/16;
}
}
}
case 2:
{
real_t x_ = X(0), y_ = X(1), rho, phi;
rho = std::hypot(x_, y_);
double x_ = X(0), y_ = X(1), rho, phi;
rho = hypot(x_, y_);
phi = atan2(y_, x_);
return pow(sin(M_PI*rho),2)*sin(3*phi);
}
case 3:
{
const real_t f = M_PI;
const double f = M_PI;
return sin(f*X(0))*sin(f*X(1));
}
}
@@ -838,7 +838,7 @@ real_t u0_function(const Vector &x)
}
// Inflow boundary condition (zero for the problems considered in this example)
real_t inflow_function(const Vector &x)
double inflow_function(const Vector &x)
{
switch (problem)
{
+3 -3
View File
@@ -23,11 +23,11 @@ MFEM_LIB_FILE = mfem_is_not_built
SEQ_EXAMPLES = ex0 ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex14 ex15 ex16 \
ex17 ex18 ex19 ex20 ex21 ex22 ex23 ex24 ex25 ex26 ex27 ex28 ex29 ex30 \
ex31 ex33 ex34 ex36 ex37 ex38 ex39 ex40
ex31 ex33 ex34 ex36 ex37
PAR_EXAMPLES = ex0p ex1p ex2p ex3p ex4p ex5p ex6p ex7p ex8p ex9p ex10p ex11p \
ex12p ex13p ex14p ex15p ex16p ex17p ex18p ex19p ex20p ex21p ex22p ex24p \
ex25p ex26p ex27p ex28p ex29p ex30p ex31p ex32p ex33p ex34p ex35p ex36p \
ex37p ex39p ex40p
ex37p
SEQ_DEVICE_EXAMPLES = ex1 ex3 ex4 ex5 ex6 ex9 ex22 ex24 ex25 ex26 ex34
PAR_DEVICE_EXAMPLES = ex1p ex2p ex3p ex4p ex5p ex6p ex7p ex9p ex13p ex22p \
ex24p ex25p ex26p ex34p ex35p
@@ -187,11 +187,11 @@ clean-exec:
@rm -f deformed.* velocity.* elastic_energy.* mode_* mode_deriv_* flux.*
@rm -f ex5-p-*.bp ex9-p-*.bp ex12-p-*.bp ex16-p-*.bp
@rm -f ex16.mesh ex16-mesh.* ex16-init.* ex16-final.*
@rm -f vortex-mesh.* vortex.mesh vortex-?-init.* vortex-?-final.*
@rm -f deformation.* pressure.*
@rm -f ex20.dat ex20p_?????.dat gnuplot_ex20.inp gnuplot_ex20p.inp
@rm -f ex21*.mesh ex21*.sol ex21p_*.*
@rm -f ex23.mesh ex23-*.gf
@rm -f ex25.mesh ex25-*.gf ex25p-*.*
@rm -f euler-?-final.* euler-?-init.* euler-mesh-final.* euler-mesh.*
@rm -rf ex28_* ex28p_*
@rm -rf cond.* cond_mesh.* cond_j.* dsol.* port_mesh.* port_mode.*
+5 -6
View File
@@ -81,8 +81,7 @@ set(EX1_ARGS_HIPAMG -m ../../data/star.mesh --usepetsc --device hip --petscopts
set(EX2_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p)
set(EX2_ARGS_BDDC -m ../../data/beam-tri.mesh --usepetsc --nonoverlapping --petscopts rc_ex2p_bddc)
set(EX2_ARGS_ASM -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p_asm)
set(EX3_ARGS_BDDC_2D -m ../../data/klein-bottle.mesh -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping)
set(EX3_ARGS_BDDC_3D -m ../../data/amr-hex.mesh -rs 1 -rp 0 -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping)
set(EX3_ARGS -m ../../data/klein-bottle.mesh -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping)
set(EX4_ARGS -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping)
set(EX4_HYB_ARGS -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping --hybridization)
set(EX5_BDDC_LB_ARGS -m ../../data/star.mesh --usepetsc -o 0 --petscopts rc_ex5p_bddc --nonoverlapping --local-bdr)
@@ -110,10 +109,10 @@ endif()
# Add the tests: one test per command-line-variable.
if (MFEM_ENABLE_TESTING)
set(TEST_OPTIONS_VARS
EX1_ARGS_W EX1_ARGS_P EX2_ARGS EX2_ARGS_BDDC EX2_ARGS_ASM EX3_ARGS_BDDC_2D
EX3_ARGS_BDDC_3D EX4_ARGS EX4_HYB_ARGS EX5_BDDC_LB_ARGS EX5_BDDC_GB_ARGS
EX5_FSPL_ARGS EX6_ARGS EX6_NONOVL_ARGS EX9_E_ARGS EX9_ES_ARGS EX9_IS_ARGS
EX10_ARGS EX10_MF_ARGS EX10_MFOP_ARGS EX10_JFNK_ARGS)
EX1_ARGS_W EX1_ARGS_P EX2_ARGS EX2_ARGS_BDDC EX2_ARGS_ASM EX3_ARGS
EX4_ARGS EX4_HYB_ARGS EX5_BDDC_LB_ARGS EX5_BDDC_GB_ARGS EX5_FSPL_ARGS
EX6_ARGS EX6_NONOVL_ARGS EX9_E_ARGS EX9_ES_ARGS EX9_IS_ARGS EX10_ARGS
EX10_MF_ARGS EX10_MFOP_ARGS EX10_JFNK_ARGS)
if (MFEM_USE_SLEPC)
list(APPEND TEST_OPTIONS_VARS
EX11_ARGS_SINV EX11_ARGS_LOBPCG EX11_ARGS_GD)
+36 -42
View File
@@ -68,7 +68,7 @@ protected:
ParBilinearForm M, S;
ParNonlinearForm H;
real_t viscosity;
double viscosity;
HyperelasticModel *model;
HypreParMatrix *Mmat; // Mass matrix from ParallelAssemble()
@@ -96,17 +96,17 @@ protected:
public:
HyperelasticOperator(ParFiniteElementSpace &f, Array<int> &ess_bdr,
real_t visc, real_t mu, real_t K,
double visc, double mu, double K,
bool use_petsc, bool petsc_use_jfnk);
/// Compute the right-hand side of the ODE system.
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.*/
virtual void ImplicitSolve(const real_t dt, const Vector &x, Vector &k);
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &k);
real_t ElasticEnergy(const ParGridFunction &x) const;
real_t KineticEnergy(const ParGridFunction &v) const;
double ElasticEnergy(const ParGridFunction &x) const;
double KineticEnergy(const ParGridFunction &v) const;
void GetElasticEnergyDensity(const ParGridFunction &x,
ParGridFunction &w) const;
@@ -123,7 +123,7 @@ private:
ParBilinearForm *M, *S;
ParNonlinearForm *H;
mutable HypreParMatrix *Jacobian;
real_t dt;
double dt;
const Vector *v, *x;
mutable Vector w, z;
const Array<int> &ess_tdof_list;
@@ -133,7 +133,7 @@ public:
ParNonlinearForm *H_, const Array<int> &ess_tdof_list);
/// Set current dt, v, x values - needed to compute action and Jacobian.
void SetParameters(real_t dt_, const Vector *v_, const Vector *x_);
void SetParameters(double dt_, const Vector *v_, const Vector *x_);
/// Compute y = H(x + dt (v + dt k)) + M k + S (v + dt k).
virtual void Mult(const Vector &k, Vector &y) const;
@@ -170,7 +170,7 @@ private:
public:
ElasticEnergyCoefficient(HyperelasticModel &m, const ParGridFunction &x_)
: model(m), x(x_) { }
virtual real_t Eval(ElementTransformation &T, const IntegrationPoint &ip);
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip) const;
virtual ~ElasticEnergyCoefficient() { }
};
@@ -196,11 +196,11 @@ int main(int argc, char *argv[])
int par_ref_levels = 0;
int order = 2;
int ode_solver_type = 3;
real_t t_final = 300.0;
real_t dt = 3.0;
real_t visc = 1e-2;
real_t mu = 0.25;
real_t K = 5.0;
double t_final = 300.0;
double dt = 3.0;
double visc = 1e-2;
double mu = 0.25;
double K = 5.0;
bool visualization = true;
int vis_steps = 1;
bool use_petsc = true;
@@ -387,8 +387,8 @@ int main(int argc, char *argv[])
}
}
real_t ee0 = oper->ElasticEnergy(x_gf);
real_t 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;
@@ -396,7 +396,7 @@ int main(int argc, char *argv[])
cout << "initial total energy (TE) = " << (ee0 + ke0) << endl;
}
real_t t = 0.0;
double t = 0.0;
oper->SetTime(t);
ode_solver->Init(*oper);
@@ -405,7 +405,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);
ode_solver->Step(vx, t, dt_real);
@@ -415,8 +415,8 @@ int main(int argc, char *argv[])
{
v_gf.SetFromTrueVector(); x_gf.SetFromTrueVector();
real_t ee = oper->ElasticEnergy(x_gf);
real_t ke = oper->KineticEnergy(v_gf);
double ee = oper->ElasticEnergy(x_gf);
double ke = oper->KineticEnergy(v_gf);
if (myid == 0)
{
@@ -515,7 +515,7 @@ ReducedSystemOperator::ReducedSystemOperator(
ess_tdof_list(ess_tdof_list_)
{ }
void ReducedSystemOperator::SetParameters(real_t dt_, const Vector *v_,
void ReducedSystemOperator::SetParameters(double dt_, const Vector *v_,
const Vector *x_)
{
dt = dt_; v = v_; x = x_;
@@ -555,24 +555,18 @@ ReducedSystemOperator::~ReducedSystemOperator()
HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
Array<int> &ess_bdr, real_t visc,
real_t mu, real_t K, bool use_petsc,
Array<int> &ess_bdr, double visc,
double mu, double K, bool use_petsc,
bool use_petsc_factory)
: TimeDependentOperator(2*f.TrueVSize(), static_cast<real_t>(0.0)), fespace(f),
: TimeDependentOperator(2*f.TrueVSize(), 0.0), fespace(f),
M(&fespace), S(&fespace), H(&fespace),
viscosity(visc), M_solver(f.GetComm()),
newton_solver(f.GetComm()), pnewton_solver(NULL), z(height/2)
{
#if defined(MFEM_USE_DOUBLE)
const real_t rel_tol = 1e-8;
const real_t newton_abs_tol = 0.0;
#elif defined(MFEM_USE_SINGLE)
const real_t rel_tol = 1e-3;
const real_t newton_abs_tol = 1e-4;
#endif
const double rel_tol = 1e-8;
const int skip_zero_entries = 0;
const real_t ref_density = 1.0; // density in the reference configuration
const double ref_density = 1.0; // density in the reference configuration
ConstantCoefficient rho0(ref_density);
M.AddDomainIntegrator(new VectorMassIntegrator(rho0));
M.Assemble(skip_zero_entries);
@@ -623,7 +617,7 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
newton_solver.SetOperator(*reduced_oper);
newton_solver.SetPrintLevel(1); // print Newton iterations
newton_solver.SetRelTol(rel_tol);
newton_solver.SetAbsTol(newton_abs_tol);
newton_solver.SetAbsTol(0.0);
newton_solver.SetMaxIter(10);
}
else
@@ -644,7 +638,7 @@ HyperelasticOperator::HyperelasticOperator(ParFiniteElementSpace &f,
}
pnewton_solver->SetPrintLevel(1); // print Newton iterations
pnewton_solver->SetRelTol(rel_tol);
pnewton_solver->SetAbsTol(newton_abs_tol);
pnewton_solver->SetAbsTol(0.0);
pnewton_solver->SetMaxIter(10);
}
}
@@ -670,7 +664,7 @@ void HyperelasticOperator::Mult(const Vector &vx, Vector &dvx_dt) const
dx_dt = v;
}
void HyperelasticOperator::ImplicitSolve(const real_t dt,
void HyperelasticOperator::ImplicitSolve(const double dt,
const Vector &vx, Vector &dvx_dt)
{
int sc = height/2;
@@ -702,16 +696,16 @@ void HyperelasticOperator::ImplicitSolve(const real_t dt,
add(v, dt, dv_dt, dx_dt);
}
real_t HyperelasticOperator::ElasticEnergy(const ParGridFunction &x) const
double HyperelasticOperator::ElasticEnergy(const ParGridFunction &x) const
{
return H.GetEnergy(x);
}
real_t HyperelasticOperator::KineticEnergy(const ParGridFunction &v) const
double HyperelasticOperator::KineticEnergy(const ParGridFunction &v) const
{
real_t loc_energy = 0.5*M.InnerProduct(v, v);
real_t energy;
MPI_Allreduce(&loc_energy, &energy, 1, MPITypeMap<real_t>::mpi_type, MPI_SUM,
double loc_energy = 0.5*M.InnerProduct(v, v);
double energy;
MPI_Allreduce(&loc_energy, &energy, 1, MPI_DOUBLE, MPI_SUM,
fespace.GetComm());
return energy;
}
@@ -748,8 +742,8 @@ Solver* PreconditionerFactory::NewPreconditioner(const mfem::OperatorHandle& oh)
return new PetscPreconditioner(*pP,"jfnk_");
}
real_t ElasticEnergyCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip)
double ElasticEnergyCoefficient::Eval(ElementTransformation &T,
const IntegrationPoint &ip) const
{
model.SetTransformation(T);
x.GetVectorGradient(T, J);
@@ -768,7 +762,7 @@ void InitialDeformation(const Vector &x, Vector &y)
void InitialVelocity(const Vector &x, Vector &v)
{
const int dim = x.Size();
const real_t s = 0.1/64.;
const double s = 0.1/64.;
v = 0.0;
v(dim-1) = s*x(0)*x(0)*(8.0-x(0));
+2 -2
View File
@@ -207,7 +207,7 @@ int main(int argc, char *argv[])
m->AddDomainIntegrator(new MassIntegrator(one));
m->Assemble();
// shift the eigenvalue corresponding to eliminated dofs to a large value
m->EliminateEssentialBCDiag(ess_bdr, numeric_limits<real_t>::min());
m->EliminateEssentialBCDiag(ess_bdr, numeric_limits<double>::min());
m->Finalize();
PetscParMatrix *pA = NULL, *pM = NULL;
@@ -317,7 +317,7 @@ int main(int argc, char *argv[])
// 9. Compute the eigenmodes and extract the array of eigenvalues. Define a
// parallel grid function to represent each of the eigenmodes returned by
// the solver.
Array<real_t> eigenvalues;
Array<double> eigenvalues;
if (!use_slepc)
{
lobpcg->Solve();
+1 -2
View File
@@ -58,8 +58,6 @@ int main(int argc, char *argv[])
// 2. Parse command-line options.
const char *mesh_file = "../../data/beam-tri.mesh";
int ser_ref_levels = -1;
int par_ref_levels = 1;
int order = 1;
bool static_cond = false;
bool visualization = 1;
@@ -67,6 +65,7 @@ int main(int argc, char *argv[])
bool use_petsc = true;
const char *petscrc_file = "";
bool use_nonoverlapping = false;
int ser_ref_levels = -1, par_ref_levels = 1;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
+6 -23
View File
@@ -40,7 +40,7 @@ using namespace mfem;
// Exact solution, E, and r.h.s., f. See below for implementation.
void E_exact(const Vector &, Vector &);
void f_exact(const Vector &, Vector &);
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int dim;
int main(int argc, char *argv[])
@@ -53,8 +53,6 @@ int main(int argc, char *argv[])
// 2. Parse command-line options.
const char *mesh_file = "../../data/beam-tet.mesh";
int ser_ref_levels = -1;
int par_ref_levels = 2;
int order = 1;
bool static_cond = false;
bool visualization = 1;
@@ -65,10 +63,6 @@ int main(int argc, char *argv[])
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(&freq, "-f", "--frequency", "Set the frequency for the exact"
@@ -109,16 +103,6 @@ int main(int argc, char *argv[])
// and volume meshes with the same code.
Mesh *mesh = new Mesh(mesh_file, 1, 1);
dim = mesh->Dimension();
#if PETSC_VERSION_LT(3,21,0)
if (dim == 3 && use_petsc && use_nonoverlapping)
{
cout << "\nFor three-dimensional runs you need a version of PETSc greater or equal 3.21.\n\n";
delete mesh;
MFEMFinalizePetsc();
Mpi::Finalize();
return MFEM_SKIP_RETURN_VALUE;
}
#endif
int sdim = mesh->SpaceDimension();
// 4. Refine the serial mesh on all processors to increase the resolution. In
@@ -126,11 +110,9 @@ int main(int argc, char *argv[])
// 'ref_levels' to be the largest number that gives a final mesh with no
// more than 1,000 elements.
{
if (ser_ref_levels < 0)
{
ser_ref_levels = (int)floor(log(1000./mesh->GetNE())/log(2.)/dim);
}
for (int l = 0; l < ser_ref_levels; l++)
int ref_levels =
(int)floor(log(1000./mesh->GetNE())/log(2.)/dim);
for (int l = 0; l < ref_levels; l++)
{
mesh->UniformRefinement();
}
@@ -142,6 +124,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();
@@ -278,7 +261,7 @@ int main(int argc, char *argv[])
// 14. Compute and print the L^2 norm of the error.
{
real_t err = x.ComputeL2Error(E);
double err = x.ComputeL2Error(E);
if (myid == 0)
{
cout << "\n|| E_h - E ||_{L^2} = " << err << '\n' << endl;
+14 -22
View File
@@ -36,7 +36,7 @@ using namespace mfem;
// Exact solution, F, and r.h.s., f. See below for implementation.
void F_exact(const Vector &, Vector &);
void f_exact(const Vector &, Vector &);
real_t freq = 1.0, kappa;
double freq = 1.0, kappa;
int main(int argc, char *argv[])
{
@@ -48,8 +48,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 set_bc = true;
bool static_cond = false;
@@ -62,10 +60,6 @@ int main(int argc, char *argv[])
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(&set_bc, "-bc", "--impose-bc", "-no-bc", "--dont-impose-bc",
@@ -117,11 +111,9 @@ int main(int argc, char *argv[])
// 'ref_levels' to be the largest number that gives a final mesh with no
// more than 1,000 elements.
{
if (ser_ref_levels < 0)
{
ser_ref_levels = (int)floor(log(1000./mesh->GetNE())/log(2.)/dim);
}
for (int l = 0; l < ser_ref_levels; l++)
int ref_levels =
(int)floor(log(1000./mesh->GetNE())/log(2.)/dim);
for (int l = 0; l < ref_levels; l++)
{
mesh->UniformRefinement();
}
@@ -133,6 +125,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();
@@ -259,8 +252,7 @@ int main(int argc, char *argv[])
if (use_nonoverlapping)
{
ParFiniteElementSpace *prec_fespace =
(a->StaticCondensationIsEnabled() ? a->SCParFESpace() :
(hfes ? NULL : fespace));
(a->StaticCondensationIsEnabled() ? a->SCParFESpace() : fespace);
// Auxiliary class for BDDC customization
PetscBDDCSolverParams opts;
@@ -288,7 +280,7 @@ int main(int argc, char *argv[])
// 14. Compute and print the L^2 norm of the error.
{
real_t err = x.ComputeL2Error(F);
double err = x.ComputeL2Error(F);
if (myid == 0)
{
cout << "\n|| F_h - F ||_{L^2} = " << err << '\n' << endl;
@@ -345,9 +337,9 @@ void F_exact(const Vector &p, Vector &F)
{
int dim = p.Size();
real_t x = p(0);
real_t y = p(1);
// real_t z = (dim == 3) ? p(2) : 0.0;
double x = p(0);
double y = p(1);
// double z = (dim == 3) ? p(2) : 0.0;
F(0) = cos(kappa*x)*sin(kappa*y);
F(1) = cos(kappa*y)*sin(kappa*x);
@@ -362,11 +354,11 @@ void f_exact(const Vector &p, Vector &f)
{
int dim = p.Size();
real_t x = p(0);
real_t y = p(1);
// real_t z = (dim == 3) ? p(2) : 0.0;
double x = p(0);
double y = p(1);
// double z = (dim == 3) ? p(2) : 0.0;
real_t temp = 1 + 2*kappa*kappa;
double temp = 1 + 2*kappa*kappa;
f(0) = temp*cos(kappa*x)*sin(kappa*y);
f(1) = temp*cos(kappa*y)*sin(kappa*x);
+18 -18
View File
@@ -41,10 +41,10 @@ using namespace mfem;
// Define the analytical solution and forcing terms / boundary conditions
void uFun_ex(const Vector & x, Vector & u);
real_t pFun_ex(const Vector & x);
double pFun_ex(const Vector & x);
void fFun(const Vector & x, Vector & f);
real_t gFun(const Vector & x);
real_t f_natural(const Vector & x);
double gFun(const Vector & x);
double f_natural(const Vector & x);
int main(int argc, char *argv[])
{
@@ -356,8 +356,8 @@ int main(int argc, char *argv[])
// Check the norm of the unpreconditioned residual.
int maxIter(500);
real_t rtol(1.e-6);
real_t atol(1.e-10);
double rtol(1.e-6);
double atol(1.e-10);
chrono.Clear();
chrono.Start();
@@ -454,10 +454,10 @@ int main(int argc, char *argv[])
irs[i] = &(IntRules.Get(i, order_quad));
}
real_t err_u = u->ComputeL2Error(ucoeff, irs);
real_t norm_u = ComputeGlobalLpNorm(2, ucoeff, *pmesh, irs);
real_t err_p = p->ComputeL2Error(pcoeff, irs);
real_t norm_p = ComputeGlobalLpNorm(2, pcoeff, *pmesh, irs);
double err_u = u->ComputeL2Error(ucoeff, irs);
double norm_u = ComputeGlobalLpNorm(2, ucoeff, *pmesh, irs);
double err_p = p->ComputeL2Error(pcoeff, irs);
double norm_p = ComputeGlobalLpNorm(2, pcoeff, *pmesh, irs);
if (verbose)
{
@@ -551,9 +551,9 @@ int main(int argc, char *argv[])
void uFun_ex(const Vector & x, Vector & u)
{
real_t xi(x(0));
real_t yi(x(1));
real_t zi(0.0);
double xi(x(0));
double yi(x(1));
double zi(0.0);
if (x.Size() == 3)
{
zi = x(2);
@@ -569,11 +569,11 @@ void uFun_ex(const Vector & x, Vector & u)
}
// Change if needed
real_t pFun_ex(const Vector & x)
double pFun_ex(const Vector & x)
{
real_t xi(x(0));
real_t yi(x(1));
real_t zi(0.0);
double xi(x(0));
double yi(x(1));
double zi(0.0);
if (x.Size() == 3)
{
@@ -588,7 +588,7 @@ void fFun(const Vector & x, Vector & f)
f = 0.0;
}
real_t gFun(const Vector & x)
double gFun(const Vector & x)
{
if (x.Size() == 3)
{
@@ -600,7 +600,7 @@ real_t gFun(const Vector & x)
}
}
real_t f_natural(const Vector & x)
double f_natural(const Vector & x)
{
return (-pFun_ex(x));
}
+1 -1
View File
@@ -204,7 +204,7 @@ int main(int argc, char *argv[])
// The system will be solved for true (unconstrained/unique) DOFs only.
Array<int> ess_tdof_list;
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
real_t time;
double time;
const int copy_interior = 1;
if (use_petsc)
+19 -19
View File
@@ -49,10 +49,10 @@ int problem;
void velocity_function(const Vector &x, Vector &v);
// Initial condition
real_t u0_function(const Vector &x);
double u0_function(const Vector &x);
// Inflow boundary condition
real_t inflow_function(const Vector &x);
double inflow_function(const Vector &x);
// Mesh bounding box
Vector bb_min, bb_max;
@@ -87,7 +87,7 @@ public:
virtual void Mult(const Vector &x, Vector &y) const;
virtual Operator& GetExplicitGradient(const Vector &x) const;
virtual Operator& GetImplicitGradient(const Vector &x, const Vector &xp,
real_t shift) const;
double shift) const;
virtual ~FE_Evolution() { delete iJacobian; delete rJacobian; }
};
@@ -153,8 +153,8 @@ int main(int argc, char *argv[])
bool fa = false;
const char *device_config = "cpu";
int ode_solver_type = 4;
real_t t_final = 10.0;
real_t dt = 0.01;
double t_final = 10.0;
double dt = 0.01;
bool visualization = true;
bool visit = false;
bool binary = false;
@@ -431,7 +431,7 @@ int main(int argc, char *argv[])
// 10. Define the time-dependent evolution operator describing the ODE
FE_Evolution *adv = new FE_Evolution(*m, *k, *B, implicit);
real_t t = 0.0;
double t = 0.0;
adv->SetTime(t);
if (use_petsc)
{
@@ -451,7 +451,7 @@ int main(int argc, char *argv[])
{
// We cannot match exactly the time history of the Run method
// since we are explicitly telling PETSc to use a time step
real_t dt_real = min(dt, t_final - t);
double dt_real = min(dt, t_final - t);
ode_solver->Step(*U, t, dt_real);
ti++;
@@ -621,7 +621,7 @@ Operator& FE_Evolution::GetExplicitGradient(const Vector &x) const
// LHS Jacobian, evaluated as shift*F_du/dt + F_u
Operator& FE_Evolution::GetImplicitGradient(const Vector &x, const Vector &xp,
real_t shift) const
double shift) const
{
Operator::Type otype = (MAlev == AssemblyLevel::LEGACY ?
Operator::PETSC_MATAIJ : Operator::ANY_TYPE);
@@ -648,7 +648,7 @@ void velocity_function(const Vector &x, Vector &v)
Vector X(dim);
for (int i = 0; i < dim; i++)
{
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
@@ -670,7 +670,7 @@ void velocity_function(const Vector &x, Vector &v)
case 2:
{
// Clockwise rotation in 2D around the origin
const real_t w = M_PI/2;
const double w = M_PI/2;
switch (dim)
{
case 1: v(0) = 1.0; break;
@@ -682,8 +682,8 @@ void velocity_function(const Vector &x, Vector &v)
case 3:
{
// Clockwise twisting rotation in 2D around the origin
const real_t w = M_PI/2;
real_t d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
const double w = M_PI/2;
double d = max((X(0)+1.)*(1.-X(0)),0.) * max((X(1)+1.)*(1.-X(1)),0.);
d = d*d;
switch (dim)
{
@@ -697,7 +697,7 @@ void velocity_function(const Vector &x, Vector &v)
}
// Initial condition
real_t u0_function(const Vector &x)
double u0_function(const Vector &x)
{
int dim = x.Size();
@@ -705,7 +705,7 @@ real_t u0_function(const Vector &x)
Vector X(dim);
for (int i = 0; i < dim; i++)
{
real_t center = (bb_min[i] + bb_max[i]) * 0.5;
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
@@ -721,10 +721,10 @@ real_t u0_function(const Vector &x)
case 2:
case 3:
{
real_t rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
if (dim == 3)
{
const real_t s = (1. + 0.25*cos(2*M_PI*X(2)));
const double s = (1. + 0.25*cos(2*M_PI*X(2)));
rx *= s;
ry *= s;
}
@@ -735,14 +735,14 @@ real_t u0_function(const Vector &x)
}
case 2:
{
real_t x_ = X(0), y_ = X(1), rho, phi;
double x_ = X(0), y_ = X(1), rho, phi;
rho = hypot(x_, y_);
phi = atan2(y_, x_);
return pow(sin(M_PI*rho),2)*sin(3*phi);
}
case 3:
{
const real_t f = M_PI;
const double f = M_PI;
return sin(f*X(0))*sin(f*X(1));
}
}
@@ -750,7 +750,7 @@ real_t u0_function(const Vector &x)
}
// Inflow boundary condition (zero for the problems considered in this example)
real_t inflow_function(const Vector &x)
double inflow_function(const Vector &x)
{
switch (problem)
{
+2 -4
View File
@@ -83,8 +83,7 @@ EX1_ARGS_HIPAMG := -m ../../data/star.mesh --usepetsc --device hip --petsc
EX2_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p
EX2_ARGS_BDDC := -m ../../data/beam-tri.mesh --usepetsc --nonoverlapping --petscopts rc_ex2p_bddc
EX2_ARGS_ASM := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p_asm
EX3_ARGS_BDDC_2D := -m ../../data/klein-bottle.mesh -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping
EX3_ARGS_BDDC_3D := -m ../../data/amr-hex.mesh -rs 1 -rp 0 -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping
EX3_ARGS := -m ../../data/klein-bottle.mesh -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping
EX4_ARGS := -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping
EX4_HYB_ARGS := -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping --hybridization
EX5_BDDC_LB_ARGS := -m ../../data/star.mesh --usepetsc -o 0 --petscopts rc_ex5p_bddc --nonoverlapping --local-bdr
@@ -123,8 +122,7 @@ ex2p-test-par: ex2p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX2_ARGS_BDDC))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX2_ARGS_ASM))
ex3p-test-par: ex3p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX3_ARGS_BDDC_2D))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX3_ARGS_BDDC_3D))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX3_ARGS))
ex4p-test-par: ex4p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX4_ARGS))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX4_HYB_ARGS))
-2
View File
@@ -4,9 +4,7 @@
-ksp_converged_reason
# Internal use (don't remove it)
# It is duplicated because we support older versions of PETSc
-matis_convert_local_nest
-mat_is_convert_local_nest
# PCBDDC options

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