Compare commits

..
Author SHA1 Message Date
Yohann Dudouit 798a7d047d Testing environment on. 2019-04-01 15:36:26 -07:00
Yohann Dudouit d88ea50d65 Add computation time to ex9 2019-02-04 11:10:41 -08:00
Yohann Dudouit f865768703 Simplifications and some vectorization attempts. 2018-05-14 17:29:32 -07:00
Yohann Dudouit 8c7eee36ac Cleaning and making the code easier to understand. 2018-05-07 19:07:39 -07:00
Yohann Dudouit a5e22fe61e Use Partial Assembly for the evaluation of Jacobians for face terms. 2018-05-07 14:56:22 -07:00
Yohann Dudouit ecf98066b0 Add a Local Conjugate Gradient with local preconditioner for DG methods. 2018-05-03 15:42:19 -07:00
Yohann Dudouit df6a848fd8 Adds a Conjugate Gradient Solvers for partial assembly.
- Basic conjugate gradient solver for partial assembly without preconditioning.
- Conjugate gradient solver for PA with Prec.
- Diag Solver (can be used as preconditionner).
- Conjugate gradient working on element level for DG methods.
2018-05-03 15:00:37 -07:00
Yohann Dudouit 0eecb89c77 Adds a local CG solver and a Diag solver for DG problems. 2018-04-16 11:17:57 -07:00
Yohann Dudouit d5896ec636 Correctly computes Jacobian for 2D and 3D in partial assembly using tensorial products. 2018-04-06 16:51:49 -07:00
Yohann Dudouit c8151962af Merge branch 'master' into ex9-pa-dev
Resolved conflicts:
	examples/makefile
	fem/bilinearform.hpp
	fem/nonlininteg.hpp
	linalg/densemat.hpp
	linalg/operator.hpp
2018-04-06 15:37:52 -07:00
Yohann Dudouit 32e2808ff7 Adds tensorial construction of the Jacobian and splits code in different files. 2018-03-27 14:49:29 -07:00
Yohann Dudouit 564054e5f1 Replace keyword "using" by "typedef". 2018-03-20 15:13:40 -07:00
Yohann Dudouit 7eb9af3ffe Adds function that avoid variadic templates for integrators. 2018-03-20 14:29:13 -07:00
Yohann Dudouit e078a2bc24 Fix 3D DG for structured and periodic meshes.
* Unstructured meshes with different orientations configurations have
to be tested
2018-03-16 16:09:29 -07:00
Yohann Dudouit 32157d90ae 3D implemented, compiles, but doesn't work.
- Adds the 3D permutation functions
 - Add 3D BtDB Kernel for faces
2018-03-09 16:13:02 -08:00
Yohann Dudouit 5db57ef64e Fix some compilation errors due to previous commit. 2018-03-07 15:48:44 -08:00
Yohann Dudouit 20afdbd7b6 Simplify the code and add the 3D permutations for DG. 2018-03-07 15:32:07 -08:00
Yohann Dudouit 286d8a31d3 Integrates Johann's changes to this branch. 2018-03-07 15:30:11 -08:00
Yohann Dudouit 34edd1e775 Merge branch 'pa-oper-dev' into ex9-pa-dev
Conflicts:
	examples/makefile
	fem/bilinearform.cpp
	fem/obilininteg.hpp
	fem/painteg.cpp
	makefile
2017-12-11 14:37:11 -08:00
Yohann Dudouit 398562a73b Unified and simpler design for Domain and Face Partial Assembly
Integrators.
2017-12-11 09:28:57 -08:00
Yohann Dudouit 9e4c36094f Always more efficient Face Partial Assembly Kernels.
Lot of simplifications in the design of Domain Kernels.
Remove inefficient Kernels Based on Eigen.
2017-12-06 16:20:54 -08:00
Johann Dahm 96e9557c25 Fix uninitialization bug and unrelated compiler warning 2017-12-04 17:41:54 -08:00
Johann Dahm 02778c55fd Add ex1p support 2017-12-04 15:20:32 -08:00
Johann Dahm 4937dff6d7 Add VectorMassIntegrator to PAIntegratorMap 2017-12-03 21:16:54 -08:00
Johann Dahm 32801fa560 Add AssembleForm to MixedBilinearForm 2017-12-01 21:33:41 -08:00
Johann Dahm 772b83ee0d Rename operator and edits to FormSystemOperator and FormLinearSystem 2017-11-30 15:36:47 -08:00
Johann Dahm 8eb4b72fb8 Merge branch 'tbasis-dev' into pa-oper-dev 2017-11-30 10:24:48 -08:00
Yohann Dudouit 290141b127 Corrects a bug for partial assembly DG Face terms for advection
when velocity field is non constant.
2017-11-29 14:49:01 -08:00
Yohann Dudouit b92436a89e Adds the missing templated Tensor class. 2017-11-29 11:03:45 -08:00
Johann Dahm d064feaf63 Add FESpaceForm (mostly replaces BilinearFormOperator) 2017-11-28 22:30:04 -05:00
Yohann Dudouit 2b0a4268b0 Removes memory leak for the templated Tensor class. 2017-11-28 18:29:42 -08:00
Yohann Dudouit abb2181550 New Kernel working for unstructured meshes. 2017-11-28 15:41:20 -08:00
Yohann Dudouit 26679914fb Adds the external fluxes for the Dummy Kernel 2, only works for
"structured" mesh for the moment.
2017-11-22 10:51:46 -08:00
Yohann Dudouit 8fa336fd85 Adds a templated interface for Face terms partial assembly integrators,
called PAFaceIntegrator. Adds a per element Partial Assembly Face Kernel.
Adds the interior fluxes kernels for the previous kernel.
2017-11-20 13:46:29 -08:00
Yohann Dudouit 66ad469e34 Adds a Partial Assembly Face Kernel Interface for Partial Assembly
Face Integrators.
2017-11-16 16:52:24 -08:00
Johann Dahm 511be753c4 Refactor of partial assembly 2017-11-15 15:59:18 -08:00
Johann Dahm 1570e99bff Merge branch 'intrule-dev' into pa-oper-dev 2017-11-15 15:32:54 -08:00
Yohann Dudouit 0d6ad1a455 Adds a generic PADomainIntegrator that defines the interface the
PA Kernels.
2017-11-14 11:12:39 -08:00
Johann Dahm ee51644ddb Merge branch 'master' into pa-oper-dev 2017-11-13 14:32:42 -08:00
Yohann Dudouit 03db4d58c6 fixes few typos 2017-11-13 10:13:50 -08:00
Yohann Dudouit 0d7fc30429 Dummy domain kernels available for any variational form (BtDB, BtDG, GtDB, GtDG)
and any dimension (1 to 3).
2017-11-13 09:48:47 -08:00
Yohann Dudouit 2a56202df8 Removes unecessary pre-instantiation of partial assembly kernels. 2017-11-07 17:03:51 -08:00
Yohann Dudouit 4496d921e0 Adds a Domain Partial Assembly Kernel based on Tensors from Eigen library 2017-11-07 16:48:11 -08:00
Yohann Dudouit 8db895f790 ex9PA working, but code needs a lot of cleaning 2017-11-02 17:13:12 -07:00
Yohann Dudouit 266f4e4c1c Compute all fluxes for 2D case 2017-10-27 13:18:11 -07:00
Yohann Dudouit df2aa5f201 Added a 2d DummyFaceKernel 2017-10-26 18:24:10 -07:00
Yohann Dudouit 45490c50e9 Adds a dummy Face Partial Assembly Kernel.
Adds a PADGConvectionFaceIntegrator that initialize the 4 differents
convection fluxes for a face.
2017-10-24 14:00:09 -07:00
Yohann Dudouit 2b1662672f Separate the partial assembly implementation from obilininteg.* .
The DG implementation uses Kernels to separate the computation of D
and the computation of V=BDBU. Uses a dummy kernel implementation
for domain Integrator. The dummy Kernel for face Integrator is
not yet implemented.
Also adds functions to compute change of basis from one element to
another on a face.
2017-10-17 15:57:15 -07:00
Yohann Dudouit d9ffb65430 New functions in dgfacefunctions to compute coordinate transformation on a face
according to the element on one side or on the other side of the face.
2017-10-11 14:00:55 -07:00
Yohann Dudouit 9733b2d200 added a partial assembly convection operator (PAConvectionIntegrator) 2017-10-06 10:33:00 -07:00
Yohann Dudouit 6bcb4767e9 Merge branch 'pa-oper-dev' into ex9-pa-dev 2017-10-05 10:58:39 -07:00
Johann Dahm 84df47605e Remove the TensorBasisElement from class storage 2017-10-04 17:10:06 -07:00
Johann Dahm 40067064d5 FiniteElementSpace* -> const FiniteElement* in ComputeBasis1d 2017-10-04 17:03:36 -07:00
Yohann Dudouit a40477d96a factorize tensor operations into one class instead of having them in every PAIntegrator. 2017-10-04 14:02:36 -07:00
Yohann Dudouit 6e8c31b861 adds the partial assembly file for example 9. 2017-10-04 13:59:22 -07:00
Johann Dahm 48bfad0ad7 Add vdim support to PA integrators 2017-09-30 22:31:27 -07:00
Johann Dahm 7f22a84a33 Fix: increment offset in 1D PA integrators 2017-09-30 22:18:16 -07:00
Johann Dahm 0e6783a659 Remove unneeded DenseTensor constructor
This constructor is added on the array-dev branch but not needed here.
2017-09-29 15:38:22 -07:00
Yohann Dudouit 62602a44a3 Overload ComputeBasis1d to compute only shape1d (skip gradient computation) 2017-09-29 15:27:11 -07:00
Johann Dahm ce8809c55d Add coefficients and support in ex16 2017-09-25 15:21:54 -07:00
Johann Dahm bd65eb1818 Add mass integrator 2017-09-25 12:04:26 -07:00
Johann Dahm f9f1ab74fd Add 1D diffusion integrator 2017-09-25 11:09:26 -07:00
Johann Dahm 566f03cbaa Make notation consistent 2017-09-23 20:34:31 -07:00
Johann Dahm f93db7db30 Put back preconditioner and clean up logic 2017-09-22 17:19:13 -07:00
Johann Dahm ad102a5d29 Add 3D diffusion integrator and refactor 2017-09-22 15:03:14 -07:00
Johann Dahm 7c37ac0a24 Merge branch 'tbasis-dev' into pa-oper-dev 2017-09-22 08:27:39 -07:00
Johann Dahm d6bb74d2a0 Merge branch 'master' into pa-oper-dev 2017-09-22 08:24:44 -07:00
Johann Dahm ea535368b6 Move PA integrations to fem/obilininteg.{c,h}pp 2017-09-20 17:16:39 -07:00
Johann Dahm 7721bb8e9e Merge branch 'master' into pa-oper-dev 2017-09-20 14:23:50 -07:00
Johann Dahm 6fa3f1da2e Add partial assembly-based operator for quads and add to ex1 2017-09-13 13:57:17 -07:00
Johann Dahm eb520d1a12 Tensorized finite element bases from occa-dev branch.
Thanks, David!
2017-09-12 14:14:42 -07:00
293 changed files with 16745 additions and 55620 deletions
+1 -3
View File
@@ -43,9 +43,7 @@ before_build:
build_script:
- cmake --build build_parallel
- cmake --build build_serial
- cmake --build build_serial --target exec
after_build:
# - cmake --build build_parallel --target check
- cmake --build build_serial --target RUN_TESTS
- cmake --build build_serial --target check
-27
View File
@@ -45,8 +45,6 @@ examples/ex[1-9]
examples/ex[1-9]p
examples/ex1[04-9]
examples/ex1[0-9]p
examples/ex2[0-9]
examples/ex2[0-9]p
examples/refined.mesh
examples/displaced.mesh
@@ -78,13 +76,6 @@ examples/vortex-?-init.*
examples/vortex-?-final.*
examples/deformation.*
examples/pressure.*
examples/ex20.dat
examples/ex20p_?????.dat
examples/gnuplot_ex20.inp
examples/gnuplot_ex20p.inp
examples/ex22*.mesh
examples/ex22*.sol
examples/ex22p_*.*
examples/sundials/ex9
examples/sundials/ex1[06]
@@ -121,15 +112,6 @@ examples/petsc/deformed.*
examples/petsc/velocity.*
examples/petsc/elastic_energy.*
examples/pumi/ex1
examples/pumi/ex[126]p
examples/pumi/refined.mesh
examples/pumi/sol.gf
examples/pumi/mesh.*
examples/pumi/sol.*
examples/pumi/displaced.mesh
miniapps/electromagnetics/volta
miniapps/electromagnetics/tesla
miniapps/electromagnetics/maxwell
@@ -142,20 +124,16 @@ miniapps/electromagnetics/Joule_*
miniapps/meshing/mobius-strip
miniapps/meshing/klein-bottle
miniapps/meshing/toroid
miniapps/meshing/mesh-explorer
miniapps/meshing/shaper
miniapps/meshing/extruder
miniapps/meshing/mesh-optimizer
miniapps/meshing/pmesh-optimizer
miniapps/meshing/mobius-strip.mesh
miniapps/meshing/klein-bottle.mesh
miniapps/meshing/toroid-*.mesh
miniapps/meshing/mesh-explorer.mesh
miniapps/meshing/partitioning.txt
miniapps/meshing/shaper.mesh
miniapps/meshing/extruder.mesh
miniapps/meshing/optimized*
miniapps/meshing/perturbed*
@@ -169,7 +147,6 @@ miniapps/performance/sol.*
miniapps/tools/display-basis
miniapps/tools/load-dc
miniapps/tools/convert-dc
miniapps/tools/lor-transfer
miniapps/nurbs/ex1
miniapps/nurbs/ex1p
@@ -179,7 +156,3 @@ miniapps/nurbs/mesh.*
miniapps/nurbs/sol.*
miniapps/nurbs/mode_*
miniapps/nurbs/Example1*
# Unit test binary and outputs
tests/unit/output_meshes
tests/unit/unit_tests
-1
View File
@@ -205,7 +205,6 @@ install:
else
echo "Reusing cached hypre-2.10.0b/";
fi;
ln -s hypre-2.10.0b hypre;
else
echo "Serial build, not using hypre";
fi
+6 -194
View File
@@ -8,192 +8,11 @@
http://mfem.org
Version 4.0-RC2, Apr 24, 2019
=============================
Requirements and Limitations
----------------------------
- This is a release candidate for mfem-4.0.
- Use at your own risk -- not everything will work and the API may change.
- We are looking for feedback from friendly users.
- Unlike previous MFEM releases, this version requires a C++11 compiler.
- GPU-related limitations:
* Hypre preconditioners are not yet available in GPU mode.
* Only constant coefficients are currently supported on GPUs.
* Full-assembly (on device), element assembly, and matrix-free bilinear forms
are not supported yet. Element batching is currently ignored.
* Partial assembly kernels are not implemented yet for simplices.
GPU support
-----------
- Added initial support for hardware devices, such as GPUs, and programming
models, such as CUDA, OCCA, RAJA and OpenMP.
- The GPU/device support is based on MFEM's new backends and kernels working
seamlessly with a new lightweight device/host memory manager. The kernels can
be implemented either in OCCA, or as a simple wrapper around for-loops, which
can then be dispatched to RAJA and native backends. See the files forall.hpp
and mem_manager.hpp in the general/ directory.
- Several of the MFEM example codes (ex1, ex1p, ex6, and ex6p) can now take
advantage of GPU acceleration with the backend selectable at runtime. Many of
the linear algebra and finite element operations (e.g. partially assembled
bilinear forms) have been extended to take advantage of kernel acceleration by
simply replacing loops with the MFEM_FORALL() macro.
- In addition to pure CUDA, the library currently supports OCCA, RAJA and OpenMP
kernels, which could be mixed and matched in different parts of the same
application. We plan on adding support for more programming models and devices
in the future, without the need for significant modifications in user code.
The list of current backends is: "occa-cuda", "raja-cuda", "cuda", "occa-omp",
"raja-omp", "omp", "occa-cpu", "raja-cpu", and "cpu".
Discretization improvements
---------------------------
- Added support for a general "low-order refined"-to-"high-order" transfer of
GridFunction data from a "low-order refined" (LOR) space defined on a refined
mesh to a "high-order" (HO) finite element space defined on a coarse mesh. See
the new classes InterpolationGridTransfer and L2ProjectionGridTransfer and the
new LOR Transfer miniapp: miniapps/tools/lor-transfer.cpp.
- Added support for derefinement of vector (RT + ND) spaces.
- Added element flux, and flux energy computation in class ElasticityIntegrator,
allowing for the use of Zienkiewicz-Zhu type error estimators with the
integrator. For an illustration of this addition, see the new Example 22.
- Added a variety of coefficients which are sums or products of existing
coefficients as well as grid function coefficients which return the
divergence, gradient, or curl of their GridFunctions.
Support for wedge elements and meshes with mixed element types
--------------------------------------------------------------
- Added support for wedge-shaped mesh elements of arbitrary order (with Geometry
type PRISM) which have two triangular faces and three quadrilateral faces.
Several examples of such meshes can be found in the data/ directory.
- Added H1 and L2 finite elements of arbitrary order for Wedge elements.
- Added support for mixed meshes containing triangles and quadrilaterals in 2D
or tetrahedra, wedges, and hexahedra in 3D. This includes support for uniform
refinement of such meshes. Several examples of such meshes can be found in the
data/ directory.
- Added support for reading and writing linear and quadratic meshes containing
wedge elements in VTK mesh format. Several examples of such meshes can be
found in the data/ directory.
Other meshing improvements
--------------------------
- Improved the uniform refinement of tetrahedral meshes (also part of the
uniform refinement of mixed 3D meshes). The previous refinement algorithm is
still available as an option in Mesh::UniformRefinement. Both can be used in
the updated Mesh Explorer miniapp.
- The local tetrahedral mesh refinement algorithm in serial and in parallel now
follows precisely the paper:
D. Arnold, A. Mukherjee, and L. Pouly, "Locally Adapted Tetrahedral Meshes
Using Bisection", SIAM J. Sci. Comput. 22 (2000), 431448.
This guarantees that the shape regularity of the elements will be preserved
under refinement.
- Added support for parallel communication groups on non-conforming meshes.
- Improved parallel partitioning of non-conforming meshes. If the coarse mesh
elements are ordered as a sequence of face-neighbors, the parallel partitions
are now guaranteed to be continuous. To that end, inline quadrilateral and
hexahedral meshes are now by default ordered along a space-filling curve.
- A boundary in a NURBS mesh can now be connected with another boundary. Such a
periodic NURBS mesh is a simple way to impose periodic boundary conditions.
- Added support for reading linear and quadratic 2D quadrilateral and triangular
Cubit meshes.
- The TMOP mesh optimization algorithms were extended to support user-defined
space-dependent limiting terms. Improved the TMOP objective functions by more
accurate normalization of the different terms.
New and updated examples and miniapps
-------------------------------------
- Added a new meshing miniapp, Toroid, which can produce a variety of torus
shaped meshes by twisting a stack of wedges or hexahedra.
- Added a new meshing miniapp, Extruder, that demonstrates the capability to
produce 3D meshes by extruding 2D meshes.
- Added a simple miniapp, LOR Transfer, for visualizing the actions of the
transfer operators between a high-order and a low-order refined spaces.
- Added a new example, Example 20/20p, that solves a system of 1D ODEs derived
from a Hamiltonian. The example demonstrates the use of the variable order,
symplectic integration algorithm implemented in class SIAVSolver.
- Added a new example, Example 22/22p, that illustrates the use of AMR to solve
a linear elasticity problem. This is an extension of Example 2/2p.
New and improved solvers and preconditioners
--------------------------------------------
- Added support for parallel ILU preconditioning via hypre's Euclid solver.
- Added support for STRUMPACK v3 with a small API change in the class
STRUMPACKSolver, see "API changes" below.
Miscellaneous
-------------
- In SparseMatrix added the option to perform MultTranspose() by matvec with
computed and stored transpose matrix. This is required for deterministic
results when using devices such as CUDA and OpenMP.
- Added unit tests based on the Catch++ library.
- Renamed the option MFEM_USE_OPENMP to MFEM_USE_LEGACY_OPENMP. This legacy
option is deprecated and planned for removal in a future release. The original
option name, MFEM_USE_OPENMP, is now used to enable the new OpenMP backends in
the new kernels.
- Altered the way FGMRES counts its iterations so that it matches GMRES.
- Various other simplifications, extensions, and bugfixes in the code.
API changes
-----------
- In multiple places, use Geometry::Type instead of int, where appropriate.
- In multiple places, use Element::Type instead of int, where appropriate.
- The Mesh methods GetElementBaseGeometry and GetBdrElementBaseGeometry no
longer have a default value for their parameter, they only work with an
explicitly given index.
- In class Mesh, added methods useful for queries regarding the types of
elements present in the mesh: HasGeometry, GetNumGeometries, GetGeometries,
and class Mesh::GeometryList.
- The struct CoarseFineTransformations (returned by the Mesh method
GetRefinementTransforms) now stores the embedding matrices separately for each
Geometry::Type.
- In class ParMesh, replaced the method GroupNFaces with two new methods:
GroupNTriangles and GroupNQuadrilaterals. Also, replaced GroupFace with two
methods: GroupTriangle and GroupQuadrilateral.
- In class ParMesh, made the two RefineGroups methods protected.
- Removed the virtual method Element::GetRefinementFlag, it is only used by the
derived class Tetrahedron.
- Added new methods: Array::CopyTo, Tetrahedron::Init.
- In class STRUMPACKSolver, the method SetMC64Job() was replaced by the new
methods: DisableMatching(), EnableMatching(), and EnableParallelMatching().
Version 3.4, released on May 29, 2018
=====================================
More general and efficient mesh adaptivity
------------------------------------------
- Added support for PUMI, the Parallel Unstructured Mesh Infrastructure from
https://scorec.rpi.edu/pumi. PUMI is an unstructured, distributed mesh data
management system that is capable of handling general non-manifold models and
effectively supports automated adaptive analysis. PUMI enables for the first
time support for parallel unstructured modifications of MFEM meshes.
Version 3.3.3 (development)
===========================
More efficient non-conforming adaptive mesh refinement
------------------------------------------------------
- Significantly reduced MPI communication in the construction of the parallel
prolongation matrix in ParFiniteElementSpace, for much improved parallel
scaling of non-conforming AMR on hundreds of thousands of MPI tasks. The
@@ -235,10 +54,8 @@ Discretization improvements
- In the classes NonlinearForm and ParNonlinearForm, added support for
non-conforming AMR meshes; see also the "API changes" section.
- New specialized time integrators: symplectic integrators of orders 1-4 for
systems of first order ODEs derived from a Hamiltonian and generalized-alpha
ODE solver for the filtered NavierStokes equations with stabilization. See
classes SIASolver and GeneralizedAlphaSolver in linalg/ode.hpp.
- Added symplectic integrators of orders 1-4 for systems of first order ODEs
derived from a Hamiltonian, see class SIASolver in linalg/ode.hpp.
- Inherit finite element classes from the new base class TensorBasisElement,
whenever the basis can be represented by a tensor product of 1D bases.
@@ -262,11 +79,6 @@ New and updated examples and miniapps
NURBS meshes in the miniapps/nurbs directory. Currently the directory contains
variable order NURBS versions of examples 1, 1p and 11p.
- Added PUMI versions of examples ex1, ex1p, ex2 and ex6p in a new examples/pumi
directory. The new examples demonstrate the PUMI APIs for parallel and serial
mesh loading (ex1 and ex1p), applying BCs using classification (ex2), and
performing parallel mesh adaptation (ex6p).
- Added two new miniapps related to DataCollection I/O in miniapps/tools:
load-dc.cpp can be used to visualize fields saved via DataCollection classes;
convert-dc.cpp demonstrates how to convert between MFEM's different concrete
+15 -96
View File
@@ -13,11 +13,6 @@ cmake_minimum_required(VERSION 2.8.11)
set(USER_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/config/user.cmake" CACHE PATH
"Path to optional user configuration file.")
# Require C++11 and disable compiler-specific extensions
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Load user settings before the defaults - this way the defaults will not
# overwrite the user set options. If the user has not set all options, we still
# have the defaults.
@@ -50,7 +45,7 @@ project(mfem NONE)
# Current version of MFEM, see also `makefile`.
# mfem_VERSION = (string)
# MFEM_VERSION = (int) [automatically derived from mfem_VERSION]
set(${PROJECT_NAME}_VERSION 3.4.1)
set(${PROJECT_NAME}_VERSION 3.3.3)
# Prohibit in-source build
if (${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR})
@@ -86,13 +81,6 @@ include("${CMAKE_CURRENT_SOURCE_DIR}/config/XSDKDefaults.cmake")
# Enable languages.
enable_language(CXX)
if (MFEM_USE_CUDA)
# MFEM_USE_CUDA requires CMake 3.8 or newer (for direct CUDA support)
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
enable_language(CUDA)
message(STATUS "Using CUDA architecture: ${CUDA_ARCH}")
endif()
if (XSDK_ENABLE_C)
enable_language(C)
endif()
@@ -151,7 +139,7 @@ if (MFEM_USE_MPI)
set(PETSC_INCLUDE_DIRS ${PETSC_INCLUDES})
endif()
else()
set(PKGS_NEED_MPI SUPERLU PETSC STRUMPACK PUMI)
set(PKGS_NEED_MPI SUPERLU PETSC STRUMPACK)
foreach(PKG IN LISTS PKGS_NEED_MPI)
if (MFEM_USE_${PKG})
message(STATUS "Disabling package ${PKG} - requires MPI")
@@ -182,11 +170,12 @@ if (MFEM_USE_LAPACK)
endif()
# OpenMP
if (MFEM_USE_OPENMP OR MFEM_USE_LEGACY_OPENMP)
if (NOT MFEM_THREAD_SAFE AND MFEM_USE_LEGACY_OPENMP)
message(FATAL_ERROR " *** MFEM_USE_LEGACY_OPENMP requires MFEM_THREAD_SAFE=ON.")
if (MFEM_USE_OPENMP)
if (MFEM_THREAD_SAFE)
find_package(OpenMP REQUIRED)
else()
message(FATAL_ERROR " *** MFEM_USE_OPENMP requires MFEM_THREAD_SAFE=ON.")
endif()
find_package(OpenMP REQUIRED)
endif()
# SuiteSparse (before SUNDIALS which may depend on KLU)
@@ -257,48 +246,6 @@ if (MFEM_USE_SIDRE)
find_package(Axom REQUIRED Sidre SLIC axom_utils)
endif()
# PUMI
if (MFEM_USE_PUMI)
# If PUMI_DIR was specified, only link to that directory,
# i.e. don't link to another installation in /usr/lib by mistake
find_package(SCOREC 2.1.0 REQUIRED OPTIONAL_COMPONENTS gmi_sim
CONFIG PATHS ${PUMI_DIR} NO_DEFAULT_PATH)
if (SCOREC_FOUND)
# Define a header file with the MFEM_USE_SIMMETRIX preprocessor variable
set(MFEM_USE_SIMMETRIX ${SCOREC_gmi_sim_FOUND})
set(PUMI_FOUND ${SCOREC_FOUND})
get_target_property(PUMI_INCLUDE_DIRS
SCOREC::apf INTERFACE_INCLUDE_DIRECTORIES)
set(PUMI_LIBRARIES SCOREC::core)
endif()
endif()
# CUDA
if (MFEM_USE_CUDA)
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_EXTENSIONS OFF)
set(CMAKE_CUDA_FLAGS "-arch=${CUDA_ARCH} --expt-extended-lambda"
CACHE STRING "CUDA flags set for MFEM" FORCE)
if (MFEM_USE_MPI)
set(CUDA_CCBIN_COMPILER ${MPI_CXX_COMPILER})
else()
set(CUDA_CCBIN_COMPILER ${CMAKE_CXX_COMPILER})
endif()
string(APPEND CMAKE_CUDA_FLAGS " -ccbin ${CUDA_CCBIN_COMPILER}")
set(MFEM_USE_MM YES CACHE BOOL "Enable MFEM's memory manager" FORCE)
endif()
# OCCA
if (MFEM_USE_OCCA)
find_package(OCCA REQUIRED)
endif()
# RAJA
if (MFEM_USE_RAJA)
find_package(RAJA REQUIRED)
endif()
# MFEM_TIMER_TYPE
if (NOT DEFINED MFEM_TIMER_TYPE)
if (APPLE)
@@ -323,8 +270,8 @@ endif()
# integers, the METIS header (with 32-bit indices, as used by mfem) needs to
# be before SuiteSparse.
set(MFEM_TPLS MPI_CXX OPENMP BLAS LAPACK METIS HYPRE SuiteSparse SUNDIALS PETSC
MESQUITE SuperLUDist STRUMPACK AXOM CONDUIT GECKO GNUTLS NETCDF MPFR PUMI
POSIXCLOCKS MFEMBacktrace ZLIB OCCA RAJA)
MESQUITE SuperLUDist STRUMPACK AXOM CONDUIT GECKO GNUTLS NETCDF MPFR POSIXCLOCKS
MFEMBacktrace ZLIB)
# Add all *_FOUND libraries in the variable TPL_LIBRARIES.
set(TPL_LIBRARIES "")
set(TPL_INCLUDE_DIRS "")
@@ -349,6 +296,9 @@ message(STATUS "MFEM build type: CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}")
message(STATUS "MFEM version: v${MFEM_VERSION_STRING}")
message(STATUS "MFEM git string: ${MFEM_GIT_STRING}")
# Windows specific
set(_USE_MATH_DEFINES ${WIN32})
#-------------------------------------------------------------------------------
# Define and configure the MFEM library
#-------------------------------------------------------------------------------
@@ -360,13 +310,6 @@ set(MFEM_SOURCE_DIRS general linalg mesh fem)
foreach(DIR IN LISTS MFEM_SOURCE_DIRS)
add_subdirectory(${DIR})
endforeach()
if (MFEM_USE_CUDA)
foreach(file IN LISTS SOURCES)
set_property(SOURCE ${file} PROPERTY LANGUAGE CUDA)
endforeach()
endif()
add_subdirectory(config)
set(MASTER_HEADERS
${PROJECT_SOURCE_DIR}/mfem.hpp
@@ -377,11 +320,6 @@ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON CACHE BOOL "")
set(CMAKE_INSTALL_RPATH "${_lib_path}" CACHE PATH "")
set(CMAKE_INSTALL_NAME_DIR "${_lib_path}" CACHE PATH "")
set(MFEM_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
"The MFEM source directory" FORCE)
set(MFEM_INSTALL_DIR ${CMAKE_INSTALL_PREFIX} CACHE PATH
"The MFEM install directory" FORCE)
# Declaring the library
add_library(mfem ${SOURCES} ${HEADERS} ${MASTER_HEADERS})
# message(STATUS "TPL_LIBRARIES = ${TPL_LIBRARIES}")
@@ -434,9 +372,6 @@ endif()
# Enable testing if required
if (MFEM_ENABLE_TESTING)
enable_testing()
set(MFEM_ALL_TESTS_TARGET_NAME tests)
add_mfem_target(${MFEM_ALL_TESTS_TARGET_NAME} OFF)
add_subdirectory(tests EXCLUDE_FROM_ALL)
endif()
# Define a target that all examples and miniapps will depend on.
@@ -456,9 +391,7 @@ add_subdirectory(miniapps EXCLUDE_FROM_ALL)
# Target to build all executables, i.e. everything.
add_custom_target(exec)
add_dependencies(exec
${MFEM_ALL_EXAMPLES_TARGET_NAME}
${MFEM_ALL_MINIAPPS_TARGET_NAME}
${MFEM_ALL_TESTS_TARGET_NAME})
${MFEM_ALL_EXAMPLES_TARGET_NAME} ${MFEM_ALL_MINIAPPS_TARGET_NAME})
# Here, we want to "add_dependencies(test exec)". However, dependencies for
# 'test' (and other built-in targets) can not be added with add_dependencies():
# - https://gitlab.kitware.com/cmake/cmake/issues/8438
@@ -479,12 +412,12 @@ endif()
# Add 'check' target - quick test
if (NOT MFEM_USE_MPI)
add_custom_target(check
${CMAKE_CTEST_COMMAND} -R \"^ex1_ser\" -C ${CMAKE_CFG_INTDIR}
${CMAKE_CTEST_COMMAND} -R '^ex1_ser' -C ${CMAKE_CFG_INTDIR}
USES_TERMINAL)
add_dependencies(check ex1)
else()
add_custom_target(check
${CMAKE_CTEST_COMMAND} -R \"^ex1p\" -C ${CMAKE_CFG_INTDIR}
${CMAKE_CTEST_COMMAND} -R '^ex1p' -C ${CMAKE_CFG_INTDIR}
USES_TERMINAL)
add_dependencies(check ex1p)
endif()
@@ -529,13 +462,6 @@ install(DIRECTORY ${MFEM_SOURCE_DIRS}
DESTINATION ${INSTALL_INCLUDE_DIR}/mfem
FILES_MATCHING PATTERN "*.hpp")
# Install the okl files
if (MFEM_USE_OCCA)
install(DIRECTORY ${MFEM_SOURCE_DIRS}
DESTINATION ${INSTALL_INCLUDE_DIR}/mfem
FILES_MATCHING PATTERN "*.okl")
endif()
# Install ${HEADERS}
# ---
# foreach (HDR ${HEADERS})
@@ -601,10 +527,3 @@ install(FILES
# Install the export set for use with the install-tree
install(EXPORT ${PROJECT_NAME_UC}Targets
DESTINATION ${INSTALL_CMAKE_DIR})
#-------------------------------------------------------------------------------
# Create 'config.mk' from 'config.mk.in' for the build and install locations and
# define install rules for 'config.mk' and 'test.mk'
#-------------------------------------------------------------------------------
mfem_export_mk_files()
+6 -124
View File
@@ -1,15 +1,3 @@
<p align="center">
<a href="http://mfem.org/"><img alt="mfem" src="http://mfem.org/img/logo-300.png"></a>
</p>
<p align="center">
<a href="https://github.com/mfem/mfem/blob/master/COPYRIGHT"><img alt="License" src="https://img.shields.io/badge/License-LGPL--2.1-brightgreen.svg"></a>
<a href="https://travis-ci.org/mfem/mfem"><img alt="Build Status" src="https://travis-ci.org/mfem/mfem.svg?branch=master"></a>
<a href="https://ci.appveyor.com/project/mfem/mfem"><img alt="Build Status" src="https://ci.appveyor.com/api/projects/status/19non9sqm6msi2wy?svg=true"></a>
<a href="http://mfem.github.io/doxygen/html/index.html"><img alt="Doxygen" src="https://img.shields.io/badge/code-documented-brightgreen.svg"></a>
</p>
# How to Contribute
The MFEM team welcomes contributions at all levels: bugfixes; code
@@ -28,7 +16,6 @@ See the [Quick Summary](#quick-summary) section for the main highlights of our
GitHub workflow. For more details, consult the following sections and refer
back to them before issuing pull requests:
- [Code Overview](#code-overview)
- [GitHub Workflow](#github-workflow)
- [MFEM Organization](#mfem-organization)
- [New Feature Development](#new-feature-development)
@@ -66,112 +53,6 @@ Origin](#developers-certificate-of-origin-11) at the end of this file.*
- Don't hesitate to [contact us](#contact-information) if you have any questions.
### Code Overview
- The MFEM library uses object-orient design principles which reflect, in code,
the independent mathematical concepts of meshing, linear algebra and finite
element spaces and operators.
- The MFEM source code has the following structure:
```
.
├── config
│ └── cmake
│ └── modules
├── data
├── doc
│ └── web
│ └── examples
├── examples
│ ├── petsc
│ ├── pumi
│ └── sundials
├── fem
├── general
├── linalg
├── mesh
├── miniapps
│ ├── common
│ ├── electromagnetics
│ ├── meshing
│ ├── nurbs
│ ├── performance
│ └── tools
└── tests
├── unit
│ ├── ...
└── ...
```
- The main directories are `fem/`, `mesh/` and `linalg/` containing the C++
classes implementing the finite element, mesh and linear algebra concepts
respectively.
- The main mesh classes are:
+ [`Mesh`](http://mfem.github.io/doxygen/html/classmfem_1_1Mesh.html)
+ [`NCMesh`](http://mfem.github.io/doxygen/html/classmfem_1_1NCMesh.html)
+ [`Element`](http://mfem.github.io/doxygen/html/classmfem_1_1Element.html)
+ [`ElementTransformation`](http://mfem.github.io/doxygen/html/classmfem_1_1ElementTransformation.html)
- The main finite element classes are:
+ [`FiniteElement`](http://mfem.github.io/doxygen/html/classmfem_1_1FiniteElement.html)
+ [`FiniteElementCollection`](http://mfem.github.io/doxygen/html/classmfem_1_1FiniteElement.html)
+ [`FiniteElementSpace`](http://mfem.github.io/doxygen/html/classmfem_1_1FiniteElementSpace.html)
+ [`GridFunction`](http://mfem.github.io/doxygen/html/classmfem_1_1GridFunction.html)
+ [`BilinearFormIntegrator`](http://mfem.github.io/doxygen/html/classmfem_1_1BilinearFormIntegrator.html) and [`LinearFormIntegrator`](http://mfem.github.io/doxygen/html/classmfem_1_1LinearFormIntegrator.html)
+ [`LinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1LinearFormIntegrator.html), [`BilinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1BilinearForm.html) and [`MixedBilinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1MixedBilinearForm.html)
- The main linear algebra classes and sources are
+ [`Operator`](http://mfem.github.io/doxygen/html/classmfem_1_1Operator.html) and [`BilinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1BilinearForm.html)
+ [`Vector`](http://mfem.github.io/doxygen/html/classmfem_1_1BilinearForm.html) and [`LinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1LinearForm.html)
+ [`DenseMatrix`](http://mfem.github.io/doxygen/html/classmfem_1_1DenseMatrix.html) and [`SparseMatrix`](http://mfem.github.io/doxygen/html/classmfem_1_1SparseMatrix.html)
+ Sparse [smoothers](http://mfem.github.io/doxygen/html/sparsesmoothers_8hpp.html) and linear [solvers](http://mfem.github.io/doxygen/html/solvers_8hpp.html)
- Parallel MPI objects in MFEM inherit their serial counterparts, so a parallel
mesh for example is just a serial mesh on each task plus the information on
shared geometric entities between different tasks. The parallel source files
have a `p` prefix, e.g. `pmesh.cpp` vs. the serial `mesh.cpp`.
- The main parallel classes are
+ [`ParMesh`](http://mfem.github.io/doxygen/html/solvers_8hpp.html)
+ [`ParNCMesh`](http://mfem.github.io/doxygen/html/classmfem_1_1ParMesh.html)
+ [`ParFiniteElementSpace`](http://mfem.github.io/doxygen/html/classmfem_1_1ParFiniteElementSpace.html)
+ [`ParGridFunction`](http://mfem.github.io/doxygen/html/classmfem_1_1ParGridFunction.html)
+ [`ParBilinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1ParBilinearForm.html) and [`ParLinearForm`](http://mfem.github.io/doxygen/html/classmfem_1_1ParLinearForm.html)
+ [`HypreParMatrix`](http://mfem.github.io/doxygen/html/classmfem_1_1HypreParMatrix.html) and [`HypreParVector`](http://mfem.github.io/doxygen/html/classmfem_1_1HypreParVector.html)
+ [`HypreSolver`](http://mfem.github.io/doxygen/html/classmfem_1_1HypreSolver.html) and other [hypre classes](http://mfem.github.io/doxygen/html/hypre_8hpp.html)
- GPU and multi-core CPU support is based on device kernels supporting different
backends (CUDA, OCCA, RAJA, OpenMP, etc.) and an internal lightweight
device/host memory manager.
- The main device-relevant classes and sources are:
+ [`Device`](http://mfem.github.io/doxygen/html/device_8hpp.html)
+ [`MemoryManager`](http://mfem.github.io/doxygen/html/mem_manager_8hpp.html)
+ the [`MFEM_FORALL`](http://mfem.github.io/doxygen/html/forall_8hpp.html) macro
+ the [`cuda.hpp`](http://mfem.github.io/doxygen/html/cuda_8hpp.html) and [`occa.hpp`](http://mfem.github.io/doxygen/html/occa_8hpp.html) files
- The `general/` directory contains C++ classes that serve as utilities for
communication, error handling, arrays, (Boolean) tables, timing, etc.
- The `config/` directory contains build-related files, both for the plain
Makefile and the CMake build options.
- The `doc/` directory contains configuration for the Doxygen code documentation
that can either be build locally, or browsed online at
http://mfem.github.io/doxygen/html/index.html.
- The `data/` directory contains a collection of small mesh files, that are used
in the simple example codes and more fully-featured mini applications in the
`examples/` and `miniapps/` directories.
- The `tests/` directory contains a unit test suite and will later contain more
tests that run example codes.
- See also the [code overview](http://mfem.org/code-overview/) section on the
MFEM website.
## GitHub Workflow
The GitHub organization, https://github.com/mfem, is the main developer hub for
@@ -241,7 +122,7 @@ will allow us to reach you directly with project announcements.
# Work on "feature-dev", add local commits
# ...
# (One time only) push the branch to github and setup your local
# One time only) push the branch to github and setup your local
# branch to track the github branch (for "git pull"):
git push -u origin feature-dev
@@ -334,9 +215,9 @@ Before a PR can be merged, it should satisfy the following:
- [ ] Is this a new feature users need to be aware of? New or updated example or miniapp?
- [ ] Does it make sense to create a new section in the `CHANGELOG` to group with other related features?
- [ ] Update `INSTALL`:
- [ ] Had a new optional library been added? (*Make sure the external library is licensed under LGPL, not GPL!*)
- [ ] Has a new optional library been added? (*Make sure the external library is licensed under LGPL, not GPL!*)
- [ ] Does `make` or `cmake` have a new target?
- [ ] Did the requirements or the installation process change? *(rare)*
- [ ] Did the requirements or the installation process change? *(rare)*.
- [ ] Update `.gitignore`:
- [ ] Check if `make distclean; git status` shows any files that are generated from the source but we don't want to track in the repository.
- [ ] Add new patterns (just for the new files above) and re-run the above test.
@@ -376,10 +257,10 @@ Before a PR can be merged, it should satisfy the following:
- [ ] If this is a major new feature, consider mentioning in the short summary inside `README` *(rare)*.
- [ ] List major new classes in `doc/CodeDocumentation.dox` *(rare)*.
- [ ] Update this checklist, if the new pull request affects it.
- [ ] Run the unit tests and make sure they all pass `make unittest`.
- [ ] (LLNL only) Clone the `tests` repository and run the following tests, see `mfem/tests/README.md`:
- [ ] `compilers`
- [ ] `memcheck`
- [ ] `unit-test`
- [ ] `documentation`
- [ ] (LLNL only) After merging:
- [ ] Regenerate `README.html` files from companion documentation pull requests.
@@ -451,7 +332,7 @@ MFEM uses a `master`/`next`-branch workflow as described below:
- [ ] `CHANGELOG`
- [ ] `makefile`
- [ ] `CMakeLists.txt`
- [ ] `doc/CodeDocumentation.conf.in`
- [ ] `doc/CodeDocumentation.conf`
- [ ] (LLNL only) Make sure all `README.html` files in the source repo are up to date.
- [ ] Tag the repository:
@@ -490,6 +371,7 @@ MFEM uses a `master`/`next`-branch workflow as described below:
- `mfem:gh-next` -- Bleeding-edge development version, may be broken, use at
your own risk.
## Automated Testing
MFEM has several levels of automated testing running on GitHub, as well as on
+16 -126
View File
@@ -13,52 +13,22 @@ of MFEM is a (modern) C++ compiler, such as g++. The parallel version of MFEM
requires an MPI C++ compiler, as well as the following external libraries:
- hypre (a library of high-performance preconditioners)
https://github.com/hypre-space/hypre
http://www.llnl.gov/CASC/hypre
- METIS (a family of multilevel partitioning algorithms)
http://glaros.dtc.umn.edu/gkhome/metis/metis/overview
The hypre dependency can be downloaded as a tarball from GitHub or from the
project webpage https://www.llnl.gov/casc/hypre. For example, the 2.16.0 release
of hypre is available at
https://github.com/hypre-space/hypre/archive/v2.16.0.tar.gz
The METIS dependency can be disabled but that is not generally recommended, see
the option MFEM_USE_METIS.
MFEM also includes support for devices such as GPUs, and programming models such
as CUDA, OCCA, OpenMP and RAJA.
- Starting with version 4.0, MFEM requires a C++11 compiler
- CUDA support requires an NVIDIA GPU and an installation of the CUDA Toolkit
https://developer.nvidia.com/cuda-toolkit
- OCCA support requires the OCCA library
https://libocca.org
- OpenMP support requires a compiler implementing the OpenMP API
https://www.openmp.org
- RAJA support requires installation of the RAJA performance portability layer
with (optionally) support for CUDA and OpenMP
https://github.com/LLNL/RAJA
The library supports two build systems: one based on GNU make, and a second one
based on CMake. Both build systems are described below. Some hints for building
without GNU make or CMake can be found at the end of this file.
In addition to the native build systems, MFEM packages are also available in the
following package managers:
In addition to the native build systems, MFEM packages are also available in
the Homebrew/Science, https://github.com/Homebrew/homebrew-science, and the
Spack, https://github.com/LLNL/spack, package managers.
- Spack, https://github.com/spack/spack
- OpenHPC, http://openhpc.community
- Homebrew/Science, https://github.com/Homebrew/homebrew-science (deprecated)
We also recommend downloading and building the MFEM-based GLVis visualization
tool which can be used to visualize the meshes and solution in MFEM's examples
and miniapps. See http://glvis.org and http://mfem.org/building.
Quick start with GNU make
=========================
@@ -66,15 +36,11 @@ Serial build:
make serial -j 4
Parallel build:
(download hypre and METIS 4 from above URLs)
(download hypre 2.10.0b and METIS 4 from above URLs)
(build METIS 4 in ../metis-4.0 relative to mfem/)
(build hypre in ../hypre relative to mfem/)
(build hypre 2.10.0b in ../hypre-2.10.0b relative to mfem/)
make parallel -j 4
CUDA build:
make cuda -j 4
(build for a specific compute capability: 'make cuda -j 4 CUDA_ARCH=sm_30')
Example codes (serial/parallel, depending on the build):
cd examples
make -j 4
@@ -85,6 +51,7 @@ Build everything (library, examples and miniapps) with current configuration:
Quick-check the build by running Example 1/1p (optional):
make check
Quick start with CMake
======================
Serial build:
@@ -93,19 +60,13 @@ Serial build:
make -j 4 (assuming "UNIX Makefiles" generator)
Parallel build:
(download hypre and METIS 4 from above URLs)
(download hypre 2.10.0b and METIS 4 from above URLs)
(build METIS 4 in ../metis-4.0 relative to mfem/)
(build hypre in ../hypre relative to mfem/)
(build hypre 2.10.0b in ../hypre-2.10.0b relative to mfem/)
mkdir <mfem-build-dir> ; cd <mfem-build-dir>
cmake <mfem-source-dir> -DMFEM_USE_MPI=YES
make -j 4
CUDA build:
(this build requires CMake 3.8 or newer)
mkdir <mfem-build-dir> ; cd <mfem-build-dir>
cmake <mfem-source-dir> -DMFEM_USE_CUDA=YES
make -j 4
Example codes (serial/parallel, depending on the build):
make examples -j 4
@@ -165,10 +126,6 @@ are also defined:
make parallel -> Builds parallel optimized version of the library
make debug -> Builds serial debug version of the library
make pdebug -> Builds parallel debug version of the library
make cuda -> Builds serial cuda optimized version of the library
make pcuda -> Builds parallel cuda optimized version of the library
make cudebug -> Builds serial cuda debug version of the library
make pcudebug -> Builds parallel cuda debug version of the library
Note that any of the above shortcuts accept configuration options, either at the
command line or through a user configuration file.
@@ -230,9 +187,8 @@ Configuration options (GNU make)
See the configuration file config/defaults.mk for the default settings.
Compilers:
CXX - C++ compiler, serial build
MPICXX - MPI C++ compiler, parallel build
CUDA_CXX - The CUDA compiler, 'nvcc'
CXX - C++ compiler, serial build
MPICXX - MPI C++ compiler, parallel build
Compiler options:
OPTIM_FLAGS - Options for optimized build
@@ -268,7 +224,7 @@ MFEM_DEBUG = YES/NO
and consistency checks that may simplify bug-hunting.
MFEM_USE_EXCEPTIONS = YES/NO
Enable the use of exceptions. In particular, modifies the default behavior
Enable the use of exceptions. In particular, modifies the default bahavior
when errors are encountered: throw an exception, instead of aborting.
MFEM_USE_LIBUNWIND = YES/NO
@@ -288,12 +244,8 @@ MFEM_THREAD_SAFE = YES/NO
Use thread-safe implementation for some classes/methods. This comes at the
cost of extra memory allocation and de-allocation.
MFEM_USE_LEGACY_OPENMP = YES/NO
Enable (basic) experimental OpenMP support. Requires MFEM_THREAD_SAFE.
This option is deprecated.
MFEM_USE_OPENMP = YES/NO
Enable the OpenMP backend.
Enable (basic) experimental OpenMP support. Requires MFEM_THREAD_SAFE.
MFEM_USE_MEMALLOC = YES/NO
Internal MFEM option: enable batch allocation for some small objects.
@@ -397,39 +349,6 @@ MFEM_USE_GZSTREAM = YES/NO
before attempting to use it with MFEM.
When enabled, this option uses the ZLIB_* library options, see below.
MFEM_USE_PUMI = YES/NO
Enable the usage of PUMI (https://scorec.rpi.edu/pumi/) in MFEM. The Parallel
Unstructured Mesh Infrastructure (PUMI) is an unstructured, distributed mesh
data management system that is capable of handling general non-manifold
models and effectively supports automated adaptive analysis. PUMI enables
support for parallel unstructured mesh modifications in MFEM.
MFEM_USE_MM = YES/NO
Enables support for the MFEM's memory manager (MM), which is required to
support devices with different memory spaces. This option is required when
CUDA support is enabled, i.e. when MFEM_USE_CUDA=YES.
MFEM_USE_CUDA = YES/NO
Enables support for CUDA devices in MFEM. CUDA is a parallel computing
platform and programming model for general computing on graphical processing
units (GPUs). This option requires MFEM_USE_MM. The variable CUDA_ARCH is
used to specify the CUDA compute capability used during compilation (by
default, CUDA_ARCH=sm_60). When enabled, this option uses the CUDA_* build
options, see below.
MFEM_USE_RAJA = YES/NO
Enable support for the RAJA performance portability layer in MFEM. RAJA
provides a portable abstraction for loops, supporting different programming
model backends. When using RAJA built with CUDA support, CUDA support must be
also enabled in MFEM, i.e. MFEM_USE_CUDA=YES must be set.
MFEM_USE_OCCA = YES/NO
Enables support for the OCCA library in MFEM. OCCA is an open-source library
which aims to make it easy to program different types of devices (e.g. CPU,
GPU, FPGA) by providing an unified API for interacting with JIT-compiled
backends. In order to use the OCCA CUDA backend, CUDA support must be enabled
in MFEM as well, i.e. MFEM_USE_CUDA=YES must be set.
MFEM_BUILD_TAG = (any value)
An optional tag to characterize the build. Exported to config/config.mk.
Can be used to identify the MFEM build from other makefiles.
@@ -451,7 +370,7 @@ directory and use the string @MFEM_DIR@, e.g. HYPRE_OPT = -I@MFEM_DIR@/../hypre.
The specific libraries and their options are:
- HYPRE, required for the parallel build, i.e. when MFEM_USE_MPI = YES.
URL: https://github.com/hypre-space/hypre and https://www.llnl.gov/casc/hypre
URL: http://www.llnl.gov/CASC/hypre
Options: HYPRE_OPT, HYPRE_LIB.
- METIS, used when MFEM_USE_METIS = YES. If using METIS 5, set
@@ -465,8 +384,7 @@ The specific libraries and their options are:
http://math-atlas.sourceforge.net (ATLAS)
Options: LAPACK_OPT (currently not used/needed), LAPACK_LIB.
- OpenMP (optional), usually part of compiler, used when either MFEM_USE_OPENMP
or MFEM_USE_LEGACY_OPENMP is set to YES.
- OpenMP (optional), usually part of compiler, used when MFEM_USE_OPENMP = YES.
Options: OPENMP_OPT, OPENMP_LIB.
- High-resolution POSIX clocks: when using MFEM_TIMER_TYPE = 2, it may be
@@ -498,8 +416,7 @@ The specific libraries and their options are:
- STRUMPACK (optional), used when MFEM_USE_STRUMPACK = YES. Note that STRUMPACK
requires the PT-Scotch and Scalapack libraries as well as ParMETIS, which
includes METIS 5 in its distribution. Starting with STRUMPACK v2.2.0, ParMETIS
and PT-Scotch are optional dependencies.
includes METIS 5 in its distribution.
The support for STRUMPACK was added in MFEM v3.3.2 and it requires STRUMPACK
2.0.0 or later.
URL: http://portal.nersc.gov/project/sparse/strumpack
@@ -541,22 +458,6 @@ The specific libraries and their options are:
https://support.hdfgroup.org/HDF5 (HDF5)
Options: CONDUIT_OPT, CONDUIT_LIB.
- PUMI, used when MFEM_USE_PUMI = YES.
URL: https://scorec.rpi.edu/pumi
Options: PUMI_OPT, PUMI_LIB.
- CUDA, used when MFEM_USE_CUDA = YES.
URL: https://developer.nvidia.com/cuda-toolkit
Options: CUDA_CXX, CUDA_ARCH, CUDA_OPT, CUDA_LIB.
- OCCA, used when MFEM_USE_OCCA = YES.
URL: https://libocca.org
Options: OCCA_DIR, OCCA_OPT, OCCA_LIB.
- RAJA, used when MFEM_USE_RAJA = YES.
URL: https://github.com/LLNL/RAJA
Options: RAJA_DIR, RAJA_OPT, RAJA_LIB.
- MPFR (optional), used when MFEM_USE_MPFR = YES.
URL: http://mpfr.org, it depends on the GMP library: https://gmplib.org
Options: MPFR_OPT, MPFR_LIB.
@@ -661,8 +562,6 @@ Configuration variables (CMake)
===============================
See the configuration file config/defaults.cmake for the default settings.
Note: the option MFEM_USE_CUDA requires CMake version 3.8 or newer!
Non-standard CMake variables for compilers:
CXX - If set, overwrite the auto-detected C++ compiler, serial build
MPICXX - If set, overwrite the auto-detected MPI C++ compiler, parallel build
@@ -680,7 +579,6 @@ MFEM_USE_METIS - Set to ${MFEM_USE_MPI}, can be overwritten.
MFEM_USE_LIBUNWIND
MFEM_USE_LAPACK
MFEM_THREAD_SAFE
MFEM_USE_LEGACY_OPENMP
MFEM_USE_OPENMP
MFEM_USE_MEMALLOC
MFEM_TIMER_TYPE - Set automatically, can be overwritten.
@@ -692,11 +590,6 @@ MFEM_USE_GNUTLS
MFEM_USE_NETCDF
MFEM_USE_MPFR
MFEM_USE_GZSTREAM
MFEM_USE_PUMI
MFEM_USE_CUDA
MFEM_USE_OCCA
MFEM_USE_RAJA
MFEM_USE_MM
The following options are CMake specific:
@@ -742,9 +635,6 @@ The CMake build system adds auto-detection for the following packages/libraries:
- MPFR
- LIBUNWIND
- POSIXCLOCKS
- PUMI
- OCCA
- RAJA
The following built-in CMake packages are also used:
+11 -11
View File
@@ -1,5 +1,5 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@@ -10,7 +10,7 @@
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@@ -112,7 +112,7 @@ modification follow. Pay close attention to the difference between a
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
@@ -146,7 +146,7 @@ such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
@@ -432,7 +432,7 @@ decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
@@ -455,7 +455,7 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
@@ -485,8 +485,7 @@ convey the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
@@ -495,10 +494,11 @@ school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random
Hacker.
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
+22 -28
View File
@@ -8,19 +8,15 @@
http://mfem.org
MFEM is a modular parallel C++ library for finite element methods. Its goal is
to enable high-performance scalable finite element discretization research and
application development on a wide variety of platforms, ranging from laptops to
supercomputers.
to enable the research and development of scalable finite element discretization
and solver algorithms through general finite element abstractions, accurate and
flexible visualization, and tight integration with the hypre library.
* For building instructions, see the file INSTALL, or type "make help".
For building instructions, see the file INSTALL, or type "make help". Copyright
information and licensing restrictions can be found in the file COPYRIGHT.
* Copyright and licensing information can be found in the file COPYRIGHT.
* The best starting point for new users interested in MFEM's features is the
interactive documentation in examples/README.html.
* Developers interested in contributing to the library, should read the
instructions and documentation in the CONTRIBUTING.md file.
The best starting point for new users interested in MFEM's features is the
interactive documentation in examples/README.html.
Conceptually, MFEM can be viewed as a finite element toolbox that provides the
building blocks for developing finite element algorithms in a manner similar to
@@ -39,30 +35,28 @@ conforming and non-conforming (AMR) adaptive refinement. Arbitrary element
transformations, allowing for high-order mesh elements with curved boundaries,
are also supported.
When used as a "finite element to linear algebra translator", MFEM can take a
problem described in terms of finite element-type objects, and produce the
corresponding linear algebra vectors and fully or partially assembled operators,
e.g. in the form of global sparse matrices or matrix-free operators. The library
includes simple smoothers and Krylov solvers, such as PCG, MINRES and GMRES, as
well as support for sequential sparse direct solvers from the SuiteSparse
MFEM is commonly used as a "finite element to linear algebra translator", since
it can take a problem described in terms of finite element-type objects, and
produce the corresponding linear algebra vectors and sparse matrices. In order
to facilitate this, MFEM uses compressed sparse row (CSR) sparse matrix storage
and includes simple smoothers and Krylov solvers, such as PCG, MINRES and GMRES,
as well as support for sequential sparse direct solvers from the SuiteSparse
library. Nonlinear solvers (the Newton method), eigensolvers (LOBPCG), and
several explicit and implicit Runge-Kutta time integrators are also available.
MFEM supports MPI-based parallelism throughout the library, and can readily be
used as a scalable unstructured finite element problem generator. As of version
4.0, MFEM offers initial support for GPU acceleration, and programming models,
such as CUDA, OCCA, RAJA and OpenMP. MFEM-based applications require minimal
changes to switch from a serial to a high-performing MPI-parallel version of the
code, where they can take advantage of the integrated linear solvers from the
hypre library. Comprehensive support for other external packages, e.g. PETSc
and SUNDIALS is also included, giving access to many additional linear and
nonlinear solvers, preconditioners, time integrators, etc.
used as a scalable unstructured finite element problem generator. MFEM-based
applications require minimal changes to transition from a serial to a
high-performing parallel version of the code, where they can take advantage of
the integrated scalable linear solvers from the hypre library. Comprehensive
support for other external packages, e.g. PETSc and SUNDIALS is also included,
giving access to many additional linear and nonlinear solvers, preconditioners,
time integrators, etc.
For examples of using MFEM, see the examples/ and miniapps/ directories, as well
as the OpenGL visualization tool GLVis which is available at http://glvis.org.
This project is released under the LGPL v2.1 license with static linking
exception. See files COPYRIGHT and LICENSE file for full details.
This project is released under the LGPL v2.1 license. See LICENSE file for full
details.
LLNL Release Number: LLNL-CODE-443211
DOI: 10.11578/dc.20171025.1248
+4 -95
View File
@@ -74,7 +74,7 @@
IF (NOT COMMAND PRINT_VAR)
FUNCTION(PRINT_VAR VAR_NAME)
MESSAGE(STATUS "${VAR_NAME} = '${${VAR_NAME}}'")
MESSAGE("-- " "${VAR_NAME} = '${${VAR_NAME}}'")
ENDFUNCTION()
ENDIF()
@@ -166,108 +166,17 @@ IF (USE_XSDK_DEFAULTS)
ENDIF()
XSDK_HANDLE_LANG_DEFAULTS(Fortran FC "FFLAGS;FCFLAGS")
ENDIF()
# Set XSDK defaults for other CMake variables
IF ("${BUILD_SHARED_LIBS}" STREQUAL "")
MESSAGE("-- " "XSDK: Setting default BUILD_SHARED_LIBS=TRUE")
SET(BUILD_SHARED_LIBS TRUE CACHE BOOL "Set by default in XSDK mode")
ENDIF()
IF ("${CMAKE_BUILD_TYPE}" STREQUAL "")
MESSAGE("-- " "XSDK: Setting default CMAKE_BUILD_TYPE=DEBUG")
SET(CMAKE_BUILD_TYPE DEBUG CACHE STRING "Set by default in XSDK mode")
ENDIF()
ENDIF()
##################################################################################
#
# MFEM-specific additions: set TPL MFEM_USE_* defaults
#
##################################################################################
IF (DEFINED TPL_ENABLE_MPI)
SET(MFEM_USE_MPI ${TPL_ENABLE_MPI} CACHE BOOL "Enable MPI parallel build" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_METIS)
SET(MFEM_USE_METIS ${TPL_ENABLE_METIS} CACHE BOOL "Enable METIS usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_GZSTREAM)
SET(MFEM_USE_GZSTREAM ${TPL_ENABLE_GZSTREAM} CACHE BOOL "Enable gzstream for compressed data streams." FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_LIBUNWIND)
SET(MFEM_USE_LIBUNWIND ${TPL_ENABLE_LIBUNWIND} CACHE BOOL "Enable backtrace for errors." FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_LAPACK)
SET(MFEM_USE_LAPACK ${TPL_ENABLE_LAPACK} CACHE BOOL "Enable LAPACK usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_SUNDIALS)
SET(MFEM_USE_SUNDIALS ${TPL_ENABLE_SUNDIALS} CACHE BOOL "Enable SUNDIALS usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_MESQUITE)
SET(MFEM_USE_MESQUITE ${TPL_ENABLE_MESQUITE} CACHE BOOL "Enable MESQUITE usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_SUITESPARSE)
SET(MFEM_USE_SUITESPARSE ${TPL_ENABLE_SUITESPARSE} CACHE BOOL "Enable SuiteSparse usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_SUPERLU)
SET(MFEM_USE_SUPERLU ${TPL_ENABLE_SUPERLU} CACHE BOOL "Enable SuperLU_DIST usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_STRUMPACK)
SET(MFEM_USE_STRUMPACK ${TPL_ENABLE_STRUMPACK} CACHE BOOL "Enable STRUMPACK usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_GECKO)
SET(MFEM_USE_GECKO ${TPL_ENABLE_GECKO} CACHE BOOL "Enable GECKO usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_GNUTLS)
SET(MFEM_USE_GNUTLS ${TPL_ENABLE_GNUTLS} CACHE BOOL "Enable GNUTLS usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_NETCDF)
SET(MFEM_USE_NETCDF ${TPL_ENABLE_NETCDF} CACHE BOOL "Enable NETCDF usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_PETSC)
SET(MFEM_USE_PETSC ${TPL_ENABLE_PETSC} CACHE BOOL "Enable PETSc support." FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_MPFR)
SET(MFEM_USE_MPFR ${TPL_ENABLE_MPFR} CACHE BOOL "Enable MPFR usage." FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_SIDRE)
SET(MFEM_USE_SIDRE ${TPL_ENABLE_SIDRE} CACHE BOOL "Enable Axom/Sidre usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_CONDUIT)
SET(MFEM_USE_CONDUIT ${TPL_ENABLE_CONDUIT} CACHE BOOL "Enable Conduit usage" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_PUMI)
SET(MFEM_USE_PUMI ${TPL_ENABLE_PUMI} CACHE BOOL "Enable PUMI" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_CUDA)
SET(MFEM_USE_CUDA ${TPL_ENABLE_CUDA} CACHE BOOL "Enable CUDA" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_OCCA)
SET(MFEM_USE_OCCA ${TPL_ENABLE_OCCA} CACHE BOOL "Enable OCCA" FORCE)
ENDIF()
IF (DEFINED TPL_ENABLE_RAJA)
SET(MFEM_USE_RAJA ${TPL_ENABLE_RAJA} CACHE BOOL "Enable RAJA" FORCE)
ENDIF()
-6
View File
@@ -25,7 +25,6 @@ set(MFEM_USE_LIBUNWIND @MFEM_USE_LIBUNWIND@)
set(MFEM_USE_LAPACK @MFEM_USE_LAPACK@)
set(MFEM_THREAD_SAFE @MFEM_THREAD_SAFE@)
set(MFEM_USE_OPENMP @MFEM_USE_OPENMP@)
set(MFEM_USE_LEGACY_OPENMP @MFEM_USE_LEGACY_OPENMP@)
set(MFEM_USE_MEMALLOC @MFEM_USE_MEMALLOC@)
set(MFEM_TIMER_TYPE @MFEM_TIMER_TYPE@)
set(MFEM_USE_SUNDIALS @MFEM_USE_SUNDIALS@)
@@ -40,11 +39,6 @@ set(MFEM_USE_PETSC @MFEM_USE_PETSC@)
set(MFEM_USE_MPFR @MFEM_USE_MPFR@)
set(MFEM_USE_SIDRE @MFEM_USE_SIDRE@)
set(MFEM_USE_CONDUIT @MFEM_USE_CONDUIT@)
set(MFEM_USE_PUMI @MFEM_USE_PUMI@)
set(MFEM_USE_MM @MFEM_USE_MM@)
set(MFEM_USE_CUDA @MFEM_USE_CUDA@)
set(MFEM_USE_OCCA @MFEM_USE_OCCA@)
set(MFEM_USE_RAJA @MFEM_USE_RAJA@)
set(MFEM_CXX_COMPILER "@CMAKE_CXX_COMPILER@")
set(MFEM_CXX_FLAGS "@CMAKE_CXX_FLAGS@")
+5 -30
View File
@@ -30,12 +30,6 @@
#define MFEM_VERSION_MINOR (((MFEM_VERSION)/100)%100)
#define MFEM_VERSION_PATCH ((MFEM_VERSION)%100)
// MFEM source directory.
#define MFEM_SOURCE_DIR "@MFEM_SOURCE_DIR@"
// MFEM install directory.
#define MFEM_INSTALL_DIR "@MFEM_INSTALL_DIR@"
// Description of the git commit used to build MFEM.
#cmakedefine MFEM_GIT_STRING "@MFEM_GIT_STRING@"
@@ -68,12 +62,9 @@
// allocation and de-allocation.
#cmakedefine MFEM_THREAD_SAFE
// Enable the OpenMP backend.
// Enable experimental OpenMP support. Requires MFEM_THREAD_SAFE.
#cmakedefine MFEM_USE_OPENMP
// [Deprecated] Enable experimental OpenMP support. Requires MFEM_THREAD_SAFE.
#cmakedefine MFEM_USE_LEGACY_OPENMP
// Enable MFEM functionality based on the Mesquite library.
#cmakedefine MFEM_USE_MESQUITE
@@ -107,22 +98,6 @@
// Enable MFEM functionality based on Conduit
#cmakedefine MFEM_USE_CONDUIT
// Enable MFEM functionality based on the PUMI library
#cmakedefine MFEM_USE_PUMI
// Build the GPU/CUDA-enabled version of the MFEM library.
// Requires a CUDA compiler (nvcc).
#cmakedefine MFEM_USE_CUDA
// Enable MFEM functionality based on the RAJA library
#cmakedefine MFEM_USE_RAJA
// Enable MFEM functionality based on the OCCA library
#cmakedefine MFEM_USE_OCCA
// Enable MFEM's internal Memory Manager (needed e.g. for MFEM_USE_CUDA)
#cmakedefine MFEM_USE_MM
// Which library functions to use in class StopWatch for measuring time.
// For a list of the available options, see INSTALL.
// If not defined, an option is selected automatically.
@@ -131,11 +106,11 @@
// Enable MFEM functionality based on the SUNDIALS libraries.
#cmakedefine MFEM_USE_SUNDIALS
// Windows specific options
// Macro needed to get defines like M_PI from <cmath>. (Visual Studio C++ only?)
#cmakedefine _USE_MATH_DEFINES
// Version of HYPRE used for building MFEM.
#cmakedefine MFEM_HYPRE_VERSION @MFEM_HYPRE_VERSION@
// Macro defined when PUMI is built with support for the Simmetrix SimModSuite
// library.
#cmakedefine MFEM_USE_SIMMETRIX
#endif // MFEM_CONFIG_HEADER
-19
View File
@@ -1,19 +0,0 @@
# Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at the
# Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights reserved.
# See file COPYRIGHT for details.
#
# This file is part of the MFEM library. For more information and source code
# availability see http://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License (as published by the Free
# Software Foundation) version 2.1 dated February 1999.
# Defines the following variables:
# - OCCA_FOUND
# - OCCA_LIBRARIES
# - OCCA_INCLUDE_DIRS
include(MfemCmakeUtilities)
mfem_find_package(OCCA OCCA OCCA_DIR "include" "occa.hpp" "lib" "occa"
"Paths to headers required by OCCA." "Libraries required by OCCA.")
-30
View File
@@ -1,30 +0,0 @@
# Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at the
# Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights reserved.
# See file COPYRIGHT for details.
#
# This file is part of the MFEM library. For more information and source code
# availability see http://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License (as published by the Free
# Software Foundation) version 2.1 dated February 1999.
# Defines the following variables:
# - RAJA_FOUND
# - RAJA_LIBRARIES
# - RAJA_INCLUDE_DIRS
include(MfemCmakeUtilities)
mfem_find_package(RAJA RAJA RAJA_DIR "include" "RAJA/RAJA.hpp" "lib" "RAJA"
"Paths to headers required by RAJA." "Libraries required by RAJA.")
if (NOT RAJA_CONFIG_CMAKE)
set(RAJA_CONFIG_CMAKE "${RAJA_DIR}/share/raja/cmake/raja-config.cmake")
endif()
if (EXISTS "${RAJA_CONFIG_CMAKE}")
include("${RAJA_CONFIG_CMAKE}")
if (ENABLE_CUDA AND NOT MFEM_USE_CUDA)
message(FATAL_ERROR
"RAJA is built with CUDA: MFEM_USE_CUDA=YES is required")
endif()
endif()
@@ -229,17 +229,6 @@ endfunction(mfem_find_component)
function(mfem_find_package Name Prefix DirVar IncSuffixes Header LibSuffixes
Lib IncDoc LibDoc)
# If we have the TPL_ versions of _INCLUDE_DIRS and _LIBRARIES then set the
# standard ${Prefix} versions
if (TPL_${Prefix}_INCLUDE_DIRS)
set(${Prefix}_INCLUDE_DIRS ${TPL_${Prefix}_INCLUDE_DIRS} CACHE STRING
"TPL_${Prefix}_INCLUDE_DIRS was found." FORCE)
endif()
if (TPL_${Prefix}_LIBRARIES)
set(${Prefix}_LIBRARIES ${TPL_${Prefix}_LIBRARIES} CACHE STRING
"TPL_${Prefix}_LIBRARIES was found." FORCE)
endif()
# Quick return
if (${Prefix}_FOUND)
return()
@@ -696,164 +685,3 @@ function(mfem_find_library Name Prefix Lib LibDoc CheckVar CheckSrc)
endif()
endfunction(mfem_find_library)
#
# Function that creates 'config.mk' from 'config.mk.in' for the both the
# build- and the install-locations and define install rules for 'config.mk'
# and 'test.mk'.
#
function(mfem_export_mk_files)
# Define a few auxiliary variables (not written to 'config.mk')
string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
# CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG -> '-Wl,-rpath,'
set(shared_link_flag ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG})
if (NOT shared_link_flag)
set(shared_link_flag "-Wl,-rpath,")
endif()
# Convert Boolean vars to YES/NO without writting the values to cache
set(CONFIG_MK_BOOL_VARS MFEM_USE_MPI MFEM_USE_METIS MFEM_USE_METIS_5
MFEM_DEBUG MFEM_USE_EXCEPTIONS MFEM_USE_GZSTREAM MFEM_USE_LIBUNWIND
MFEM_USE_LAPACK MFEM_THREAD_SAFE MFEM_USE_OPENMP MFEM_USE_LEGACY_OPENMP
MFEM_USE_MEMALLOC MFEM_USE_SUNDIALS MFEM_USE_MESQUITE MFEM_USE_SUITESPARSE
MFEM_USE_SUPERLU MFEM_USE_STRUMPACK MFEM_USE_GECKO MFEM_USE_GNUTLS
MFEM_USE_NETCDF MFEM_USE_PETSC MFEM_USE_MPFR MFEM_USE_SIDRE
MFEM_USE_CONDUIT MFEM_USE_PUMI MFEM_USE_MM MFEM_USE_CUDA MFEM_USE_OCCA
MFEM_USE_RAJA)
foreach(var ${CONFIG_MK_BOOL_VARS})
if (${var})
set(${var} YES)
else()
set(${var} NO)
endif()
endforeach()
# TODO: Add support for MFEM_USE_CUDA=YES
set(MFEM_CXX ${CMAKE_CXX_COMPILER})
set(MFEM_CPPFLAGS "")
string(STRIP "${CMAKE_CXX_FLAGS_${BUILD_TYPE}} ${CMAKE_CXX_FLAGS}"
MFEM_CXXFLAGS)
set(MFEM_TPLFLAGS "")
foreach(dir ${MFEM_TPL_INCLUDE_DIRS})
set(MFEM_TPLFLAGS "${MFEM_TPLFLAGS} -I${dir}")
endforeach()
# TODO: MFEM_TPLFLAGS: add other TPL flags, in addition to the -I flags.
set(MFEM_INCFLAGS "-I\$(MFEM_INC_DIR) \$(MFEM_TPLFLAGS)")
set(MFEM_PICFLAG "")
if (BUILD_SHARED_LIBS)
set(MFEM_PICFLAG "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}")
endif()
set(MFEM_FLAGS "\$(MFEM_CPPFLAGS) \$(MFEM_CXXFLAGS) \$(MFEM_INCFLAGS)")
# TPL link flags: set below
set(MFEM_EXT_LIBS "")
if (BUILD_SHARED_LIBS)
set(MFEM_LIBS "${shared_link_flag}\$(MFEM_LIB_DIR) -L\$(MFEM_LIB_DIR)")
set(MFEM_LIBS "${MFEM_LIBS} -lmfem \$(MFEM_EXT_LIBS)")
if (APPLE)
set(SO_VER ".${mfem_VERSION}${CMAKE_SHARED_LIBRARY_SUFFIX}")
else()
set(SO_VER "${CMAKE_SHARED_LIBRARY_SUFFIX}.${mfem_VERSION}")
endif()
set(MFEM_LIB_FILE "\$(MFEM_LIB_DIR)/libmfem${SO_VER}")
set(MFEM_SHARED YES)
set(MFEM_STATIC NO)
else()
set(MFEM_LIBS "-L\$(MFEM_LIB_DIR) -lmfem \$(MFEM_EXT_LIBS)")
set(MFEM_LIB_FILE "\$(MFEM_LIB_DIR)/libmfem.a")
set(MFEM_SHARED NO)
set(MFEM_STATIC YES)
endif()
set(MFEM_BUILD_TAG "${CMAKE_SYSTEM}")
set(MFEM_PREFIX "${CMAKE_INSTALL_PREFIX}")
# For the next 4 variable, these are the values for the build-tree version of
# 'config.mk'
set(MFEM_INC_DIR "${PROJECT_BINARY_DIR}")
set(MFEM_LIB_DIR "${PROJECT_BINARY_DIR}")
set(MFEM_TEST_MK "${PROJECT_SOURCE_DIR}/config/test.mk")
set(MFEM_CONFIG_EXTRA "MFEM_BUILD_DIR ?= ${PROJECT_BINARY_DIR}")
set(MFEM_MPIEXEC ${MPIEXEC})
if (NOT MFEM_MPIEXEC)
set(MFEM_MPIEXEC "mpirun")
endif()
set(MFEM_MPIEXEC_NP ${MPIEXEC_NUMPROC_FLAG})
if (NOT MFEM_MPIEXEC_NP)
set(MFEM_MPIEXEC_NP "-np")
endif()
# MFEM_MPI_NP is already set
# Define the variable 'MFEM_EXT_LIBS': handle PUMI libs
if ("${MFEM_USE_PUMI}" STREQUAL "YES")
message(STATUS "simmodsuite_dir = '${SIMMODSUITE_DIR}'")
get_target_property(liblist ${PUMI_LIBRARIES} INTERFACE_LINK_LIBRARIES)
set(pumi_dep_libs "${liblist}")
foreach(pumilib ${liblist})
get_target_property(libdeps ${pumilib} INTERFACE_LINK_LIBRARIES)
if (NOT "${libdeps}" MATCHES "libdeps-NOTFOUND")
list(APPEND pumi_dep_libs ${libdeps})
endif()
endforeach()
list(REMOVE_DUPLICATES pumi_dep_libs)
foreach(pumilib ${pumi_dep_libs})
unset(lib CACHE)
string(REGEX REPLACE "^SCOREC::" "" libname ${pumilib})
string(FIND "${pumilib}" ".a" staticlib)
string(FIND "${pumilib}" ".so" sharedlib)
find_library(lib ${libname} PATHS ${PUMI_DIR}/lib NO_DEFUALT_PATH)
if (NOT "${sharedlib}" MATCHES "-1" OR
NOT "${staticlib}" MATCHES "-1" )
set(MFEM_EXT_LIBS "${pumilib} ${MFEM_EXT_LIBS}")
elseif (NOT "${lib}" MATCHES "lib-NOTFOUND")
set(MFEM_EXT_LIBS "${lib} ${MFEM_EXT_LIBS}")
elseif ("${lib}" MATCHES "lib-NOTFOUND" AND
NOT "${libname}" MATCHES "can" AND
NOT "${libname}" MATCHES "pthread")
message(FATAL_ERROR "SCOREC lib ${libname} not found")
endif()
endforeach()
endif()
# Define the variable 'MFEM_EXT_LIBS': handle other (not PUMI) libs
foreach(lib ${TPL_LIBRARIES})
get_filename_component(suffix ${lib} EXT)
# handle interfaces (e.g., SCOREC::apf)
if ("${lib}" MATCHES "SCOREC::.*")
elseif (NOT "${lib}" MATCHES "SCOREC::.*" AND "${lib}" MATCHES ".*::.*")
message(FATAL_ERROR "***** interface lib found ... exiting *****")
# handle static and shared libs
elseif ("${suffix}" STREQUAL "${CMAKE_SHARED_LIBRARY_SUFFIX}")
get_filename_component(dir ${lib} DIRECTORY)
get_filename_component(fullLibName ${lib} NAME_WE)
string(REGEX REPLACE "^lib" "" libname ${fullLibName})
set(MFEM_EXT_LIBS
"${MFEM_EXT_LIBS} ${shared_link_flag}${dir} -L${dir} -l${libname}")
else()
set(MFEM_EXT_LIBS "${MFEM_EXT_LIBS} ${lib}")
endif()
endforeach()
# Create the build-tree version of 'config.mk'
configure_file(
"${PROJECT_SOURCE_DIR}/config/config.mk.in"
"${PROJECT_BINARY_DIR}/config/config.mk")
# Copy 'test.mk' from the source-tree to the build-tree
configure_file(
"${PROJECT_SOURCE_DIR}/config/test.mk"
"${PROJECT_BINARY_DIR}/config/test.mk" COPYONLY)
# Update variables for the install-tree version of 'config.mk'
set(MFEM_INC_DIR "${CMAKE_INSTALL_PREFIX}/include")
set(MFEM_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
set(MFEM_TEST_MK "${CMAKE_INSTALL_PREFIX}/share/mfem/test.mk")
set(MFEM_CONFIG_EXTRA "")
# Create the install-tree version of 'config.mk'
configure_file(
"${PROJECT_SOURCE_DIR}/config/config.mk.in"
"${PROJECT_BINARY_DIR}/config/config-install.mk")
# Install rules for 'config.mk' and 'test.mk'
install(FILES ${PROJECT_SOURCE_DIR}/config/test.mk
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mfem/)
install(FILES ${PROJECT_BINARY_DIR}/config/config-install.mk
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/mfem/ RENAME config.mk)
endfunction()
-25
View File
@@ -15,9 +15,6 @@
//
// Otherwise, use the local file: _config.hpp.
#ifndef MFEM_CONFIG_HPP
#define MFEM_CONFIG_HPP
#ifdef MFEM_BUILD_DIR
#define MFEM_QUOTE(a) #a
#define MFEM_MAKE_PATH(x,y) MFEM_QUOTE(x/y)
@@ -26,18 +23,6 @@
#include "_config.hpp"
#endif
// Common configuration macros
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__)
#define MFEM_HAVE_GCC_PRAGMA_DIAGNOSTIC
#endif
// Windows specific options
#ifdef _WIN32
// Macro needed to get defines like M_PI from <cmath>. (Visual Studio C++ only?)
#define _USE_MATH_DEFINES
#endif
// Check dependencies:
// Options that require MPI
@@ -51,14 +36,4 @@
#ifdef MFEM_USE_PETSC
#error Building with PETSc (MFEM_USE_PETSC=YES) requires MPI (MFEM_USE_MPI=YES)
#endif
#ifdef MFEM_USE_PUMI
#error Building with PUMI (MFEM_USE_PUMI=YES) requires MPI (MFEM_USE_MPI=YES)
#endif
#endif // MFEM_USE_MPI not defined
// CUDA requires the memory manager
#if defined(MFEM_USE_CUDA) && !defined(MFEM_USE_MM)
#error Building with CUDA (MFEM_USE_CUDA=YES) requires MFEM_USE_MM=YES
#endif
#endif // MFEM_CONFIG_HPP
+9 -29
View File
@@ -30,12 +30,6 @@
#define MFEM_VERSION_MINOR (((MFEM_VERSION)/100)%100)
#define MFEM_VERSION_PATCH ((MFEM_VERSION)%100)
// The absolute path of the MFEM source prefix
// #define MFEM_SOURCE_DIR "@MFEM_SOURCE_DIR@"
// The absolute path of the MFEM installation prefix
// #define MFEM_INSTALL_DIR "@MFEM_INSTALL_DIR@"
// Description of the git commit used to build MFEM.
// #define MFEM_GIT_STRING "@MFEM_GIT_STRING@"
@@ -64,16 +58,16 @@
// Use LAPACK routines for various dense linear algebra operations.
// #define MFEM_USE_LAPACK
// Use Eigen for math routines
// #define MFEM_USE_EIGEN
// Use thread-safe implementation. This comes at the cost of extra memory
// allocation and de-allocation.
// #define MFEM_THREAD_SAFE
// Enable the OpenMP backend.
// Enable experimental OpenMP support. Requires MFEM_THREAD_SAFE.
// #define MFEM_USE_OPENMP
// [Deprecated] Enable experimental OpenMP support. Requires MFEM_THREAD_SAFE.
// #define MFEM_USE_LEGACY_OPENMP
// Internal MFEM option: enable group/batch allocation for some small objects.
// #define MFEM_USE_MEMALLOC
@@ -118,27 +112,13 @@
// Enable functionality based on the MPFR library.
// #define MFEM_USE_MPFR
// Enable MFEM functionality based on the PUMI library
// #define MFEM_USE_PUMI
// Build the GPU/CUDA-enabled version of the MFEM library.
// Requires a CUDA compiler (nvcc).
// #define MFEM_USE_CUDA
// Enable functionality based on the RAJA library.
// #define MFEM_USE_RAJA
// Enable functionality based on the OCCA library.
// #define MFEM_USE_OCCA
// Enable MFEM's internal Memory Manager (needed e.g. for MFEM_USE_CUDA)
// #define MFEM_USE_MM
// Windows specific options
#ifdef _WIN32
// Macro needed to get defines like M_PI from <cmath>. (Visual Studio C++ only?)
#define _USE_MATH_DEFINES
#endif
// Version of HYPRE used for building MFEM.
// #define MFEM_HYPRE_VERSION @MFEM_HYPRE_VERSION@
// Macro defined when PUMI is built with support for the Simmetrix SimModSuite
// library.
// #define MFEM_USE_SIMMETRIX
#endif // MFEM_CONFIG_HEADER
+28 -38
View File
@@ -10,41 +10,34 @@
# Software Foundation) version 2.1 dated February 1999.
# Variables corresponding to defines in config.hpp (YES, NO, or value)
MFEM_VERSION = @MFEM_VERSION@
MFEM_VERSION_STRING = @MFEM_VERSION_STRING@
MFEM_SOURCE_DIR = @MFEM_SOURCE_DIR@
MFEM_INSTALL_DIR = @MFEM_INSTALL_DIR@
MFEM_GIT_STRING = @MFEM_GIT_STRING@
MFEM_USE_MPI = @MFEM_USE_MPI@
MFEM_USE_METIS = @MFEM_USE_METIS@
MFEM_USE_METIS_5 = @MFEM_USE_METIS_5@
MFEM_DEBUG = @MFEM_DEBUG@
MFEM_USE_EXCEPTIONS = @MFEM_USE_EXCEPTIONS@
MFEM_USE_GZSTREAM = @MFEM_USE_GZSTREAM@
MFEM_USE_LIBUNWIND = @MFEM_USE_LIBUNWIND@
MFEM_USE_LAPACK = @MFEM_USE_LAPACK@
MFEM_THREAD_SAFE = @MFEM_THREAD_SAFE@
MFEM_USE_LEGACY_OPENMP = @MFEM_USE_LEGACY_OPENMP@
MFEM_USE_OPENMP = @MFEM_USE_OPENMP@
MFEM_USE_MEMALLOC = @MFEM_USE_MEMALLOC@
MFEM_TIMER_TYPE = @MFEM_TIMER_TYPE@
MFEM_USE_SUNDIALS = @MFEM_USE_SUNDIALS@
MFEM_USE_MESQUITE = @MFEM_USE_MESQUITE@
MFEM_USE_SUITESPARSE = @MFEM_USE_SUITESPARSE@
MFEM_USE_SUPERLU = @MFEM_USE_SUPERLU@
MFEM_USE_STRUMPACK = @MFEM_USE_STRUMPACK@
MFEM_USE_GECKO = @MFEM_USE_GECKO@
MFEM_USE_GNUTLS = @MFEM_USE_GNUTLS@
MFEM_USE_NETCDF = @MFEM_USE_NETCDF@
MFEM_USE_PETSC = @MFEM_USE_PETSC@
MFEM_USE_MPFR = @MFEM_USE_MPFR@
MFEM_USE_SIDRE = @MFEM_USE_SIDRE@
MFEM_USE_CONDUIT = @MFEM_USE_CONDUIT@
MFEM_USE_PUMI = @MFEM_USE_PUMI@
MFEM_USE_CUDA = @MFEM_USE_CUDA@
MFEM_USE_RAJA = @MFEM_USE_RAJA@
MFEM_USE_OCCA = @MFEM_USE_OCCA@
MFEM_USE_MM = @MFEM_USE_MM@
MFEM_VERSION = @MFEM_VERSION@
MFEM_VERSION_STRING = @MFEM_VERSION_STRING@
MFEM_GIT_STRING = @MFEM_GIT_STRING@
MFEM_USE_MPI = @MFEM_USE_MPI@
MFEM_USE_METIS = @MFEM_USE_METIS@
MFEM_USE_METIS_5 = @MFEM_USE_METIS_5@
MFEM_DEBUG = @MFEM_DEBUG@
MFEM_USE_EXCEPTIONS = @MFEM_USE_EXCEPTIONS@
MFEM_USE_GZSTREAM = @MFEM_USE_GZSTREAM@
MFEM_USE_LIBUNWIND = @MFEM_USE_LIBUNWIND@
MFEM_USE_LAPACK = @MFEM_USE_LAPACK@
MFEM_USE_EIGEN = @MFEM_USE_EIGEN@
MFEM_THREAD_SAFE = @MFEM_THREAD_SAFE@
MFEM_USE_OPENMP = @MFEM_USE_OPENMP@
MFEM_USE_MEMALLOC = @MFEM_USE_MEMALLOC@
MFEM_TIMER_TYPE = @MFEM_TIMER_TYPE@
MFEM_USE_SUNDIALS = @MFEM_USE_SUNDIALS@
MFEM_USE_MESQUITE = @MFEM_USE_MESQUITE@
MFEM_USE_SUITESPARSE = @MFEM_USE_SUITESPARSE@
MFEM_USE_SUPERLU = @MFEM_USE_SUPERLU@
MFEM_USE_STRUMPACK = @MFEM_USE_STRUMPACK@
MFEM_USE_GECKO = @MFEM_USE_GECKO@
MFEM_USE_GNUTLS = @MFEM_USE_GNUTLS@
MFEM_USE_NETCDF = @MFEM_USE_NETCDF@
MFEM_USE_PETSC = @MFEM_USE_PETSC@
MFEM_USE_MPFR = @MFEM_USE_MPFR@
MFEM_USE_SIDRE = @MFEM_USE_SIDRE@
MFEM_USE_CONDUIT = @MFEM_USE_CONDUIT@
# Compiler, compile options, and link options
MFEM_CXX = @MFEM_CXX@
@@ -72,8 +65,5 @@ MFEM_MPIEXEC = @MFEM_MPIEXEC@
MFEM_MPIEXEC_NP = @MFEM_MPIEXEC_NP@
MFEM_MPI_NP = @MFEM_MPI_NP@
# The NVCC compiler cannot link with -x=cu
MFEM_LINK_FLAGS := $(filter-out -x=cu, $(MFEM_FLAGS))
# Optional extra configuration
@MFEM_CONFIG_EXTRA@
+3 -22
View File
@@ -26,8 +26,7 @@ option(MFEM_USE_GZSTREAM "Enable gzstream for compressed data streams." OFF)
option(MFEM_USE_LIBUNWIND "Enable backtrace for errors." OFF)
option(MFEM_USE_LAPACK "Enable LAPACK usage" OFF)
option(MFEM_THREAD_SAFE "Enable thread safety" OFF)
option(MFEM_USE_OPENMP "Enable the OpenMP backend" OFF)
option(MFEM_USE_LEGACY_OPENMP "Enable legacy OpenMP usage" OFF)
option(MFEM_USE_OPENMP "Enable OpenMP usage" OFF)
option(MFEM_USE_MEMALLOC "Enable the internal MEMALLOC option." ON)
option(MFEM_USE_SUNDIALS "Enable SUNDIALS usage" OFF)
option(MFEM_USE_MESQUITE "Enable MESQUITE usage" OFF)
@@ -41,13 +40,6 @@ option(MFEM_USE_PETSC "Enable PETSc support." OFF)
option(MFEM_USE_MPFR "Enable MPFR usage." OFF)
option(MFEM_USE_SIDRE "Enable Axom/Sidre usage" OFF)
option(MFEM_USE_CONDUIT "Enable Conduit usage" OFF)
option(MFEM_USE_PUMI "Enable PUMI" OFF)
option(MFEM_USE_MM "Enable MFEM's memory manager" OFF)
option(MFEM_USE_CUDA "Enable CUDA" OFF)
option(MFEM_USE_OCCA "Enable OCCA" OFF)
option(MFEM_USE_RAJA "Enable RAJA" OFF)
set(MFEM_MPI_NP 4 CACHE STRING "Number of processes used for MPI tests")
# Allow a user to disable testing, examples, and/or miniapps at CONFIGURE TIME
# if they don't want/need them (e.g. if MFEM is "just a dependency" and all they
@@ -63,16 +55,13 @@ option(MFEM_ENABLE_MINIAPPS "Build all of the miniapps" OFF)
# set(CXX g++)
# set(MPICXX mpicxx)
# Set the target CUDA architecture
set(CUDA_ARCH "sm_60" CACHE STRING "Target CUDA architecture.")
set(MFEM_DIR ${CMAKE_CURRENT_SOURCE_DIR})
# The *_DIR paths below will be the first place searched for the corresponding
# headers and library. If these fail, then standard cmake search is performed.
# Note: if the variables are already in the cache, they are not overwritten.
set(HYPRE_DIR "${MFEM_DIR}/../hypre/src/hypre" CACHE PATH
set(HYPRE_DIR "${MFEM_DIR}/../hypre-2.10.0b/src/hypre" CACHE PATH
"Path to the hypre library.")
# If hypre was compiled to depend on BLAS and LAPACK:
# set(HYPRE_REQUIRED_PACKAGES "BLAS" "LAPACK" CACHE STRING
@@ -110,7 +99,6 @@ set(SuperLUDist_REQUIRED_PACKAGES "MPI" "BLAS" "ParMETIS" CACHE STRING
set(STRUMPACK_DIR "${MFEM_DIR}/../STRUMPACK-build" CACHE PATH
"Path to the STRUMPACK library.")
# STRUMPACK may also depend on "OpenMP", depending on how it was compiled.
# Starting with v2.2.0 of STRUMPACK, ParMETIS and Scotch are optional.
set(STRUMPACK_REQUIRED_PACKAGES "MPI" "MPI_Fortran" "ParMETIS" "METIS"
"ScaLAPACK" "Scotch/ptscotch/ptscotcherr/scotch/scotcherr" CACHE STRING
"Additional packages required by STRUMPACK.")
@@ -118,8 +106,7 @@ set(STRUMPACK_REQUIRED_PACKAGES "MPI" "MPI_Fortran" "ParMETIS" "METIS"
# set(STRUMPACK_REQUIRED_LIBRARIES "gfortran" "mpi_mpifh" CACHE STRING
# "Additional libraries required by STRUMPACK.")
# The Scotch library, required by STRUMPACK <= v2.1.0, optional in STRUMPACK >=
# v2.2.0.
# The Scotch library, required by STRUMPACK
set(Scotch_DIR "${MFEM_DIR}/../scotch_6.0.4" CACHE PATH
"Path to the Scotch and PT-Scotch libraries.")
set(Scotch_REQUIRED_PACKAGES "Threads" CACHE STRING
@@ -158,12 +145,6 @@ set(AXOM_DIR "${MFEM_DIR}/../axom" CACHE PATH "Path to the Axom library.")
set(Axom_REQUIRED_PACKAGES "Conduit/relay" CACHE STRING
"Additional packages required by Axom.")
set(PUMI_DIR "${MFEM_DIR}/../pumi-2.1.0" CACHE STRING
"Directory where PUMI is installed")
set(OCCA_DIR "${MFEM_DIR}/../occa" CACHE PATH "Path to OCCA")
set(RAJA_DIR "${MFEM_DIR}/../raja" CACHE PATH "Path to RAJA")
set(BLAS_INCLUDE_DIRS "" CACHE STRING "Path to BLAS headers.")
set(BLAS_LIBRARIES "" CACHE STRING "The BLAS library.")
set(LAPACK_INCLUDE_DIRS "" CACHE STRING "Path to LAPACK headers.")
+43 -83
View File
@@ -21,13 +21,8 @@ NOTMAC := $(subst Darwin,,$(shell uname -s))
CXX = g++
MPICXX = mpicxx
BASE_FLAGS = -std=c++11
OPTIM_FLAGS = -O3 $(BASE_FLAGS)
DEBUG_FLAGS = -g $(XCOMPILER)-Wall $(BASE_FLAGS)
# Prefixes for passing flags to the compiler and linker when using CXX or MPICXX
CXX_XCOMPILER =
CXX_XLINKER = -Wl,
OPTIM_FLAGS = -O3 -pg
DEBUG_FLAGS = -g -Wall
# Destination location of make install
# PREFIX = $(HOME)/mfem
@@ -38,41 +33,33 @@ INSTALL = /usr/bin/install
STATIC = YES
SHARED = NO
# CUDA configuration options
CUDA_CXX = nvcc
CUDA_ARCH = sm_60
CUDA_FLAGS = -x=cu --expt-extended-lambda -arch=$(CUDA_ARCH)
# Prefixes for passing flags to the host compiler and linker when using CUDA_CXX
CUDA_XCOMPILER = -Xcompiler=
CUDA_XLINKER = -Xlinker=
ifneq ($(NOTMAC),)
AR = ar
ARFLAGS = cruv
RANLIB = ranlib
PICFLAG = $(XCOMPILER)-fPIC
PICFLAG = -fPIC
SO_EXT = so
SO_VER = so.$(MFEM_VERSION_STRING)
BUILD_SOFLAGS = -shared $(XLINKER)-soname,libmfem.$(SO_VER)
BUILD_RPATH = $(XLINKER)-rpath,$(BUILD_REAL_DIR)
BUILD_SOFLAGS = -shared -Wl,-soname,libmfem.$(SO_VER)
BUILD_RPATH = -Wl,-rpath,$(BUILD_REAL_DIR)
INSTALL_SOFLAGS = $(BUILD_SOFLAGS)
INSTALL_RPATH = $(XLINKER)-rpath,@MFEM_LIB_DIR@
INSTALL_RPATH = -Wl,-rpath,@MFEM_LIB_DIR@
else
# Silence "has no symbols" warnings on Mac OS X
AR = ar
ARFLAGS = Scruv
RANLIB = ranlib -no_warning_for_no_symbols
PICFLAG = $(XCOMPILER)-fPIC
PICFLAG = -fPIC
SO_EXT = dylib
SO_VER = $(MFEM_VERSION_STRING).dylib
MAKE_SOFLAGS = $(XLINKER)-dylib,-install_name,$(1)/libmfem.$(SO_VER),\
MAKE_SOFLAGS = -Wl,-dylib,-install_name,$(1)/libmfem.$(SO_VER),\
-compatibility_version,$(MFEM_VERSION_STRING),\
-current_version,$(MFEM_VERSION_STRING),\
-undefined,dynamic_lookup
BUILD_SOFLAGS = $(subst $1 ,,$(call MAKE_SOFLAGS,$(BUILD_REAL_DIR)))
BUILD_RPATH = $(XLINKER)-undefined,dynamic_lookup
BUILD_RPATH = -Wl,-undefined,dynamic_lookup
INSTALL_SOFLAGS = $(subst $1 ,,$(call MAKE_SOFLAGS,$(MFEM_LIB_DIR)))
INSTALL_RPATH = $(XLINKER)-undefined,dynamic_lookup
INSTALL_RPATH = -Wl,-undefined,dynamic_lookup
endif
# Set CXXFLAGS to overwrite the default selection of DEBUG_FLAGS/OPTIM_FLAGS
@@ -95,36 +82,31 @@ MFEM_MPI_NP = 4
# config.hpp. The values below are the defaults for generating the actual values
# in config.mk and config.hpp.
MFEM_USE_MPI = NO
MFEM_USE_METIS = $(MFEM_USE_MPI)
MFEM_USE_METIS_5 = NO
MFEM_DEBUG = NO
MFEM_USE_EXCEPTIONS = NO
MFEM_USE_GZSTREAM = NO
MFEM_USE_LIBUNWIND = NO
MFEM_USE_LAPACK = NO
MFEM_THREAD_SAFE = NO
MFEM_USE_OPENMP = NO
MFEM_USE_LEGACY_OPENMP = NO
MFEM_USE_MEMALLOC = YES
MFEM_TIMER_TYPE = $(if $(NOTMAC),2,4)
MFEM_USE_SUNDIALS = NO
MFEM_USE_MESQUITE = NO
MFEM_USE_SUITESPARSE = NO
MFEM_USE_SUPERLU = NO
MFEM_USE_STRUMPACK = NO
MFEM_USE_GECKO = NO
MFEM_USE_GNUTLS = NO
MFEM_USE_NETCDF = NO
MFEM_USE_PETSC = NO
MFEM_USE_MPFR = NO
MFEM_USE_SIDRE = NO
MFEM_USE_CONDUIT = NO
MFEM_USE_PUMI = NO
MFEM_USE_CUDA = NO
MFEM_USE_RAJA = NO
MFEM_USE_OCCA = NO
MFEM_USE_MM = NO
MFEM_USE_MPI = NO
MFEM_USE_METIS = $(MFEM_USE_MPI)
MFEM_USE_METIS_5 = NO
MFEM_DEBUG = NO
MFEM_USE_EXCEPTIONS = NO
MFEM_USE_GZSTREAM = NO
MFEM_USE_LIBUNWIND = NO
MFEM_USE_LAPACK = NO
MFEM_USE_EIGEN = NO
MFEM_THREAD_SAFE = NO
MFEM_USE_OPENMP = NO
MFEM_USE_MEMALLOC = YES
MFEM_TIMER_TYPE = $(if $(NOTMAC),2,4)
MFEM_USE_SUNDIALS = NO
MFEM_USE_MESQUITE = NO
MFEM_USE_SUITESPARSE = NO
MFEM_USE_SUPERLU = NO
MFEM_USE_STRUMPACK = NO
MFEM_USE_GECKO = NO
MFEM_USE_GNUTLS = NO
MFEM_USE_NETCDF = NO
MFEM_USE_PETSC = NO
MFEM_USE_MPFR = NO
MFEM_USE_SIDRE = NO
MFEM_USE_CONDUIT = NO
# Compile and link options for zlib.
ZLIB_DIR =
@@ -136,7 +118,7 @@ LIBUNWIND_OPT = -g
LIBUNWIND_LIB = $(if $(NOTMAC),-lunwind -ldl,)
# HYPRE library configuration (needed to build the parallel version)
HYPRE_DIR = @MFEM_DIR@/../hypre/src/hypre
HYPRE_DIR = @MFEM_DIR@/../hypre-2.10.0b/src/hypre
HYPRE_OPT = -I$(HYPRE_DIR)/include
HYPRE_LIB = -L$(HYPRE_DIR)/lib -lHYPRE
@@ -154,8 +136,6 @@ ifeq ($(MFEM_USE_SUPERLU)$(MFEM_USE_STRUMPACK),NONO)
else
# ParMETIS: currently needed by SuperLU or STRUMPACK. We assume that METIS 5
# (included with ParMETIS) is installed in the same location.
# Starting with STRUMPACK v2.2.0, ParMETIS is an optional dependency while
# METIS is still required.
METIS_DIR = @MFEM_DIR@/../parmetis-4.0.3
METIS_OPT = -I$(METIS_DIR)/include
METIS_LIB = -L$(METIS_DIR)/lib -lparmetis -lmetis
@@ -166,8 +146,13 @@ endif
LAPACK_OPT =
LAPACK_LIB = $(if $(NOTMAC),-llapack -lblas,-framework Accelerate)
# Eigen configuration
EIGEN_DIR = @MFEM_DIR@/../eigen
EIGEN_OPT = -I$(EIGEN_DIR) -std=c++11 -Wno-enum-compare
EIGEN_LIB =
# OpenMP configuration
OPENMP_OPT = $(XCOMPILER)-fopenmp
OPENMP_OPT = -fopenmp
OPENMP_LIB =
# Used when MFEM_TIMER_TYPE = 2
@@ -203,8 +188,7 @@ SUPERLU_DIR = @MFEM_DIR@/../SuperLU_DIST_5.1.0
SUPERLU_OPT = -I$(SUPERLU_DIR)/SRC
SUPERLU_LIB = -Wl,-rpath,$(SUPERLU_DIR)/SRC -L$(SUPERLU_DIR)/SRC -lsuperlu_dist
# SCOTCH library configuration (required by STRUMPACK <= v2.1.0, optional in
# STRUMPACK >= v2.2.0)
# SCOTCH library configuration (required by STRUMPACK)
SCOTCH_DIR = @MFEM_DIR@/../scotch_6.0.4
SCOTCH_OPT = -I$(SCOTCH_DIR)/include
SCOTCH_LIB = -L$(SCOTCH_DIR)/lib -lptscotch -lptscotcherr -lscotch -lscotcherr\
@@ -293,30 +277,6 @@ SIDRE_LIB = \
-Wl,-rpath,$(HDF5_DIR)/lib -L$(HDF5_DIR)/lib \
-lsidre -lslic -laxom_utils -lconduit -lconduit_relay -lhdf5 $(ZLIB_LIB) -ldl
# PUMI
# Note that PUMI_DIR is needed -- it is used to check for gmi_sim.h
PUMI_DIR = @MFEM_DIR@/../pumi-2.1.0
PUMI_OPT = -I$(PUMI_DIR)/include
PUMI_LIB = -L$(PUMI_DIR)/lib -lpumi -lcrv -lma -lmds -lapf -lpcu -lgmi -lparma\
-llion -lmth -lapf_zoltan -lspr
# CUDA library configuration (currently not needed)
CUDA_OPT =
CUDA_LIB =
# OCCA library configuration
OCCA_DIR = @MFEM_DIR@/../occa
OCCA_OPT = -I$(OCCA_DIR)/include
OCCA_LIB = $(XLINKER)-rpath,$(OCCA_DIR)/lib -L$(OCCA_DIR)/lib -locca
# RAJA library configuration
RAJA_DIR = @MFEM_DIR@/../raja
RAJA_OPT = -I$(RAJA_DIR)/include
ifdef CUB_DIR
RAJA_OPT += -I$(CUB_DIR)
endif
RAJA_LIB = $(XLINKER)-rpath,$(RAJA_DIR)/lib -L$(RAJA_DIR)/lib -lRAJA
# If YES, enable some informational messages
VERBOSE = NO
+2 -11
View File
@@ -38,9 +38,6 @@ all: header config-mk
MPI = $(MFEM_USE_MPI:NO=)
GHV = get_hypre_version
GHV_FLAGS = $(subst @MFEM_DIR@,$(if $(MFEM_DIR),$(MFEM_DIR),..),$(HYPRE_OPT))
SMX = $(if $(MFEM_USE_PUMI:NO=),MFEM_USE_SIMMETRIX)
SMX_PATH = $(PUMI_DIR)/include/gmi_sim.h
SMX_FILE = $(subst @MFEM_DIR@,$(if $(MFEM_DIR),$(MFEM_DIR),..),$(SMX_PATH))
$(GHV): $(SRC)$(GHV).cpp
$(call mfem-info, Determining HYPRE version ...)
@@ -55,16 +52,10 @@ get-hypre-version: $(GHV).out
$(info HYPRE version: $(MFEM_HYPRE_VERSION)),\
$(error Unable to determine HYPRE version))
check-smx:
$(call mfem-info, Checking for Simmetrix header [$(SMX_FILE)] ...)
$(eval MFEM_USE_SIMMETRIX:=$(if $(wildcard $(SMX_FILE)),YES,NO))
$(call mfem-info, MFEM_USE_SIMMETRIX = $(MFEM_USE_SIMMETRIX))
$(eval export MFEM_USE_SIMMETRIX)
header: $(if $(MPI),get-hypre-version,) $(if $(SMX),check-smx)
header: $(if $(MPI),get-hypre-version,)
$(call mfem-info, Writing $(CONFIG_HPP) ...)
@set -- && \
for def in $${MFEM_DEFINES} $(if $(MPI),MFEM_HYPRE_VERSION) $(SMX); do \
for def in $${MFEM_DEFINES} $(if $(MPI),MFEM_HYPRE_VERSION,); do \
eval var=\$$$$def && \
if [ "NO" != "$${var}" ]; then \
set -- "$$@" -e "s|// \(#define $${def} \)|\1|" && \
+8 -36
View File
@@ -18,8 +18,6 @@ run_prefix=""
run_vg="valgrind --leak-check=full --show-reachable=yes --track-origins=yes"
run_suffix="-no-vis"
skip_gen_meshes="yes"
# filter-out device runs ("no") or non-device runs ("yes"):
device_runs="no"
cur_dir="${PWD}"
mfem_dir="$(cd "$(dirname "$0")"/.. && pwd)"
mfem_build_dir=""
@@ -32,7 +30,7 @@ groups_serial=(
'"examples"
"Examples:"
"examples"
"ex{,1,2}[0-9].cpp"'
"ex{,1}[0-9].cpp"'
# "ex1.cpp"'
'"sundials"
"SUNDIALS examples:"
@@ -46,15 +44,14 @@ groups_serial=(
'"meshing"
"Meshing miniapps:"
"miniapps/meshing"
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp
mesh-optimizer.cpp"'
"mobius-strip.cpp klein-bottle.cpp mesh-optimizer.cpp"'
)
# Parallel groups
groups_parallel=(
'"examples"
"Examples:"
"examples"
"ex{,1,2}[0-9]p.cpp"'
"ex{,1}[0-9]p.cpp"'
# "ex1p.cpp"'
'"sundials"
"SUNDIALS examples:"
@@ -84,7 +81,7 @@ groups_all=(
'"examples"
"Examples:"
"examples"
"ex\"{,1,2}[0-9]\"{,p}.cpp"'
"ex\"{,1}[0-9]\"{,p}.cpp"'
'"sundials"
"SUNDIALS examples:"
"examples/sundials"
@@ -100,8 +97,7 @@ groups_all=(
'"meshing"
"Meshing miniapps:"
"miniapps/meshing"
"mobius-strip.cpp klein-bottle.cpp extruder.cpp toroid.cpp
{,p}mesh-optimizer.cpp"'
"mobius-strip.cpp klein-bottle.cpp {,p}mesh-optimizer.cpp"'
'"electromagnetics"
"Electromagnetics miniapps:"
"miniapps/electromagnetics"
@@ -150,11 +146,6 @@ function extract_sample_runs()
if [ "$skip_gen_meshes" == "yes" ]; then
runs=`printf "%s" "$runs" | grep -v ".* -m .*\.gen"`
fi
if [ "$device_runs" == "yes" ]; then
runs=`printf "%s" "$runs" | grep ".* -d .*"`
else
runs=`printf "%s" "$runs" | grep -v ".* -d .*"`
fi
IFS=$'\n'
runs=(${runs})
IFS="${old_IFS}"
@@ -176,15 +167,9 @@ function help_message()
-g <dir> <pattern>
Specify explicitly a group (dir + file pattern) to run; This
option can be used multiple times to define multiple groups
-dev configure only sample runs using devices.
To test with a parallel build, the parallel (-p|-par) option
should be set first on the command line.
-v Enable valgrind
-o <dir> [${output_dir:-"<empty>: output goes to stdout"}]
If not empty, save output to files inside <dir>
-d <dir> [${mfem_build_dir}]
If <dir> is different from <mfem_dir> then use an
out-of-source build in <dir>
-j <np> [${make_j}] Specify the number of jobs to use for building
-c|-color Always use colors for the status messages: OK, FAILED, etc
-b|-built Do NOT rebuild the library and the executables
@@ -211,8 +196,8 @@ function help_message()
Their values can also set using the respective uppercase environment
variable
mfem_build_dir [${mfem_build_dir}]
Same as '-d': set this variable to something different from <mfem_dir>
to use an out-of-source build
Set this variable to something different from <mfem_dir> to use an
out-of-source build
For other valid variables, see the script source.
@@ -263,7 +248,7 @@ case "$1" in
-h|-help)
opt_help="yes"
;;
-p|-par)
-p|-parallel)
mfem_config="MFEM_USE_MPI=YES MFEM_DEBUG=NO"
;;
-g)
@@ -274,11 +259,6 @@ case "$1" in
groups=("${groups[@]}" "${test_group}")
shift 2
;;
-dev)
device_runs="yes"
mfem_config+=" MFEM_USE_CUDA=YES MFEM_USE_MM=YES \
MFEM_USE_OCCA=YES MFEM_USE_RAJA=YES MFEM_USE_OPENMP=YES"
;;
-v)
valgrind="yes"
;;
@@ -286,10 +266,6 @@ MFEM_USE_OCCA=YES MFEM_USE_RAJA=YES MFEM_USE_OPENMP=YES"
shift
output_dir="$1"
;;
-d)
shift
mfem_build_dir="$1"
;;
-j)
shift
make_j="-j $1"
@@ -309,10 +285,6 @@ MFEM_USE_OCCA=YES MFEM_USE_RAJA=YES MFEM_USE_OPENMP=YES"
-n)
run_prefix="echo"
;;
-*)
echo "unknown option: '$1'"
exit 1
;;
*=*)
eval $1
;;
+2 -5
View File
@@ -14,13 +14,11 @@
# Colors used below:
# green '\033[0;32m'
# red '\033[0;31m'
# yellow '\033[0;33m'
# no color '\033[0m'
COLOR_PRINT = if [ -t 1 ]; then \
printf $(1)$(2)'\033[0m'$(3); else printf $(2)$(3); fi
PRINT_OK = $(call COLOR_PRINT,'\033[0;32m',OK," ($$1 $$2)\n")
PRINT_FAILED = $(call COLOR_PRINT,'\033[0;31m',FAILED," ($$1 $$2)\n")
PRINT_SKIP = $(call COLOR_PRINT,'\033[0;33m',SKIP,"\n")
# Timing support
define TIMECMD_detect
@@ -38,7 +36,7 @@ export TIME='%es %MkB %x'; \
set -- $$($(1) $(SHELL) -c "$(2)" 2>&1); while [ "$$#" -gt 3 ]; do shift; done
endef
define TIMECMD.NOTGNU
set -- $$($(1) -l $(SHELL) -c "{ $(2); } > /dev/null 2>&1" 2>&1; echo $$?); \
set -- $$($(1) -l $(SHELL) -c "$(2)" 2>&1; echo $$?); \
set -- "$$1"s "$$(($$7/1024))"kB "$${60}"
endef
define TIMECMD.BASH
@@ -60,8 +58,7 @@ endif
# Test runs of the examples/miniapps with parameters - check exit code
mfem-test = \
printf " $(3) [$(2) $(1) ... ]: "; \
$(call $(TIMEFUN),$(TIMECMD),$(2) ./$(1) $(if $(5),,-no-vis )$(4) \
> $(1).stderr 2>&1); \
$(call $(TIMEFUN),$(TIMECMD),$(2) ./$(1) -no-vis $(4) > $(1).stderr 2>&1); \
if [ "$$3" = 0 ]; \
then $(PRINT_OK); else $(PRINT_FAILED); cat $(1).stderr; fi; \
rm -f $(1).stderr; exit $$3
-87
View File
@@ -1,87 +0,0 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
3
elements
8
1 6 0 9 18 1 10 19
1 6 1 10 19 2 11 20
1 6 2 11 20 3 12 21
1 6 3 12 21 4 13 22
2 6 4 13 22 5 14 23
2 6 5 14 23 6 15 24
2 6 6 15 24 7 16 25
2 6 7 16 25 8 17 26
boundary
26
1 2 0 18 9
2 2 8 17 26
3 3 0 9 10 1
3 3 1 10 11 2
3 3 2 11 12 3
3 3 3 12 13 4
3 3 4 13 14 5
3 3 5 14 15 6
3 3 6 15 16 7
3 3 7 16 17 8
3 3 18 0 1 19
3 3 19 1 2 20
3 3 20 2 3 21
3 3 21 3 4 22
3 3 22 4 5 23
3 3 23 5 6 24
3 3 24 6 7 25
3 3 25 7 8 26
3 3 9 18 19 10
3 3 10 19 20 11
3 3 11 20 21 12
3 3 12 21 22 13
3 3 13 22 23 14
3 3 14 23 24 15
3 3 15 24 25 16
3 3 16 25 26 17
vertices
27
3
0 0 0
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
0 1 0
1 1 0
2 1 0
3 1 0
4 1 0
5 1 0
6 1 0
7 1 0
8 1 0
0 0.5 1
1 0.5 1
2 0.5 1
3 0.5 1
4 0.5 1
5 0.5 1
6 0.5 1
7 0.5 1
8 0.5 1
-61
View File
@@ -1,61 +0,0 @@
# vtk DataFile Version 3.0
Generated by MFEM
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 27 double
0 0 0
1 0 0
2 0 0
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
0 1 0
1 1 0
2 1 0
3 1 0
4 1 0
5 1 0
6 1 0
7 1 0
8 1 0
0 0.5 1
1 0.5 1
2 0.5 1
3 0.5 1
4 0.5 1
5 0.5 1
6 0.5 1
7 0.5 1
8 0.5 1
CELLS 8 56
6 0 9 18 1 10 19
6 1 10 19 2 11 20
6 2 11 20 3 12 21
6 3 12 21 4 13 22
6 4 13 22 5 14 23
6 5 14 23 6 15 24
6 6 15 24 7 16 25
6 7 16 25 8 17 26
CELL_TYPES 8
13
13
13
13
13
13
13
13
CELL_DATA 8
SCALARS material int
LOOKUP_TABLE default
1
1
1
1
2
2
2
2
-192
View File
@@ -1,192 +0,0 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
3
elements
14
1 4 13 15 21 25
1 4 15 13 21 12
1 4 21 13 25 22
1 4 15 21 25 24
1 4 13 15 25 16
1 5 0 1 4 3 9 10 13 12
1 5 8 9 12 11 17 18 21 20
1 5 2 3 6 5 11 12 15 14
1 6 3 4 6 12 13 15
1 6 4 7 6 13 16 15
1 6 12 13 21 9 10 18
1 6 13 22 21 10 19 18
1 6 11 14 20 12 15 21
1 6 15 21 24 14 20 23
boundary
30
1 3 5 6 3 2
2 2 6 4 3
2 2 4 6 7
3 3 3 4 1 0
4 3 11 12 9 8
5 3 2 3 12 11
6 3 0 1 10 9
7 2 10 18 9
7 2 18 10 19
8 3 8 9 18 17
9 3 1 4 13 10
10 3 4 7 16 13
11 2 25 13 16
11 2 13 25 22
12 3 10 13 22 19
13 3 7 6 15 16
14 3 6 5 14 15
15 3 15 14 23 24
16 2 15 25 16
16 2 25 15 24
17 3 5 2 11 14
18 3 3 0 9 12
19 3 11 8 17 20
20 2 20 14 11
20 2 14 20 23
21 3 17 18 21 20
22 3 18 19 22 21
23 2 25 21 22
23 2 21 25 24
24 3 20 21 24 23
vertices
26
nodes
FiniteElementSpace
FiniteElementCollection: H1_3D_P2
VDim: 3
Ordering: 1
0.028213666146621 -1.0129124616273 -1.0197422793601
0.99151103207842 -0.97408353323117 -1.0219424221199
-0.98628834960982 -0.048291393648833 -1.0334530425724
-0.045286384224892 -0.028259630873799 -0.95961592583917
1.0351351283956 0.016103611653671 -1.0465984194074
-0.97963495329022 0.975340601895 -0.95050375238061
-0.016565482225269 0.98394050155766 -1.0119900547434
0.98232264800655 1.0061312792241 -0.97468885016611
-1.0111163694877 -1.0328216757625 -0.033904406474903
-0.031359497737139 -0.95907832225785 -0.02936147605069
1.0216721775476 -0.95571139678359 -0.041445003869012
-0.96617995956913 0.013420177670196 -0.047073400672525
0.03735491973348 0.024136644229293 -0.035419858060777
0.99844568660483 -0.023344853520393 0.043047091318294
-1.0075354852248 0.95110015915707 0.040374961402267
-0.018023004801944 0.98735854397528 0.035048884851858
0.96496833880778 0.98624407089765 0.029059857856424
-0.95618249163963 -0.95913625303656 0.99699592567049
0.010523111699149 -1.0380611987319 1.0054330066312
1.0131589291349 -0.99133288586241 1.0510169859154
-0.9992929702159 -0.016950021823868 1.0209834648762
-0.030905270343646 -0.024878516234457 0.96677784407511
1.0369556044533 0.036727200814101 0.97476146325791
-1.0268666699025 0.99100244478387 0.95557046163574
0.032850918109418 0.9761234538078 0.99340013005027
0.96517252528448 1.018590816239 0.96241486393546
0.52641251369336 0.53453492783232 -0.046831832639522
0.54842095679127 0.012466884090474 0.52264325135947
1.0546647359835 0.51503200008771 0.47661895657821
0.008193729444779 0.46320342579585 0.51330736048101
0.48446121998846 1.0366433051979 0.46910527980021
0.50338134740858 0.53372671722279 1.0016026703109
-0.0026805294677615 0.54834160562605 -0.022633473388851
0.4992129677441 -0.027650739811361 -0.025983834639192
-0.010308592952788 0.043478553090245 0.54404251929373
0.52373361142037 0.017260625417003 1.0190168930687
0.95156254112601 0.024917951411289 0.48927665714905
1.0114961385777 0.53988309084877 0.98077339629239
0.01429600397056 1.0255897320394 0.44945099394948
-0.0037663174125072 0.46114195337251 0.98693741812483
0.53955416269275 0.95254191223583 0.99345054396648
1.0344137934711 0.51549308419917 0.0019079259000746
0.4635900873147 1.0074141174823 -0.025796540646941
1.0393698821347 0.99823230649269 0.53561992818844
0.54910938213579 -1.0186136680655 -1.0399189315271
0.98251790353097 -0.52159510049969 -1.0488538759761
0.51290647936985 0.019199261348695 -1.0180139709264
0.039190890220925 -0.51870735888369 -1.0145805133507
0.54531239252537 -1.0346180800814 -0.026071808021516
1.0111227696296 -0.45961035727523 0.028725982550532
-0.0024106570985168 -0.51591348233633 0.042102640075609
0.019072471559048 -1.0489699664991 -0.53822694290429
1.0197706996463 -1.0138504981995 -0.48532295548357
0.97708769380115 0.012869927892461 -0.49512141938321
-0.0056951441802084 -0.018287890031934 -0.46456751856022
-0.48628377295099 -0.97137148869224 -0.040609835088253
-0.52949825478718 0.022831952339038 0.036623532185331
-0.9682938832324 -0.51529484749772 0.039498377451673
-0.45076946932822 -0.98247022288851 1.0229644412175
-0.036635886738077 -0.53934830226935 0.97308384231292
-0.47986206617206 -0.041745604947209 0.98161771683954
-0.95103283049539 -0.5087813614402 1.0116585971788
-0.95395673410967 -0.95082942959853 0.50977751370519
0.030673310998827 -0.97366141136736 0.47265974627808
-1.0076441270299 0.025157339498401 0.51940553779714
-0.45112570035271 0.030354945734143 -1.0244264173787
-0.034796683816239 0.47213521944359 -1.0233666383661
-0.52309081116691 1.0127369282767 -1.030445962213
-1.0052867605351 0.54541603662074 -0.99267176855355
-0.53441363093443 1.0101050069556 0.034852372528985
-1.0361742412671 0.51952713127248 -0.0075041593052447
-1.0224051106721 0.037305149668828 -0.51234883274883
-0.0468317149207 0.99936735257506 -0.53290488454513
-1.0323944162577 1.0470460939221 -0.49629869163036
0.50827771586097 0.51091354087276 -0.96143114171132
0.97860428203942 0.53881222049291 -1.0227558970328
0.54899092558423 1.0449853148062 -1.0290394971016
0.98149990118493 1.0265442789565 -0.45402792714566
0.47938502309767 -0.95321110021154 0.46438798044786
0.98893120098231 -1.0252040218394 0.52866776747387
0.46061993861414 -0.973998097143 0.95264651015888
0.98858339184873 -0.49578777734639 0.97955980177082
-0.95322811676761 0.49312524158842 0.46350421594559
-0.9670648949319 0.52720408663568 1.0147400701319
-0.95970724064157 0.9966338243727 0.47198853459547
-0.55076990539437 0.95548113087191 1.0002298586837
0.48237521727569 -0.51972299404442 -0.98436066769063
0.45025863721967 -1.0030842470471 -0.53693975312635
0.95356930759735 -0.4606471833773 -0.49721032292582
0.48610299886204 0.033102156873792 -0.45204877182841
0.016292646434158 -0.4694908623118 -0.53292224425822
0.47584088565782 -0.54223454683088 -0.036028525792062
-0.53143287785351 -0.4923779387027 0.0039846746250987
-0.52957315347157 -1.0359902368858 0.51208876920864
-0.024055424472317 -0.49951890320517 0.48579422575422
-0.45644746879116 -0.012607240816578 0.51010388839059
-0.98394734906033 -0.50309513998218 0.47998268660158
-0.53098605261184 -0.48258609846234 0.97544367099181
-0.51822144156322 0.45223189569078 -1.0385291075334
-0.45871022404172 -0.042734754644334 -0.54302125046961
0.041843411838636 0.46222349074669 -0.5097909247037
-0.45607118047774 1.0116704457439 -0.45481789885089
-1.0244252419565 0.4849586374592 -0.50017994958907
-0.52441235366277 0.50157218999229 0.023797604069114
0.46467856940869 0.54693057615002 -0.46251054922067
0.98669286111723 0.51824862516758 -0.45168929326637
0.54790127868275 0.98589193659248 -0.51421705686245
0.54233705943277 -0.4508773840935 0.45025142266283
1.0203662623874 -0.5304726794563 0.52365051237419
0.48446453821555 -0.47976663671026 1.043945324572
-0.48793381256969 0.50247088679532 0.48323828733422
-0.52670996575095 0.50194146344506 1.0026980744777
-0.47523256142428 0.97748358070477 0.48234451559035
0.45616661459208 -0.50770850274712 -0.4568053398747
-0.52734654471278 -0.51337681044824 0.47594708297402
-0.45737625267357 0.47732204026543 -0.54846904515289
-168
View File
@@ -1,168 +0,0 @@
# vtk DataFile Version 3.0
Generated by MFEM
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 116 double
0.028213666146621 -1.0129124616273 -1.0197422793601
0.99151103207842 -0.97408353323117 -1.0219424221199
-0.98628834960982 -0.048291393648833 -1.0334530425724
-0.045286384224892 -0.028259630873799 -0.95961592583917
1.0351351283956 0.016103611653671 -1.0465984194074
-0.97963495329022 0.975340601895 -0.95050375238061
-0.016565482225269 0.98394050155766 -1.0119900547434
0.98232264800655 1.0061312792241 -0.97468885016611
-1.0111163694877 -1.0328216757625 -0.033904406474903
-0.031359497737139 -0.95907832225785 -0.02936147605069
1.0216721775476 -0.95571139678359 -0.041445003869012
-0.96617995956913 0.013420177670196 -0.047073400672525
0.03735491973348 0.024136644229293 -0.035419858060777
0.99844568660483 -0.023344853520393 0.043047091318294
-1.0075354852248 0.95110015915707 0.040374961402267
-0.018023004801944 0.98735854397528 0.035048884851858
0.96496833880778 0.98624407089765 0.029059857856424
-0.95618249163963 -0.95913625303656 0.99699592567049
0.010523111699149 -1.0380611987319 1.0054330066312
1.0131589291349 -0.99133288586241 1.0510169859154
-0.9992929702159 -0.016950021823868 1.0209834648762
-0.030905270343646 -0.024878516234457 0.96677784407511
1.0369556044533 0.036727200814101 0.97476146325791
-1.0268666699025 0.99100244478387 0.95557046163574
0.032850918109418 0.9761234538078 0.99340013005027
0.96517252528448 1.018590816239 0.96241486393546
0.50338134740858 0.53372671722279 1.0016026703109
0.54842095679127 0.012466884090474 0.52264325135947
0.008193729444779 0.46320342579585 0.51330736048101
1.0546647359835 0.51503200008771 0.47661895657821
0.48446121998846 1.0366433051979 0.46910527980021
0.52641251369336 0.53453492783232 -0.046831832639522
-0.0026805294677615 0.54834160562605 -0.022633473388851
0.4992129677441 -0.027650739811361 -0.025983834639192
-0.010308592952788 0.043478553090245 0.54404251929373
1.0114961385777 0.53988309084877 0.98077339629239
0.52373361142037 0.017260625417003 1.0190168930687
0.95156254112601 0.024917951411289 0.48927665714905
-0.0037663174125072 0.46114195337251 0.98693741812483
0.53955416269275 0.95254191223583 0.99345054396648
0.01429600397056 1.0255897320394 0.44945099394948
1.0344137934711 0.51549308419917 0.0019079259000746
0.4635900873147 1.0074141174823 -0.025796540646941
1.0393698821347 0.99823230649269 0.53561992818844
0.54910938213579 -1.0186136680655 -1.0399189315271
0.98251790353097 -0.52159510049969 -1.0488538759761
0.51290647936985 0.019199261348695 -1.0180139709264
0.039190890220925 -0.51870735888369 -1.0145805133507
0.54531239252537 -1.0346180800814 -0.026071808021516
1.0111227696296 -0.45961035727523 0.028725982550532
-0.0024106570985168 -0.51591348233633 0.042102640075609
0.019072471559048 -1.0489699664991 -0.53822694290429
1.0197706996463 -1.0138504981995 -0.48532295548357
0.97708769380115 0.012869927892461 -0.49512141938321
-0.0056951441802084 -0.018287890031934 -0.46456751856022
-0.48628377295099 -0.97137148869224 -0.040609835088253
-0.52949825478718 0.022831952339038 0.036623532185331
-0.9682938832324 -0.51529484749772 0.039498377451673
-0.45076946932822 -0.98247022288851 1.0229644412175
-0.036635886738077 -0.53934830226935 0.97308384231292
-0.47986206617206 -0.041745604947209 0.98161771683954
-0.95103283049539 -0.5087813614402 1.0116585971788
-0.95395673410967 -0.95082942959853 0.50977751370519
0.030673310998827 -0.97366141136736 0.47265974627808
-1.0076441270299 0.025157339498401 0.51940553779714
-0.45112570035271 0.030354945734143 -1.0244264173787
-0.034796683816239 0.47213521944359 -1.0233666383661
-0.52309081116691 1.0127369282767 -1.030445962213
-1.0052867605351 0.54541603662074 -0.99267176855355
-0.53441363093443 1.0101050069556 0.034852372528985
-1.0361742412671 0.51952713127248 -0.0075041593052447
-1.0224051106721 0.037305149668828 -0.51234883274883
-0.0468317149207 0.99936735257506 -0.53290488454513
-1.0323944162577 1.0470460939221 -0.49629869163036
0.50827771586097 0.51091354087276 -0.96143114171132
0.97860428203942 0.53881222049291 -1.0227558970328
0.54899092558423 1.0449853148062 -1.0290394971016
0.98149990118493 1.0265442789565 -0.45402792714566
0.47938502309767 -0.95321110021154 0.46438798044786
0.98893120098231 -1.0252040218394 0.52866776747387
0.46061993861414 -0.973998097143 0.95264651015888
0.98858339184873 -0.49578777734639 0.97955980177082
-0.95322811676761 0.49312524158842 0.46350421594559
-0.9670648949319 0.52720408663568 1.0147400701319
-0.95970724064157 0.9966338243727 0.47198853459547
-0.55076990539437 0.95548113087191 1.0002298586837
0.48237521727569 -0.51972299404442 -0.98436066769063
0.45025863721967 -1.0030842470471 -0.53693975312635
0.95356930759735 -0.4606471833773 -0.49721032292582
0.48610299886204 0.033102156873792 -0.45204877182841
0.016292646434158 -0.4694908623118 -0.53292224425822
0.47584088565782 -0.54223454683088 -0.036028525792062
-0.53143287785351 -0.4923779387027 0.0039846746250987
-0.52957315347157 -1.0359902368858 0.51208876920864
-0.024055424472317 -0.49951890320517 0.48579422575422
-0.45644746879116 -0.012607240816578 0.51010388839059
-0.98394734906033 -0.50309513998218 0.47998268660158
-0.53098605261184 -0.48258609846234 0.97544367099181
-0.51822144156322 0.45223189569078 -1.0385291075334
-0.45871022404172 -0.042734754644334 -0.54302125046961
0.041843411838636 0.46222349074669 -0.5097909247037
-0.45607118047774 1.0116704457439 -0.45481789885089
-1.0244252419565 0.4849586374592 -0.50017994958907
-0.52441235366277 0.50157218999229 0.023797604069114
0.46467856940869 0.54693057615002 -0.46251054922067
0.98669286111723 0.51824862516758 -0.45168929326637
0.54790127868275 0.98589193659248 -0.51421705686245
0.54233705943277 -0.4508773840935 0.45025142266283
1.0203662623874 -0.5304726794563 0.52365051237419
0.48446453821555 -0.47976663671026 1.043945324572
-0.48793381256969 0.50247088679532 0.48323828733422
-0.52670996575095 0.50194146344506 1.0026980744777
-0.47523256142428 0.97748358070477 0.48234451559035
0.45616661459208 -0.50770850274712 -0.4568053398747
-0.52734654471278 -0.51337681044824 0.47594708297402
-0.45737625267357 0.47732204026543 -0.54846904515289
CELLS 14 253
10 21 25 13 15 26 29 27 28 30 31
10 15 13 21 12 31 27 28 32 33 34
10 25 21 13 22 26 27 29 35 36 37
10 21 25 15 24 26 30 28 38 39 40
10 13 15 25 16 31 30 29 41 42 43
27 0 1 4 3 9 10 13 12 44 45 46 47 48 49 33 50 51 52 53 54 90 88 87 89 86 91 113
27 8 9 12 11 17 18 21 20 55 50 56 57 58 59 60 61 62 63 34 64 96 94 93 95 92 97 114
27 2 3 6 5 11 12 15 14 65 66 67 68 56 32 69 70 71 54 72 73 102 100 99 101 98 103 115
18 3 6 4 12 15 13 66 74 46 32 31 33 54 72 53 100 104 89
18 4 6 7 13 15 16 74 76 75 31 42 41 53 72 77 104 106 105
18 12 21 13 9 18 10 34 27 33 63 78 48 50 59 49 94 107 91
18 13 21 22 10 18 19 27 36 37 78 80 79 49 59 81 107 109 108
18 11 20 14 12 21 15 64 82 70 34 28 32 56 60 69 95 110 103
18 15 24 21 14 23 20 40 38 28 84 83 82 69 85 60 112 111 110
CELL_TYPES 14
24
24
24
24
24
29
29
29
32
32
32
32
32
32
CELL_DATA 14
SCALARS material int
LOOKUP_TABLE default
1
1
1
1
1
1
1
1
1
1
1
1
1
1
-96
View File
@@ -1,96 +0,0 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
3
elements
14
1 4 13 15 21 25
1 4 12 13 15 21
1 4 13 21 22 25
1 4 15 24 21 25
1 4 13 15 25 16
1 5 0 1 4 3 9 10 13 12
1 5 8 9 12 11 17 18 21 20
1 5 2 3 6 5 11 12 15 14
1 6 3 4 6 12 13 15
1 6 4 7 6 13 16 15
1 6 12 13 21 9 10 18
1 6 13 22 21 10 19 18
1 6 11 14 20 12 15 21
1 6 15 21 24 14 20 23
boundary
30
1 3 5 6 3 2
2 2 3 6 4
2 2 4 6 7
3 3 3 4 1 0
4 3 11 12 9 8
5 3 2 3 12 11
6 3 0 1 10 9
7 2 9 10 18
7 2 10 19 18
8 3 8 9 18 17
9 3 1 4 13 10
10 3 4 7 16 13
11 2 13 16 25
11 2 13 25 22
12 3 10 13 22 19
13 3 7 6 15 16
14 3 6 5 14 15
15 3 15 14 23 24
16 2 16 15 25
16 2 15 24 25
17 3 5 2 11 14
18 3 3 0 9 12
19 3 11 8 17 20
20 2 11 20 14
20 2 14 20 23
21 3 17 18 21 20
22 3 18 19 22 21
23 2 21 22 25
23 2 21 25 24
24 3 20 21 24 23
vertices
26
3
0 -1 -1
1 -1 -1
-1 0 -1
0 0 -1
1 0 -1
-1 1 -1
0 1 -1
1 1 -1
-1 -1 0
0 -1 0
1 -1 0
-1 0 0
0 0 0
1 0 0
-1 1 0
0 1 0
1 1 0
-1 -1 1
0 -1 1
1 -1 1
-1 0 1
0 0 1
1 0 1
-1 1 1
0 1 1
1 1 1
+3 -3
View File
@@ -19,10 +19,10 @@ elements
1 5 0 1 4 3 9 10 13 12
1 5 3 4 7 6 12 13 16 15
1 5 2 3 6 5 11 12 15 14
1 5 11 12 15 14 20 21 24 23
1 5 12 13 16 15 21 22 25 24
1 5 9 10 13 12 18 19 22 21
1 5 8 9 12 11 17 18 21 20
1 5 9 10 13 12 18 19 22 21
1 5 12 13 16 15 21 22 25 24
1 5 11 12 15 14 20 21 24 23
boundary
24
-9
View File
@@ -1,9 +0,0 @@
MFEM INLINE mesh v1.0
type = wedge
nx = 4
ny = 4
nz = 4
sx = 1.0
sy = 1.0
sz = 1.0
-182
View File
@@ -1,182 +0,0 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
#
dimension
2
elements
30
1 3 0 11 26 14
1 3 0 14 27 17
1 3 0 17 28 20
1 3 0 20 29 23
1 3 0 23 30 11
1 2 1 26 11
1 2 26 1 12
1 3 26 12 3 13
1 2 2 26 13
1 2 26 2 14
1 2 2 27 14
1 2 27 2 15
1 3 27 15 5 16
1 2 4 27 16
1 2 27 4 17
1 2 4 28 17
1 2 28 4 18
1 3 28 18 7 19
1 2 6 28 19
1 2 28 6 20
1 2 6 29 20
1 2 29 6 21
1 3 29 21 9 22
1 2 8 29 22
1 2 29 8 23
1 2 8 30 23
1 2 30 8 24
1 3 30 24 10 25
1 2 1 30 25
1 2 30 1 11
boundary
20
1 1 13 2
1 1 12 3
1 1 16 4
1 1 15 5
1 1 19 6
1 1 18 7
1 1 22 8
1 1 21 9
1 1 25 1
1 1 24 10
1 1 3 13
1 1 1 12
1 1 5 16
1 1 2 15
1 1 7 19
1 1 4 18
1 1 9 22
1 1 6 21
1 1 10 25
1 1 8 24
vertices
31
nodes
FiniteElementSpace
FiniteElementCollection: H1_2D_P2
VDim: 2
Ordering: 1
0.01350768617383 -0.0075500592639684
1 0
0.309017 0.951057
1.30902 0.951057
-0.809017 0.587785
-0.5 1.53884
-0.809017 -0.587785
-1.61803 0
0.309017 -0.951057
-0.5 -1.53884
1.30902 -0.951057
0.4935497789318 -0.012882964767041
1.15451 0.475529
0.809019 0.951057
0.17136163619581 0.48175756223348
-0.0954915 1.24495
-0.654508 1.06331
-0.41734925397369 0.28726550311701
-1.21352 0.293893
-1.21352 -0.293892
-0.39460365124056 -0.30156877530663
-0.654508 -1.06331
-0.0954915 -1.24495
0.14399901886801 -0.48762042397771
0.809019 -0.951057
1.15451 -0.475529
0.6498356311584 0.48434918539882
-0.24288407581812 0.75594729997554
-0.8152592767797 0.0028387384025541
-0.22754482186326 -0.77540708661379
0.672255499984 -0.48174474211839
0.22829595615988 0.0021164169942289
0.60101450815825 0.21860266792331
0.41883194868682 0.47605389684094
0.07343165966527 0.21396989328966
-0.02571592547416 0.63942139993498
-0.32229829912758 0.53827901417123
-0.17873676879185 0.14412581843398
-0.6182337454462 0.14256917811499
-0.59596471744054 -0.16569961862581
-0.19439899436461 -0.12390276596268
-0.33986575323528 -0.53331120777067
-0.064647379830725 -0.60235938684263
0.091924539036435 -0.25440885597942
0.40469418107844 -0.47549896605132
0.59442400974309 -0.23815570080881
0.83567929699787 0.25605757828544
0.73491944894413 -0.013500778246483
1.077255 0.2377645
0.88696375569985 0.49133008726061
1.231765 0.713293
1.0590195 0.951057
0.72725653289275 0.73104100472096
0.50225974659165 0.6904536152084
0.559018 0.951057
0.23657516510421 0.69857072686934
0.011561493903121 0.87524541641085
0.10676275 1.0980035
-0.17127243181091 0.99863326833074
-0.29774575 1.391895
-0.577254 1.301075
-0.45323351407757 0.93490604288187
-0.55200861955087 0.66792304985565
-0.7317625 0.8255475
-0.58327877079184 0.4240660861124
-0.81465656906104 0.28713104760848
-1.0112685 0.440839
-0.99771272279525 0.1592736885552
-1.415775 0.1469465
-1.415775 -0.146946
-1.0166887889241 -0.16866723370018
-0.80412516287867 -0.29582734656
-1.0112685 -0.4408385
-0.6073309356422 -0.45826153759998
-0.55501395481483 -0.68914767547246
-0.7317625 -0.8255475
-0.45240617124569 -0.93833106759189
-0.577254 -1.301075
-0.29774575 -1.391895
-0.1923419715726 -1.0285844005569
0.031614306262131 -0.83601077226744
0.10676275 -1.0980035
0.22112358843745 -0.69009711121629
0.50046759811715 -0.72837571286759
0.559018 -0.951057
0.71074483315985 -0.70826931724532
1.0590195 -0.951057
1.231765 -0.713293
0.89135027612826 -0.46226040977064
0.84948897506491 -0.23986695857234
1.077255 -0.2377645
0.31586449185434 0.2462788698702
-0.13788918217579 0.40149150514309
-0.40416548945856 0.0027692745957735
-0.14861804521337 -0.3698676302047
0.33007376541085 -0.24598293851351
0.99473757603443 0.69214841080247
-0.38122249894249 1.1629329119286
-1.208195003484 -0.0026998371675556
-0.35890854853443 -1.1361244276705
0.9901912195942 -0.73640851058427
-201
View File
@@ -1,201 +0,0 @@
# vtk DataFile Version 3.0
Generated by MFEM
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 101 double
0.01350768617383 -0.0075500592639684 0
1 0 0
0.309017 0.951057 0
1.30902 0.951057 0
-0.809017 0.587785 0
-0.5 1.53884 0
-0.809017 -0.587785 0
-1.61803 0 0
0.309017 -0.951057 0
-0.5 -1.53884 0
1.30902 -0.951057 0
0.4935497789318 -0.012882964767041 0
1.15451 0.475529 0
0.809019 0.951057 0
0.17136163619581 0.48175756223348 0
-0.0954915 1.24495 0
-0.654508 1.06331 0
-0.41734925397369 0.28726550311701 0
-1.21352 0.293893 0
-1.21352 -0.293892 0
-0.39460365124056 -0.30156877530663 0
-0.654508 -1.06331 0
-0.0954915 -1.24495 0
0.14399901886801 -0.48762042397771 0
0.809019 -0.951057 0
1.15451 -0.475529 0
0.6498356311584 0.48434918539882 0
-0.24288407581812 0.75594729997554 0
-0.8152592767797 0.0028387384025541 0
-0.22754482186326 -0.77540708661379 0
0.672255499984 -0.48174474211839 0
0.22829595615988 0.0021164169942289 0
0.60101450815825 0.21860266792331 0
0.41883194868682 0.47605389684094 0
0.07343165966527 0.21396989328966 0
-0.02571592547416 0.63942139993498 0
-0.32229829912758 0.53827901417123 0
-0.17873676879185 0.14412581843398 0
-0.6182337454462 0.14256917811499 0
-0.59596471744054 -0.16569961862581 0
-0.19439899436461 -0.12390276596268 0
-0.33986575323528 -0.53331120777067 0
-0.064647379830725 -0.60235938684263 0
0.091924539036435 -0.25440885597942 0
0.40469418107844 -0.47549896605132 0
0.59442400974309 -0.23815570080881 0
0.83567929699787 0.25605757828544 0
0.73491944894413 -0.013500778246483 0
1.077255 0.2377645 0
0.88696375569985 0.49133008726061 0
1.231765 0.713293 0
1.0590195 0.951057 0
0.72725653289275 0.73104100472096 0
0.50225974659165 0.6904536152084 0
0.559018 0.951057 0
0.23657516510421 0.69857072686934 0
0.011561493903121 0.87524541641085 0
0.10676275 1.0980035 0
-0.17127243181091 0.99863326833074 0
-0.29774575 1.391895 0
-0.577254 1.301075 0
-0.45323351407757 0.93490604288187 0
-0.55200861955087 0.66792304985565 0
-0.7317625 0.8255475 0
-0.58327877079184 0.4240660861124 0
-0.81465656906104 0.28713104760848 0
-1.0112685 0.440839 0
-0.99771272279525 0.1592736885552 0
-1.415775 0.1469465 0
-1.415775 -0.146946 0
-1.0166887889241 -0.16866723370018 0
-0.80412516287867 -0.29582734656 0
-1.0112685 -0.4408385 0
-0.6073309356422 -0.45826153759998 0
-0.55501395481483 -0.68914767547246 0
-0.7317625 -0.8255475 0
-0.45240617124569 -0.93833106759189 0
-0.577254 -1.301075 0
-0.29774575 -1.391895 0
-0.1923419715726 -1.0285844005569 0
0.031614306262131 -0.83601077226744 0
0.10676275 -1.0980035 0
0.22112358843745 -0.69009711121629 0
0.50046759811715 -0.72837571286759 0
0.559018 -0.951057 0
0.71074483315985 -0.70826931724532 0
1.0590195 -0.951057 0
1.231765 -0.713293 0
0.89135027612826 -0.46226040977064 0
0.84948897506491 -0.23986695857234 0
1.077255 -0.2377645 0
0.31586449185434 0.2462788698702 0
-0.13788918217579 0.40149150514309 0
-0.40416548945856 0.0027692745957735 0
-0.14861804521337 -0.3698676302047 0
0.33007376541085 -0.24598293851351 0
0.99473757603443 0.69214841080247 0
-0.38122249894249 1.1629329119286 0
-1.208195003484 -0.0026998371675556 0
-0.35890854853443 -1.1361244276705 0
0.9901912195942 -0.73640851058427 0
CELLS 30 240
9 0 11 26 14 31 32 33 34 91
9 0 14 27 17 34 35 36 37 92
9 0 17 28 20 37 38 39 40 93
9 0 20 29 23 40 41 42 43 94
9 0 23 30 11 43 44 45 31 95
6 1 26 11 46 32 47
6 26 1 12 46 48 49
9 26 12 3 13 49 50 51 52 96
6 2 26 13 53 52 54
6 26 2 14 53 55 33
6 2 27 14 56 35 55
6 27 2 15 56 57 58
9 27 15 5 16 58 59 60 61 97
6 4 27 16 62 61 63
6 27 4 17 62 64 36
6 4 28 17 65 38 64
6 28 4 18 65 66 67
9 28 18 7 19 67 68 69 70 98
6 6 28 19 71 70 72
6 28 6 20 71 73 39
6 6 29 20 74 41 73
6 29 6 21 74 75 76
9 29 21 9 22 76 77 78 79 99
6 8 29 22 80 79 81
6 29 8 23 80 82 42
6 8 30 23 83 44 82
6 30 8 24 83 84 85
9 30 24 10 25 85 86 87 88 100
6 1 30 25 89 88 90
6 30 1 11 89 47 45
CELL_TYPES 30
28
28
28
28
28
22
22
28
22
22
22
22
28
22
22
22
22
28
22
22
22
22
28
22
22
22
22
28
22
22
CELL_DATA 30
SCALARS material int
LOOKUP_TABLE default
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
-107
View File
@@ -1,107 +0,0 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
2
elements
30
1 3 0 11 26 14
1 3 0 14 27 17
1 3 0 17 28 20
1 3 0 20 29 23
1 3 0 23 30 11
1 2 11 1 26
1 2 1 12 26
1 3 26 12 3 13
1 2 26 13 2
1 2 14 26 2
1 2 14 2 27
1 2 2 15 27
1 3 27 15 5 16
1 2 27 16 4
1 2 17 27 4
1 2 17 4 28
1 2 4 18 28
1 3 28 18 7 19
1 2 28 19 6
1 2 20 28 6
1 2 20 6 29
1 2 6 21 29
1 3 29 21 9 22
1 2 29 22 8
1 2 23 29 8
1 2 23 8 30
1 2 8 24 30
1 3 30 24 10 25
1 2 30 25 1
1 2 11 30 1
boundary
20
1 1 13 2
1 1 12 3
1 1 16 4
1 1 15 5
1 1 19 6
1 1 18 7
1 1 22 8
1 1 21 9
1 1 25 1
1 1 24 10
1 1 3 13
1 1 1 12
1 1 5 16
1 1 2 15
1 1 7 19
1 1 4 18
1 1 9 22
1 1 6 21
1 1 10 25
1 1 8 24
vertices
31
2
0 0
1 0
0.309017 0.951057
1.30902 0.951057
-0.809017 0.587785
-0.5 1.53884
-0.809017 -0.587785
-1.61803 0
0.309017 -0.951057
-0.5 -1.53884
1.30902 -0.951057
0.5 0
1.15451 0.475529
0.809019 0.951057
0.154508 0.475529
-0.0954915 1.24495
-0.654508 1.06331
-0.404508 0.293893
-1.21352 0.293893
-1.21352 -0.293892
-0.404508 -0.293893
-0.654508 -1.06331
-0.0954915 -1.24495
0.154508 -0.475529
0.809019 -0.951057
1.15451 -0.475529
0.654509 0.475529
-0.25 0.769421
-0.809016 0
-0.25 -0.76942
0.654509 -0.475529
-350
View File
@@ -1,350 +0,0 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
3
elements
6
1 5 0 1 2 3 4 5 6 7
1 5 4 5 6 7 8 9 10 11
1 5 8 9 10 11 12 13 14 15
1 5 12 13 14 15 16 17 18 19
1 5 16 17 18 19 20 21 22 23
1 5 20 21 22 23 3 0 1 2
boundary
24
1 3 0 1 5 4
1 3 1 2 6 5
1 3 2 3 7 6
1 3 3 0 4 7
1 3 4 5 9 8
1 3 5 6 10 9
1 3 6 7 11 10
1 3 7 4 8 11
1 3 8 9 13 12
1 3 9 10 14 13
1 3 10 11 15 14
1 3 11 8 12 15
1 3 12 13 17 16
1 3 13 14 18 17
1 3 14 15 19 18
1 3 15 12 16 19
1 3 16 17 21 20
1 3 17 18 22 21
1 3 18 19 23 22
1 3 19 16 20 23
1 3 20 21 0 3
1 3 21 22 1 0
1 3 22 23 2 1
1 3 23 20 3 2
vertices
24
nodes
FiniteElementSpace
FiniteElementCollection: H1_3D_P3
VDim: 3
Ordering: 1
0.71715729 -1.7565288e-16 -0.28284271
0.71715729 -1.7565288e-16 0.28284271
1.2828427 -3.1420584e-16 0.28284271
1.2828427 -3.1420584e-16 -0.28284271
0.3 0.51961524 -2.7755576e-17
0.5 0.8660254 0.4
0.7 1.2124356 2.7755576e-17
0.5 0.8660254 -0.4
-0.35857864 0.62107643 0.28284271
-0.64142136 1.1109744 0.28284271
-0.64142136 1.1109744 -0.28284271
-0.35857864 0.62107643 -0.28284271
-1 1.2246468e-16 0.4
-1.4 1.7145055e-16 2.7755576e-17
-1 1.2246468e-16 -0.4
-0.6 7.3478808e-17 -2.7755576e-17
-0.64142136 -1.1109744 0.28284271
-0.64142136 -1.1109744 -0.28284271
-0.35857864 -0.62107643 -0.28284271
-0.35857864 -0.62107643 0.28284271
0.7 -1.2124356 8.3266727e-17
0.5 -0.8660254 -0.4
0.3 -0.51961524 -8.3266727e-17
0.5 -0.8660254 0.4
0.71715729 -1.7565288e-16 -0.12649111
0.71715729 -1.7565288e-16 0.12649111
0.87350889 -2.1394797e-16 0.28284271
1.1264911 -2.7591075e-16 0.28284271
1.2828427 -3.1420584e-16 0.12649111
1.2828427 -3.1420584e-16 -0.12649111
0.87350889 -2.1394797e-16 -0.28284271
1.1264911 -2.7591075e-16 -0.28284271
0.35527864 0.61536066 0.11055728
0.44472136 0.77027999 0.28944272
0.55527864 0.96177082 0.28944272
0.64472136 1.1166902 0.11055728
0.64472136 1.1166902 -0.11055728
0.55527864 0.96177082 -0.28944272
0.35527864 0.61536066 -0.11055728
0.44472136 0.77027999 -0.28944272
0.63530452 0.18919442 -0.21528657
0.44264573 0.41882944 -0.086151128
0.75207276 0.22396814 0.33712267
0.66379961 0.62808427 0.39061232
1.2815042 0.38163342 0.21528657
1.01011 0.95576166 0.086151128
1.1647359 0.3468597 -0.33712267
0.78895615 0.74650684 -0.39061232
-0.43675445 0.75648089 0.28284271
-0.56324555 0.97556992 0.28284271
-0.64142136 1.1109744 0.12649111
-0.64142136 1.1109744 -0.12649111
-0.56324555 0.97556992 -0.28284271
-0.43675445 0.75648089 -0.28284271
-0.35857864 0.62107643 0.12649111
-0.35857864 0.62107643 -0.12649111
0.14139407 0.59275717 0.086151128
-0.15380509 0.64478706 0.21528657
0.25201581 1.0565095 0.39061232
-0.28197865 1.1821208 0.33712267
0.32265887 1.3526618 -0.086151128
-0.31024785 1.3006319 -0.21528657
0.21203713 0.88890945 -0.39061232
-0.18207429 0.76329818 -0.33712267
-1.1105573 1.3600404e-16 0.28944272
-1.2894427 1.5791119e-16 0.11055728
-1.2894427 1.5791119e-16 -0.11055728
-1.1105573 1.3600404e-16 -0.28944272
-0.88944272 1.0892532e-16 -0.28944272
-0.71055728 8.701817e-17 -0.11055728
-0.88944272 1.0892532e-16 0.28944272
-0.71055728 8.701817e-17 0.11055728
-0.56999848 0.53933005 0.33712267
-0.87583673 0.26082519 0.39061232
-0.97125633 0.91899846 0.21528657
-1.3327689 0.39690011 0.086151128
-0.88275728 0.83526106 -0.33712267
-1.040972 0.31000265 -0.39061232
-0.48149943 0.45559264 -0.21528657
-0.5840398 0.17392773 -0.086151128
-0.64142136 -1.1109744 0.12649111
-0.64142136 -1.1109744 -0.12649111
-0.56324555 -0.97556992 -0.28284271
-0.43675445 -0.75648089 -0.28284271
-0.35857864 -0.62107643 -0.12649111
-0.35857864 -0.62107643 0.12649111
-0.56324555 -0.97556992 0.28284271
-0.43675445 -0.75648089 0.28284271
-1.040972 -0.31000265 0.39061232
-0.88275728 -0.83526106 0.33712267
-1.3327689 -0.39690011 -0.086151128
-0.97125633 -0.91899846 -0.21528657
-0.87583673 -0.26082519 -0.39061232
-0.56999848 -0.53933005 -0.33712267
-0.5840398 -0.17392773 0.086151128
-0.48149943 -0.45559264 0.21528657
0.64472136 -1.1166902 -0.11055728
0.55527864 -0.96177082 -0.28944272
0.44472136 -0.77027999 -0.28944272
0.35527864 -0.61536066 -0.11055728
0.35527864 -0.61536066 0.11055728
0.44472136 -0.77027999 0.28944272
0.64472136 -1.1166902 0.11055728
0.55527864 -0.96177082 0.28944272
-0.31024785 -1.3006319 0.21528657
0.32265887 -1.3526618 0.086151128
-0.28197865 -1.1821208 -0.33712267
0.25201581 -1.0565095 -0.39061232
-0.15380509 -0.64478706 -0.21528657
0.14139407 -0.59275717 -0.086151128
-0.18207429 -0.76329818 0.33712267
0.21203713 -0.88890945 0.39061232
1.2815042 -0.38163342 -0.21528657
1.01011 -0.95576166 -0.086151128
0.75207276 -0.22396814 -0.33712267
0.66379961 -0.62808427 -0.39061232
0.63530452 -0.18919442 0.21528657
0.44264573 -0.41882944 0.086151128
1.1647359 -0.3468597 0.33712267
0.78895615 -0.74650684 0.39061232
1.1264911 -2.7591075e-16 -0.12649111
1.1264911 -2.7591075e-16 0.12649111
0.87350889 -2.1394797e-16 -0.12649111
0.87350889 -9.8977972e-16 0.12649111
0.66757847 0.19880564 -0.062604414
0.71979881 0.21435692 0.18444051
0.50377116 0.47666605 0.045623048
0.60267418 0.57024766 0.25883814
0.89840401 0.26754575 0.303448
1.1351729 0.33805581 0.24896124
0.75951745 0.71865207 0.30646131
0.91439218 0.86519386 0.17030213
1.2492302 0.3720222 0.062604414
1.1970099 0.35647092 -0.18444051
0.9489846 0.89792505 -0.045623048
0.85008158 0.80434345 -0.25883814
1.0184047 0.30328209 -0.303448
0.78163576 0.23277203 -0.24896124
0.69323831 0.65593903 -0.30646131
0.53836358 0.50939725 -0.17030213
0.41055728 0.71110607 -1.3877788e-17
0.5 0.8660254 0.17888544
0.5 0.8660254 -0.17888544
0.58944272 1.0209447 1.3877788e-17
0.17196917 0.72093516 0.17030213
0.22144071 0.9283315 0.30646131
-0.18923139 0.79330244 0.24896124
-0.24655235 1.0336054 0.303448
0.27154107 1.138364 0.25883814
0.30313361 1.2708073 0.045623048
-0.28979207 1.2148764 0.18444051
-0.30243444 1.2678762 -0.062604414
0.29208377 1.2244838 -0.17030213
0.24261222 1.0170874 -0.30646131
-0.27482155 1.1521165 -0.24896124
-0.21750059 0.91181357 -0.303448
0.19251187 0.80705498 -0.25883814
0.16091933 0.67461165 -0.045623048
-0.17426087 0.73054252 -0.18444051
-0.1616185 0.67754273 0.062604414
-0.43675445 0.75648089 0.12649111
-0.56324555 0.97556992 0.12649111
-0.43675445 0.75648089 -0.12649111
-0.56324555 0.97556992 -0.12649111
-0.68090342 0.64426782 0.303448
-0.86035138 0.81406069 0.24896124
-1.0021297 0.29843537 0.30646131
-1.2064759 0.35928993 0.17030213
-0.94679579 0.89585401 0.062604414
-0.90721782 0.85840551 -0.18444051
-1.2521182 0.37288224 -0.045623048
-1.1216227 0.33402052 -0.25883814
-0.77185234 0.73032329 -0.303448
-0.59240437 0.56053041 -0.24896124
-0.91467902 0.27239247 -0.30646131
-0.71033275 0.21153791 -0.17030213
-0.50595997 0.47873709 -0.062604414
-0.54553794 0.5161856 0.18444051
-0.66469049 0.19794559 0.045623048
-0.79518604 0.23680732 0.25883814
-1 1.2246468e-16 0.17888544
-1.1788854 1.4437183e-16 1.3877788e-17
-0.82111456 1.0055753e-16 -1.3877788e-17
-1 5.6655389e-16 -0.17888544
-1.1216227 -0.33402052 0.25883814
-1.2521182 -0.37288224 0.045623048
-0.90721782 -0.85840551 0.18444051
-0.94679579 -0.89585401 -0.062604414
-1.2064759 -0.35928993 -0.17030213
-1.0021297 -0.29843537 -0.30646131
-0.86035138 -0.81406069 -0.24896124
-0.68090342 -0.64426782 -0.303448
-0.79518604 -0.23680732 -0.25883814
-0.66469049 -0.19794559 -0.045623048
-0.54553794 -0.5161856 -0.18444051
-0.50595997 -0.47873709 0.062604414
-0.71033275 -0.21153791 0.17030213
-0.91467902 -0.27239247 0.30646131
-0.59240437 -0.56053041 0.24896124
-0.77185234 -0.73032329 0.303448
-0.56324555 -0.97556992 0.12649111
-0.56324555 -0.97556992 -0.12649111
-0.43675445 -0.75648089 0.12649111
-0.43675445 -0.75648089 -0.12649111
-0.30243444 -1.2678762 0.062604414
-0.28979207 -1.2148764 -0.18444051
0.30313361 -1.2708073 -0.045623048
0.27154107 -1.138364 -0.25883814
-0.24655235 -1.0336054 -0.303448
-0.18923139 -0.79330244 -0.24896124
0.22144071 -0.9283315 -0.30646131
0.17196917 -0.72093516 -0.17030213
-0.1616185 -0.67754273 -0.062604414
-0.17426087 -0.73054252 0.18444051
0.16091933 -0.67461165 0.045623048
0.19251187 -0.80705498 0.25883814
-0.21750059 -0.91181357 0.303448
-0.27482155 -1.1521165 0.24896124
0.24261222 -1.0170874 0.30646131
0.29208377 -1.2244838 0.17030213
0.58944272 -1.0209447 2.7755576e-17
0.5 -0.8660254 -0.17888544
0.5 -0.8660254 0.17888544
0.41055728 -0.71110607 -2.7755576e-17
0.91439218 -0.86519386 -0.17030213
0.75951745 -0.71865207 -0.30646131
1.1351729 -0.33805581 -0.24896124
0.89840401 -0.26754575 -0.303448
0.60267418 -0.57024766 -0.25883814
0.50377116 -0.47666605 -0.045623048
0.71979881 -0.21435692 -0.18444051
0.66757847 -0.19880564 0.062604414
0.53836358 -0.50939725 0.17030213
0.69323831 -0.65593903 0.30646131
0.78163576 -0.23277203 0.24896124
1.0184047 -0.30328209 0.303448
0.85008158 -0.80434345 0.25883814
0.9489846 -0.89792505 0.045623048
1.1970099 -0.35647092 0.18444051
1.2492302 -0.3720222 -0.062604414
0.81390971 0.24238325 -0.096279082
0.86613006 0.25793453 0.15076584
1.0506786 0.31289331 -0.15076584
1.102899 0.32844459 0.096279082
0.59948901 0.56723386 -0.038527956
0.69839202 0.66081546 0.17468714
0.75436373 0.71377565 -0.17468714
0.85326675 0.80735725 0.038527956
0.19149443 0.80278964 0.038527956
0.24096597 1.010186 0.17468714
0.22308696 0.93523296 -0.17468714
0.27255851 1.1426293 -0.038527956
-0.1970448 0.82605811 0.096279082
-0.25436576 1.066361 0.15076584
-0.20968717 0.8790579 -0.15076584
-0.26700813 1.1193608 -0.096279082
-0.65644288 0.62112337 0.15076584
-0.83589085 0.79091624 0.096279082
-0.61686491 0.58367486 -0.096279082
-0.79631287 0.75346774 -0.15076584
-0.92147899 0.2744175 0.17468714
-1.1258253 0.33527206 0.038527956
-0.79098343 0.23555578 -0.038527956
-0.99532971 0.29641033 -0.17468714
-0.99532971 -0.29641033 0.17468714
-1.1258253 -0.33527206 -0.038527956
-0.79098343 -0.23555578 0.038527956
-0.92147899 -0.2744175 -0.17468714
-0.79631287 -0.75346774 0.15076584
-0.83589085 -0.79091624 -0.096279082
-0.61686491 -0.58367486 0.096279082
-0.65644288 -0.62112337 -0.15076584
-0.26700813 -1.1193608 0.096279082
-0.25436576 -1.066361 -0.15076584
-0.20968717 -0.8790579 0.15076584
-0.1970448 -0.82605811 -0.096279082
0.27255851 -1.1426293 0.038527956
0.24096597 -1.010186 -0.17468714
0.22308696 -0.93523296 0.17468714
0.19149443 -0.80278964 -0.038527956
0.85326675 -0.80735725 -0.038527956
0.69839202 -0.66081546 -0.17468714
0.75436373 -0.71377565 0.17468714
0.59948901 -0.56723386 0.038527956
1.102899 -0.32844459 -0.096279082
0.86613006 -0.25793453 -0.15076584
1.0506786 -0.31289331 0.15076584
0.81390971 -0.24238325 0.096279082
-236
View File
@@ -1,236 +0,0 @@
MFEM mesh v1.0
#
# MFEM Geometry Types (see mesh/geom.hpp):
#
# POINT = 0
# SEGMENT = 1
# TRIANGLE = 2
# SQUARE = 3
# TETRAHEDRON = 4
# CUBE = 5
# PRISM = 6
#
dimension
3
elements
6
1 6 0 1 2 3 4 5
1 6 3 4 5 6 7 8
1 6 6 7 8 9 10 11
1 6 9 10 11 12 13 14
1 6 12 13 14 15 16 17
1 6 15 16 17 0 1 2
boundary
18
1 3 0 1 4 3
1 3 1 2 5 4
1 3 2 0 3 5
1 3 3 4 7 6
1 3 4 5 8 7
1 3 5 3 6 8
1 3 6 7 10 9
1 3 7 8 11 10
1 3 8 6 9 11
1 3 9 10 13 12
1 3 10 11 14 13
1 3 11 9 12 14
1 3 12 13 16 15
1 3 13 14 17 16
1 3 14 12 15 17
1 3 15 16 1 0
1 3 16 17 2 1
1 3 17 15 0 2
vertices
18
nodes
FiniteElementSpace
FiniteElementCollection: H1_3D_P3
VDim: 3
Ordering: 1
0.6 -1.4695762e-16 -9.7971744e-17
1.2 -2.9391523e-16 0.34641016
1.2 -1.3597293e-15 -0.34641016
0.4 0.69282032 0.34641016
0.7 1.2124356 2.7755576e-17
0.4 0.69282032 -0.34641016
-0.6 1.0392305 0.34641016
-0.6 1.0392305 -0.34641016
-0.3 0.51961524 -3.8651415e-16
-1.4 1.7145055e-16 4.8985872e-17
-0.8 9.7971744e-17 -0.34641016
-0.8 4.5324311e-16 0.34641016
-0.6 -1.0392305 -0.34641016
-0.3 -0.51961524 -2.220446e-16
-0.6 -1.0392305 0.34641016
0.4 -0.69282032 -0.34641016
0.4 -0.69282032 0.34641016
0.7 -1.2124356 7.7509221e-16
0.76583592 -8.6777464e-16 0.095745414
1.0341641 2.5022695e-15 0.25066475
1.2 -1.3597293e-15 0.15491933
1.2 -2.9391523e-16 -0.15491933
0.76583592 4.9262324e-16 -0.095745414
1.0341641 3.4207917e-15 -0.25066475
0.48291796 0.83643844 0.25066475
0.61708204 1.0688174 0.095745414
0.61708204 1.0688174 -0.095745414
0.48291796 0.83643844 -0.25066475
0.4 0.69282032 0.15491933
0.4 0.69282032 -0.15491933
0.59098879 0.17599714 0.11416557
0.51532795 0.48760104 0.27491822
1.2368698 0.36834126 0.27491822
1.0048434 0.95077837 0.11416557
1.0473544 0.31190335 -0.38908379
0.65896232 0.62350725 -0.38908379
-0.6 1.0392305 0.15491933
-0.6 1.0392305 -0.15491933
-0.51708204 0.89561236 -0.25066475
-0.38291796 0.66323336 -0.095745414
-0.51708204 0.89561236 0.25066475
-0.38291796 0.66323336 0.095745414
0.21049196 0.88243173 0.38908379
-0.25356098 1.0629872 0.38908379
0.32097654 1.3456091 -0.11416557
-0.29944203 1.2553313 -0.27491822
0.16461091 0.69008761 -0.27491822
-0.1430764 0.59980988 -0.11416557
-1.2341641 6.9922046e-16 -0.095745414
-0.96583592 -1.1684711e-15 -0.25066475
-0.8 4.5324311e-16 -0.15491933
-0.8 9.7971744e-17 0.15491933
-1.2341641 -3.9693744e-16 0.095745414
-0.96583592 -1.5973885e-15 0.25066475
-0.93742781 0.88699007 0.27491822
-1.3258199 0.3948307 0.11416557
-0.79379344 0.75108386 -0.38908379
-0.86945428 0.25892449 -0.38908379
-0.44791239 0.42381273 0.11416557
-0.67993886 0.20248658 0.27491822
-0.51708204 -0.89561236 -0.25066475
-0.38291796 -0.66323336 -0.095745414
-0.38291796 -0.66323336 0.095745414
-0.51708204 -0.89561236 0.25066475
-0.6 -1.0392305 -0.15491933
-0.6 -1.0392305 0.15491933
-1.3258199 -0.3948307 -0.11416557
-0.93742781 -0.88699007 -0.27491822
-0.67993886 -0.20248658 -0.27491822
-0.44791239 -0.42381273 -0.11416557
-0.86945428 -0.25892449 0.38908379
-0.79379344 -0.75108386 0.38908379
0.4 -0.69282032 -0.15491933
0.4 -0.69282032 0.15491933
0.48291796 -0.83643844 0.25066475
0.61708204 -1.0688174 0.095745414
0.48291796 -0.83643844 -0.25066475
0.61708204 -1.0688174 -0.095745414
-0.25356098 -1.0629872 -0.38908379
0.21049196 -0.88243173 -0.38908379
-0.1430764 -0.59980988 0.11416557
0.16461091 -0.69008761 0.27491822
-0.29944203 -1.2553313 0.27491822
0.32097654 -1.3456091 0.11416557
0.59098879 -0.17599714 -0.11416557
0.51532795 -0.48760104 -0.27491822
1.0473544 -0.31190335 0.38908379
0.65896232 -0.62350725 0.38908379
1.2368698 -0.36834126 -0.27491822
1.0048434 -0.95077837 -0.11416557
1 2.4196059e-15 -1.3788671e-16
0.5 0.8660254 -8.6542076e-17
0.76950592 0.22915975 0.15859651
1.0583527 0.31517866 0.23048728
0.65062668 0.6156201 0.23048728
0.86954463 0.8227593 0.15859651
1.1844891 0.35274221 0.091392579
1.0997352 0.32750241 -0.20555815
0.9092442 0.86032286 -0.024929133
0.75456149 0.71396276 -0.24998909
0.92121806 0.2743398 -0.24998909
0.71712515 0.2135607 -0.024929133
0.61926276 0.5859437 -0.20555815
0.55502751 0.52516459 0.091392579
-0.5 0.8660254 5.1344633e-17
0.24102914 1.0104508 0.24998909
0.29043935 1.21759 0.024929133
-0.26624219 1.1161498 0.20555815
-0.28676082 1.2021687 -0.091392579
0.27775814 1.1644274 -0.15859651
0.20782931 0.87126929 -0.23048728
-0.25622363 1.0741497 -0.23048728
-0.1862948 0.78099155 -0.15859651
0.17729212 0.74325022 -0.091392579
0.19781075 0.82926913 0.20555815
-0.17361359 0.72782894 0.024929133
-0.22302379 0.93496814 0.24998909
-1 -1.2098029e-15 1.3788671e-16
-0.89772824 0.84942651 0.091392579
-0.833493 0.78864741 -0.20555815
-1.1996835 0.35726714 -0.024929133
-0.99559063 0.29648804 -0.24998909
-0.69819427 0.66062834 -0.24998909
-0.54351156 0.51426825 -0.024929133
-0.8170735 0.24332543 -0.20555815
-0.73231963 0.21808563 0.091392579
-0.58321113 0.5518318 0.15859651
-0.80212907 0.758971 0.23048728
-0.85845599 0.25564918 0.23048728
-1.1473028 0.34166809 0.15859651
-0.5 -0.8660254 8.6542076e-17
-1.1473028 -0.34166809 -0.15859651
-0.85845599 -0.25564918 -0.23048728
-0.80212907 -0.758971 -0.23048728
-0.58321113 -0.5518318 -0.15859651
-0.73231963 -0.21808563 -0.091392579
-0.8170735 -0.24332543 0.20555815
-0.54351156 -0.51426825 0.024929133
-0.69819427 -0.66062834 0.24998909
-0.99559063 -0.29648804 0.24998909
-1.1996835 -0.35726714 0.024929133
-0.833493 -0.78864741 0.20555815
-0.89772824 -0.84942651 -0.091392579
0.5 -0.8660254 -5.1344633e-17
-0.22302379 -0.93496814 -0.24998909
-0.17361359 -0.72782894 -0.024929133
0.19781075 -0.82926913 -0.20555815
0.17729212 -0.74325022 0.091392579
-0.1862948 -0.78099155 0.15859651
-0.25622363 -1.0741497 0.23048728
0.20782931 -0.87126929 0.23048728
0.27775814 -1.1644274 0.15859651
-0.28676082 -1.2021687 0.091392579
-0.26624219 -1.1161498 -0.20555815
0.29043935 -1.21759 -0.024929133
0.24102914 -1.0104508 -0.24998909
0.55502751 -0.52516459 -0.091392579
0.61926276 -0.5859437 0.20555815
0.71712515 -0.2135607 0.024929133
0.92121806 -0.2743398 0.24998909
0.75456149 -0.71396276 0.24998909
0.9092442 -0.86032286 0.024929133
1.0997352 -0.32750241 0.20555815
1.1844891 -0.35274221 -0.091392579
0.86954463 -0.8227593 -0.15859651
0.65062668 -0.6156201 -0.23048728
1.0583527 -0.31517866 -0.23048728
0.76950592 -0.22915975 -0.15859651
0.95840435 0.28541392 -1.3795119e-16
0.72637788 0.68729555 -1.1412456e-16
0.23202647 0.97270947 -5.1760042e-17
-0.23202647 0.97270947 1.2226691e-17
-0.72637788 0.68729555 8.6191148e-17
-0.95840435 0.28541392 1.2635125e-16
-0.95840435 -0.28541392 1.3795119e-16
-0.72637788 -0.68729555 1.1412456e-16
-0.23202647 -0.97270947 5.1760042e-17
0.23202647 -0.97270947 -1.2226691e-17
0.72637788 -0.68729555 -8.6191148e-17
0.95840435 -0.28541392 -1.2635125e-16
+1 -2
View File
@@ -38,7 +38,7 @@ PROJECT_NAME = "MFEM"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = v3.4.1
PROJECT_NUMBER = v3.3.3
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -767,7 +767,6 @@ INPUT = @MFEM_SOURCE_DIR@/doc/CodeDocumentation.dox \
@MFEM_SOURCE_DIR@/fem \
@MFEM_SOURCE_DIR@/examples \
@MFEM_SOURCE_DIR@/examples/petsc \
@MFEM_SOURCE_DIR@/examples/pumi \
@MFEM_SOURCE_DIR@/examples/sundials \
@MFEM_SOURCE_DIR@/miniapps/common \
@MFEM_SOURCE_DIR@/miniapps/meshing \
+3 -23
View File
@@ -35,13 +35,9 @@ namespace mfem {
* - HypreParMatrix and HypreParVector
* - HypreSolver and other \link hypre.hpp hypre classes\endlink
*
* <H3>Main GPU classes</H3>
* - Device
* - MemoryManager
*
* <H3>Example codes</H3>
* - <a class="el" href="examples_2ex1_8cpp_source.html">Example 1</a>: nodal H1 FEM for the Laplace problem
* - <a class="el" href="examples_2ex1p_8cpp_source.html">Example 1p</a>: parallel nodal H1 FEM for the Laplace problem
* - <a class="el" href="ex1_8cpp_source.html">Example 1</a>: nodal H1 FEM for the Laplace problem
* - <a class="el" href="ex1p_8cpp_source.html">Example 1p</a>: parallel nodal H1 FEM for the Laplace problem
* - <a class="el" href="ex2_8cpp_source.html">Example 2</a>: vector FEM for linear elasticity
* - <a class="el" href="ex2p_8cpp_source.html">Example 2p</a>: parallel vector FEM for linear elasticity
* - <a class="el" href="ex3_8cpp_source.html">Example 3</a>: Nedelec H(curl) FEM for the definite Maxwell problem
@@ -60,7 +56,7 @@ namespace mfem {
* - <a class="el" href="ex9p_8cpp_source.html">Example 9p</a>: parallel Discontinuous Galerkin (DG) time-dependent advection
* - <a class="el" href="ex10_8cpp_source.html">Example 10</a>: time-dependent implicit nonlinear elasticity
* - <a class="el" href="ex10p_8cpp_source.html">Example 10p</a>: parallel time-dependent implicit nonlinear elasticity
* - <a class="el" href="examples_2ex11p_8cpp_source.html">Example 11p</a>: parallel Laplace eigensolver
* - <a class="el" href="ex11p_8cpp_source.html">Example 11p</a>: parallel Laplace eigensolver
* - <a class="el" href="ex12p_8cpp_source.html">Example 12p</a>: parallel linear elasticity eigensolver
* - <a class="el" href="ex13p_8cpp_source.html">Example 13p</a>: parallel Maxwell eigensolver
* - <a class="el" href="ex14_8cpp_source.html">Example 14</a>: Discontinuous Galerkin (DG) for the Laplace problem
@@ -75,10 +71,6 @@ namespace mfem {
* - <a class="el" href="ex18p_8cpp_source.html">Example 18p</a>: parallel Discontinuous Galerkin (DG) for the Euler equations
* - <a class="el" href="ex19_8cpp_source.html">Example 19</a>: incompressible nonlinear elasticity
* - <a class="el" href="ex19p_8cpp_source.html">Example 19p</a>: parallel incompressible nonlinear elasticity
* - <a class="el" href="ex20_8cpp_source.html">Example 20</a>: symplectic ODE integration
* - <a class="el" href="ex20p_8cpp_source.html">Example 20p</a>: parallel symplectic ODE integration
* - <a class="el" href="ex22_8cpp_source.html">Example 22</a>: adaptive mesh refinement for linear elasticity
* - <a class="el" href="ex22p_8cpp_source.html">Example 22p</a>: parallel adaptive mesh refinement for linear elasticity
*
* <H4>SUNDIALS Examples</H4>
* - Variants of Examples
@@ -104,15 +96,6 @@ namespace mfem {
* <a class="el" href="petsc_2ex10p_8cpp_source.html">10p</a>
* demonstrating the use of MFEM's \link petsc.hpp PETSc classes\endlink
*
* <H4>PUMI Examples</H4>
* - Variants of Examples
* <a class="el" href="examples_2pumi_2ex1_8cpp_source.html">1</a>,
* <a class="el" href="examples_2pumi_2ex1p_8cpp_source.html">1p</a>,
* <a class="el" href="pumi_2ex2_8cpp_source.html">2</a>,
* and
* <a class="el" href="pumi_2ex6p_8cpp_source.html">6p</a>
* demonstrating the use of MFEM's \link pumi.hpp PUMI classes\endlink
*
* <H3>Miniapps</H3>
* - <a class="el" href="volta_8cpp_source.html">Volta</a>: simple electrostatics simulation code
* - <a class="el" href="tesla_8cpp_source.html">Tesla</a>: simple magnetostatics simulation code
@@ -120,15 +103,12 @@ namespace mfem {
* - <a class="el" href="joule_8cpp_source.html">Joule</a>: transient magnetics and Joule heating miniapp
* - <a class="el" href="mobius-strip_8cpp_source.html">Mobius Strip</a>: generate various Mobius strip-like meshes
* - <a class="el" href="klein-bottle_8cpp_source.html">Klein Bottle</a>: generate three types of Klein bottle surfaces
* - <a class="el" href="toroid_8cpp_source.html">Toroid</a>: generate simple toroidal meshes
* - <a class="el" href="shaper_8cpp_source.html">Shaper</a>: resolve material interfaces by mesh refinement
* - <a class="el" href="extruder_8cpp_source.html">Extruder</a>: extrude a low-dimensional mesh into a higher dimension
* - <a class="el" href="mesh-explorer_8cpp_source.html">Mesh Explorer</a>: visualize and manipulate meshes
* - <a class="el" href="mesh-optimizer_8cpp_source.html">Mesh Optimizer</a>: optimize high-order meshes, <a class="el" href="mesh-optimizer_8cpp_source.html">serial</a> and <a class="el" href="pmesh-optimizer_8cpp_source.html">parallel</a> versions
* - <a class="el" href="display-basis_8cpp_source.html">Display Basis</a>: visualize finite element basis functions
* - <a class="el" href="load-dc_8cpp_source.html">Load DC</a>: visualize fields saved via DataCollection classes
* - <a class="el" href="convert-dc_8cpp_source.html">Convert DC</a>: convert between diffirent DataCollection formats
* - <a class="el" href="lor-transfer_8cpp_source.html">LOR Transfer</a>: map functions between high-order and low-order refined spaces
* - <a class="el" href="miniapps_2performance_2ex1_8cpp_source.html">HPC Example 1</a>: high-performance nodal H1 FEM for the Laplace problem
* - <a class="el" href="miniapps_2performance_2ex1p_8cpp_source.html">HPC Example 1p</a>: high-performance parallel nodal H1 FEM for the Laplace problem
*
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

+4 -24
View File
@@ -25,10 +25,6 @@ list(APPEND ALL_EXE_SRCS
ex16.cpp
ex17.cpp
ex18.cpp
ex19.cpp
ex20.cpp
ex22.cpp
ex23.cpp
)
if (MFEM_USE_MPI)
@@ -51,10 +47,6 @@ if (MFEM_USE_MPI)
ex16p.cpp
ex17p.cpp
ex18p.cpp
ex19p.cpp
ex20p.cpp
ex22p.cpp
ex23p.cpp
)
endif()
@@ -69,6 +61,8 @@ foreach(SRC_FILE ${ALL_EXE_SRCS})
get_filename_component(SRC_FILENAME ${SRC_FILE} NAME)
string(REPLACE ".cpp" "" TEST_NAME ${SRC_FILENAME})
string(FIND ${TEST_NAME} "p" is_parallel_test)
set(THIS_TEST_OPTIONS "-no-vis")
if (${TEST_NAME} MATCHES "ex10p*")
list(APPEND THIS_TEST_OPTIONS "-tf" "5")
@@ -76,27 +70,18 @@ foreach(SRC_FILE ${ALL_EXE_SRCS})
list(APPEND THIS_TEST_OPTIONS "-e" "1")
endif()
if (NOT (${TEST_NAME} MATCHES ".*p$"))
if (is_parallel_test EQUAL -1)
add_test(NAME ${TEST_NAME}_ser
COMMAND ${TEST_NAME} ${THIS_TEST_OPTIONS})
else()
add_test(NAME ${TEST_NAME}_np=4
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MFEM_MPI_NP}
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 4
${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${TEST_NAME}> ${THIS_TEST_OPTIONS}
${MPIEXEC_POSTFLAGS})
endif()
endforeach()
# If STRUMPACK is enabled, add a test run that uses it.
if (MFEM_USE_STRUMPACK)
add_test(NAME ex11p_strumpack_np=4
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MFEM_MPI_NP}
${MPIEXEC_PREFLAGS}
$<TARGET_FILE:ex11p> "-no-vis" "--strumpack"
${MPIEXEC_POSTFLAGS})
endif()
# Include the examples/sundials directory if SUNDIALS is enabled.
if (MFEM_USE_SUNDIALS)
add_subdirectory(sundials)
@@ -106,8 +91,3 @@ endif()
if (MFEM_USE_PETSC)
add_subdirectory(petsc)
endif()
# Include the examples/pumi directory if PUMI is enabled
if (MFEM_USE_PUMI)
add_subdirectory(pumi)
endif()
+77 -160
View File
File diff suppressed because one or more lines are too long
+49 -55
View File
@@ -4,18 +4,13 @@
//
// Sample runs: ex1 -m ../data/square-disc.mesh
// ex1 -m ../data/star.mesh
// ex1 -m ../data/star-mixed.mesh
// ex1 -m ../data/escher.mesh
// ex1 -m ../data/fichera.mesh
// ex1 -m ../data/fichera-mixed.mesh
// ex1 -m ../data/toroid-wedge.mesh
// ex1 -m ../data/square-disc-p2.vtk -o 2
// ex1 -m ../data/square-disc-p3.mesh -o 3
// ex1 -m ../data/square-disc-nurbs.mesh -o -1
// ex1 -m ../data/star-mixed-p2.mesh -o 2
// ex1 -m ../data/disc-nurbs.mesh -o -1
// ex1 -m ../data/pipe-nurbs.mesh -o -1
// ex1 -m ../data/fichera-mixed-p2.mesh -o 2
// ex1 -m ../data/star-surf.mesh
// ex1 -m ../data/square-disc-surf.mesh
// ex1 -m ../data/inline-segment.mesh
@@ -25,14 +20,6 @@
// ex1 -m ../data/mobius-strip.mesh
// ex1 -m ../data/mobius-strip.mesh -o -1 -sc
//
// Device sample runs:
// ex1 -pa -d cuda
// ex1 -pa -d raja-cuda
// ex1 -pa -d occa-cuda
// ex1 -pa -d raja-omp
// ex1 -pa -d occa-omp
// ex1 -m ../data/beam-hex.mesh -pa -d cuda
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
@@ -61,9 +48,9 @@ int main(int argc, char *argv[])
const char *mesh_file = "../data/star.mesh";
int order = 1;
bool static_cond = false;
bool pa = false;
const char *device = "cpu";
bool visualization = true;
bool use_partial_assembly = false;
bool use_smoother = true;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -71,12 +58,12 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree) or -1 for"
" isoparametric space.");
args.AddOption(&use_partial_assembly, "-pa", "--partial-assembly",
"-no-pa", "--no-partial-assembly", "Enable partial assembly.");
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
"--no-partial-assembly", "Enable Partial Assembly.");
args.AddOption(&device, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&use_smoother, "-pc", "--peconditioner", "-no-pc",
"--no-preconditioner", "Use a Gauss-Seidel preconditioner.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
@@ -148,65 +135,71 @@ int main(int argc, char *argv[])
b->AddDomainIntegrator(new DomainLFIntegrator(one));
b->Assemble();
// 7. Set device config parameters from the command line options and switch
// to working on the device.
Device::Configure(device);
Device::Print();
Device::Enable();
// 8. Define the solution vector x as a finite element grid function
// 7. Define the solution vector x as a finite element grid function
// corresponding to fespace. Initialize x with initial guess of zero,
// which satisfies the boundary conditions.
GridFunction x(fespace);
x = 0.0;
// 9. Set up the bilinear form a(.,.) on the finite element space
// 8. Set up the bilinear form a(.,.) on the finite element space
// corresponding to the Laplacian operator -Delta, by adding the Diffusion
// domain integrator.
Vector B, X;
BilinearForm *a = new BilinearForm(fespace);
if (pa) { a->SetAssemblyLevel(AssemblyLevel::PARTIAL); }
a->AddDomainIntegrator(new DiffusionIntegrator(one));
// 10. Assemble the bilinear form and the corresponding linear system,
// applying any necessary transformations such as: eliminating boundary
// conditions, applying conforming constraints for non-conforming AMR,
// static condensation, etc.
if (static_cond) { a->EnableStaticCondensation(); }
a->Assemble();
BilinearFormOperator A_pa(new PAIntegratorMap);
SparseMatrix A_sp;
if (!use_partial_assembly)
{
a->AssembleForm(A_sp);
}
else
{
// Can add a custom FESpaceIntegrator in this way:
// a->AddIntegrator(new PADiffusionIntegrator(new DiffusionIntegrator(one)));
a->AssembleForm(A_pa);
}
OperatorPtr A;
Vector B, X;
Operator *A;
a->FormLinearSystem(ess_tdof_list, x, *b, A, X, B);
// 9. Assemble the bilinear form and the corresponding linear system,
// applying any necessary transformations such as: eliminating boundary
// conditions, applying conforming constraints for non-conforming AMR,
// static condensation, etc.
cout << "Size of linear system: " << A->Height() << endl;
// 11. Solve the linear system A X = B.
if (!pa)
{
#ifndef MFEM_USE_SUITESPARSE
// Use a simple symmetric Gauss-Seidel preconditioner with PCG.
GSSmoother M((SparseMatrix&)(*A));
// 10. Define a simple symmetric Gauss-Seidel preconditioner and use it to
// solve the system A X = B with PCG.
if (use_smoother && !use_partial_assembly)
{
GSSmoother M(A_sp);
PCG(*A, M, B, X, 1, 200, 1e-12, 0.0);
}
else
{
CG(*A, B, X, 1, 200, 1e-12, 0.0);
}
#else
// If MFEM was compiled with SuiteSparse, use UMFPACK to solve the system.
// 10. If MFEM was compiled with SuiteSparse, use UMFPACK to solve the system.
if (!use_partial_assembly)
{
UMFPackSolver umf_solver;
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
umf_solver.SetOperator(*A);
umf_solver.SetOperator(A_sp);
umf_solver.Mult(B, X);
}
#endif
}
else // No preconditioning for now in partial assembly mode.
{
CG(*A, B, X, 1, 2000, 1e-12, 0.0);
}
// 12. Recover the solution as a finite element grid function.
// 11. Recover the solution as a finite element grid function.
a->RecoverFEMSolution(X, *b, x);
// 13. Switch back to the host.
Device::Disable();
// 14. Save the refined mesh and the solution. This output can be viewed later
// 12. Save the refined mesh and the solution. This output can be viewed later
// using GLVis: "glvis -m refined.mesh -g sol.gf".
ofstream mesh_ofs("refined.mesh");
mesh_ofs.precision(8);
@@ -215,7 +208,7 @@ int main(int argc, char *argv[])
sol_ofs.precision(8);
x.Save(sol_ofs);
// 15. Send the solution by socket to a GLVis server.
// 13. Send the solution by socket to a GLVis server.
if (visualization)
{
char vishost[] = "localhost";
@@ -225,7 +218,8 @@ int main(int argc, char *argv[])
sol_sock << "solution\n" << *mesh << x << flush;
}
// 16. Free the used memory.
// 14. Free the used memory.
delete A;
delete a;
delete b;
delete fespace;
-2
View File
@@ -7,7 +7,6 @@
// ex10 -m ../data/beam-tri.mesh -s 3 -r 2 -o 2 -dt 3
// ex10 -m ../data/beam-hex.mesh -s 2 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-tet.mesh -s 2 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-wedge.mesh -s 2 -r 1 -o 2 -dt 3
// ex10 -m ../data/beam-quad.mesh -s 14 -r 2 -o 2 -dt 0.03 -vs 20
// ex10 -m ../data/beam-hex.mesh -s 14 -r 1 -o 2 -dt 0.05 -vs 20
// ex10 -m ../data/beam-quad-amr.mesh -s 3 -r 2 -o 2 -dt 3
@@ -223,7 +222,6 @@ int main(int argc, char *argv[])
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 13: ode_solver = new RK3SSPSolver; break;
case 14: ode_solver = new RK4Solver; break;
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
-2
View File
@@ -7,7 +7,6 @@
// mpirun -np 4 ex10p -m ../data/beam-tri.mesh -s 3 -rs 2 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 2 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-tet.mesh -s 2 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-wedge.mesh -s 2 -rs 1 -dt 3
// mpirun -np 4 ex10p -m ../data/beam-quad.mesh -s 14 -rs 2 -dt 0.03 -vs 20
// mpirun -np 4 ex10p -m ../data/beam-hex.mesh -s 14 -rs 1 -dt 0.05 -vs 20
// mpirun -np 4 ex10p -m ../data/beam-quad-amr.mesh -s 3 -rs 2 -dt 3
@@ -245,7 +244,6 @@ int main(int argc, char *argv[])
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 13: ode_solver = new RK3SSPSolver; break;
case 14: ode_solver = new RK4Solver; break;
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
+2 -9
View File
@@ -4,11 +4,8 @@
//
// Sample runs: mpirun -np 4 ex11p -m ../data/square-disc.mesh
// mpirun -np 4 ex11p -m ../data/star.mesh
// mpirun -np 4 ex11p -m ../data/star-mixed.mesh
// mpirun -np 4 ex11p -m ../data/escher.mesh
// mpirun -np 4 ex11p -m ../data/fichera.mesh
// mpirun -np 4 ex11p -m ../data/fichera-mixed.mesh
// mpirun -np 4 ex11p -m ../data/toroid-wedge.mesh -o 2
// mpirun -np 4 ex11p -m ../data/square-disc-p2.vtk -o 2
// mpirun -np 4 ex11p -m ../data/square-disc-p3.mesh -o 3
// mpirun -np 4 ex11p -m ../data/square-disc-nurbs.mesh -o -1
@@ -18,11 +15,6 @@
// mpirun -np 4 ex11p -m ../data/star-surf.mesh
// mpirun -np 4 ex11p -m ../data/square-disc-surf.mesh
// mpirun -np 4 ex11p -m ../data/inline-segment.mesh
// mpirun -np 4 ex11p -m ../data/inline-quad.mesh
// mpirun -np 4 ex11p -m ../data/inline-tri.mesh
// mpirun -np 4 ex11p -m ../data/inline-hex.mesh
// mpirun -np 4 ex11p -m ../data/inline-tet.mesh
// mpirun -np 4 ex11p -m ../data/inline-wedge.mesh -s 83
// mpirun -np 4 ex11p -m ../data/amr-quad.mesh
// mpirun -np 4 ex11p -m ../data/amr-hex.mesh
// mpirun -np 4 ex11p -m ../data/mobius-strip.mesh -n 8
@@ -261,7 +253,8 @@ int main(int argc, char *argv[])
strumpack->SetPrintSolveStatistics(false);
strumpack->SetKrylovSolver(strumpack::KrylovSolver::DIRECT);
strumpack->SetReorderingStrategy(strumpack::ReorderingStrategy::METIS);
strumpack->DisableMatching();
strumpack->SetMC64Job(strumpack::MC64Job::NONE);
// strumpack->SetSymmetricPattern(true);
strumpack->SetOperator(*Arow);
strumpack->SetFromCommandLine();
precond = strumpack;
+2 -3
View File
@@ -5,10 +5,9 @@
// Sample runs:
// mpirun -np 4 ex12p -m ../data/beam-tri.mesh
// mpirun -np 4 ex12p -m ../data/beam-quad.mesh
// mpirun -np 4 ex12p -m ../data/beam-tet.mesh -s 79 -n 10 -o 2 -elast
// mpirun -np 4 ex12p -m ../data/beam-tet.mesh -n 10 -o 2 -elast
// mpirun -np 4 ex12p -m ../data/beam-hex.mesh -s 3876
// mpirun -np 4 ex12p -m ../data/beam-wedge.mesh -s 79
// mpirun -np 4 ex12p -m ../data/beam-tri.mesh -s 3876 -o 2 -sys
// mpirun -np 4 ex12p -m ../data/beam-tri.mesh -o 2 -sys
// mpirun -np 4 ex12p -m ../data/beam-quad.mesh -s 4526 -n 6 -o 3 -elast
// mpirun -np 4 ex12p -m ../data/beam-quad-nurbs.mesh
// mpirun -np 4 ex12p -m ../data/beam-hex-nurbs.mesh
-1
View File
@@ -110,7 +110,6 @@ int main(int argc, char *argv[])
{
pmesh->UniformRefinement();
}
pmesh->ReorientTetMesh();
// 6. Define a parallel finite element space on the parallel mesh. Here we
// use the Nedelec finite elements of the specified order.
-2
View File
@@ -4,10 +4,8 @@
//
// Sample runs: ex14 -m ../data/inline-quad.mesh -o 0
// ex14 -m ../data/star.mesh -r 4 -o 2
// ex14 -m ../data/star-mixed.mesh -r 4 -o 2
// ex14 -m ../data/escher.mesh -s 1
// ex14 -m ../data/fichera.mesh -s 1 -k 1
// ex14 -m ../data/fichera-mixed.mesh -s 1 -k 1
// ex14 -m ../data/square-disc-p2.vtk -r 3 -o 2
// ex14 -m ../data/square-disc-p3.mesh -r 2 -o 3
// ex14 -m ../data/square-disc-nurbs.mesh -o 1
-2
View File
@@ -4,10 +4,8 @@
//
// Sample runs: mpirun -np 4 ex14p -m ../data/inline-quad.mesh -o 0
// mpirun -np 4 ex14p -m ../data/star.mesh -o 2
// mpirun -np 4 ex14p -m ../data/star-mixed.mesh -o 2
// mpirun -np 4 ex14p -m ../data/escher.mesh -s 1
// mpirun -np 4 ex14p -m ../data/fichera.mesh -s 1 -k 1
// mpirun -np 4 ex14p -m ../data/fichera-mixed.mesh -s 1 -k 1
// mpirun -np 4 ex14p -m ../data/square-disc-p2.vtk -o 2
// mpirun -np 4 ex14p -m ../data/square-disc-p3.mesh -o 3
// mpirun -np 4 ex14p -m ../data/square-disc-nurbs.mesh -o 1
-2
View File
@@ -135,8 +135,6 @@ int main(int argc, char *argv[])
{
mesh.UniformRefinement();
}
// Make sure tet-only meshes are marked for local refinement.
mesh.Finalize(true);
// 4. All boundary attributes will be used for essential (Dirichlet) BC.
MFEM_VERIFY(mesh.bdr_attributes.Size() > 0,
-2
View File
@@ -151,8 +151,6 @@ int main(int argc, char *argv[])
{
mesh->UniformRefinement();
}
// Make sure tet-only meshes are marked for local refinement.
mesh->Finalize(true);
// 5. Define a parallel mesh by partitioning the serial mesh. Once the
// parallel mesh is defined, the serial mesh can be deleted.
+95 -20
View File
@@ -10,7 +10,6 @@
// ex16 -s 3 -a 0.5 -k 0.5 -o 4
// ex16 -s 14 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// ex16 -m ../data/fichera-q2.mesh
// ex16 -m ../data/fichera-mixed.mesh
// ex16 -m ../data/escher.mesh
// ex16 -m ../data/beam-tet.mesh -tf 10 -dt 0.1
// ex16 -m ../data/amr-quad.mesh -o 4 -r 0
@@ -36,6 +35,10 @@
using namespace std;
using namespace mfem;
bool partial_assembly_mass;
bool partial_assembly_diff;
bool preconditioner;
/** After spatial discretization, the conduction model can be written as:
*
* du/dt = M^{-1}(-Ku)
@@ -55,6 +58,8 @@ protected:
BilinearForm *M;
BilinearForm *K;
Operator *Koper, *Moper, *Toper;
BilinearFormOperator Mpaop, Kpaop;
SparseMatrix Mmat, Kmat;
SparseMatrix *T; // T = M + dt K
double current_dt;
@@ -84,11 +89,39 @@ public:
virtual ~ConductionOperator();
};
class TimeDerivativeOperator : public Operator
{
Operator *Moper;
Operator *Koper;
mutable Vector Kdu;
const double dt;
public:
TimeDerivativeOperator(Operator *_Moper, const double _dt, Operator *_Koper)
: Operator(_Moper->Height(), _Moper->Width()),
Moper(_Moper),
Koper(_Koper),
Kdu(Height()),
dt(_dt) { }
virtual void Mult(const Vector &x, Vector &y) const
{
Moper->Mult(x, y);
Koper->Mult(x, Kdu);
Kdu *= dt;
y += Kdu;
}
};
double InitialTemperature(const Vector &x);
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
partial_assembly_mass = false;
partial_assembly_diff = false;
preconditioner = true;
const char *mesh_file = "../data/star.mesh";
int ref_levels = 2;
int order = 2;
@@ -122,6 +155,12 @@ int main(int argc, char *argv[])
"Alpha coefficient.");
args.AddOption(&kappa, "-k", "--kappa",
"Kappa coefficient offset.");
args.AddOption(&partial_assembly_mass, "-pam", "--partial-assembly-mass",
"-no-pam", "--no-partial-assembly-mass", "Enable partial assembly for the mass.");
args.AddOption(&partial_assembly_diff, "-pad", "--partial-assembly-diff",
"-no-pad", "--no-partial-assembly-diff", "Enable partial assembly for the diffusion.");
args.AddOption(&preconditioner, "-pc", "--peconditioner", "-no-pc",
"--no-preconditioner", "Use a Gauss-Seidel preconditioner.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
@@ -158,7 +197,6 @@ int main(int argc, char *argv[])
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 13: ode_solver = new RK3SSPSolver; break;
case 14: ode_solver = new RK4Solver; break;
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
@@ -293,22 +331,35 @@ int main(int argc, char *argv[])
ConductionOperator::ConductionOperator(FiniteElementSpace &f, double al,
double kap, const Vector &u)
: TimeDependentOperator(f.GetTrueVSize(), 0.0), fespace(f), M(NULL), K(NULL),
Toper(NULL), Mpaop(new PAIntegratorMap), Kpaop(new PAIntegratorMap),
T(NULL), current_dt(0.0), z(height)
{
const double rel_tol = 1e-8;
M = new BilinearForm(&fespace);
M->AddDomainIntegrator(new MassIntegrator());
M->Assemble();
M->FormSystemMatrix(ess_tdof_list, Mmat);
M->AddDomainIntegrator(new MassIntegrator);
if (!partial_assembly_mass)
{
M->AssembleForm(Mmat);
M->FormSystemOperator(ess_tdof_list, Moper);
M_solver.SetOperator(static_cast<SparseMatrix&>(*Moper));
}
else
{
M->AssembleForm(Mpaop);
M->FormSystemOperator(ess_tdof_list, Moper);
M_solver.SetOperator(*Moper);
}
M_solver.iterative_mode = false;
M_solver.SetRelTol(rel_tol);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(30);
M_solver.SetPrintLevel(0);
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(Mmat);
if (preconditioner && !partial_assembly_mass)
{
M_solver.SetPreconditioner(M_prec);
}
alpha = al;
kappa = kap;
@@ -318,7 +369,12 @@ ConductionOperator::ConductionOperator(FiniteElementSpace &f, double al,
T_solver.SetAbsTol(0.0);
T_solver.SetMaxIter(100);
T_solver.SetPrintLevel(0);
T_solver.SetPreconditioner(T_prec);
if (preconditioner &&
!partial_assembly_diff &&
!partial_assembly_mass)
{
T_solver.SetPreconditioner(T_prec);
}
SetParameters(u);
}
@@ -328,7 +384,7 @@ void ConductionOperator::Mult(const Vector &u, Vector &du_dt) const
// Compute:
// du_dt = M^{-1}*-K(u)
// for du_dt
Kmat.Mult(u, z);
Koper->Mult(u, z);
z.Neg(); // z = -z
M_solver.Mult(z, du_dt);
}
@@ -339,14 +395,22 @@ void ConductionOperator::ImplicitSolve(const double dt,
// Solve the equation:
// du_dt = M^{-1}*[-K(u + dt*du_dt)]
// for du_dt
if (!T)
if (!T && !Toper)
{
T = Add(1.0, Mmat, dt, Kmat);
current_dt = dt;
T_solver.SetOperator(*T);
if (!partial_assembly_diff && !partial_assembly_mass)
{
T = Add(1.0, Mmat, dt, Kmat);
T_solver.SetOperator(*T);
}
else
{
Toper = new TimeDerivativeOperator(Moper, dt, Koper);
T_solver.SetOperator(*Toper);
}
}
MFEM_VERIFY(dt == current_dt, ""); // SDIRK methods use the same dt
Kmat.Mult(u, z);
Koper->Mult(u, z);
z.Neg();
T_solver.Mult(z, du_dt);
}
@@ -360,21 +424,32 @@ void ConductionOperator::SetParameters(const Vector &u)
u_alpha_gf(i) = kappa + alpha*u_alpha_gf(i);
}
delete K;
K = new BilinearForm(&fespace);
GridFunctionCoefficient u_coeff(&u_alpha_gf);
delete K;
K = new BilinearForm(&fespace);
K->AddDomainIntegrator(new DiffusionIntegrator(u_coeff));
K->Assemble();
K->FormSystemMatrix(ess_tdof_list, Kmat);
if (!partial_assembly_diff)
{
K->AssembleForm(Kmat);
K->FormSystemOperator(ess_tdof_list, Koper);
}
else
{
K->AssembleForm(Kpaop);
K->FormSystemOperator(ess_tdof_list, Koper);
}
// re-compute on the next ImplicitSolve
delete T;
T = NULL; // re-compute T on the next ImplicitSolve
delete Toper;
Toper = NULL;
T = NULL;
}
ConductionOperator::~ConductionOperator()
{
delete T;
delete Toper;
delete M;
delete K;
}
-2
View File
@@ -10,7 +10,6 @@
// mpirun -np 8 ex16p -s 3 -a 0.5 -k 0.5 -o 4
// mpirun -np 4 ex16p -s 14 -dt 1.0e-4 -tf 4.0e-2 -vs 40
// mpirun -np 16 ex16p -m ../data/fichera-q2.mesh
// mpirun -np 16 ex16p -m ../data/fichera-mixed.mesh
// mpirun -np 16 ex16p -m ../data/escher-p2.mesh
// mpirun -np 8 ex16p -m ../data/beam-tet.mesh -tf 10 -dt 0.1
// mpirun -np 4 ex16p -m ../data/amr-quad.mesh -o 4 -rs 0 -rp 0
@@ -174,7 +173,6 @@ int main(int argc, char *argv[])
case 12: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 13: ode_solver = new RK3SSPSolver; break;
case 14: ode_solver = new RK4Solver; break;
case 15: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
-1
View File
@@ -8,7 +8,6 @@
// ex17 -m ../data/beam-quad.mesh
// ex17 -m ../data/beam-tet.mesh
// ex17 -m ../data/beam-hex.mesh
// ex17 -m ../data/beam-wedge.mesh
// ex17 -m ../data/beam-quad.mesh -r 2 -o 3
// ex17 -m ../data/beam-quad.mesh -r 2 -o 2 -a 1 -k 1
// ex17 -m ../data/beam-hex.mesh -r 2 -o 2
-1
View File
@@ -8,7 +8,6 @@
// mpirun -np 4 ex17p -m ../data/beam-quad.mesh
// mpirun -np 4 ex17p -m ../data/beam-tet.mesh
// mpirun -np 4 ex17p -m ../data/beam-hex.mesh
// mpirun -np 4 ex17p -m ../data/beam-wedge.mesh
// mpirun -np 4 ex17p -m ../data/beam-quad.mesh -rs 2 -rp 2 -o 3 -elast
// mpirun -np 4 ex17p -m ../data/beam-quad.mesh -rs 2 -rp 3 -o 2 -a 1 -k 1
// mpirun -np 4 ex17p -m ../data/beam-hex.mesh -rs 2 -rp 1 -o 2
+2 -1
View File
@@ -509,7 +509,8 @@ bool StateIsPhysical(const Vector &state, const int dim)
// Initial condition
void InitialCondition(const Vector &x, Vector &y)
{
MFEM_ASSERT(x.Size() == 2, "");
const int dim = x.Size();
MFEM_ASSERT(dim == 2, "");
double radius = 0, Minf = 0, beta = 0;
if (problem == 1)
+1 -2
View File
@@ -7,7 +7,6 @@
// ex19 -m ../data/beam-tri.mesh
// ex19 -m ../data/beam-hex.mesh
// ex19 -m ../data/beam-tet.mesh
// ex19 -m ../data/beam-wedge.mesh
//
// Description: This examples solves a quasi-static incompressible nonlinear
// elasticity problem of the form 0 = H(x), where H is an
@@ -51,7 +50,7 @@ using namespace mfem;
//
// and K^-1 is an approximation of the inverse of the displacement part of the
// Jacobian and S^-1 is an approximation of the inverse of the Schur
// complement S = B K^-1 B^T. The Schur complement is approximated using
// complement S = B K^-1 B^T. The Schur complement is approximiated using
// a mass matrix of the pressure variables.
class JacobianPreconditioner : public Solver
{
+1 -2
View File
@@ -7,7 +7,6 @@
// mpirun -np 2 ex19p -m ../data/beam-tri.mesh
// mpirun -np 2 ex19p -m ../data/beam-hex.mesh
// mpirun -np 2 ex19p -m ../data/beam-tet.mesh
// mpirun -np 2 ex19p -m ../data/beam-wedge.mesh
//
// Description: This examples solves a quasi-static incompressible nonlinear
// elasticity problem of the form 0 = H(x), where H is an
@@ -51,7 +50,7 @@ using namespace mfem;
//
// and K^-1 is an approximation of the inverse of the displacement part of the
// Jacobian and S^-1 is an approximation of the inverse of the Schur
// complement S = B K^-1 B^T. The Schur complement is approximated using
// complement S = B K^-1 B^T. The Schur complement is approximiated using
// a mass matrix of the pressure variables.
class JacobianPreconditioner : public Solver
{
+65 -52
View File
@@ -4,19 +4,14 @@
//
// Sample runs: mpirun -np 4 ex1p -m ../data/square-disc.mesh
// mpirun -np 4 ex1p -m ../data/star.mesh
// mpirun -np 4 ex1p -m ../data/star-mixed.mesh
// mpirun -np 4 ex1p -m ../data/escher.mesh
// mpirun -np 4 ex1p -m ../data/fichera.mesh
// mpirun -np 4 ex1p -m ../data/fichera-mixed.mesh
// mpirun -np 4 ex1p -m ../data/toroid-wedge.mesh
// mpirun -np 4 ex1p -m ../data/square-disc-p2.vtk -o 2
// mpirun -np 4 ex1p -m ../data/square-disc-p3.mesh -o 3
// mpirun -np 4 ex1p -m ../data/square-disc-nurbs.mesh -o -1
// mpirun -np 4 ex1p -m ../data/star-mixed-p2.mesh -o 2
// mpirun -np 4 ex1p -m ../data/disc-nurbs.mesh -o -1
// mpirun -np 4 ex1p -m ../data/pipe-nurbs.mesh -o -1
// mpirun -np 4 ex1p -m ../data/ball-nurbs.mesh -o 2
// mpirun -np 4 ex1p -m ../data/fichera-mixed-p2.mesh -o 2
// mpirun -np 4 ex1p -m ../data/star-surf.mesh
// mpirun -np 4 ex1p -m ../data/square-disc-surf.mesh
// mpirun -np 4 ex1p -m ../data/inline-segment.mesh
@@ -25,11 +20,6 @@
// mpirun -np 4 ex1p -m ../data/mobius-strip.mesh
// mpirun -np 4 ex1p -m ../data/mobius-strip.mesh -o -1 -sc
//
// Device sample runs:
// mpirun -np 4 ex1p -pa -d cuda
// mpirun -np 4 ex1p -pa -d occa-cuda
// mpirun -np 4 ex1p -pa -d raja-omp
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
@@ -64,9 +54,9 @@ int main(int argc, char *argv[])
const char *mesh_file = "../data/star.mesh";
int order = 1;
bool static_cond = false;
bool pa = false;
const char *device = "cpu";
bool visualization = true;
bool use_partial_assembly = false;
bool use_amg = true;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
@@ -74,12 +64,12 @@ int main(int argc, char *argv[])
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree) or -1 for"
" isoparametric space.");
args.AddOption(&use_partial_assembly, "-pa", "--partial-assembly",
"-no-pa", "--no-partial-assembly", "Enable partial assembly.");
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
"--no-partial-assembly", "Enable Partial Assembly.");
args.AddOption(&device, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&use_amg, "-pc", "--peconditioner", "-no-pc",
"--no-preconditioner", "Use an algebraic multigrid preconditioner.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
@@ -177,58 +167,78 @@ int main(int argc, char *argv[])
b->AddDomainIntegrator(new DomainLFIntegrator(one));
b->Assemble();
// 9. Set device config parameters from the command line options and switch
// to working on the device.
Device::Configure(device);
if (myid == 0) { Device::Print(); }
Device::Enable();
// 10. Define the solution vector x as a parallel finite element grid function
// corresponding to fespace. Initialize x with initial guess of zero,
// which satisfies the boundary conditions.
// 9. Define the solution vector x as a parallel finite element grid function
// corresponding to fespace. Initialize x with initial guess of zero,
// which satisfies the boundary conditions.
ParGridFunction x(fespace);
x = 0.0;
// 11. Set up the parallel bilinear form a(.,.) on the finite element space
// 10. Set up the parallel bilinear form a(.,.) on the finite element space
// corresponding to the Laplacian operator -Delta, by adding the Diffusion
// domain integrator.
ParBilinearForm *a = new ParBilinearForm(fespace);
if (pa) { a->SetAssemblyLevel(AssemblyLevel::PARTIAL); }
a->AddDomainIntegrator(new DiffusionIntegrator(one));
// 12. Assemble the parallel bilinear form and the corresponding linear
// Use the global map instead
BilinearFormOperator A_pa(new PAIntegratorMap);
HypreParMatrix A_hpm;
Vector B, X;
if (static_cond) { a->EnableStaticCondensation(); }
// 11. Assemble the parallel bilinear form and the corresponding linear
// system, applying any necessary transformations such as: parallel
// assembly, eliminating boundary conditions, applying conforming
// constraints for non-conforming AMR, static condensation, etc.
if (static_cond) { a->EnableStaticCondensation(); }
a->Assemble();
if (!use_partial_assembly)
{
a->AssembleForm(A_hpm);
}
else
{
a->AssembleForm(A_pa);
}
OperatorPtr A;
Vector B, X;
Operator *A;
a->FormLinearSystem(ess_tdof_list, x, *b, A, X, B);
// 13. Solve the linear system A X = B.
// * With full assembly, use the BoomerAMG preconditioner from hypre.
// * With partial assembly, use no preconditioner, for now.
Solver *prec = NULL;
if (!pa) { prec = new HypreBoomerAMG; }
CGSolver cg(MPI_COMM_WORLD);
cg.SetRelTol(1e-12);
cg.SetMaxIter(2000);
cg.SetPrintLevel(1);
if (prec) { cg.SetPreconditioner(*prec); }
cg.SetOperator(*A);
cg.Mult(B, X);
delete prec;
if (myid == 0)
{
cout << "Size of linear system: " << A->Height() << endl;
}
// 14. Recover the parallel grid function corresponding to X. This is the
// 12. Define and apply a parallel PCG solver for AX=B with the BoomerAMG
// preconditioner from hypre.
Solver *pcg = NULL;
HypreSolver *amg = NULL;
if (!use_partial_assembly)
{
HyprePCG *hypre_pcg = new HyprePCG(A_hpm);
pcg = hypre_pcg;
hypre_pcg->SetTol(1e-12);
hypre_pcg->SetMaxIter(200);
hypre_pcg->SetPrintLevel(2);
if (use_amg)
{
amg = new HypreBoomerAMG(A_hpm);
hypre_pcg->SetPreconditioner(*amg);
}
}
else
{
CGSolver *mfem_pcg = new CGSolver(MPI_COMM_WORLD);
pcg = mfem_pcg;
mfem_pcg->SetRelTol(1e-12);
mfem_pcg->SetMaxIter(200);
mfem_pcg->SetPrintLevel(1);
mfem_pcg->SetOperator(*A);
}
pcg->Mult(B, X);
// 13. Recover the parallel grid function corresponding to X. This is the
// local finite element solution on each processor.
a->RecoverFEMSolution(X, *b, x);
// 15. Switch back to the host.
Device::Disable();
// 16. Save the refined mesh and the solution in parallel. This output can
// 14. Save the refined mesh and the solution in parallel. This output can
// be viewed later using GLVis: "glvis -np <np> -m mesh -g sol".
{
ostringstream mesh_name, sol_name;
@@ -244,7 +254,7 @@ int main(int argc, char *argv[])
x.Save(sol_ofs);
}
// 17. Send the solution by socket to a GLVis server.
// 15. Send the solution by socket to a GLVis server.
if (visualization)
{
char vishost[] = "localhost";
@@ -255,7 +265,10 @@ int main(int argc, char *argv[])
sol_sock << "solution\n" << *pmesh << x << flush;
}
// 18. Free the used memory.
// 16. Free the used memory.
delete A;
delete pcg;
delete amg;
delete a;
delete b;
delete fespace;
-1
View File
@@ -6,7 +6,6 @@
// ex2 -m ../data/beam-quad.mesh
// ex2 -m ../data/beam-tet.mesh
// ex2 -m ../data/beam-hex.mesh
// ex2 -m ../data/beam-wedge.mesh
// ex2 -m ../data/beam-quad.mesh -o 3 -sc
// ex2 -m ../data/beam-quad-nurbs.mesh
// ex2 -m ../data/beam-hex-nurbs.mesh
-298
View File
@@ -1,298 +0,0 @@
// MFEM Example 20
//
// Compile with: make ex20
//
// Sample runs: ex20
//
// Description: This example demonstrates the use of the variable order,
// symplectic ODE integration algorithm. Symplectic integration
// algorithms are designed to conserve energy when integrating, in
// time, systems of ODEs which are derived from Hamiltonian
// systems.
//
// Hamiltonian systems define the energy of a system as a function
// of time (t), a set of generalized coordinates (q), and their
// corresponding generalized momenta (p).
//
// H(q,p,t) = T(p) + V(q,t)
//
// Hamilton's equations then specify how q and p evolve in time:
//
// dq/dt = dH/dp
// dp/dt = -dH/dq
//
// To use the symplectic integration classes we need to define an
// mfem::Operator P which evaluates the action of dH/dp, and an
// mfem::TimeDependentOperator F which computes -dH/dq.
//
// This example offers five simple 1D Hamiltonians:
// 0) Simple Harmonic Oscillator (mass on a spring)
// H = ( p^2 / m + q^2 / k ) / 2
// 1) Pendulum
// H = ( p^2 / m - k ( 1 - cos(q) ) ) / 2
// 2) Gaussian Potential Well
// H = ( p^2 / m ) / 2 - k exp(-q^2 / 2)
// 3) Quartic Potential
// H = ( p^2 / m + k ( 1 + q^2 ) q^2 ) / 2
// 4) Negative Quartic Potential
// H = ( p^2 / m + k ( 1 - q^2 /8 ) q^2 ) / 2
//
// In all cases these Hamiltonians are shifted by constant values
// so that the energy will remain positive. The mean and standard
// deviation of the computed energies at each time step are
// displayed upon completion.
//
// We then use GLVis to visualize the results in a non-standard way
// by defining the axes to be q, p, and t rather than x, y, and z.
// In this space we build a ribbon-like mesh with nodes at (0,0,t)
// and (q,p,t). Finally we plot the energy as a function of time
// as a scalar field on this ribbon-like mesh.
//
// For a more traditional plot of the results, including q, p, and
// H, can be obtained by selecting the "-gp" option. This creates
// a data file and input deck for the GnuPlot application (not
// included with MFEM). To visualize these results on most Linux
// systems type the command "gnuplot gnuplot_ex20.inp". The data
// file, named "ex20.dat", should be simple enough to display with
// other plotting programs as well.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
// Constants used in the Hamiltonian
static int prob_ = 0;
static double m_ = 1.0;
static double k_ = 1.0;
// Hamiltonian functional, see below for implementation
double hamiltonian(double q, double p, double t);
class GradT : public Operator
{
public:
GradT() : Operator(1) {}
void Mult(const Vector &x, Vector &y) const { y.Set(1.0/m_, x); }
};
class NegGradV : public TimeDependentOperator
{
public:
NegGradV() : TimeDependentOperator(1) {}
void Mult(const Vector &x, Vector &y) const;
};
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
int order = 1;
int nsteps = 100;
double dt = 0.1;
bool visualization = true;
bool gnuplot = false;
OptionsParser args(argc, argv);
args.AddOption(&order, "-o", "--order",
"Time integration order.");
args.AddOption(&prob_, "-p", "--problem-type",
"Problem Type:\n"
"\t 0 - Simple Harmonic Oscillator\n"
"\t 1 - Pendulum\n"
"\t 2 - Gaussian Potential Well\n"
"\t 3 - Quartic Potential\n"
"\t 4 - Negative Quartic Potential");
args.AddOption(&nsteps, "-n", "--number-of-steps",
"Number of time steps.");
args.AddOption(&dt, "-dt", "--time-step",
"Time step size.");
args.AddOption(&m_, "-m", "--mass",
"Mass.");
args.AddOption(&k_, "-k", "--spring-const",
"Spring constant.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&gnuplot, "-gp", "--gnuplot", "-no-gp", "--no-gnuplot",
"Enable or disable GnuPlot visualization.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
// 2. Create and Initialize the Symplectic Integration Solver
SIAVSolver siaSolver(order);
GradT P;
NegGradV F;
siaSolver.Init(P,F);
// 3. Set the initial conditions
double t = 0.0;
Vector q(1), p(1);
Vector e(nsteps+1);
q(0) = 0.0;
p(0) = 1.0;
// 4. Prepare GnuPlot output file if needed
ofstream ofs;
if (gnuplot)
{
ofs.open("ex20.dat");
ofs << t << "\t" << q(0) << "\t" << p(0) << endl;
}
// 5. Create a Mesh for visualization in phase space
int nverts = (visualization) ? 2*(nsteps+1) : 0;
int nelems = (visualization) ? nsteps : 0;
Mesh mesh(2, nverts, nelems, 0, 3);
int v[4];
Vector x0(3); x0 = 0.0;
Vector x1(3); x1 = 0.0;
// 6. Perform time-stepping
double e_mean = 0.0;
for (int i = 0; i < nsteps; i++)
{
// 6a. Record initial state
if (i == 0)
{
e[0] = hamiltonian(q(0),p(0),t);
e_mean += e[0];
if (visualization)
{
x1[0] = q(0);
x1[1] = p(0);
x1[2] = 0.0;
mesh.AddVertex(x0);
mesh.AddVertex(x1);
}
}
// 6b. Advance the state of the system
siaSolver.Step(q,p,t,dt);
e[i+1] = hamiltonian(q(0),p(0),t);
e_mean += e[i+1];
// 6c. Record the state of the system
if (gnuplot)
{
ofs << t << "\t" << q(0) << "\t" << p(0) << "\t" << e[i+1] << endl;
}
// 6d. Add results to GLVis visualization
if (visualization)
{
x0[2] = t;
x1[0] = q(0);
x1[1] = p(0);
x1[2] = t;
mesh.AddVertex(x0);
mesh.AddVertex(x1);
v[0] = 2*i;
v[1] = 2*(i+1);
v[2] = 2*(i+1)+1;
v[3] = 2*i+1;
mesh.AddQuad(v);
}
}
// 7. Compute and display mean and standard deviation of the energy
e_mean /= (nsteps + 1);
double e_var = 0.0;
for (int i=0; i<=nsteps; i++)
{
e_var += pow(e[i] - e_mean, 2);
}
e_var /= (nsteps + 1);
double e_sd = sqrt(e_var);
cout << endl << "Mean and standard deviation of the energy" << endl;
cout << e_mean << "\t" << e_sd << endl;
// 8. Finalize the GnuPlot output
if (gnuplot)
{
ofs.close();
ofs.open("gnuplot_ex20.inp");
ofs << "plot 'ex20.dat' using 1:2 w l t 'q', "
<< "'ex20.dat' using 1:3 w l t 'p', "
<< "'ex20.dat' using 1:4 w l t 'H'" << endl;
ofs.close();
}
// 9. Finalize the GLVis output
if (visualization)
{
H1_FECollection fec(order = 1, 2);
FiniteElementSpace fespace(&mesh, &fec);
GridFunction energy(&fespace);
energy = 0.0;
for (int i = 0; i <= nsteps; i++)
{
energy[2*i+0] = e[i];
energy[2*i+1] = e[i];
}
char vishost[] = "localhost";
int visport = 19916;
socketstream sock(vishost, visport);
sock.precision(8);
sock << "solution\n" << mesh << energy
<< "window_title 'Energy in Phase Space'\n"
<< "keys\n maac\n" << "axis_labels 'q' 'p' 't'\n"<< flush;
}
}
double hamiltonian(double q, double p, double t)
{
double h = 1.0 - 0.5 / m_ + 0.5 * p * p / m_;
switch (prob_)
{
case 1:
h += k_ * (1.0 - cos(q));
break;
case 2:
h += k_ * (1.0 - exp(-0.5 * q * q));
break;
case 3:
h += 0.5 * k_ * (1.0 + q * q) * q * q;
break;
case 4:
h += 0.5 * k_ * (1.0 - 0.125 * q * q) * q * q;
break;
default:
h += 0.5 * k_ * q * q;
break;
}
return h;
}
void NegGradV::Mult(const Vector &x, Vector &y) const
{
switch (prob_)
{
case 1:
y(0) = - k_* sin(x(0));
break;
case 2:
y(0) = - k_ * x(0) * exp(-0.5 * x(0) * x(0));
break;
case 3:
y(0) = - k_ * (1.0 + 2.0 * x(0) * x(0)) * x(0);
break;
case 4:
y(0) = - k_ * (1.0 - 0.25 * x(0) * x(0)) * x(0);
break;
default:
y(0) = - k_ * x(0);
break;
};
}
-364
View File
@@ -1,364 +0,0 @@
// MFEM Example 20 - Parallel Version
//
// Compile with: make ex20p
//
// Sample runs: mpirun -np 4 ex20p
//
// Description: This example demonstrates the use of the variable order,
// symplectic ODE integration algorithm. Symplectic integration
// algorithms are designed to conserve energy when integrating, in
// time, systems of ODEs which are derived from Hamiltonian
// systems.
//
// Hamiltonian systems define the energy of a system as a function
// of time (t), a set of generalized coordinates (q), and their
// corresponding generalized momenta (p).
//
// H(q,p,t) = T(p) + V(q,t)
//
// Hamilton's equations then specify how q and p evolve in time:
//
// dq/dt = dH/dp
// dp/dt = -dH/dq
//
// To use the symplectic integration classes we need to define an
// mfem::Operator P which evaluates the action of dH/dp, and an
// mfem::TimeDependentOperator F which computes -dH/dq.
//
// This example offers five simple 1D Hamiltonians:
// 0) Simple Harmonic Oscillator (mass on a spring)
// H = ( p^2 / m + q^2 / k ) / 2
// 1) Pendulum
// H = ( p^2 / m - k ( 1 - cos(q) ) ) / 2
// 2) Gaussian Potential Well
// H = ( p^2 / m ) / 2 - k exp(-q^2 / 2)
// 3) Quartic Potential
// H = ( p^2 / m + k ( 1 + q^2 ) q^2 ) / 2
// 4) Negative Quartic Potential
// H = ( p^2 / m + k ( 1 - q^2 /8 ) q^2 ) / 2
//
// In all cases these Hamiltonians are shifted by constant values
// so that the energy will remain positive. The mean and standard
// deviation of the computed energies at each time step are
// displayed upon completion. When run in parallel the same
// Hamiltonian system is evolved on each processor but starting
// from different initial conditions.
//
// We then use GLVis to visualize the results in a non-standard way
// by defining the axes to be q, p, and t rather than x, y, and z.
// In this space we build a ribbon-like mesh on each processor with
// nodes at (0,0,t) and (q,p,t). When these ribbons are bonded
// together on the t-axis they resemble a Rotini pasta. Finally we
// plot the energy as a function of time as a scalar field on this
// Rotini-like mesh.
//
// For a more traditional plot of the results, including q, p, and
// H from each processor, can be obtained by selecting the "-gp"
// option. This creates a collection of data files and an input
// deck for the GnuPlot application (not included with MFEM). To
// visualize these results on most linux systems type the command
// "gnuplot gnuplot_ex20p.inp". The data files, named
// "ex20p_?????.dat", should be simple enough to display with other
// plotting programs as well.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
// Constants used in the Hamiltonian
static int prob_ = 0;
static double m_ = 1.0;
static double k_ = 1.0;
// Hamiltonian functional, see below for implementation
double hamiltonian(double q, double p, double t);
class GradT : public Operator
{
public:
GradT() : Operator(1) {}
void Mult(const Vector &x, Vector &y) const { y.Set(1.0/m_, x); }
};
class NegGradV : public TimeDependentOperator
{
public:
NegGradV() : TimeDependentOperator(1) {}
void Mult(const Vector &x, Vector &y) const;
};
int main(int argc, char *argv[])
{
// 1. Initialize MPI.
int num_procs, myid;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Init(&argc, &argv);
MPI_Comm_size(comm, &num_procs);
MPI_Comm_rank(comm, &myid);
// 2. Parse command-line options.
int order = 1;
int nsteps = 100;
double dt = 0.1;
bool visualization = true;
bool gnuplot = false;
OptionsParser args(argc, argv);
args.AddOption(&order, "-o", "--order",
"Time integration order.");
args.AddOption(&prob_, "-p", "--problem-type",
"Problem Type:\n"
"\t 0 - Simple Harmonic Oscillator\n"
"\t 1 - Pendulum\n"
"\t 2 - Gaussian Potential Well\n"
"\t 3 - Quartic Potential\n"
"\t 4 - Negative Quartic Potential");
args.AddOption(&nsteps, "-n", "--number-of-steps",
"Number of time steps.");
args.AddOption(&dt, "-dt", "--time-step",
"Time step size.");
args.AddOption(&m_, "-m", "--mass",
"Mass.");
args.AddOption(&k_, "-k", "--spring-const",
"Spring constant.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&gnuplot, "-gp", "--gnuplot", "-no-gp", "--no-gnuplot",
"Enable or disable GnuPlot visualization.");
args.Parse();
if (!args.Good())
{
if (myid == 0)
{
args.PrintUsage(cout);
}
MPI_Finalize();
return 1;
}
if (myid == 0)
{
args.PrintOptions(cout);
}
// 3. Create and Initialize the Symplectic Integration Solver
SIAVSolver siaSolver(order);
GradT P;
NegGradV F;
siaSolver.Init(P,F);
// 4. Set the initial conditions
double t = 0.0;
Vector q(1), p(1);
Vector e(nsteps+1);
q(0) = sin(2.0*M_PI*(double)myid/num_procs);
p(0) = cos(2.0*M_PI*(double)myid/num_procs);
// 5. Prepare GnuPlot output file if needed
ostringstream oss;
ofstream ofs;
if (gnuplot)
{
oss << "ex20p_" << setfill('0') << setw(5) << myid << ".dat";
ofs.open(oss.str().c_str());
ofs << t << "\t" << q(0) << "\t" << p(0) << endl;
}
// 6. Create a Mesh for visualization in phase space
int nverts = (visualization) ? (num_procs+1)*(nsteps+1) : 0;
int nelems = (visualization) ? (nsteps * num_procs) : 0;
Mesh mesh(2, nverts, nelems, 0, 3);
int *part = (visualization) ? (new int[nelems]) : NULL;
int v[4];
Vector x0(3); x0 = 0.0;
Vector x1(3); x1 = 0.0;
// 7. Perform time-stepping
double e_mean = 0.0;
for (int i = 0; i < nsteps; i++)
{
// 7a. Record initial state
if (i == 0)
{
e[0] = hamiltonian(q(0),p(0),t);
e_mean += e[0];
if (visualization)
{
mesh.AddVertex(x0);
for (int j = 0; j < num_procs; j++)
{
x1[0] = q(0);
x1[1] = p(0);
x1[2] = 0.0;
mesh.AddVertex(x1);
}
}
}
// 7b. Advance the state of the system
siaSolver.Step(q,p,t,dt);
e[i+1] = hamiltonian(q(0),p(0),t);
e_mean += e[i+1];
// 7c. Record the state of the system
if (gnuplot)
{
ofs << t << "\t" << q(0) << "\t" << p(0) << "\t" << e[i+1] << endl;
}
// 7d. Add results to GLVis visualization
if (visualization)
{
x0[2] = t;
mesh.AddVertex(x0);
for (int j = 0; j < num_procs; j++)
{
x1[0] = q(0);
x1[1] = p(0);
x1[2] = t;
mesh.AddVertex(x1);
v[0] = (num_procs + 1) * i;
v[1] = (num_procs + 1) * (i + 1);
v[2] = (num_procs + 1) * (i + 1) + j + 1;
v[3] = (num_procs + 1) * i + j + 1;
mesh.AddQuad(v);
part[num_procs * i + j] = j;
}
}
}
// 8. Compute and display mean and standard deviation of the energy
e_mean /= (nsteps + 1);
double e_var = 0.0;
for (int i = 0; i <= nsteps; i++)
{
e_var += pow(e[i] - e_mean, 2);
}
e_var /= (nsteps + 1);
double e_sd = sqrt(e_var);
if (myid == 0)
{
cout << endl << "Mean and standard deviation of the energy" << endl;
}
for (int i = 0; i < num_procs; i++)
{
if (myid == i)
{
cout << myid << ": " << e_mean << "\t" << e_sd << endl;
}
MPI_Barrier(comm);
}
// 9. Finalize the GnuPlot output
if (gnuplot)
{
ofs.close();
if (myid == 0)
{
ofs.open("gnuplot_ex20p.inp");
for (int i = 0; i < num_procs; i++)
{
ostringstream ossi;
ossi << "ex20p_" << setfill('0') << setw(5) << i << ".dat";
if (i == 0)
{
ofs << "plot";
}
ofs << " '" << ossi.str() << "' using 1:2 w l t 'q" << i << "',"
<< " '" << ossi.str() << "' using 1:3 w l t 'p" << i << "',"
<< " '" << ossi.str() << "' using 1:4 w l t 'H" << i << "'";
if (i < num_procs-1)
{
ofs << ",";
}
else
{
ofs << ";" << endl;
}
}
ofs.close();
}
}
// 10. Finalize the GLVis output
if (visualization)
{
mesh.FinalizeQuadMesh(1);
ParMesh pmesh(comm, mesh, part);
delete [] part;
H1_FECollection fec(order = 1, 2);
ParFiniteElementSpace fespace(&pmesh, &fec);
ParGridFunction energy(&fespace);
energy = 0.0;
for (int i = 0; i <= nsteps; i++)
{
energy[2*i+0] = e[i];
energy[2*i+1] = e[i];
}
char vishost[] = "localhost";
int visport = 19916;
socketstream sock(vishost, visport);
sock.precision(8);
sock << "parallel " << num_procs << " " << myid << "\n"
<< "solution\n" << pmesh << energy
<< "window_title 'Energy in Phase Space'\n"
<< "keys\n maac\n" << "axis_labels 'q' 'p' 't'\n"<< flush;
}
MPI_Finalize();
}
double hamiltonian(double q, double p, double t)
{
double h = 1.0 - 0.5 / m_ + 0.5 * p * p / m_;
switch (prob_)
{
case 1:
h += k_ * (1.0 - cos(q));
break;
case 2:
h += k_ * (1.0 - exp(-0.5 * q * q));
break;
case 3:
h += 0.5 * k_ * (1.0 + q * q) * q * q;
break;
case 4:
h += 0.5 * k_ * (1.0 - 0.125 * q * q) * q * q;
break;
default:
h += 0.5 * k_ * q * q;
break;
}
return h;
}
void NegGradV::Mult(const Vector &x, Vector &y) const
{
switch (prob_)
{
case 1:
y(0) = - k_* sin(x(0));
break;
case 2:
y(0) = - k_ * x(0) * exp(-0.5 * x(0) * x(0));
break;
case 3:
y(0) = - k_ * (1.0 + 2.0 * x(0) * x(0)) * x(0);
break;
case 4:
y(0) = - k_ * (1.0 - 0.25 * x(0) * x(0)) * x(0);
break;
default:
y(0) = - k_ * x(0);
break;
};
}
-310
View File
@@ -1,310 +0,0 @@
// MFEM Example 22
//
// Compile with: make ex22
//
// Sample runs: ex22
// ex22 -o 3
// ex22 -m ../data/beam-quad.mesh
// ex22 -m ../data/beam-quad.mesh -o 3
// ex22 -m ../data/beam-quad.mesh -o 3 -f 1
// ex22 -m ../data/beam-tet.mesh
// ex22 -m ../data/beam-tet.mesh -o 2
// ex22 -m ../data/beam-hex.mesh
// ex22 -m ../data/beam-hex.mesh -o 2
//
// Description: This is a version of Example 2 with a simple adaptive mesh
// refinement loop. The problem being solved is again the linear
// elasticity describing a multi-material cantilever beam.
// The problem is solved on a sequence of meshes which
// are locally refined in a conforming (triangles, tetrahedrons)
// or non-conforming (quadrilaterals, hexahedra) manner according
// to a simple ZZ error estimator.
//
// The example demonstrates MFEM's capability to work with both
// conforming and nonconforming refinements, in 2D and 3D, on
// linear and curved meshes. Interpolation of functions from
// coarse to fine meshes, as well as persistent GLVis
// visualization are also illustrated.
//
// We recommend viewing Examples 2 and 6 before viewing this
// example.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
const char *mesh_file = "../data/beam-tri.mesh";
int order = 1;
bool static_cond = false;
int flux_averaging = 0;
bool visualization = 1;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&flux_averaging, "-f", "--flux-averaging",
"Flux averaging: 0 - global, 1 - by mesh attribute.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
// 2. Read the mesh from the given mesh file. We can handle triangular,
// quadrilateral, tetrahedral, and hexahedral meshes with the same code.
Mesh mesh(mesh_file, 1, 1);
int dim = mesh.Dimension();
MFEM_VERIFY(mesh.SpaceDimension() == dim, "invalid mesh");
if (mesh.attributes.Max() < 2 || mesh.bdr_attributes.Max() < 2)
{
cerr << "\nInput mesh should have at least two materials and "
<< "two boundary attributes! (See schematic in ex2.cpp)\n"
<< endl;
return 3;
}
// 3. Since a NURBS mesh can currently only be refined uniformly, we need to
// convert it to a piecewise-polynomial curved mesh. First we refine the
// NURBS mesh a bit more and then project the curvature to quadratic Nodes.
if (mesh.NURBSext)
{
for (int i = 0; i < 2; i++)
{
mesh.UniformRefinement();
}
mesh.SetCurvature(2);
}
// 4. Define a finite element space on the mesh. The polynomial order is
// one (linear) by default, but this can be changed on the command line.
H1_FECollection fec(order, dim);
FiniteElementSpace fespace(&mesh, &fec, dim);
// 5. As in Example 2, we set up the linear form b(.) which corresponds to
// the right-hand side of the FEM linear system. In this case, b_i equals
// the boundary integral of f*phi_i where f represents a "pull down"
// force on the Neumann part of the boundary and phi_i are the basis
// functions in the finite element fespace. The force is defined by the
// VectorArrayCoefficient object f, which is a vector of Coefficient
// objects. The fact that f is non-zero on boundary attribute 2 is
// indicated by the use of piece-wise constants coefficient for its last
// component. We don't assemble the discrete problem yet, this will be
// done in the main loop.
VectorArrayCoefficient f(dim);
for (int i = 0; i < dim-1; i++)
{
f.Set(i, new ConstantCoefficient(0.0));
}
{
Vector pull_force(mesh.bdr_attributes.Max());
pull_force = 0.0;
pull_force(1) = -1.0e-2;
f.Set(dim-1, new PWConstCoefficient(pull_force));
}
LinearForm b(&fespace);
b.AddDomainIntegrator(new VectorBoundaryLFIntegrator(f));
// 6. Set up the bilinear form a(.,.) on the finite element space
// corresponding to the linear elasticity integrator with piece-wise
// constants coefficient lambda and mu.
Vector lambda(mesh.attributes.Max());
lambda = 1.0;
lambda(0) = lambda(1)*50;
PWConstCoefficient lambda_func(lambda);
Vector mu(mesh.attributes.Max());
mu = 1.0;
mu(0) = mu(1)*50;
PWConstCoefficient mu_func(mu);
BilinearForm a(&fespace);
BilinearFormIntegrator *integ =
new ElasticityIntegrator(lambda_func,mu_func);
a.AddDomainIntegrator(integ);
if (static_cond) { a.EnableStaticCondensation(); }
// 7. The solution vector x and the associated finite element grid function
// will be maintained over the AMR iterations. We initialize it to zero.
Vector zero_vec(dim);
zero_vec = 0.0;
VectorConstantCoefficient zero_vec_coeff(zero_vec);
GridFunction x(&fespace);
x = 0.0;
// 8. Determine the list of true (i.e. conforming) essential boundary dofs.
// In this example, the boundary conditions are defined by marking only
// boundary attribute 1 from the mesh as essential and converting it to a
// list of true dofs. The conversion to true dofs will be done in the
// main loop.
Array<int> ess_bdr(mesh.bdr_attributes.Max());
ess_bdr = 0;
ess_bdr[0] = 1;
// 9. Connect to GLVis.
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock;
if (visualization)
{
sol_sock.open(vishost, visport);
sol_sock.precision(8);
}
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
// that uses the ComputeElementFlux method of the ElasticityIntegrator to
// recover a smoothed flux (stress) that is subtracted from the element
// flux to get an error indicator. We need to supply the space for the
// smoothed flux: an (H1)^tdim (i.e., vector-valued) space is used here.
// Here, tdim represents the number of components for a symmetric (dim x
// dim) tensor.
const int tdim = dim*(dim+1)/2;
FiniteElementSpace flux_fespace(&mesh, &fec, tdim);
ZienkiewiczZhuEstimator estimator(*integ, x, flux_fespace);
estimator.SetFluxAveraging(flux_averaging);
// 11. A refiner selects and refines elements based on a refinement strategy.
// The strategy here is to refine elements with errors larger than a
// fraction of the maximum element error. Other strategies are possible.
// The refiner will call the given error estimator.
ThresholdRefiner refiner(estimator);
refiner.SetTotalErrorFraction(0.7);
// 12. The main AMR loop. In each iteration we solve the problem on the
// current mesh, visualize the solution, and refine the mesh.
const int max_dofs = 50000;
const int max_amr_itr = 20;
for (int it = 0; it <= max_amr_itr; it++)
{
int cdofs = fespace.GetTrueVSize();
cout << "\nAMR iteration " << it << endl;
cout << "Number of unknowns: " << cdofs << endl;
// 13. Assemble the stiffness matrix and the right-hand side.
a.Assemble();
b.Assemble();
// 14. Set Dirichlet boundary values in the GridFunction x.
// Determine the list of Dirichlet true DOFs in the linear system.
Array<int> ess_tdof_list;
x.ProjectBdrCoefficient(zero_vec_coeff, ess_bdr);
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
// 15. Create the linear system: eliminate boundary conditions, constrain
// hanging nodes and possibly apply other transformations. The system
// will be solved for true (unconstrained) DOFs only.
SparseMatrix A;
Vector B, X;
const int copy_interior = 1;
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
#ifndef MFEM_USE_SUITESPARSE
// 16. Define a simple symmetric Gauss-Seidel preconditioner and use it to
// solve the linear system with PCG.
GSSmoother M(A);
PCG(A, M, B, X, 3, 2000, 1e-12, 0.0);
#else
// 16. If MFEM was compiled with SuiteSparse, use UMFPACK to solve the
// the linear system.
UMFPackSolver umf_solver;
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
umf_solver.SetOperator(A);
umf_solver.Mult(B, X);
#endif
// 17. After solving the linear system, reconstruct the solution as a
// finite element GridFunction. Constrained nodes are interpolated
// from true DOFs (it may therefore happen that x.Size() >= X.Size()).
a.RecoverFEMSolution(X, b, x);
// 18. Send solution by socket to the GLVis server.
if (visualization && sol_sock.good())
{
GridFunction nodes(&fespace), *nodes_p = &nodes;
mesh.GetNodes(nodes);
nodes += x;
int own_nodes = 0;
mesh.SwapNodes(nodes_p, own_nodes);
x.Neg(); // visualize the backward displacement
sol_sock << "solution\n" << mesh << x << flush;
x.Neg();
mesh.SwapNodes(nodes_p, own_nodes);
if (it == 0)
{
sol_sock << "keys '" << ((dim == 2) ? "Rjl" : "") << "m'" << endl;
}
sol_sock << "window_title 'AMR iteration: " << it << "'\n"
<< "pause" << endl;
cout << "Visualization paused. "
"Press <space> in the GLVis window to continue." << endl;
}
if (cdofs > max_dofs)
{
cout << "Reached the maximum number of dofs. Stop." << endl;
break;
}
// 19. Call the refiner to modify the mesh. The refiner calls the error
// estimator to obtain element errors, then it selects elements to be
// refined and finally it modifies the mesh. The Stop() method can be
// used to determine if a stopping criterion was met.
refiner.Apply(mesh);
if (refiner.Stop())
{
cout << "Stopping criterion satisfied. Stop." << endl;
break;
}
// 20. Update the space to reflect the new state of the mesh. Also,
// interpolate the solution x so that it lies in the new space but
// represents the same function. This saves solver iterations later
// since we'll have a good initial guess of x in the next step.
// Internally, FiniteElementSpace::Update() calculates an
// interpolation matrix which is then used by GridFunction::Update().
fespace.Update();
x.Update();
// 21. Inform also the bilinear and linear forms that the space has
// changed.
a.Update();
b.Update();
}
{
ofstream mesh_ref_out("ex22_reference.mesh");
mesh_ref_out.precision(16);
mesh.Print(mesh_ref_out);
ofstream mesh_out("ex22_deformed.mesh");
mesh_out.precision(16);
GridFunction nodes(&fespace), *nodes_p = &nodes;
mesh.GetNodes(nodes);
nodes += x;
int own_nodes = 0;
mesh.SwapNodes(nodes_p, own_nodes);
mesh.Print(mesh_out);
mesh.SwapNodes(nodes_p, own_nodes);
ofstream x_out("ex22_displacement.sol");
x_out.precision(16);
x.Save(x_out);
}
return 0;
}
-366
View File
@@ -1,366 +0,0 @@
// MFEM Example 22
//
// Compile with: make ex22p
//
// Sample runs: mpirun -np 4 ex22p
// mpirun -np 4 ex22p -o 3
// mpirun -np 4 ex22p -m ../data/beam-quad.mesh
// mpirun -np 4 ex22p -m ../data/beam-quad.mesh -o 3
// mpirun -np 4 ex22p -m ../data/beam-tet.mesh
// mpirun -np 4 ex22p -m ../data/beam-tet.mesh -o 2
// mpirun -np 4 ex22p -m ../data/beam-hex.mesh
// mpirun -np 4 ex22p -m ../data/beam-hex.mesh -o 2
//
// Description: This is a version of Example 2p with a simple adaptive mesh
// refinement loop. The problem being solved is again the linear
// elasticity describing a multi-material cantilever beam.
// The problem is solved on a sequence of meshes which
// are locally refined in a conforming (triangles, tetrahedrons)
// or non-conforming (quadrilaterals, hexahedra) manner according
// to a simple ZZ error estimator.
//
// The example demonstrates MFEM's capability to work with both
// conforming and nonconforming refinements, in 2D and 3D, on
// linear and curved meshes. Interpolation of functions from
// coarse to fine meshes, as well as persistent GLVis
// visualization are also illustrated.
//
// We recommend viewing Examples 2p and 6p before viewing this
// example.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
int main(int argc, char *argv[])
{
// 0. Initialize MPI.
int num_procs, myid;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
// 1. Parse command-line options.
const char *mesh_file = "../data/beam-tri.mesh";
int serial_ref_levels = 0;
int order = 1;
bool static_cond = false;
bool visualization = 1;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&serial_ref_levels, "-rs", "--refine-serial",
"Number of uniform serial refinements (before parallel"
" partitioning)");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.Parse();
if (!args.Good())
{
if (myid == 0)
{
args.PrintUsage(cout);
}
MPI_Finalize();
return 1;
}
if (myid == 0)
{
args.PrintOptions(cout);
}
// 2. Read the mesh from the given mesh file. We can handle triangular,
// quadrilateral, tetrahedral, and hexahedral meshes with the same code.
Mesh mesh(mesh_file, 1, 1);
int dim = mesh.Dimension();
MFEM_VERIFY(mesh.SpaceDimension() == dim, "invalid mesh");
if (mesh.attributes.Max() < 2 || mesh.bdr_attributes.Max() < 2)
{
cerr << "\nInput mesh should have at least two materials and "
<< "two boundary attributes! (See schematic in ex2.cpp)\n"
<< endl;
MPI_Finalize();
return 3;
}
// 3. Refine the mesh before parallel partitioning. Since a NURBS mesh can
// currently only be refined uniformly, we need to convert it to a
// piecewise-polynomial curved mesh. First we refine the NURBS mesh a bit
// more and then project the curvature to quadratic Nodes.
if (mesh.NURBSext && serial_ref_levels == 0)
{
serial_ref_levels = 2;
}
for (int i = 0; i < serial_ref_levels; i++)
{
mesh.UniformRefinement();
}
if (mesh.NURBSext)
{
mesh.SetCurvature(2);
}
mesh.EnsureNCMesh();
ParMesh pmesh(MPI_COMM_WORLD, mesh);
mesh.Clear();
// 4. Define a finite element space on the mesh. The polynomial order is
// one (linear) by default, but this can be changed on the command line.
H1_FECollection fec(order, dim);
ParFiniteElementSpace fespace(&pmesh, &fec, dim);
// 5. As in Example 2, we set up the linear form b(.) which corresponds to
// the right-hand side of the FEM linear system. In this case, b_i equals
// the boundary integral of f*phi_i where f represents a "pull down"
// force on the Neumann part of the boundary and phi_i are the basis
// functions in the finite element fespace. The force is defined by the
// VectorArrayCoefficient object f, which is a vector of Coefficient
// objects. The fact that f is non-zero on boundary attribute 2 is
// indicated by the use of piece-wise constants coefficient for its last
// component. We don't assemble the discrete problem yet, this will be
// done in the main loop.
VectorArrayCoefficient f(dim);
for (int i = 0; i < dim-1; i++)
{
f.Set(i, new ConstantCoefficient(0.0));
}
{
Vector pull_force(pmesh.bdr_attributes.Max());
pull_force = 0.0;
pull_force(1) = -1.0e-2;
f.Set(dim-1, new PWConstCoefficient(pull_force));
}
ParLinearForm b(&fespace);
b.AddDomainIntegrator(new VectorBoundaryLFIntegrator(f));
// 6. Set up the bilinear form a(.,.) on the finite element space
// corresponding to the linear elasticity integrator with piece-wise
// constants coefficient lambda and mu.
Vector lambda(pmesh.attributes.Max());
lambda = 1.0;
lambda(0) = lambda(1)*50;
PWConstCoefficient lambda_func(lambda);
Vector mu(pmesh.attributes.Max());
mu = 1.0;
mu(0) = mu(1)*50;
PWConstCoefficient mu_func(mu);
ParBilinearForm a(&fespace);
BilinearFormIntegrator *integ =
new ElasticityIntegrator(lambda_func,mu_func);
a.AddDomainIntegrator(integ);
if (static_cond) { a.EnableStaticCondensation(); }
// 7. The solution vector x and the associated finite element grid function
// will be maintained over the AMR iterations. We initialize it to zero.
Vector zero_vec(dim);
zero_vec = 0.0;
VectorConstantCoefficient zero_vec_coeff(zero_vec);
ParGridFunction x(&fespace);
x = 0.0;
// 8. Determine the list of true (i.e. conforming) essential boundary dofs.
// In this example, the boundary conditions are defined by marking only
// boundary attribute 1 from the mesh as essential and converting it to a
// list of true dofs. The conversion to true dofs will be done in the
// main loop.
Array<int> ess_bdr(pmesh.bdr_attributes.Max());
ess_bdr = 0;
ess_bdr[0] = 1;
// 9. GLVis visualization.
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock;
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
// that uses the ComputeElementFlux method of the ElasticityIntegrator to
// recover a smoothed flux (stress) that is subtracted from the element
// flux to get an error indicator. We need to supply the space for the
// smoothed flux: an (H1)^tdim (i.e., vector-valued) space is used here.
// Here, tdim represents the number of components for a symmetric (dim x
// dim) tensor.
const int tdim = dim*(dim+1)/2;
L2_FECollection flux_fec(order, dim);
ParFiniteElementSpace flux_fespace(&pmesh, &flux_fec, tdim);
ParFiniteElementSpace smooth_flux_fespace(&pmesh, &fec, tdim);
L2ZienkiewiczZhuEstimator estimator(*integ, x, flux_fespace,
smooth_flux_fespace);
// 11. A refiner selects and refines elements based on a refinement strategy.
// The strategy here is to refine elements with errors larger than a
// fraction of the maximum element error. Other strategies are possible.
// The refiner will call the given error estimator.
ThresholdRefiner refiner(estimator);
refiner.SetTotalErrorFraction(0.7);
// 12. The main AMR loop. In each iteration we solve the problem on the
// current mesh, visualize the solution, and refine the mesh.
const int max_dofs = 50000;
const int max_amr_itr = 20;
for (int it = 0; it <= max_amr_itr; it++)
{
HYPRE_Int global_dofs = fespace.GlobalTrueVSize();
if (myid == 0)
{
cout << "\nAMR iteration " << it << endl;
cout << "Number of unknowns: " << global_dofs << endl;
}
// 13. Assemble the stiffness matrix and the right-hand side.
a.Assemble();
b.Assemble();
// 14. Set Dirichlet boundary values in the GridFunction x.
// Determine the list of Dirichlet true DOFs in the linear system.
Array<int> ess_tdof_list;
x.ProjectBdrCoefficient(zero_vec_coeff, ess_bdr);
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
// 15. Create the linear system: eliminate boundary conditions, constrain
// hanging nodes and possibly apply other transformations. The system
// will be solved for true (unconstrained) DOFs only.
HypreParMatrix A;
Vector B, X;
const int copy_interior = 1;
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
// 16. Define and apply a parallel PCG solver for AX=B with the BoomerAMG
// preconditioner from hypre.
HypreBoomerAMG amg;
amg.SetPrintLevel(0);
// amg.SetSystemsOptions(dim); // optional
CGSolver pcg(A.GetComm());
pcg.SetPreconditioner(amg);
pcg.SetOperator(A);
pcg.SetRelTol(1e-6);
pcg.SetMaxIter(500);
pcg.SetPrintLevel(3); // print the first and the last iterations only
pcg.Mult(B, X);
// 17. After solving the linear system, reconstruct the solution as a
// finite element GridFunction. Constrained nodes are interpolated
// from true DOFs (it may therefore happen that x.Size() >= X.Size()).
a.RecoverFEMSolution(X, b, x);
// 18. Send solution by socket to the GLVis server.
if (visualization && it == 0)
{
sol_sock.open(vishost, visport);
sol_sock.precision(8);
}
if (visualization && sol_sock.good())
{
GridFunction nodes(&fespace), *nodes_p = &nodes;
pmesh.GetNodes(nodes);
nodes += x;
int own_nodes = 0;
pmesh.SwapNodes(nodes_p, own_nodes);
x.Neg(); // visualize the backward displacement
sol_sock << "parallel " << num_procs << ' ' << myid << '\n';
sol_sock << "solution\n" << pmesh << x << flush;
x.Neg();
pmesh.SwapNodes(nodes_p, own_nodes);
if (it == 0)
{
sol_sock << "keys '" << ((dim == 2) ? "Rjl" : "") << "m'" << endl;
}
sol_sock << "window_title 'AMR iteration: " << it << "'\n"
<< "pause" << endl;
if (myid == 0)
{
cout << "Visualization paused. "
"Press <space> in the GLVis window to continue." << endl;
}
}
if (global_dofs > max_dofs)
{
if (myid == 0)
{
cout << "Reached the maximum number of dofs. Stop." << endl;
}
break;
}
// 19. Call the refiner to modify the mesh. The refiner calls the error
// estimator to obtain element errors, then it selects elements to be
// refined and finally it modifies the mesh. The Stop() method can be
// used to determine if a stopping criterion was met.
refiner.Apply(pmesh);
if (refiner.Stop())
{
if (myid == 0)
{
cout << "Stopping criterion satisfied. Stop." << endl;
}
break;
}
// 20. Update the space to reflect the new state of the mesh. Also,
// interpolate the solution x so that it lies in the new space but
// represents the same function. This saves solver iterations later
// since we'll have a good initial guess of x in the next step.
// Internally, FiniteElementSpace::Update() calculates an
// interpolation matrix which is then used by GridFunction::Update().
fespace.Update();
x.Update();
// 21. Load balance the mesh, and update the space and solution. Currently
// available only for nonconforming meshes.
if (pmesh.Nonconforming())
{
pmesh.Rebalance();
// Update the space and the GridFunction. This time the update matrix
// redistributes the GridFunction among the processors.
fespace.Update();
x.Update();
}
// 22. Inform also the bilinear and linear forms that the space has
// changed.
a.Update();
b.Update();
}
{
ostringstream mref_name, mesh_name, sol_name;
mref_name << "ex22p_reference_mesh." << setfill('0') << setw(6) << myid;
mesh_name << "ex22p_deformed_mesh." << setfill('0') << setw(6) << myid;
sol_name << "ex22p_displacement." << setfill('0') << setw(6) << myid;
ofstream mesh_ref_out(mref_name.str().c_str());
mesh_ref_out.precision(16);
pmesh.Print(mesh_ref_out);
ofstream mesh_out(mesh_name.str().c_str());
mesh_out.precision(16);
GridFunction nodes(&fespace), *nodes_p = &nodes;
pmesh.GetNodes(nodes);
nodes += x;
int own_nodes = 0;
pmesh.SwapNodes(nodes_p, own_nodes);
pmesh.Print(mesh_out);
pmesh.SwapNodes(nodes_p, own_nodes);
ofstream x_out(sol_name.str().c_str());
x_out.precision(16);
x.Save(x_out);
}
MPI_Finalize();
return 0;
}
-734
View File
@@ -1,734 +0,0 @@
// MFEM Example 23
//
// Compile with: make ex23
//
// Sample runs:
// ex23 -m ../data/periodic-segment.mesh -p 0 -s 2 -dt 0.001 -vs 50
// ex23 -m ../data/periodic-segment.mesh -p 0 -s 12 -dt 0.01
// ex23 -m ../data/periodic-segment.mesh -p 0 -s 22 -dt 0.01
// ex23 -m ../data/periodic-segment.mesh -p 0 -s 32 -dt 0.005 -vs 10
// ex23 -m ../data/periodic-square.mesh -p 0 -dt 0.01
// ex23 -m ../data/periodic-square.mesh -p 0 -s 32 -dt 0.01
// ex23 -m ../data/periodic-hexagon.mesh -p 0 -d 0.001 -s 12 -dt 0.02
// ex23 -m ../data/periodic-hexagon.mesh -p 0 -d 0.001 -s 32 -dt 0.009 -vs 10
// ex23 -m ../data/periodic-square.mesh -p 1 -dt 0.01 -tf 9
// ex23 -m ../data/periodic-hexagon.mesh -p 1 -dt 0.01 -tf 9
// ex23 -m ../data/amr-quad.mesh -p 1 -dt 0.01 -tf 9 -vs 2
// ex23 -m ../data/disc-nurbs.mesh -p 1 -r 3 -dt 0.01 -tf 9
// ex23 -m ../data/disc-nurbs.mesh -p 2 -r 3 -dt 0.01 -tf 9
// ex23 -m ../data/disc-nurbs.mesh -p 3 -r 3 -dt 0.01 -tf 9 -d 0.02
// ex23 -m ../data/periodic-square.mesh -p 3 -r 3 -dt 0.025 -tf 9
// ex23 -m ../data/periodic-cube.mesh -p 0 -o 2 -dt 0.025 -tf 8
//
// Description: This example code solves the time-dependent advection-diffusion
// equation
// du/dt - div(D grad(u)) + v.grad(u) = 0, where
// D is a diffusion coefficient,
// v is a given fluid velocity, and
// u0(x)=u(0,x) is a given initial condition.
//
// The example demonstrates the use of Discontinuous Galerkin (DG)
// bilinear forms in MFEM (face integrators), the use of explicit,
// implicit, and implicit-explicit ODE time integrators, the
// definition of periodic boundary conditions through periodic
// meshes, as well as the use of GLVis for persistent
// visualization of a time-evolving solution. The saving of
// time-dependent data files for external visualization with
// VisIt (visit.llnl.gov) is also illustrated.
//
// This example is a merger of examples 9 and 14.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
// Choice for the problem setup. The fluid velocity, initial condition and
// boundary condition are chosen based on this parameter.
int problem;
// Velocity coefficient
void velocity_function(const Vector &x, Vector &v);
// Initial condition
double u0_function(const Vector &x);
// Mesh bounding box
Vector bb_min, bb_max;
/** A time-dependent operator for the right-hand side of the ODE for use with
explicit ODE solvers. The DG weak form of du/dt = div(D grad(u))-v.grad(u) is
M du/dt = - S u + K u + b, where M, S, and K are the mass,
stiffness, and advection matrices, and b describes sources and the flow on
the boundary.
This can be written as a general ODE,
du/dt = M^{-1} (-S u + K u + b), and this class is used to compute the RHS
and perform the solve for du/dt. */
class EX_Evolution : public TimeDependentOperator
{
private:
SparseMatrix &M, &S, &K;
const Vector &b;
DSmoother M_prec;
CGSolver M_solver;
mutable Vector z;
void initA(double dt);
public:
EX_Evolution(SparseMatrix &_M, SparseMatrix &_S, SparseMatrix &_K,
const Vector &_b);
virtual void Mult(const Vector &x, Vector &y) const;
virtual ~EX_Evolution() {}
};
/** A time-dependent operator for the right-hand side of the ODE for use with
implicit ODE solvers. The DG weak form of du/dt = div(D grad(u))-v.grad(u) is
[M + dt (S - K)] du/dt = - S u + K u + b, where M, S, and K are the mass,
stiffness, and advection matrices, and b describes sources and the flow on
the boundary.
This can be written as a general ODE,
du/dt = A^{-1} (-S u + K u + b) with A = [M + dt (S - K)], and this class is
used to perform the fully implicit solve for du/dt. */
class IM_Evolution : public TimeDependentOperator
{
private:
SparseMatrix &M, &S, &K;
SparseMatrix *A;
const Vector &b;
DSmoother M_prec;
CGSolver M_solver;
DSmoother *A_prec;
GMRESSolver *A_solver;
double dt;
mutable Vector z;
void initA(double dt);
public:
IM_Evolution(SparseMatrix &_M, SparseMatrix &_S, SparseMatrix &_K,
const Vector &_b);
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &y);
virtual ~IM_Evolution() { delete A_solver; delete A_prec; delete A; }
};
/** A time-dependent operator for the right-hand side of the ODE for use with
IMEX (Implicit-Explicit) ODE solvers. The DG weak form of
du/dt = div(D grad(u))-v.grad(u) is
[M + dt S] du/dt = - S u + K u + b, where M, S, and K are the mass,
stiffness, and advection matrices, and b describes sources and the flow on
the boundary.
This can be written as a general ODE,
du/dt = A^{-1} (-S u + K u + b) with A = [M + dt (S - K)], and this class is
used to perform the implicit or explicit solve for du/dt. */
class IMEX_Evolution : public TimeDependentOperator
{
private:
SparseMatrix &M, &S, &K;
SparseMatrix *A;
const Vector &b;
DSmoother M_prec;
CGSolver M_solver;
DSmoother *A_prec;
CGSolver *A_solver;
double dt;
mutable Vector z;
void initA(double dt);
public:
IMEX_Evolution(SparseMatrix &_M, SparseMatrix &_S, SparseMatrix &_K,
const Vector &_b);
virtual void ExplicitMult(const Vector &x, Vector &y) const;
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &y);
virtual ~IMEX_Evolution() { delete A_solver; delete A_prec; delete A; }
};
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
problem = 0;
const char *mesh_file = "../data/periodic-hexagon.mesh";
int ref_levels = 2;
int order = 3;
int ode_solver_type = 12;
double t_final = 10.0;
double d_coef = 0.01;
double dt = 0.01;
double sigma = -1.0;
double kappa = -1.0;
bool visualization = true;
bool visit = false;
bool binary = false;
int vis_steps = 5;
int precision = 8;
cout.precision(precision);
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&problem, "-p", "--problem",
"Problem setup to use. See options in velocity_function().");
args.AddOption(&ref_levels, "-r", "--refine",
"Number of times to refine the mesh uniformly.");
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler, 2 - RK2, 3 - RK3 SSP,"
" 4 - RK4, 5 - Generalized Alpha,\n\t"
"11 - Backward Euler, 12 - SDIRK2, 13 - SDIRK3,\n\t"
"22 - Implicit Midpoint, 23 SDIRK23, 24 - SDIRK34,\n\t"
"31 - IMEX BE/FE, 32 - IMEX RK2.");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
"Time step.");
args.AddOption(&d_coef, "-d", "--diff-coef",
"Diffusion coefficient.");
args.AddOption(&sigma, "-s", "--sigma",
"One of the two DG penalty parameters, typically +1/-1."
" See the documentation of class DGDiffusionIntegrator.");
args.AddOption(&kappa, "-k", "--kappa",
"One of the two DG penalty parameters, should be positive."
" Negative values are replaced with (order+1)^2.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&visit, "-visit", "--visit-datafiles", "-no-visit",
"--no-visit-datafiles",
"Save data files for VisIt (visit.llnl.gov) visualization.");
args.AddOption(&binary, "-binary", "--binary-datafiles", "-ascii",
"--ascii-datafiles",
"Use binary (Sidre) or ascii format for VisIt data files.");
args.AddOption(&vis_steps, "-vs", "--visualization-steps",
"Visualize every n-th timestep.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
if (kappa < 0)
{
kappa = (order+1)*(order+1);
}
args.PrintOptions(cout);
// 2. Define the ODE solver used for time integration. Several explicit
// Runge-Kutta methods are available.
ODESolver *ode_solver = NULL;
switch (ode_solver_type)
{
// Explicit methods
case 1: ode_solver = new ForwardEulerSolver; break;
case 2: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 3: ode_solver = new RK3SSPSolver; break;
case 4: ode_solver = new RK4Solver; break;
case 5: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit L-stable methods
case 11: ode_solver = new BackwardEulerSolver; break;
case 12: ode_solver = new SDIRK23Solver(2); break;
case 13: ode_solver = new SDIRK33Solver; break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
case 24: ode_solver = new SDIRK34Solver; break;
// Implicit-Explicit methods
case 31: ode_solver = new IMEX_BE_FE; break;
case 32: ode_solver = new IMEXRK2; break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
return 3;
}
// 3. Read the serial mesh from the given mesh file on all processors. We can
// handle geometrically periodic meshes in this code.
Mesh mesh(mesh_file, 1, 1);
int dim = mesh.Dimension();
// 4. Refine the mesh in serial to increase the resolution. In this example
// we do 'ser_ref_levels' of uniform refinement, where 'ser_ref_levels' is
// a command-line parameter. If the mesh is of NURBS type, we convert it
// to a (piecewise-polynomial) high-order mesh.
for (int lev = 0; lev < ref_levels; lev++)
{
mesh.UniformRefinement();
}
if (mesh.NURBSext)
{
mesh.SetCurvature(max(order, 1));
}
mesh.GetBoundingBox(bb_min, bb_max, max(order, 1));
// 5. Define the parallel discontinuous DG finite element space on the
// parallel refined mesh of the given polynomial order.
DG_FECollection fec(order, dim);
FiniteElementSpace fes(&mesh, &fec);
cout << "Number of unknowns: " << fes.GetVSize() << endl;
// 6. Set up and assemble the parallel bilinear and linear forms (and the
// parallel hypre matrices) corresponding to the DG discretization. The
// DGTraceIntegrator involves integrals over mesh interior faces.
ConstantCoefficient diff_coef(d_coef);
VectorFunctionCoefficient velocity(dim, velocity_function);
FunctionCoefficient u0(u0_function);
BilinearForm m(&fes);
m.AddDomainIntegrator(new MassIntegrator);
BilinearForm s(&fes);
s.AddDomainIntegrator(new DiffusionIntegrator(diff_coef));
s.AddInteriorFaceIntegrator(new DGDiffusionIntegrator(diff_coef, sigma,
kappa));
s.AddBdrFaceIntegrator(new DGDiffusionIntegrator(diff_coef, sigma, kappa));
BilinearForm k(&fes);
k.AddDomainIntegrator(new ConvectionIntegrator(velocity, -1.0));
k.AddInteriorFaceIntegrator(
new TransposeIntegrator(new DGTraceIntegrator(velocity, 1.0, -0.5)));
k.AddBdrFaceIntegrator(
new TransposeIntegrator(new DGTraceIntegrator(velocity, 1.0, -0.5)));
LinearForm b(&fes);
b.AddBdrFaceIntegrator(
new DGDirichletLFIntegrator(u0, diff_coef, sigma, kappa));
int skip_zeros = 0;
m.Assemble(skip_zeros);
m.Finalize(skip_zeros);
s.Assemble(skip_zeros);
s.Finalize(skip_zeros);
k.Assemble(skip_zeros);
k.Finalize(skip_zeros);
b.Assemble();
// 7. Define the initial conditions, save the corresponding grid function to
// a file and (optionally) save data in the VisIt format and initialize
// GLVis visualization.
GridFunction u(&fes);
u.ProjectCoefficient(u0);
{
ofstream omesh("ex23.mesh");
omesh.precision(precision);
mesh.Print(omesh);
ofstream osol("ex23-init.gf");
osol.precision(precision);
u.Save(osol);
}
// Create data collection for solution output: either VisItDataCollection for
// ascii data files, or SidreDataCollection for binary data files.
DataCollection *dc = NULL;
if (visit)
{
if (binary)
{
#ifdef MFEM_USE_SIDRE
dc = new SidreDataCollection("Example23", &mesh);
#else
MFEM_ABORT("Must build with MFEM_USE_SIDRE=YES for binary output.");
#endif
}
else
{
dc = new VisItDataCollection("Example23", &mesh);
dc->SetPrecision(precision);
}
dc->RegisterField("solution", &u);
dc->SetCycle(0);
dc->SetTime(0.0);
dc->Save();
}
socketstream sout;
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
sout.open(vishost, visport);
if (!sout)
{
cout << "Unable to connect to GLVis server at "
<< vishost << ':' << visport << endl;
visualization = false;
cout << "GLVis visualization disabled.\n";
}
else
{
sout.precision(precision);
sout << "solution\n" << mesh << u;
sout << "pause\n";
sout << flush;
cout << "GLVis visualization paused."
<< " Press space (in the GLVis window) to resume it.\n";
}
}
// 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).
TimeDependentOperator *adv = NULL;
if (ode_solver_type < 10)
{
adv = new EX_Evolution(m.SpMat(), s.SpMat(), k.SpMat(), b);
}
else if (ode_solver_type < 30)
{
adv = new IM_Evolution(m.SpMat(), s.SpMat(), k.SpMat(), b);
}
else
{
adv = new IMEX_Evolution(m.SpMat(), s.SpMat(), k.SpMat(), b);
}
double t = 0.0;
adv->SetTime(t);
ode_solver->Init(*adv);
int n_steps = (int)ceil(t_final / dt);
double dt_real = t_final / n_steps;
for (int ti = 0; ti < n_steps; )
{
ode_solver->Step(u, t, dt_real);
ti++;
if (ti % vis_steps == 0 || ti == n_steps)
{
cout << "time step: " << ti << ", time: " << t << endl;
if (visualization)
{
sout << "solution\n" << mesh << u << flush;
}
if (visit)
{
dc->SetCycle(ti);
dc->SetTime(t);
dc->Save();
}
}
}
// 9. Save the final solution in parallel. This output can be viewed later
// using GLVis: "glvis -np <np> -m ex23-mesh -g ex23-final".
{
ofstream osol("ex23-final.gf");
osol.precision(precision);
u.Save(osol);
}
// 10. Free the used memory.
delete ode_solver;
delete adv;
delete dc;
return 0;
}
// Implementation of class EX_Evolution
EX_Evolution::EX_Evolution(SparseMatrix &_M, SparseMatrix &_S,
SparseMatrix &_K, const Vector &_b)
: TimeDependentOperator(_M.Height()),
M(_M), S(_S), K(_K), b(_b), z(_M.Height())
{
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(M);
M_solver.iterative_mode = false;
M_solver.SetRelTol(1e-9);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(100);
M_solver.SetPrintLevel(0);
}
void EX_Evolution::Mult(const Vector &x, Vector &y) const
{
// y = M^{-1} (-S x + K x + b)
K.Mult(x, z);
S.AddMult(x, z, -1.0);
z += b;
M_solver.Mult(z, y);
}
// Implementation of class IM_Evolution
IM_Evolution::IM_Evolution(SparseMatrix &_M, SparseMatrix &_S,
SparseMatrix &_K, const Vector &_b)
: TimeDependentOperator(_M.Height()),
M(_M), S(_S), K(_K), A(NULL), b(_b),
A_prec(NULL), A_solver(NULL), dt(-1.0), z(_M.Height())
{
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(M);
M_solver.iterative_mode = false;
M_solver.SetRelTol(1e-9);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(100);
M_solver.SetPrintLevel(0);
}
void IM_Evolution::initA(double _dt)
{
if (fabs(dt - _dt) > 1e-4 * _dt)
{
delete A_solver;
delete A_prec;
delete A;
SparseMatrix * SK = Add(1.0, S, -1.0, K);
A = Add(1.0, M, _dt, *SK);
delete SK;
dt = _dt;
A_prec = new DSmoother(*A);
A_solver = new GMRESSolver;
A_solver->SetOperator(*A);
A_solver->SetPreconditioner(*A_prec);
A_solver->iterative_mode = false;
A_solver->SetRelTol(1e-9);
A_solver->SetAbsTol(0.0);
A_solver->SetMaxIter(100);
A_solver->SetPrintLevel(0);
}
}
void IM_Evolution::Mult(const Vector &x, Vector &y) const
{
// y = M^{-1} (-S x + K x + b)
K.Mult(x, z);
S.AddMult(x, z, -1.0);
z += b;
M_solver.Mult(z, y);
}
void IM_Evolution::ImplicitSolve(const double _dt, const Vector &x, Vector &y)
{
this->initA(_dt);
// y = (M + dt S - dt K)^{-1} (-S x + K x + b)
K.Mult(x, z);
S.AddMult(x, z, -1.0);
z += b;
A_solver->Mult(z, y);
}
// Implementation of class IMEX_Evolution
IMEX_Evolution::IMEX_Evolution(SparseMatrix &_M, SparseMatrix &_S,
SparseMatrix &_K, const Vector &_b)
: TimeDependentOperator(_M.Height()),
M(_M), S(_S), K(_K), A(NULL), b(_b),
A_prec(NULL), A_solver(NULL), dt(-1.0), z(_M.Height())
{
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(M);
M_solver.iterative_mode = false;
M_solver.SetRelTol(1e-9);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(100);
M_solver.SetPrintLevel(0);
}
void IMEX_Evolution::initA(double _dt)
{
if (fabs(dt - _dt) > 1e-4 * _dt)
{
delete A_solver;
delete A_prec;
delete A;
A = Add(_dt, S, 1.0, M); // A = M + dt * S
dt = _dt;
A_prec = new DSmoother(*A);
A_solver = new CGSolver;
A_solver->SetOperator(*A);
A_solver->SetPreconditioner(*A_prec);
A_solver->iterative_mode = false;
A_solver->SetRelTol(1e-9);
A_solver->SetAbsTol(0.0);
A_solver->SetMaxIter(100);
A_solver->SetPrintLevel(0);
}
}
void IMEX_Evolution::Mult(const Vector &x, Vector &y) const
{
// y = M^{-1} (-S x + K x + b)
K.Mult(x, z);
S.AddMult(x, z, -1.0);
z += b;
M_solver.Mult(z, y);
}
void IMEX_Evolution::ExplicitMult(const Vector &x, Vector &y) const
{
// y = M^{-1} (K x + b)
K.Mult(x, z);
z += b;
M_solver.Mult(z, y);
}
void IMEX_Evolution::ImplicitSolve(const double _dt, const Vector &x, Vector &y)
{
this->initA(_dt);
// y = (M + dt S)^{-1} (-S x + b)
S.Mult(x, z);
z *= -1.0;
z += b;
A_solver->Mult(z, y);
}
// Velocity coefficient
void velocity_function(const Vector &x, Vector &v)
{
int dim = x.Size();
// map to the reference [-1,1] domain
Vector X(dim);
for (int i = 0; i < dim; i++)
{
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
switch (problem)
{
case 0:
{
// Translations in 1D, 2D, and 3D
switch (dim)
{
case 1: v(0) = 1.0; break;
case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.); break;
case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
break;
}
break;
}
case 1:
case 2:
{
// Clockwise rotation in 2D around the origin
const double w = M_PI/2;
switch (dim)
{
case 1: v(0) = 1.0; break;
case 2: v(0) = w*X(1); v(1) = -w*X(0); break;
case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0; break;
}
break;
}
case 3:
{
// Clockwise twisting rotation in 2D around the origin
const 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)
{
case 1: v(0) = 1.0; break;
case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0); break;
case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0; break;
}
break;
}
}
}
// Initial condition
double u0_function(const Vector &x)
{
int dim = x.Size();
// map to the reference [-1,1] domain
Vector X(dim);
for (int i = 0; i < dim; i++)
{
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
switch (problem)
{
case 0:
case 1:
{
switch (dim)
{
case 1:
return exp(-40.*pow(X(0)-0.5,2));
case 2:
case 3:
{
double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
if (dim == 3)
{
const double s = (1. + 0.25*cos(2*M_PI*X(2)));
rx *= s;
ry *= s;
}
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:
{
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 double f = M_PI;
return sin(f*X(0))*sin(f*X(1));
}
}
return 0.0;
}
// Inflow boundary condition (zero for the problems considered in this example)
double inflow_function(const Vector &x)
{
switch (problem)
{
case 0:
case 1:
case 2:
case 3: return 0.0;
}
return 0.0;
}
-797
View File
@@ -1,797 +0,0 @@
// MFEM Example 23 - Parallel Version
//
// Compile with: make ex23p
//
// Sample runs:
// mpirun -np 4 ex23p -m ../data/periodic-segment.mesh -p 0 -s 2 -dt 0.001 -vs 50
// mpirun -np 4 ex23p -m ../data/periodic-segment.mesh -p 0 -s 12 -dt 0.01
// mpirun -np 4 ex23p -m ../data/periodic-segment.mesh -p 0 -s 22 -dt 0.01
// mpirun -np 4 ex23p -m ../data/periodic-segment.mesh -p 0 -s 32 -dt 0.005 -vs 10
// mpirun -np 4 ex23p -m ../data/periodic-square.mesh -p 0 -dt 0.01
// mpirun -np 4 ex23p -m ../data/periodic-square.mesh -p 0 -s 32 -dt 0.01
// mpirun -np 4 ex23p -m ../data/periodic-hexagon.mesh -p 0 -d 0.001 -s 12 -dt 0.02
// mpirun -np 4 ex23p -m ../data/periodic-hexagon.mesh -p 0 -d 0.001 -s 32 -dt 0.009 -vs 10
// mpirun -np 4 ex23p -m ../data/periodic-square.mesh -p 1 -dt 0.01 -tf 9
// mpirun -np 4 ex23p -m ../data/periodic-hexagon.mesh -p 1 -dt 0.01 -tf 9
// mpirun -np 4 ex23p -m ../data/amr-quad.mesh -p 1 -dt 0.01 -tf 9 -vs 2
// mpirun -np 4 ex23p -m ../data/disc-nurbs.mesh -p 1 -rp 1 -dt 0.01 -tf 9
// mpirun -np 4 ex23p -m ../data/disc-nurbs.mesh -p 2 -rp 1 -dt 0.01 -tf 9
// mpirun -np 4 ex23p -m ../data/disc-nurbs.mesh -p 3 -rp 1 -dt 0.01 -tf 9 -d 0.02
// mpirun -np 4 ex23p -m ../data/periodic-square.mesh -p 3 -rp 1 -dt 0.025 -tf 9
// mpirun -np 4 ex23p -m ../data/periodic-cube.mesh -p 0 -o 2 -dt 0.025 -tf 8
//
// Description: This example code solves the time-dependent advection-diffusion
// equation
// du/dt - div(D grad(u)) + v.grad(u) = 0, where
// D is a diffusion coefficient,
// v is a given fluid velocity, and
// u0(x)=u(0,x) is a given initial condition.
//
// The example demonstrates the use of Discontinuous Galerkin (DG)
// bilinear forms in MFEM (face integrators), the use of explicit,
// implicit, and implicit-explicit ODE time integrators, the
// definition of periodic boundary conditions through periodic
// meshes, as well as the use of GLVis for persistent
// visualization of a time-evolving solution. The saving of
// time-dependent data files for external visualization with
// VisIt (visit.llnl.gov) is also illustrated.
//
// This example is a merger of examples 9 and 14.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
using namespace std;
using namespace mfem;
// Choice for the problem setup. The fluid velocity, initial condition and
// boundary condition are chosen based on this parameter.
int problem;
// Velocity coefficient
void velocity_function(const Vector &x, Vector &v);
// Initial condition
double u0_function(const Vector &x);
// Mesh bounding box
Vector bb_min, bb_max;
/** A time-dependent operator for the right-hand side of the ODE for use with
explicit ODE solvers. The DG weak form of du/dt = div(D grad(u))-v.grad(u) is
M du/dt = - S u + K u + b, where M, S, and K are the mass,
stiffness, and advection matrices, and b describes sources and the flow on
the boundary.
This can be written as a general ODE,
du/dt = M^{-1} (-S u + K u + b), and this class is used to compute the RHS
and perform the solve for du/dt. */
class EX_Evolution : public TimeDependentOperator
{
private:
HypreParMatrix &M, &S, &K;
const Vector &b;
HypreSmoother M_prec;
CGSolver M_solver;
mutable Vector z;
void initA(double dt);
public:
EX_Evolution(HypreParMatrix &_M, HypreParMatrix &_S, HypreParMatrix &_K,
const Vector &_b);
virtual void Mult(const Vector &x, Vector &y) const;
virtual ~EX_Evolution() {}
};
/** A time-dependent operator for the right-hand side of the ODE for use with
implicit ODE solvers. The DG weak form of du/dt = div(D grad(u))-v.grad(u) is
[M + dt (S - K)] du/dt = - S u + K u + b, where M, S, and K are the mass,
stiffness, and advection matrices, and b describes sources and the flow on
the boundary.
This can be written as a general ODE,
du/dt = A^{-1} (-S u + K u + b) with A = [M + dt (S - K)], and this class is
used to perform the fully implicit solve for du/dt. */
class IM_Evolution : public TimeDependentOperator
{
private:
HypreParMatrix &M, &S, &K;
HypreParMatrix *A;
const Vector &b;
HypreSmoother M_prec;
CGSolver M_solver;
HypreBoomerAMG *A_prec;
GMRESSolver *A_solver;
double dt;
mutable Vector z;
void initA(double dt);
public:
IM_Evolution(HypreParMatrix &_M, HypreParMatrix &_S, HypreParMatrix &_K,
const Vector &_b);
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &y);
virtual ~IM_Evolution() { delete A_solver; delete A_prec; delete A; }
};
/** A time-dependent operator for the right-hand side of the ODE for use with
IMEX (Implicit-Explicit) ODE solvers. The DG weak form of
du/dt = div(D grad(u))-v.grad(u) is
[M + dt S] du/dt = - S u + K u + b, where M, S, and K are the mass,
stiffness, and advection matrices, and b describes sources and the flow on
the boundary.
This can be written as a general ODE,
du/dt = A^{-1} (-S u + K u + b) with A = [M + dt (S - K)], and this class is
used to perform the implicit or explicit solve for du/dt. */
class IMEX_Evolution : public TimeDependentOperator
{
private:
HypreParMatrix &M, &S, &K;
HypreParMatrix *A;
const Vector &b;
HypreSmoother M_prec;
CGSolver M_solver;
HypreBoomerAMG *A_prec;
CGSolver *A_solver;
double dt;
mutable Vector z;
void initA(double dt);
public:
IMEX_Evolution(HypreParMatrix &_M, HypreParMatrix &_S, HypreParMatrix &_K,
const Vector &_b);
virtual void ExplicitMult(const Vector &x, Vector &y) const;
virtual void Mult(const Vector &x, Vector &y) const;
virtual void ImplicitSolve(const double dt, const Vector &x, Vector &y);
virtual ~IMEX_Evolution() { delete A_solver; delete A_prec; delete A; }
};
int main(int argc, char *argv[])
{
// 1. Initialize MPI.
int num_procs, myid;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
// 2. Parse command-line options.
problem = 0;
const char *mesh_file = "../data/periodic-hexagon.mesh";
int ser_ref_levels = 2;
int par_ref_levels = 0;
int order = 3;
int ode_solver_type = 12;
double t_final = 10.0;
double d_coef = 0.01;
double dt = 0.01;
double sigma = -1.0;
double kappa = -1.0;
bool visualization = true;
bool visit = false;
bool binary = false;
int vis_steps = 5;
int precision = 8;
cout.precision(precision);
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&problem, "-p", "--problem",
"Problem setup to use. See options in velocity_function().");
args.AddOption(&ser_ref_levels, "-rs", "--refine-serial",
"Number of times to refine the mesh uniformly in serial.");
args.AddOption(&par_ref_levels, "-rp", "--refine-parallel",
"Number of times to refine the mesh uniformly in parallel.");
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler, 2 - RK2, 3 - RK3 SSP,"
" 4 - RK4, 5 - Generalized Alpha,\n\t"
"11 - Backward Euler, 12 - SDIRK2, 13 - SDIRK3,\n\t"
"22 - Implicit Midpoint, 23 SDIRK23, 24 - SDIRK34,\n\t"
"31 - IMEX BE/FE, 32 - IMEX RK2.");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
"Time step.");
args.AddOption(&d_coef, "-d", "--diff-coef",
"Diffusion coefficient.");
args.AddOption(&sigma, "-s", "--sigma",
"One of the two DG penalty parameters, typically +1/-1."
" See the documentation of class DGDiffusionIntegrator.");
args.AddOption(&kappa, "-k", "--kappa",
"One of the two DG penalty parameters, should be positive."
" Negative values are replaced with (order+1)^2.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&visit, "-visit", "--visit-datafiles", "-no-visit",
"--no-visit-datafiles",
"Save data files for VisIt (visit.llnl.gov) visualization.");
args.AddOption(&binary, "-binary", "--binary-datafiles", "-ascii",
"--ascii-datafiles",
"Use binary (Sidre) or ascii format for VisIt data files.");
args.AddOption(&vis_steps, "-vs", "--visualization-steps",
"Visualize every n-th timestep.");
args.Parse();
if (!args.Good())
{
if (myid == 0)
{
args.PrintUsage(cout);
}
MPI_Finalize();
return 1;
}
if (kappa < 0)
{
kappa = (order+1)*(order+1);
}
if (myid == 0)
{
args.PrintOptions(cout);
}
// 3. Define the ODE solver used for time integration. Several explicit,
// implicitit, and implicit-explicit Runge-Kutta methods are available.
ODESolver *ode_solver = NULL;
switch (ode_solver_type)
{
// Explicit methods
case 1: ode_solver = new ForwardEulerSolver; break;
case 2: ode_solver = new RK2Solver(0.5); break; // midpoint method
case 3: ode_solver = new RK3SSPSolver; break;
case 4: ode_solver = new RK4Solver; break;
case 5: ode_solver = new GeneralizedAlphaSolver(0.5); break;
// Implicit L-stable methods
case 11: ode_solver = new BackwardEulerSolver; break;
case 12: ode_solver = new SDIRK23Solver(2); break;
case 13: ode_solver = new SDIRK33Solver; break;
// Implicit A-stable methods (not L-stable)
case 22: ode_solver = new ImplicitMidpointSolver; break;
case 23: ode_solver = new SDIRK23Solver; break;
case 24: ode_solver = new SDIRK34Solver; break;
// Implicit-Explicit methods
case 31: ode_solver = new IMEX_BE_FE; break;
case 32: ode_solver = new IMEXRK2; break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
return 3;
}
// 4. Read the serial mesh from the given mesh file on all processors. We can
// handle geometrically periodic meshes in this code.
Mesh *mesh = new Mesh(mesh_file, 1, 1);
int dim = mesh->Dimension();
// 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. If the mesh is of NURBS type, we convert it
// to a (piecewise-polynomial) high-order mesh.
for (int lev = 0; lev < ser_ref_levels; lev++)
{
mesh->UniformRefinement();
}
if (mesh->NURBSext)
{
mesh->SetCurvature(max(order, 1));
}
mesh->GetBoundingBox(bb_min, bb_max, max(order, 1));
// 6. Define the parallel mesh by a partitioning of the serial mesh. Refine
// this mesh further in parallel to increase the resolution. Once the
// parallel mesh is defined, the serial mesh can be deleted.
ParMesh *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
delete mesh;
for (int lev = 0; lev < par_ref_levels; lev++)
{
pmesh->UniformRefinement();
}
// 7. Define the parallel discontinuous DG finite element space on the
// parallel refined mesh of the given polynomial order.
DG_FECollection fec(order, dim);
ParFiniteElementSpace *fes = new ParFiniteElementSpace(pmesh, &fec);
HYPRE_Int global_vSize = fes->GlobalTrueVSize();
if (myid == 0)
{
cout << "Number of unknowns: " << global_vSize << endl;
}
// 8. Set up and assemble the parallel bilinear and linear forms (and the
// parallel hypre matrices) corresponding to the DG discretization. The
// DGTraceIntegrator involves integrals over mesh interior faces.
ConstantCoefficient diff_coef(d_coef);
VectorFunctionCoefficient velocity(dim, velocity_function);
FunctionCoefficient u0(u0_function);
ParBilinearForm *m = new ParBilinearForm(fes);
m->AddDomainIntegrator(new MassIntegrator);
ParBilinearForm *s = new ParBilinearForm(fes);
s->AddDomainIntegrator(new DiffusionIntegrator(diff_coef));
s->AddInteriorFaceIntegrator(new DGDiffusionIntegrator(diff_coef, sigma,
kappa));
s->AddBdrFaceIntegrator(new DGDiffusionIntegrator(diff_coef, sigma, kappa));
ParBilinearForm *k = new ParBilinearForm(fes);
k->AddDomainIntegrator(new ConvectionIntegrator(velocity, -1.0));
k->AddInteriorFaceIntegrator(
new TransposeIntegrator(new DGTraceIntegrator(velocity, 1.0, -0.5)));
k->AddBdrFaceIntegrator(
new TransposeIntegrator(new DGTraceIntegrator(velocity, 1.0, -0.5)));
ParLinearForm *b = new ParLinearForm(fes);
b->AddBdrFaceIntegrator(
new DGDirichletLFIntegrator(u0, diff_coef, sigma, kappa));
int skip_zeros = 0;
m->Assemble(skip_zeros);
m->Finalize(skip_zeros);
s->Assemble(skip_zeros);
s->Finalize(skip_zeros);
k->Assemble(skip_zeros);
k->Finalize(skip_zeros);
b->Assemble();
HypreParMatrix *M = m->ParallelAssemble();
HypreParMatrix *S = s->ParallelAssemble();
HypreParMatrix *K = k->ParallelAssemble();
HypreParVector *B = b->ParallelAssemble();
// 9. Define the initial conditions, save the corresponding grid function to
// a file and (optionally) save data in the VisIt format and initialize
// GLVis visualization.
ParGridFunction *u = new ParGridFunction(fes);
u->ProjectCoefficient(u0);
HypreParVector *U = u->GetTrueDofs();
{
ostringstream mesh_name, sol_name;
mesh_name << "ex23-mesh." << setfill('0') << setw(6) << myid;
sol_name << "ex23-init." << setfill('0') << setw(6) << myid;
ofstream omesh(mesh_name.str().c_str());
omesh.precision(precision);
pmesh->Print(omesh);
ofstream osol(sol_name.str().c_str());
osol.precision(precision);
u->Save(osol);
}
// Create data collection for solution output: either VisItDataCollection for
// ascii data files, or SidreDataCollection for binary data files.
DataCollection *dc = NULL;
if (visit)
{
if (binary)
{
#ifdef MFEM_USE_SIDRE
dc = new SidreDataCollection("Example23-Parallel", pmesh);
#else
MFEM_ABORT("Must build with MFEM_USE_SIDRE=YES for binary output.");
#endif
}
else
{
dc = new VisItDataCollection("Example23-Parallel", pmesh);
dc->SetPrecision(precision);
// To save the mesh using MFEM's parallel mesh format:
// dc->SetFormat(DataCollection::PARALLEL_FORMAT);
}
dc->RegisterField("solution", u);
dc->SetCycle(0);
dc->SetTime(0.0);
dc->Save();
}
socketstream sout;
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
sout.open(vishost, visport);
if (!sout)
{
if (myid == 0)
cout << "Unable to connect to GLVis server at "
<< vishost << ':' << visport << endl;
visualization = false;
if (myid == 0)
{
cout << "GLVis visualization disabled.\n";
}
}
else
{
sout << "parallel " << num_procs << " " << myid << "\n";
sout.precision(precision);
sout << "solution\n" << *pmesh << *u;
sout << "pause\n";
sout << flush;
if (myid == 0)
cout << "GLVis visualization paused."
<< " Press space (in the GLVis window) to resume it.\n";
}
}
// 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).
TimeDependentOperator *adv = NULL;
if (ode_solver_type < 10)
{
adv = new EX_Evolution(*M, *S, *K, *B);
}
else if (ode_solver_type < 30)
{
adv = new IM_Evolution(*M, *S, *K, *B);
}
else
{
adv = new IMEX_Evolution(*M, *S, *K, *B);
}
double t = 0.0;
adv->SetTime(t);
ode_solver->Init(*adv);
int n_steps = (int)ceil(t_final / dt);
double dt_real = t_final / n_steps;
for (int ti = 0; ti < n_steps; )
{
ode_solver->Step(*U, t, dt_real);
ti++;
if (ti % vis_steps == 0 || ti == n_steps)
{
if (myid == 0)
{
cout << "time step: " << ti << ", time: " << t << endl;
}
// 11. Extract the parallel grid function corresponding to the finite
// element approximation U (the local solution on each processor).
*u = *U;
if (visualization)
{
sout << "parallel " << num_procs << " " << myid << "\n";
sout << "solution\n" << *pmesh << *u << flush;
}
if (visit)
{
dc->SetCycle(ti);
dc->SetTime(t);
dc->Save();
}
}
}
// 12. Save the final solution in parallel. This output can be viewed later
// using GLVis: "glvis -np <np> -m ex23-mesh -g ex23-final".
{
*u = *U;
ostringstream sol_name;
sol_name << "ex23-final." << setfill('0') << setw(6) << myid;
ofstream osol(sol_name.str().c_str());
osol.precision(precision);
u->Save(osol);
}
// 13. Free the used memory.
delete U;
delete u;
delete B;
delete b;
delete K;
delete k;
delete S;
delete s;
delete M;
delete m;
delete fes;
delete pmesh;
delete ode_solver;
delete adv;
delete dc;
MPI_Finalize();
return 0;
}
// Implementation of class EX_Evolution
EX_Evolution::EX_Evolution(HypreParMatrix &_M, HypreParMatrix &_S,
HypreParMatrix &_K, const Vector &_b)
: TimeDependentOperator(_M.Height()),
M(_M), S(_S), K(_K), b(_b),
M_prec(M), M_solver(M.GetComm()), z(M.Height())
{
M_prec.SetType(HypreSmoother::Jacobi);
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(M);
M_solver.iterative_mode = false;
M_solver.SetRelTol(1e-9);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(100);
M_solver.SetPrintLevel(0);
}
void EX_Evolution::Mult(const Vector &x, Vector &y) const
{
// y = M^{-1} (-S x + K x + b)
S.Mult(-1.0, x, 0.0, z);
K.Mult(1.0, x, 1.0, z);
z += b;
M_solver.Mult(z, y);
}
// Implementation of class IM_Evolution
IM_Evolution::IM_Evolution(HypreParMatrix &_M, HypreParMatrix &_S,
HypreParMatrix &_K, const Vector &_b)
: TimeDependentOperator(_M.Height()),
M(_M), S(_S), K(_K), A(NULL), b(_b),
M_prec(M), M_solver(M.GetComm()),
A_prec(NULL), A_solver(NULL), dt(-1.0), z(M.Height())
{
M_prec.SetType(HypreSmoother::Jacobi);
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(M);
M_solver.iterative_mode = false;
M_solver.SetRelTol(1e-9);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(100);
M_solver.SetPrintLevel(0);
}
void IM_Evolution::initA(double _dt)
{
if (fabs(dt - _dt) > 1e-4 * _dt)
{
delete A_solver;
delete A_prec;
delete A;
HypreParMatrix * SK = Add(1.0, S, -1.0, K); // SK = S - K
A = Add(_dt, *SK, 1.0, M); // A = M + dt * (S - K)
delete SK;
dt = _dt;
A_prec = new HypreBoomerAMG(*A);
A_solver = new GMRESSolver(A->GetComm());
A_solver->SetOperator(*A);
A_solver->SetPreconditioner(*A_prec);
A_solver->iterative_mode = false;
A_solver->SetRelTol(1e-9);
A_solver->SetAbsTol(0.0);
A_solver->SetMaxIter(100);
A_solver->SetPrintLevel(0);
}
}
void IM_Evolution::Mult(const Vector &x, Vector &y) const
{
// y = M^{-1} (-S x + K x + b)
S.Mult(-1.0, x, 0.0, z);
K.Mult(1.0, x, 1.0, z);
z += b;
M_solver.Mult(z, y);
}
void IM_Evolution::ImplicitSolve(const double _dt, const Vector &x, Vector &y)
{
this->initA(_dt);
// y = (M + dt S - dt K)^{-1} (-S x + K x + b)
S.Mult(-1.0, x, 0.0, z);
K.Mult(1.0, x, 1.0, z);
z += b;
A_solver->Mult(z, y);
}
// Implementation of class IMEX_Evolution
IMEX_Evolution::IMEX_Evolution(HypreParMatrix &_M, HypreParMatrix &_S,
HypreParMatrix &_K, const Vector &_b)
: TimeDependentOperator(_M.Height()),
M(_M), S(_S), K(_K), A(NULL), b(_b),
M_prec(M), M_solver(M.GetComm()),
A_prec(NULL), A_solver(NULL), dt(-1.0), z(M.Height())
{
M_prec.SetType(HypreSmoother::Jacobi);
M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(M);
M_solver.iterative_mode = false;
M_solver.SetRelTol(1e-9);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(100);
M_solver.SetPrintLevel(0);
}
void IMEX_Evolution::initA(double _dt)
{
if (fabs(dt - _dt) > 1e-4 * _dt)
{
delete A_solver;
delete A_prec;
delete A;
A = Add(_dt, S, 1.0, M); // A = M + dt * S
dt = _dt;
A_prec = new HypreBoomerAMG(*A);
A_solver = new CGSolver(A->GetComm());
A_solver->SetOperator(*A);
A_solver->SetPreconditioner(*A_prec);
A_solver->iterative_mode = false;
A_solver->SetRelTol(1e-9);
A_solver->SetAbsTol(0.0);
A_solver->SetMaxIter(100);
A_solver->SetPrintLevel(0);
}
}
void IMEX_Evolution::Mult(const Vector &x, Vector &y) const
{
// y = M^{-1} (-S x + K x + b)
S.Mult(-1.0, x, 0.0, z);
K.Mult(1.0, x, 1.0, z);
z += b;
M_solver.Mult(z, y);
}
void IMEX_Evolution::ExplicitMult(const Vector &x, Vector &y) const
{
// y = M^{-1} (K x + b)
K.Mult(1.0, x, 0.0, z);
z += b;
M_solver.Mult(z, y);
}
void IMEX_Evolution::ImplicitSolve(const double _dt, const Vector &x, Vector &y)
{
this->initA(_dt);
// y = (M + dt S)^{-1} (-S x + b)
S.Mult(-1.0, x, 0.0, z);
z += b;
A_solver->Mult(z, y);
}
// Velocity coefficient
void velocity_function(const Vector &x, Vector &v)
{
int dim = x.Size();
// map to the reference [-1,1] domain
Vector X(dim);
for (int i = 0; i < dim; i++)
{
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
switch (problem)
{
case 0:
{
// Translations in 1D, 2D, and 3D
switch (dim)
{
case 1: v(0) = 1.0; break;
case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.); break;
case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
break;
}
break;
}
case 1:
case 2:
{
// Clockwise rotation in 2D around the origin
const double w = M_PI/2;
switch (dim)
{
case 1: v(0) = 1.0; break;
case 2: v(0) = w*X(1); v(1) = -w*X(0); break;
case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0; break;
}
break;
}
case 3:
{
// Clockwise twisting rotation in 2D around the origin
const 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)
{
case 1: v(0) = 1.0; break;
case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0); break;
case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0; break;
}
break;
}
}
}
// Initial condition
double u0_function(const Vector &x)
{
int dim = x.Size();
// map to the reference [-1,1] domain
Vector X(dim);
for (int i = 0; i < dim; i++)
{
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
switch (problem)
{
case 0:
case 1:
{
switch (dim)
{
case 1:
return exp(-40.*pow(X(0)-0.5,2));
case 2:
case 3:
{
double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
if (dim == 3)
{
const double s = (1. + 0.25*cos(2*M_PI*X(2)));
rx *= s;
ry *= s;
}
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:
{
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 double f = M_PI;
return sin(f*X(0))*sin(f*X(1));
}
}
return 0.0;
}
-1
View File
@@ -6,7 +6,6 @@
// mpirun -np 4 ex2p -m ../data/beam-quad.mesh
// mpirun -np 4 ex2p -m ../data/beam-tet.mesh
// mpirun -np 4 ex2p -m ../data/beam-hex.mesh
// mpirun -np 4 ex2p -m ../data/beam-wedge.mesh
// mpirun -np 4 ex2p -m ../data/beam-tri.mesh -o 2 -sys
// mpirun -np 4 ex2p -m ../data/beam-quad.mesh -o 3 -elast
// mpirun -np 4 ex2p -m ../data/beam-quad.mesh -o 3 -sc
-1
View File
@@ -7,7 +7,6 @@
// ex3 -m ../data/beam-tet.mesh
// ex3 -m ../data/beam-hex.mesh
// ex3 -m ../data/escher.mesh
// ex3 -m ../data/escher.mesh -o 2
// ex3 -m ../data/fichera.mesh
// ex3 -m ../data/fichera-q2.vtk
// ex3 -m ../data/fichera-q3.mesh
-1
View File
@@ -7,7 +7,6 @@
// mpirun -np 4 ex3p -m ../data/beam-tet.mesh
// mpirun -np 4 ex3p -m ../data/beam-hex.mesh
// mpirun -np 4 ex3p -m ../data/escher.mesh
// mpirun -np 4 ex3p -m ../data/escher.mesh -o 2
// mpirun -np 4 ex3p -m ../data/fichera.mesh
// mpirun -np 4 ex3p -m ../data/fichera-q2.vtk
// mpirun -np 4 ex3p -m ../data/fichera-q3.mesh
+33 -60
View File
@@ -15,17 +15,12 @@
// ex6 -m ../data/square-disc-surf.mesh -o 2
// ex6 -m ../data/amr-quad.mesh
//
// Device sample runs:
// ex6 -pa -d cuda
// ex6 -pa -d occa-cuda
// ex6 -pa -d raja-omp
//
// Description: This is a version of Example 1 with a simple adaptive mesh
// refinement loop. The problem being solved is again the Laplace
// equation -Delta u = 1 with homogeneous Dirichlet boundary
// conditions. The problem is solved on a sequence of meshes which
// are locally refined in a conforming (triangles, tetrahedrons)
// or non-conforming (quadrilaterals, hexahedra) manner according
// or non-conforming (quadrilateral, hexahedrons) manner according
// to a simple ZZ error estimator.
//
// The example demonstrates MFEM's capability to work with both
@@ -48,19 +43,13 @@ int main(int argc, char *argv[])
// 1. Parse command-line options.
const char *mesh_file = "../data/star.mesh";
int order = 1;
bool pa = false;
const char *device = "cpu";
bool visualization = true;
bool visualization = 1;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
"--no-partial-assembly", "Enable Partial Assembly.");
args.AddOption(&device, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
@@ -96,15 +85,10 @@ int main(int argc, char *argv[])
H1_FECollection fec(order, dim);
FiniteElementSpace fespace(&mesh, &fec);
// 5. Set device config parameters from the command line options.
Device::Configure(device);
Device::Print();
// 6. As in Example 1, we set up bilinear and linear forms corresponding to
// 5. As in Example 1, we set up bilinear and linear forms corresponding to
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
// problem yet, this will be done in the main loop.
BilinearForm a(&fespace);
if (pa) { a.SetAssemblyLevel(AssemblyLevel::PARTIAL); }
LinearForm b(&fespace);
ConstantCoefficient one(1.0);
@@ -114,18 +98,18 @@ int main(int argc, char *argv[])
a.AddDomainIntegrator(integ);
b.AddDomainIntegrator(new DomainLFIntegrator(one));
// 7. The solution vector x and the associated finite element grid function
// 6. The solution vector x and the associated finite element grid function
// will be maintained over the AMR iterations. We initialize it to zero.
GridFunction x(&fespace);
x = 0.0;
// 8. All boundary attributes will be used for essential (Dirichlet) BC.
// 7. All boundary attributes will be used for essential (Dirichlet) BC.
MFEM_VERIFY(mesh.bdr_attributes.Size() > 0,
"Boundary attributes required in the mesh.");
Array<int> ess_bdr(mesh.bdr_attributes.Max());
ess_bdr = 1;
// 9. Connect to GLVis.
// 8. Connect to GLVis.
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock;
@@ -134,23 +118,23 @@ int main(int argc, char *argv[])
sol_sock.open(vishost, visport);
}
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
// that uses the ComputeElementFlux method of the DiffusionIntegrator to
// recover a smoothed flux (gradient) that is subtracted from the element
// flux to get an error indicator. We need to supply the space for the
// smoothed flux: an (H1)^sdim (i.e., vector-valued) space is used here.
// 9. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
// that uses the ComputeElementFlux method of the DiffusionIntegrator to
// recover a smoothed flux (gradient) that is subtracted from the element
// flux to get an error indicator. We need to supply the space for the
// smoothed flux: an (H1)^sdim (i.e., vector-valued) space is used here.
FiniteElementSpace flux_fespace(&mesh, &fec, sdim);
ZienkiewiczZhuEstimator estimator(*integ, x, flux_fespace);
estimator.SetAnisotropic();
// 11. A refiner selects and refines elements based on a refinement strategy.
// 10. A refiner selects and refines elements based on a refinement strategy.
// The strategy here is to refine elements with errors larger than a
// fraction of the maximum element error. Other strategies are possible.
// The refiner will call the given error estimator.
ThresholdRefiner refiner(estimator);
refiner.SetTotalErrorFraction(0.7);
// 12. The main AMR loop. In each iteration we solve the problem on the
// 11. The main AMR loop. In each iteration we solve the problem on the
// current mesh, visualize the solution, and refine the mesh.
const int max_dofs = 50000;
for (int it = 0; ; it++)
@@ -159,55 +143,44 @@ int main(int argc, char *argv[])
cout << "\nAMR iteration " << it << endl;
cout << "Number of unknowns: " << cdofs << endl;
// 13. Assemble the right-hand side.
// 12. Assemble the stiffness matrix and the right-hand side.
a.Assemble();
b.Assemble();
// 14. Set Dirichlet boundary values in the GridFunction x.
// 13. Set Dirichlet boundary values in the GridFunction x.
// Determine the list of Dirichlet true DOFs in the linear system.
Array<int> ess_tdof_list;
x.ProjectBdrCoefficient(zero, ess_bdr);
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
// 15. Switch to the device and assemble the stiffness matrix.
Device::Enable();
a.Assemble();
// 16. Create the linear system: eliminate boundary conditions, constrain
// 14. Create the linear system: eliminate boundary conditions, constrain
// hanging nodes and possibly apply other transformations. The system
// will be solved for true (unconstrained) DOFs only.
OperatorPtr A;
SparseMatrix A;
Vector B, X;
const int copy_interior = 1;
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
// 17. Solve the linear system A X = B.
if (!pa)
{
#ifndef MFEM_USE_SUITESPARSE
// Use a simple symmetric Gauss-Seidel preconditioner with PCG.
GSSmoother M((SparseMatrix&)(*A));
PCG(*A, M, B, X, 3, 200, 1e-12, 0.0);
// 15. Define a simple symmetric Gauss-Seidel preconditioner and use it to
// solve the linear system with PCG.
GSSmoother M(A);
PCG(A, M, B, X, 3, 200, 1e-12, 0.0);
#else
// If MFEM was compiled with SuiteSparse, use UMFPACK to solve the system.
UMFPackSolver umf_solver;
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
umf_solver.SetOperator(*A);
umf_solver.Mult(B, X);
// 15. If MFEM was compiled with SuiteSparse, use UMFPACK to solve the
// the linear system.
UMFPackSolver umf_solver;
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
umf_solver.SetOperator(A);
umf_solver.Mult(B, X);
#endif
}
else // No preconditioning for now in partial assembly mode.
{
CG(*A, B, X, 3, 2000, 1e-12, 0.0);
}
// 18. After solving the linear system, reconstruct the solution as a
// 16. After solving the linear system, reconstruct the solution as a
// finite element GridFunction. Constrained nodes are interpolated
// from true DOFs (it may therefore happen that x.Size() >= X.Size()).
Device::Disable();
a.RecoverFEMSolution(X, b, x);
// 19. Send solution by socket to the GLVis server.
// 17. Send solution by socket to the GLVis server.
if (visualization && sol_sock.good())
{
sol_sock.precision(8);
@@ -220,7 +193,7 @@ int main(int argc, char *argv[])
break;
}
// 20. Call the refiner to modify the mesh. The refiner calls the error
// 18. Call the refiner to modify the mesh. The refiner calls the error
// estimator to obtain element errors, then it selects elements to be
// refined and finally it modifies the mesh. The Stop() method can be
// used to determine if a stopping criterion was met.
@@ -231,7 +204,7 @@ int main(int argc, char *argv[])
break;
}
// 21. Update the space to reflect the new state of the mesh. Also,
// 19. Update the space to reflect the new state of the mesh. Also,
// interpolate the solution x so that it lies in the new space but
// represents the same function. This saves solver iterations later
// since we'll have a good initial guess of x in the next step.
@@ -240,7 +213,7 @@ int main(int argc, char *argv[])
fespace.Update();
x.Update();
// 22. Inform also the bilinear and linear forms that the space has
// 20. Inform also the bilinear and linear forms that the space has
// changed.
a.Update();
b.Update();
+36 -59
View File
@@ -15,17 +15,12 @@
// mpirun -np 4 ex6p -m ../data/square-disc-surf.mesh -o 2
// mpirun -np 4 ex6p -m ../data/amr-quad.mesh
//
// Device sample runs:
// mpirun -np 4 ex6p -pa -d cuda
// mpirun -np 4 ex6p -pa -d occa-cuda
// mpirun -np 4 ex6p -pa -d raja-omp
//
// Description: This is a version of Example 1 with a simple adaptive mesh
// refinement loop. The problem being solved is again the Laplace
// equation -Delta u = 1 with homogeneous Dirichlet boundary
// conditions. The problem is solved on a sequence of meshes which
// are locally refined in a conforming (triangles, tetrahedrons)
// or non-conforming (quadrilaterals, hexahedra) manner according
// or non-conforming (quadrilateral, hexahedrons) manner according
// to a simple ZZ error estimator.
//
// The example demonstrates MFEM's capability to work with both
@@ -54,8 +49,6 @@ int main(int argc, char *argv[])
// 2. Parse command-line options.
const char *mesh_file = "../data/star.mesh";
int order = 1;
bool pa = false;
const char *device = "cpu";
bool visualization = true;
OptionsParser args(argc, argv);
@@ -63,10 +56,6 @@ int main(int argc, char *argv[])
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
"--no-partial-assembly", "Enable Partial Assembly.");
args.AddOption(&device, "-d", "--device",
"Device configuration string, see Device::Configure().");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
@@ -117,15 +106,10 @@ int main(int argc, char *argv[])
H1_FECollection fec(order, dim);
ParFiniteElementSpace fespace(&pmesh, &fec);
// 7. Set device config parameters from the command line options.
Device::Configure(device);
if (myid == 0) { Device::Print(); }
// 8. As in Example 1p, we set up bilinear and linear forms corresponding to
// 7. As in Example 1p, we set up bilinear and linear forms corresponding to
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
// problem yet, this will be done in the main loop.
ParBilinearForm a(&fespace);
if (pa) { a.SetAssemblyLevel(AssemblyLevel::PARTIAL); }
ParLinearForm b(&fespace);
ConstantCoefficient one(1.0);
@@ -134,12 +118,12 @@ int main(int argc, char *argv[])
a.AddDomainIntegrator(integ);
b.AddDomainIntegrator(new DomainLFIntegrator(one));
// 9. The solution vector x and the associated finite element grid function
// 8. The solution vector x and the associated finite element grid function
// will be maintained over the AMR iterations. We initialize it to zero.
ParGridFunction x(&fespace);
x = 0;
// 10. Connect to GLVis.
// 9. Connect to GLVis.
char vishost[] = "localhost";
int visport = 19916;
@@ -161,7 +145,7 @@ int main(int argc, char *argv[])
sout.precision(8);
}
// 11. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
// with L2 projection in the smoothing step to better handle hanging
// nodes and parallel partitioning. We need to supply a space for the
// discontinuous flux (L2) and a space for the smoothed flux (H(div) is
@@ -175,14 +159,14 @@ int main(int argc, char *argv[])
// ParFiniteElementSpace smooth_flux_fes(&pmesh, &smooth_flux_fec, dim);
L2ZienkiewiczZhuEstimator estimator(*integ, x, flux_fes, smooth_flux_fes);
// 12. A refiner selects and refines elements based on a refinement strategy.
// 11. A refiner selects and refines elements based on a refinement strategy.
// The strategy here is to refine elements with errors larger than a
// fraction of the maximum element error. Other strategies are possible.
// The refiner will call the given error estimator.
ThresholdRefiner refiner(estimator);
refiner.SetTotalErrorFraction(0.7);
// 13. The main AMR loop. In each iteration we solve the problem on the
// 12. The main AMR loop. In each iteration we solve the problem on the
// current mesh, visualize the solution, and refine the mesh.
const int max_dofs = 100000;
for (int it = 0; ; it++)
@@ -194,48 +178,41 @@ int main(int argc, char *argv[])
cout << "Number of unknowns: " << global_dofs << endl;
}
// 14. Assemble the right-hand side and determine the list of true
// (i.e. parallel conforming) essential boundary dofs.
Array<int> ess_tdof_list;
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
// 13. Assemble the stiffness matrix and the right-hand side. Note that
// MFEM doesn't care at this point that the mesh is nonconforming
// and parallel. The FE space is considered 'cut' along hanging
// edges/faces, and also across processor boundaries.
a.Assemble();
b.Assemble();
// 15. Switch to the device and assemble the stiffness matrix. Note that
// MFEM doesn't care at this point that the mesh is nonconforming and
// parallel. The FE space is considered 'cut' along hanging
// edges/faces, and also across processor boundaries.
Device::Enable();
a.Assemble();
// 16. Create the parallel linear system: eliminate boundary conditions.
// 14. Create the parallel linear system: eliminate boundary conditions,
// constrain hanging nodes and nodes across processor boundaries.
// The system will be solved for true (unconstrained/unique) DOFs only.
OperatorPtr A;
Vector B, X;
Array<int> ess_tdof_list;
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
HypreParMatrix A;
Vector B, X;
const int copy_interior = 1;
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
// 17. Solve the linear system A X = B.
// * With full assembly, use the BoomerAMG preconditioner from hypre.
// * With partial assembly, use no preconditioner, for now.
HypreBoomerAMG *amg = NULL;
if (!pa) { amg = new HypreBoomerAMG; amg->SetPrintLevel(0); }
CGSolver cg(MPI_COMM_WORLD);
cg.SetRelTol(1e-6);
cg.SetMaxIter(2000);
cg.SetPrintLevel(3); // print the first and the last iterations only
if (amg) { cg.SetPreconditioner(*amg); }
cg.SetOperator(*A);
cg.Mult(B, X);
delete amg;
// 15. Define and apply a parallel PCG solver for AX=B with the BoomerAMG
// preconditioner from hypre.
HypreBoomerAMG amg;
amg.SetPrintLevel(0);
CGSolver pcg(A.GetComm());
pcg.SetPreconditioner(amg);
pcg.SetOperator(A);
pcg.SetRelTol(1e-6);
pcg.SetMaxIter(200);
pcg.SetPrintLevel(3); // print the first and the last iterations only
pcg.Mult(B, X);
// 18. Switch back to the host and extract the parallel grid function
// corresponding to the finite element approximation X. This is the
// local solution on each processor.
Device::Disable();
// 16. Extract the parallel grid function corresponding to the finite element
// approximation X. This is the local solution on each processor.
a.RecoverFEMSolution(X, b, x);
// 19. Send the solution by socket to a GLVis server.
// 17. Send the solution by socket to a GLVis server.
if (visualization)
{
sout << "parallel " << num_procs << " " << myid << "\n";
@@ -251,7 +228,7 @@ int main(int argc, char *argv[])
break;
}
// 20. Call the refiner to modify the mesh. The refiner calls the error
// 18. Call the refiner to modify the mesh. The refiner calls the error
// estimator to obtain element errors, then it selects elements to be
// refined and finally it modifies the mesh. The Stop() method can be
// used to determine if a stopping criterion was met.
@@ -265,7 +242,7 @@ int main(int argc, char *argv[])
break;
}
// 21. Update the finite element space (recalculate the number of DOFs,
// 19. Update the finite element space (recalculate the number of DOFs,
// etc.) and create a grid function update matrix. Apply the matrix
// to any GridFunctions over the space. In this case, the update
// matrix is an interpolation matrix so the updated GridFunction will
@@ -273,7 +250,7 @@ int main(int argc, char *argv[])
fespace.Update();
x.Update();
// 22. Load balance the mesh, and update the space and solution. Currently
// 20. Load balance the mesh, and update the space and solution. Currently
// available only for nonconforming meshes.
if (pmesh.Nonconforming())
{
@@ -285,7 +262,7 @@ int main(int argc, char *argv[])
x.Update();
}
// 23. Inform also the bilinear and linear forms that the space has
// 21. Inform also the bilinear and linear forms that the space has
// changed.
a.Update();
b.Update();
-2
View File
@@ -4,10 +4,8 @@
//
// Sample runs: ex8 -m ../data/square-disc.mesh
// ex8 -m ../data/star.mesh
// ex8 -m ../data/star-mixed.mesh
// ex8 -m ../data/escher.mesh
// ex8 -m ../data/fichera.mesh
// ex8 -m ../data/fichera-mixed.mesh
// ex8 -m ../data/square-disc-p2.vtk
// ex8 -m ../data/square-disc-p3.mesh
// ex8 -m ../data/star-surf.mesh -o 2
-6
View File
@@ -4,10 +4,8 @@
//
// Sample runs: mpirun -np 4 ex8p -m ../data/square-disc.mesh
// mpirun -np 4 ex8p -m ../data/star.mesh
// mpirun -np 4 ex8p -m ../data/star-mixed.mesh
// mpirun -np 4 ex8p -m ../data/escher.mesh
// mpirun -np 4 ex8p -m ../data/fichera.mesh
// mpirun -np 4 ex8p -m ../data/fichera-mixed.mesh
// mpirun -np 4 ex8p -m ../data/square-disc-p2.vtk
// mpirun -np 4 ex8p -m ../data/square-disc-p3.mesh
// mpirun -np 4 ex8p -m ../data/star-surf.mesh -o 2
@@ -125,13 +123,9 @@ int main(int argc, char *argv[])
test_order++;
}
if (test_order < trial_order)
{
if (myid == 0)
{
cerr << "Warning, test space not enriched enough to handle primal"
<< " trial space\n";
}
}
FiniteElementCollection *x0_fec, *xhat_fec, *test_fec;
+68 -19
View File
@@ -10,7 +10,6 @@
// ex9 -m ../data/periodic-hexagon.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/amr-quad.mesh -p 1 -r 2 -dt 0.002 -tf 9
// ex9 -m ../data/star-q3.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/star-mixed.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/disc-nurbs.mesh -p 1 -r 3 -dt 0.005 -tf 9
// ex9 -m ../data/disc-nurbs.mesh -p 2 -r 3 -dt 0.005 -tf 9
// ex9 -m ../data/periodic-square.mesh -p 3 -r 4 -dt 0.0025 -tf 9 -vs 20
@@ -79,6 +78,7 @@ public:
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
problem = 0;
const char *mesh_file = "../data/periodic-hexagon.mesh";
@@ -132,8 +132,8 @@ int main(int argc, char *argv[])
// 2. Read the mesh from the given mesh file. We can handle geometrically
// periodic meshes in this code.
Mesh mesh(mesh_file, 1, 1);
int dim = mesh.Dimension();
Mesh *mesh = new Mesh(mesh_file, 1, 1);
int dim = mesh->Dimension();
// 3. Define the ODE solver used for time integration. Several explicit
// Runge-Kutta methods are available.
@@ -147,6 +147,7 @@ int main(int argc, char *argv[])
case 6: ode_solver = new RK6Solver; break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
delete mesh;
return 3;
}
@@ -156,18 +157,18 @@ int main(int argc, char *argv[])
// a (piecewise-polynomial) high-order mesh.
for (int lev = 0; lev < ref_levels; lev++)
{
mesh.UniformRefinement();
mesh->UniformRefinement();
}
if (mesh.NURBSext)
if (mesh->NURBSext)
{
mesh.SetCurvature(max(order, 1));
mesh->SetCurvature(max(order, 1));
}
mesh.GetBoundingBox(bb_min, bb_max, max(order, 1));
mesh->GetBoundingBox(bb_min, bb_max, max(order, 1));
// 5. Define the discontinuous DG finite element space of the given
// polynomial order on the refined mesh.
DG_FECollection fec(order, dim);
FiniteElementSpace fes(&mesh, &fec);
FiniteElementSpace fes(mesh, &fec);
cout << "Number of unknowns: " << fes.GetVSize() << endl;
@@ -178,8 +179,20 @@ int main(int argc, char *argv[])
FunctionCoefficient inflow(inflow_function);
FunctionCoefficient u0(u0_function);
tic_toc.Clear();
tic_toc.Start();
BilinearForm m(&fes);
m.AddDomainIntegrator(new MassIntegrator);
m.Assemble();
m.Finalize();
tic_toc.Stop();
double mass_init_time = tic_toc.RealTime();
cout << " Mass initialization time: " << mass_init_time << "s." << endl;
tic_toc.Clear();
tic_toc.Start();
BilinearForm k(&fes);
k.AddDomainIntegrator(new ConvectionIntegrator(velocity, -1.0));
k.AddInteriorFaceIntegrator(
@@ -187,15 +200,20 @@ int main(int argc, char *argv[])
k.AddBdrFaceIntegrator(
new TransposeIntegrator(new DGTraceIntegrator(velocity, 1.0, -0.5)));
LinearForm b(&fes);
b.AddBdrFaceIntegrator(
new BoundaryFlowIntegrator(inflow, velocity, -1.0, -0.5));
m.Assemble();
m.Finalize();
int skip_zeros = 0;
k.Assemble(skip_zeros);
k.Finalize(skip_zeros);
tic_toc.Stop();
double adv_init_time = tic_toc.RealTime();
cout << " Advection initialization time: " << adv_init_time << "s." << endl;
tic_toc.Clear();
tic_toc.Start();
LinearForm b(&fes);
b.AddBdrFaceIntegrator(
new BoundaryFlowIntegrator(inflow, velocity, -1.0, -0.5));
b.Assemble();
// 7. Define the initial conditions, save the corresponding grid function to
@@ -207,12 +225,16 @@ int main(int argc, char *argv[])
{
ofstream omesh("ex9.mesh");
omesh.precision(precision);
mesh.Print(omesh);
mesh->Print(omesh);
ofstream osol("ex9-init.gf");
osol.precision(precision);
u.Save(osol);
}
tic_toc.Stop();
double total_init_time = mass_init_time + adv_init_time + tic_toc.RealTime();
cout << " Initialization time: " << total_init_time << "s." << endl;
// Create data collection for solution output: either VisItDataCollection for
// ascii data files, or SidreDataCollection for binary data files.
DataCollection *dc = NULL;
@@ -221,14 +243,14 @@ int main(int argc, char *argv[])
if (binary)
{
#ifdef MFEM_USE_SIDRE
dc = new SidreDataCollection("Example9", &mesh);
dc = new SidreDataCollection("Example9", mesh);
#else
MFEM_ABORT("Must build with MFEM_USE_SIDRE=YES for binary output.");
#endif
}
else
{
dc = new VisItDataCollection("Example9", &mesh);
dc = new VisItDataCollection("Example9", mesh);
dc->SetPrecision(precision);
}
dc->RegisterField("solution", &u);
@@ -253,7 +275,7 @@ int main(int argc, char *argv[])
else
{
sout.precision(precision);
sout << "solution\n" << mesh << u;
sout << "solution\n" << *mesh << u;
sout << "pause\n";
sout << flush;
cout << "GLVis visualization paused."
@@ -270,6 +292,9 @@ int main(int argc, char *argv[])
adv.SetTime(t);
ode_solver->Init(adv);
tic_toc.Clear();
tic_toc.Start();
bool done = false;
for (int ti = 0; !done; )
{
@@ -285,7 +310,7 @@ int main(int argc, char *argv[])
if (visualization)
{
sout << "solution\n" << mesh << u << flush;
sout << "solution\n" << *mesh << u << flush;
}
if (visit)
@@ -297,6 +322,9 @@ int main(int argc, char *argv[])
}
}
tic_toc.Stop();
cout << " Computation time: " << tic_toc.RealTime() << "s." << endl;
// 9. Save the final solution. This output can be viewed later using GLVis:
// "glvis -m ex9.mesh -g ex9-final.gf".
{
@@ -317,7 +345,7 @@ int main(int argc, char *argv[])
FE_Evolution::FE_Evolution(SparseMatrix &_M, SparseMatrix &_K, const Vector &_b)
: TimeDependentOperator(_M.Size()), M(_M), K(_K), b(_b), z(_M.Size())
{
M_solver.SetPreconditioner(M_prec);
//M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(M);
M_solver.iterative_mode = false;
@@ -329,10 +357,31 @@ FE_Evolution::FE_Evolution(SparseMatrix &_M, SparseMatrix &_K, const Vector &_b)
void FE_Evolution::Mult(const Vector &x, Vector &y) const
{
/*y = 0.;
Vector xx(x);
int size = xx.Size();
int n = size;
int order = 1;
int dofs = (order+1)*(order+1);
for (int i = 0; i < n; ++i)
{
cout << "cacahuete " << i << endl;
xx = 0.;
xx(i) = 1000.;
// y = M^{-1} (K x + b)
K.Mult(xx, z);
for (int j = 0; j < z.Size(); ++j)
{
z(j) = abs(z(j)) < 1e-12 ? 0 : z(j);
}
z.Print(std::cout,dofs);
y += z;
}*/
// y = M^{-1} (K x + b)
K.Mult(x, z);
z += b;
M_solver.Mult(z, y);
// K.Mult(x, y);
}
+584
View File
@@ -0,0 +1,584 @@
// MFEM Example 9
//
// Compile with: make ex9
//
// Sample runs:
// ex9 -m ../data/periodic-segment.mesh -p 0 -r 2 -dt 0.005
// ex9 -m ../data/periodic-square.mesh -p 0 -r 2 -dt 0.01 -tf 10
// ex9 -m ../data/periodic-hexagon.mesh -p 0 -r 2 -dt 0.01 -tf 10
// ex9 -m ../data/periodic-square.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/periodic-hexagon.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/amr-quad.mesh -p 1 -r 2 -dt 0.002 -tf 9
// ex9 -m ../data/star-q3.mesh -p 1 -r 2 -dt 0.005 -tf 9
// ex9 -m ../data/disc-nurbs.mesh -p 1 -r 3 -dt 0.005 -tf 9
// ex9 -m ../data/disc-nurbs.mesh -p 2 -r 3 -dt 0.005 -tf 9
// ex9 -m ../data/periodic-square.mesh -p 3 -r 4 -dt 0.0025 -tf 9 -vs 20
// ex9 -m ../data/periodic-cube.mesh -p 0 -r 2 -o 2 -dt 0.02 -tf 8
//
// Description: This example code solves the time-dependent advection equation
// du/dt + v.grad(u) = 0, where v is a given fluid velocity, and
// u0(x)=u(0,x) is a given initial condition.
//
// The example demonstrates the use of Discontinuous Galerkin (DG)
// bilinear forms in MFEM (face integrators), the use of explicit
// ODE time integrators, the definition of periodic boundary
// conditions through periodic meshes, as well as the use of GLVis
// for persistent visualization of a time-evolving solution. The
// saving of time-dependent data files for external visualization
// with VisIt (visit.llnl.gov) is also illustrated.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include <algorithm>
#include "../fem/dgpabilininteg.hpp"
#include "../fem/dgfacefunctions.hpp"
#include "../fem/partialassemblykernel.hpp"
using namespace std;
using namespace mfem;
// Choice for the problem setup. The fluid velocity, initial condition and
// inflow boundary condition are chosen based on this parameter.
int problem;
// Velocity coefficient
void velocity_function(const Vector &x, Vector &v);
// Initial condition
double u0_function(const Vector &x);
// Inflow boundary condition
double inflow_function(const Vector &x);
// Mesh bounding box
Vector bb_min, bb_max;
/** A time-dependent operator for the right-hand side of the ODE. The DG weak
form of du/dt = -v.grad(u) is M du/dt = K u + b, where M and K are the mass
and advection matrices, and b describes the flow on the boundary. This can
be written as a general ODE, du/dt = M^{-1} (K u + b), and this class is
used to evaluate the right-hand side. */
class FE_Evolution : public TimeDependentOperator
{
private:
// BilinearForm &M;
Operator &M;
Operator &K;
const Vector &b;
CGSolver M_solver;
DSmoother M_prec;
mutable Vector z;
public:
// FE_Evolution(BilinearForm &_M, BilinearForm &_K, const Vector &_b);
FE_Evolution(Operator &_M, Operator &_K, const Vector &_b);
virtual void Mult(const Vector &x, Vector &y) const;
virtual ~FE_Evolution() { }
};
int main(int argc, char *argv[])
{
// 1. Parse command-line options.
problem = 0;
const char *mesh_file = "../data/periodic-hexagon.mesh";
int ref_levels = 2;
int order = 3;
int ode_solver_type = 4;
double t_final = 10.0;
double dt = 0.01;
bool visualization = true;
bool visit = false;
bool binary = false;
int vis_steps = 5;
int precision = 8;
cout.precision(precision);
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&problem, "-p", "--problem",
"Problem setup to use. See options in velocity_function().");
args.AddOption(&ref_levels, "-r", "--refine",
"Number of times to refine the mesh uniformly.");
args.AddOption(&order, "-o", "--order",
"Order (degree) of the finite elements.");
args.AddOption(&ode_solver_type, "-s", "--ode-solver",
"ODE solver: 1 - Forward Euler,\n\t"
" 2 - RK2 SSP, 3 - RK3 SSP, 4 - RK4, 6 - RK6.");
args.AddOption(&t_final, "-tf", "--t-final",
"Final time; start time is 0.");
args.AddOption(&dt, "-dt", "--time-step",
"Time step.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&visit, "-visit", "--visit-datafiles", "-no-visit",
"--no-visit-datafiles",
"Save data files for VisIt (visit.llnl.gov) visualization.");
args.AddOption(&binary, "-binary", "--binary-datafiles", "-ascii",
"--ascii-datafiles",
"Use binary (Sidre) or ascii format for VisIt data files.");
args.AddOption(&vis_steps, "-vs", "--visualization-steps",
"Visualize every n-th timestep.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
// 2. Read the mesh from the given mesh file. We can handle geometrically
// periodic meshes in this code.
Mesh *mesh = new Mesh(mesh_file, 1, 1);
int dim = mesh->Dimension();
// 3. Define the ODE solver used for time integration. Several explicit
// Runge-Kutta methods are available.
ODESolver *ode_solver = NULL;
switch (ode_solver_type)
{
case 1: ode_solver = new ForwardEulerSolver; break;
case 2: ode_solver = new RK2Solver(1.0); break;
case 3: ode_solver = new RK3SSPSolver; break;
case 4: ode_solver = new RK4Solver; break;
case 6: ode_solver = new RK6Solver; break;
default:
cout << "Unknown ODE solver type: " << ode_solver_type << '\n';
return 3;
}
// 4. Refine the mesh to increase the resolution. In this example we do
// 'ref_levels' of uniform refinement, where 'ref_levels' is a
// command-line parameter. If the mesh is of NURBS type, we convert it to
// a (piecewise-polynomial) high-order mesh.
for (int lev = 0; lev < ref_levels; lev++)
{
mesh->UniformRefinement();
}
if (mesh->NURBSext)
{
mesh->SetCurvature(max(order, 1));
}
if (!mesh->GetNodes())
{
mesh->SetCurvature(1);
}
mesh->GetBoundingBox(bb_min, bb_max, max(order, 1));
// 5. Define the discontinuous DG finite element space of the given
// polynomial order on the refined mesh.
DG_FECollection fec(order, dim);
//H1_FECollection fec(order, dim);
FiniteElementSpace fes(mesh, &fec);
cout << "Number of unknowns: " << fes.GetVSize() << endl;
// 6. Set up and assemble the bilinear and linear forms corresponding to the
// DG discretization. The DGTraceIntegrator involves integrals over mesh
// interior faces.
VectorFunctionCoefficient velocity(dim, velocity_function);
FunctionCoefficient inflow(inflow_function);
FunctionCoefficient u0(u0_function);
//Creating a partial assembly Kernel
//Maybe not the right place to initialize tensor size.
int ir_order = 2*order+1;
tic_toc.Clear();
tic_toc.Start();
//Initialization of the Mass operator
// BilinearFormOperator m(&fes);
// m.AddDomainIntegrator(new PAMassIntegrator(&fes,ir_order));
// m.AddDomainIntegrator(new EigenPAMassIntegrator<2>(&fes,ir_order));
// m.AddDomainIntegrator(new EigenPAMassIntegrator<2,EigenDomainPAK>(&fes,ir_order));
//BilinearForm m(&fes);
//m.AddIntegrator(new PADomainInt<MassEquation>(&fes,ir_order,MassEquation::ArgsEmpty{}));
// m.AddDomainIntegrator(new MassIntegrator());
// m.AddIntegrator(new PADomainInt<MassEquation,CGSolverDG>(&fes,ir_order,MassEquation::ArgsEmpty{}));
// m.AddIntegrator(new PADomainInt<MassEquation>(&fes,ir_order));
PADomainInt<MassEquation> mass(&fes,ir_order,MassEquation::ArgsEmpty{});
// DiagSolverDG m(fes,ir_order,mass);
// PACGSolver<PADomainInt<MassEquation>> m(&fes,mass);
DiagSolverDG prec(fes,ir_order,mass);
// PAPrecCGSolver<PADomainInt<MassEquation>,DiagSolverDG> m(&fes,mass,prec);
// CGSolverDG<PADomainInt<MassEquation>> m(fes,ir_order,mass);
PrecCGSolverDG<PADomainInt<MassEquation>,DiagSolverDG> m(fes,ir_order,mass,prec);
Operator* mo = &m;
Array<int> ess_tdof_list;
// SparseMatrix msp;
// BilinearFormOperator mbf;
// Operator *mo;
// m.AssembleForm(msp);
// m.AssembleForm(mbf);
// m.FormSystemOperator(ess_tdof_list, mo);
tic_toc.Stop();
double mass_init_time = tic_toc.RealTime();
cout << " Mass initialization time: " << mass_init_time << "s." << endl;
tic_toc.Clear();
tic_toc.Start();
//Initialization of the Stiffness operator
BilinearForm k(&fes);
//k.AddDomainIntegrator(new EigenPAConvectionIntegrator<2>(&fes,ir_order,velocity, -1.0));
// k.AddDomainIntegrator(new PAConvectionIntegrator<DummyDomainPAK>(&fes,ir_order,velocity, -1.0));
typename DGConvectionEquation::Args argsEq(velocity,-1.0,-0.5);
k.AddIntegrator(new PADomainInt<DGConvectionEquation>(&fes,ir_order,argsEq));
// k.AddIntegrator(new PADomainInt<DGConvectionEquation>(&fes,ir_order,velocity,-1.0));
// k.AddDomainIntegrator(
// new PADGConvectionFaceIntegrator<DummyFacePAK>(&fes,ir_order,velocity, 1.0, -0.5));
// k.AddDomainIntegrator(
// new PADGConvectionFaceIntegrator2<FacePAK>(&fes,ir_order,velocity, 1.0, -0.5));
k.AddIntegrator(new PAFaceInt<DGConvectionEquation>(&fes,ir_order,argsEq));
// k.AddIntegrator(new PAFaceInt<DGConvectionEquation>(&fes,ir_order,velocity, 1.0, -0.5));
BilinearFormOperator kbf;
Operator *ko;
k.AssembleForm(kbf);
k.FormSystemOperator(ess_tdof_list, ko);
tic_toc.Stop();
double adv_init_time = tic_toc.RealTime();
cout << " Advection initialization time: " << adv_init_time << "s." << endl;
tic_toc.Clear();
tic_toc.Start();
//No need to do PA
LinearForm b(&fes);
b.AddBdrFaceIntegrator(
new BoundaryFlowIntegrator(inflow, velocity, -1.0, -0.5));
b.Assemble();
tic_toc.Stop();
double total_init_time = mass_init_time + adv_init_time + tic_toc.RealTime();
cout << " Initialization time: " << total_init_time << "s." << endl;
// 7. Define the initial conditions, save the corresponding grid function to
// a file and (optionally) save data in the VisIt format and initialize
// GLVis visualization.
GridFunction u(&fes);
u.ProjectCoefficient(u0);
{
ofstream omesh("ex9.mesh");
omesh.precision(precision);
mesh->Print(omesh);
ofstream osol("ex9-init.gf");
osol.precision(precision);
u.Save(osol);
}
// Create data collection for solution output: either VisItDataCollection for
// ascii data files, or SidreDataCollection for binary data files.
DataCollection *dc = NULL;
if (visit)
{
if (binary)
{
#ifdef MFEM_USE_SIDRE
dc = new SidreDataCollection("Example9", mesh);
#else
MFEM_ABORT("Must build with MFEM_USE_SIDRE=YES for binary output.");
#endif
}
else
{
dc = new VisItDataCollection("Example9", mesh);
dc->SetPrecision(precision);
}
dc->RegisterField("solution", &u);
dc->SetCycle(0);
dc->SetTime(0.0);
dc->Save();
}
socketstream sout;
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
sout.open(vishost, visport);
if (!sout)
{
cout << "Unable to connect to GLVis server at "
<< vishost << ':' << visport << endl;
visualization = false;
cout << "GLVis visualization disabled.\n";
}
else
{
sout.precision(precision);
sout << "solution\n" << *mesh << u;
sout << "pause\n";
sout << flush;
cout << "GLVis visualization paused."
<< " Press space (in the GLVis window) to resume it.\n";
}
}
// 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 adv(*mo, *ko, b);
// FE_Evolution adv(m, k, b);
double t = 0.0;
adv.SetTime(t);
ode_solver->Init(adv);
tic_toc.Clear();
tic_toc.Start();
bool done = false;
for (int ti = 0; !done; )
{
double dt_real = min(dt, t_final - t);
ode_solver->Step(u, t, dt_real);
ti++;
//done = true;
done = (t >= t_final - 1e-8*dt);
if (done || ti % vis_steps == 0)
{
cout << "time step: " << ti << ", time: " << t << endl;
if (visualization)
{
sout << "solution\n" << *mesh << u << flush;
// sout << "screenshot\n" << "ex9-" << ti << ".png" << flush;
}
if (visit)
{
dc->SetCycle(ti);
dc->SetTime(t);
dc->Save();
}
}
}
tic_toc.Stop();
cout << " Computation time: " << tic_toc.RealTime() << "s." << endl;
// 9. Save the final solution. This output can be viewed later using GLVis:
// "glvis -m ex9.mesh -g ex9-final.gf".
{
ofstream osol("ex9-final.gf");
osol.precision(precision);
u.Save(osol);
}
// 10. Free the used memory.
delete ode_solver;
delete dc;
//delete mo;
//delete ko;
return 0;
}
// Implementation of class FE_Evolution
// FE_Evolution::FE_Evolution(BilinearForm &_M, BilinearForm &_K, const Vector &_b)
// : TimeDependentOperator(_M.Size(), 0.0), M(_M), K(_K), b(_b), z(_M.Size())
// {
// //TODO have to take into account the block diagonal structure of M
// //M_solver.SetPreconditioner(M_prec);
// M_solver.SetOperator(M);
// M_solver.iterative_mode = true;
// M_solver.SetRelTol(1e-9);
// M_solver.SetAbsTol(0.0);
// M_solver.SetMaxIter(100);
// M_solver.SetPrintLevel(0);
// }
FE_Evolution::FE_Evolution(Operator &_M, Operator &_K, const Vector &_b)
: TimeDependentOperator(_M.Height(), 0.0), M(_M), K(_K), b(_b), z(_M.Height())
{
//TODO have to take into account the block diagonal structure of M
// M_solver.SetPreconditioner(M_prec);
M_solver.SetOperator(M);
M_solver.iterative_mode = true;
M_solver.SetRelTol(1e-9);
M_solver.SetAbsTol(0.0);
M_solver.SetMaxIter(100);
M_solver.SetPrintLevel(0);
}
void FE_Evolution::Mult(const Vector &x, Vector &y) const
{
// y = 0.;
// Vector xx(x);
// int size = xx.Size();
// int n = size;
// int order = 1;
// int dofs = (order+1)*(order+1);
// for (int i = 0; i < n; ++i)
// {
// cout << "cacahuete " << i << endl;
// xx = 0.;
// xx(i) = 1000.;
// // y = M^{-1} (K x + b)
// K.Mult(xx, z);
// for (int j = 0; j < z.Size(); ++j)
// {
// z(j) = abs(z(j)) < 1e-12 ? 0 : z(j);
// }
// z.Print(std::cout,dofs);
// y += z;
// }
K.Mult(x, z);
z += b;
// M_solver.Mult(z, y);
M.Mult(z,y);
// K.Mult(x, y);
}
// Velocity coefficient
void velocity_function(const Vector &x, Vector &v)
{
int dim = x.Size();
// map to the reference [-1,1] domain
Vector X(dim);
for (int i = 0; i < dim; i++)
{
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
switch (problem)
{
case 4:
case 0:
{
// Translations in 1D, 2D, and 3D
switch (dim)
{
case 1: v(0) = 1.0; break;
case 2: v(0) = sqrt(2./3.); v(1) = sqrt(1./3.); break;
// case 2: v(0) = 1+abs(X(0)); v(1) = 1+abs(X(0)); break;
case 3: v(0) = sqrt(3./6.); v(1) = sqrt(2./6.); v(2) = sqrt(1./6.);
break;
}
break;
}
case 1:
case 2:
{
// Clockwise rotation in 2D around the origin
const double w = M_PI/2;
switch (dim)
{
case 1: v(0) = 1.0; break;
case 2: v(0) = w*X(1); v(1) = -w*X(0); break;
case 3: v(0) = w*X(1); v(1) = -w*X(0); v(2) = 0.0; break;
}
break;
}
case 3:
{
// Clockwise twisting rotation in 2D around the origin
const 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)
{
case 1: v(0) = 1.0; break;
case 2: v(0) = d*w*X(1); v(1) = -d*w*X(0); break;
case 3: v(0) = d*w*X(1); v(1) = -d*w*X(0); v(2) = 0.0; break;
}
break;
}
}
}
// Initial condition
double u0_function(const Vector &x)
{
int dim = x.Size();
// map to the reference [-1,1] domain
Vector X(dim);
for (int i = 0; i < dim; i++)
{
double center = (bb_min[i] + bb_max[i]) * 0.5;
X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]);
}
switch (problem)
{
case 0:
case 1:
{
switch (dim)
{
case 1:
return exp(-40.*pow(X(0)-0.5,2));
case 2:
case 3:
{
double rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.;
// double rx = 0.05, ry = 0.05, cx = -0., cy = -0.5, w = 10.;
if (dim == 3)
{
const double s = (1. + 0.25*cos(2*M_PI*X(2)));
rx *= s;
ry *= s;
}
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:
{
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 double f = M_PI;
return sin(f*X(0))*sin(f*X(1));
}
case 4:
{
return exp( -40*( X(0)*X(0) + X(1)*X(1) + X(2)*X(2) ) );
}
}
return 0.0;
}
// Inflow boundary condition (zero for the problems considered in this example)
double inflow_function(const Vector &x)
{
switch (problem)
{
case 0:
case 1:
case 2:
case 3: return 0.0;
}
return 0.0;
}
-1
View File
@@ -10,7 +10,6 @@
// mpirun -np 4 ex9p -m ../data/periodic-hexagon.mesh -p 1 -dt 0.005 -tf 9
// mpirun -np 4 ex9p -m ../data/amr-quad.mesh -p 1 -rp 1 -dt 0.002 -tf 9
// mpirun -np 4 ex9p -m ../data/star-q3.mesh -p 1 -rp 1 -dt 0.004 -tf 9
// mpirun -np 4 ex9p -m ../data/star-mixed.mesh -p 1 -rp 1 -dt 0.004 -tf 9
// mpirun -np 4 ex9p -m ../data/disc-nurbs.mesh -p 1 -rp 1 -dt 0.005 -tf 9
// mpirun -np 4 ex9p -m ../data/disc-nurbs.mesh -p 2 -rp 1 -dt 0.005 -tf 9
// mpirun -np 4 ex9p -m ../data/periodic-square.mesh -p 3 -rp 2 -dt 0.0025 -tf 9 -vs 20
+4 -16
View File
@@ -21,10 +21,10 @@ CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
SEQ_EXAMPLES = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex10 ex14 ex15 ex16 ex17\
ex18 ex19 ex20 ex22 ex23
SEQ_EXAMPLES = ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 ex9PA ex10 ex14 ex15 ex16\
ex17 ex18 ex19
PAR_EXAMPLES = ex1p ex2p ex3p ex4p ex5p ex6p ex7p ex8p ex9p ex10p ex11p ex12p\
ex13p ex14p ex15p ex16p ex17p ex18p ex19p ex20p ex22p ex23p
ex13p ex14p ex15p ex16p ex17p ex18p ex19p
ifeq ($(MFEM_USE_MPI),NO)
EXAMPLES = $(SEQ_EXAMPLES)
@@ -38,9 +38,6 @@ endif
ifeq ($(MFEM_USE_PETSC),YES)
SUBDIRS += petsc
endif
ifeq ($(MFEM_USE_PUMI),YES)
SUBDIRS += pumi
endif
SUBDIRS_ALL = $(addsuffix /all,$(SUBDIRS))
SUBDIRS_TEST = $(addsuffix /test,$(SUBDIRS))
SUBDIRS_CLEAN = $(addsuffix /clean,$(SUBDIRS))
@@ -96,12 +93,6 @@ ex15-test-seq: ex15
@$(call mfem-test,$<,, Serial example,-e 1)
ex15p-test-par: ex15p
@$(call mfem-test,$<, $(RUN_MPI), Parallel example,-e 1)
# Testing: optional tests
ifeq ($(MFEM_USE_STRUMPACK),YES)
ex11p-test-strumpack: ex11p
@$(call mfem-test,$<, $(RUN_MPI), STRUMPACK example,--strumpack)
test-par-YES: ex11p-test-strumpack
endif
# Testing: "test" target and mfem-test* variables are defined in config/test.mk
@@ -117,13 +108,10 @@ clean-build:
clean-exec:
@rm -f refined.mesh displaced.mesh mesh.* ex5.mesh
@rm -rf Example5* Example9* Example15* Example16* Example23*
@rm -rf Example5* Example9* Example15* Example16*
@rm -f sphere_refined.* sol.* sol_u.* sol_p.*
@rm -f ex9.mesh ex9-mesh.* ex9-init.* ex9-final.*
@rm -f deformed.* velocity.* elastic_energy.* mode_*
@rm -f ex16.mesh ex16-mesh.* ex16-init.* ex16-final.*
@rm -f vortex-mesh.* vortex.mesh vortex-?-init.* vortex-?-final.*
@rm -f deformation.* pressure.*
@rm -f ex20.dat ex20p_?????.dat gnuplot_ex20.inp gnuplot_ex20p.inp
@rm -f ex22*.mesh ex22*.sol ex22p_*.*
@rm -f ex23.mesh ex23-mesh.* ex23-init.* ex23-final.*
+22 -20
View File
@@ -63,29 +63,31 @@ add_mfem_examples(PETSC_EXAMPLES_SRCS ${PFX} copy_petsc_rc_files test_petsc)
# ctest -R petsc
# Command line options for the tests.
set(EX1_ARGS_W -m ../../data/amr-quad.mesh --usepetsc)
set(EX1_ARGS_P -m ../../data/amr-quad.mesh --usepetsc --petscopts rc_ex1p)
set(EX2_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p)
set(EX3_ARGS -m ../../data/klein-bottle.mesh -o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping)
set(EX4_ARGS -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping)
set(EX4_HYB_ARGS -m ../../data/klein-bottle.mesh -o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping --hybridization)
set(EX5_BDDC_LB_ARGS -m ../../data/star.mesh --usepetsc -o 0 --petscopts rc_ex5p_bddc --nonoverlapping --local-bdr)
set(EX5_BDDC_GB_ARGS -m ../../data/star.mesh --usepetsc -o 0 --petscopts rc_ex5p_bddc --nonoverlapping)
set(EX5_FSPL_ARGS -m ../../data/beam-tet.mesh --usepetsc -o 0 --petscopts rc_ex5p_fieldsplit)
set(EX6_ARGS -m ../../data/amr-quad.mesh --usepetsc)
set(EX6_NONOVL_ARGS -m ../../data/amr-quad.mesh --usepetsc --nonoverlapping)
set(EX9_E_ARGS -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl -dt 0.1)
set(EX9_ES_ARGS -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl --no-step)
set(EX9_IS_ARGS -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_impl --implicit -tf 0.5)
set(EX10_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p -tf 30 -s 3 -rs 2 -dt 3)
set(EX1P_ARGS -m ../../data/amr-quad.mesh --usepetsc --petscopts rc_ex1p)
set(EX2P_ARGS -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p)
set(EX3P_ARGS -m ../../data/klein-bottle.mesh
-o 2 -f 0.1 --usepetsc --petscopts rc_ex3p_bddc --nonoverlapping)
set(EX4P_ARGS -m ../../data/klein-bottle.mesh
-o 2 --usepetsc --petscopts rc_ex4p_bddc --nonoverlapping)
set(EX5P_BDDC_ARGS -m ../../data/star.mesh
--usepetsc --petscopts rc_ex5p_bddc --nonoverlapping)
set(EX5P_FSPL_ARGS -m ../../data/beam-tet.mesh
--usepetsc --petscopts rc_ex5p_fieldsplit)
set(EX6P_ARGS -m ../../data/amr-quad.mesh --usepetsc)
set(EX9P_E_ARGS -m ../../data/periodic-hexagon.mesh
--usepetsc --petscopts rc_ex9p_expl -dt 0.1)
set(EX9P_ES_ARGS -m ../../data/periodic-hexagon.mesh
--usepetsc --petscopts rc_ex9p_expl --no-step)
set(EX9P_IS_ARGS -m ../../data/periodic-hexagon.mesh
--usepetsc --petscopts rc_ex9p_impl --implicit -tf 0.5)
set(EX10P_ARGS -m ../../data/beam-quad.mesh
-tf 30 -s 3 -rs 2 -dt 3 --usepetsc --petscopts rc_ex10p)
# Add the tests: one test per command-line-variable.
foreach(TEST_OPTIONS_VAR
EX1_ARGS_W EX1_ARGS_P EX2_ARGS EX3_ARGS EX4_ARGS EX4_HYB_ARGS
EX5_BDDC_LB_ARGS EX5_BDDC_GB_ARGS EX5_FSPL_ARGS EX6_ARGS EX6_NONOVL_ARGS
EX9_E_ARGS EX9_ES_ARGS EX9_IS_ARGS EX10_ARGS)
EX1P_ARGS EX2P_ARGS EX3P_ARGS EX4P_ARGS EX5P_BDDC_ARGS EX5P_FSPL_ARGS
EX6P_ARGS EX9P_E_ARGS EX9P_ES_ARGS EX9P_IS_ARGS EX10P_ARGS)
string(REGEX REPLACE "^(.+)_ARGS" "\\1" TEST_NAME_UC ${TEST_OPTIONS_VAR})
string(REGEX REPLACE "^([^_]+)" "\\1P" TEST_NAME_UC ${TEST_NAME_UC})
string(TOLOWER ${TEST_NAME_UC} TEST_NAME_FULL)
string(REGEX REPLACE "^([^_]+).*" "\\1" TEST_NAME ${TEST_NAME_FULL})
set(TEST_NAME_FULL ${PFX}${TEST_NAME_FULL})
@@ -96,7 +98,7 @@ foreach(TEST_OPTIONS_VAR
# All PETSC tests are parallel.
if (MFEM_USE_MPI)
add_test(NAME ${TEST_NAME_FULL}_np=4
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${MFEM_MPI_NP}
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 4
${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${TEST_NAME}> ${TEST_OPTIONS}
${MPIEXEC_POSTFLAGS})
+2 -2
View File
@@ -239,7 +239,7 @@ int main(int argc, char *argv[])
// 2b. We initialize PETSc
if (use_petsc)
{
MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL);
PetscInitialize(NULL,NULL,petscrc_file,NULL);
}
// 3. Read the serial mesh from the given mesh file on all processors. We can
@@ -446,7 +446,7 @@ int main(int argc, char *argv[])
delete oper;
// We finalize PETSc
if (use_petsc) { MFEMFinalizePetsc(); }
if (use_petsc) { PetscFinalize(); }
MPI_Finalize();
+3 -2
View File
@@ -123,7 +123,7 @@ int main(int argc, char *argv[])
}
// 2b. We initialize PETSc
MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL);
PetscInitialize(NULL,NULL,petscrc_file,NULL);
// 3. Read the (serial) mesh from the given mesh file on all processors. We
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
@@ -266,6 +266,7 @@ int main(int argc, char *argv[])
if (visualization && petscmonitor)
{
pcg->SetMonitor(&mymon);
pcg->SetPrintLevel(4);
pcg->iterative_mode = true;
X.Randomize();
}
@@ -313,7 +314,7 @@ int main(int argc, char *argv[])
delete pmesh;
// We finalize PETSc
MFEMFinalizePetsc();
PetscFinalize();
MPI_Finalize();
+2 -2
View File
@@ -101,7 +101,7 @@ int main(int argc, char *argv[])
}
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
// 3. Read the (serial) mesh from the given mesh file on all processors. We
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
@@ -359,7 +359,7 @@ int main(int argc, char *argv[])
delete pmesh;
// We finalize PETSc
if (use_petsc) { MFEMFinalizePetsc(); }
if (use_petsc) { PetscFinalize(); }
MPI_Finalize();
+2 -2
View File
@@ -96,7 +96,7 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
kappa = freq * M_PI;
// 3. Read the (serial) mesh from the given mesh file on all processors. We
@@ -309,7 +309,7 @@ int main(int argc, char *argv[])
delete pmesh;
// We finalize PETSc
if (use_petsc) { MFEMFinalizePetsc(); }
if (use_petsc) { PetscFinalize(); }
MPI_Finalize();
+2 -2
View File
@@ -97,7 +97,7 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
kappa = freq * M_PI;
// 3. Read the (serial) mesh from the given mesh file on all processors. We
@@ -330,7 +330,7 @@ int main(int argc, char *argv[])
delete pmesh;
// We finalize PETSc
if (use_petsc) { MFEMFinalizePetsc(); }
if (use_petsc) { PetscFinalize(); }
MPI_Finalize();
+13 -22
View File
@@ -64,7 +64,6 @@ int main(int argc, char *argv[])
bool visualization = 1;
bool use_petsc = true;
bool use_nonoverlapping = false;
bool local_bdr_spec = false;
const char *petscrc_file = "";
OptionsParser args(argc, argv);
@@ -87,9 +86,6 @@ int main(int argc, char *argv[])
"-no-nonoverlapping", "--no-nonoverlapping",
"Use or not the block diagonal PETSc's matrix format "
"for non-overlapping domain decomposition.");
args.AddOption(&local_bdr_spec, "-local-bdr", "--local-bdr", "-no-local-bdr",
"--no-local-bdr",
"Specify boundary dofs in local (Vdofs) ordering.");
args.Parse();
if (!args.Good())
{
@@ -105,7 +101,7 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
// 3. Read the (serial) mesh from the given mesh file on all processors. We
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
@@ -310,38 +306,33 @@ int main(int argc, char *argv[])
{
if (use_nonoverlapping)
{
PetscBDDCSolverParams opts;
// For saddle point problems, we need to provide BDDC the list of
// boundary dofs either essential or natural.
// Since R_space is the only space that may have boundary dofs and it
// is ordered first then W_space, we don't need any local offset when
// specifying the dofs.
Array<int> bdr_tdof_list;
bool local = false;
if (pmesh->bdr_attributes.Size())
{
Array<int> bdr(pmesh->bdr_attributes.Max());
bdr = 1;
if (!local_bdr_spec)
{
// Essential dofs in global ordering
R_space->GetEssentialTrueDofs(bdr, bdr_tdof_list);
}
else
{
// Alternatively, you can also provide the list of dofs in local
// ordering
R_space->GetEssentialVDofs(bdr, bdr_tdof_list);
bdr_tdof_list.SetSize(R_space->GetVSize()+W_space->GetVSize(),0);
}
opts.SetNatBdrDofs(&bdr_tdof_list,local_bdr_spec);
R_space->GetEssentialTrueDofs(bdr, bdr_tdof_list);
local = false;
// Alternatively, you can also provide the list of dofs in local
// ordering:
// R_space->GetEssentialVDofs(bdr, bdr_tdof_list);
// bdr_tdof_list.SetSize(R_space->GetVSize()+W_space->GetVSize(),0);
// local = true;
}
else
{
MFEM_WARNING("Missing boundary dofs. This may cause solver failures.");
MFEM_ABORT("Need to know the boundary dofs");
}
PetscBDDCSolverParams opts;
opts.SetNatBdrDofs(&bdr_tdof_list,local);
// See also command line options rc_ex5p_bddc
pdarcyPr = new PetscBDDCSolver(MPI_COMM_WORLD,*darcyOp,opts,"prec_");
}
@@ -544,7 +535,7 @@ int main(int argc, char *argv[])
delete pmesh;
// We finalize PETSc
if (use_petsc) { MFEMFinalizePetsc(); }
if (use_petsc) { PetscFinalize(); }
MPI_Finalize();
+3 -3
View File
@@ -12,7 +12,7 @@
// equation -Delta u = 1 with homogeneous Dirichlet boundary
// conditions. The problem is solved on a sequence of meshes which
// are locally refined in a conforming (triangles, tetrahedrons)
// or non-conforming (quadrilaterals, hexahedra) manner according
// or non-conforming (quadrilateral, hexahedrons) manner according
// to a simple ZZ error estimator.
//
// The example demonstrates MFEM's capability to work with both
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
args.PrintOptions(cout);
}
// 2b. We initialize PETSc
if (use_petsc) { MFEMInitializePetsc(NULL,NULL,petscrc_file,NULL); }
if (use_petsc) { PetscInitialize(NULL,NULL,petscrc_file,NULL); }
// 3. Read the (serial) mesh from the given mesh file on all processors. We
// can handle triangular, quadrilateral, tetrahedral, hexahedral, surface
@@ -315,7 +315,7 @@ int main(int argc, char *argv[])
}
// We finalize PETSc
if (use_petsc) { MFEMFinalizePetsc(); }
if (use_petsc) { PetscFinalize(); }
MPI_Finalize();
return 0;
+2 -2
View File
@@ -248,7 +248,7 @@ int main(int argc, char *argv[])
{
// When using PETSc, we just create the ODE solver. We use command line
// customization to select a specific solver.
MFEMInitializePetsc(NULL, NULL, petscrc_file, NULL);
PetscInitialize(NULL, NULL, petscrc_file, NULL);
ode_solver = pode_solver = new PetscODESolver(MPI_COMM_WORLD);
}
@@ -481,7 +481,7 @@ int main(int argc, char *argv[])
delete pmon;
// We finalize PETSc
if (use_petsc) { MFEMFinalizePetsc(); }
if (use_petsc) { PetscFinalize(); }
MPI_Finalize();
return 0;
+13 -19
View File
@@ -69,21 +69,18 @@ TESTNAME = Parallel PETSc example
# Testing PETSc execution options.
EX1_ARGS_W := -m ../../data/amr-quad.mesh --usepetsc
EX1_ARGS_P := -m ../../data/amr-quad.mesh --usepetsc --petscopts rc_ex1p
EX2_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p
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
EX5_BDDC_GB_ARGS := -m ../../data/star.mesh --usepetsc -o 0 --petscopts rc_ex5p_bddc --nonoverlapping
EX5_FSPL_ARGS := -m ../../data/beam-tet.mesh --usepetsc -o 0 --petscopts rc_ex5p_fieldsplit
EX6_ARGS := -m ../../data/amr-quad.mesh --usepetsc
EX6_NONOVL_ARGS := -m ../../data/amr-quad.mesh --usepetsc --nonoverlapping
EX9_E_ARGS := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl -dt 0.1
EX9_ES_ARGS := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl --no-step
EX9_IS_ARGS := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_impl --implicit -tf 0.5
EX10_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p -tf 30 -s 3 -rs 2 -dt 3
EX1_ARGS_W := -m ../../data/amr-quad.mesh --usepetsc
EX1_ARGS_P := -m ../../data/amr-quad.mesh --usepetsc --petscopts rc_ex1p
EX2_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex2p
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
EX5_BDDC_ARGS := -m ../../data/star.mesh --usepetsc -o 0 --petscopts rc_ex5p_bddc --nonoverlapping
EX5_FSPL_ARGS := -m ../../data/beam-tet.mesh --usepetsc -o 0 --petscopts rc_ex5p_fieldsplit
EX6_ARGS := -m ../../data/amr-quad.mesh --usepetsc
EX9_E_ARGS := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl -dt 0.1
EX9_ES_ARGS := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_expl --no-step
EX9_IS_ARGS := -m ../../data/periodic-hexagon.mesh --usepetsc --petscopts rc_ex9p_impl --implicit -tf 0.5
EX10_ARGS := -m ../../data/beam-quad.mesh --usepetsc --petscopts rc_ex10p -tf 30 -s 3 -rs 2 -dt 3
ex1p-test-par: ex1p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX1_ARGS_W))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX1_ARGS_P))
@@ -93,14 +90,11 @@ ex3p-test-par: ex3p
@$(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))
ex5p-test-par: ex5p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX5_BDDC_LB_ARGS))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX5_BDDC_GB_ARGS))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX5_BDDC_ARGS))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX5_FSPL_ARGS))
ex6p-test-par: ex6p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX6_ARGS))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX6_NONOVL_ARGS))
ex9p-test-par: ex9p
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX9_E_ARGS))
@$(call mfem-test,$<, $(RUN_MPI), $(TESTNAME),$(EX9_ES_ARGS))
-3
View File
@@ -6,7 +6,4 @@
# it needs PETSc configured with MUMPS
-solver_pc_type cholesky
# Petsc 3.9
-solver_pc_factor_mat_solver_type mumps
# Older versions of PETSc
-solver_pc_factor_mat_solver_package mumps
+3 -6
View File
@@ -16,10 +16,7 @@
#-pc_bddc_adaptive_threshold 10
# Customization of the local solvers
# With PETSc versions older than 3.9
# use "mat_solver_package" instead of "mat_solver_type"
#
#-pc_bddc_neumann_pc_factor_mat_solver_type mumps
#-pc_bddc_dirichlet_pc_factor_mat_solver_type mumps
#-pc_bddc_neumann_pc_factor_mat_solver_package mumps
#-pc_bddc_dirichlet_pc_factor_mat_solver_package mumps
#-pc_bddc_coarse_pc_type cholesky
#-pc_bddc_coarse_pc_factor_mat_solver_type mumps
#-pc_bddc_coarse_pc_factor_mat_solver_package mumps
-3
View File
@@ -2,7 +2,4 @@
# it needs PETSc configured with MUMPS
-solver_pc_type cholesky
# Petsc 3.9
-solver_pc_factor_mat_solver_type mumps
# Older versions of PETSc
-solver_pc_factor_mat_solver_package mumps
+3 -6
View File
@@ -13,10 +13,7 @@
#-pc_bddc_adaptive_threshold 10
# Customization of the local solvers
# With PETSc versions older than 3.9
# use "mat_solver_package" instead of "mat_solver_type"
#
#-pc_bddc_neumann_pc_factor_mat_solver_type mumps
#-pc_bddc_dirichlet_pc_factor_mat_solver_type mumps
#-pc_bddc_neumann_pc_factor_mat_solver_package mumps
#-pc_bddc_dirichlet_pc_factor_mat_solver_package mumps
#-pc_bddc_coarse_pc_type cholesky
#-pc_bddc_coarse_pc_factor_mat_solver_type mumps
#-pc_bddc_coarse_pc_factor_mat_solver_package mumps
+4 -18
View File
@@ -25,29 +25,15 @@
# verbose output
#-prec_pc_bddc_check_level 1
# local solvers (default "petsc" solvers will fail)
# needs PETSc compiled with support for MUMPS or SuiteSparse
# use "umfpack" in place of "mumps" if you want to use
# SuiteSparse solvers
#
# With PETSc versions older than 3.9
# use "mat_solver_package" instead of "mat_solver_type"
#
# local solvers (needs PETSc compiled with support for SuiteSparse)
# default solvers will fail
-prec_pc_bddc_neumann_pc_type lu
-prec_pc_bddc_neumann_pc_factor_mat_solver_type mumps
-prec_pc_bddc_neumann_pc_factor_mat_solver_package mumps
-prec_pc_bddc_neumann_pc_factor_mat_solver_package umfpack
-prec_pc_bddc_dirichlet_pc_type lu
-prec_pc_bddc_dirichlet_pc_factor_mat_solver_type mumps
-prec_pc_bddc_dirichlet_pc_factor_mat_solver_package mumps
# MUMPS sometimes fails with a very annoying error
-mat_mumps_icntl_14 500
-prec_pc_bddc_dirichlet_mat_mumps_icntl_14 500
-prec_pc_bddc_neumann_mat_mumps_icntl_14 500
-prec_pc_bddc_dirichlet_pc_factor_mat_solver_package umfpack
# coarse solver (needs PETSc compiled with support for MUMPS)
# default solver may fail
-prec_pc_bddc_coarse_pc_factor_mat_solver_type mumps
-prec_pc_bddc_coarse_pc_factor_mat_solver_package mumps
-prec_pc_bddc_coarse_pc_type cholesky
-73
View File
@@ -1,73 +0,0 @@
# Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at the
# Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights reserved.
# See file COPYRIGHT for details.
#
# This file is part of the MFEM library. For more information and source code
# availability see http://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License (as published by the Free
# Software Foundation) version 2.1 dated February 1999.
set(PUMI_EXAMPLES_SRCS)
# All PUMI examples require MPI
if (MFEM_USE_MPI)
list(APPEND PUMI_EXAMPLES_SRCS
ex1.cpp
ex1p.cpp
ex2.cpp
ex6p.cpp
)
endif()
# Include the source directory where mfem.hpp and mfem-performance.hpp are.
include_directories(BEFORE ${PROJECT_BINARY_DIR})
# Add "test_pumi" target, see below.
add_custom_target(test_pumi
${CMAKE_CTEST_COMMAND} -R pumi USES_TERMINAL)
# Add one executable per cpp file, adding "pumi_" as prefix. Sets
# "test_pumi" as a target that depends on the given examples.
set(PFX pumi_)
add_mfem_examples(PUMI_EXAMPLES_SRCS ${PFX} "" test_pumi)
# Testing.
# The PUMI tests can be run separately using the target "test_pumi"
# which builds the examples and runs:
# ctest -R pumi
# Command line options for the tests.
# TODO...
# Set the number of processors for the parallel examples. The value of
# MFEM_MPI_NP is ignored.
set(EX1_TEST_NP 1)
set(EX1P_TEST_NP 8)
set(EX2_TEST_NP 1)
set(EX6P_TEST_NP 8)
# Add the tests: one test per source file.
foreach(SRC_FILE ${PUMI_EXAMPLES_SRCS})
get_filename_component(SRC_FILENAME ${SRC_FILE} NAME)
string(REPLACE ".cpp" "" TEST_NAME ${SRC_FILENAME})
string(TOUPPER ${TEST_NAME} UP_TEST_NAME)
set(TEST_NAME ${PFX}${TEST_NAME})
set(THIS_TEST_OPTIONS "-no-vis")
list(APPEND THIS_TEST_OPTIONS ${${UP_TEST_NAME}_TEST_OPTS})
# message(STATUS "Test ${TEST_NAME} options: ${THIS_TEST_OPTIONS}")
# All PUMI examples require MPI
if (FALSE)
add_test(NAME ${TEST_NAME}_ser
COMMAND ${TEST_NAME} ${THIS_TEST_OPTIONS})
else()
set(TEST_NP ${${UP_TEST_NAME}_TEST_NP})
add_test(NAME ${TEST_NAME}_np=${TEST_NP}
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} ${TEST_NP}
${MPIEXEC_PREFLAGS}
$<TARGET_FILE:${TEST_NAME}> ${THIS_TEST_OPTIONS}
${MPIEXEC_POSTFLAGS})
endif()
endforeach()
-18
View File
@@ -1,18 +0,0 @@
Finite Element Discretization Library
__
_ __ ___ / _| ___ _ __ ___
| '_ ` _ \ | |_ / _ \| '_ ` _ \
| | | | | || _|| __/| | | | | |
|_| |_| |_||_| \___||_| |_| |_|
http://mfem.org
This directory contains modifications of the example codes that illustrate the
use of MFEM features based on the Parallel Unstructured Mesh Infrastructure,
PUMI, from https://scorec.rpi.edu/pumi.
To build these examples, make sure that MFEM is configured with the option
"MFEM_USE_PUMI = YES", see the top-level INSTALL file for details.
We recommend comparing the original example codes with the corresponding files
in the current directory.
-262
View File
@@ -1,262 +0,0 @@
// MFEM Example 1
// PUMI Modification
//
// Compile with: make ex1
//
// Sample runs:
// ex1 -m ../../data/pumi/serial/Kova.smb -p ../../data/pumi/geom/Kova.dmg
//
// Note: Example models + meshes for the PUMI examples can be downloaded
// from github.com/mfem/data/pumi. After downloading we recommend
// creating a symbolic link to the above directory in ../../data.
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
// space (i.e. quadratic for quadratic curvilinear mesh, NURBS for
// NURBS mesh, etc.)
//
// The example highlights the use of mesh refinement, finite
// element grid functions, as well as linear and bilinear forms
// corresponding to the left-hand side and right-hand side of the
// discrete linear system. We also cover the explicit elimination
// of essential boundary conditions, static condensation, and the
// optional connection to the GLVis tool for visualization.
//
// This PUMI modification demonstrates how PUMI's API can be used
// to load a PUMI mesh classified on a geometric model and then
// convert it to the MFEM mesh format. The inputs are a Parasolid
// model, "*.xmt_txt" and a SCOREC mesh "*.smb". The option "-o"
// is used for the Finite Element order and "-go" is used for the
// geometry order. Note that they can be used independently, i.e.
// "-o 8 -go 3" solves for 8th order FE on a third order geometry.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#ifdef MFEM_USE_SIMMETRIX
#include <SimUtil.h>
#include <gmi_sim.h>
#endif
#include <apfMDS.h>
#include <gmi_null.h>
#include <PCU.h>
#include <apfConvert.h>
#include <gmi_mesh.h>
#include <crv.h>
using namespace std;
using namespace mfem;
int main(int argc, char *argv[])
{
// 1. Initialize MPI (required by PUMI).
int num_procs, myid;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
// 2. Parse command-line options.
const char *mesh_file = "../../data/pumi/serial/Kova.smb";
#ifdef MFEM_USE_SIMMETRIX
const char *model_file = "../../data/pumi/geom/Kova.x_t";
#else
const char *model_file = "../../data/pumi/geom/Kova.dmg";
#endif
int order = 1;
bool static_cond = false;
bool visualization = 1;
int geom_order = 1;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree) or -1 for"
" isoparametric space.");
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&model_file, "-p", "--parasolid",
"Parasolid model to use.");
args.AddOption(&geom_order, "-go", "--geometry_order",
"Geometric order of the model");
args.Parse();
if (!args.Good())
{
if (myid == 0)
{
args.PrintUsage(cout);
}
MPI_Finalize();
return 1;
}
if (myid == 0)
{
args.PrintOptions(cout);
}
// 3. Read the SCOREC Mesh.
PCU_Comm_Init();
#ifdef MFEM_USE_SIMMETRIX
Sim_readLicenseFile(0);
gmi_sim_start();
gmi_register_sim();
#endif
gmi_register_mesh();
apf::Mesh2* pumi_mesh;
pumi_mesh = apf::loadMdsMesh(model_file, mesh_file);
// 4. Increase the geometry order if necessary.
if (geom_order > 1)
{
crv::BezierCurver bc(pumi_mesh, geom_order, 2);
bc.run();
}
pumi_mesh->verify();
// 5. Create the MFEM mesh object from the PUMI mesh. We can handle
// triangular and tetrahedral meshes. Other inputs are the same as the
// MFEM default constructor.
Mesh *mesh = new PumiMesh(pumi_mesh, 1, 1);
int dim = mesh->Dimension();
// 6. 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();
}
}
// 7. Define a finite element space on the mesh. Here we use continuous
// Lagrange finite elements of the specified order. If order < 1, we
// instead use an isoparametric/isogeometric space.
FiniteElementCollection *fec;
if (order > 0)
{
fec = new H1_FECollection(order, dim);
}
else if (mesh->GetNodes())
{
fec = mesh->GetNodes()->OwnFEC();
cout << "Using isoparametric FEs: " << fec->Name() << endl;
}
else
{
fec = new H1_FECollection(order = 1, dim);
}
FiniteElementSpace *fespace = new FiniteElementSpace(mesh, fec);
cout << "Number of finite element unknowns: "
<< fespace->GetTrueVSize() << endl;
// 8. Determine the list of true (i.e. conforming) essential boundary dofs.
// In this example, the boundary conditions are defined by marking all
// the boundary attributes from the mesh as essential (Dirichlet) and
// converting them to a list of true dofs.
Array<int> ess_tdof_list;
if (mesh->bdr_attributes.Size())
{
Array<int> ess_bdr(mesh->bdr_attributes.Max());
ess_bdr = 1;
fespace->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
}
// 9. Set up the linear form b(.) which corresponds to the right-hand side of
// the FEM linear system, which in this case is (1,phi_i) where phi_i are
// the basis functions in the finite element fespace.
LinearForm *b = new LinearForm(fespace);
ConstantCoefficient one(1.0);
b->AddDomainIntegrator(new DomainLFIntegrator(one));
b->Assemble();
// 10. 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;
// 11. Set up the bilinear form a(.,.) on the finite element space
// corresponding to the Laplacian operator -Delta, by adding the
// Diffusion domain integrator.
BilinearForm *a = new BilinearForm(fespace);
a->AddDomainIntegrator(new DiffusionIntegrator(one));
// 12. Assemble the bilinear form and the corresponding linear system,
// applying any necessary transformations such as: eliminating boundary
// conditions, applying conforming constraints for non-conforming AMR,
// static condensation, etc.
if (static_cond) { a->EnableStaticCondensation(); }
a->Assemble();
SparseMatrix A;
Vector B, X;
a->FormLinearSystem(ess_tdof_list, x, *b, A, X, B);
cout << "Size of linear system: " << A.Height() << endl;
#ifndef MFEM_USE_SUITESPARSE
// 13. Define a simple symmetric Gauss-Seidel preconditioner and use it to
// solve the system A X = B with PCG.
GSSmoother M(A);
PCG(A, M, B, X, 1, 200, 1e-12, 0.0);
#else
// 13. If MFEM was compiled with SuiteSparse, use UMFPACK to solve the system.
UMFPackSolver umf_solver;
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
umf_solver.SetOperator(A);
umf_solver.Mult(B, X);
#endif
// 14. Recover the solution as a finite element grid function.
a->RecoverFEMSolution(X, *b, x);
// 15. Save the refined mesh and the solution. This output can be viewed later
// using GLVis: "glvis -m refined.mesh -g sol.gf".
ofstream mesh_ofs("refined.mesh");
mesh_ofs.precision(8);
mesh->Print(mesh_ofs);
ofstream sol_ofs("sol.gf");
sol_ofs.precision(8);
x.Save(sol_ofs);
// 16. Send the solution by socket to a GLVis server.
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock(vishost, visport);
sol_sock.precision(8);
sol_sock << "solution\n" << *mesh << x << flush;
}
// 17. Free the used memory.
delete a;
delete b;
delete fespace;
if (order > 0) { delete fec; }
delete mesh;
pumi_mesh->destroyNative();
apf::destroyMesh(pumi_mesh);
PCU_Comm_Free();
#ifdef MFEM_USE_SIMMETRIX
gmi_sim_stop();
Sim_unregisterAllKeys();
#endif
MPI_Finalize();
return 0;
}
-292
View File
@@ -1,292 +0,0 @@
// MFEM Example 1 - Parallel Version
// PUMI Modification
//
// Compile with: make ex1p
//
// Sample runs:
// mpirun -np 8 ex1p -m ../../data/pumi/parallel/Kova/Kova100k_8.smb
// -p ../../data/pumi/geom/Kova.dmg -o 1 -go 2
//
// Note: Example models + meshes for the PUMI examples can be downloaded
// from github.com/mfem/data/pumi. After downloading we recommend
// creating a symbolic link to the above directory in ../../data.
//
// Description: This example code demonstrates the use of MFEM to define a
// simple finite element discretization of the Laplace problem
// -Delta u = 1 with homogeneous Dirichlet boundary conditions.
// Specifically, we discretize using a FE space of the specified
// order, or if order < 1 using an isoparametric/isogeometric
// space (i.e. quadratic for quadratic curvilinear mesh, NURBS for
// NURBS mesh, etc.)
//
// The example highlights the use of mesh refinement, finite
// element grid functions, as well as linear and bilinear forms
// corresponding to the left-hand side and right-hand side of the
// discrete linear system. We also cover the explicit elimination
// of essential boundary conditions, static condensation, and the
// optional connection to the GLVis tool for visualization.
//
// This PUMI modification demonstrates how PUMI's API can be used
// to load a parallel PUMI mesh classified on a geometric model
// and then generate the corresponding parallel MFEM mesh. The
// example also performs a "uniform" refinement, similar to the
// MFEM examples, for coarse meshes. However, the refinement is
// performed using the PUMI API. The inputs are a Parasolid
// model, "*.xmt_txt" and SCOREC parallel meshes "*.smb". The
// option "-o" is used for the Finite Element order and "-go" for
// the geometry order. Note that they can be used independently:
// "-o 8 -go 3" solves for 8th order FE on third order geometry.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#ifdef MFEM_USE_SIMMETRIX
#include <SimUtil.h>
#include <gmi_sim.h>
#endif
#include <apfMDS.h>
#include <gmi_null.h>
#include <PCU.h>
#include <apfConvert.h>
#include <gmi_mesh.h>
#include <crv.h>
using namespace std;
using namespace mfem;
int main(int argc, char *argv[])
{
// 1. Initialize MPI.
int num_procs, myid;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
// 2. Parse command-line options.
const char *mesh_file = "../../data/pumi/parallel/Kova/Kova100k_8.smb";
#ifdef MFEM_USE_SIMMETRIX
const char *model_file = "../../data/pumi/geom/Kova.x_t";
#else
const char *model_file = "../../data/pumi/geom/Kova.dmg";
#endif
int order = 1;
bool static_cond = false;
bool visualization = 1;
int geom_order = 1;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree) or -1 for"
" isoparametric space.");
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&model_file, "-p", "--parasolid",
"Parasolid model to use.");
args.AddOption(&geom_order, "-go", "--geometry_order",
"Geometric order of the model");
args.Parse();
if (!args.Good())
{
if (myid == 0)
{
args.PrintUsage(cout);
}
MPI_Finalize();
return 1;
}
if (myid == 0)
{
args.PrintOptions(cout);
}
// 3. Read the SCOREC Mesh
PCU_Comm_Init();
#ifdef MFEM_USE_SIMMETRIX
Sim_readLicenseFile(0);
gmi_sim_start();
gmi_register_sim();
#endif
gmi_register_mesh();
apf::Mesh2* pumi_mesh;
pumi_mesh = apf::loadMdsMesh(model_file, mesh_file);
// 4. Increase the geometry order and refine the mesh if necessary. Parallel
// uniform refinement is performed if the total number of elements is less
// than 10,000.
int dim = pumi_mesh->getDimension();
int nEle = pumi_mesh->count(dim);
int ref_levels = (int)floor(log(10000./nEle)/log(2.)/dim);
if (geom_order > 1)
{
crv::BezierCurver bc(pumi_mesh, geom_order, 2);
bc.run();
}
// Perform Uniform refinement
if (ref_levels > 1)
{
ma::Input* uniInput = ma::configureUniformRefine(pumi_mesh, ref_levels);
if (geom_order > 1)
{
crv::adapt(uniInput);
}
else
{
ma::adapt(uniInput);
}
}
pumi_mesh->verify();
// 5. Create the parallel MFEM mesh object from the parallel PUMI mesh.
// We can handle triangular and tetrahedral meshes. Note that the
// mesh resolution is performed on the PUMI mesh.
ParMesh *pmesh = new ParPumiMesh(MPI_COMM_WORLD, pumi_mesh);
// 6. 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.
FiniteElementCollection *fec;
if (order > 0)
{
fec = new H1_FECollection(order, dim);
}
else if (pmesh->GetNodes())
{
fec = pmesh->GetNodes()->OwnFEC();
if (myid == 0)
{
cout << "Using isoparametric FEs: " << fec->Name() << endl;
}
}
else
{
fec = new H1_FECollection(order = 1, dim);
}
ParFiniteElementSpace *fespace = new ParFiniteElementSpace(pmesh, fec);
HYPRE_Int size = fespace->GlobalTrueVSize();
if (myid == 0)
{
cout << "Number of finite element unknowns: " << size << endl;
}
// 7. Determine the list of true (i.e. parallel conforming) essential
// boundary dofs. In this example, the boundary conditions are defined
// by marking all the boundary attributes from the mesh as essential
// (Dirichlet) and converting them to a list of true dofs.
Array<int> ess_tdof_list;
if (pmesh->bdr_attributes.Size())
{
Array<int> ess_bdr(pmesh->bdr_attributes.Max());
ess_bdr = 1;
fespace->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
}
// 8. Set up the parallel linear form b(.) which corresponds to the
// right-hand side of the FEM linear system, which in this case is
// (1,phi_i) where phi_i are the basis functions in fespace.
ParLinearForm *b = new ParLinearForm(fespace);
ConstantCoefficient one(1.0);
b->AddDomainIntegrator(new DomainLFIntegrator(one));
b->Assemble();
// 9. Define the solution vector x as a parallel finite element grid function
// corresponding to fespace. Initialize x with initial guess of zero,
// which satisfies the boundary conditions.
ParGridFunction x(fespace);
x = 0.0;
// 10. Set up the parallel bilinear form a(.,.) on the finite element space
// corresponding to the Laplacian operator -Delta, by adding the Diffusion
// domain integrator.
ParBilinearForm *a = new ParBilinearForm(fespace);
a->AddDomainIntegrator(new DiffusionIntegrator(one));
// 11. Assemble the parallel bilinear form and the corresponding linear
// system, applying any necessary transformations such as: parallel
// assembly, eliminating boundary conditions, applying conforming
// constraints for non-conforming AMR, static condensation, etc.
if (static_cond) { a->EnableStaticCondensation(); }
a->Assemble();
HypreParMatrix A;
Vector B, X;
a->FormLinearSystem(ess_tdof_list, x, *b, A, X, B);
if (myid == 0)
{
cout << "Size of linear system: " << A.GetGlobalNumRows() << endl;
}
// 12. Define and apply a parallel PCG solver for AX=B with the BoomerAMG
// preconditioner from hypre.
HypreSolver *amg = new HypreBoomerAMG(A);
HyprePCG *pcg = new HyprePCG(A);
pcg->SetTol(1e-12);
pcg->SetMaxIter(200);
pcg->SetPrintLevel(2);
pcg->SetPreconditioner(*amg);
pcg->Mult(B, X);
// 13. Recover the parallel grid function corresponding to X. This is the
// local finite element solution on each processor.
a->RecoverFEMSolution(X, *b, x);
// 14. Save the refined mesh and the solution in parallel. This output can
// be viewed later using GLVis: "glvis -np <np> -m mesh -g sol".
{
ostringstream mesh_name, sol_name;
mesh_name << "mesh." << setfill('0') << setw(6) << myid;
sol_name << "sol." << setfill('0') << setw(6) << myid;
ofstream mesh_ofs(mesh_name.str().c_str());
mesh_ofs.precision(8);
pmesh->Print(mesh_ofs);
ofstream sol_ofs(sol_name.str().c_str());
sol_ofs.precision(8);
x.Save(sol_ofs);
}
// 15. Send the solution by socket to a GLVis server.
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock(vishost, visport);
sol_sock << "parallel " << num_procs << " " << myid << "\n";
sol_sock.precision(8);
sol_sock << "solution\n" << *pmesh << x << flush;
}
// 16. Free the used memory.
delete pcg;
delete amg;
delete a;
delete b;
delete fespace;
if (order > 0) { delete fec; }
delete pmesh;
pumi_mesh->destroyNative();
apf::destroyMesh(pumi_mesh);
PCU_Comm_Free();
#ifdef MFEM_USE_SIMMETRIX
gmi_sim_stop();
Sim_unregisterAllKeys();
#endif
MPI_Finalize();
return 0;
}
-413
View File
@@ -1,413 +0,0 @@
// MFEM Example 2
// PUMI Modification
//
// Compile with: make ex2
//
// Sample runs:
// ex2 -m ../../data/pumi/serial/pillbox.smb -p ../../data/pumi/geom/pillbox.dmg
// -bf ../../data/pumi/serial/boundary.mesh
//
// Note: Example models + meshes for the PUMI examples can be downloaded
// from github.com/mfem/data/pumi. After downloading we recommend
// creating a symbolic link to the above directory in ../../data.
//
// Description: This example code solves a simple linear elasticity problem
// describing a multi-material cantilever beam.
//
// Specifically, we approximate the weak form of -div(sigma(u))=0
// where sigma(u)=lambda*div(u)*I+mu*(grad*u+u*grad) is the stress
// tensor corresponding to displacement field u, and lambda and mu
// are the material Lame constants. The boundary conditions are
// u=0 on the fixed part of the boundary with attribute 1, and
// sigma(u).n=f on the remainder with f being a constant pull down
// vector on boundary elements with attribute 2, and zero
// otherwise. The geometry of the domain is assumed to be as
// follows:
// boundary
// attribute 2
// (push down)
// ||
// \/
// +----------+
// | |
// | |
// +---------| material |----------+
// boundary --->| material| 2 | material |<--- boundary
// attribute 1 | 1 | | 3 | attribute 1
// (fixed) +---------+----------+----------+ (fixed)
//
// The example demonstrates the use of high-order and NURBS vector
// finite element spaces with the linear elasticity bilinear form,
// meshes with curved elements, and the definition of piece-wise
// constant and vector coefficient objects. Static condensation is
// also illustrated.
//
// We recommend viewing Example 1 before viewing this example.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#include "../../general/text.hpp"
#ifdef MFEM_USE_SIMMETRIX
#include <SimUtil.h>
#include <gmi_sim.h>
#endif
#include <apfMDS.h>
#include <gmi_null.h>
#include <PCU.h>
#include <apfConvert.h>
#include <gmi_mesh.h>
#include <crv.h>
using namespace std;
using namespace mfem;
int main(int argc, char *argv[])
{
// 1. Initialize MPI (required by PUMI).
int num_proc, myId;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_proc);
MPI_Comm_rank(MPI_COMM_WORLD, &myId);
// 2. Parse command-line options.
const char *mesh_file = "../../data/pumi/serial/pillbox.smb";
const char *boundary_file = "../../data/pumi/serial/boundary.mesh";
#ifdef MFEM_USE_SIMMETRIX
const char *model_file = "../../data/pumi/geom/pillbox.smd";
#else
const char *model_file = "../../data/pumi/geom/pillbox.dmg";
#endif
int order = 1;
bool static_cond = false;
bool visualization = 1;
int geom_order = 1;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&static_cond, "-sc", "--static-condensation", "-no-sc",
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&model_file, "-p", "--parasolid",
"Parasolid model to use.");
args.AddOption(&geom_order, "-go", "--geometry_order",
"Geometric order of the model");
args.AddOption(&boundary_file, "-bf", "--txt",
"txt file containing boundary tags");
args.Parse();
if (!args.Good())
{
args.PrintUsage(cout);
return 1;
}
args.PrintOptions(cout);
// 3. Read the SCOREC Mesh.
PCU_Comm_Init();
#ifdef MFEM_USE_SIMMETRIX
Sim_readLicenseFile(0);
gmi_sim_start();
gmi_register_sim();
#endif
gmi_register_mesh();
apf::Mesh2* pumi_mesh;
pumi_mesh = apf::loadMdsMesh(model_file, mesh_file);
// 4. Increase the geometry order if necessary.
if (geom_order > 1)
{
crv::BezierCurver bc(pumi_mesh, geom_order, 0);
bc.run();
}
pumi_mesh->verify();
// Read boundary
string bdr_tags;
named_ifgzstream input_bdr(boundary_file);
input_bdr >> ws;
getline(input_bdr, bdr_tags);
filter_dos(bdr_tags);
cout << " the boundary tag is : " << bdr_tags << endl;
Array<int> Dirichlet;
int numOfent;
if (bdr_tags == "Dirichlet")
{
input_bdr >> numOfent;
cout << " num of Dirichlet bdr conditions : " << numOfent << endl;
Dirichlet.SetSize(numOfent);
for (int kk = 0; kk < numOfent; kk++)
{
input_bdr >> Dirichlet[kk];
}
}
Dirichlet.Print();
Array<int> load_bdr;
skip_comment_lines(input_bdr, '#');
input_bdr >> bdr_tags;
filter_dos(bdr_tags);
cout << " the boundary tag is : " << bdr_tags << endl;
if (bdr_tags == "Load")
{
input_bdr >> numOfent;
load_bdr.SetSize(numOfent);
cout << " num of load bdr conditions : " << numOfent << endl;
for (int kk = 0; kk < numOfent; kk++)
{
input_bdr >> load_bdr[kk];
}
}
load_bdr.Print();
// 5. Create the MFEM mesh object from the PUMI mesh. We can handle triangular
// and tetrahedral meshes. Other inputs are the same as MFEM default
// constructor.
Mesh *mesh = new PumiMesh(pumi_mesh, 1, 1);
int dim = mesh->Dimension();
// Boundary conditions hack.
apf::MeshIterator* itr = pumi_mesh->begin(dim-1);
apf::MeshEntity* ent ;
int bdr_cnt = 0;
while ((ent = pumi_mesh->iterate(itr)))
{
apf::ModelEntity *me = pumi_mesh->toModel(ent);
if (pumi_mesh->getModelType(me) == (dim-1))
{
// Everywhere 3 as initial
(mesh->GetBdrElement(bdr_cnt))->SetAttribute(3);
int tag = pumi_mesh->getModelTag(me);
if (Dirichlet.Find(tag) != -1)
{
// Dirichlet attr -> 1
(mesh->GetBdrElement(bdr_cnt))->SetAttribute(1);
}
else if (load_bdr.Find(tag) != -1)
{
// Load attr -> 2
(mesh->GetBdrElement(bdr_cnt))->SetAttribute(2);
}
bdr_cnt++;
}
}
pumi_mesh->end(itr);
// Assign attributes for elements.
double ppt[3];
Vector cent(ppt, dim);
for (int el = 0; el < mesh->GetNE(); el++)
{
(mesh->GetElementTransformation(el))->
Transform(Geometries.GetCenter(mesh->GetElementBaseGeometry(el)),cent);
if (cent(0) <= -0.05)
{
mesh->SetAttribute(el, 1);
}
else if (cent(0) >= 0.05)
{
mesh->SetAttribute(el, 2);
}
else
{
mesh->SetAttribute(el, 3);
}
}
mesh->SetAttributes();
if (mesh->attributes.Max() < 2 || mesh->bdr_attributes.Max() < 2)
{
cerr << "\nInput mesh should have at least two materials and "
<< "two boundary attributes! (See schematic in ex2.cpp)\n"
<< endl;
return 3;
}
// 6. 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 5,000
// elements.
{
int ref_levels =
(int)floor(log(5000./mesh->GetNE())/log(2.)/dim);
for (int l = 0; l < ref_levels; l++)
{
mesh->UniformRefinement();
}
}
// 7. Define a finite element space on the mesh. Here we use vector finite
// elements, i.e. dim copies of a scalar finite element space. The vector
// dimension is specified by the last argument of the FiniteElementSpace
// constructor. For NURBS meshes, we use the (degree elevated) NURBS space
// associated with the mesh nodes.
FiniteElementCollection *fec;
FiniteElementSpace *fespace;
if (mesh->NURBSext)
{
fec = NULL;
fespace = mesh->GetNodes()->FESpace();
}
else
{
fec = new H1_FECollection(order, dim);
fespace = new FiniteElementSpace(mesh, fec, dim);
}
cout << "Number of finite element unknowns: " << fespace->GetTrueVSize()
<< endl << "Assembling: " << flush;
// 8. Determine the list of true (i.e. conforming) essential boundary dofs.
// In this example, the boundary conditions are defined by marking only
// boundary attribute 1 from the mesh as essential and converting it to a
// list of true dofs.
Array<int> ess_tdof_list, ess_bdr(mesh->bdr_attributes.Max());
ess_bdr = 0;
ess_bdr[0] = 1;
fespace->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
// 9. Set up the linear form b(.) which corresponds to the right-hand side of
// the FEM linear system. In this case, b_i equals the boundary integral
// of f*phi_i where f represents a "pull down" force on the Neumann part
// of the boundary and phi_i are the basis functions in the finite element
// fespace. The force is defined by the VectorArrayCoefficient object f,
// which is a vector of Coefficient objects. The fact that f is non-zero
// on boundary attribute 2 is indicated by the use of piece-wise constants
// coefficient for its last component.
VectorArrayCoefficient f(dim);
for (int i = 0; i < dim-1; i++)
{
f.Set(i, new ConstantCoefficient(0.0));
}
{
Vector pull_force(mesh->bdr_attributes.Max());
pull_force = 0.0;
pull_force(1) = -3.0e-2;
f.Set(dim-1, new PWConstCoefficient(pull_force));
f.Set(dim-2, new PWConstCoefficient(pull_force));
}
LinearForm *b = new LinearForm(fespace);
b->AddBoundaryIntegrator(new VectorBoundaryLFIntegrator(f));
cout << "r.h.s. ... " << flush;
b->Assemble();
// 10. 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;
// 11. Set up the bilinear form a(.,.) on the finite element space
// corresponding to the linear elasticity integrator with piece-wise
// constants coefficient lambda and mu.
Vector lambda(mesh->attributes.Max());
lambda = 1.0;
lambda(0) = lambda(1)*10;
lambda(1) = lambda(1)*100;
PWConstCoefficient lambda_func(lambda);
Vector mu(mesh->attributes.Max());
mu = 1.0;
mu(0) = mu(1)*10;
mu(1) = mu(1)*100;
PWConstCoefficient mu_func(mu);
BilinearForm *a = new BilinearForm(fespace);
a->AddDomainIntegrator(new ElasticityIntegrator(lambda_func,mu_func));
// 12. Assemble the bilinear form and the corresponding linear system,
// applying any necessary transformations such as: eliminating boundary
// conditions, applying conforming constraints for non-conforming AMR,
// static condensation, etc.
cout << "matrix ... " << flush;
if (static_cond) { a->EnableStaticCondensation(); }
a->Assemble();
SparseMatrix A;
Vector B, X;
a->FormLinearSystem(ess_tdof_list, x, *b, A, X, B);
cout << "done." << endl;
cout << "Size of linear system: " << A.Height() << endl;
#ifndef MFEM_USE_SUITESPARSE
// 13. Define a simple symmetric Gauss-Seidel preconditioner and use it to
// solve the system Ax=b with PCG.
GSSmoother M(A);
PCG(A, M, B, X, 1, 500, 1e-8, 0.0);
#else
// 13. If MFEM was compiled with SuiteSparse, use UMFPACK to solve the system.
UMFPackSolver umf_solver;
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
umf_solver.SetOperator(A);
umf_solver.Mult(B, X);
#endif
// 14. Recover the solution as a finite element grid function.
a->RecoverFEMSolution(X, *b, x);
// 15. For non-NURBS meshes, make the mesh curved based on the finite element
// space. This means that we define the mesh elements through a fespace
// based transformation of the reference element. This allows us to save
// the displaced mesh as a curved mesh when using high-order finite
// element displacement field. We assume that the initial mesh (read from
// the file) is not higher order curved mesh compared to the chosen FE
// space.
if (!mesh->NURBSext)
{
mesh->SetNodalFESpace(fespace);
}
// 16. Save the displaced mesh and the inverted solution (which gives the
// backward displacements to the original grid). This output can be
// viewed later using GLVis: "glvis -m displaced.mesh -g sol.gf".
{
GridFunction *nodes = mesh->GetNodes();
*nodes += x;
x *= -1;
ofstream mesh_ofs("displaced.mesh");
mesh_ofs.precision(8);
mesh->Print(mesh_ofs);
ofstream sol_ofs("sol.gf");
sol_ofs.precision(8);
x.Save(sol_ofs);
}
// 17. Send the above data by socket to a GLVis server. Use the "n" and "b"
// keys in GLVis to visualize the displacements.
if (visualization)
{
char vishost[] = "localhost";
int visport = 19916;
socketstream sol_sock(vishost, visport);
sol_sock.precision(8);
sol_sock << "solution\n" << *mesh << x << flush;
}
// 18. Free the used memory.
delete a;
delete b;
if (fec)
{
delete fespace;
delete fec;
}
delete mesh;
pumi_mesh->destroyNative();
apf::destroyMesh(pumi_mesh);
PCU_Comm_Free();
#ifdef MFEM_USE_SIMMETRIX
gmi_sim_stop();
Sim_unregisterAllKeys();
#endif
MPI_Finalize();
return 0;
}
-387
View File
@@ -1,387 +0,0 @@
// MFEM Example 6 - Parallel Version
// PUMI Modification
//
// Compile with: make ex1p
//
// Sample runs: mpirun -np 8 ex6p
//
// Description: This is a version of Example 1 with a simple adaptive mesh
// refinement loop. The problem being solved is again the Laplace
// equation -Delta u = 1 with homogeneous Dirichlet boundary
// conditions. The problem is solved on a sequence of meshes which
// are adapted in a conforming (tetrahedrons) manner according
// to a simple SPR ZZ error estimator.
//
// This PUMI variation also performs a "uniform" refinement,
// similar to MFEM examples, for coarse meshes. However, the
// refinement is performed using the PUMI API. A new option "-ar"
// is added to modify the "adapt_ratio" which is the fraction of
// allowable error that scales the output size field of the error
// estimator.
#include "mfem.hpp"
#include <fstream>
#include <iostream>
#ifdef MFEM_USE_SIMMETRIX
#include <SimUtil.h>
#include <gmi_sim.h>
#endif
#include <apfMDS.h>
#include <gmi_null.h>
#include <PCU.h>
#include <spr.h>
#include <apfConvert.h>
#include <gmi_mesh.h>
#include <crv.h>
using namespace std;
using namespace mfem;
int main(int argc, char *argv[])
{
// 1. Initialize MPI.
int num_procs, myid;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
// 2. Parse command-line options.
const char *mesh_file = "../../data/pumi/parallel/Kova/Kova100k_8.smb";
#ifdef MFEM_USE_SIMMETRIX
const char *model_file = "../../data/pumi/geom/Kova.x_t";
const char *smd_file = NULL;
#else
const char *model_file = "../../data/pumi/geom/Kova.dmg";
#endif
int order = 1;
bool static_cond = false;
bool visualization = 1;
int geom_order = 1;
double adapt_ratio = 0.05;
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(&static_cond, "-sc", "--static-condensation", "-no-sc",
"--no-static-condensation", "Enable static condensation.");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.AddOption(&model_file, "-p", "--model",
"parasolid or .dmg model to use.");
#ifdef MFEM_USE_SIMMETRIX
args.AddOption(&smd_file, "-sm", "--smd_model",
"smd model file to use.");
#endif
args.AddOption(&geom_order, "-go", "--geometry_order",
"Geometric order of the model");
args.AddOption(&adapt_ratio, "-ar", "--adapt_ratio",
"adaptation factor used in MeshAdapt");
args.Parse();
if (!args.Good())
{
if (myid == 0)
{
args.PrintUsage(cout);
}
MPI_Finalize();
return 1;
}
if (myid == 0)
{
args.PrintOptions(cout);
}
// 3. Read the SCOREC Mesh.
PCU_Comm_Init();
#ifdef MFEM_USE_SIMMETRIX
Sim_readLicenseFile(0);
gmi_sim_start();
gmi_register_sim();
#endif
gmi_register_mesh();
apf::Mesh2* pumi_mesh;
#ifdef MFEM_USE_SIMMETRIX
if (smd_file)
{
gmi_model *mixed_model = gmi_sim_load(model_file, smd_file);
pumi_mesh = apf::loadMdsMesh(mixed_model, mesh_file);
}
else
#endif
{
pumi_mesh = apf::loadMdsMesh(model_file, mesh_file);
}
// 4. Increase the geometry order and refine the mesh if necessary. Parallel
// uniform refinement is performed if the total number of elements is less
// than 100,000.
int dim = pumi_mesh->getDimension();
int nEle = pumi_mesh->count(dim);
int ref_levels = (int)floor(log(100000./nEle)/log(2.)/dim);
if (geom_order > 1)
{
crv::BezierCurver bc(pumi_mesh, geom_order, 2);
bc.run();
}
// Perform Uniform refinement
if (myid == 1)
{
std::cout << " ref level : " << ref_levels << std::endl;
}
if (ref_levels > 1)
{
ma::Input* uniInput = ma::configureUniformRefine(pumi_mesh, ref_levels);
if ( geom_order > 1)
{
crv::adapt(uniInput);
}
else
{
ma::adapt(uniInput);
}
}
pumi_mesh->verify();
// 5. Create the parallel MFEM mesh object from the parallel PUMI mesh. We
// can handle triangular and tetrahedral meshes. Note that the mesh
// resolution is performed on the PUMI mesh.
ParMesh *pmesh = new ParPumiMesh(MPI_COMM_WORLD, pumi_mesh);
// 6. 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.
FiniteElementCollection *fec;
if (order > 0)
{
fec = new H1_FECollection(order, dim);
}
else if (pmesh->GetNodes())
{
fec = pmesh->GetNodes()->OwnFEC();
if (myid == 1)
{
cout << "Using isoparametric FEs: " << fec->Name() << endl;
}
}
else
{
fec = new H1_FECollection(order = 1, dim);
}
ParFiniteElementSpace *fespace = new ParFiniteElementSpace(pmesh, fec);
HYPRE_Int size = fespace->GlobalTrueVSize();
if (myid == 1)
{
cout << "Number of finite element unknowns: " << size << endl;
}
// 7. 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,phi_i) where phi_i are the basis functions in fespace.
ParLinearForm *b = new ParLinearForm(fespace);
ConstantCoefficient one(1.0);
b->AddDomainIntegrator(new DomainLFIntegrator(one));
// 8. 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;
// 9. Connect to GLVis.
char vishost[] = "localhost";
int visport = 19916;
socketstream sout;
if (visualization)
{
sout.open(vishost, visport);
if (!sout)
{
if (myid == 0)
{
cout << "Unable to connect to GLVis server at "
<< vishost << ':' << visport << endl;
cout << "GLVis visualization disabled.\n";
}
visualization = false;
}
sout.precision(8);
}
// 10. Set up the parallel bilinear form a(.,.) on the finite element space
// corresponding to the Laplacian operator -Delta, by adding the
// Diffusion domain integrator.
ParBilinearForm *a = new ParBilinearForm(fespace);
a->AddDomainIntegrator(new DiffusionIntegrator(one));
// 11. Assemble the parallel bilinear form and the corresponding linear
// system, applying any necessary transformations such as: parallel
// assembly, eliminating boundary conditions, applying conforming
// constraints for non-conforming AMR, static condensation, etc.
if (static_cond) { a->EnableStaticCondensation(); }
// 12. The main AMR loop. In each iteration we solve the problem on the
// current mesh, visualize the solution, and adapt the mesh.
apf::Field* Tmag_field = 0;
apf::Field* temp_field = 0;
apf::Field* ipfield = 0;
apf::Field* sizefield = 0;
int max_iter = 3;
for (int Itr = 0; Itr < max_iter; Itr++)
{
HYPRE_Int global_dofs = fespace->GlobalTrueVSize();
if (myid == 1)
{
cout << "\nAMR iteration " << Itr << endl;
cout << "Number of unknowns: " << global_dofs << endl;
}
// Assemble.
a->Assemble();
b->Assemble();
// Essential boundary condition.
Array<int> ess_tdof_list;
if (pmesh->bdr_attributes.Size())
{
Array<int> ess_bdr(pmesh->bdr_attributes.Max());
ess_bdr = 1;
fespace->GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
}
// Form linear system.
HypreParMatrix A;
Vector B, X;
const int copy_interior = 1;
a->FormLinearSystem(ess_tdof_list, x, *b, A, X, B, copy_interior);
// 13. Define and apply a parallel PCG solver for AX=B with the BoomerAMG
// preconditioner from hypre.
HypreBoomerAMG amg;
amg.SetPrintLevel(0);
CGSolver pcg(A.GetComm());
pcg.SetPreconditioner(amg);
pcg.SetOperator(A);
pcg.SetRelTol(1e-6);
pcg.SetMaxIter(200);
pcg.SetPrintLevel(3); // print the first and the last iterations only
pcg.Mult(B, X);
// 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 in parallel the displaced mesh and the inverted solution (which
// gives the backward displacements to the original grid). This output
// can be viewed later using GLVis: "glvis -np <np> -m mesh -g sol".
{
ostringstream mesh_name, sol_name;
mesh_name << "mesh." << setfill('0') << setw(6) << myid;
sol_name << "sol." << setfill('0') << setw(6) << myid;
ofstream mesh_ofs(mesh_name.str().c_str());
mesh_ofs.precision(8);
pmesh->Print(mesh_ofs);
ofstream sol_ofs(sol_name.str().c_str());
sol_ofs.precision(8);
x.Save(sol_ofs);
}
// 16. Send the above data by socket to a GLVis server. Use the "n" and "b"
// keys in GLVis to visualize the displacements.
if (visualization)
{
sout << "parallel " << num_procs << " " << myid << "\n";
sout << "solution\n" << *pmesh << x << flush;
}
// 17. Field transfer. Scalar solution field and magnitude field for error
// estimation are created the PUMI mesh.
if (order > geom_order)
{
Tmag_field = apf::createField(pumi_mesh, "field_mag",
apf::SCALAR, apf::getLagrange(order));
temp_field = apf::createField(pumi_mesh, "T_field",
apf::SCALAR, apf::getLagrange(order));
}
else
{
Tmag_field = apf::createFieldOn(pumi_mesh, "field_mag",apf::SCALAR);
temp_field = apf::createFieldOn(pumi_mesh, "T_field", apf::SCALAR);
}
ParPumiMesh* pPPmesh = dynamic_cast<ParPumiMesh*>(pmesh);
pPPmesh->FieldMFEMtoPUMI(pumi_mesh, &x, temp_field, Tmag_field);
ipfield= spr::getGradIPField(Tmag_field, "MFEM_gradip", 2);
sizefield = spr::getSPRSizeField(ipfield, adapt_ratio);
apf::destroyField(Tmag_field);
apf::destroyField(ipfield);
apf::destroyNumbering(pumi_mesh->findNumbering("LocalVertexNumbering"));
// 18. Perform MesAdapt.
ma::Input* erinput = ma::configure(pumi_mesh, sizefield);
erinput->shouldFixShape = true;
erinput->maximumIterations = 2;
if ( geom_order > 1)
{
crv::adapt(erinput);
}
else
{
ma::adapt(erinput);
}
ParMesh* Adapmesh = new ParPumiMesh(MPI_COMM_WORLD, pumi_mesh);
pPPmesh->UpdateMesh(Adapmesh);
delete Adapmesh;
// 19. Update the FiniteElementSpace, GridFunction, and bilinear form.
fespace->Update();
x.Update();
x = 0.0;
pPPmesh->FieldPUMItoMFEM(pumi_mesh, temp_field, &x);
a->Update();
b->Update();
// Destroy fields.
apf::destroyField(temp_field);
apf::destroyField(sizefield);
}
// 20. Free the used memory.
delete a;
delete b;
delete fespace;
if (order > 0) { delete fec; }
delete pmesh;
pumi_mesh->destroyNative();
apf::destroyMesh(pumi_mesh);
PCU_Comm_Free();
#ifdef MFEM_USE_SIMMETRIX
gmi_sim_stop();
Sim_unregisterAllKeys();
#endif
MPI_Finalize();
return 0;
}
-94
View File
@@ -1,94 +0,0 @@
# Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at the
# Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights reserved.
# See file COPYRIGHT for details.
#
# This file is part of the MFEM library. For more information and source code
# availability see http://mfem.org.
#
# MFEM is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License (as published by the Free
# Software Foundation) version 2.1 dated February 1999.
# Use the MFEM build directory
MFEM_DIR ?= ../..
MFEM_BUILD_DIR ?= ../..
SRC = $(if $(MFEM_DIR:../..=),$(MFEM_DIR)/examples/pumi/,)
CONFIG_MK = $(MFEM_BUILD_DIR)/config/config.mk
# Use the MFEM install directory
# MFEM_INSTALL_DIR = ../../mfem
# CONFIG_MK = $(MFEM_INSTALL_DIR)/share/mfem/config.mk
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
# All PUMI examples require MPI
SEQ_EXAMPLES =
PAR_EXAMPLES = ex1 ex1p ex2 ex6p
ifeq ($(MFEM_USE_MPI),NO)
EXAMPLES = $(SEQ_EXAMPLES)
else
EXAMPLES = $(PAR_EXAMPLES) $(SEQ_EXAMPLES)
endif
.SUFFIXES:
.SUFFIXES: .o .cpp .mk
.PHONY: all clean clean-build clean-exec
# Remove built-in rule
%: %.cpp
# Replace the default implicit rule for *.cpp files
%: $(SRC)%.cpp $(MFEM_LIB_FILE) $(CONFIG_MK)
$(MFEM_CXX) $(MFEM_FLAGS) $< -o $@ $(MFEM_LIBS)
all: $(EXAMPLES)
ifeq ($(MFEM_USE_PUMI),NO)
$(EXAMPLES):
$(error MFEM is not configured with PUMI)
endif
MFEM_TESTS = EXAMPLES
include $(MFEM_TEST_MK)
ifneq (,$(filter test%,$(MAKECMDGOALS)))
ifeq (,$(wildcard ../../data/pumi))
$(info PUMI data directory not found. The PUMI tests will be SKIPPED.)
mfem-test = printf " $(3) [$(2) $(1) ... ]: "; $(PRINT_SKIP)
endif
endif
# Testing: Parallel vs. serial runs
RUN_MPI_NP = $(MFEM_MPIEXEC) $(MFEM_MPIEXEC_NP)
RUN_MPI = $(RUN_MPI_NP) $(MFEM_MPI_NP)
SERIAL_NAME := Serial PUMI example
PARALLEL_NAME := Parallel PUMI example
%-test-par: %
@$(call mfem-test,$<, $(RUN_MPI), $(PARALLEL_NAME))
%-test-seq: %
@$(call mfem-test,$<,, $(SERIAL_NAME))
# Testing: Example-specific execution options:
ex1-test-par: ex1
@$(call mfem-test,$<, $(RUN_MPI_NP) 1, $(PARALLEL_NAME))
ex1p-test-par: ex1p
@$(call mfem-test,$<, $(RUN_MPI_NP) 8, $(PARALLEL_NAME))
ex2-test-par: ex2
@$(call mfem-test,$<, $(RUN_MPI_NP) 1, $(PARALLEL_NAME))
ex6p-test-par: ex6p
@$(call mfem-test,$<, $(RUN_MPI_NP) 8, $(PARALLEL_NAME))
# Testing: "test" target and mfem-test* variables are defined in config/test.mk
# Generate an error message if the MFEM library is not built and exit
$(MFEM_LIB_FILE):
$(error The MFEM library is not built)
clean: clean-build clean-exec
clean-build:
rm -f *.o *~ $(SEQ_EXAMPLES) $(PAR_EXAMPLES)
rm -rf *.dSYM *.TVD.*breakpoints
clean-exec:
@rm -f refined.mesh sol.gf mesh.* sol.* displaced.mesh

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